diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..d2623ee07a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,20 @@ +name: ci + +on: + pull_request: + branches: [main] + +jobs: + tests: + name: Tests + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Install dependencies + run: npm ci + + - name: Run test + run: npm run test diff --git a/README.md b/README.md index c2bec0368b..4dbd9fb849 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,5 @@ go build -o notely && ./notely *This starts the server in non-database mode.* It will serve a simple webpage at `http://localhost:8080`. You do *not* need to set up a database or any interactivity on the webpage yet. Instructions for that will come later in the course! + +Chinmay's version of Boot.dev's Notely app. diff --git a/node_modules/.bin/esbuild b/node_modules/.bin/esbuild new file mode 120000 index 0000000000..c83ac07079 --- /dev/null +++ b/node_modules/.bin/esbuild @@ -0,0 +1 @@ +../esbuild/bin/esbuild \ No newline at end of file diff --git a/node_modules/.bin/nanoid b/node_modules/.bin/nanoid new file mode 120000 index 0000000000..e2be547bcb --- /dev/null +++ b/node_modules/.bin/nanoid @@ -0,0 +1 @@ +../nanoid/bin/nanoid.cjs \ No newline at end of file diff --git a/node_modules/.bin/rollup b/node_modules/.bin/rollup new file mode 120000 index 0000000000..5939621caa --- /dev/null +++ b/node_modules/.bin/rollup @@ -0,0 +1 @@ +../rollup/dist/bin/rollup \ No newline at end of file diff --git a/node_modules/.bin/vite b/node_modules/.bin/vite new file mode 120000 index 0000000000..6d1e3beaf6 --- /dev/null +++ b/node_modules/.bin/vite @@ -0,0 +1 @@ +../vite/bin/vite.js \ No newline at end of file diff --git a/node_modules/.bin/vite-node b/node_modules/.bin/vite-node new file mode 120000 index 0000000000..d68f74cb96 --- /dev/null +++ b/node_modules/.bin/vite-node @@ -0,0 +1 @@ +../vite-node/vite-node.mjs \ No newline at end of file diff --git a/node_modules/.bin/vitest b/node_modules/.bin/vitest new file mode 120000 index 0000000000..2273497945 --- /dev/null +++ b/node_modules/.bin/vitest @@ -0,0 +1 @@ +../vitest/vitest.mjs \ No newline at end of file diff --git a/node_modules/.bin/why-is-node-running b/node_modules/.bin/why-is-node-running new file mode 120000 index 0000000000..f08a594c75 --- /dev/null +++ b/node_modules/.bin/why-is-node-running @@ -0,0 +1 @@ +../why-is-node-running/cli.js \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000000..1400309cc2 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,1546 @@ +{ + "name": "learn-cicd-starter", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", + "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", + "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "cpu": [ + "arm" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", + "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", + "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", + "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", + "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", + "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", + "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", + "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "cpu": [ + "arm" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", + "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "cpu": [ + "ia32" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", + "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", + "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", + "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", + "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", + "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "cpu": [ + "s390x" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", + "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", + "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", + "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", + "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", + "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", + "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", + "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", + "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", + "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "cpu": [ + "ia32" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", + "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.49.0.tgz", + "integrity": "sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA==", + "cpu": [ + "arm" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.49.0.tgz", + "integrity": "sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.49.0.tgz", + "integrity": "sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.49.0.tgz", + "integrity": "sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.49.0.tgz", + "integrity": "sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.49.0.tgz", + "integrity": "sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.49.0.tgz", + "integrity": "sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w==", + "cpu": [ + "arm" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.49.0.tgz", + "integrity": "sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA==", + "cpu": [ + "arm" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.49.0.tgz", + "integrity": "sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.49.0.tgz", + "integrity": "sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.49.0.tgz", + "integrity": "sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.49.0.tgz", + "integrity": "sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.49.0.tgz", + "integrity": "sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.49.0.tgz", + "integrity": "sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.49.0.tgz", + "integrity": "sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A==", + "cpu": [ + "s390x" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.49.0.tgz", + "integrity": "sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.49.0.tgz", + "integrity": "sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.49.0.tgz", + "integrity": "sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA==", + "cpu": [ + "arm64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.49.0.tgz", + "integrity": "sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA==", + "cpu": [ + "ia32" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.49.0.tgz", + "integrity": "sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg==", + "cpu": [ + "x64" + ], + "dev": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "ideallyInert": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.18", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz", + "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "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, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.49.0.tgz", + "integrity": "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.49.0", + "@rollup/rollup-android-arm64": "4.49.0", + "@rollup/rollup-darwin-arm64": "4.49.0", + "@rollup/rollup-darwin-x64": "4.49.0", + "@rollup/rollup-freebsd-arm64": "4.49.0", + "@rollup/rollup-freebsd-x64": "4.49.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.49.0", + "@rollup/rollup-linux-arm-musleabihf": "4.49.0", + "@rollup/rollup-linux-arm64-gnu": "4.49.0", + "@rollup/rollup-linux-arm64-musl": "4.49.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.49.0", + "@rollup/rollup-linux-ppc64-gnu": "4.49.0", + "@rollup/rollup-linux-riscv64-gnu": "4.49.0", + "@rollup/rollup-linux-riscv64-musl": "4.49.0", + "@rollup/rollup-linux-s390x-gnu": "4.49.0", + "@rollup/rollup-linux-x64-gnu": "4.49.0", + "@rollup/rollup-linux-x64-musl": "4.49.0", + "@rollup/rollup-win32-arm64-msvc": "4.49.0", + "@rollup/rollup-win32-ia32-msvc": "4.49.0", + "@rollup/rollup-win32-x64-msvc": "4.49.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", + "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vite": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.3.tgz", + "integrity": "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.14" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json b/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json new file mode 100644 index 0000000000..00cd84cc1c --- /dev/null +++ b/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json @@ -0,0 +1 @@ +{"version":"3.2.4","results":[[":src/tests/auth.test.ts",{"duration":6.0587150000000065,"failed":true}]]} \ No newline at end of file diff --git a/node_modules/@esbuild/linux-x64/README.md b/node_modules/@esbuild/linux-x64/README.md new file mode 100644 index 0000000000..b2f1930043 --- /dev/null +++ b/node_modules/@esbuild/linux-x64/README.md @@ -0,0 +1,3 @@ +# esbuild + +This is the Linux 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details. diff --git a/node_modules/@esbuild/linux-x64/bin/esbuild b/node_modules/@esbuild/linux-x64/bin/esbuild new file mode 100755 index 0000000000..6a456f3482 Binary files /dev/null and b/node_modules/@esbuild/linux-x64/bin/esbuild differ diff --git a/node_modules/@esbuild/linux-x64/package.json b/node_modules/@esbuild/linux-x64/package.json new file mode 100644 index 0000000000..8d0ec96f9e --- /dev/null +++ b/node_modules/@esbuild/linux-x64/package.json @@ -0,0 +1,20 @@ +{ + "name": "@esbuild/linux-x64", + "version": "0.25.9", + "description": "The Linux 64-bit binary for esbuild, a JavaScript bundler.", + "repository": { + "type": "git", + "url": "git+https://github.com/evanw/esbuild.git" + }, + "license": "MIT", + "preferUnplugged": true, + "engines": { + "node": ">=18" + }, + "os": [ + "linux" + ], + "cpu": [ + "x64" + ] +} diff --git a/node_modules/@jridgewell/sourcemap-codec/LICENSE b/node_modules/@jridgewell/sourcemap-codec/LICENSE new file mode 100644 index 0000000000..1f6ce94c11 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/LICENSE @@ -0,0 +1,19 @@ +Copyright 2024 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@jridgewell/sourcemap-codec/README.md b/node_modules/@jridgewell/sourcemap-codec/README.md new file mode 100644 index 0000000000..b3e0708bf9 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/README.md @@ -0,0 +1,264 @@ +# @jridgewell/sourcemap-codec + +Encode/decode the `mappings` property of a [sourcemap](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit). + + +## Why? + +Sourcemaps are difficult to generate and manipulate, because the `mappings` property – the part that actually links the generated code back to the original source – is encoded using an obscure method called [Variable-length quantity](https://en.wikipedia.org/wiki/Variable-length_quantity). On top of that, each segment in the mapping contains offsets rather than absolute indices, which means that you can't look at a segment in isolation – you have to understand the whole sourcemap. + +This package makes the process slightly easier. + + +## Installation + +```bash +npm install @jridgewell/sourcemap-codec +``` + + +## Usage + +```js +import { encode, decode } from '@jridgewell/sourcemap-codec'; + +var decoded = decode( ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' ); + +assert.deepEqual( decoded, [ + // the first line (of the generated code) has no mappings, + // as shown by the starting semi-colon (which separates lines) + [], + + // the second line contains four (comma-separated) segments + [ + // segments are encoded as you'd expect: + // [ generatedCodeColumn, sourceIndex, sourceCodeLine, sourceCodeColumn, nameIndex ] + + // i.e. the first segment begins at column 2, and maps back to the second column + // of the second line (both zero-based) of the 0th source, and uses the 0th + // name in the `map.names` array + [ 2, 0, 2, 2, 0 ], + + // the remaining segments are 4-length rather than 5-length, + // because they don't map a name + [ 4, 0, 2, 4 ], + [ 6, 0, 2, 5 ], + [ 7, 0, 2, 7 ] + ], + + // the final line contains two segments + [ + [ 2, 1, 10, 19 ], + [ 12, 1, 11, 20 ] + ] +]); + +var encoded = encode( decoded ); +assert.equal( encoded, ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' ); +``` + +## Benchmarks + +``` +node v20.10.0 + +amp.js.map - 45120 segments + +Decode Memory Usage: +local code 5815135 bytes +@jridgewell/sourcemap-codec 1.4.15 5868160 bytes +sourcemap-codec 5492584 bytes +source-map-0.6.1 13569984 bytes +source-map-0.8.0 6390584 bytes +chrome dev tools 8011136 bytes +Smallest memory usage is sourcemap-codec + +Decode speed: +decode: local code x 492 ops/sec ±1.22% (90 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 499 ops/sec ±1.16% (89 runs sampled) +decode: sourcemap-codec x 376 ops/sec ±1.66% (89 runs sampled) +decode: source-map-0.6.1 x 34.99 ops/sec ±0.94% (48 runs sampled) +decode: source-map-0.8.0 x 351 ops/sec ±0.07% (95 runs sampled) +chrome dev tools x 165 ops/sec ±0.91% (86 runs sampled) +Fastest is decode: @jridgewell/sourcemap-codec 1.4.15 + +Encode Memory Usage: +local code 444248 bytes +@jridgewell/sourcemap-codec 1.4.15 623024 bytes +sourcemap-codec 8696280 bytes +source-map-0.6.1 8745176 bytes +source-map-0.8.0 8736624 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 796 ops/sec ±0.11% (97 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 795 ops/sec ±0.25% (98 runs sampled) +encode: sourcemap-codec x 231 ops/sec ±0.83% (86 runs sampled) +encode: source-map-0.6.1 x 166 ops/sec ±0.57% (86 runs sampled) +encode: source-map-0.8.0 x 203 ops/sec ±0.45% (88 runs sampled) +Fastest is encode: local code,encode: @jridgewell/sourcemap-codec 1.4.15 + + +*** + + +babel.min.js.map - 347793 segments + +Decode Memory Usage: +local code 35424960 bytes +@jridgewell/sourcemap-codec 1.4.15 35424696 bytes +sourcemap-codec 36033464 bytes +source-map-0.6.1 62253704 bytes +source-map-0.8.0 43843920 bytes +chrome dev tools 45111400 bytes +Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15 + +Decode speed: +decode: local code x 38.18 ops/sec ±5.44% (52 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 38.36 ops/sec ±5.02% (52 runs sampled) +decode: sourcemap-codec x 34.05 ops/sec ±4.45% (47 runs sampled) +decode: source-map-0.6.1 x 4.31 ops/sec ±2.76% (15 runs sampled) +decode: source-map-0.8.0 x 55.60 ops/sec ±0.13% (73 runs sampled) +chrome dev tools x 16.94 ops/sec ±3.78% (46 runs sampled) +Fastest is decode: source-map-0.8.0 + +Encode Memory Usage: +local code 2606016 bytes +@jridgewell/sourcemap-codec 1.4.15 2626440 bytes +sourcemap-codec 21152576 bytes +source-map-0.6.1 25023928 bytes +source-map-0.8.0 25256448 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 127 ops/sec ±0.18% (83 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 128 ops/sec ±0.26% (83 runs sampled) +encode: sourcemap-codec x 29.31 ops/sec ±2.55% (53 runs sampled) +encode: source-map-0.6.1 x 18.85 ops/sec ±3.19% (36 runs sampled) +encode: source-map-0.8.0 x 19.34 ops/sec ±1.97% (36 runs sampled) +Fastest is encode: @jridgewell/sourcemap-codec 1.4.15 + + +*** + + +preact.js.map - 1992 segments + +Decode Memory Usage: +local code 261696 bytes +@jridgewell/sourcemap-codec 1.4.15 244296 bytes +sourcemap-codec 302816 bytes +source-map-0.6.1 939176 bytes +source-map-0.8.0 336 bytes +chrome dev tools 587368 bytes +Smallest memory usage is source-map-0.8.0 + +Decode speed: +decode: local code x 17,782 ops/sec ±0.32% (97 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 17,863 ops/sec ±0.40% (100 runs sampled) +decode: sourcemap-codec x 12,453 ops/sec ±0.27% (101 runs sampled) +decode: source-map-0.6.1 x 1,288 ops/sec ±1.05% (96 runs sampled) +decode: source-map-0.8.0 x 9,289 ops/sec ±0.27% (101 runs sampled) +chrome dev tools x 4,769 ops/sec ±0.18% (100 runs sampled) +Fastest is decode: @jridgewell/sourcemap-codec 1.4.15 + +Encode Memory Usage: +local code 262944 bytes +@jridgewell/sourcemap-codec 1.4.15 25544 bytes +sourcemap-codec 323048 bytes +source-map-0.6.1 507808 bytes +source-map-0.8.0 507480 bytes +Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15 + +Encode speed: +encode: local code x 24,207 ops/sec ±0.79% (95 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 24,288 ops/sec ±0.48% (96 runs sampled) +encode: sourcemap-codec x 6,761 ops/sec ±0.21% (100 runs sampled) +encode: source-map-0.6.1 x 5,374 ops/sec ±0.17% (99 runs sampled) +encode: source-map-0.8.0 x 5,633 ops/sec ±0.32% (99 runs sampled) +Fastest is encode: @jridgewell/sourcemap-codec 1.4.15,encode: local code + + +*** + + +react.js.map - 5726 segments + +Decode Memory Usage: +local code 678816 bytes +@jridgewell/sourcemap-codec 1.4.15 678816 bytes +sourcemap-codec 816400 bytes +source-map-0.6.1 2288864 bytes +source-map-0.8.0 721360 bytes +chrome dev tools 1012512 bytes +Smallest memory usage is local code + +Decode speed: +decode: local code x 6,178 ops/sec ±0.19% (98 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 6,261 ops/sec ±0.22% (100 runs sampled) +decode: sourcemap-codec x 4,472 ops/sec ±0.90% (99 runs sampled) +decode: source-map-0.6.1 x 449 ops/sec ±0.31% (95 runs sampled) +decode: source-map-0.8.0 x 3,219 ops/sec ±0.13% (100 runs sampled) +chrome dev tools x 1,743 ops/sec ±0.20% (99 runs sampled) +Fastest is decode: @jridgewell/sourcemap-codec 1.4.15 + +Encode Memory Usage: +local code 140960 bytes +@jridgewell/sourcemap-codec 1.4.15 159808 bytes +sourcemap-codec 969304 bytes +source-map-0.6.1 930520 bytes +source-map-0.8.0 930248 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 8,013 ops/sec ±0.19% (100 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 7,989 ops/sec ±0.20% (101 runs sampled) +encode: sourcemap-codec x 2,472 ops/sec ±0.21% (99 runs sampled) +encode: source-map-0.6.1 x 2,200 ops/sec ±0.17% (99 runs sampled) +encode: source-map-0.8.0 x 2,220 ops/sec ±0.37% (99 runs sampled) +Fastest is encode: local code + + +*** + + +vscode.map - 2141001 segments + +Decode Memory Usage: +local code 198955264 bytes +@jridgewell/sourcemap-codec 1.4.15 199175352 bytes +sourcemap-codec 199102688 bytes +source-map-0.6.1 386323432 bytes +source-map-0.8.0 244116432 bytes +chrome dev tools 293734280 bytes +Smallest memory usage is local code + +Decode speed: +decode: local code x 3.90 ops/sec ±22.21% (15 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 3.95 ops/sec ±23.53% (15 runs sampled) +decode: sourcemap-codec x 3.82 ops/sec ±17.94% (14 runs sampled) +decode: source-map-0.6.1 x 0.61 ops/sec ±7.81% (6 runs sampled) +decode: source-map-0.8.0 x 9.54 ops/sec ±0.28% (28 runs sampled) +chrome dev tools x 2.18 ops/sec ±10.58% (10 runs sampled) +Fastest is decode: source-map-0.8.0 + +Encode Memory Usage: +local code 13509880 bytes +@jridgewell/sourcemap-codec 1.4.15 13537648 bytes +sourcemap-codec 32540104 bytes +source-map-0.6.1 127531040 bytes +source-map-0.8.0 127535312 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 20.10 ops/sec ±0.19% (38 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 20.26 ops/sec ±0.32% (38 runs sampled) +encode: sourcemap-codec x 5.44 ops/sec ±1.64% (18 runs sampled) +encode: source-map-0.6.1 x 2.30 ops/sec ±4.79% (10 runs sampled) +encode: source-map-0.8.0 x 2.46 ops/sec ±6.53% (10 runs sampled) +Fastest is encode: @jridgewell/sourcemap-codec 1.4.15 +``` + +# License + +MIT diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs new file mode 100644 index 0000000000..532bab39f0 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs @@ -0,0 +1,423 @@ +// src/vlq.ts +var comma = ",".charCodeAt(0); +var semicolon = ";".charCodeAt(0); +var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var intToChar = new Uint8Array(64); +var charToInt = new Uint8Array(128); +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decodeInteger(reader, relative) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -2147483648 | -value; + } + return relative + value; +} +function encodeInteger(builder, num, relative) { + let delta = num - relative; + delta = delta < 0 ? -delta << 1 | 1 : delta << 1; + do { + let clamped = delta & 31; + delta >>>= 5; + if (delta > 0) clamped |= 32; + builder.write(intToChar[clamped]); + } while (delta > 0); + return num; +} +function hasMoreVlq(reader, max) { + if (reader.pos >= max) return false; + return reader.peek() !== comma; +} + +// src/strings.ts +var bufLength = 1024 * 16; +var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { + decode(buf) { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + } +} : { + decode(buf) { + let out = ""; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + } +}; +var StringWriter = class { + constructor() { + this.pos = 0; + this.out = ""; + this.buffer = new Uint8Array(bufLength); + } + write(v) { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + flush() { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } +}; +var StringReader = class { + constructor(buffer) { + this.pos = 0; + this.buffer = buffer; + } + next() { + return this.buffer.charCodeAt(this.pos++); + } + peek() { + return this.buffer.charCodeAt(this.pos); + } + indexOf(char) { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +}; + +// src/scopes.ts +var EMPTY = []; +function decodeOriginalScopes(input) { + const { length } = input; + const reader = new StringReader(input); + const scopes = []; + const stack = []; + let line = 0; + for (; reader.pos < length; reader.pos++) { + line = decodeInteger(reader, line); + const column = decodeInteger(reader, 0); + if (!hasMoreVlq(reader, length)) { + const last = stack.pop(); + last[2] = line; + last[3] = column; + continue; + } + const kind = decodeInteger(reader, 0); + const fields = decodeInteger(reader, 0); + const hasName = fields & 1; + const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]; + let vars = EMPTY; + if (hasMoreVlq(reader, length)) { + vars = []; + do { + const varsIndex = decodeInteger(reader, 0); + vars.push(varsIndex); + } while (hasMoreVlq(reader, length)); + } + scope.vars = vars; + scopes.push(scope); + stack.push(scope); + } + return scopes; +} +function encodeOriginalScopes(scopes) { + const writer = new StringWriter(); + for (let i = 0; i < scopes.length; ) { + i = _encodeOriginalScopes(scopes, i, writer, [0]); + } + return writer.flush(); +} +function _encodeOriginalScopes(scopes, index, writer, state) { + const scope = scopes[index]; + const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope; + if (index > 0) writer.write(comma); + state[0] = encodeInteger(writer, startLine, state[0]); + encodeInteger(writer, startColumn, 0); + encodeInteger(writer, kind, 0); + const fields = scope.length === 6 ? 1 : 0; + encodeInteger(writer, fields, 0); + if (scope.length === 6) encodeInteger(writer, scope[5], 0); + for (const v of vars) { + encodeInteger(writer, v, 0); + } + for (index++; index < scopes.length; ) { + const next = scopes[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeOriginalScopes(scopes, index, writer, state); + } + writer.write(comma); + state[0] = encodeInteger(writer, endLine, state[0]); + encodeInteger(writer, endColumn, 0); + return index; +} +function decodeGeneratedRanges(input) { + const { length } = input; + const reader = new StringReader(input); + const ranges = []; + const stack = []; + let genLine = 0; + let definitionSourcesIndex = 0; + let definitionScopeIndex = 0; + let callsiteSourcesIndex = 0; + let callsiteLine = 0; + let callsiteColumn = 0; + let bindingLine = 0; + let bindingColumn = 0; + do { + const semi = reader.indexOf(";"); + let genColumn = 0; + for (; reader.pos < semi; reader.pos++) { + genColumn = decodeInteger(reader, genColumn); + if (!hasMoreVlq(reader, semi)) { + const last = stack.pop(); + last[2] = genLine; + last[3] = genColumn; + continue; + } + const fields = decodeInteger(reader, 0); + const hasDefinition = fields & 1; + const hasCallsite = fields & 2; + const hasScope = fields & 4; + let callsite = null; + let bindings = EMPTY; + let range; + if (hasDefinition) { + const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex); + definitionScopeIndex = decodeInteger( + reader, + definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0 + ); + definitionSourcesIndex = defSourcesIndex; + range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex]; + } else { + range = [genLine, genColumn, 0, 0]; + } + range.isScope = !!hasScope; + if (hasCallsite) { + const prevCsi = callsiteSourcesIndex; + const prevLine = callsiteLine; + callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex); + const sameSource = prevCsi === callsiteSourcesIndex; + callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0); + callsiteColumn = decodeInteger( + reader, + sameSource && prevLine === callsiteLine ? callsiteColumn : 0 + ); + callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn]; + } + range.callsite = callsite; + if (hasMoreVlq(reader, semi)) { + bindings = []; + do { + bindingLine = genLine; + bindingColumn = genColumn; + const expressionsCount = decodeInteger(reader, 0); + let expressionRanges; + if (expressionsCount < -1) { + expressionRanges = [[decodeInteger(reader, 0)]]; + for (let i = -1; i > expressionsCount; i--) { + const prevBl = bindingLine; + bindingLine = decodeInteger(reader, bindingLine); + bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0); + const expression = decodeInteger(reader, 0); + expressionRanges.push([expression, bindingLine, bindingColumn]); + } + } else { + expressionRanges = [[expressionsCount]]; + } + bindings.push(expressionRanges); + } while (hasMoreVlq(reader, semi)); + } + range.bindings = bindings; + ranges.push(range); + stack.push(range); + } + genLine++; + reader.pos = semi + 1; + } while (reader.pos < length); + return ranges; +} +function encodeGeneratedRanges(ranges) { + if (ranges.length === 0) return ""; + const writer = new StringWriter(); + for (let i = 0; i < ranges.length; ) { + i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]); + } + return writer.flush(); +} +function _encodeGeneratedRanges(ranges, index, writer, state) { + const range = ranges[index]; + const { + 0: startLine, + 1: startColumn, + 2: endLine, + 3: endColumn, + isScope, + callsite, + bindings + } = range; + if (state[0] < startLine) { + catchupLine(writer, state[0], startLine); + state[0] = startLine; + state[1] = 0; + } else if (index > 0) { + writer.write(comma); + } + state[1] = encodeInteger(writer, range[1], state[1]); + const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0); + encodeInteger(writer, fields, 0); + if (range.length === 6) { + const { 4: sourcesIndex, 5: scopesIndex } = range; + if (sourcesIndex !== state[2]) { + state[3] = 0; + } + state[2] = encodeInteger(writer, sourcesIndex, state[2]); + state[3] = encodeInteger(writer, scopesIndex, state[3]); + } + if (callsite) { + const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite; + if (sourcesIndex !== state[4]) { + state[5] = 0; + state[6] = 0; + } else if (callLine !== state[5]) { + state[6] = 0; + } + state[4] = encodeInteger(writer, sourcesIndex, state[4]); + state[5] = encodeInteger(writer, callLine, state[5]); + state[6] = encodeInteger(writer, callColumn, state[6]); + } + if (bindings) { + for (const binding of bindings) { + if (binding.length > 1) encodeInteger(writer, -binding.length, 0); + const expression = binding[0][0]; + encodeInteger(writer, expression, 0); + let bindingStartLine = startLine; + let bindingStartColumn = startColumn; + for (let i = 1; i < binding.length; i++) { + const expRange = binding[i]; + bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine); + bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn); + encodeInteger(writer, expRange[0], 0); + } + } + } + for (index++; index < ranges.length; ) { + const next = ranges[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeGeneratedRanges(ranges, index, writer, state); + } + if (state[0] < endLine) { + catchupLine(writer, state[0], endLine); + state[0] = endLine; + state[1] = 0; + } else { + writer.write(comma); + } + state[1] = encodeInteger(writer, endColumn, state[1]); + return index; +} +function catchupLine(writer, lastLine, line) { + do { + writer.write(semicolon); + } while (++lastLine < line); +} + +// src/sourcemap-codec.ts +function decode(mappings) { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + do { + const semi = reader.indexOf(";"); + const line = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + while (reader.pos < semi) { + let seg; + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) sorted = false; + lastCol = genColumn; + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } else { + seg = [genColumn]; + } + line.push(seg); + reader.pos++; + } + if (!sorted) sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + return decoded; +} +function sort(line) { + line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[0] - b[0]; +} +function encode(decoded) { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + let genColumn = 0; + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + genColumn = encodeInteger(writer, segment[0], genColumn); + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + return writer.flush(); +} +export { + decode, + decodeGeneratedRanges, + decodeOriginalScopes, + encode, + encodeGeneratedRanges, + encodeOriginalScopes +}; +//# sourceMappingURL=sourcemap-codec.mjs.map diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map new file mode 100644 index 0000000000..c276844b25 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../src/vlq.ts", "../src/strings.ts", "../src/scopes.ts", "../src/sourcemap-codec.ts"], + "mappings": "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", + "names": [] +} diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js new file mode 100644 index 0000000000..2d8e459f3e --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js @@ -0,0 +1,464 @@ +(function (global, factory) { + if (typeof exports === 'object' && typeof module !== 'undefined') { + factory(module); + module.exports = def(module); + } else if (typeof define === 'function' && define.amd) { + define(['module'], function(mod) { + factory.apply(this, arguments); + mod.exports = def(mod); + }); + } else { + const mod = { exports: {} }; + factory(mod); + global = typeof globalThis !== 'undefined' ? globalThis : global || self; + global.sourcemapCodec = def(mod); + } + function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; } +})(this, (function (module) { +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/sourcemap-codec.ts +var sourcemap_codec_exports = {}; +__export(sourcemap_codec_exports, { + decode: () => decode, + decodeGeneratedRanges: () => decodeGeneratedRanges, + decodeOriginalScopes: () => decodeOriginalScopes, + encode: () => encode, + encodeGeneratedRanges: () => encodeGeneratedRanges, + encodeOriginalScopes: () => encodeOriginalScopes +}); +module.exports = __toCommonJS(sourcemap_codec_exports); + +// src/vlq.ts +var comma = ",".charCodeAt(0); +var semicolon = ";".charCodeAt(0); +var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var intToChar = new Uint8Array(64); +var charToInt = new Uint8Array(128); +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decodeInteger(reader, relative) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -2147483648 | -value; + } + return relative + value; +} +function encodeInteger(builder, num, relative) { + let delta = num - relative; + delta = delta < 0 ? -delta << 1 | 1 : delta << 1; + do { + let clamped = delta & 31; + delta >>>= 5; + if (delta > 0) clamped |= 32; + builder.write(intToChar[clamped]); + } while (delta > 0); + return num; +} +function hasMoreVlq(reader, max) { + if (reader.pos >= max) return false; + return reader.peek() !== comma; +} + +// src/strings.ts +var bufLength = 1024 * 16; +var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { + decode(buf) { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + } +} : { + decode(buf) { + let out = ""; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + } +}; +var StringWriter = class { + constructor() { + this.pos = 0; + this.out = ""; + this.buffer = new Uint8Array(bufLength); + } + write(v) { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + flush() { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } +}; +var StringReader = class { + constructor(buffer) { + this.pos = 0; + this.buffer = buffer; + } + next() { + return this.buffer.charCodeAt(this.pos++); + } + peek() { + return this.buffer.charCodeAt(this.pos); + } + indexOf(char) { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +}; + +// src/scopes.ts +var EMPTY = []; +function decodeOriginalScopes(input) { + const { length } = input; + const reader = new StringReader(input); + const scopes = []; + const stack = []; + let line = 0; + for (; reader.pos < length; reader.pos++) { + line = decodeInteger(reader, line); + const column = decodeInteger(reader, 0); + if (!hasMoreVlq(reader, length)) { + const last = stack.pop(); + last[2] = line; + last[3] = column; + continue; + } + const kind = decodeInteger(reader, 0); + const fields = decodeInteger(reader, 0); + const hasName = fields & 1; + const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]; + let vars = EMPTY; + if (hasMoreVlq(reader, length)) { + vars = []; + do { + const varsIndex = decodeInteger(reader, 0); + vars.push(varsIndex); + } while (hasMoreVlq(reader, length)); + } + scope.vars = vars; + scopes.push(scope); + stack.push(scope); + } + return scopes; +} +function encodeOriginalScopes(scopes) { + const writer = new StringWriter(); + for (let i = 0; i < scopes.length; ) { + i = _encodeOriginalScopes(scopes, i, writer, [0]); + } + return writer.flush(); +} +function _encodeOriginalScopes(scopes, index, writer, state) { + const scope = scopes[index]; + const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope; + if (index > 0) writer.write(comma); + state[0] = encodeInteger(writer, startLine, state[0]); + encodeInteger(writer, startColumn, 0); + encodeInteger(writer, kind, 0); + const fields = scope.length === 6 ? 1 : 0; + encodeInteger(writer, fields, 0); + if (scope.length === 6) encodeInteger(writer, scope[5], 0); + for (const v of vars) { + encodeInteger(writer, v, 0); + } + for (index++; index < scopes.length; ) { + const next = scopes[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeOriginalScopes(scopes, index, writer, state); + } + writer.write(comma); + state[0] = encodeInteger(writer, endLine, state[0]); + encodeInteger(writer, endColumn, 0); + return index; +} +function decodeGeneratedRanges(input) { + const { length } = input; + const reader = new StringReader(input); + const ranges = []; + const stack = []; + let genLine = 0; + let definitionSourcesIndex = 0; + let definitionScopeIndex = 0; + let callsiteSourcesIndex = 0; + let callsiteLine = 0; + let callsiteColumn = 0; + let bindingLine = 0; + let bindingColumn = 0; + do { + const semi = reader.indexOf(";"); + let genColumn = 0; + for (; reader.pos < semi; reader.pos++) { + genColumn = decodeInteger(reader, genColumn); + if (!hasMoreVlq(reader, semi)) { + const last = stack.pop(); + last[2] = genLine; + last[3] = genColumn; + continue; + } + const fields = decodeInteger(reader, 0); + const hasDefinition = fields & 1; + const hasCallsite = fields & 2; + const hasScope = fields & 4; + let callsite = null; + let bindings = EMPTY; + let range; + if (hasDefinition) { + const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex); + definitionScopeIndex = decodeInteger( + reader, + definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0 + ); + definitionSourcesIndex = defSourcesIndex; + range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex]; + } else { + range = [genLine, genColumn, 0, 0]; + } + range.isScope = !!hasScope; + if (hasCallsite) { + const prevCsi = callsiteSourcesIndex; + const prevLine = callsiteLine; + callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex); + const sameSource = prevCsi === callsiteSourcesIndex; + callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0); + callsiteColumn = decodeInteger( + reader, + sameSource && prevLine === callsiteLine ? callsiteColumn : 0 + ); + callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn]; + } + range.callsite = callsite; + if (hasMoreVlq(reader, semi)) { + bindings = []; + do { + bindingLine = genLine; + bindingColumn = genColumn; + const expressionsCount = decodeInteger(reader, 0); + let expressionRanges; + if (expressionsCount < -1) { + expressionRanges = [[decodeInteger(reader, 0)]]; + for (let i = -1; i > expressionsCount; i--) { + const prevBl = bindingLine; + bindingLine = decodeInteger(reader, bindingLine); + bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0); + const expression = decodeInteger(reader, 0); + expressionRanges.push([expression, bindingLine, bindingColumn]); + } + } else { + expressionRanges = [[expressionsCount]]; + } + bindings.push(expressionRanges); + } while (hasMoreVlq(reader, semi)); + } + range.bindings = bindings; + ranges.push(range); + stack.push(range); + } + genLine++; + reader.pos = semi + 1; + } while (reader.pos < length); + return ranges; +} +function encodeGeneratedRanges(ranges) { + if (ranges.length === 0) return ""; + const writer = new StringWriter(); + for (let i = 0; i < ranges.length; ) { + i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]); + } + return writer.flush(); +} +function _encodeGeneratedRanges(ranges, index, writer, state) { + const range = ranges[index]; + const { + 0: startLine, + 1: startColumn, + 2: endLine, + 3: endColumn, + isScope, + callsite, + bindings + } = range; + if (state[0] < startLine) { + catchupLine(writer, state[0], startLine); + state[0] = startLine; + state[1] = 0; + } else if (index > 0) { + writer.write(comma); + } + state[1] = encodeInteger(writer, range[1], state[1]); + const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0); + encodeInteger(writer, fields, 0); + if (range.length === 6) { + const { 4: sourcesIndex, 5: scopesIndex } = range; + if (sourcesIndex !== state[2]) { + state[3] = 0; + } + state[2] = encodeInteger(writer, sourcesIndex, state[2]); + state[3] = encodeInteger(writer, scopesIndex, state[3]); + } + if (callsite) { + const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite; + if (sourcesIndex !== state[4]) { + state[5] = 0; + state[6] = 0; + } else if (callLine !== state[5]) { + state[6] = 0; + } + state[4] = encodeInteger(writer, sourcesIndex, state[4]); + state[5] = encodeInteger(writer, callLine, state[5]); + state[6] = encodeInteger(writer, callColumn, state[6]); + } + if (bindings) { + for (const binding of bindings) { + if (binding.length > 1) encodeInteger(writer, -binding.length, 0); + const expression = binding[0][0]; + encodeInteger(writer, expression, 0); + let bindingStartLine = startLine; + let bindingStartColumn = startColumn; + for (let i = 1; i < binding.length; i++) { + const expRange = binding[i]; + bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine); + bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn); + encodeInteger(writer, expRange[0], 0); + } + } + } + for (index++; index < ranges.length; ) { + const next = ranges[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeGeneratedRanges(ranges, index, writer, state); + } + if (state[0] < endLine) { + catchupLine(writer, state[0], endLine); + state[0] = endLine; + state[1] = 0; + } else { + writer.write(comma); + } + state[1] = encodeInteger(writer, endColumn, state[1]); + return index; +} +function catchupLine(writer, lastLine, line) { + do { + writer.write(semicolon); + } while (++lastLine < line); +} + +// src/sourcemap-codec.ts +function decode(mappings) { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + do { + const semi = reader.indexOf(";"); + const line = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + while (reader.pos < semi) { + let seg; + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) sorted = false; + lastCol = genColumn; + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } else { + seg = [genColumn]; + } + line.push(seg); + reader.pos++; + } + if (!sorted) sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + return decoded; +} +function sort(line) { + line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[0] - b[0]; +} +function encode(decoded) { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + let genColumn = 0; + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + genColumn = encodeInteger(writer, segment[0], genColumn); + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + return writer.flush(); +} +})); +//# sourceMappingURL=sourcemap-codec.umd.js.map diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map new file mode 100644 index 0000000000..abc18d286e --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../src/sourcemap-codec.ts", "../src/vlq.ts", "../src/strings.ts", "../src/scopes.ts"], + "mappings": "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", + "names": [] +} diff --git a/node_modules/@jridgewell/sourcemap-codec/package.json b/node_modules/@jridgewell/sourcemap-codec/package.json new file mode 100644 index 0000000000..da55137644 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/package.json @@ -0,0 +1,63 @@ +{ + "name": "@jridgewell/sourcemap-codec", + "version": "1.5.5", + "description": "Encode/decode sourcemap mappings", + "keywords": [ + "sourcemap", + "vlq" + ], + "main": "dist/sourcemap-codec.umd.js", + "module": "dist/sourcemap-codec.mjs", + "types": "types/sourcemap-codec.d.cts", + "files": [ + "dist", + "src", + "types" + ], + "exports": { + ".": [ + { + "import": { + "types": "./types/sourcemap-codec.d.mts", + "default": "./dist/sourcemap-codec.mjs" + }, + "default": { + "types": "./types/sourcemap-codec.d.cts", + "default": "./dist/sourcemap-codec.umd.js" + } + }, + "./dist/sourcemap-codec.umd.js" + ], + "./package.json": "./package.json" + }, + "scripts": { + "benchmark": "run-s build:code benchmark:*", + "benchmark:install": "cd benchmark && npm install", + "benchmark:only": "node --expose-gc benchmark/index.js", + "build": "run-s -n build:code build:types", + "build:code": "node ../../esbuild.mjs sourcemap-codec.ts", + "build:types": "run-s build:types:force build:types:emit build:types:mts", + "build:types:force": "rimraf tsconfig.build.tsbuildinfo", + "build:types:emit": "tsc --project tsconfig.build.json", + "build:types:mts": "node ../../mts-types.mjs", + "clean": "run-s -n clean:code clean:types", + "clean:code": "tsc --build --clean tsconfig.build.json", + "clean:types": "rimraf dist types", + "test": "run-s -n test:types test:only test:format", + "test:format": "prettier --check '{src,test}/**/*.ts'", + "test:only": "mocha", + "test:types": "eslint '{src,test}/**/*.ts'", + "lint": "run-s -n lint:types lint:format", + "lint:format": "npm run test:format -- --write", + "lint:types": "npm run test:types -- --fix", + "prepublishOnly": "npm run-s -n build test" + }, + "homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/sourcemap-codec", + "repository": { + "type": "git", + "url": "git+https://github.com/jridgewell/sourcemaps.git", + "directory": "packages/sourcemap-codec" + }, + "author": "Justin Ridgewell ", + "license": "MIT" +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts b/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts new file mode 100644 index 0000000000..d194c2f0a6 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts @@ -0,0 +1,345 @@ +import { StringReader, StringWriter } from './strings'; +import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq'; + +const EMPTY: any[] = []; + +type Line = number; +type Column = number; +type Kind = number; +type Name = number; +type Var = number; +type SourcesIndex = number; +type ScopesIndex = number; + +type Mix = (A & O) | (B & O); + +export type OriginalScope = Mix< + [Line, Column, Line, Column, Kind], + [Line, Column, Line, Column, Kind, Name], + { vars: Var[] } +>; + +export type GeneratedRange = Mix< + [Line, Column, Line, Column], + [Line, Column, Line, Column, SourcesIndex, ScopesIndex], + { + callsite: CallSite | null; + bindings: Binding[]; + isScope: boolean; + } +>; +export type CallSite = [SourcesIndex, Line, Column]; +type Binding = BindingExpressionRange[]; +export type BindingExpressionRange = [Name] | [Name, Line, Column]; + +export function decodeOriginalScopes(input: string): OriginalScope[] { + const { length } = input; + const reader = new StringReader(input); + const scopes: OriginalScope[] = []; + const stack: OriginalScope[] = []; + let line = 0; + + for (; reader.pos < length; reader.pos++) { + line = decodeInteger(reader, line); + const column = decodeInteger(reader, 0); + + if (!hasMoreVlq(reader, length)) { + const last = stack.pop()!; + last[2] = line; + last[3] = column; + continue; + } + + const kind = decodeInteger(reader, 0); + const fields = decodeInteger(reader, 0); + const hasName = fields & 0b0001; + + const scope: OriginalScope = ( + hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind] + ) as OriginalScope; + + let vars: Var[] = EMPTY; + if (hasMoreVlq(reader, length)) { + vars = []; + do { + const varsIndex = decodeInteger(reader, 0); + vars.push(varsIndex); + } while (hasMoreVlq(reader, length)); + } + scope.vars = vars; + + scopes.push(scope); + stack.push(scope); + } + + return scopes; +} + +export function encodeOriginalScopes(scopes: OriginalScope[]): string { + const writer = new StringWriter(); + + for (let i = 0; i < scopes.length; ) { + i = _encodeOriginalScopes(scopes, i, writer, [0]); + } + + return writer.flush(); +} + +function _encodeOriginalScopes( + scopes: OriginalScope[], + index: number, + writer: StringWriter, + state: [ + number, // GenColumn + ], +): number { + const scope = scopes[index]; + const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope; + + if (index > 0) writer.write(comma); + + state[0] = encodeInteger(writer, startLine, state[0]); + encodeInteger(writer, startColumn, 0); + encodeInteger(writer, kind, 0); + + const fields = scope.length === 6 ? 0b0001 : 0; + encodeInteger(writer, fields, 0); + if (scope.length === 6) encodeInteger(writer, scope[5], 0); + + for (const v of vars) { + encodeInteger(writer, v, 0); + } + + for (index++; index < scopes.length; ) { + const next = scopes[index]; + const { 0: l, 1: c } = next; + if (l > endLine || (l === endLine && c >= endColumn)) { + break; + } + index = _encodeOriginalScopes(scopes, index, writer, state); + } + + writer.write(comma); + state[0] = encodeInteger(writer, endLine, state[0]); + encodeInteger(writer, endColumn, 0); + + return index; +} + +export function decodeGeneratedRanges(input: string): GeneratedRange[] { + const { length } = input; + const reader = new StringReader(input); + const ranges: GeneratedRange[] = []; + const stack: GeneratedRange[] = []; + + let genLine = 0; + let definitionSourcesIndex = 0; + let definitionScopeIndex = 0; + let callsiteSourcesIndex = 0; + let callsiteLine = 0; + let callsiteColumn = 0; + let bindingLine = 0; + let bindingColumn = 0; + + do { + const semi = reader.indexOf(';'); + let genColumn = 0; + + for (; reader.pos < semi; reader.pos++) { + genColumn = decodeInteger(reader, genColumn); + + if (!hasMoreVlq(reader, semi)) { + const last = stack.pop()!; + last[2] = genLine; + last[3] = genColumn; + continue; + } + + const fields = decodeInteger(reader, 0); + const hasDefinition = fields & 0b0001; + const hasCallsite = fields & 0b0010; + const hasScope = fields & 0b0100; + + let callsite: CallSite | null = null; + let bindings: Binding[] = EMPTY; + let range: GeneratedRange; + if (hasDefinition) { + const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex); + definitionScopeIndex = decodeInteger( + reader, + definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0, + ); + + definitionSourcesIndex = defSourcesIndex; + range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex] as GeneratedRange; + } else { + range = [genLine, genColumn, 0, 0] as GeneratedRange; + } + + range.isScope = !!hasScope; + + if (hasCallsite) { + const prevCsi = callsiteSourcesIndex; + const prevLine = callsiteLine; + callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex); + const sameSource = prevCsi === callsiteSourcesIndex; + callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0); + callsiteColumn = decodeInteger( + reader, + sameSource && prevLine === callsiteLine ? callsiteColumn : 0, + ); + + callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn]; + } + range.callsite = callsite; + + if (hasMoreVlq(reader, semi)) { + bindings = []; + do { + bindingLine = genLine; + bindingColumn = genColumn; + const expressionsCount = decodeInteger(reader, 0); + let expressionRanges: BindingExpressionRange[]; + if (expressionsCount < -1) { + expressionRanges = [[decodeInteger(reader, 0)]]; + for (let i = -1; i > expressionsCount; i--) { + const prevBl = bindingLine; + bindingLine = decodeInteger(reader, bindingLine); + bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0); + const expression = decodeInteger(reader, 0); + expressionRanges.push([expression, bindingLine, bindingColumn]); + } + } else { + expressionRanges = [[expressionsCount]]; + } + bindings.push(expressionRanges); + } while (hasMoreVlq(reader, semi)); + } + range.bindings = bindings; + + ranges.push(range); + stack.push(range); + } + + genLine++; + reader.pos = semi + 1; + } while (reader.pos < length); + + return ranges; +} + +export function encodeGeneratedRanges(ranges: GeneratedRange[]): string { + if (ranges.length === 0) return ''; + + const writer = new StringWriter(); + + for (let i = 0; i < ranges.length; ) { + i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]); + } + + return writer.flush(); +} + +function _encodeGeneratedRanges( + ranges: GeneratedRange[], + index: number, + writer: StringWriter, + state: [ + number, // GenLine + number, // GenColumn + number, // DefSourcesIndex + number, // DefScopesIndex + number, // CallSourcesIndex + number, // CallLine + number, // CallColumn + ], +): number { + const range = ranges[index]; + const { + 0: startLine, + 1: startColumn, + 2: endLine, + 3: endColumn, + isScope, + callsite, + bindings, + } = range; + + if (state[0] < startLine) { + catchupLine(writer, state[0], startLine); + state[0] = startLine; + state[1] = 0; + } else if (index > 0) { + writer.write(comma); + } + + state[1] = encodeInteger(writer, range[1], state[1]); + + const fields = + (range.length === 6 ? 0b0001 : 0) | (callsite ? 0b0010 : 0) | (isScope ? 0b0100 : 0); + encodeInteger(writer, fields, 0); + + if (range.length === 6) { + const { 4: sourcesIndex, 5: scopesIndex } = range; + if (sourcesIndex !== state[2]) { + state[3] = 0; + } + state[2] = encodeInteger(writer, sourcesIndex, state[2]); + state[3] = encodeInteger(writer, scopesIndex, state[3]); + } + + if (callsite) { + const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite!; + if (sourcesIndex !== state[4]) { + state[5] = 0; + state[6] = 0; + } else if (callLine !== state[5]) { + state[6] = 0; + } + state[4] = encodeInteger(writer, sourcesIndex, state[4]); + state[5] = encodeInteger(writer, callLine, state[5]); + state[6] = encodeInteger(writer, callColumn, state[6]); + } + + if (bindings) { + for (const binding of bindings) { + if (binding.length > 1) encodeInteger(writer, -binding.length, 0); + const expression = binding[0][0]; + encodeInteger(writer, expression, 0); + let bindingStartLine = startLine; + let bindingStartColumn = startColumn; + for (let i = 1; i < binding.length; i++) { + const expRange = binding[i]; + bindingStartLine = encodeInteger(writer, expRange[1]!, bindingStartLine); + bindingStartColumn = encodeInteger(writer, expRange[2]!, bindingStartColumn); + encodeInteger(writer, expRange[0]!, 0); + } + } + } + + for (index++; index < ranges.length; ) { + const next = ranges[index]; + const { 0: l, 1: c } = next; + if (l > endLine || (l === endLine && c >= endColumn)) { + break; + } + index = _encodeGeneratedRanges(ranges, index, writer, state); + } + + if (state[0] < endLine) { + catchupLine(writer, state[0], endLine); + state[0] = endLine; + state[1] = 0; + } else { + writer.write(comma); + } + state[1] = encodeInteger(writer, endColumn, state[1]); + + return index; +} + +function catchupLine(writer: StringWriter, lastLine: number, line: number) { + do { + writer.write(semicolon); + } while (++lastLine < line); +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts b/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts new file mode 100644 index 0000000000..a81f894dc1 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts @@ -0,0 +1,111 @@ +import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq'; +import { StringWriter, StringReader } from './strings'; + +export { + decodeOriginalScopes, + encodeOriginalScopes, + decodeGeneratedRanges, + encodeGeneratedRanges, +} from './scopes'; +export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes'; + +export type SourceMapSegment = + | [number] + | [number, number, number, number] + | [number, number, number, number, number]; +export type SourceMapLine = SourceMapSegment[]; +export type SourceMapMappings = SourceMapLine[]; + +export function decode(mappings: string): SourceMapMappings { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded: SourceMapMappings = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + + do { + const semi = reader.indexOf(';'); + const line: SourceMapLine = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + + while (reader.pos < semi) { + let seg: SourceMapSegment; + + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) sorted = false; + lastCol = genColumn; + + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } else { + seg = [genColumn]; + } + + line.push(seg); + reader.pos++; + } + + if (!sorted) sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + + return decoded; +} + +function sort(line: SourceMapSegment[]) { + line.sort(sortComparator); +} + +function sortComparator(a: SourceMapSegment, b: SourceMapSegment): number { + return a[0] - b[0]; +} + +export function encode(decoded: SourceMapMappings): string; +export function encode(decoded: Readonly): string; +export function encode(decoded: Readonly): string { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + + let genColumn = 0; + + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + + genColumn = encodeInteger(writer, segment[0], genColumn); + + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + + return writer.flush(); +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/strings.ts b/node_modules/@jridgewell/sourcemap-codec/src/strings.ts new file mode 100644 index 0000000000..d1619650ea --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/strings.ts @@ -0,0 +1,65 @@ +const bufLength = 1024 * 16; + +// Provide a fallback for older environments. +const td = + typeof TextDecoder !== 'undefined' + ? /* #__PURE__ */ new TextDecoder() + : typeof Buffer !== 'undefined' + ? { + decode(buf: Uint8Array): string { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + }, + } + : { + decode(buf: Uint8Array): string { + let out = ''; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + }, + }; + +export class StringWriter { + pos = 0; + private out = ''; + private buffer = new Uint8Array(bufLength); + + write(v: number): void { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + + flush(): string { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } +} + +export class StringReader { + pos = 0; + declare private buffer: string; + + constructor(buffer: string) { + this.buffer = buffer; + } + + next(): number { + return this.buffer.charCodeAt(this.pos++); + } + + peek(): number { + return this.buffer.charCodeAt(this.pos); + } + + indexOf(char: string): number { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts b/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts new file mode 100644 index 0000000000..a42c681511 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts @@ -0,0 +1,55 @@ +import type { StringReader, StringWriter } from './strings'; + +export const comma = ','.charCodeAt(0); +export const semicolon = ';'.charCodeAt(0); + +const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +const intToChar = new Uint8Array(64); // 64 possible chars. +const charToInt = new Uint8Array(128); // z is 122 in ASCII + +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} + +export function decodeInteger(reader: StringReader, relative: number): number { + let value = 0; + let shift = 0; + let integer = 0; + + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + + const shouldNegate = value & 1; + value >>>= 1; + + if (shouldNegate) { + value = -0x80000000 | -value; + } + + return relative + value; +} + +export function encodeInteger(builder: StringWriter, num: number, relative: number): number { + let delta = num - relative; + + delta = delta < 0 ? (-delta << 1) | 1 : delta << 1; + do { + let clamped = delta & 0b011111; + delta >>>= 5; + if (delta > 0) clamped |= 0b100000; + builder.write(intToChar[clamped]); + } while (delta > 0); + + return num; +} + +export function hasMoreVlq(reader: StringReader, max: number) { + if (reader.pos >= max) return false; + return reader.peek() !== comma; +} diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts new file mode 100644 index 0000000000..c583c7560d --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts @@ -0,0 +1,50 @@ +type Line = number; +type Column = number; +type Kind = number; +type Name = number; +type Var = number; +type SourcesIndex = number; +type ScopesIndex = number; +type Mix = (A & O) | (B & O); +export type OriginalScope = Mix<[ + Line, + Column, + Line, + Column, + Kind +], [ + Line, + Column, + Line, + Column, + Kind, + Name +], { + vars: Var[]; +}>; +export type GeneratedRange = Mix<[ + Line, + Column, + Line, + Column +], [ + Line, + Column, + Line, + Column, + SourcesIndex, + ScopesIndex +], { + callsite: CallSite | null; + bindings: Binding[]; + isScope: boolean; +}>; +export type CallSite = [SourcesIndex, Line, Column]; +type Binding = BindingExpressionRange[]; +export type BindingExpressionRange = [Name] | [Name, Line, Column]; +export declare function decodeOriginalScopes(input: string): OriginalScope[]; +export declare function encodeOriginalScopes(scopes: OriginalScope[]): string; +export declare function decodeGeneratedRanges(input: string): GeneratedRange[]; +export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string; +export {}; +//# sourceMappingURL=scopes.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map new file mode 100644 index 0000000000..630e6477b7 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts new file mode 100644 index 0000000000..c583c7560d --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts @@ -0,0 +1,50 @@ +type Line = number; +type Column = number; +type Kind = number; +type Name = number; +type Var = number; +type SourcesIndex = number; +type ScopesIndex = number; +type Mix = (A & O) | (B & O); +export type OriginalScope = Mix<[ + Line, + Column, + Line, + Column, + Kind +], [ + Line, + Column, + Line, + Column, + Kind, + Name +], { + vars: Var[]; +}>; +export type GeneratedRange = Mix<[ + Line, + Column, + Line, + Column +], [ + Line, + Column, + Line, + Column, + SourcesIndex, + ScopesIndex +], { + callsite: CallSite | null; + bindings: Binding[]; + isScope: boolean; +}>; +export type CallSite = [SourcesIndex, Line, Column]; +type Binding = BindingExpressionRange[]; +export type BindingExpressionRange = [Name] | [Name, Line, Column]; +export declare function decodeOriginalScopes(input: string): OriginalScope[]; +export declare function encodeOriginalScopes(scopes: OriginalScope[]): string; +export declare function decodeGeneratedRanges(input: string): GeneratedRange[]; +export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string; +export {}; +//# sourceMappingURL=scopes.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map new file mode 100644 index 0000000000..630e6477b7 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts new file mode 100644 index 0000000000..5f35e22fbd --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts @@ -0,0 +1,9 @@ +export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.cts'; +export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.cts'; +export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number]; +export type SourceMapLine = SourceMapSegment[]; +export type SourceMapMappings = SourceMapLine[]; +export declare function decode(mappings: string): SourceMapMappings; +export declare function encode(decoded: SourceMapMappings): string; +export declare function encode(decoded: Readonly): string; +//# sourceMappingURL=sourcemap-codec.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map new file mode 100644 index 0000000000..7123d52083 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts new file mode 100644 index 0000000000..199fb9f534 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts @@ -0,0 +1,9 @@ +export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.mts'; +export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.mts'; +export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number]; +export type SourceMapLine = SourceMapSegment[]; +export type SourceMapMappings = SourceMapLine[]; +export declare function decode(mappings: string): SourceMapMappings; +export declare function encode(decoded: SourceMapMappings): string; +export declare function encode(decoded: Readonly): string; +//# sourceMappingURL=sourcemap-codec.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map new file mode 100644 index 0000000000..7123d52083 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts new file mode 100644 index 0000000000..62faceb3de --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts @@ -0,0 +1,16 @@ +export declare class StringWriter { + pos: number; + private out; + private buffer; + write(v: number): void; + flush(): string; +} +export declare class StringReader { + pos: number; + private buffer; + constructor(buffer: string); + next(): number; + peek(): number; + indexOf(char: string): number; +} +//# sourceMappingURL=strings.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map new file mode 100644 index 0000000000..d3602da425 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAuBA,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA6B;IAE3C,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAStB,KAAK,IAAI,MAAM;CAIhB;AAED,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,QAAgB,MAAM,CAAS;gBAEnB,MAAM,EAAE,MAAM;IAI1B,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAK9B"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts new file mode 100644 index 0000000000..62faceb3de --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts @@ -0,0 +1,16 @@ +export declare class StringWriter { + pos: number; + private out; + private buffer; + write(v: number): void; + flush(): string; +} +export declare class StringReader { + pos: number; + private buffer; + constructor(buffer: string); + next(): number; + peek(): number; + indexOf(char: string): number; +} +//# sourceMappingURL=strings.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map new file mode 100644 index 0000000000..d3602da425 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAuBA,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA6B;IAE3C,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAStB,KAAK,IAAI,MAAM;CAIhB;AAED,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,QAAgB,MAAM,CAAS;gBAEnB,MAAM,EAAE,MAAM;IAI1B,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAK9B"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts new file mode 100644 index 0000000000..dbd6602d18 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts @@ -0,0 +1,7 @@ +import type { StringReader, StringWriter } from './strings.cts'; +export declare const comma: number; +export declare const semicolon: number; +export declare function decodeInteger(reader: StringReader, relative: number): number; +export declare function encodeInteger(builder: StringWriter, num: number, relative: number): number; +export declare function hasMoreVlq(reader: StringReader, max: number): boolean; +//# sourceMappingURL=vlq.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map new file mode 100644 index 0000000000..6fdc356977 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"vlq.d.ts","sourceRoot":"","sources":["../src/vlq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,KAAK,QAAoB,CAAC;AACvC,eAAO,MAAM,SAAS,QAAoB,CAAC;AAY3C,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY1F;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,WAG3D"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts new file mode 100644 index 0000000000..2c739bc9fe --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts @@ -0,0 +1,7 @@ +import type { StringReader, StringWriter } from './strings.mts'; +export declare const comma: number; +export declare const semicolon: number; +export declare function decodeInteger(reader: StringReader, relative: number): number; +export declare function encodeInteger(builder: StringWriter, num: number, relative: number): number; +export declare function hasMoreVlq(reader: StringReader, max: number): boolean; +//# sourceMappingURL=vlq.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map new file mode 100644 index 0000000000..6fdc356977 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"vlq.d.ts","sourceRoot":"","sources":["../src/vlq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,KAAK,QAAoB,CAAC;AACvC,eAAO,MAAM,SAAS,QAAoB,CAAC;AAY3C,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY1F;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,WAG3D"} \ No newline at end of file diff --git a/node_modules/@rollup/rollup-linux-x64-gnu/README.md b/node_modules/@rollup/rollup-linux-x64-gnu/README.md new file mode 100644 index 0000000000..cabe280f1a --- /dev/null +++ b/node_modules/@rollup/rollup-linux-x64-gnu/README.md @@ -0,0 +1,3 @@ +# `@rollup/rollup-linux-x64-gnu` + +This is the **x86_64-unknown-linux-gnu** binary for `rollup` diff --git a/node_modules/@rollup/rollup-linux-x64-gnu/package.json b/node_modules/@rollup/rollup-linux-x64-gnu/package.json new file mode 100644 index 0000000000..06155fd032 --- /dev/null +++ b/node_modules/@rollup/rollup-linux-x64-gnu/package.json @@ -0,0 +1,22 @@ +{ + "name": "@rollup/rollup-linux-x64-gnu", + "version": "4.49.0", + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "files": [ + "rollup.linux-x64-gnu.node" + ], + "description": "Native bindings for Rollup", + "author": "Lukas Taegert-Atkinson", + "homepage": "https://rollupjs.org/", + "license": "MIT", + "repository": "rollup/rollup", + "libc": [ + "glibc" + ], + "main": "./rollup.linux-x64-gnu.node" +} \ No newline at end of file diff --git a/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node b/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node new file mode 100644 index 0000000000..6b3249b74e Binary files /dev/null and b/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node differ diff --git a/node_modules/@types/chai/LICENSE b/node_modules/@types/chai/LICENSE new file mode 100644 index 0000000000..9e841e7a26 --- /dev/null +++ b/node_modules/@types/chai/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/node_modules/@types/chai/README.md b/node_modules/@types/chai/README.md new file mode 100644 index 0000000000..11378aaba6 --- /dev/null +++ b/node_modules/@types/chai/README.md @@ -0,0 +1,15 @@ +# Installation +> `npm install --save @types/chai` + +# Summary +This package contains type definitions for chai (http://chaijs.com/). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/chai. + +### Additional Details + * Last updated: Mon, 05 May 2025 21:33:58 GMT + * Dependencies: [@types/deep-eql](https://npmjs.com/package/@types/deep-eql) + +# Credits +These definitions were written by [Bart van der Schoor](https://github.com/Bartvds), [Andrew Brown](https://github.com/AGBrown), [Olivier Chevet](https://github.com/olivr70), [Matt Wistrand](https://github.com/mwistrand), [Shaun Luttin](https://github.com/shaunluttin), [Satana Charuwichitratana](https://github.com/micksatana), [Erik Schierboom](https://github.com/ErikSchierboom), [Bogdan Paranytsia](https://github.com/bparan), [CXuesong](https://github.com/CXuesong), and [Joey Kilpatrick](https://github.com/joeykilpatrick). diff --git a/node_modules/@types/chai/index.d.ts b/node_modules/@types/chai/index.d.ts new file mode 100644 index 0000000000..67b59e26c3 --- /dev/null +++ b/node_modules/@types/chai/index.d.ts @@ -0,0 +1,2149 @@ +import deepEqual = require("deep-eql"); + +declare global { + namespace Chai { + type Message = string | (() => string); + type ObjectProperty = string | symbol | number; + + interface PathInfo { + parent: object; + name: string; + value?: any; + exists: boolean; + } + + interface Constructor { + new(...args: any[]): T; + } + + interface ErrorConstructor { + new(...args: any[]): Error; + } + + interface ChaiUtils { + addChainableMethod( + // object to define the method on, e.g. chai.Assertion.prototype + ctx: object, + // method name + name: string, + // method itself; any arguments + method: (...args: any[]) => void, + // called when property is accessed + chainingBehavior?: () => void, + ): void; + overwriteChainableMethod( + ctx: object, + name: string, + method: (...args: any[]) => void, + chainingBehavior?: () => void, + ): void; + addLengthGuard( + fn: Function, + assertionName: string, + isChainable: boolean, + ): void; + addMethod(ctx: object, name: string, method: Function): void; + addProperty(ctx: object, name: string, getter: () => any): void; + overwriteMethod(ctx: object, name: string, method: Function): void; + overwriteProperty(ctx: object, name: string, getter: (this: AssertionStatic, _super: any) => any): void; + compareByInspect(a: object, b: object): -1 | 1; + expectTypes(obj: object, types: string[]): void; + flag(obj: object, key: string, value?: any): any; + getActual(obj: object, args: AssertionArgs): any; + getProperties(obj: object): string[]; + getEnumerableProperties(obj: object): string[]; + getOwnEnumerablePropertySymbols(obj: object): symbol[]; + getOwnEnumerableProperties(obj: object): Array; + getMessage(errorLike: Error | string): string; + getMessage(obj: any, args: AssertionArgs): string; + inspect(obj: any, showHidden?: boolean, depth?: number, colors?: boolean): string; + isProxyEnabled(): boolean; + objDisplay(obj: object): void; + proxify(obj: object, nonChainableMethodName: string): object; + test(obj: object, args: AssertionArgs): boolean; + transferFlags(assertion: Assertion, obj: object, includeAll?: boolean): void; + compatibleInstance(thrown: Error, errorLike: Error | ErrorConstructor): boolean; + compatibleConstructor(thrown: Error, errorLike: Error | ErrorConstructor): boolean; + compatibleMessage(thrown: Error, errMatcher: string | RegExp): boolean; + getConstructorName(constructorFn: Function): string; + getFuncName(constructorFn: Function): string | null; + + // Reexports from pathval: + hasProperty(obj: object | undefined | null, name: ObjectProperty): boolean; + getPathInfo(obj: object, path: string): PathInfo; + getPathValue(obj: object, path: string): object | undefined; + + eql: typeof deepEqual; + } + + type ChaiPlugin = (chai: ChaiStatic, utils: ChaiUtils) => void; + + interface ChaiStatic { + expect: ExpectStatic; + should(): Should; + /** + * Provides a way to extend the internals of Chai + */ + use(fn: ChaiPlugin): ChaiStatic; + util: ChaiUtils; + assert: AssertStatic; + config: Config; + Assertion: AssertionStatic; + AssertionError: typeof AssertionError; + version: string; + } + + export interface ExpectStatic { + (val: any, message?: string): Assertion; + fail(message?: string): never; + fail(actual: any, expected: any, message?: string, operator?: Operator): never; + } + + export interface AssertStatic extends Assert { + } + + // chai.Assertion.prototype.assert arguments + type AssertionArgs = [ + any, // expression to be tested + Message, // message or function that returns message to display if expression fails + Message, // negatedMessage or function that returns negatedMessage to display if expression fails + any?, // expected value + any?, // actual value + boolean?, // showDiff, when set to `true`, assert will display a diff in addition to the message if expression fails + ]; + + export interface AssertionPrototype { + assert(...args: AssertionArgs): void; + _obj: any; + } + + export interface AssertionStatic extends AssertionPrototype { + prototype: AssertionPrototype; + + new(target: any, message?: string, ssfi?: Function, lockSsfi?: boolean): Assertion; + + // Deprecated properties: + includeStack: boolean; + showDiff: boolean; + + // Partials of functions on ChaiUtils: + addProperty(name: string, getter: (this: AssertionStatic) => any): void; + addMethod(name: string, method: (this: AssertionStatic, ...args: any[]) => any): void; + addChainableMethod( + name: string, + method: (this: AssertionStatic, ...args: any[]) => void, + chainingBehavior?: () => void, + ): void; + overwriteProperty(name: string, getter: (this: AssertionStatic, _super: any) => any): void; + overwriteMethod(name: string, method: (this: AssertionStatic, ...args: any[]) => any): void; + overwriteChainableMethod( + name: string, + method: (this: AssertionStatic, ...args: any[]) => void, + chainingBehavior?: () => void, + ): void; + } + + export type Operator = string; // "==" | "===" | ">" | ">=" | "<" | "<=" | "!=" | "!=="; + + export type OperatorComparable = boolean | null | number | string | undefined | Date; + + interface ShouldAssertion { + equal(value1: any, value2: any, message?: string): void; + Throw: ShouldThrow; + throw: ShouldThrow; + exist(value: any, message?: string): void; + } + + interface Should extends ShouldAssertion { + not: ShouldAssertion; + fail(message?: string): never; + fail(actual: any, expected: any, message?: string, operator?: Operator): never; + } + + interface ShouldThrow { + (actual: Function, expected?: string | RegExp, message?: string): void; + (actual: Function, constructor: Error | Function, expected?: string | RegExp, message?: string): void; + } + + interface Assertion extends LanguageChains, NumericComparison, TypeComparison { + not: Assertion; + deep: Deep; + ordered: Ordered; + nested: Nested; + own: Own; + any: KeyFilter; + all: KeyFilter; + a: Assertion; + an: Assertion; + include: Include; + includes: Include; + contain: Include; + contains: Include; + ok: Assertion; + true: Assertion; + false: Assertion; + null: Assertion; + undefined: Assertion; + NaN: Assertion; + exist: Assertion; + empty: Assertion; + arguments: Assertion; + Arguments: Assertion; + finite: Assertion; + equal: Equal; + equals: Equal; + eq: Equal; + eql: Equal; + eqls: Equal; + containSubset: ContainSubset; + property: Property; + ownProperty: Property; + haveOwnProperty: Property; + ownPropertyDescriptor: OwnPropertyDescriptor; + haveOwnPropertyDescriptor: OwnPropertyDescriptor; + length: Length; + lengthOf: Length; + match: Match; + matches: Match; + string(string: string, message?: string): Assertion; + keys: Keys; + key(string: string): Assertion; + throw: Throw; + throws: Throw; + Throw: Throw; + respondTo: RespondTo; + respondsTo: RespondTo; + itself: Assertion; + satisfy: Satisfy; + satisfies: Satisfy; + closeTo: CloseTo; + approximately: CloseTo; + members: Members; + increase: PropertyChange; + increases: PropertyChange; + decrease: PropertyChange; + decreases: PropertyChange; + change: PropertyChange; + changes: PropertyChange; + extensible: Assertion; + sealed: Assertion; + frozen: Assertion; + oneOf: OneOf; + } + + interface LanguageChains { + to: Assertion; + be: Assertion; + been: Assertion; + is: Assertion; + that: Assertion; + which: Assertion; + and: Assertion; + has: Assertion; + have: Assertion; + with: Assertion; + at: Assertion; + of: Assertion; + same: Assertion; + but: Assertion; + does: Assertion; + } + + interface NumericComparison { + above: NumberComparer; + gt: NumberComparer; + greaterThan: NumberComparer; + least: NumberComparer; + gte: NumberComparer; + greaterThanOrEqual: NumberComparer; + below: NumberComparer; + lt: NumberComparer; + lessThan: NumberComparer; + most: NumberComparer; + lte: NumberComparer; + lessThanOrEqual: NumberComparer; + within(start: number, finish: number, message?: string): Assertion; + within(start: Date, finish: Date, message?: string): Assertion; + } + + interface NumberComparer { + (value: number | Date, message?: string): Assertion; + } + + interface TypeComparison { + (type: string, message?: string): Assertion; + instanceof: InstanceOf; + instanceOf: InstanceOf; + } + + interface InstanceOf { + (constructor: any, message?: string): Assertion; + } + + interface CloseTo { + (expected: number, delta: number, message?: string): Assertion; + } + + interface Nested { + include: Include; + includes: Include; + contain: Include; + contains: Include; + property: Property; + members: Members; + } + + interface Own { + include: Include; + includes: Include; + contain: Include; + contains: Include; + property: Property; + } + + interface Deep extends KeyFilter { + be: Assertion; + equal: Equal; + equals: Equal; + eq: Equal; + include: Include; + includes: Include; + contain: Include; + contains: Include; + property: Property; + ordered: Ordered; + nested: Nested; + oneOf: OneOf; + own: Own; + } + + interface Ordered { + members: Members; + } + + interface KeyFilter { + keys: Keys; + members: Members; + } + + interface Equal { + (value: any, message?: string): Assertion; + } + + interface ContainSubset { + (expected: any): Assertion; + } + + interface Property { + (name: string | symbol, value: any, message?: string): Assertion; + (name: string | symbol, message?: string): Assertion; + } + + interface OwnPropertyDescriptor { + (name: string | symbol, descriptor: PropertyDescriptor, message?: string): Assertion; + (name: string | symbol, message?: string): Assertion; + } + + interface Length extends LanguageChains, NumericComparison { + (length: number, message?: string): Assertion; + } + + interface Include { + (value: any, message?: string): Assertion; + keys: Keys; + deep: Deep; + ordered: Ordered; + members: Members; + any: KeyFilter; + all: KeyFilter; + oneOf: OneOf; + } + + interface OneOf { + (list: readonly unknown[], message?: string): Assertion; + } + + interface Match { + (regexp: RegExp, message?: string): Assertion; + } + + interface Keys { + (...keys: string[]): Assertion; + (keys: readonly any[] | Object): Assertion; + } + + interface Throw { + (expected?: string | RegExp, message?: string): Assertion; + (constructor: Error | Function, expected?: string | RegExp, message?: string): Assertion; + } + + interface RespondTo { + (method: string, message?: string): Assertion; + } + + interface Satisfy { + (matcher: Function, message?: string): Assertion; + } + + interface Members { + (set: readonly any[], message?: string): Assertion; + } + + interface PropertyChange { + (object: Object, property?: string, message?: string): DeltaAssertion; + } + + interface DeltaAssertion extends Assertion { + by(delta: number, msg?: string): Assertion; + } + + export interface Assert { + /** + * @param expression Expression to test for truthiness. + * @param message Message to display on error. + */ + (expression: any, message?: string): asserts expression; + + /** + * Throws a failure. + * + * @param message Message to display on error. + * @remarks Node.js assert module-compatible. + */ + fail(message?: string): never; + + /** + * Throws a failure. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + * @param operator Comparison operator, if not strict equality. + * @remarks Node.js assert module-compatible. + */ + fail(actual: T, expected: T, message?: string, operator?: Operator): never; + + /** + * Asserts that object is truthy. + * + * @param object Object to test. + * @param message Message to display on error. + */ + isOk(value: unknown, message?: string): asserts value; + + /** + * Asserts that object is truthy. + * + * @param object Object to test. + * @param message Message to display on error. + */ + ok(value: unknown, message?: string): asserts value; + + /** + * Asserts that object is falsy. + * + * T Type of object. + * @param object Object to test. + * @param message Message to display on error. + */ + isNotOk(value: T, message?: string): void; + + /** + * Asserts that object is falsy. + * + * T Type of object. + * @param object Object to test. + * @param message Message to display on error. + */ + notOk(value: T, message?: string): void; + + /** + * Asserts non-strict equality (==) of actual and expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + equal(actual: T, expected: T, message?: string): void; + + /** + * Asserts non-strict inequality (!=) of actual and expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + notEqual(actual: T, expected: T, message?: string): void; + + /** + * Asserts strict equality (===) of actual and expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + strictEqual(actual: T, expected: T, message?: string): void; + + /** + * Asserts strict inequality (!==) of actual and expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + notStrictEqual(actual: T, expected: T, message?: string): void; + + /** + * Asserts that actual is deeply equal to expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + deepEqual(actual: T, expected: T, message?: string): void; + + /** + * Asserts that actual is not deeply equal to expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + notDeepEqual(actual: T, expected: T, message?: string): void; + + /** + * Alias to deepEqual + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + deepStrictEqual(actual: T, expected: T, message?: string): void; + + /** + * Partially matches actual and expected. + * + * @param actual Actual value. + * @param expected Potential subset of the value. + * @param message Message to display on error. + */ + containSubset(val: any, exp: any, msg?: string): void; + + /** + * Partially matches actual and expected. + * + * @param actual Actual value. + * @param expected Potential subset of the value. + * @param message Message to display on error. + */ + containsSubset(val: any, exp: any, msg?: string): void; + + /** + * No partial match between actual and expected exists. + * + * @param actual Actual value. + * @param expected Potential subset of the value. + * @param message Message to display on error. + */ + doesNotContainSubset(val: any, exp: any, msg?: string): void; + + /** + * Asserts valueToCheck is strictly greater than (>) valueToBeAbove. + * + * @param valueToCheck Actual value. + * @param valueToBeAbove Minimum Potential expected value. + * @param message Message to display on error. + */ + isAbove(valueToCheck: number, valueToBeAbove: number, message?: string): void; + + /** + * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtLeast. + * + * @param valueToCheck Actual value. + * @param valueToBeAtLeast Minimum Potential expected value. + * @param message Message to display on error. + */ + isAtLeast(valueToCheck: number, valueToBeAtLeast: number, message?: string): void; + + /** + * Asserts valueToCheck is strictly less than (<) valueToBeBelow. + * + * @param valueToCheck Actual value. + * @param valueToBeBelow Minimum Potential expected value. + * @param message Message to display on error. + */ + isBelow(valueToCheck: number, valueToBeBelow: number, message?: string): void; + + /** + * Asserts valueToCheck is less than or equal to (<=) valueToBeAtMost. + * + * @param valueToCheck Actual value. + * @param valueToBeAtMost Minimum Potential expected value. + * @param message Message to display on error. + */ + isAtMost(valueToCheck: number, valueToBeAtMost: number, message?: string): void; + + /** + * Asserts that value is true. + * + * @param value Actual value. + * @param message Message to display on error. + */ + isTrue(value: unknown, message?: string): asserts value is true; + + /** + * Asserts that value is false. + * + * @param value Actual value. + * @param message Message to display on error. + */ + isFalse(value: unknown, message?: string): asserts value is false; + + /** + * Asserts that value is not true. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotTrue(value: T, message?: string): asserts value is Exclude; + + /** + * Asserts that value is not false. + * + * @param value Actual value. + * @param message Message to display on error. + */ + isNotFalse(value: T, message?: string): asserts value is Exclude; + + /** + * Asserts that value is null. + * + * @param value Actual value. + * @param message Message to display on error. + */ + isNull(value: unknown, message?: string): asserts value is null; + + /** + * Asserts that value is not null. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotNull(value: T, message?: string): asserts value is Exclude; + + /** + * Asserts that value is NaN. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNaN(value: T, message?: string): void; + + /** + * Asserts that value is not NaN. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotNaN(value: T, message?: string): void; + + /** + * Asserts that the target is neither null nor undefined. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + exists(value: T, message?: string): asserts value is NonNullable; + + /** + * Asserts that the target is either null or undefined. + * + * @param value Actual value. + * @param message Message to display on error. + */ + notExists(value: unknown, message?: string): asserts value is + | null + | undefined; + + /** + * Asserts that value is undefined. + * + * @param value Actual value. + * @param message Message to display on error. + */ + isUndefined(value: unknown, message?: string): asserts value is undefined; + + /** + * Asserts that value is not undefined. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isDefined(value: T, message?: string): asserts value is Exclude; + + /** + * Asserts that value is a function. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isFunction(value: T, message?: string): void; + + /** + * Asserts that value is not a function. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotFunction(value: T, message?: string): void; + + /** + * Asserts that value is an object of type 'Object' + * (as revealed by Object.prototype.toString). + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + * @remarks The assertion does not match subclassed objects. + */ + isObject(value: T, message?: string): void; + + /** + * Asserts that value is not an object of type 'Object' + * (as revealed by Object.prototype.toString). + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotObject(value: T, message?: string): void; + + /** + * Asserts that value is an array. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isArray(value: T, message?: string): void; + + /** + * Asserts that value is not an array. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotArray(value: T, message?: string): void; + + /** + * Asserts that value is a string. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isString(value: T, message?: string): void; + + /** + * Asserts that value is not a string. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotString(value: T, message?: string): void; + + /** + * Asserts that value is a number. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNumber(value: T, message?: string): void; + + /** + * Asserts that value is not a number. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotNumber(value: T, message?: string): void; + + /** + * Asserts that value is a finite number. + * Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. + * + * T Type of value + * @param value Actual value + * @param message Message to display on error. + */ + isFinite(value: T, message?: string): void; + + /** + * Asserts that value is a boolean. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isBoolean(value: T, message?: string): void; + + /** + * Asserts that value is not a boolean. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotBoolean(value: T, message?: string): void; + + /** + * Asserts that value's type is name, as determined by Object.prototype.toString. + * + * T Type of value. + * @param value Actual value. + * @param name Potential expected type name of value. + * @param message Message to display on error. + */ + typeOf(value: T, name: string, message?: string): void; + + /** + * Asserts that value's type is not name, as determined by Object.prototype.toString. + * + * T Type of value. + * @param value Actual value. + * @param name Potential expected type name of value. + * @param message Message to display on error. + */ + notTypeOf(value: T, name: string, message?: string): void; + + /** + * Asserts that value is an instance of constructor. + * + * T Expected type of value. + * @param value Actual value. + * @param constructor Potential expected contructor of value. + * @param message Message to display on error. + */ + instanceOf( + value: unknown, + constructor: Constructor, + message?: string, + ): asserts value is T; + + /** + * Asserts that value is not an instance of constructor. + * + * T Type of value. + * U Type that value shouldn't be an instance of. + * @param value Actual value. + * @param constructor Potential expected contructor of value. + * @param message Message to display on error. + */ + notInstanceOf(value: T, type: Constructor, message?: string): asserts value is Exclude; + + /** + * Asserts that haystack includes needle. + * + * @param haystack Container string. + * @param needle Potential substring of haystack. + * @param message Message to display on error. + */ + include(haystack: string, needle: string, message?: string): void; + + /** + * Asserts that haystack includes needle. + * + * T Type of values in haystack. + * @param haystack Container array, set or map. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + include( + haystack: readonly T[] | ReadonlySet | ReadonlyMap, + needle: T, + message?: string, + ): void; + + /** + * Asserts that haystack includes needle. + * + * T Type of values in haystack. + * @param haystack WeakSet container. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + include(haystack: WeakSet, needle: T, message?: string): void; + + /** + * Asserts that haystack includes needle. + * + * T Type of haystack. + * @param haystack Object. + * @param needle Potential subset of the haystack's properties. + * @param message Message to display on error. + */ + include(haystack: T, needle: Partial, message?: string): void; + + /** + * Asserts that haystack does not include needle. + * + * @param haystack Container string. + * @param needle Potential substring of haystack. + * @param message Message to display on error. + */ + notInclude(haystack: string, needle: string, message?: string): void; + + /** + * Asserts that haystack does not include needle. + * + * T Type of values in haystack. + * @param haystack Container array, set or map. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + notInclude( + haystack: readonly T[] | ReadonlySet | ReadonlyMap, + needle: T, + message?: string, + ): void; + + /** + * Asserts that haystack does not include needle. + * + * T Type of values in haystack. + * @param haystack WeakSet container. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + notInclude(haystack: WeakSet, needle: T, message?: string): void; + + /** + * Asserts that haystack does not include needle. + * + * T Type of haystack. + * @param haystack Object. + * @param needle Potential subset of the haystack's properties. + * @param message Message to display on error. + */ + notInclude(haystack: T, needle: Partial, message?: string): void; + + /** + * Asserts that haystack includes needle. Deep equality is used. + * + * @param haystack Container string. + * @param needle Potential substring of haystack. + * @param message Message to display on error. + * + * @deprecated Does not have any effect on string. Use {@link Assert#include} instead. + */ + deepInclude(haystack: string, needle: string, message?: string): void; + + /** + * Asserts that haystack includes needle. Deep equality is used. + * + * T Type of values in haystack. + * @param haystack Container array, set or map. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + deepInclude( + haystack: readonly T[] | ReadonlySet | ReadonlyMap, + needle: T, + message?: string, + ): void; + + /** + * Asserts that haystack includes needle. Deep equality is used. + * + * T Type of haystack. + * @param haystack Object. + * @param needle Potential subset of the haystack's properties. + * @param message Message to display on error. + */ + deepInclude(haystack: T, needle: T extends WeakSet ? never : Partial, message?: string): void; + + /** + * Asserts that haystack does not include needle. Deep equality is used. + * + * @param haystack Container string. + * @param needle Potential substring of haystack. + * @param message Message to display on error. + * + * @deprecated Does not have any effect on string. Use {@link Assert#notInclude} instead. + */ + notDeepInclude(haystack: string, needle: string, message?: string): void; + + /** + * Asserts that haystack does not include needle. Deep equality is used. + * + * T Type of values in haystack. + * @param haystack Container array, set or map. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + notDeepInclude( + haystack: readonly T[] | ReadonlySet | ReadonlyMap, + needle: T, + message?: string, + ): void; + + /** + * Asserts that haystack does not include needle. Deep equality is used. + * + * T Type of haystack. + * @param haystack Object. + * @param needle Potential subset of the haystack's properties. + * @param message Message to display on error. + */ + notDeepInclude(haystack: T, needle: T extends WeakSet ? never : Partial, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the inclusion of a subset of properties in an object. + * + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes.Asserts that ‘haystack’ includes ‘needle’. + * Can be used to assert the inclusion of a subset of properties in an object. + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + nestedInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ does not include ‘needle’. Can be used to assert the absence of a subset of properties in an object. + * + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes.Asserts that ‘haystack’ includes ‘needle’. + * Can be used to assert the inclusion of a subset of properties in an object. + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + notNestedInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the inclusion of a subset of properties in an object while checking for deep equality + * + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes.Asserts that ‘haystack’ includes ‘needle’. + * Can be used to assert the inclusion of a subset of properties in an object. + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + deepNestedInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ does not include ‘needle’. Can be used to assert the absence of a subset of properties in an object while checking for deep equality. + * + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes.Asserts that ‘haystack’ includes ‘needle’. + * Can be used to assert the inclusion of a subset of properties in an object. + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + notDeepNestedInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the inclusion of a subset of properties in an object while ignoring inherited properties. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + ownInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the absence of a subset of properties in an object while ignoring inherited properties. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + notOwnInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the inclusion of a subset of properties in an object while ignoring inherited properties and checking for deep + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + deepOwnInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the absence of a subset of properties in an object while ignoring inherited properties and checking for deep equality. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + notDeepOwnInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that value matches the regular expression regexp. + * + * @param value Actual value. + * @param regexp Potential match of value. + * @param message Message to display on error. + */ + match(value: string, regexp: RegExp, message?: string): void; + + /** + * Asserts that value does not match the regular expression regexp. + * + * @param value Actual value. + * @param regexp Potential match of value. + * @param message Message to display on error. + */ + notMatch(expected: any, regexp: RegExp, message?: string): void; + + /** + * Asserts that object has a property named by property. + * + * T Type of object. + * @param object Container object. + * @param property Potential contained property of object. + * @param message Message to display on error. + */ + property(object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that object does not have a property named by property. + * + * T Type of object. + * @param object Container object. + * @param property Potential contained property of object. + * @param message Message to display on error. + */ + notProperty(object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that object has a property named by property, which can be a string + * using dot- and bracket-notation for deep reference. + * + * T Type of object. + * @param object Container object. + * @param property Potential contained property of object. + * @param message Message to display on error. + */ + deepProperty(object: T, property: string, message?: string): void; + + /** + * Asserts that object does not have a property named by property, which can be a + * string using dot- and bracket-notation for deep reference. + * + * T Type of object. + * @param object Container object. + * @param property Potential contained property of object. + * @param message Message to display on error. + */ + notDeepProperty(object: T, property: string, message?: string): void; + + /** + * Asserts that object has a property named by property with value given by value. + * + * T Type of object. + * V Type of value. + * @param object Container object. + * @param property Potential contained property of object. + * @param value Potential expected property value. + * @param message Message to display on error. + */ + propertyVal(object: T, property: string, /* keyof T */ value: V, message?: string): void; + + /** + * Asserts that object has a property named by property with value given by value. + * + * T Type of object. + * V Type of value. + * @param object Container object. + * @param property Potential contained property of object. + * @param value Potential expected property value. + * @param message Message to display on error. + */ + notPropertyVal(object: T, property: string, /* keyof T */ value: V, message?: string): void; + + /** + * Asserts that object has a property named by property, which can be a string + * using dot- and bracket-notation for deep reference. + * + * T Type of object. + * V Type of value. + * @param object Container object. + * @param property Potential contained property of object. + * @param value Potential expected property value. + * @param message Message to display on error. + */ + deepPropertyVal(object: T, property: string, value: V, message?: string): void; + + /** + * Asserts that object does not have a property named by property, which can be a + * string using dot- and bracket-notation for deep reference. + * + * T Type of object. + * V Type of value. + * @param object Container object. + * @param property Potential contained property of object. + * @param value Potential expected property value. + * @param message Message to display on error. + */ + notDeepPropertyVal(object: T, property: string, value: V, message?: string): void; + + /** + * Asserts that object has a length property with the expected value. + * + * T Type of object. + * @param object Container object. + * @param length Potential expected length of object. + * @param message Message to display on error. + */ + lengthOf( + object: T, + length: number, + message?: string, + ): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errMsgMatcher Expected error message matcher. + * @param ignored Ignored parameter. + * @param message Message to display on error. + */ + throw(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errorLike Expected error constructor or error instance. + * @param errMsgMatcher Expected error message matcher. + * @param message Message to display on error. + */ + throw( + fn: () => void, + errorLike?: ErrorConstructor | Error | null, + errMsgMatcher?: RegExp | string | null, + message?: string, + ): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errMsgMatcher Expected error message matcher. + * @param ignored Ignored parameter. + * @param message Message to display on error. + */ + throws(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errorLike Expected error constructor or error instance. + * @param errMsgMatcher Expected error message matcher. + * @param message Message to display on error. + */ + throws( + fn: () => void, + errorLike?: ErrorConstructor | Error | null, + errMsgMatcher?: RegExp | string | null, + message?: string, + ): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errMsgMatcher Expected error message matcher. + * @param ignored Ignored parameter. + * @param message Message to display on error. + */ + Throw(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errorLike Expected error constructor or error instance. + * @param errMsgMatcher Expected error message matcher. + * @param message Message to display on error. + */ + Throw( + fn: () => void, + errorLike?: ErrorConstructor | Error | null, + errMsgMatcher?: RegExp | string | null, + message?: string, + ): void; + + /** + * Asserts that fn will not throw an error. + * + * @param fn Function that may throw. + * @param errMsgMatcher Expected error message matcher. + * @param ignored Ignored parameter. + * @param message Message to display on error. + */ + doesNotThrow(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void; + + /** + * Asserts that fn will not throw an error. + * + * @param fn Function that may throw. + * @param errorLike Expected error constructor or error instance. + * @param errMsgMatcher Expected error message matcher. + * @param message Message to display on error. + */ + doesNotThrow( + fn: () => void, + errorLike?: ErrorConstructor | Error | null, + errMsgMatcher?: RegExp | string | null, + message?: string, + ): void; + + /** + * Compares two values using operator. + * + * @param val1 Left value during comparison. + * @param operator Comparison operator. + * @param val2 Right value during comparison. + * @param message Message to display on error. + */ + operator(val1: OperatorComparable, operator: Operator, val2: OperatorComparable, message?: string): void; + + /** + * Asserts that the target is equal to expected, to within a +/- delta range. + * + * @param actual Actual value + * @param expected Potential expected value. + * @param delta Maximum differenced between values. + * @param message Message to display on error. + */ + closeTo(actual: number, expected: number, delta: number, message?: string): void; + + /** + * Asserts that the target is equal to expected, to within a +/- delta range. + * + * @param actual Actual value + * @param expected Potential expected value. + * @param delta Maximum differenced between values. + * @param message Message to display on error. + */ + approximately(act: number, exp: number, delta: number, message?: string): void; + + /** + * Asserts that set1 and set2 have the same members. Order is not take into account. + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + sameMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 have the same members using deep equality checking. + * Order is not take into account. + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + sameDeepMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a deep equality check. + * + * T Type of set values. + * @param set1 + * @param set2 + * @param message + */ + notSameDeepMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 have the same members in the same order. + * Uses a strict equality check (===). + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + sameOrderedMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 don’t have the same members in the same order. + * Uses a strict equality check (===). + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + notSameOrderedMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 have the same members in the same order. + * Uses a deep equality check. + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + sameDeepOrderedMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 don’t have the same members in the same order. + * Uses a deep equality check. + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + notSameDeepOrderedMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that subset is included in superset in the same order beginning with the first element in superset. + * Uses a strict equality check (===). + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + includeOrderedMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset isn’t included in superset in the same order beginning with the first element in superset. + * Uses a strict equality check (===). + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + notIncludeOrderedMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset is included in superset in the same order beginning with the first element in superset. + * Uses a deep equality check. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + includeDeepOrderedMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset isn’t included in superset in the same order beginning with the first element in superset. + * Uses a deep equality check. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + notIncludeDeepOrderedMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset is included in superset. Order is not take into account. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + includeMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset isn’t included in superset in any order. + * Uses a strict equality check (===). Duplicates are ignored. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential not contained set of values. + * @param message Message to display on error. + */ + notIncludeMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset is included in superset using deep equality checking. + * Order is not take into account. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + includeDeepMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * deep equality check. Duplicates are ignored. + * + * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + notIncludeDeepMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that non-object, non-array value inList appears in the flat array list. + * + * T Type of list values. + * @param inList Value expected to be in the list. + * @param list List of values. + * @param message Message to display on error. + */ + oneOf(inList: T, list: T[], message?: string): void; + + /** + * Asserts that a function changes the value of a property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected to be modified. + * @param message Message to display on error. + */ + changes(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function changes the value of a property by an amount (delta). + * + * @param modifier function + * @param object or getter function + * @param property name _optional_ + * @param change amount (delta) + * @param message _optional_ + */ + changesBy( + modifier: Function, + object: T, + property: string, + /* keyof T */ change: number, + message?: string, + ): void; + changesBy(modifier: Function, object: T, change: number, message?: string): void; + + /** + * Asserts that a function does not change the value of a property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected not to be modified. + * @param message Message to display on error. + */ + doesNotChange(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function increases an object property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected to be increased. + * @param message Message to display on error. + */ + increases(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). + * + * T Type of object or function. + * @param modifier function + * @param object or getter function + * @param property name _optional_ + * @param change amount (delta) + * @param message _optional_ + */ + increasesBy( + modifier: Function, + object: T, + property: string, + /* keyof T */ change: number, + message?: string, + ): void; + increasesBy(modifier: Function, object: T, change: number, message?: string): void; + + /** + * Asserts that a function does not increase an object property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected not to be increased. + * @param message Message to display on error. + */ + doesNotIncrease(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). + * + * T Type of object or function. + * @param modifier function + * @param object or getter function + * @param property name _optional_ + * @param change amount (delta) + * @param message _optional_ + */ + + increasesButNotBy( + modifier: Function, + object: T, + property: string, + /* keyof T */ change: number, + message?: string, + ): void; + increasesButNotBy(modifier: Function, object: T, change: number, message?: string): void; + + /** + * Asserts that a function decreases an object property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected to be decreased. + * @param message Message to display on error. + */ + decreases(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) + * + * T Type of object or function. + * @param modifier function + * @param object or getter function + * @param property name _optional_ + * @param change amount (delta) + * @param message _optional_ + */ + + decreasesBy( + modifier: Function, + object: T, + property: string, + /* keyof T */ change: number, + message?: string, + ): void; + decreasesBy(modifier: Function, object: T, change: number, message?: string): void; + + /** + * Asserts that a function does not decrease an object property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected not to be decreased. + * @param message Message to display on error. + */ + doesNotDecrease(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * T Type of object or function. + * @param modifier function + * @param object or getter function + * @param property name _optional_ + * @param change amount (delta) + * @param message _optional_ + */ + + doesNotDecreaseBy( + modifier: Function, + object: T, + property: string, + /* keyof T */ change: number, + message?: string, + ): void; + doesNotDecreaseBy(modifier: Function, object: T, change: number, message?: string): void; + + /** + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * T Type of object or function. + * @param modifier function + * @param object or getter function + * @param property name _optional_ + * @param change amount (delta) + * @param message _optional_ + */ + + decreasesButNotBy( + modifier: Function, + object: T, + property: string, + /* keyof T */ change: number, + message?: string, + ): void; + decreasesButNotBy(modifier: Function, object: T, change: number, message?: string): void; + + /** + * Asserts if value is not a false value, and throws if it is a true value. + * + * T Type of object. + * @param object Actual value. + * @param message Message to display on error. + * @remarks This is added to allow for chai to be a drop-in replacement for + * Node’s assert class. + */ + ifError(object: T, message?: string): void; + + /** + * Asserts that object is extensible (can have new properties added to it). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isExtensible(object: T, message?: string): void; + + /** + * Asserts that object is extensible (can have new properties added to it). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + extensible(object: T, message?: string): void; + + /** + * Asserts that object is not extensible. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isNotExtensible(object: T, message?: string): void; + + /** + * Asserts that object is not extensible. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + notExtensible(object: T, message?: string): void; + + /** + * Asserts that object is sealed (can have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isSealed(object: T, message?: string): void; + + /** + * Asserts that object is sealed (can have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + sealed(object: T, message?: string): void; + + /** + * Asserts that object is not sealed. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isNotSealed(object: T, message?: string): void; + + /** + * Asserts that object is not sealed. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + notSealed(object: T, message?: string): void; + + /** + * Asserts that object is frozen (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isFrozen(object: T, message?: string): void; + + /** + * Asserts that object is frozen (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + frozen(object: T, message?: string): void; + + /** + * Asserts that object is not frozen (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isNotFrozen(object: T, message?: string): void; + + /** + * Asserts that object is not frozen (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + notFrozen(object: T, message?: string): void; + + /** + * Asserts that the target does not contain any values. For arrays and + * strings, it checks the length property. For Map and Set instances, it + * checks the size property. For non-function objects, it gets the count + * of own enumerable string keys. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isEmpty(object: T, message?: string): void; + + /** + * Asserts that the target contains values. For arrays and strings, it checks + * the length property. For Map and Set instances, it checks the size property. + * For non-function objects, it gets the count of own enumerable string keys. + * + * T Type of object. + * @param object Object to test. + * @param message Message to display on error. + */ + isNotEmpty(object: T, message?: string): void; + + /** + * Asserts that `object` has at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + hasAnyKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` has all and only all of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + hasAllKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` has all of the `keys` provided but may have more keys not listed. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + containsAllKeys( + object: T, + keys: Array | { [key: string]: any }, + message?: string, + ): void; + + /** + * Asserts that `object` has none of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + doesNotHaveAnyKeys( + object: T, + keys: Array | { [key: string]: any }, + message?: string, + ): void; + + /** + * Asserts that `object` does not have at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + doesNotHaveAllKeys( + object: T, + keys: Array | { [key: string]: any }, + message?: string, + ): void; + + /** + * Asserts that `object` has at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + hasAnyDeepKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` has all and only all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + hasAllDeepKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + containsAllDeepKeys( + object: T, + keys: Array | { [key: string]: any }, + message?: string, + ): void; + + /** + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + doesNotHaveAnyDeepKeys( + object: T, + keys: Array | { [key: string]: any }, + message?: string, + ): void; + + /** + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + doesNotHaveAllDeepKeys( + object: T, + keys: Array | { [key: string]: any }, + message?: string, + ): void; + + /** + * Asserts that object has a direct or inherited property named by property, + * which can be a string using dot- and bracket-notation for nested reference. + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param message Message to display on error. + */ + nestedProperty(object: T, property: string, message?: string): void; + + /** + * Asserts that object does not have a property named by property, + * which can be a string using dot- and bracket-notation for nested reference. + * The property cannot exist on the object nor anywhere in its prototype chain. + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param message Message to display on error. + */ + notNestedProperty(object: T, property: string, message?: string): void; + + /** + * Asserts that object has a property named by property with value given by value. + * property can use dot- and bracket-notation for nested reference. Uses a strict equality check (===). + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param value Value to test. + * @param message Message to display on error. + */ + nestedPropertyVal(object: T, property: string, value: any, message?: string): void; + + /** + * Asserts that object does not have a property named by property with value given by value. + * property can use dot- and bracket-notation for nested reference. Uses a strict equality check (===). + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param value Value to test. + * @param message Message to display on error. + */ + notNestedPropertyVal(object: T, property: string, value: any, message?: string): void; + + /** + * Asserts that object has a property named by property with a value given by value. + * property can use dot- and bracket-notation for nested reference. Uses a deep equality check. + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param value Value to test. + * @param message Message to display on error. + */ + deepNestedPropertyVal(object: T, property: string, value: any, message?: string): void; + + /** + * Asserts that object does not have a property named by property with value given by value. + * property can use dot- and bracket-notation for nested reference. Uses a deep equality check. + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param value Value to test. + * @param message Message to display on error. + */ + notDeepNestedPropertyVal(object: T, property: string, value: any, message?: string): void; + } + + export interface Config { + /** + * Default: false + */ + includeStack: boolean; + + /** + * Default: true + */ + showDiff: boolean; + + /** + * Default: 40 + */ + truncateThreshold: number; + + /** + * Default: true + */ + useProxy: boolean; + + /** + * Default: ['then', 'catch', 'inspect', 'toJSON'] + */ + proxyExcludedKeys: string[]; + + deepEqual: (expected: L, actual: R) => void; + } + + export class AssertionError { + constructor(message: string, _props?: any, ssf?: Function); + name: string; + message: string; + showDiff: boolean; + stack: string; + } + } +} + +export function use(fn: Chai.ChaiPlugin): Chai.ChaiStatic; + +export const util: Chai.ChaiUtils; +export const config: Chai.Config; +export const Assertion: Chai.AssertionStatic; +export function should(): Chai.Should; +export function Should(): Chai.Should; +export const assert: Chai.AssertStatic; +export const expect: Chai.ExpectStatic; diff --git a/node_modules/@types/chai/package.json b/node_modules/@types/chai/package.json new file mode 100644 index 0000000000..808d189aed --- /dev/null +++ b/node_modules/@types/chai/package.json @@ -0,0 +1,74 @@ +{ + "name": "@types/chai", + "version": "5.2.2", + "description": "TypeScript definitions for chai", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/chai", + "license": "MIT", + "contributors": [ + { + "name": "Bart van der Schoor", + "githubUsername": "Bartvds", + "url": "https://github.com/Bartvds" + }, + { + "name": "Andrew Brown", + "githubUsername": "AGBrown", + "url": "https://github.com/AGBrown" + }, + { + "name": "Olivier Chevet", + "githubUsername": "olivr70", + "url": "https://github.com/olivr70" + }, + { + "name": "Matt Wistrand", + "githubUsername": "mwistrand", + "url": "https://github.com/mwistrand" + }, + { + "name": "Shaun Luttin", + "githubUsername": "shaunluttin", + "url": "https://github.com/shaunluttin" + }, + { + "name": "Satana Charuwichitratana", + "githubUsername": "micksatana", + "url": "https://github.com/micksatana" + }, + { + "name": "Erik Schierboom", + "githubUsername": "ErikSchierboom", + "url": "https://github.com/ErikSchierboom" + }, + { + "name": "Bogdan Paranytsia", + "githubUsername": "bparan", + "url": "https://github.com/bparan" + }, + { + "name": "CXuesong", + "githubUsername": "CXuesong", + "url": "https://github.com/CXuesong" + }, + { + "name": "Joey Kilpatrick", + "githubUsername": "joeykilpatrick", + "url": "https://github.com/joeykilpatrick" + } + ], + "type": "module", + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/chai" + }, + "scripts": {}, + "dependencies": { + "@types/deep-eql": "*" + }, + "peerDependencies": {}, + "typesPublisherContentHash": "174d4205d8ad5de1f59dc1f4c1ca29f9ec7d12d905cd5eb02cd537b1e90e8a74", + "typeScriptVersion": "5.1" +} \ No newline at end of file diff --git a/node_modules/@types/chai/register-should.d.ts b/node_modules/@types/chai/register-should.d.ts new file mode 100644 index 0000000000..1e14f93b30 --- /dev/null +++ b/node_modules/@types/chai/register-should.d.ts @@ -0,0 +1,7 @@ +declare global { + interface Object { + should: Chai.Assertion; + } +} + +export {}; diff --git a/node_modules/@types/deep-eql/LICENSE b/node_modules/@types/deep-eql/LICENSE new file mode 100644 index 0000000000..9e841e7a26 --- /dev/null +++ b/node_modules/@types/deep-eql/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/node_modules/@types/deep-eql/README.md b/node_modules/@types/deep-eql/README.md new file mode 100644 index 0000000000..48d96fc640 --- /dev/null +++ b/node_modules/@types/deep-eql/README.md @@ -0,0 +1,57 @@ +# Installation +> `npm install --save @types/deep-eql` + +# Summary +This package contains type definitions for deep-eql (https://github.com/chaijs/deep-eql). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/deep-eql. +## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/deep-eql/index.d.ts) +````ts +declare namespace deepEqual { + /** + * Memoization class used to speed up comparison. + */ + class MemoizeMap extends WeakMap {} + + interface DeepEqualOptions { + /** + * Override default algorithm, determining custom equality. + */ + comparator?: (leftHandOperand: T1, rightHandOperand: T2) => boolean | null; + + /** + * Provide a custom memoization object which will cache the results of + * complex objects for a speed boost. + * + * By passing `false` you can disable memoization, but this will cause circular + * references to blow the stack. + */ + memoize?: MemoizeMap | false; + } +} + +/** + * Assert deeply nested sameValue equality between two objects of any type. + * + * @param leftHandOperand + * @param rightHandOperand + * @param [options] Additional options + * @return equal match + */ +declare function deepEqual( + leftHandOperand: T1, + rightHandOperand: T2, + options?: deepEqual.DeepEqualOptions, +): boolean; + +export = deepEqual; + +```` + +### Additional Details + * Last updated: Mon, 06 Nov 2023 22:41:05 GMT + * Dependencies: none + +# Credits +These definitions were written by [Rodrigo Pietnechuk](https://github.com/ghnoob). diff --git a/node_modules/@types/deep-eql/index.d.ts b/node_modules/@types/deep-eql/index.d.ts new file mode 100644 index 0000000000..0cdbefe930 --- /dev/null +++ b/node_modules/@types/deep-eql/index.d.ts @@ -0,0 +1,38 @@ +declare namespace deepEqual { + /** + * Memoization class used to speed up comparison. + */ + class MemoizeMap extends WeakMap {} + + interface DeepEqualOptions { + /** + * Override default algorithm, determining custom equality. + */ + comparator?: (leftHandOperand: T1, rightHandOperand: T2) => boolean | null; + + /** + * Provide a custom memoization object which will cache the results of + * complex objects for a speed boost. + * + * By passing `false` you can disable memoization, but this will cause circular + * references to blow the stack. + */ + memoize?: MemoizeMap | false; + } +} + +/** + * Assert deeply nested sameValue equality between two objects of any type. + * + * @param leftHandOperand + * @param rightHandOperand + * @param [options] Additional options + * @return equal match + */ +declare function deepEqual( + leftHandOperand: T1, + rightHandOperand: T2, + options?: deepEqual.DeepEqualOptions, +): boolean; + +export = deepEqual; diff --git a/node_modules/@types/deep-eql/package.json b/node_modules/@types/deep-eql/package.json new file mode 100644 index 0000000000..876158157a --- /dev/null +++ b/node_modules/@types/deep-eql/package.json @@ -0,0 +1,25 @@ +{ + "name": "@types/deep-eql", + "version": "4.0.2", + "description": "TypeScript definitions for deep-eql", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/deep-eql", + "license": "MIT", + "contributors": [ + { + "name": "Rodrigo Pietnechuk", + "githubUsername": "ghnoob", + "url": "https://github.com/ghnoob" + } + ], + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/deep-eql" + }, + "scripts": {}, + "dependencies": {}, + "typesPublisherContentHash": "3b8981ce557947fc00ca08cbd93b4206bfc0943360956867381a0a3f6b1eabf5", + "typeScriptVersion": "4.5" +} \ No newline at end of file diff --git a/node_modules/@types/estree/LICENSE b/node_modules/@types/estree/LICENSE new file mode 100644 index 0000000000..9e841e7a26 --- /dev/null +++ b/node_modules/@types/estree/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/node_modules/@types/estree/README.md b/node_modules/@types/estree/README.md new file mode 100644 index 0000000000..2af760b2bd --- /dev/null +++ b/node_modules/@types/estree/README.md @@ -0,0 +1,15 @@ +# Installation +> `npm install --save @types/estree` + +# Summary +This package contains type definitions for estree (https://github.com/estree/estree). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/estree. + +### Additional Details + * Last updated: Fri, 06 Jun 2025 00:04:33 GMT + * Dependencies: none + +# Credits +These definitions were written by [RReverser](https://github.com/RReverser). diff --git a/node_modules/@types/estree/flow.d.ts b/node_modules/@types/estree/flow.d.ts new file mode 100644 index 0000000000..9d001a92b5 --- /dev/null +++ b/node_modules/@types/estree/flow.d.ts @@ -0,0 +1,167 @@ +declare namespace ESTree { + interface FlowTypeAnnotation extends Node {} + + interface FlowBaseTypeAnnotation extends FlowTypeAnnotation {} + + interface FlowLiteralTypeAnnotation extends FlowTypeAnnotation, Literal {} + + interface FlowDeclaration extends Declaration {} + + interface AnyTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface ArrayTypeAnnotation extends FlowTypeAnnotation { + elementType: FlowTypeAnnotation; + } + + interface BooleanLiteralTypeAnnotation extends FlowLiteralTypeAnnotation {} + + interface BooleanTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface ClassImplements extends Node { + id: Identifier; + typeParameters?: TypeParameterInstantiation | null; + } + + interface ClassProperty { + key: Expression; + value?: Expression | null; + typeAnnotation?: TypeAnnotation | null; + computed: boolean; + static: boolean; + } + + interface DeclareClass extends FlowDeclaration { + id: Identifier; + typeParameters?: TypeParameterDeclaration | null; + body: ObjectTypeAnnotation; + extends: InterfaceExtends[]; + } + + interface DeclareFunction extends FlowDeclaration { + id: Identifier; + } + + interface DeclareModule extends FlowDeclaration { + id: Literal | Identifier; + body: BlockStatement; + } + + interface DeclareVariable extends FlowDeclaration { + id: Identifier; + } + + interface FunctionTypeAnnotation extends FlowTypeAnnotation { + params: FunctionTypeParam[]; + returnType: FlowTypeAnnotation; + rest?: FunctionTypeParam | null; + typeParameters?: TypeParameterDeclaration | null; + } + + interface FunctionTypeParam { + name: Identifier; + typeAnnotation: FlowTypeAnnotation; + optional: boolean; + } + + interface GenericTypeAnnotation extends FlowTypeAnnotation { + id: Identifier | QualifiedTypeIdentifier; + typeParameters?: TypeParameterInstantiation | null; + } + + interface InterfaceExtends extends Node { + id: Identifier | QualifiedTypeIdentifier; + typeParameters?: TypeParameterInstantiation | null; + } + + interface InterfaceDeclaration extends FlowDeclaration { + id: Identifier; + typeParameters?: TypeParameterDeclaration | null; + extends: InterfaceExtends[]; + body: ObjectTypeAnnotation; + } + + interface IntersectionTypeAnnotation extends FlowTypeAnnotation { + types: FlowTypeAnnotation[]; + } + + interface MixedTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface NullableTypeAnnotation extends FlowTypeAnnotation { + typeAnnotation: TypeAnnotation; + } + + interface NumberLiteralTypeAnnotation extends FlowLiteralTypeAnnotation {} + + interface NumberTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface StringLiteralTypeAnnotation extends FlowLiteralTypeAnnotation {} + + interface StringTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface TupleTypeAnnotation extends FlowTypeAnnotation { + types: FlowTypeAnnotation[]; + } + + interface TypeofTypeAnnotation extends FlowTypeAnnotation { + argument: FlowTypeAnnotation; + } + + interface TypeAlias extends FlowDeclaration { + id: Identifier; + typeParameters?: TypeParameterDeclaration | null; + right: FlowTypeAnnotation; + } + + interface TypeAnnotation extends Node { + typeAnnotation: FlowTypeAnnotation; + } + + interface TypeCastExpression extends Expression { + expression: Expression; + typeAnnotation: TypeAnnotation; + } + + interface TypeParameterDeclaration extends Node { + params: Identifier[]; + } + + interface TypeParameterInstantiation extends Node { + params: FlowTypeAnnotation[]; + } + + interface ObjectTypeAnnotation extends FlowTypeAnnotation { + properties: ObjectTypeProperty[]; + indexers: ObjectTypeIndexer[]; + callProperties: ObjectTypeCallProperty[]; + } + + interface ObjectTypeCallProperty extends Node { + value: FunctionTypeAnnotation; + static: boolean; + } + + interface ObjectTypeIndexer extends Node { + id: Identifier; + key: FlowTypeAnnotation; + value: FlowTypeAnnotation; + static: boolean; + } + + interface ObjectTypeProperty extends Node { + key: Expression; + value: FlowTypeAnnotation; + optional: boolean; + static: boolean; + } + + interface QualifiedTypeIdentifier extends Node { + qualification: Identifier | QualifiedTypeIdentifier; + id: Identifier; + } + + interface UnionTypeAnnotation extends FlowTypeAnnotation { + types: FlowTypeAnnotation[]; + } + + interface VoidTypeAnnotation extends FlowBaseTypeAnnotation {} +} diff --git a/node_modules/@types/estree/index.d.ts b/node_modules/@types/estree/index.d.ts new file mode 100644 index 0000000000..2bc66fb6c7 --- /dev/null +++ b/node_modules/@types/estree/index.d.ts @@ -0,0 +1,694 @@ +// This definition file follows a somewhat unusual format. ESTree allows +// runtime type checks based on the `type` parameter. In order to explain this +// to typescript we want to use discriminated union types: +// https://github.com/Microsoft/TypeScript/pull/9163 +// +// For ESTree this is a bit tricky because the high level interfaces like +// Node or Function are pulling double duty. We want to pass common fields down +// to the interfaces that extend them (like Identifier or +// ArrowFunctionExpression), but you can't extend a type union or enforce +// common fields on them. So we've split the high level interfaces into two +// types, a base type which passes down inherited fields, and a type union of +// all types which extend the base type. Only the type union is exported, and +// the union is how other types refer to the collection of inheriting types. +// +// This makes the definitions file here somewhat more difficult to maintain, +// but it has the notable advantage of making ESTree much easier to use as +// an end user. + +export interface BaseNodeWithoutComments { + // Every leaf interface that extends BaseNode must specify a type property. + // The type property should be a string literal. For example, Identifier + // has: `type: "Identifier"` + type: string; + loc?: SourceLocation | null | undefined; + range?: [number, number] | undefined; +} + +export interface BaseNode extends BaseNodeWithoutComments { + leadingComments?: Comment[] | undefined; + trailingComments?: Comment[] | undefined; +} + +export interface NodeMap { + AssignmentProperty: AssignmentProperty; + CatchClause: CatchClause; + Class: Class; + ClassBody: ClassBody; + Expression: Expression; + Function: Function; + Identifier: Identifier; + Literal: Literal; + MethodDefinition: MethodDefinition; + ModuleDeclaration: ModuleDeclaration; + ModuleSpecifier: ModuleSpecifier; + Pattern: Pattern; + PrivateIdentifier: PrivateIdentifier; + Program: Program; + Property: Property; + PropertyDefinition: PropertyDefinition; + SpreadElement: SpreadElement; + Statement: Statement; + Super: Super; + SwitchCase: SwitchCase; + TemplateElement: TemplateElement; + VariableDeclarator: VariableDeclarator; +} + +export type Node = NodeMap[keyof NodeMap]; + +export interface Comment extends BaseNodeWithoutComments { + type: "Line" | "Block"; + value: string; +} + +export interface SourceLocation { + source?: string | null | undefined; + start: Position; + end: Position; +} + +export interface Position { + /** >= 1 */ + line: number; + /** >= 0 */ + column: number; +} + +export interface Program extends BaseNode { + type: "Program"; + sourceType: "script" | "module"; + body: Array; + comments?: Comment[] | undefined; +} + +export interface Directive extends BaseNode { + type: "ExpressionStatement"; + expression: Literal; + directive: string; +} + +export interface BaseFunction extends BaseNode { + params: Pattern[]; + generator?: boolean | undefined; + async?: boolean | undefined; + // The body is either BlockStatement or Expression because arrow functions + // can have a body that's either. FunctionDeclarations and + // FunctionExpressions have only BlockStatement bodies. + body: BlockStatement | Expression; +} + +export type Function = FunctionDeclaration | FunctionExpression | ArrowFunctionExpression; + +export type Statement = + | ExpressionStatement + | BlockStatement + | StaticBlock + | EmptyStatement + | DebuggerStatement + | WithStatement + | ReturnStatement + | LabeledStatement + | BreakStatement + | ContinueStatement + | IfStatement + | SwitchStatement + | ThrowStatement + | TryStatement + | WhileStatement + | DoWhileStatement + | ForStatement + | ForInStatement + | ForOfStatement + | Declaration; + +export interface BaseStatement extends BaseNode {} + +export interface EmptyStatement extends BaseStatement { + type: "EmptyStatement"; +} + +export interface BlockStatement extends BaseStatement { + type: "BlockStatement"; + body: Statement[]; + innerComments?: Comment[] | undefined; +} + +export interface StaticBlock extends Omit { + type: "StaticBlock"; +} + +export interface ExpressionStatement extends BaseStatement { + type: "ExpressionStatement"; + expression: Expression; +} + +export interface IfStatement extends BaseStatement { + type: "IfStatement"; + test: Expression; + consequent: Statement; + alternate?: Statement | null | undefined; +} + +export interface LabeledStatement extends BaseStatement { + type: "LabeledStatement"; + label: Identifier; + body: Statement; +} + +export interface BreakStatement extends BaseStatement { + type: "BreakStatement"; + label?: Identifier | null | undefined; +} + +export interface ContinueStatement extends BaseStatement { + type: "ContinueStatement"; + label?: Identifier | null | undefined; +} + +export interface WithStatement extends BaseStatement { + type: "WithStatement"; + object: Expression; + body: Statement; +} + +export interface SwitchStatement extends BaseStatement { + type: "SwitchStatement"; + discriminant: Expression; + cases: SwitchCase[]; +} + +export interface ReturnStatement extends BaseStatement { + type: "ReturnStatement"; + argument?: Expression | null | undefined; +} + +export interface ThrowStatement extends BaseStatement { + type: "ThrowStatement"; + argument: Expression; +} + +export interface TryStatement extends BaseStatement { + type: "TryStatement"; + block: BlockStatement; + handler?: CatchClause | null | undefined; + finalizer?: BlockStatement | null | undefined; +} + +export interface WhileStatement extends BaseStatement { + type: "WhileStatement"; + test: Expression; + body: Statement; +} + +export interface DoWhileStatement extends BaseStatement { + type: "DoWhileStatement"; + body: Statement; + test: Expression; +} + +export interface ForStatement extends BaseStatement { + type: "ForStatement"; + init?: VariableDeclaration | Expression | null | undefined; + test?: Expression | null | undefined; + update?: Expression | null | undefined; + body: Statement; +} + +export interface BaseForXStatement extends BaseStatement { + left: VariableDeclaration | Pattern; + right: Expression; + body: Statement; +} + +export interface ForInStatement extends BaseForXStatement { + type: "ForInStatement"; +} + +export interface DebuggerStatement extends BaseStatement { + type: "DebuggerStatement"; +} + +export type Declaration = FunctionDeclaration | VariableDeclaration | ClassDeclaration; + +export interface BaseDeclaration extends BaseStatement {} + +export interface MaybeNamedFunctionDeclaration extends BaseFunction, BaseDeclaration { + type: "FunctionDeclaration"; + /** It is null when a function declaration is a part of the `export default function` statement */ + id: Identifier | null; + body: BlockStatement; +} + +export interface FunctionDeclaration extends MaybeNamedFunctionDeclaration { + id: Identifier; +} + +export interface VariableDeclaration extends BaseDeclaration { + type: "VariableDeclaration"; + declarations: VariableDeclarator[]; + kind: "var" | "let" | "const" | "using" | "await using"; +} + +export interface VariableDeclarator extends BaseNode { + type: "VariableDeclarator"; + id: Pattern; + init?: Expression | null | undefined; +} + +export interface ExpressionMap { + ArrayExpression: ArrayExpression; + ArrowFunctionExpression: ArrowFunctionExpression; + AssignmentExpression: AssignmentExpression; + AwaitExpression: AwaitExpression; + BinaryExpression: BinaryExpression; + CallExpression: CallExpression; + ChainExpression: ChainExpression; + ClassExpression: ClassExpression; + ConditionalExpression: ConditionalExpression; + FunctionExpression: FunctionExpression; + Identifier: Identifier; + ImportExpression: ImportExpression; + Literal: Literal; + LogicalExpression: LogicalExpression; + MemberExpression: MemberExpression; + MetaProperty: MetaProperty; + NewExpression: NewExpression; + ObjectExpression: ObjectExpression; + SequenceExpression: SequenceExpression; + TaggedTemplateExpression: TaggedTemplateExpression; + TemplateLiteral: TemplateLiteral; + ThisExpression: ThisExpression; + UnaryExpression: UnaryExpression; + UpdateExpression: UpdateExpression; + YieldExpression: YieldExpression; +} + +export type Expression = ExpressionMap[keyof ExpressionMap]; + +export interface BaseExpression extends BaseNode {} + +export type ChainElement = SimpleCallExpression | MemberExpression; + +export interface ChainExpression extends BaseExpression { + type: "ChainExpression"; + expression: ChainElement; +} + +export interface ThisExpression extends BaseExpression { + type: "ThisExpression"; +} + +export interface ArrayExpression extends BaseExpression { + type: "ArrayExpression"; + elements: Array; +} + +export interface ObjectExpression extends BaseExpression { + type: "ObjectExpression"; + properties: Array; +} + +export interface PrivateIdentifier extends BaseNode { + type: "PrivateIdentifier"; + name: string; +} + +export interface Property extends BaseNode { + type: "Property"; + key: Expression | PrivateIdentifier; + value: Expression | Pattern; // Could be an AssignmentProperty + kind: "init" | "get" | "set"; + method: boolean; + shorthand: boolean; + computed: boolean; +} + +export interface PropertyDefinition extends BaseNode { + type: "PropertyDefinition"; + key: Expression | PrivateIdentifier; + value?: Expression | null | undefined; + computed: boolean; + static: boolean; +} + +export interface FunctionExpression extends BaseFunction, BaseExpression { + id?: Identifier | null | undefined; + type: "FunctionExpression"; + body: BlockStatement; +} + +export interface SequenceExpression extends BaseExpression { + type: "SequenceExpression"; + expressions: Expression[]; +} + +export interface UnaryExpression extends BaseExpression { + type: "UnaryExpression"; + operator: UnaryOperator; + prefix: true; + argument: Expression; +} + +export interface BinaryExpression extends BaseExpression { + type: "BinaryExpression"; + operator: BinaryOperator; + left: Expression | PrivateIdentifier; + right: Expression; +} + +export interface AssignmentExpression extends BaseExpression { + type: "AssignmentExpression"; + operator: AssignmentOperator; + left: Pattern | MemberExpression; + right: Expression; +} + +export interface UpdateExpression extends BaseExpression { + type: "UpdateExpression"; + operator: UpdateOperator; + argument: Expression; + prefix: boolean; +} + +export interface LogicalExpression extends BaseExpression { + type: "LogicalExpression"; + operator: LogicalOperator; + left: Expression; + right: Expression; +} + +export interface ConditionalExpression extends BaseExpression { + type: "ConditionalExpression"; + test: Expression; + alternate: Expression; + consequent: Expression; +} + +export interface BaseCallExpression extends BaseExpression { + callee: Expression | Super; + arguments: Array; +} +export type CallExpression = SimpleCallExpression | NewExpression; + +export interface SimpleCallExpression extends BaseCallExpression { + type: "CallExpression"; + optional: boolean; +} + +export interface NewExpression extends BaseCallExpression { + type: "NewExpression"; +} + +export interface MemberExpression extends BaseExpression, BasePattern { + type: "MemberExpression"; + object: Expression | Super; + property: Expression | PrivateIdentifier; + computed: boolean; + optional: boolean; +} + +export type Pattern = Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression; + +export interface BasePattern extends BaseNode {} + +export interface SwitchCase extends BaseNode { + type: "SwitchCase"; + test?: Expression | null | undefined; + consequent: Statement[]; +} + +export interface CatchClause extends BaseNode { + type: "CatchClause"; + param: Pattern | null; + body: BlockStatement; +} + +export interface Identifier extends BaseNode, BaseExpression, BasePattern { + type: "Identifier"; + name: string; +} + +export type Literal = SimpleLiteral | RegExpLiteral | BigIntLiteral; + +export interface SimpleLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value: string | boolean | number | null; + raw?: string | undefined; +} + +export interface RegExpLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value?: RegExp | null | undefined; + regex: { + pattern: string; + flags: string; + }; + raw?: string | undefined; +} + +export interface BigIntLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value?: bigint | null | undefined; + bigint: string; + raw?: string | undefined; +} + +export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; + +export type BinaryOperator = + | "==" + | "!=" + | "===" + | "!==" + | "<" + | "<=" + | ">" + | ">=" + | "<<" + | ">>" + | ">>>" + | "+" + | "-" + | "*" + | "/" + | "%" + | "**" + | "|" + | "^" + | "&" + | "in" + | "instanceof"; + +export type LogicalOperator = "||" | "&&" | "??"; + +export type AssignmentOperator = + | "=" + | "+=" + | "-=" + | "*=" + | "/=" + | "%=" + | "**=" + | "<<=" + | ">>=" + | ">>>=" + | "|=" + | "^=" + | "&=" + | "||=" + | "&&=" + | "??="; + +export type UpdateOperator = "++" | "--"; + +export interface ForOfStatement extends BaseForXStatement { + type: "ForOfStatement"; + await: boolean; +} + +export interface Super extends BaseNode { + type: "Super"; +} + +export interface SpreadElement extends BaseNode { + type: "SpreadElement"; + argument: Expression; +} + +export interface ArrowFunctionExpression extends BaseExpression, BaseFunction { + type: "ArrowFunctionExpression"; + expression: boolean; + body: BlockStatement | Expression; +} + +export interface YieldExpression extends BaseExpression { + type: "YieldExpression"; + argument?: Expression | null | undefined; + delegate: boolean; +} + +export interface TemplateLiteral extends BaseExpression { + type: "TemplateLiteral"; + quasis: TemplateElement[]; + expressions: Expression[]; +} + +export interface TaggedTemplateExpression extends BaseExpression { + type: "TaggedTemplateExpression"; + tag: Expression; + quasi: TemplateLiteral; +} + +export interface TemplateElement extends BaseNode { + type: "TemplateElement"; + tail: boolean; + value: { + /** It is null when the template literal is tagged and the text has an invalid escape (e.g. - tag`\unicode and \u{55}`) */ + cooked?: string | null | undefined; + raw: string; + }; +} + +export interface AssignmentProperty extends Property { + value: Pattern; + kind: "init"; + method: boolean; // false +} + +export interface ObjectPattern extends BasePattern { + type: "ObjectPattern"; + properties: Array; +} + +export interface ArrayPattern extends BasePattern { + type: "ArrayPattern"; + elements: Array; +} + +export interface RestElement extends BasePattern { + type: "RestElement"; + argument: Pattern; +} + +export interface AssignmentPattern extends BasePattern { + type: "AssignmentPattern"; + left: Pattern; + right: Expression; +} + +export type Class = ClassDeclaration | ClassExpression; +export interface BaseClass extends BaseNode { + superClass?: Expression | null | undefined; + body: ClassBody; +} + +export interface ClassBody extends BaseNode { + type: "ClassBody"; + body: Array; +} + +export interface MethodDefinition extends BaseNode { + type: "MethodDefinition"; + key: Expression | PrivateIdentifier; + value: FunctionExpression; + kind: "constructor" | "method" | "get" | "set"; + computed: boolean; + static: boolean; +} + +export interface MaybeNamedClassDeclaration extends BaseClass, BaseDeclaration { + type: "ClassDeclaration"; + /** It is null when a class declaration is a part of the `export default class` statement */ + id: Identifier | null; +} + +export interface ClassDeclaration extends MaybeNamedClassDeclaration { + id: Identifier; +} + +export interface ClassExpression extends BaseClass, BaseExpression { + type: "ClassExpression"; + id?: Identifier | null | undefined; +} + +export interface MetaProperty extends BaseExpression { + type: "MetaProperty"; + meta: Identifier; + property: Identifier; +} + +export type ModuleDeclaration = + | ImportDeclaration + | ExportNamedDeclaration + | ExportDefaultDeclaration + | ExportAllDeclaration; +export interface BaseModuleDeclaration extends BaseNode {} + +export type ModuleSpecifier = ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier; +export interface BaseModuleSpecifier extends BaseNode { + local: Identifier; +} + +export interface ImportDeclaration extends BaseModuleDeclaration { + type: "ImportDeclaration"; + specifiers: Array; + attributes: ImportAttribute[]; + source: Literal; +} + +export interface ImportSpecifier extends BaseModuleSpecifier { + type: "ImportSpecifier"; + imported: Identifier | Literal; +} + +export interface ImportAttribute extends BaseNode { + type: "ImportAttribute"; + key: Identifier | Literal; + value: Literal; +} + +export interface ImportExpression extends BaseExpression { + type: "ImportExpression"; + source: Expression; + options?: Expression | null | undefined; +} + +export interface ImportDefaultSpecifier extends BaseModuleSpecifier { + type: "ImportDefaultSpecifier"; +} + +export interface ImportNamespaceSpecifier extends BaseModuleSpecifier { + type: "ImportNamespaceSpecifier"; +} + +export interface ExportNamedDeclaration extends BaseModuleDeclaration { + type: "ExportNamedDeclaration"; + declaration?: Declaration | null | undefined; + specifiers: ExportSpecifier[]; + attributes: ImportAttribute[]; + source?: Literal | null | undefined; +} + +export interface ExportSpecifier extends Omit { + type: "ExportSpecifier"; + local: Identifier | Literal; + exported: Identifier | Literal; +} + +export interface ExportDefaultDeclaration extends BaseModuleDeclaration { + type: "ExportDefaultDeclaration"; + declaration: MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | Expression; +} + +export interface ExportAllDeclaration extends BaseModuleDeclaration { + type: "ExportAllDeclaration"; + exported: Identifier | Literal | null; + attributes: ImportAttribute[]; + source: Literal; +} + +export interface AwaitExpression extends BaseExpression { + type: "AwaitExpression"; + argument: Expression; +} diff --git a/node_modules/@types/estree/package.json b/node_modules/@types/estree/package.json new file mode 100644 index 0000000000..68c0782c77 --- /dev/null +++ b/node_modules/@types/estree/package.json @@ -0,0 +1,27 @@ +{ + "name": "@types/estree", + "version": "1.0.8", + "description": "TypeScript definitions for estree", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/estree", + "license": "MIT", + "contributors": [ + { + "name": "RReverser", + "githubUsername": "RReverser", + "url": "https://github.com/RReverser" + } + ], + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/estree" + }, + "scripts": {}, + "dependencies": {}, + "peerDependencies": {}, + "typesPublisherContentHash": "7a167b6e4a4d9f6e9a2cb9fd3fc45c885f89cbdeb44b3e5961bb057a45c082fd", + "typeScriptVersion": "5.1", + "nonNpm": true +} \ No newline at end of file diff --git a/node_modules/@vitest/expect/LICENSE b/node_modules/@vitest/expect/LICENSE new file mode 100644 index 0000000000..5ae481fdb8 --- /dev/null +++ b/node_modules/@vitest/expect/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/expect/README.md b/node_modules/@vitest/expect/README.md new file mode 100644 index 0000000000..4d7143bf64 --- /dev/null +++ b/node_modules/@vitest/expect/README.md @@ -0,0 +1,21 @@ +# @vitest/expect + +Jest's expect matchers as a Chai plugin. + +## Usage + +```js +import { + JestAsymmetricMatchers, + JestChaiExpect, + JestExtend, +} from '@vitest/expect' +import * as chai from 'chai' + +// allows using expect.extend instead of chai.use to extend plugins +chai.use(JestExtend) +// adds all jest matchers to expect +chai.use(JestChaiExpect) +// adds asymmetric matchers like stringContaining, objectContaining +chai.use(JestAsymmetricMatchers) +``` diff --git a/node_modules/@vitest/expect/dist/index.d.ts b/node_modules/@vitest/expect/dist/index.d.ts new file mode 100644 index 0000000000..4f93e89978 --- /dev/null +++ b/node_modules/@vitest/expect/dist/index.d.ts @@ -0,0 +1,808 @@ +import { MockInstance } from '@vitest/spy'; +import { stringify, Constructable } from '@vitest/utils'; +import { Formatter } from 'tinyrainbow'; +import { diff, printDiffOrStringify } from '@vitest/utils/diff'; +export { DiffOptions } from '@vitest/utils/diff'; + +declare const MATCHERS_OBJECT: unique symbol; +declare const JEST_MATCHERS_OBJECT: unique symbol; +declare const GLOBAL_EXPECT: unique symbol; +declare const ASYMMETRIC_MATCHERS_OBJECT: unique symbol; + +/* eslint-disable unicorn/no-instanceof-builtins -- we check both */ + +interface AsymmetricMatcherInterface { + asymmetricMatch: (other: unknown) => boolean; + toString: () => string; + getExpectedType?: () => string; + toAsymmetricMatcher?: () => string; +} +declare abstract class AsymmetricMatcher< + T, + State extends MatcherState = MatcherState +> implements AsymmetricMatcherInterface { + protected sample: T; + protected inverse: boolean; + // should have "jest" to be compatible with its ecosystem + $$typeof: symbol; + constructor(sample: T, inverse?: boolean); + protected getMatcherContext(expect?: Chai.ExpectStatic): State; + abstract asymmetricMatch(other: unknown): boolean; + abstract toString(): string; + getExpectedType?(): string; + toAsymmetricMatcher?(): string; +} +declare class StringContaining extends AsymmetricMatcher { + constructor(sample: string, inverse?: boolean); + asymmetricMatch(other: string): boolean; + toString(): string; + getExpectedType(): string; +} +declare class Anything extends AsymmetricMatcher { + asymmetricMatch(other: unknown): boolean; + toString(): string; + toAsymmetricMatcher(): string; +} +declare class ObjectContaining extends AsymmetricMatcher> { + constructor(sample: Record, inverse?: boolean); + getPrototype(obj: object): any; + hasProperty(obj: object | null, property: string): boolean; + asymmetricMatch(other: any): boolean; + toString(): string; + getExpectedType(): string; +} +declare class ArrayContaining extends AsymmetricMatcher> { + constructor(sample: Array, inverse?: boolean); + asymmetricMatch(other: Array): boolean; + toString(): string; + getExpectedType(): string; +} +declare class Any extends AsymmetricMatcher { + constructor(sample: unknown); + fnNameFor(func: Function): string; + asymmetricMatch(other: unknown): boolean; + toString(): string; + getExpectedType(): string; + toAsymmetricMatcher(): string; +} +declare class StringMatching extends AsymmetricMatcher { + constructor(sample: string | RegExp, inverse?: boolean); + asymmetricMatch(other: string): boolean; + toString(): string; + getExpectedType(): string; +} +declare const JestAsymmetricMatchers: ChaiPlugin; + +declare function matcherHint(matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions): string; +declare function printReceived(object: unknown): string; +declare function printExpected(value: unknown): string; +declare function getMatcherUtils(): { + EXPECTED_COLOR: Formatter + RECEIVED_COLOR: Formatter + INVERTED_COLOR: Formatter + BOLD_WEIGHT: Formatter + DIM_COLOR: Formatter + diff: typeof diff + matcherHint: typeof matcherHint + printReceived: typeof printReceived + printExpected: typeof printExpected + printDiffOrStringify: typeof printDiffOrStringify + printWithType: typeof printWithType +}; +declare function printWithType(name: string, value: T, print: (value: T) => string): string; +declare function addCustomEqualityTesters(newTesters: Array): void; + +/** +* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +*/ + +type ChaiPlugin = Chai.ChaiPlugin; +type Tester = (this: TesterContext, a: any, b: any, customTesters: Array) => boolean | undefined; +interface TesterContext { + equals: (a: unknown, b: unknown, customTesters?: Array, strictCheck?: boolean) => boolean; +} + +interface MatcherHintOptions { + comment?: string; + expectedColor?: Formatter; + isDirectExpectCall?: boolean; + isNot?: boolean; + promise?: string; + receivedColor?: Formatter; + secondArgument?: string; + secondArgumentColor?: Formatter; +} +interface MatcherState { + customTesters: Array; + assertionCalls: number; + currentTestName?: string; + dontThrow?: () => void; + error?: Error; + equals: (a: unknown, b: unknown, customTesters?: Array, strictCheck?: boolean) => boolean; + expand?: boolean; + expectedAssertionsNumber?: number | null; + expectedAssertionsNumberErrorGen?: (() => Error) | null; + isExpectingAssertions?: boolean; + isExpectingAssertionsError?: Error | null; + isNot: boolean; + // environment: VitestEnvironment + promise: string; + // snapshotState: SnapshotState + suppressedErrors: Array; + testPath?: string; + utils: ReturnType & { + diff: typeof diff + stringify: typeof stringify + iterableEquality: Tester + subsetEquality: Tester + }; + soft?: boolean; + poll?: boolean; +} +interface SyncExpectationResult { + pass: boolean; + message: () => string; + actual?: any; + expected?: any; +} +type AsyncExpectationResult = Promise; +type ExpectationResult = SyncExpectationResult | AsyncExpectationResult; +interface RawMatcherFn< + T extends MatcherState = MatcherState, + E extends Array = Array +> { + (this: T, received: any, ...expected: E): ExpectationResult; +} +// Allow unused `T` to preserve its name for extensions. +// Type parameter names must be identical when extending those types. +// eslint-disable-next-line +interface Matchers {} +type MatchersObject = Record> & ThisType & { [K in keyof Matchers]? : RawMatcherFn[K]>> }; +interface ExpectStatic extends Chai.ExpectStatic, Matchers, AsymmetricMatchersContaining { + (actual: T, message?: string): Assertion; + extend: (expects: MatchersObject) => void; + anything: () => any; + any: (constructor: unknown) => any; + getState: () => MatcherState; + setState: (state: Partial) => void; + not: AsymmetricMatchersContaining; +} +interface CustomMatcher { + /** + * Checks that a value satisfies a custom matcher function. + * + * @param matcher - A function returning a boolean based on the custom condition + * @param message - Optional custom error message on failure + * + * @example + * expect(age).toSatisfy(val => val >= 18, 'Age must be at least 18'); + * expect(age).toEqual(expect.toSatisfy(val => val >= 18, 'Age must be at least 18')); + */ + toSatisfy: (matcher: (value: any) => boolean, message?: string) => any; + /** + * Matches if the received value is one of the values in the expected array. + * + * @example + * expect(1).toBeOneOf([1, 2, 3]) + * expect('foo').toBeOneOf([expect.any(String)]) + * expect({ a: 1 }).toEqual({ a: expect.toBeOneOf(['1', '2', '3']) }) + */ + toBeOneOf: (sample: Array) => any; +} +interface AsymmetricMatchersContaining extends CustomMatcher { + /** + * Matches if the received string contains the expected substring. + * + * @example + * expect('I have an apple').toEqual(expect.stringContaining('apple')); + * expect({ a: 'test string' }).toEqual({ a: expect.stringContaining('test') }); + */ + stringContaining: (expected: string) => any; + /** + * Matches if the received object contains all properties of the expected object. + * + * @example + * expect({ a: '1', b: 2 }).toEqual(expect.objectContaining({ a: '1' })) + */ + objectContaining: (expected: DeeplyAllowMatchers) => any; + /** + * Matches if the received array contains all elements in the expected array. + * + * @example + * expect(['a', 'b', 'c']).toEqual(expect.arrayContaining(['b', 'a'])); + */ + arrayContaining: (expected: Array>) => any; + /** + * Matches if the received string or regex matches the expected pattern. + * + * @example + * expect('hello world').toEqual(expect.stringMatching(/^hello/)); + * expect('hello world').toEqual(expect.stringMatching('hello')); + */ + stringMatching: (expected: string | RegExp) => any; + /** + * Matches if the received number is within a certain precision of the expected number. + * + * @param precision - Optional decimal precision for comparison. Default is 2. + * + * @example + * expect(10.45).toEqual(expect.closeTo(10.5, 1)); + * expect(5.11).toEqual(expect.closeTo(5.12)); // with default precision + */ + closeTo: (expected: number, precision?: number) => any; +} +type WithAsymmetricMatcher = T | AsymmetricMatcher; +type DeeplyAllowMatchers = T extends Array ? WithAsymmetricMatcher | DeeplyAllowMatchers[] : T extends object ? WithAsymmetricMatcher | { [K in keyof T] : DeeplyAllowMatchers } : WithAsymmetricMatcher; +interface JestAssertion extends jest.Matchers, CustomMatcher { + /** + * Used when you want to check that two objects have the same value. + * This matcher recursively checks the equality of all fields, rather than checking for object identity. + * + * @example + * expect(user).toEqual({ name: 'Alice', age: 30 }); + */ + toEqual: (expected: E) => void; + /** + * Use to test that objects have the same types as well as structure. + * + * @example + * expect(user).toStrictEqual({ name: 'Alice', age: 30 }); + */ + toStrictEqual: (expected: E) => void; + /** + * Checks that a value is what you expect. It calls `Object.is` to compare values. + * Don't use `toBe` with floating-point numbers. + * + * @example + * expect(result).toBe(42); + * expect(status).toBe(true); + */ + toBe: (expected: E) => void; + /** + * Check that a string matches a regular expression. + * + * @example + * expect(message).toMatch(/hello/); + * expect(greeting).toMatch('world'); + */ + toMatch: (expected: string | RegExp) => void; + /** + * Used to check that a JavaScript object matches a subset of the properties of an object + * + * @example + * expect(user).toMatchObject({ + * name: 'Alice', + * address: { city: 'Wonderland' } + * }); + */ + toMatchObject: (expected: E) => void; + /** + * Used when you want to check that an item is in a list. + * For testing the items in the list, this uses `===`, a strict equality check. + * + * @example + * expect(items).toContain('apple'); + * expect(numbers).toContain(5); + */ + toContain: (item: E) => void; + /** + * Used when you want to check that an item is in a list. + * For testing the items in the list, this matcher recursively checks the + * equality of all fields, rather than checking for object identity. + * + * @example + * expect(items).toContainEqual({ name: 'apple', quantity: 1 }); + */ + toContainEqual: (item: E) => void; + /** + * Use when you don't care what a value is, you just want to ensure a value + * is true in a boolean context. In JavaScript, there are six falsy values: + * `false`, `0`, `''`, `null`, `undefined`, and `NaN`. Everything else is truthy. + * + * @example + * expect(user.isActive).toBeTruthy(); + */ + toBeTruthy: () => void; + /** + * When you don't care what a value is, you just want to + * ensure a value is false in a boolean context. + * + * @example + * expect(user.isActive).toBeFalsy(); + */ + toBeFalsy: () => void; + /** + * For comparing floating point numbers. + * + * @example + * expect(score).toBeGreaterThan(10); + */ + toBeGreaterThan: (num: number | bigint) => void; + /** + * For comparing floating point numbers. + * + * @example + * expect(score).toBeGreaterThanOrEqual(10); + */ + toBeGreaterThanOrEqual: (num: number | bigint) => void; + /** + * For comparing floating point numbers. + * + * @example + * expect(score).toBeLessThan(10); + */ + toBeLessThan: (num: number | bigint) => void; + /** + * For comparing floating point numbers. + * + * @example + * expect(score).toBeLessThanOrEqual(10); + */ + toBeLessThanOrEqual: (num: number | bigint) => void; + /** + * Used to check that a variable is NaN. + * + * @example + * expect(value).toBeNaN(); + */ + toBeNaN: () => void; + /** + * Used to check that a variable is undefined. + * + * @example + * expect(value).toBeUndefined(); + */ + toBeUndefined: () => void; + /** + * This is the same as `.toBe(null)` but the error messages are a bit nicer. + * So use `.toBeNull()` when you want to check that something is null. + * + * @example + * expect(value).toBeNull(); + */ + toBeNull: () => void; + /** + * Ensure that a variable is not undefined. + * + * @example + * expect(value).toBeDefined(); + */ + toBeDefined: () => void; + /** + * Ensure that an object is an instance of a class. + * This matcher uses `instanceof` underneath. + * + * @example + * expect(new Date()).toBeInstanceOf(Date); + */ + toBeInstanceOf: (expected: E) => void; + /** + * Used to check that an object has a `.length` property + * and it is set to a certain numeric value. + * + * @example + * expect([1, 2, 3]).toHaveLength(3); + * expect('hello').toHaveLength(5); + */ + toHaveLength: (length: number) => void; + /** + * Use to check if a property at the specified path exists on an object. + * For checking deeply nested properties, you may use dot notation or an array containing + * the path segments for deep references. + * + * Optionally, you can provide a value to check if it matches the value present at the path + * on the target object. This matcher uses 'deep equality' (like `toEqual()`) and recursively checks + * the equality of all fields. + * + * @example + * expect(user).toHaveProperty('address.city', 'New York'); + * expect(config).toHaveProperty(['settings', 'theme'], 'dark'); + */ + toHaveProperty: (property: string | (string | number)[], value?: E) => void; + /** + * Using exact equality with floating point numbers is a bad idea. + * Rounding means that intuitive things fail. + * The default for `precision` is 2. + * + * @example + * expect(price).toBeCloseTo(9.99, 2); + */ + toBeCloseTo: (number: number, numDigits?: number) => void; + /** + * Ensures that a mock function is called an exact number of times. + * + * Also under the alias `expect.toBeCalledTimes`. + * + * @example + * expect(mockFunc).toHaveBeenCalledTimes(2); + */ + toHaveBeenCalledTimes: (times: number) => void; + /** + * Ensures that a mock function is called an exact number of times. + * + * Alias for `expect.toHaveBeenCalledTimes`. + * + * @example + * expect(mockFunc).toBeCalledTimes(2); + */ + toBeCalledTimes: (times: number) => void; + /** + * Ensures that a mock function is called. + * + * Also under the alias `expect.toBeCalled`. + * + * @example + * expect(mockFunc).toHaveBeenCalled(); + */ + toHaveBeenCalled: () => void; + /** + * Ensures that a mock function is called. + * + * Alias for `expect.toHaveBeenCalled`. + * + * @example + * expect(mockFunc).toBeCalled(); + */ + toBeCalled: () => void; + /** + * Ensure that a mock function is called with specific arguments. + * + * Also under the alias `expect.toBeCalledWith`. + * + * @example + * expect(mockFunc).toHaveBeenCalledWith('arg1', 42); + */ + toHaveBeenCalledWith: (...args: E) => void; + /** + * Ensure that a mock function is called with specific arguments. + * + * Alias for `expect.toHaveBeenCalledWith`. + * + * @example + * expect(mockFunc).toBeCalledWith('arg1', 42); + */ + toBeCalledWith: (...args: E) => void; + /** + * Ensure that a mock function is called with specific arguments on an Nth call. + * + * Also under the alias `expect.nthCalledWith`. + * + * @example + * expect(mockFunc).toHaveBeenNthCalledWith(2, 'secondArg'); + */ + toHaveBeenNthCalledWith: (n: number, ...args: E) => void; + /** + * Ensure that a mock function is called with specific arguments on an Nth call. + * + * Alias for `expect.toHaveBeenNthCalledWith`. + * + * @example + * expect(mockFunc).nthCalledWith(2, 'secondArg'); + */ + nthCalledWith: (nthCall: number, ...args: E) => void; + /** + * If you have a mock function, you can use `.toHaveBeenLastCalledWith` + * to test what arguments it was last called with. + * + * Also under the alias `expect.lastCalledWith`. + * + * @example + * expect(mockFunc).toHaveBeenLastCalledWith('lastArg'); + */ + toHaveBeenLastCalledWith: (...args: E) => void; + /** + * If you have a mock function, you can use `.lastCalledWith` + * to test what arguments it was last called with. + * + * Alias for `expect.toHaveBeenLastCalledWith`. + * + * @example + * expect(mockFunc).lastCalledWith('lastArg'); + */ + lastCalledWith: (...args: E) => void; + /** + * Used to test that a function throws when it is called. + * + * Also under the alias `expect.toThrowError`. + * + * @example + * expect(() => functionWithError()).toThrow('Error message'); + * expect(() => parseJSON('invalid')).toThrow(SyntaxError); + */ + toThrow: (expected?: string | Constructable | RegExp | Error) => void; + /** + * Used to test that a function throws when it is called. + * + * Alias for `expect.toThrow`. + * + * @example + * expect(() => functionWithError()).toThrowError('Error message'); + * expect(() => parseJSON('invalid')).toThrowError(SyntaxError); + */ + toThrowError: (expected?: string | Constructable | RegExp | Error) => void; + /** + * Use to test that the mock function successfully returned (i.e., did not throw an error) at least one time + * + * Alias for `expect.toHaveReturned`. + * + * @example + * expect(mockFunc).toReturn(); + */ + toReturn: () => void; + /** + * Use to test that the mock function successfully returned (i.e., did not throw an error) at least one time + * + * Also under the alias `expect.toReturn`. + * + * @example + * expect(mockFunc).toHaveReturned(); + */ + toHaveReturned: () => void; + /** + * Use to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times. + * Any calls to the mock function that throw an error are not counted toward the number of times the function returned. + * + * Alias for `expect.toHaveReturnedTimes`. + * + * @example + * expect(mockFunc).toReturnTimes(3); + */ + toReturnTimes: (times: number) => void; + /** + * Use to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times. + * Any calls to the mock function that throw an error are not counted toward the number of times the function returned. + * + * Also under the alias `expect.toReturnTimes`. + * + * @example + * expect(mockFunc).toHaveReturnedTimes(3); + */ + toHaveReturnedTimes: (times: number) => void; + /** + * Use to ensure that a mock function returned a specific value. + * + * Alias for `expect.toHaveReturnedWith`. + * + * @example + * expect(mockFunc).toReturnWith('returnValue'); + */ + toReturnWith: (value: E) => void; + /** + * Use to ensure that a mock function returned a specific value. + * + * Also under the alias `expect.toReturnWith`. + * + * @example + * expect(mockFunc).toHaveReturnedWith('returnValue'); + */ + toHaveReturnedWith: (value: E) => void; + /** + * Use to test the specific value that a mock function last returned. + * If the last call to the mock function threw an error, then this matcher will fail + * no matter what value you provided as the expected return value. + * + * Also under the alias `expect.lastReturnedWith`. + * + * @example + * expect(mockFunc).toHaveLastReturnedWith('lastValue'); + */ + toHaveLastReturnedWith: (value: E) => void; + /** + * Use to test the specific value that a mock function last returned. + * If the last call to the mock function threw an error, then this matcher will fail + * no matter what value you provided as the expected return value. + * + * Alias for `expect.toHaveLastReturnedWith`. + * + * @example + * expect(mockFunc).lastReturnedWith('lastValue'); + */ + lastReturnedWith: (value: E) => void; + /** + * Use to test the specific value that a mock function returned for the nth call. + * If the nth call to the mock function threw an error, then this matcher will fail + * no matter what value you provided as the expected return value. + * + * Also under the alias `expect.nthReturnedWith`. + * + * @example + * expect(mockFunc).toHaveNthReturnedWith(2, 'nthValue'); + */ + toHaveNthReturnedWith: (nthCall: number, value: E) => void; + /** + * Use to test the specific value that a mock function returned for the nth call. + * If the nth call to the mock function threw an error, then this matcher will fail + * no matter what value you provided as the expected return value. + * + * Alias for `expect.toHaveNthReturnedWith`. + * + * @example + * expect(mockFunc).nthReturnedWith(2, 'nthValue'); + */ + nthReturnedWith: (nthCall: number, value: E) => void; +} +type VitestAssertion< + A, + T +> = { [K in keyof A] : A[K] extends Chai.Assertion ? Assertion : A[K] extends (...args: any[]) => any ? A[K] : VitestAssertion } & ((type: string, message?: string) => Assertion); +type Promisify = { [K in keyof O] : O[K] extends (...args: infer A) => infer R ? Promisify & ((...args: A) => Promise) : O[K] }; +type PromisifyAssertion = Promisify>; +interface Assertion extends VitestAssertion, JestAssertion, Matchers { + /** + * Ensures a value is of a specific type. + * + * @example + * expect(value).toBeTypeOf('string'); + * expect(number).toBeTypeOf('number'); + */ + toBeTypeOf: (expected: "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined") => void; + /** + * Asserts that a mock function was called exactly once. + * + * @example + * expect(mockFunc).toHaveBeenCalledOnce(); + */ + toHaveBeenCalledOnce: () => void; + /** + * Ensure that a mock function is called with specific arguments and called + * exactly once. + * + * @example + * expect(mockFunc).toHaveBeenCalledExactlyOnceWith('arg1', 42); + */ + toHaveBeenCalledExactlyOnceWith: (...args: E) => void; + /** + * This assertion checks if a `Mock` was called before another `Mock`. + * @param mock - A mock function created by `vi.spyOn` or `vi.fn` + * @param failIfNoFirstInvocation - Fail if the first mock was never called + * @example + * const mock1 = vi.fn() + * const mock2 = vi.fn() + * + * mock1() + * mock2() + * mock1() + * + * expect(mock1).toHaveBeenCalledBefore(mock2) + */ + toHaveBeenCalledBefore: (mock: MockInstance, failIfNoFirstInvocation?: boolean) => void; + /** + * This assertion checks if a `Mock` was called after another `Mock`. + * @param mock - A mock function created by `vi.spyOn` or `vi.fn` + * @param failIfNoFirstInvocation - Fail if the first mock was never called + * @example + * const mock1 = vi.fn() + * const mock2 = vi.fn() + * + * mock2() + * mock1() + * mock2() + * + * expect(mock1).toHaveBeenCalledAfter(mock2) + */ + toHaveBeenCalledAfter: (mock: MockInstance, failIfNoFirstInvocation?: boolean) => void; + /** + * Checks that a promise resolves successfully at least once. + * + * @example + * await expect(promise).toHaveResolved(); + */ + toHaveResolved: () => void; + /** + * Checks that a promise resolves to a specific value. + * + * @example + * await expect(promise).toHaveResolvedWith('success'); + */ + toHaveResolvedWith: (value: E) => void; + /** + * Ensures a promise resolves a specific number of times. + * + * @example + * expect(mockAsyncFunc).toHaveResolvedTimes(3); + */ + toHaveResolvedTimes: (times: number) => void; + /** + * Asserts that the last resolved value of a promise matches an expected value. + * + * @example + * await expect(mockAsyncFunc).toHaveLastResolvedWith('finalResult'); + */ + toHaveLastResolvedWith: (value: E) => void; + /** + * Ensures a specific value was returned by a promise on the nth resolution. + * + * @example + * await expect(mockAsyncFunc).toHaveNthResolvedWith(2, 'secondResult'); + */ + toHaveNthResolvedWith: (nthCall: number, value: E) => void; + /** + * Verifies that a promise resolves. + * + * @example + * await expect(someAsyncFunc).resolves.toBe(42); + */ + resolves: PromisifyAssertion; + /** + * Verifies that a promise rejects. + * + * @example + * await expect(someAsyncFunc).rejects.toThrow('error'); + */ + rejects: PromisifyAssertion; +} +declare global { + // support augmenting jest.Matchers by other libraries + // eslint-disable-next-line ts/no-namespace + namespace jest { + // eslint-disable-next-line unused-imports/no-unused-vars, ts/no-empty-object-type +interface Matchers< + R, + T = {} + > {} + } +} + +// selectively ported from https://github.com/jest-community/jest-extended +declare const customMatchers: MatchersObject; + +// Jest Expect Compact +declare const JestChaiExpect: ChaiPlugin; + +declare const JestExtend: ChaiPlugin; + +/* +Copyright (c) 2008-2016 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +// Extracted out of jasmine 2.5.2 +declare function equals(a: unknown, b: unknown, customTesters?: Array, strictCheck?: boolean): boolean; +declare function isAsymmetric(obj: any): boolean; +declare function hasAsymmetric(obj: any, seen?: Set): boolean; +declare function isA(typeName: string, value: unknown): boolean; +declare function fnNameFor(func: Function): string; +declare function hasProperty(obj: object | null, property: string): boolean; +declare function isImmutableUnorderedKeyed(maybeKeyed: any): boolean; +declare function isImmutableUnorderedSet(maybeSet: any): boolean; +declare function iterableEquality(a: any, b: any, customTesters?: Array, aStack?: Array, bStack?: Array): boolean | undefined; +declare function subsetEquality(object: unknown, subset: unknown, customTesters?: Array): boolean | undefined; +declare function typeEquality(a: any, b: any): boolean | undefined; +declare function arrayBufferEquality(a: unknown, b: unknown): boolean | undefined; +declare function sparseArrayEquality(a: unknown, b: unknown, customTesters?: Array): boolean | undefined; +declare function generateToBeMessage(deepEqualityName: string, expected?: string, actual?: string): string; +declare function pluralize(word: string, count: number): string; +declare function getObjectKeys(object: object): Array; +declare function getObjectSubset(object: any, subset: any, customTesters: Array): { + subset: any + stripped: number +}; + +declare function getState(expect: ExpectStatic): State; +declare function setState(state: Partial, expect: ExpectStatic): void; + +export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, customMatchers, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality }; +export type { Assertion, AsymmetricMatcherInterface, AsymmetricMatchersContaining, AsyncExpectationResult, ChaiPlugin, DeeplyAllowMatchers, ExpectStatic, ExpectationResult, JestAssertion, MatcherHintOptions, MatcherState, Matchers, MatchersObject, PromisifyAssertion, RawMatcherFn, SyncExpectationResult, Tester, TesterContext }; diff --git a/node_modules/@vitest/expect/dist/index.js b/node_modules/@vitest/expect/dist/index.js new file mode 100644 index 0000000000..db037119d9 --- /dev/null +++ b/node_modules/@vitest/expect/dist/index.js @@ -0,0 +1,1799 @@ +import { getType, stringify, isObject, noop, assertTypes } from '@vitest/utils'; +import { printDiffOrStringify, diff } from '@vitest/utils/diff'; +import c from 'tinyrainbow'; +import { isMockFunction } from '@vitest/spy'; +import { processError } from '@vitest/utils/error'; +import { use, util } from 'chai'; + +const MATCHERS_OBJECT = Symbol.for("matchers-object"); +const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object"); +const GLOBAL_EXPECT = Symbol.for("expect-global"); +const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for("asymmetric-matchers-object"); + +// selectively ported from https://github.com/jest-community/jest-extended +const customMatchers = { + toSatisfy(actual, expected, message) { + const { printReceived, printExpected, matcherHint } = this.utils; + const pass = expected(actual); + return { + pass, + message: () => pass ? `\ +${matcherHint(".not.toSatisfy", "received", "")} + +Expected value to not satisfy: +${message || printExpected(expected)} +Received: +${printReceived(actual)}` : `\ +${matcherHint(".toSatisfy", "received", "")} + +Expected value to satisfy: +${message || printExpected(expected)} + +Received: +${printReceived(actual)}` + }; + }, + toBeOneOf(actual, expected) { + const { equals, customTesters } = this; + const { printReceived, printExpected, matcherHint } = this.utils; + if (!Array.isArray(expected)) { + throw new TypeError(`You must provide an array to ${matcherHint(".toBeOneOf")}, not '${typeof expected}'.`); + } + const pass = expected.length === 0 || expected.some((item) => equals(item, actual, customTesters)); + return { + pass, + message: () => pass ? `\ +${matcherHint(".not.toBeOneOf", "received", "")} + +Expected value to not be one of: +${printExpected(expected)} +Received: +${printReceived(actual)}` : `\ +${matcherHint(".toBeOneOf", "received", "")} + +Expected value to be one of: +${printExpected(expected)} + +Received: +${printReceived(actual)}` + }; + } +}; + +const EXPECTED_COLOR = c.green; +const RECEIVED_COLOR = c.red; +const INVERTED_COLOR = c.inverse; +const BOLD_WEIGHT = c.bold; +const DIM_COLOR = c.dim; +function matcherHint(matcherName, received = "received", expected = "expected", options = {}) { + const { comment = "", isDirectExpectCall = false, isNot = false, promise = "", secondArgument = "", expectedColor = EXPECTED_COLOR, receivedColor = RECEIVED_COLOR, secondArgumentColor = EXPECTED_COLOR } = options; + let hint = ""; + let dimString = "expect"; + if (!isDirectExpectCall && received !== "") { + hint += DIM_COLOR(`${dimString}(`) + receivedColor(received); + dimString = ")"; + } + if (promise !== "") { + hint += DIM_COLOR(`${dimString}.`) + promise; + dimString = ""; + } + if (isNot) { + hint += `${DIM_COLOR(`${dimString}.`)}not`; + dimString = ""; + } + if (matcherName.includes(".")) { + // Old format: for backward compatibility, + // especially without promise or isNot options + dimString += matcherName; + } else { + // New format: omit period from matcherName arg + hint += DIM_COLOR(`${dimString}.`) + matcherName; + dimString = ""; + } + if (expected === "") { + dimString += "()"; + } else { + hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected); + if (secondArgument) { + hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument); + } + dimString = ")"; + } + if (comment !== "") { + dimString += ` // ${comment}`; + } + if (dimString !== "") { + hint += DIM_COLOR(dimString); + } + return hint; +} +const SPACE_SYMBOL = "·"; +// Instead of inverse highlight which now implies a change, +// replace common spaces with middle dot at the end of any line. +function replaceTrailingSpaces(text) { + return text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length)); +} +function printReceived(object) { + return RECEIVED_COLOR(replaceTrailingSpaces(stringify(object))); +} +function printExpected(value) { + return EXPECTED_COLOR(replaceTrailingSpaces(stringify(value))); +} +function getMatcherUtils() { + return { + EXPECTED_COLOR, + RECEIVED_COLOR, + INVERTED_COLOR, + BOLD_WEIGHT, + DIM_COLOR, + diff, + matcherHint, + printReceived, + printExpected, + printDiffOrStringify, + printWithType + }; +} +function printWithType(name, value, print) { + const type = getType(value); + const hasType = type !== "null" && type !== "undefined" ? `${name} has type: ${type}\n` : ""; + const hasValue = `${name} has value: ${print(value)}`; + return hasType + hasValue; +} +function addCustomEqualityTesters(newTesters) { + if (!Array.isArray(newTesters)) { + throw new TypeError(`expect.customEqualityTesters: Must be set to an array of Testers. Was given "${getType(newTesters)}"`); + } + globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters.push(...newTesters); +} +function getCustomEqualityTesters() { + return globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters; +} + +// Extracted out of jasmine 2.5.2 +function equals(a, b, customTesters, strictCheck) { + customTesters = customTesters || []; + return eq(a, b, [], [], customTesters, strictCheck ? hasKey : hasDefinedKey); +} +const functionToString = Function.prototype.toString; +function isAsymmetric(obj) { + return !!obj && typeof obj === "object" && "asymmetricMatch" in obj && isA("Function", obj.asymmetricMatch); +} +function hasAsymmetric(obj, seen = new Set()) { + if (seen.has(obj)) { + return false; + } + seen.add(obj); + if (isAsymmetric(obj)) { + return true; + } + if (Array.isArray(obj)) { + return obj.some((i) => hasAsymmetric(i, seen)); + } + if (obj instanceof Set) { + return Array.from(obj).some((i) => hasAsymmetric(i, seen)); + } + if (isObject(obj)) { + return Object.values(obj).some((v) => hasAsymmetric(v, seen)); + } + return false; +} +function asymmetricMatch(a, b) { + const asymmetricA = isAsymmetric(a); + const asymmetricB = isAsymmetric(b); + if (asymmetricA && asymmetricB) { + return undefined; + } + if (asymmetricA) { + return a.asymmetricMatch(b); + } + if (asymmetricB) { + return b.asymmetricMatch(a); + } +} +// Equality function lovingly adapted from isEqual in +// [Underscore](http://underscorejs.org) +function eq(a, b, aStack, bStack, customTesters, hasKey) { + let result = true; + const asymmetricResult = asymmetricMatch(a, b); + if (asymmetricResult !== undefined) { + return asymmetricResult; + } + const testerContext = { equals }; + for (let i = 0; i < customTesters.length; i++) { + const customTesterResult = customTesters[i].call(testerContext, a, b, customTesters); + if (customTesterResult !== undefined) { + return customTesterResult; + } + } + if (typeof URL === "function" && a instanceof URL && b instanceof URL) { + return a.href === b.href; + } + if (Object.is(a, b)) { + return true; + } + // A strict comparison is necessary because `null == undefined`. + if (a === null || b === null) { + return a === b; + } + const className = Object.prototype.toString.call(a); + if (className !== Object.prototype.toString.call(b)) { + return false; + } + switch (className) { + case "[object Boolean]": + case "[object String]": + case "[object Number]": if (typeof a !== typeof b) { + // One is a primitive, one a `new Primitive()` + return false; + } else if (typeof a !== "object" && typeof b !== "object") { + // both are proper primitives + return Object.is(a, b); + } else { + // both are `new Primitive()`s + return Object.is(a.valueOf(), b.valueOf()); + } + case "[object Date]": { + const numA = +a; + const numB = +b; + // Coerce dates to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are equivalent. + return numA === numB || Number.isNaN(numA) && Number.isNaN(numB); + } + case "[object RegExp]": return a.source === b.source && a.flags === b.flags; + case "[object Temporal.Instant]": + case "[object Temporal.ZonedDateTime]": + case "[object Temporal.PlainDateTime]": + case "[object Temporal.PlainDate]": + case "[object Temporal.PlainTime]": + case "[object Temporal.PlainYearMonth]": + case "[object Temporal.PlainMonthDay]": return a.equals(b); + case "[object Temporal.Duration]": return a.toString() === b.toString(); + } + if (typeof a !== "object" || typeof b !== "object") { + return false; + } + // Use DOM3 method isEqualNode (IE>=9) + if (isDomNode(a) && isDomNode(b)) { + return a.isEqualNode(b); + } + // Used to detect circular references. + let length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + // circular references at same depth are equal + // circular reference is not equal to non-circular one + if (aStack[length] === a) { + return bStack[length] === b; + } else if (bStack[length] === b) { + return false; + } + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + // Recursively compare objects and arrays. + // Compare array lengths to determine if a deep comparison is necessary. + if (className === "[object Array]" && a.length !== b.length) { + return false; + } + if (a instanceof Error && b instanceof Error) { + try { + return isErrorEqual(a, b, aStack, bStack, customTesters, hasKey); + } finally { + aStack.pop(); + bStack.pop(); + } + } + // Deep compare objects. + const aKeys = keys(a, hasKey); + let key; + let size = aKeys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (keys(b, hasKey).length !== size) { + return false; + } + while (size--) { + key = aKeys[size]; + // Deep compare each member + result = hasKey(b, key) && eq(a[key], b[key], aStack, bStack, customTesters, hasKey); + if (!result) { + return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return result; +} +function isErrorEqual(a, b, aStack, bStack, customTesters, hasKey) { + // https://nodejs.org/docs/latest-v22.x/api/assert.html#comparison-details + // - [[Prototype]] of objects are compared using the === operator. + // - Only enumerable "own" properties are considered. + // - Error names, messages, causes, and errors are always compared, even if these are not enumerable properties. errors is also compared. + let result = Object.getPrototypeOf(a) === Object.getPrototypeOf(b) && a.name === b.name && a.message === b.message; + // check Error.cause asymmetrically + if (typeof b.cause !== "undefined") { + result && (result = eq(a.cause, b.cause, aStack, bStack, customTesters, hasKey)); + } + // AggregateError.errors + if (a instanceof AggregateError && b instanceof AggregateError) { + result && (result = eq(a.errors, b.errors, aStack, bStack, customTesters, hasKey)); + } + // spread to compare enumerable properties + result && (result = eq({ ...a }, { ...b }, aStack, bStack, customTesters, hasKey)); + return result; +} +function keys(obj, hasKey) { + const keys = []; + for (const key in obj) { + if (hasKey(obj, key)) { + keys.push(key); + } + } + return keys.concat(Object.getOwnPropertySymbols(obj).filter((symbol) => Object.getOwnPropertyDescriptor(obj, symbol).enumerable)); +} +function hasDefinedKey(obj, key) { + return hasKey(obj, key) && obj[key] !== undefined; +} +function hasKey(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} +function isA(typeName, value) { + return Object.prototype.toString.apply(value) === `[object ${typeName}]`; +} +function isDomNode(obj) { + return obj !== null && typeof obj === "object" && "nodeType" in obj && typeof obj.nodeType === "number" && "nodeName" in obj && typeof obj.nodeName === "string" && "isEqualNode" in obj && typeof obj.isEqualNode === "function"; +} +function fnNameFor(func) { + if (func.name) { + return func.name; + } + const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*(?:\*\s*)?([\w$]+)\s*\(/); + return matches ? matches[1] : ""; +} +function getPrototype(obj) { + if (Object.getPrototypeOf) { + return Object.getPrototypeOf(obj); + } + if (obj.constructor.prototype === obj) { + return null; + } + return obj.constructor.prototype; +} +function hasProperty(obj, property) { + if (!obj) { + return false; + } + if (Object.prototype.hasOwnProperty.call(obj, property)) { + return true; + } + return hasProperty(getPrototype(obj), property); +} +// SENTINEL constants are from https://github.com/facebook/immutable-js +const IS_KEYED_SENTINEL = "@@__IMMUTABLE_KEYED__@@"; +const IS_SET_SENTINEL = "@@__IMMUTABLE_SET__@@"; +const IS_LIST_SENTINEL = "@@__IMMUTABLE_LIST__@@"; +const IS_ORDERED_SENTINEL = "@@__IMMUTABLE_ORDERED__@@"; +const IS_RECORD_SYMBOL = "@@__IMMUTABLE_RECORD__@@"; +function isImmutableUnorderedKeyed(maybeKeyed) { + return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL] && !maybeKeyed[IS_ORDERED_SENTINEL]); +} +function isImmutableUnorderedSet(maybeSet) { + return !!(maybeSet && maybeSet[IS_SET_SENTINEL] && !maybeSet[IS_ORDERED_SENTINEL]); +} +function isObjectLiteral(source) { + return source != null && typeof source === "object" && !Array.isArray(source); +} +function isImmutableList(source) { + return Boolean(source && isObjectLiteral(source) && source[IS_LIST_SENTINEL]); +} +function isImmutableOrderedKeyed(source) { + return Boolean(source && isObjectLiteral(source) && source[IS_KEYED_SENTINEL] && source[IS_ORDERED_SENTINEL]); +} +function isImmutableOrderedSet(source) { + return Boolean(source && isObjectLiteral(source) && source[IS_SET_SENTINEL] && source[IS_ORDERED_SENTINEL]); +} +function isImmutableRecord(source) { + return Boolean(source && isObjectLiteral(source) && source[IS_RECORD_SYMBOL]); +} +/** +* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +*/ +const IteratorSymbol = Symbol.iterator; +function hasIterator(object) { + return !!(object != null && object[IteratorSymbol]); +} +function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) { + if (typeof a !== "object" || typeof b !== "object" || Array.isArray(a) || Array.isArray(b) || !hasIterator(a) || !hasIterator(b)) { + return undefined; + } + if (a.constructor !== b.constructor) { + return false; + } + let length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + // circular references at same depth are equal + // circular reference is not equal to non-circular one + if (aStack[length] === a) { + return bStack[length] === b; + } + } + aStack.push(a); + bStack.push(b); + const filteredCustomTesters = [...customTesters.filter((t) => t !== iterableEquality), iterableEqualityWithStack]; + function iterableEqualityWithStack(a, b) { + return iterableEquality(a, b, [...customTesters], [...aStack], [...bStack]); + } + if (a.size !== undefined) { + if (a.size !== b.size) { + return false; + } else if (isA("Set", a) || isImmutableUnorderedSet(a)) { + let allFound = true; + for (const aValue of a) { + if (!b.has(aValue)) { + let has = false; + for (const bValue of b) { + const isEqual = equals(aValue, bValue, filteredCustomTesters); + if (isEqual === true) { + has = true; + } + } + if (has === false) { + allFound = false; + break; + } + } + } + // Remove the first value from the stack of traversed values. + aStack.pop(); + bStack.pop(); + return allFound; + } else if (isA("Map", a) || isImmutableUnorderedKeyed(a)) { + let allFound = true; + for (const aEntry of a) { + if (!b.has(aEntry[0]) || !equals(aEntry[1], b.get(aEntry[0]), filteredCustomTesters)) { + let has = false; + for (const bEntry of b) { + const matchedKey = equals(aEntry[0], bEntry[0], filteredCustomTesters); + let matchedValue = false; + if (matchedKey === true) { + matchedValue = equals(aEntry[1], bEntry[1], filteredCustomTesters); + } + if (matchedValue === true) { + has = true; + } + } + if (has === false) { + allFound = false; + break; + } + } + } + // Remove the first value from the stack of traversed values. + aStack.pop(); + bStack.pop(); + return allFound; + } + } + const bIterator = b[IteratorSymbol](); + for (const aValue of a) { + const nextB = bIterator.next(); + if (nextB.done || !equals(aValue, nextB.value, filteredCustomTesters)) { + return false; + } + } + if (!bIterator.next().done) { + return false; + } + if (!isImmutableList(a) && !isImmutableOrderedKeyed(a) && !isImmutableOrderedSet(a) && !isImmutableRecord(a)) { + const aEntries = Object.entries(a); + const bEntries = Object.entries(b); + if (!equals(aEntries, bEntries, filteredCustomTesters)) { + return false; + } + } + // Remove the first value from the stack of traversed values. + aStack.pop(); + bStack.pop(); + return true; +} +/** +* Checks if `hasOwnProperty(object, key)` up the prototype chain, stopping at `Object.prototype`. +*/ +function hasPropertyInObject(object, key) { + const shouldTerminate = !object || typeof object !== "object" || object === Object.prototype; + if (shouldTerminate) { + return false; + } + return Object.prototype.hasOwnProperty.call(object, key) || hasPropertyInObject(Object.getPrototypeOf(object), key); +} +function isObjectWithKeys(a) { + return isObject(a) && !(a instanceof Error) && !Array.isArray(a) && !(a instanceof Date); +} +function subsetEquality(object, subset, customTesters = []) { + const filteredCustomTesters = customTesters.filter((t) => t !== subsetEquality); + // subsetEquality needs to keep track of the references + // it has already visited to avoid infinite loops in case + // there are circular references in the subset passed to it. + const subsetEqualityWithContext = (seenReferences = new WeakMap()) => (object, subset) => { + if (!isObjectWithKeys(subset)) { + return undefined; + } + return Object.keys(subset).every((key) => { + if (subset[key] != null && typeof subset[key] === "object") { + if (seenReferences.has(subset[key])) { + return equals(object[key], subset[key], filteredCustomTesters); + } + seenReferences.set(subset[key], true); + } + const result = object != null && hasPropertyInObject(object, key) && equals(object[key], subset[key], [...filteredCustomTesters, subsetEqualityWithContext(seenReferences)]); + // The main goal of using seenReference is to avoid circular node on tree. + // It will only happen within a parent and its child, not a node and nodes next to it (same level) + // We should keep the reference for a parent and its child only + // Thus we should delete the reference immediately so that it doesn't interfere + // other nodes within the same level on tree. + seenReferences.delete(subset[key]); + return result; + }); + }; + return subsetEqualityWithContext()(object, subset); +} +function typeEquality(a, b) { + if (a == null || b == null || a.constructor === b.constructor) { + return undefined; + } + return false; +} +function arrayBufferEquality(a, b) { + let dataViewA = a; + let dataViewB = b; + if (!(a instanceof DataView && b instanceof DataView)) { + if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer)) { + return undefined; + } + try { + dataViewA = new DataView(a); + dataViewB = new DataView(b); + } catch { + return undefined; + } + } + // Buffers are not equal when they do not have the same byte length + if (dataViewA.byteLength !== dataViewB.byteLength) { + return false; + } + // Check if every byte value is equal to each other + for (let i = 0; i < dataViewA.byteLength; i++) { + if (dataViewA.getUint8(i) !== dataViewB.getUint8(i)) { + return false; + } + } + return true; +} +function sparseArrayEquality(a, b, customTesters = []) { + if (!Array.isArray(a) || !Array.isArray(b)) { + return undefined; + } + // A sparse array [, , 1] will have keys ["2"] whereas [undefined, undefined, 1] will have keys ["0", "1", "2"] + const aKeys = Object.keys(a); + const bKeys = Object.keys(b); + const filteredCustomTesters = customTesters.filter((t) => t !== sparseArrayEquality); + return equals(a, b, filteredCustomTesters, true) && equals(aKeys, bKeys); +} +function generateToBeMessage(deepEqualityName, expected = "#{this}", actual = "#{exp}") { + const toBeMessage = `expected ${expected} to be ${actual} // Object.is equality`; + if (["toStrictEqual", "toEqual"].includes(deepEqualityName)) { + return `${toBeMessage}\n\nIf it should pass with deep equality, replace "toBe" with "${deepEqualityName}"\n\nExpected: ${expected}\nReceived: serializes to the same string\n`; + } + return toBeMessage; +} +function pluralize(word, count) { + return `${count} ${word}${count === 1 ? "" : "s"}`; +} +function getObjectKeys(object) { + return [...Object.keys(object), ...Object.getOwnPropertySymbols(object).filter((s) => { + var _Object$getOwnPropert; + return (_Object$getOwnPropert = Object.getOwnPropertyDescriptor(object, s)) === null || _Object$getOwnPropert === void 0 ? void 0 : _Object$getOwnPropert.enumerable; + })]; +} +function getObjectSubset(object, subset, customTesters) { + let stripped = 0; + const getObjectSubsetWithContext = (seenReferences = new WeakMap()) => (object, subset) => { + if (Array.isArray(object)) { + if (Array.isArray(subset) && subset.length === object.length) { + // The map method returns correct subclass of subset. + return subset.map((sub, i) => getObjectSubsetWithContext(seenReferences)(object[i], sub)); + } + } else if (object instanceof Date) { + return object; + } else if (isObject(object) && isObject(subset)) { + if (equals(object, subset, [ + ...customTesters, + iterableEquality, + subsetEquality + ])) { + // return "expected" subset to avoid showing irrelevant toMatchObject diff + return subset; + } + const trimmed = {}; + seenReferences.set(object, trimmed); + // preserve constructor for toMatchObject diff + if (typeof object.constructor === "function" && typeof object.constructor.name === "string") { + Object.defineProperty(trimmed, "constructor", { + enumerable: false, + value: object.constructor + }); + } + for (const key of getObjectKeys(object)) { + if (hasPropertyInObject(subset, key)) { + trimmed[key] = seenReferences.has(object[key]) ? seenReferences.get(object[key]) : getObjectSubsetWithContext(seenReferences)(object[key], subset[key]); + } else { + if (!seenReferences.has(object[key])) { + stripped += 1; + if (isObject(object[key])) { + stripped += getObjectKeys(object[key]).length; + } + getObjectSubsetWithContext(seenReferences)(object[key], subset[key]); + } + } + } + if (getObjectKeys(trimmed).length > 0) { + return trimmed; + } + } + return object; + }; + return { + subset: getObjectSubsetWithContext()(object, subset), + stripped + }; +} + +if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) { + const globalState = new WeakMap(); + const matchers = Object.create(null); + const customEqualityTesters = []; + const asymmetricMatchers = Object.create(null); + Object.defineProperty(globalThis, MATCHERS_OBJECT, { get: () => globalState }); + Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, { + configurable: true, + get: () => ({ + state: globalState.get(globalThis[GLOBAL_EXPECT]), + matchers, + customEqualityTesters + }) + }); + Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, { get: () => asymmetricMatchers }); +} +function getState(expect) { + return globalThis[MATCHERS_OBJECT].get(expect); +} +function setState(state, expect) { + const map = globalThis[MATCHERS_OBJECT]; + const current = map.get(expect) || {}; + // so it keeps getters from `testPath` + const results = Object.defineProperties(current, { + ...Object.getOwnPropertyDescriptors(current), + ...Object.getOwnPropertyDescriptors(state) + }); + map.set(expect, results); +} + +class AsymmetricMatcher { + // should have "jest" to be compatible with its ecosystem + $$typeof = Symbol.for("jest.asymmetricMatcher"); + constructor(sample, inverse = false) { + this.sample = sample; + this.inverse = inverse; + } + getMatcherContext(expect) { + return { + ...getState(expect || globalThis[GLOBAL_EXPECT]), + equals, + isNot: this.inverse, + customTesters: getCustomEqualityTesters(), + utils: { + ...getMatcherUtils(), + diff, + stringify, + iterableEquality, + subsetEquality + } + }; + } +} +// implement custom chai/loupe inspect for better AssertionError.message formatting +// https://github.com/chaijs/loupe/blob/9b8a6deabcd50adc056a64fb705896194710c5c6/src/index.ts#L29 +// @ts-expect-error computed properties is not supported when isolatedDeclarations is enabled +// FIXME: https://github.com/microsoft/TypeScript/issues/61068 +AsymmetricMatcher.prototype[Symbol.for("chai/inspect")] = function(options) { + // minimal pretty-format with simple manual truncation + const result = stringify(this, options.depth, { min: true }); + if (result.length <= options.truncate) { + return result; + } + return `${this.toString()}{…}`; +}; +class StringContaining extends AsymmetricMatcher { + constructor(sample, inverse = false) { + if (!isA("String", sample)) { + throw new Error("Expected is not a string"); + } + super(sample, inverse); + } + asymmetricMatch(other) { + const result = isA("String", other) && other.includes(this.sample); + return this.inverse ? !result : result; + } + toString() { + return `String${this.inverse ? "Not" : ""}Containing`; + } + getExpectedType() { + return "string"; + } +} +class Anything extends AsymmetricMatcher { + asymmetricMatch(other) { + return other != null; + } + toString() { + return "Anything"; + } + toAsymmetricMatcher() { + return "Anything"; + } +} +class ObjectContaining extends AsymmetricMatcher { + constructor(sample, inverse = false) { + super(sample, inverse); + } + getPrototype(obj) { + if (Object.getPrototypeOf) { + return Object.getPrototypeOf(obj); + } + if (obj.constructor.prototype === obj) { + return null; + } + return obj.constructor.prototype; + } + hasProperty(obj, property) { + if (!obj) { + return false; + } + if (Object.prototype.hasOwnProperty.call(obj, property)) { + return true; + } + return this.hasProperty(this.getPrototype(obj), property); + } + asymmetricMatch(other) { + if (typeof this.sample !== "object") { + throw new TypeError(`You must provide an object to ${this.toString()}, not '${typeof this.sample}'.`); + } + let result = true; + const matcherContext = this.getMatcherContext(); + for (const property in this.sample) { + if (!this.hasProperty(other, property) || !equals(this.sample[property], other[property], matcherContext.customTesters)) { + result = false; + break; + } + } + return this.inverse ? !result : result; + } + toString() { + return `Object${this.inverse ? "Not" : ""}Containing`; + } + getExpectedType() { + return "object"; + } +} +class ArrayContaining extends AsymmetricMatcher { + constructor(sample, inverse = false) { + super(sample, inverse); + } + asymmetricMatch(other) { + if (!Array.isArray(this.sample)) { + throw new TypeError(`You must provide an array to ${this.toString()}, not '${typeof this.sample}'.`); + } + const matcherContext = this.getMatcherContext(); + const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every((item) => other.some((another) => equals(item, another, matcherContext.customTesters))); + return this.inverse ? !result : result; + } + toString() { + return `Array${this.inverse ? "Not" : ""}Containing`; + } + getExpectedType() { + return "array"; + } +} +class Any extends AsymmetricMatcher { + constructor(sample) { + if (typeof sample === "undefined") { + throw new TypeError("any() expects to be passed a constructor function. " + "Please pass one or use anything() to match any object."); + } + super(sample); + } + fnNameFor(func) { + if (func.name) { + return func.name; + } + const functionToString = Function.prototype.toString; + const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*(?:\*\s*)?([\w$]+)\s*\(/); + return matches ? matches[1] : ""; + } + asymmetricMatch(other) { + if (this.sample === String) { + return typeof other == "string" || other instanceof String; + } + if (this.sample === Number) { + return typeof other == "number" || other instanceof Number; + } + if (this.sample === Function) { + return typeof other == "function" || typeof other === "function"; + } + if (this.sample === Boolean) { + return typeof other == "boolean" || other instanceof Boolean; + } + if (this.sample === BigInt) { + return typeof other == "bigint" || other instanceof BigInt; + } + if (this.sample === Symbol) { + return typeof other == "symbol" || other instanceof Symbol; + } + if (this.sample === Object) { + return typeof other == "object"; + } + return other instanceof this.sample; + } + toString() { + return "Any"; + } + getExpectedType() { + if (this.sample === String) { + return "string"; + } + if (this.sample === Number) { + return "number"; + } + if (this.sample === Function) { + return "function"; + } + if (this.sample === Object) { + return "object"; + } + if (this.sample === Boolean) { + return "boolean"; + } + return this.fnNameFor(this.sample); + } + toAsymmetricMatcher() { + return `Any<${this.fnNameFor(this.sample)}>`; + } +} +class StringMatching extends AsymmetricMatcher { + constructor(sample, inverse = false) { + if (!isA("String", sample) && !isA("RegExp", sample)) { + throw new Error("Expected is not a String or a RegExp"); + } + super(new RegExp(sample), inverse); + } + asymmetricMatch(other) { + const result = isA("String", other) && this.sample.test(other); + return this.inverse ? !result : result; + } + toString() { + return `String${this.inverse ? "Not" : ""}Matching`; + } + getExpectedType() { + return "string"; + } +} +class CloseTo extends AsymmetricMatcher { + precision; + constructor(sample, precision = 2, inverse = false) { + if (!isA("Number", sample)) { + throw new Error("Expected is not a Number"); + } + if (!isA("Number", precision)) { + throw new Error("Precision is not a Number"); + } + super(sample); + this.inverse = inverse; + this.precision = precision; + } + asymmetricMatch(other) { + if (!isA("Number", other)) { + return false; + } + let result = false; + if (other === Number.POSITIVE_INFINITY && this.sample === Number.POSITIVE_INFINITY) { + result = true; + } else if (other === Number.NEGATIVE_INFINITY && this.sample === Number.NEGATIVE_INFINITY) { + result = true; + } else { + result = Math.abs(this.sample - other) < 10 ** -this.precision / 2; + } + return this.inverse ? !result : result; + } + toString() { + return `Number${this.inverse ? "Not" : ""}CloseTo`; + } + getExpectedType() { + return "number"; + } + toAsymmetricMatcher() { + return [ + this.toString(), + this.sample, + `(${pluralize("digit", this.precision)})` + ].join(" "); + } +} +const JestAsymmetricMatchers = (chai, utils) => { + utils.addMethod(chai.expect, "anything", () => new Anything()); + utils.addMethod(chai.expect, "any", (expected) => new Any(expected)); + utils.addMethod(chai.expect, "stringContaining", (expected) => new StringContaining(expected)); + utils.addMethod(chai.expect, "objectContaining", (expected) => new ObjectContaining(expected)); + utils.addMethod(chai.expect, "arrayContaining", (expected) => new ArrayContaining(expected)); + utils.addMethod(chai.expect, "stringMatching", (expected) => new StringMatching(expected)); + utils.addMethod(chai.expect, "closeTo", (expected, precision) => new CloseTo(expected, precision)); + // defineProperty does not work + chai.expect.not = { + stringContaining: (expected) => new StringContaining(expected, true), + objectContaining: (expected) => new ObjectContaining(expected, true), + arrayContaining: (expected) => new ArrayContaining(expected, true), + stringMatching: (expected) => new StringMatching(expected, true), + closeTo: (expected, precision) => new CloseTo(expected, precision, true) + }; +}; + +function createAssertionMessage(util, assertion, hasArgs) { + const not = util.flag(assertion, "negate") ? "not." : ""; + const name = `${util.flag(assertion, "_name")}(${hasArgs ? "expected" : ""})`; + const promiseName = util.flag(assertion, "promise"); + const promise = promiseName ? `.${promiseName}` : ""; + return `expect(actual)${promise}.${not}${name}`; +} +function recordAsyncExpect(_test, promise, assertion, error) { + const test = _test; + // record promise for test, that resolves before test ends + if (test && promise instanceof Promise) { + // if promise is explicitly awaited, remove it from the list + promise = promise.finally(() => { + if (!test.promises) { + return; + } + const index = test.promises.indexOf(promise); + if (index !== -1) { + test.promises.splice(index, 1); + } + }); + // record promise + if (!test.promises) { + test.promises = []; + } + test.promises.push(promise); + let resolved = false; + test.onFinished ?? (test.onFinished = []); + test.onFinished.push(() => { + if (!resolved) { + var _vitest_worker__; + const processor = ((_vitest_worker__ = globalThis.__vitest_worker__) === null || _vitest_worker__ === void 0 ? void 0 : _vitest_worker__.onFilterStackTrace) || ((s) => s || ""); + const stack = processor(error.stack); + console.warn([ + `Promise returned by \`${assertion}\` was not awaited. `, + "Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in Vitest 3. ", + "Please remember to await the assertion.\n", + stack + ].join("")); + } + }); + return { + then(onFulfilled, onRejected) { + resolved = true; + return promise.then(onFulfilled, onRejected); + }, + catch(onRejected) { + return promise.catch(onRejected); + }, + finally(onFinally) { + return promise.finally(onFinally); + }, + [Symbol.toStringTag]: "Promise" + }; + } + return promise; +} +function handleTestError(test, err) { + var _test$result; + test.result || (test.result = { state: "fail" }); + test.result.state = "fail"; + (_test$result = test.result).errors || (_test$result.errors = []); + test.result.errors.push(processError(err)); +} +function wrapAssertion(utils, name, fn) { + return function(...args) { + // private + if (name !== "withTest") { + utils.flag(this, "_name", name); + } + if (!utils.flag(this, "soft")) { + return fn.apply(this, args); + } + const test = utils.flag(this, "vitest-test"); + if (!test) { + throw new Error("expect.soft() can only be used inside a test"); + } + try { + const result = fn.apply(this, args); + if (result && typeof result === "object" && typeof result.then === "function") { + return result.then(noop, (err) => { + handleTestError(test, err); + }); + } + return result; + } catch (err) { + handleTestError(test, err); + } + }; +} + +// Jest Expect Compact +const JestChaiExpect = (chai, utils) => { + const { AssertionError } = chai; + const customTesters = getCustomEqualityTesters(); + function def(name, fn) { + const addMethod = (n) => { + const softWrapper = wrapAssertion(utils, n, fn); + utils.addMethod(chai.Assertion.prototype, n, softWrapper); + utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, n, softWrapper); + }; + if (Array.isArray(name)) { + name.forEach((n) => addMethod(n)); + } else { + addMethod(name); + } + } + [ + "throw", + "throws", + "Throw" + ].forEach((m) => { + utils.overwriteMethod(chai.Assertion.prototype, m, (_super) => { + return function(...args) { + const promise = utils.flag(this, "promise"); + const object = utils.flag(this, "object"); + const isNot = utils.flag(this, "negate"); + if (promise === "rejects") { + utils.flag(this, "object", () => { + throw object; + }); + } else if (promise === "resolves" && typeof object !== "function") { + if (!isNot) { + const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't"; + const error = { showDiff: false }; + throw new AssertionError(message, error, utils.flag(this, "ssfi")); + } else { + return; + } + } + _super.apply(this, args); + }; + }); + }); + // @ts-expect-error @internal + def("withTest", function(test) { + utils.flag(this, "vitest-test", test); + return this; + }); + def("toEqual", function(expected) { + const actual = utils.flag(this, "object"); + const equal = equals(actual, expected, [...customTesters, iterableEquality]); + return this.assert(equal, "expected #{this} to deeply equal #{exp}", "expected #{this} to not deeply equal #{exp}", expected, actual); + }); + def("toStrictEqual", function(expected) { + const obj = utils.flag(this, "object"); + const equal = equals(obj, expected, [ + ...customTesters, + iterableEquality, + typeEquality, + sparseArrayEquality, + arrayBufferEquality + ], true); + return this.assert(equal, "expected #{this} to strictly equal #{exp}", "expected #{this} to not strictly equal #{exp}", expected, obj); + }); + def("toBe", function(expected) { + const actual = this._obj; + const pass = Object.is(actual, expected); + let deepEqualityName = ""; + if (!pass) { + const toStrictEqualPass = equals(actual, expected, [ + ...customTesters, + iterableEquality, + typeEquality, + sparseArrayEquality, + arrayBufferEquality + ], true); + if (toStrictEqualPass) { + deepEqualityName = "toStrictEqual"; + } else { + const toEqualPass = equals(actual, expected, [...customTesters, iterableEquality]); + if (toEqualPass) { + deepEqualityName = "toEqual"; + } + } + } + return this.assert(pass, generateToBeMessage(deepEqualityName), "expected #{this} not to be #{exp} // Object.is equality", expected, actual); + }); + def("toMatchObject", function(expected) { + const actual = this._obj; + const pass = equals(actual, expected, [ + ...customTesters, + iterableEquality, + subsetEquality + ]); + const isNot = utils.flag(this, "negate"); + const { subset: actualSubset, stripped } = getObjectSubset(actual, expected, customTesters); + if (pass && isNot || !pass && !isNot) { + const msg = utils.getMessage(this, [ + pass, + "expected #{this} to match object #{exp}", + "expected #{this} to not match object #{exp}", + expected, + actualSubset, + false + ]); + const message = stripped === 0 ? msg : `${msg}\n(${stripped} matching ${stripped === 1 ? "property" : "properties"} omitted from actual)`; + throw new AssertionError(message, { + showDiff: true, + expected, + actual: actualSubset + }); + } + }); + def("toMatch", function(expected) { + const actual = this._obj; + if (typeof actual !== "string") { + throw new TypeError(`.toMatch() expects to receive a string, but got ${typeof actual}`); + } + return this.assert(typeof expected === "string" ? actual.includes(expected) : actual.match(expected), `expected #{this} to match #{exp}`, `expected #{this} not to match #{exp}`, expected, actual); + }); + def("toContain", function(item) { + const actual = this._obj; + if (typeof Node !== "undefined" && actual instanceof Node) { + if (!(item instanceof Node)) { + throw new TypeError(`toContain() expected a DOM node as the argument, but got ${typeof item}`); + } + return this.assert(actual.contains(item), "expected #{this} to contain element #{exp}", "expected #{this} not to contain element #{exp}", item, actual); + } + if (typeof DOMTokenList !== "undefined" && actual instanceof DOMTokenList) { + assertTypes(item, "class name", ["string"]); + const isNot = utils.flag(this, "negate"); + const expectedClassList = isNot ? actual.value.replace(item, "").trim() : `${actual.value} ${item}`; + return this.assert(actual.contains(item), `expected "${actual.value}" to contain "${item}"`, `expected "${actual.value}" not to contain "${item}"`, expectedClassList, actual.value); + } + // handle simple case on our own using `this.assert` to include diff in error message + if (typeof actual === "string" && typeof item === "string") { + return this.assert(actual.includes(item), `expected #{this} to contain #{exp}`, `expected #{this} not to contain #{exp}`, item, actual); + } + // make "actual" indexable to have compatibility with jest + if (actual != null && typeof actual !== "string") { + utils.flag(this, "object", Array.from(actual)); + } + return this.contain(item); + }); + def("toContainEqual", function(expected) { + const obj = utils.flag(this, "object"); + const index = Array.from(obj).findIndex((item) => { + return equals(item, expected, customTesters); + }); + this.assert(index !== -1, "expected #{this} to deep equally contain #{exp}", "expected #{this} to not deep equally contain #{exp}", expected); + }); + def("toBeTruthy", function() { + const obj = utils.flag(this, "object"); + this.assert(Boolean(obj), "expected #{this} to be truthy", "expected #{this} to not be truthy", true, obj); + }); + def("toBeFalsy", function() { + const obj = utils.flag(this, "object"); + this.assert(!obj, "expected #{this} to be falsy", "expected #{this} to not be falsy", false, obj); + }); + def("toBeGreaterThan", function(expected) { + const actual = this._obj; + assertTypes(actual, "actual", ["number", "bigint"]); + assertTypes(expected, "expected", ["number", "bigint"]); + return this.assert(actual > expected, `expected ${actual} to be greater than ${expected}`, `expected ${actual} to be not greater than ${expected}`, expected, actual, false); + }); + def("toBeGreaterThanOrEqual", function(expected) { + const actual = this._obj; + assertTypes(actual, "actual", ["number", "bigint"]); + assertTypes(expected, "expected", ["number", "bigint"]); + return this.assert(actual >= expected, `expected ${actual} to be greater than or equal to ${expected}`, `expected ${actual} to be not greater than or equal to ${expected}`, expected, actual, false); + }); + def("toBeLessThan", function(expected) { + const actual = this._obj; + assertTypes(actual, "actual", ["number", "bigint"]); + assertTypes(expected, "expected", ["number", "bigint"]); + return this.assert(actual < expected, `expected ${actual} to be less than ${expected}`, `expected ${actual} to be not less than ${expected}`, expected, actual, false); + }); + def("toBeLessThanOrEqual", function(expected) { + const actual = this._obj; + assertTypes(actual, "actual", ["number", "bigint"]); + assertTypes(expected, "expected", ["number", "bigint"]); + return this.assert(actual <= expected, `expected ${actual} to be less than or equal to ${expected}`, `expected ${actual} to be not less than or equal to ${expected}`, expected, actual, false); + }); + def("toBeNaN", function() { + const obj = utils.flag(this, "object"); + this.assert(Number.isNaN(obj), "expected #{this} to be NaN", "expected #{this} not to be NaN", Number.NaN, obj); + }); + def("toBeUndefined", function() { + const obj = utils.flag(this, "object"); + this.assert(undefined === obj, "expected #{this} to be undefined", "expected #{this} not to be undefined", undefined, obj); + }); + def("toBeNull", function() { + const obj = utils.flag(this, "object"); + this.assert(obj === null, "expected #{this} to be null", "expected #{this} not to be null", null, obj); + }); + def("toBeDefined", function() { + const obj = utils.flag(this, "object"); + this.assert(typeof obj !== "undefined", "expected #{this} to be defined", "expected #{this} to be undefined", obj); + }); + def("toBeTypeOf", function(expected) { + const actual = typeof this._obj; + const equal = expected === actual; + return this.assert(equal, "expected #{this} to be type of #{exp}", "expected #{this} not to be type of #{exp}", expected, actual); + }); + def("toBeInstanceOf", function(obj) { + return this.instanceOf(obj); + }); + def("toHaveLength", function(length) { + return this.have.length(length); + }); + // destructuring, because it checks `arguments` inside, and value is passing as `undefined` + def("toHaveProperty", function(...args) { + if (Array.isArray(args[0])) { + args[0] = args[0].map((key) => String(key).replace(/([.[\]])/g, "\\$1")).join("."); + } + const actual = this._obj; + const [propertyName, expected] = args; + const getValue = () => { + const hasOwn = Object.prototype.hasOwnProperty.call(actual, propertyName); + if (hasOwn) { + return { + value: actual[propertyName], + exists: true + }; + } + return utils.getPathInfo(actual, propertyName); + }; + const { value, exists } = getValue(); + const pass = exists && (args.length === 1 || equals(expected, value, customTesters)); + const valueString = args.length === 1 ? "" : ` with value ${utils.objDisplay(expected)}`; + return this.assert(pass, `expected #{this} to have property "${propertyName}"${valueString}`, `expected #{this} to not have property "${propertyName}"${valueString}`, expected, exists ? value : undefined); + }); + def("toBeCloseTo", function(received, precision = 2) { + const expected = this._obj; + let pass = false; + let expectedDiff = 0; + let receivedDiff = 0; + if (received === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) { + pass = true; + } else if (received === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) { + pass = true; + } else { + expectedDiff = 10 ** -precision / 2; + receivedDiff = Math.abs(expected - received); + pass = receivedDiff < expectedDiff; + } + return this.assert(pass, `expected #{this} to be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, `expected #{this} to not be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, received, expected, false); + }); + function assertIsMock(assertion) { + if (!isMockFunction(assertion._obj)) { + throw new TypeError(`${utils.inspect(assertion._obj)} is not a spy or a call to a spy!`); + } + } + function getSpy(assertion) { + assertIsMock(assertion); + return assertion._obj; + } + def(["toHaveBeenCalledTimes", "toBeCalledTimes"], function(number) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const callCount = spy.mock.calls.length; + return this.assert(callCount === number, `expected "${spyName}" to be called #{exp} times, but got ${callCount} times`, `expected "${spyName}" to not be called #{exp} times`, number, callCount, false); + }); + def("toHaveBeenCalledOnce", function() { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const callCount = spy.mock.calls.length; + return this.assert(callCount === 1, `expected "${spyName}" to be called once, but got ${callCount} times`, `expected "${spyName}" to not be called once`, 1, callCount, false); + }); + def(["toHaveBeenCalled", "toBeCalled"], function() { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const callCount = spy.mock.calls.length; + const called = callCount > 0; + const isNot = utils.flag(this, "negate"); + let msg = utils.getMessage(this, [ + called, + `expected "${spyName}" to be called at least once`, + `expected "${spyName}" to not be called at all, but actually been called ${callCount} times`, + true, + called + ]); + if (called && isNot) { + msg = formatCalls(spy, msg); + } + if (called && isNot || !called && !isNot) { + throw new AssertionError(msg); + } + }); + // manually compare array elements since `jestEquals` cannot + // apply asymmetric matcher to `undefined` array element. + function equalsArgumentArray(a, b) { + return a.length === b.length && a.every((aItem, i) => equals(aItem, b[i], [...customTesters, iterableEquality])); + } + def(["toHaveBeenCalledWith", "toBeCalledWith"], function(...args) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const pass = spy.mock.calls.some((callArg) => equalsArgumentArray(callArg, args)); + const isNot = utils.flag(this, "negate"); + const msg = utils.getMessage(this, [ + pass, + `expected "${spyName}" to be called with arguments: #{exp}`, + `expected "${spyName}" to not be called with arguments: #{exp}`, + args + ]); + if (pass && isNot || !pass && !isNot) { + throw new AssertionError(formatCalls(spy, msg, args)); + } + }); + def("toHaveBeenCalledExactlyOnceWith", function(...args) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const callCount = spy.mock.calls.length; + const hasCallWithArgs = spy.mock.calls.some((callArg) => equalsArgumentArray(callArg, args)); + const pass = hasCallWithArgs && callCount === 1; + const isNot = utils.flag(this, "negate"); + const msg = utils.getMessage(this, [ + pass, + `expected "${spyName}" to be called once with arguments: #{exp}`, + `expected "${spyName}" to not be called once with arguments: #{exp}`, + args + ]); + if (pass && isNot || !pass && !isNot) { + throw new AssertionError(formatCalls(spy, msg, args)); + } + }); + def(["toHaveBeenNthCalledWith", "nthCalledWith"], function(times, ...args) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const nthCall = spy.mock.calls[times - 1]; + const callCount = spy.mock.calls.length; + const isCalled = times <= callCount; + this.assert(nthCall && equalsArgumentArray(nthCall, args), `expected ${ordinalOf(times)} "${spyName}" call to have been called with #{exp}${isCalled ? `` : `, but called only ${callCount} times`}`, `expected ${ordinalOf(times)} "${spyName}" call to not have been called with #{exp}`, args, nthCall, isCalled); + }); + def(["toHaveBeenLastCalledWith", "lastCalledWith"], function(...args) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const lastCall = spy.mock.calls[spy.mock.calls.length - 1]; + this.assert(lastCall && equalsArgumentArray(lastCall, args), `expected last "${spyName}" call to have been called with #{exp}`, `expected last "${spyName}" call to not have been called with #{exp}`, args, lastCall); + }); + /** + * Used for `toHaveBeenCalledBefore` and `toHaveBeenCalledAfter` to determine if the expected spy was called before the result spy. + */ + function isSpyCalledBeforeAnotherSpy(beforeSpy, afterSpy, failIfNoFirstInvocation) { + const beforeInvocationCallOrder = beforeSpy.mock.invocationCallOrder; + const afterInvocationCallOrder = afterSpy.mock.invocationCallOrder; + if (beforeInvocationCallOrder.length === 0) { + return !failIfNoFirstInvocation; + } + if (afterInvocationCallOrder.length === 0) { + return false; + } + return beforeInvocationCallOrder[0] < afterInvocationCallOrder[0]; + } + def(["toHaveBeenCalledBefore"], function(resultSpy, failIfNoFirstInvocation = true) { + const expectSpy = getSpy(this); + if (!isMockFunction(resultSpy)) { + throw new TypeError(`${utils.inspect(resultSpy)} is not a spy or a call to a spy`); + } + this.assert(isSpyCalledBeforeAnotherSpy(expectSpy, resultSpy, failIfNoFirstInvocation), `expected "${expectSpy.getMockName()}" to have been called before "${resultSpy.getMockName()}"`, `expected "${expectSpy.getMockName()}" to not have been called before "${resultSpy.getMockName()}"`, resultSpy, expectSpy); + }); + def(["toHaveBeenCalledAfter"], function(resultSpy, failIfNoFirstInvocation = true) { + const expectSpy = getSpy(this); + if (!isMockFunction(resultSpy)) { + throw new TypeError(`${utils.inspect(resultSpy)} is not a spy or a call to a spy`); + } + this.assert(isSpyCalledBeforeAnotherSpy(resultSpy, expectSpy, failIfNoFirstInvocation), `expected "${expectSpy.getMockName()}" to have been called after "${resultSpy.getMockName()}"`, `expected "${expectSpy.getMockName()}" to not have been called after "${resultSpy.getMockName()}"`, resultSpy, expectSpy); + }); + def(["toThrow", "toThrowError"], function(expected) { + if (typeof expected === "string" || typeof expected === "undefined" || expected instanceof RegExp) { + // Fixes the issue related to `chai` + return this.throws(expected === "" ? /^$/ : expected); + } + const obj = this._obj; + const promise = utils.flag(this, "promise"); + const isNot = utils.flag(this, "negate"); + let thrown = null; + if (promise === "rejects") { + thrown = obj; + } else if (promise === "resolves" && typeof obj !== "function") { + if (!isNot) { + const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't"; + const error = { showDiff: false }; + throw new AssertionError(message, error, utils.flag(this, "ssfi")); + } else { + return; + } + } else { + let isThrow = false; + try { + obj(); + } catch (err) { + isThrow = true; + thrown = err; + } + if (!isThrow && !isNot) { + const message = utils.flag(this, "message") || "expected function to throw an error, but it didn't"; + const error = { showDiff: false }; + throw new AssertionError(message, error, utils.flag(this, "ssfi")); + } + } + if (typeof expected === "function") { + const name = expected.name || expected.prototype.constructor.name; + return this.assert(thrown && thrown instanceof expected, `expected error to be instance of ${name}`, `expected error not to be instance of ${name}`, expected, thrown); + } + if (expected instanceof Error) { + const equal = equals(thrown, expected, [...customTesters, iterableEquality]); + return this.assert(equal, "expected a thrown error to be #{exp}", "expected a thrown error not to be #{exp}", expected, thrown); + } + if (typeof expected === "object" && "asymmetricMatch" in expected && typeof expected.asymmetricMatch === "function") { + const matcher = expected; + return this.assert(thrown && matcher.asymmetricMatch(thrown), "expected error to match asymmetric matcher", "expected error not to match asymmetric matcher", matcher, thrown); + } + throw new Error(`"toThrow" expects string, RegExp, function, Error instance or asymmetric matcher, got "${typeof expected}"`); + }); + [{ + name: "toHaveResolved", + condition: (spy) => spy.mock.settledResults.length > 0 && spy.mock.settledResults.some(({ type }) => type === "fulfilled"), + action: "resolved" + }, { + name: ["toHaveReturned", "toReturn"], + condition: (spy) => spy.mock.calls.length > 0 && spy.mock.results.some(({ type }) => type !== "throw"), + action: "called" + }].forEach(({ name, condition, action }) => { + def(name, function() { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const pass = condition(spy); + this.assert(pass, `expected "${spyName}" to be successfully ${action} at least once`, `expected "${spyName}" to not be successfully ${action}`, pass, !pass, false); + }); + }); + [{ + name: "toHaveResolvedTimes", + condition: (spy, times) => spy.mock.settledResults.reduce((s, { type }) => type === "fulfilled" ? ++s : s, 0) === times, + action: "resolved" + }, { + name: ["toHaveReturnedTimes", "toReturnTimes"], + condition: (spy, times) => spy.mock.results.reduce((s, { type }) => type === "throw" ? s : ++s, 0) === times, + action: "called" + }].forEach(({ name, condition, action }) => { + def(name, function(times) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const pass = condition(spy, times); + this.assert(pass, `expected "${spyName}" to be successfully ${action} ${times} times`, `expected "${spyName}" to not be successfully ${action} ${times} times`, `expected resolved times: ${times}`, `received resolved times: ${pass}`, false); + }); + }); + [{ + name: "toHaveResolvedWith", + condition: (spy, value) => spy.mock.settledResults.some(({ type, value: result }) => type === "fulfilled" && equals(value, result)), + action: "resolve" + }, { + name: ["toHaveReturnedWith", "toReturnWith"], + condition: (spy, value) => spy.mock.results.some(({ type, value: result }) => type === "return" && equals(value, result)), + action: "return" + }].forEach(({ name, condition, action }) => { + def(name, function(value) { + const spy = getSpy(this); + const pass = condition(spy, value); + const isNot = utils.flag(this, "negate"); + if (pass && isNot || !pass && !isNot) { + const spyName = spy.getMockName(); + const msg = utils.getMessage(this, [ + pass, + `expected "${spyName}" to ${action} with: #{exp} at least once`, + `expected "${spyName}" to not ${action} with: #{exp}`, + value + ]); + const results = action === "return" ? spy.mock.results : spy.mock.settledResults; + throw new AssertionError(formatReturns(spy, results, msg, value)); + } + }); + }); + [{ + name: "toHaveLastResolvedWith", + condition: (spy, value) => { + const result = spy.mock.settledResults[spy.mock.settledResults.length - 1]; + return result && result.type === "fulfilled" && equals(result.value, value); + }, + action: "resolve" + }, { + name: ["toHaveLastReturnedWith", "lastReturnedWith"], + condition: (spy, value) => { + const result = spy.mock.results[spy.mock.results.length - 1]; + return result && result.type === "return" && equals(result.value, value); + }, + action: "return" + }].forEach(({ name, condition, action }) => { + def(name, function(value) { + const spy = getSpy(this); + const results = action === "return" ? spy.mock.results : spy.mock.settledResults; + const result = results[results.length - 1]; + const spyName = spy.getMockName(); + this.assert(condition(spy, value), `expected last "${spyName}" call to ${action} #{exp}`, `expected last "${spyName}" call to not ${action} #{exp}`, value, result === null || result === void 0 ? void 0 : result.value); + }); + }); + [{ + name: "toHaveNthResolvedWith", + condition: (spy, index, value) => { + const result = spy.mock.settledResults[index - 1]; + return result && result.type === "fulfilled" && equals(result.value, value); + }, + action: "resolve" + }, { + name: ["toHaveNthReturnedWith", "nthReturnedWith"], + condition: (spy, index, value) => { + const result = spy.mock.results[index - 1]; + return result && result.type === "return" && equals(result.value, value); + }, + action: "return" + }].forEach(({ name, condition, action }) => { + def(name, function(nthCall, value) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const results = action === "return" ? spy.mock.results : spy.mock.settledResults; + const result = results[nthCall - 1]; + const ordinalCall = `${ordinalOf(nthCall)} call`; + this.assert(condition(spy, nthCall, value), `expected ${ordinalCall} "${spyName}" call to ${action} #{exp}`, `expected ${ordinalCall} "${spyName}" call to not ${action} #{exp}`, value, result === null || result === void 0 ? void 0 : result.value); + }); + }); + // @ts-expect-error @internal + def("withContext", function(context) { + for (const key in context) { + utils.flag(this, key, context[key]); + } + return this; + }); + utils.addProperty(chai.Assertion.prototype, "resolves", function __VITEST_RESOLVES__() { + const error = new Error("resolves"); + utils.flag(this, "promise", "resolves"); + utils.flag(this, "error", error); + const test = utils.flag(this, "vitest-test"); + const obj = utils.flag(this, "object"); + if (utils.flag(this, "poll")) { + throw new SyntaxError(`expect.poll() is not supported in combination with .resolves`); + } + if (typeof (obj === null || obj === void 0 ? void 0 : obj.then) !== "function") { + throw new TypeError(`You must provide a Promise to expect() when using .resolves, not '${typeof obj}'.`); + } + const proxy = new Proxy(this, { get: (target, key, receiver) => { + const result = Reflect.get(target, key, receiver); + if (typeof result !== "function") { + return result instanceof chai.Assertion ? proxy : result; + } + return (...args) => { + utils.flag(this, "_name", key); + const promise = obj.then((value) => { + utils.flag(this, "object", value); + return result.call(this, ...args); + }, (err) => { + const _error = new AssertionError(`promise rejected "${utils.inspect(err)}" instead of resolving`, { showDiff: false }); + _error.cause = err; + _error.stack = error.stack.replace(error.message, _error.message); + throw _error; + }); + return recordAsyncExpect(test, promise, createAssertionMessage(utils, this, !!args.length), error); + }; + } }); + return proxy; + }); + utils.addProperty(chai.Assertion.prototype, "rejects", function __VITEST_REJECTS__() { + const error = new Error("rejects"); + utils.flag(this, "promise", "rejects"); + utils.flag(this, "error", error); + const test = utils.flag(this, "vitest-test"); + const obj = utils.flag(this, "object"); + const wrapper = typeof obj === "function" ? obj() : obj; + if (utils.flag(this, "poll")) { + throw new SyntaxError(`expect.poll() is not supported in combination with .rejects`); + } + if (typeof (wrapper === null || wrapper === void 0 ? void 0 : wrapper.then) !== "function") { + throw new TypeError(`You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`); + } + const proxy = new Proxy(this, { get: (target, key, receiver) => { + const result = Reflect.get(target, key, receiver); + if (typeof result !== "function") { + return result instanceof chai.Assertion ? proxy : result; + } + return (...args) => { + utils.flag(this, "_name", key); + const promise = wrapper.then((value) => { + const _error = new AssertionError(`promise resolved "${utils.inspect(value)}" instead of rejecting`, { + showDiff: true, + expected: new Error("rejected promise"), + actual: value + }); + _error.stack = error.stack.replace(error.message, _error.message); + throw _error; + }, (err) => { + utils.flag(this, "object", err); + return result.call(this, ...args); + }); + return recordAsyncExpect(test, promise, createAssertionMessage(utils, this, !!args.length), error); + }; + } }); + return proxy; + }); +}; +function ordinalOf(i) { + const j = i % 10; + const k = i % 100; + if (j === 1 && k !== 11) { + return `${i}st`; + } + if (j === 2 && k !== 12) { + return `${i}nd`; + } + if (j === 3 && k !== 13) { + return `${i}rd`; + } + return `${i}th`; +} +function formatCalls(spy, msg, showActualCall) { + if (spy.mock.calls.length) { + msg += c.gray(`\n\nReceived: \n\n${spy.mock.calls.map((callArg, i) => { + let methodCall = c.bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:\n\n`); + if (showActualCall) { + methodCall += diff(showActualCall, callArg, { omitAnnotationLines: true }); + } else { + methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n"); + } + methodCall += "\n"; + return methodCall; + }).join("\n")}`); + } + msg += c.gray(`\n\nNumber of calls: ${c.bold(spy.mock.calls.length)}\n`); + return msg; +} +function formatReturns(spy, results, msg, showActualReturn) { + if (results.length) { + msg += c.gray(`\n\nReceived: \n\n${results.map((callReturn, i) => { + let methodCall = c.bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:\n\n`); + if (showActualReturn) { + methodCall += diff(showActualReturn, callReturn.value, { omitAnnotationLines: true }); + } else { + methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n"); + } + methodCall += "\n"; + return methodCall; + }).join("\n")}`); + } + msg += c.gray(`\n\nNumber of calls: ${c.bold(spy.mock.calls.length)}\n`); + return msg; +} + +function getMatcherState(assertion, expect) { + const obj = assertion._obj; + const isNot = util.flag(assertion, "negate"); + const promise = util.flag(assertion, "promise") || ""; + const jestUtils = { + ...getMatcherUtils(), + diff, + stringify, + iterableEquality, + subsetEquality + }; + const matcherState = { + ...getState(expect), + customTesters: getCustomEqualityTesters(), + isNot, + utils: jestUtils, + promise, + equals, + suppressedErrors: [], + soft: util.flag(assertion, "soft"), + poll: util.flag(assertion, "poll") + }; + return { + state: matcherState, + isNot, + obj + }; +} +class JestExtendError extends Error { + constructor(message, actual, expected) { + super(message); + this.actual = actual; + this.expected = expected; + } +} +function JestExtendPlugin(c, expect, matchers) { + return (_, utils) => { + Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => { + function expectWrapper(...args) { + const { state, isNot, obj } = getMatcherState(this, expect); + const result = expectAssertion.call(state, obj, ...args); + if (result && typeof result === "object" && typeof result.then === "function") { + const thenable = result; + return thenable.then(({ pass, message, actual, expected }) => { + if (pass && isNot || !pass && !isNot) { + throw new JestExtendError(message(), actual, expected); + } + }); + } + const { pass, message, actual, expected } = result; + if (pass && isNot || !pass && !isNot) { + throw new JestExtendError(message(), actual, expected); + } + } + const softWrapper = wrapAssertion(utils, expectAssertionName, expectWrapper); + utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, softWrapper); + utils.addMethod(c.Assertion.prototype, expectAssertionName, softWrapper); + class CustomMatcher extends AsymmetricMatcher { + constructor(inverse = false, ...sample) { + super(sample, inverse); + } + asymmetricMatch(other) { + const { pass } = expectAssertion.call(this.getMatcherContext(expect), other, ...this.sample); + return this.inverse ? !pass : pass; + } + toString() { + return `${this.inverse ? "not." : ""}${expectAssertionName}`; + } + getExpectedType() { + return "any"; + } + toAsymmetricMatcher() { + return `${this.toString()}<${this.sample.map((item) => stringify(item)).join(", ")}>`; + } + } + const customMatcher = (...sample) => new CustomMatcher(false, ...sample); + Object.defineProperty(expect, expectAssertionName, { + configurable: true, + enumerable: true, + value: customMatcher, + writable: true + }); + Object.defineProperty(expect.not, expectAssertionName, { + configurable: true, + enumerable: true, + value: (...sample) => new CustomMatcher(true, ...sample), + writable: true + }); + // keep track of asymmetric matchers on global so that it can be copied over to local context's `expect`. + // note that the negated variant is automatically shared since it's assigned on the single `expect.not` object. + Object.defineProperty(globalThis[ASYMMETRIC_MATCHERS_OBJECT], expectAssertionName, { + configurable: true, + enumerable: true, + value: customMatcher, + writable: true + }); + }); + }; +} +const JestExtend = (chai, utils) => { + utils.addMethod(chai.expect, "extend", (expect, expects) => { + use(JestExtendPlugin(chai, expect, expects)); + }); +}; + +export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, customMatchers, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality }; diff --git a/node_modules/@vitest/expect/package.json b/node_modules/@vitest/expect/package.json new file mode 100644 index 0000000000..d3ec9ab4b1 --- /dev/null +++ b/node_modules/@vitest/expect/package.json @@ -0,0 +1,46 @@ +{ + "name": "@vitest/expect", + "type": "module", + "version": "3.2.4", + "description": "Jest's expect matchers as a Chai plugin", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/expect#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/expect" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "dependencies": { + "@types/chai": "^5.2.2", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4" + }, + "devDependencies": { + "rollup-plugin-copy": "^3.5.0", + "@vitest/runner": "3.2.4" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/mocker/LICENSE b/node_modules/@vitest/mocker/LICENSE new file mode 100644 index 0000000000..5ae481fdb8 --- /dev/null +++ b/node_modules/@vitest/mocker/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/mocker/README.md b/node_modules/@vitest/mocker/README.md new file mode 100644 index 0000000000..f23202d7ca --- /dev/null +++ b/node_modules/@vitest/mocker/README.md @@ -0,0 +1,5 @@ +# @vitest/mocker + +Vitest's module mocker implementation. + +[GitHub](https://github.com/vitest-dev/vitest/blob/main/packages/mocker/) | [Documentation](https://github.com/vitest-dev/vitest/blob/main/packages/mocker/EXPORTS.md) diff --git a/node_modules/@vitest/mocker/dist/auto-register.d.ts b/node_modules/@vitest/mocker/dist/auto-register.d.ts new file mode 100644 index 0000000000..04fa25ee33 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/auto-register.d.ts @@ -0,0 +1,2 @@ + +export { }; diff --git a/node_modules/@vitest/mocker/dist/auto-register.js b/node_modules/@vitest/mocker/dist/auto-register.js new file mode 100644 index 0000000000..8da252bf93 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/auto-register.js @@ -0,0 +1,9 @@ +import { M as ModuleMockerServerInterceptor } from './chunk-interceptor-native.js'; +import { registerModuleMocker } from './register.js'; +import './chunk-mocker.js'; +import './index.js'; +import './chunk-registry.js'; +import './chunk-pathe.M-eThtNZ.js'; +import '@vitest/spy'; + +registerModuleMocker(() => new ModuleMockerServerInterceptor()); diff --git a/node_modules/@vitest/mocker/dist/browser.d.ts b/node_modules/@vitest/mocker/dist/browser.d.ts new file mode 100644 index 0000000000..2629a02e7e --- /dev/null +++ b/node_modules/@vitest/mocker/dist/browser.d.ts @@ -0,0 +1,53 @@ +import { M as ModuleMockerInterceptor } from './mocker.d-Ce9_ySj5.js'; +export { C as CompilerHintsOptions, b as ModuleMocker, a as ModuleMockerCompilerHints, d as ModuleMockerConfig, e as ModuleMockerRPC, R as ResolveIdResult, f as ResolveMockResult, c as createCompilerHints } from './mocker.d-Ce9_ySj5.js'; +import { StartOptions, SetupWorker } from 'msw/browser'; +import { c as MockerRegistry, g as MockedModule } from './registry.d-D765pazg.js'; +import '@vitest/spy'; +import './types.d-D_aRZRdy.js'; + +interface ModuleMockerMSWInterceptorOptions { + /** + * The identifier to access the globalThis object in the worker. + * This will be injected into the script as is, so make sure it's a valid JS expression. + * @example + * ```js + * // globalThisAccessor: '__my_variable__' produces: + * globalThis[__my_variable__] + * // globalThisAccessor: 'Symbol.for('secret:mocks')' produces: + * globalThis[Symbol.for('secret:mocks')] + * // globalThisAccessor: '"__vitest_mocker__"' (notice quotes) produces: + * globalThis["__vitest_mocker__"] + * ``` + * @default `"__vitest_mocker__"` + */ + globalThisAccessor?: string; + /** + * Options passed down to `msw.setupWorker().start(options)` + */ + mswOptions?: StartOptions; + /** + * A pre-configured `msw.setupWorker` instance. + */ + mswWorker?: SetupWorker; +} +declare class ModuleMockerMSWInterceptor implements ModuleMockerInterceptor { + private readonly options; + protected readonly mocks: MockerRegistry; + private startPromise; + private worker; + constructor(options?: ModuleMockerMSWInterceptorOptions); + register(module: MockedModule): Promise; + delete(url: string): Promise; + invalidate(): Promise; + private resolveManualMock; + protected init(): Promise; +} + +declare class ModuleMockerServerInterceptor implements ModuleMockerInterceptor { + register(module: MockedModule): Promise; + delete(id: string): Promise; + invalidate(): Promise; +} + +export { ModuleMockerInterceptor, ModuleMockerMSWInterceptor, ModuleMockerServerInterceptor }; +export type { ModuleMockerMSWInterceptorOptions }; diff --git a/node_modules/@vitest/mocker/dist/browser.js b/node_modules/@vitest/mocker/dist/browser.js new file mode 100644 index 0000000000..6d5ae1dbfc --- /dev/null +++ b/node_modules/@vitest/mocker/dist/browser.js @@ -0,0 +1,91 @@ +export { M as ModuleMocker, c as createCompilerHints } from './chunk-mocker.js'; +import { M as MockerRegistry } from './chunk-registry.js'; +import { c as createManualModuleSource, a as cleanUrl } from './chunk-utils.js'; +export { M as ModuleMockerServerInterceptor } from './chunk-interceptor-native.js'; +import './index.js'; +import './chunk-pathe.M-eThtNZ.js'; + +class ModuleMockerMSWInterceptor { + mocks = new MockerRegistry(); + startPromise; + worker; + constructor(options = {}) { + this.options = options; + if (!options.globalThisAccessor) { + options.globalThisAccessor = "\"__vitest_mocker__\""; + } + } + async register(module) { + await this.init(); + this.mocks.add(module); + } + async delete(url) { + await this.init(); + this.mocks.delete(url); + } + async invalidate() { + this.mocks.clear(); + } + async resolveManualMock(mock) { + const exports = Object.keys(await mock.resolve()); + const text = createManualModuleSource(mock.url, exports, this.options.globalThisAccessor); + return new Response(text, { headers: { "Content-Type": "application/javascript" } }); + } + async init() { + if (this.worker) { + return this.worker; + } + if (this.startPromise) { + return this.startPromise; + } + const worker = this.options.mswWorker; + this.startPromise = Promise.all([worker ? { setupWorker(handler) { + worker.use(handler); + return worker; + } } : import('msw/browser'), import('msw/core/http')]).then(([{ setupWorker }, { http }]) => { + const worker = setupWorker(http.get(/.+/, async ({ request }) => { + const path = cleanQuery(request.url.slice(location.origin.length)); + if (!this.mocks.has(path)) { + return passthrough(); + } + const mock = this.mocks.get(path); + switch (mock.type) { + case "manual": return this.resolveManualMock(mock); + case "automock": + case "autospy": return Response.redirect(injectQuery(path, `mock=${mock.type}`)); + case "redirect": return Response.redirect(mock.redirect); + default: throw new Error(`Unknown mock type: ${mock.type}`); + } + })); + return worker.start(this.options.mswOptions).then(() => worker); + }).finally(() => { + this.worker = worker; + this.startPromise = undefined; + }); + return await this.startPromise; + } +} +const trailingSeparatorRE = /[?&]$/; +const timestampRE = /\bt=\d{13}&?\b/; +const versionRE = /\bv=\w{8}&?\b/; +function cleanQuery(url) { + return url.replace(timestampRE, "").replace(versionRE, "").replace(trailingSeparatorRE, ""); +} +function passthrough() { + return new Response(null, { + status: 302, + statusText: "Passthrough", + headers: { "x-msw-intention": "passthrough" } + }); +} +const replacePercentageRE = /%/g; +function injectQuery(url, queryToInject) { + // encode percents for consistent behavior with pathToFileURL + // see #2614 for details + const resolvedUrl = new URL(url.replace(replacePercentageRE, "%25"), location.href); + const { search, hash } = resolvedUrl; + const pathname = cleanUrl(url); + return `${pathname}?${queryToInject}${search ? `&${search.slice(1)}` : ""}${hash ?? ""}`; +} + +export { ModuleMockerMSWInterceptor }; diff --git a/node_modules/@vitest/mocker/dist/chunk-interceptor-native.js b/node_modules/@vitest/mocker/dist/chunk-interceptor-native.js new file mode 100644 index 0000000000..4b472ccf2c --- /dev/null +++ b/node_modules/@vitest/mocker/dist/chunk-interceptor-native.js @@ -0,0 +1,15 @@ +import { r as rpc } from './chunk-mocker.js'; + +class ModuleMockerServerInterceptor { + async register(module) { + await rpc("vitest:interceptor:register", module.toJSON()); + } + async delete(id) { + await rpc("vitest:interceptor:delete", id); + } + async invalidate() { + await rpc("vitest:interceptor:invalidate"); + } +} + +export { ModuleMockerServerInterceptor as M }; diff --git a/node_modules/@vitest/mocker/dist/chunk-mocker.js b/node_modules/@vitest/mocker/dist/chunk-mocker.js new file mode 100644 index 0000000000..18fb766c98 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/chunk-mocker.js @@ -0,0 +1,1602 @@ +import { mockObject } from './index.js'; +import { M as MockerRegistry, R as RedirectedModule, A as AutomockedModule } from './chunk-registry.js'; +import { e as extname, j as join } from './chunk-pathe.M-eThtNZ.js'; + +// src/index.ts +var f = { + reset: [0, 0], + bold: [1, 22, "\x1B[22m\x1B[1m"], + dim: [2, 22, "\x1B[22m\x1B[2m"], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29], + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], + blackBright: [90, 39], + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39], + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] +}, h = Object.entries(f); +function a(n) { + return String(n); +} +a.open = ""; +a.close = ""; +function C(n = false) { + let e = typeof process != "undefined" ? process : void 0, i = (e == null ? void 0 : e.env) || {}, g = (e == null ? void 0 : e.argv) || []; + return !("NO_COLOR" in i || g.includes("--no-color")) && ("FORCE_COLOR" in i || g.includes("--color") || (e == null ? void 0 : e.platform) === "win32" || n && i.TERM !== "dumb" || "CI" in i) || typeof window != "undefined" && !!window.chrome; +} +function p(n = false) { + let e = C(n), i = (r, t, c, o) => { + let l = "", s = 0; + do + l += r.substring(s, o) + c, s = o + t.length, o = r.indexOf(t, s); + while (~o); + return l + r.substring(s); + }, g = (r, t, c = r) => { + let o = (l) => { + let s = String(l), b = s.indexOf(t, r.length); + return ~b ? r + i(s, t, c, b) + t : r + s + t; + }; + return o.open = r, o.close = t, o; + }, u = { + isColorSupported: e + }, d = (r) => `\x1B[${r}m`; + for (let [r, t] of h) + u[r] = e ? g( + d(t[0]), + d(t[1]), + t[2] + ) : a; + return u; +} + +p(); + +function _mergeNamespaces(n, m) { + m.forEach(function(e) { + e && typeof e !== "string" && !Array.isArray(e) && Object.keys(e).forEach(function(k) { + if (k !== "default" && !(k in n)) { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: function() { + return e[k]; + } + }); + } + }); + }); + return Object.freeze(n); +} +function getDefaultExportFromCjs(x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x; +} +var reactIs$1 = { exports: {} }; +var reactIs_production = {}; +/** +* @license React +* react-is.production.js +* +* Copyright (c) Meta Platforms, Inc. and affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ +var hasRequiredReactIs_production; +function requireReactIs_production() { + if (hasRequiredReactIs_production) return reactIs_production; + hasRequiredReactIs_production = 1; + var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"); + function typeOf(object) { + if ("object" === typeof object && null !== object) { + var $$typeof = object.$$typeof; + switch ($$typeof) { + case REACT_ELEMENT_TYPE: switch (object = object.type, object) { + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: + case REACT_SUSPENSE_LIST_TYPE: + case REACT_VIEW_TRANSITION_TYPE: return object; + default: switch (object = object && object.$$typeof, object) { + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_LAZY_TYPE: + case REACT_MEMO_TYPE: return object; + case REACT_CONSUMER_TYPE: return object; + default: return $$typeof; + } + } + case REACT_PORTAL_TYPE: return $$typeof; + } + } + } + reactIs_production.ContextConsumer = REACT_CONSUMER_TYPE; + reactIs_production.ContextProvider = REACT_CONTEXT_TYPE; + reactIs_production.Element = REACT_ELEMENT_TYPE; + reactIs_production.ForwardRef = REACT_FORWARD_REF_TYPE; + reactIs_production.Fragment = REACT_FRAGMENT_TYPE; + reactIs_production.Lazy = REACT_LAZY_TYPE; + reactIs_production.Memo = REACT_MEMO_TYPE; + reactIs_production.Portal = REACT_PORTAL_TYPE; + reactIs_production.Profiler = REACT_PROFILER_TYPE; + reactIs_production.StrictMode = REACT_STRICT_MODE_TYPE; + reactIs_production.Suspense = REACT_SUSPENSE_TYPE; + reactIs_production.SuspenseList = REACT_SUSPENSE_LIST_TYPE; + reactIs_production.isContextConsumer = function(object) { + return typeOf(object) === REACT_CONSUMER_TYPE; + }; + reactIs_production.isContextProvider = function(object) { + return typeOf(object) === REACT_CONTEXT_TYPE; + }; + reactIs_production.isElement = function(object) { + return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE; + }; + reactIs_production.isForwardRef = function(object) { + return typeOf(object) === REACT_FORWARD_REF_TYPE; + }; + reactIs_production.isFragment = function(object) { + return typeOf(object) === REACT_FRAGMENT_TYPE; + }; + reactIs_production.isLazy = function(object) { + return typeOf(object) === REACT_LAZY_TYPE; + }; + reactIs_production.isMemo = function(object) { + return typeOf(object) === REACT_MEMO_TYPE; + }; + reactIs_production.isPortal = function(object) { + return typeOf(object) === REACT_PORTAL_TYPE; + }; + reactIs_production.isProfiler = function(object) { + return typeOf(object) === REACT_PROFILER_TYPE; + }; + reactIs_production.isStrictMode = function(object) { + return typeOf(object) === REACT_STRICT_MODE_TYPE; + }; + reactIs_production.isSuspense = function(object) { + return typeOf(object) === REACT_SUSPENSE_TYPE; + }; + reactIs_production.isSuspenseList = function(object) { + return typeOf(object) === REACT_SUSPENSE_LIST_TYPE; + }; + reactIs_production.isValidElementType = function(type) { + return "string" === typeof type || "function" === typeof type || type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || "object" === typeof type && null !== type && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_CONSUMER_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_CLIENT_REFERENCE || void 0 !== type.getModuleId) ? true : false; + }; + reactIs_production.typeOf = typeOf; + return reactIs_production; +} +var reactIs_development$1 = {}; +/** +* @license React +* react-is.development.js +* +* Copyright (c) Meta Platforms, Inc. and affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ +var hasRequiredReactIs_development$1; +function requireReactIs_development$1() { + if (hasRequiredReactIs_development$1) return reactIs_development$1; + hasRequiredReactIs_development$1 = 1; + "production" !== process.env.NODE_ENV && function() { + function typeOf(object) { + if ("object" === typeof object && null !== object) { + var $$typeof = object.$$typeof; + switch ($$typeof) { + case REACT_ELEMENT_TYPE: switch (object = object.type, object) { + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: + case REACT_SUSPENSE_LIST_TYPE: + case REACT_VIEW_TRANSITION_TYPE: return object; + default: switch (object = object && object.$$typeof, object) { + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_LAZY_TYPE: + case REACT_MEMO_TYPE: return object; + case REACT_CONSUMER_TYPE: return object; + default: return $$typeof; + } + } + case REACT_PORTAL_TYPE: return $$typeof; + } + } + } + var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"); + reactIs_development$1.ContextConsumer = REACT_CONSUMER_TYPE; + reactIs_development$1.ContextProvider = REACT_CONTEXT_TYPE; + reactIs_development$1.Element = REACT_ELEMENT_TYPE; + reactIs_development$1.ForwardRef = REACT_FORWARD_REF_TYPE; + reactIs_development$1.Fragment = REACT_FRAGMENT_TYPE; + reactIs_development$1.Lazy = REACT_LAZY_TYPE; + reactIs_development$1.Memo = REACT_MEMO_TYPE; + reactIs_development$1.Portal = REACT_PORTAL_TYPE; + reactIs_development$1.Profiler = REACT_PROFILER_TYPE; + reactIs_development$1.StrictMode = REACT_STRICT_MODE_TYPE; + reactIs_development$1.Suspense = REACT_SUSPENSE_TYPE; + reactIs_development$1.SuspenseList = REACT_SUSPENSE_LIST_TYPE; + reactIs_development$1.isContextConsumer = function(object) { + return typeOf(object) === REACT_CONSUMER_TYPE; + }; + reactIs_development$1.isContextProvider = function(object) { + return typeOf(object) === REACT_CONTEXT_TYPE; + }; + reactIs_development$1.isElement = function(object) { + return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE; + }; + reactIs_development$1.isForwardRef = function(object) { + return typeOf(object) === REACT_FORWARD_REF_TYPE; + }; + reactIs_development$1.isFragment = function(object) { + return typeOf(object) === REACT_FRAGMENT_TYPE; + }; + reactIs_development$1.isLazy = function(object) { + return typeOf(object) === REACT_LAZY_TYPE; + }; + reactIs_development$1.isMemo = function(object) { + return typeOf(object) === REACT_MEMO_TYPE; + }; + reactIs_development$1.isPortal = function(object) { + return typeOf(object) === REACT_PORTAL_TYPE; + }; + reactIs_development$1.isProfiler = function(object) { + return typeOf(object) === REACT_PROFILER_TYPE; + }; + reactIs_development$1.isStrictMode = function(object) { + return typeOf(object) === REACT_STRICT_MODE_TYPE; + }; + reactIs_development$1.isSuspense = function(object) { + return typeOf(object) === REACT_SUSPENSE_TYPE; + }; + reactIs_development$1.isSuspenseList = function(object) { + return typeOf(object) === REACT_SUSPENSE_LIST_TYPE; + }; + reactIs_development$1.isValidElementType = function(type) { + return "string" === typeof type || "function" === typeof type || type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || "object" === typeof type && null !== type && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_CONSUMER_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_CLIENT_REFERENCE || void 0 !== type.getModuleId) ? true : false; + }; + reactIs_development$1.typeOf = typeOf; + }(); + return reactIs_development$1; +} +var hasRequiredReactIs$1; +function requireReactIs$1() { + if (hasRequiredReactIs$1) return reactIs$1.exports; + hasRequiredReactIs$1 = 1; + if (process.env.NODE_ENV === "production") { + reactIs$1.exports = requireReactIs_production(); + } else { + reactIs$1.exports = requireReactIs_development$1(); + } + return reactIs$1.exports; +} +var reactIsExports$1 = requireReactIs$1(); +var index$1 = /* @__PURE__ */ getDefaultExportFromCjs(reactIsExports$1); +var ReactIs19 = /* @__PURE__ */ _mergeNamespaces({ + __proto__: null, + default: index$1 +}, [reactIsExports$1]); +var reactIs = { exports: {} }; +var reactIs_production_min = {}; +/** +* @license React +* react-is.production.min.js +* +* Copyright (c) Facebook, Inc. and its affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ +var hasRequiredReactIs_production_min; +function requireReactIs_production_min() { + if (hasRequiredReactIs_production_min) return reactIs_production_min; + hasRequiredReactIs_production_min = 1; + var b = Symbol.for("react.element"), c = Symbol.for("react.portal"), d = Symbol.for("react.fragment"), e = Symbol.for("react.strict_mode"), f = Symbol.for("react.profiler"), g = Symbol.for("react.provider"), h = Symbol.for("react.context"), k = Symbol.for("react.server_context"), l = Symbol.for("react.forward_ref"), m = Symbol.for("react.suspense"), n = Symbol.for("react.suspense_list"), p = Symbol.for("react.memo"), q = Symbol.for("react.lazy"), t = Symbol.for("react.offscreen"), u; + u = Symbol.for("react.module.reference"); + function v(a) { + if ("object" === typeof a && null !== a) { + var r = a.$$typeof; + switch (r) { + case b: switch (a = a.type, a) { + case d: + case f: + case e: + case m: + case n: return a; + default: switch (a = a && a.$$typeof, a) { + case k: + case h: + case l: + case q: + case p: + case g: return a; + default: return r; + } + } + case c: return r; + } + } + } + reactIs_production_min.ContextConsumer = h; + reactIs_production_min.ContextProvider = g; + reactIs_production_min.Element = b; + reactIs_production_min.ForwardRef = l; + reactIs_production_min.Fragment = d; + reactIs_production_min.Lazy = q; + reactIs_production_min.Memo = p; + reactIs_production_min.Portal = c; + reactIs_production_min.Profiler = f; + reactIs_production_min.StrictMode = e; + reactIs_production_min.Suspense = m; + reactIs_production_min.SuspenseList = n; + reactIs_production_min.isAsyncMode = function() { + return false; + }; + reactIs_production_min.isConcurrentMode = function() { + return false; + }; + reactIs_production_min.isContextConsumer = function(a) { + return v(a) === h; + }; + reactIs_production_min.isContextProvider = function(a) { + return v(a) === g; + }; + reactIs_production_min.isElement = function(a) { + return "object" === typeof a && null !== a && a.$$typeof === b; + }; + reactIs_production_min.isForwardRef = function(a) { + return v(a) === l; + }; + reactIs_production_min.isFragment = function(a) { + return v(a) === d; + }; + reactIs_production_min.isLazy = function(a) { + return v(a) === q; + }; + reactIs_production_min.isMemo = function(a) { + return v(a) === p; + }; + reactIs_production_min.isPortal = function(a) { + return v(a) === c; + }; + reactIs_production_min.isProfiler = function(a) { + return v(a) === f; + }; + reactIs_production_min.isStrictMode = function(a) { + return v(a) === e; + }; + reactIs_production_min.isSuspense = function(a) { + return v(a) === m; + }; + reactIs_production_min.isSuspenseList = function(a) { + return v(a) === n; + }; + reactIs_production_min.isValidElementType = function(a) { + return "string" === typeof a || "function" === typeof a || a === d || a === f || a === e || a === m || a === n || a === t || "object" === typeof a && null !== a && (a.$$typeof === q || a.$$typeof === p || a.$$typeof === g || a.$$typeof === h || a.$$typeof === l || a.$$typeof === u || void 0 !== a.getModuleId) ? true : false; + }; + reactIs_production_min.typeOf = v; + return reactIs_production_min; +} +var reactIs_development = {}; +/** +* @license React +* react-is.development.js +* +* Copyright (c) Facebook, Inc. and its affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ +var hasRequiredReactIs_development; +function requireReactIs_development() { + if (hasRequiredReactIs_development) return reactIs_development; + hasRequiredReactIs_development = 1; + if (process.env.NODE_ENV !== "production") { + (function() { + // ATTENTION + // When adding new symbols to this file, + // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols' + // The Symbol used to tag the ReactElement-like types. + var REACT_ELEMENT_TYPE = Symbol.for("react.element"); + var REACT_PORTAL_TYPE = Symbol.for("react.portal"); + var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"); + var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"); + var REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_PROVIDER_TYPE = Symbol.for("react.provider"); + var REACT_CONTEXT_TYPE = Symbol.for("react.context"); + var REACT_SERVER_CONTEXT_TYPE = Symbol.for("react.server_context"); + var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"); + var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"); + var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"); + var REACT_MEMO_TYPE = Symbol.for("react.memo"); + var REACT_LAZY_TYPE = Symbol.for("react.lazy"); + var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); + // ----------------------------------------------------------------------------- + var enableScopeAPI = false; + var enableCacheElement = false; + var enableTransitionTracing = false; + var enableLegacyHidden = false; + // stuff. Intended to enable React core members to more easily debug scheduling + // issues in DEV builds. + var enableDebugTracing = false; + var REACT_MODULE_REFERENCE; + { + REACT_MODULE_REFERENCE = Symbol.for("react.module.reference"); + } + function isValidElementType(type) { + if (typeof type === "string" || typeof type === "function") { + return true; + } + if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden || type === REACT_OFFSCREEN_TYPE || enableScopeAPI || enableCacheElement || enableTransitionTracing) { + return true; + } + if (typeof type === "object" && type !== null) { + if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== undefined) { + return true; + } + } + return false; + } + function typeOf(object) { + if (typeof object === "object" && object !== null) { + var $$typeof = object.$$typeof; + switch ($$typeof) { + case REACT_ELEMENT_TYPE: + var type = object.type; + switch (type) { + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: + case REACT_SUSPENSE_LIST_TYPE: return type; + default: + var $$typeofType = type && type.$$typeof; + switch ($$typeofType) { + case REACT_SERVER_CONTEXT_TYPE: + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_LAZY_TYPE: + case REACT_MEMO_TYPE: + case REACT_PROVIDER_TYPE: return $$typeofType; + default: return $$typeof; + } + } + case REACT_PORTAL_TYPE: return $$typeof; + } + } + return undefined; + } + var ContextConsumer = REACT_CONTEXT_TYPE; + var ContextProvider = REACT_PROVIDER_TYPE; + var Element = REACT_ELEMENT_TYPE; + var ForwardRef = REACT_FORWARD_REF_TYPE; + var Fragment = REACT_FRAGMENT_TYPE; + var Lazy = REACT_LAZY_TYPE; + var Memo = REACT_MEMO_TYPE; + var Portal = REACT_PORTAL_TYPE; + var Profiler = REACT_PROFILER_TYPE; + var StrictMode = REACT_STRICT_MODE_TYPE; + var Suspense = REACT_SUSPENSE_TYPE; + var SuspenseList = REACT_SUSPENSE_LIST_TYPE; + var hasWarnedAboutDeprecatedIsAsyncMode = false; + var hasWarnedAboutDeprecatedIsConcurrentMode = false; + function isAsyncMode(object) { + { + if (!hasWarnedAboutDeprecatedIsAsyncMode) { + hasWarnedAboutDeprecatedIsAsyncMode = true; + console["warn"]("The ReactIs.isAsyncMode() alias has been deprecated, " + "and will be removed in React 18+."); + } + } + return false; + } + function isConcurrentMode(object) { + { + if (!hasWarnedAboutDeprecatedIsConcurrentMode) { + hasWarnedAboutDeprecatedIsConcurrentMode = true; + console["warn"]("The ReactIs.isConcurrentMode() alias has been deprecated, " + "and will be removed in React 18+."); + } + } + return false; + } + function isContextConsumer(object) { + return typeOf(object) === REACT_CONTEXT_TYPE; + } + function isContextProvider(object) { + return typeOf(object) === REACT_PROVIDER_TYPE; + } + function isElement(object) { + return typeof object === "object" && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; + } + function isForwardRef(object) { + return typeOf(object) === REACT_FORWARD_REF_TYPE; + } + function isFragment(object) { + return typeOf(object) === REACT_FRAGMENT_TYPE; + } + function isLazy(object) { + return typeOf(object) === REACT_LAZY_TYPE; + } + function isMemo(object) { + return typeOf(object) === REACT_MEMO_TYPE; + } + function isPortal(object) { + return typeOf(object) === REACT_PORTAL_TYPE; + } + function isProfiler(object) { + return typeOf(object) === REACT_PROFILER_TYPE; + } + function isStrictMode(object) { + return typeOf(object) === REACT_STRICT_MODE_TYPE; + } + function isSuspense(object) { + return typeOf(object) === REACT_SUSPENSE_TYPE; + } + function isSuspenseList(object) { + return typeOf(object) === REACT_SUSPENSE_LIST_TYPE; + } + reactIs_development.ContextConsumer = ContextConsumer; + reactIs_development.ContextProvider = ContextProvider; + reactIs_development.Element = Element; + reactIs_development.ForwardRef = ForwardRef; + reactIs_development.Fragment = Fragment; + reactIs_development.Lazy = Lazy; + reactIs_development.Memo = Memo; + reactIs_development.Portal = Portal; + reactIs_development.Profiler = Profiler; + reactIs_development.StrictMode = StrictMode; + reactIs_development.Suspense = Suspense; + reactIs_development.SuspenseList = SuspenseList; + reactIs_development.isAsyncMode = isAsyncMode; + reactIs_development.isConcurrentMode = isConcurrentMode; + reactIs_development.isContextConsumer = isContextConsumer; + reactIs_development.isContextProvider = isContextProvider; + reactIs_development.isElement = isElement; + reactIs_development.isForwardRef = isForwardRef; + reactIs_development.isFragment = isFragment; + reactIs_development.isLazy = isLazy; + reactIs_development.isMemo = isMemo; + reactIs_development.isPortal = isPortal; + reactIs_development.isProfiler = isProfiler; + reactIs_development.isStrictMode = isStrictMode; + reactIs_development.isSuspense = isSuspense; + reactIs_development.isSuspenseList = isSuspenseList; + reactIs_development.isValidElementType = isValidElementType; + reactIs_development.typeOf = typeOf; + })(); + } + return reactIs_development; +} +var hasRequiredReactIs; +function requireReactIs() { + if (hasRequiredReactIs) return reactIs.exports; + hasRequiredReactIs = 1; + if (process.env.NODE_ENV === "production") { + reactIs.exports = requireReactIs_production_min(); + } else { + reactIs.exports = requireReactIs_development(); + } + return reactIs.exports; +} +var reactIsExports = requireReactIs(); +var index = /* @__PURE__ */ getDefaultExportFromCjs(reactIsExports); +var ReactIs18 = /* @__PURE__ */ _mergeNamespaces({ + __proto__: null, + default: index +}, [reactIsExports]); +const reactIsMethods = [ + "isAsyncMode", + "isConcurrentMode", + "isContextConsumer", + "isContextProvider", + "isElement", + "isForwardRef", + "isFragment", + "isLazy", + "isMemo", + "isPortal", + "isProfiler", + "isStrictMode", + "isSuspense", + "isSuspenseList", + "isValidElementType" +]; +Object.fromEntries(reactIsMethods.map((m) => [m, (v) => ReactIs18[m](v) || ReactIs19[m](v)])); + +let getPromiseValue = () => 'Promise{…}'; +try { + // @ts-ignore + const { getPromiseDetails, kPending, kRejected } = process.binding('util'); + if (Array.isArray(getPromiseDetails(Promise.resolve()))) { + getPromiseValue = (value, options) => { + const [state, innerValue] = getPromiseDetails(value); + if (state === kPending) { + return 'Promise{}'; + } + return `Promise${state === kRejected ? '!' : ''}{${options.inspect(innerValue, options)}}`; + }; + } +} +catch (notNode) { + /* ignore */ +} + +/** +* Get original stacktrace without source map support the most performant way. +* - Create only 1 stack frame. +* - Rewrite prepareStackTrace to bypass "support-stack-trace" (usually takes ~250ms). +*/ +function createSimpleStackTrace(options) { + const { message = "$$stack trace error", stackTraceLimit = 1 } = options || {}; + const limit = Error.stackTraceLimit; + const prepareStackTrace = Error.prepareStackTrace; + Error.stackTraceLimit = stackTraceLimit; + Error.prepareStackTrace = (e) => e.stack; + const err = new Error(message); + const stackTrace = err.stack || ""; + Error.prepareStackTrace = prepareStackTrace; + Error.stackTraceLimit = limit; + return stackTrace; +} + +var jsTokens_1; +var hasRequiredJsTokens; +function requireJsTokens() { + if (hasRequiredJsTokens) return jsTokens_1; + hasRequiredJsTokens = 1; + // Copyright 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Simon Lydell + // License: MIT. + var Identifier, JSXIdentifier, JSXPunctuator, JSXString, JSXText, KeywordsWithExpressionAfter, KeywordsWithNoLineTerminatorAfter, LineTerminatorSequence, MultiLineComment, Newline, NumericLiteral, Punctuator, RegularExpressionLiteral, SingleLineComment, StringLiteral, Template, TokensNotPrecedingObjectLiteral, TokensPrecedingExpression, WhiteSpace; + RegularExpressionLiteral = /\/(?![*\/])(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\\]).|\\.)*(\/[$_\u200C\u200D\p{ID_Continue}]*|\\)?/uy; + Punctuator = /--|\+\+|=>|\.{3}|\??\.(?!\d)|(?:&&|\|\||\?\?|[+\-%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2}|\/(?![\/*]))=?|[?~,:;[\](){}]/y; + Identifier = /(\x23?)(?=[$_\p{ID_Start}\\])(?:[$_\u200C\u200D\p{ID_Continue}]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+/uy; + StringLiteral = /(['"])(?:(?!\1)[^\\\n\r]|\\(?:\r\n|[^]))*(\1)?/y; + NumericLiteral = /(?:0[xX][\da-fA-F](?:_?[\da-fA-F])*|0[oO][0-7](?:_?[0-7])*|0[bB][01](?:_?[01])*)n?|0n|[1-9](?:_?\d)*n|(?:(?:0(?!\d)|0\d*[89]\d*|[1-9](?:_?\d)*)(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?|0[0-7]+/y; + Template = /[`}](?:[^`\\$]|\\[^]|\$(?!\{))*(`|\$\{)?/y; + WhiteSpace = /[\t\v\f\ufeff\p{Zs}]+/uy; + LineTerminatorSequence = /\r?\n|[\r\u2028\u2029]/y; + MultiLineComment = /\/\*(?:[^*]|\*(?!\/))*(\*\/)?/y; + SingleLineComment = /\/\/.*/y; + JSXPunctuator = /[<>.:={}]|\/(?![\/*])/y; + JSXIdentifier = /[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}-]*/uy; + JSXString = /(['"])(?:(?!\1)[^])*(\1)?/y; + JSXText = /[^<>{}]+/y; + TokensPrecedingExpression = /^(?:[\/+-]|\.{3}|\?(?:InterpolationIn(?:JSX|Template)|NoLineTerminatorHere|NonExpressionParenEnd|UnaryIncDec))?$|[{}([,;<>=*%&|^!~?:]$/; + TokensNotPrecedingObjectLiteral = /^(?:=>|[;\]){}]|else|\?(?:NoLineTerminatorHere|NonExpressionParenEnd))?$/; + KeywordsWithExpressionAfter = /^(?:await|case|default|delete|do|else|instanceof|new|return|throw|typeof|void|yield)$/; + KeywordsWithNoLineTerminatorAfter = /^(?:return|throw|yield)$/; + Newline = RegExp(LineTerminatorSequence.source); + jsTokens_1 = function* (input, { jsx = false } = {}) { + var braces, firstCodePoint, isExpression, lastIndex, lastSignificantToken, length, match, mode, nextLastIndex, nextLastSignificantToken, parenNesting, postfixIncDec, punctuator, stack; + ({length} = input); + lastIndex = 0; + lastSignificantToken = ""; + stack = [{ tag: "JS" }]; + braces = []; + parenNesting = 0; + postfixIncDec = false; + while (lastIndex < length) { + mode = stack[stack.length - 1]; + switch (mode.tag) { + case "JS": + case "JSNonExpressionParen": + case "InterpolationInTemplate": + case "InterpolationInJSX": + if (input[lastIndex] === "/" && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + RegularExpressionLiteral.lastIndex = lastIndex; + if (match = RegularExpressionLiteral.exec(input)) { + lastIndex = RegularExpressionLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield { + type: "RegularExpressionLiteral", + value: match[0], + closed: match[1] !== void 0 && match[1] !== "\\" + }; + continue; + } + } + Punctuator.lastIndex = lastIndex; + if (match = Punctuator.exec(input)) { + punctuator = match[0]; + nextLastIndex = Punctuator.lastIndex; + nextLastSignificantToken = punctuator; + switch (punctuator) { + case "(": + if (lastSignificantToken === "?NonExpressionParenKeyword") { + stack.push({ + tag: "JSNonExpressionParen", + nesting: parenNesting + }); + } + parenNesting++; + postfixIncDec = false; + break; + case ")": + parenNesting--; + postfixIncDec = true; + if (mode.tag === "JSNonExpressionParen" && parenNesting === mode.nesting) { + stack.pop(); + nextLastSignificantToken = "?NonExpressionParenEnd"; + postfixIncDec = false; + } + break; + case "{": + Punctuator.lastIndex = 0; + isExpression = !TokensNotPrecedingObjectLiteral.test(lastSignificantToken) && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken)); + braces.push(isExpression); + postfixIncDec = false; + break; + case "}": + switch (mode.tag) { + case "InterpolationInTemplate": + if (braces.length === mode.nesting) { + Template.lastIndex = lastIndex; + match = Template.exec(input); + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + postfixIncDec = false; + yield { + type: "TemplateMiddle", + value: match[0] + }; + } else { + stack.pop(); + postfixIncDec = true; + yield { + type: "TemplateTail", + value: match[0], + closed: match[1] === "`" + }; + } + continue; + } + break; + case "InterpolationInJSX": if (braces.length === mode.nesting) { + stack.pop(); + lastIndex += 1; + lastSignificantToken = "}"; + yield { + type: "JSXPunctuator", + value: "}" + }; + continue; + } + } + postfixIncDec = braces.pop(); + nextLastSignificantToken = postfixIncDec ? "?ExpressionBraceEnd" : "}"; + break; + case "]": + postfixIncDec = true; + break; + case "++": + case "--": + nextLastSignificantToken = postfixIncDec ? "?PostfixIncDec" : "?UnaryIncDec"; + break; + case "<": + if (jsx && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + stack.push({ tag: "JSXTag" }); + lastIndex += 1; + lastSignificantToken = "<"; + yield { + type: "JSXPunctuator", + value: punctuator + }; + continue; + } + postfixIncDec = false; + break; + default: postfixIncDec = false; + } + lastIndex = nextLastIndex; + lastSignificantToken = nextLastSignificantToken; + yield { + type: "Punctuator", + value: punctuator + }; + continue; + } + Identifier.lastIndex = lastIndex; + if (match = Identifier.exec(input)) { + lastIndex = Identifier.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "for": + case "if": + case "while": + case "with": if (lastSignificantToken !== "." && lastSignificantToken !== "?.") { + nextLastSignificantToken = "?NonExpressionParenKeyword"; + } + } + lastSignificantToken = nextLastSignificantToken; + postfixIncDec = !KeywordsWithExpressionAfter.test(match[0]); + yield { + type: match[1] === "#" ? "PrivateIdentifier" : "IdentifierName", + value: match[0] + }; + continue; + } + StringLiteral.lastIndex = lastIndex; + if (match = StringLiteral.exec(input)) { + lastIndex = StringLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield { + type: "StringLiteral", + value: match[0], + closed: match[2] !== void 0 + }; + continue; + } + NumericLiteral.lastIndex = lastIndex; + if (match = NumericLiteral.exec(input)) { + lastIndex = NumericLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield { + type: "NumericLiteral", + value: match[0] + }; + continue; + } + Template.lastIndex = lastIndex; + if (match = Template.exec(input)) { + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + stack.push({ + tag: "InterpolationInTemplate", + nesting: braces.length + }); + postfixIncDec = false; + yield { + type: "TemplateHead", + value: match[0] + }; + } else { + postfixIncDec = true; + yield { + type: "NoSubstitutionTemplate", + value: match[0], + closed: match[1] === "`" + }; + } + continue; + } + break; + case "JSXTag": + case "JSXTagEnd": + JSXPunctuator.lastIndex = lastIndex; + if (match = JSXPunctuator.exec(input)) { + lastIndex = JSXPunctuator.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "<": + stack.push({ tag: "JSXTag" }); + break; + case ">": + stack.pop(); + if (lastSignificantToken === "/" || mode.tag === "JSXTagEnd") { + nextLastSignificantToken = "?JSX"; + postfixIncDec = true; + } else { + stack.push({ tag: "JSXChildren" }); + } + break; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + nextLastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + break; + case "/": if (lastSignificantToken === "<") { + stack.pop(); + if (stack[stack.length - 1].tag === "JSXChildren") { + stack.pop(); + } + stack.push({ tag: "JSXTagEnd" }); + } + } + lastSignificantToken = nextLastSignificantToken; + yield { + type: "JSXPunctuator", + value: match[0] + }; + continue; + } + JSXIdentifier.lastIndex = lastIndex; + if (match = JSXIdentifier.exec(input)) { + lastIndex = JSXIdentifier.lastIndex; + lastSignificantToken = match[0]; + yield { + type: "JSXIdentifier", + value: match[0] + }; + continue; + } + JSXString.lastIndex = lastIndex; + if (match = JSXString.exec(input)) { + lastIndex = JSXString.lastIndex; + lastSignificantToken = match[0]; + yield { + type: "JSXString", + value: match[0], + closed: match[2] !== void 0 + }; + continue; + } + break; + case "JSXChildren": + JSXText.lastIndex = lastIndex; + if (match = JSXText.exec(input)) { + lastIndex = JSXText.lastIndex; + lastSignificantToken = match[0]; + yield { + type: "JSXText", + value: match[0] + }; + continue; + } + switch (input[lastIndex]) { + case "<": + stack.push({ tag: "JSXTag" }); + lastIndex++; + lastSignificantToken = "<"; + yield { + type: "JSXPunctuator", + value: "<" + }; + continue; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + lastIndex++; + lastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + yield { + type: "JSXPunctuator", + value: "{" + }; + continue; + } + } + WhiteSpace.lastIndex = lastIndex; + if (match = WhiteSpace.exec(input)) { + lastIndex = WhiteSpace.lastIndex; + yield { + type: "WhiteSpace", + value: match[0] + }; + continue; + } + LineTerminatorSequence.lastIndex = lastIndex; + if (match = LineTerminatorSequence.exec(input)) { + lastIndex = LineTerminatorSequence.lastIndex; + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + yield { + type: "LineTerminatorSequence", + value: match[0] + }; + continue; + } + MultiLineComment.lastIndex = lastIndex; + if (match = MultiLineComment.exec(input)) { + lastIndex = MultiLineComment.lastIndex; + if (Newline.test(match[0])) { + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + } + yield { + type: "MultiLineComment", + value: match[0], + closed: match[1] !== void 0 + }; + continue; + } + SingleLineComment.lastIndex = lastIndex; + if (match = SingleLineComment.exec(input)) { + lastIndex = SingleLineComment.lastIndex; + postfixIncDec = false; + yield { + type: "SingleLineComment", + value: match[0] + }; + continue; + } + firstCodePoint = String.fromCodePoint(input.codePointAt(lastIndex)); + lastIndex += firstCodePoint.length; + lastSignificantToken = firstCodePoint; + postfixIncDec = false; + yield { + type: mode.tag.startsWith("JSX") ? "JSXInvalid" : "Invalid", + value: firstCodePoint + }; + } + return void 0; + }; + return jsTokens_1; +} +requireJsTokens(); +// src/index.ts +var reservedWords = { + keyword: [ + "break", + "case", + "catch", + "continue", + "debugger", + "default", + "do", + "else", + "finally", + "for", + "function", + "if", + "return", + "switch", + "throw", + "try", + "var", + "const", + "while", + "with", + "new", + "this", + "super", + "class", + "extends", + "export", + "import", + "null", + "true", + "false", + "in", + "instanceof", + "typeof", + "void", + "delete" + ], + strict: [ + "implements", + "interface", + "let", + "package", + "private", + "protected", + "public", + "static", + "yield" + ] +}; new Set(reservedWords.keyword); new Set(reservedWords.strict); + +const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +const intToChar = new Uint8Array(64); +const charToInt = new Uint8Array(128); +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +var UrlType; +(function(UrlType) { + UrlType[UrlType["Empty"] = 1] = "Empty"; + UrlType[UrlType["Hash"] = 2] = "Hash"; + UrlType[UrlType["Query"] = 3] = "Query"; + UrlType[UrlType["RelativePath"] = 4] = "RelativePath"; + UrlType[UrlType["AbsolutePath"] = 5] = "AbsolutePath"; + UrlType[UrlType["SchemeRelative"] = 6] = "SchemeRelative"; + UrlType[UrlType["Absolute"] = 7] = "Absolute"; +})(UrlType || (UrlType = {})); +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1); + else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const CHROME_IE_STACK_REGEXP = /^\s*at .*(?:\S:\d+|\(native\))/m; +const SAFARI_NATIVE_CODE_REGEXP = /^(?:eval@)?(?:\[native code\])?$/; +function extractLocation(urlLike) { + // Fail-fast but return locations like "(native)" + if (!urlLike.includes(":")) { + return [urlLike]; + } + const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/; + const parts = regExp.exec(urlLike.replace(/^\(|\)$/g, "")); + if (!parts) { + return [urlLike]; + } + let url = parts[1]; + if (url.startsWith("async ")) { + url = url.slice(6); + } + if (url.startsWith("http:") || url.startsWith("https:")) { + const urlObj = new URL(url); + urlObj.searchParams.delete("import"); + urlObj.searchParams.delete("browserv"); + url = urlObj.pathname + urlObj.hash + urlObj.search; + } + if (url.startsWith("/@fs/")) { + const isWindows = /^\/@fs\/[a-zA-Z]:\//.test(url); + url = url.slice(isWindows ? 5 : 4); + } + return [ + url, + parts[2] || undefined, + parts[3] || undefined + ]; +} +function parseSingleFFOrSafariStack(raw) { + let line = raw.trim(); + if (SAFARI_NATIVE_CODE_REGEXP.test(line)) { + return null; + } + if (line.includes(" > eval")) { + line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1"); + } + if (!line.includes("@") && !line.includes(":")) { + return null; + } + // eslint-disable-next-line regexp/no-super-linear-backtracking, regexp/optimal-quantifier-concatenation + const functionNameRegex = /((.*".+"[^@]*)?[^@]*)(@)/; + const matches = line.match(functionNameRegex); + const functionName = matches && matches[1] ? matches[1] : undefined; + const [url, lineNumber, columnNumber] = extractLocation(line.replace(functionNameRegex, "")); + if (!url || !lineNumber || !columnNumber) { + return null; + } + return { + file: url, + method: functionName || "", + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} +function parseSingleStack(raw) { + const line = raw.trim(); + if (!CHROME_IE_STACK_REGEXP.test(line)) { + return parseSingleFFOrSafariStack(line); + } + return parseSingleV8Stack(line); +} +// Based on https://github.com/stacktracejs/error-stack-parser +// Credit to stacktracejs +function parseSingleV8Stack(raw) { + let line = raw.trim(); + if (!CHROME_IE_STACK_REGEXP.test(line)) { + return null; + } + if (line.includes("(eval ")) { + line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, ""); + } + let sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, ""); + // capture and preserve the parenthesized location "(/foo/my bar.js:12:87)" in + // case it has spaces in it, as the string is split on \s+ later on + const location = sanitizedLine.match(/ (\(.+\)$)/); + // remove the parenthesized location from the line, if it was matched + sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine; + // if a location was matched, pass it to extractLocation() otherwise pass all sanitizedLine + // because this line doesn't have function name + const [url, lineNumber, columnNumber] = extractLocation(location ? location[1] : sanitizedLine); + let method = location && sanitizedLine || ""; + let file = url && ["eval", ""].includes(url) ? undefined : url; + if (!file || !lineNumber || !columnNumber) { + return null; + } + if (method.startsWith("async ")) { + method = method.slice(6); + } + if (file.startsWith("file://")) { + file = file.slice(7); + } + // normalize Windows path (\ -> /) + file = file.startsWith("node:") || file.startsWith("internal:") ? file : resolve(file); + if (method) { + method = method.replace(/__vite_ssr_import_\d+__\./g, ""); + } + return { + method, + file, + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} + +function createCompilerHints(options) { + const globalThisAccessor = (options === null || options === void 0 ? void 0 : options.globalThisKey) || "__vitest_mocker__"; + function _mocker() { + // @ts-expect-error injected by the plugin + return typeof globalThis[globalThisAccessor] !== "undefined" ? globalThis[globalThisAccessor] : new Proxy({}, { get(_, name) { + throw new Error("Vitest mocker was not initialized in this environment. " + `vi.${String(name)}() is forbidden.`); + } }); + } + return { + hoisted(factory) { + if (typeof factory !== "function") { + throw new TypeError(`vi.hoisted() expects a function, but received a ${typeof factory}`); + } + return factory(); + }, + mock(path, factory) { + if (typeof path !== "string") { + throw new TypeError(`vi.mock() expects a string path, but received a ${typeof path}`); + } + const importer = getImporter("mock"); + _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer)) : factory); + }, + unmock(path) { + if (typeof path !== "string") { + throw new TypeError(`vi.unmock() expects a string path, but received a ${typeof path}`); + } + _mocker().queueUnmock(path, getImporter("unmock")); + }, + doMock(path, factory) { + if (typeof path !== "string") { + throw new TypeError(`vi.doMock() expects a string path, but received a ${typeof path}`); + } + const importer = getImporter("doMock"); + _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer)) : factory); + }, + doUnmock(path) { + if (typeof path !== "string") { + throw new TypeError(`vi.doUnmock() expects a string path, but received a ${typeof path}`); + } + _mocker().queueUnmock(path, getImporter("doUnmock")); + }, + async importActual(path) { + return _mocker().importActual(path, getImporter("importActual")); + }, + async importMock(path) { + return _mocker().importMock(path, getImporter("importMock")); + } + }; +} +function getImporter(name) { + const stackTrace = /* @__PURE__ */ createSimpleStackTrace({ stackTraceLimit: 5 }); + const stackArray = stackTrace.split("\n"); + // if there is no message in a stack trace, use the item - 1 + const importerStackIndex = stackArray.findIndex((stack) => { + return stack.includes(` at Object.${name}`) || stack.includes(`${name}@`); + }); + const stack = /* @__PURE__ */ parseSingleStack(stackArray[importerStackIndex + 1]); + return (stack === null || stack === void 0 ? void 0 : stack.file) || ""; +} + +const hot = import.meta.hot || { + on: warn, + off: warn, + send: warn +}; +function warn() { + console.warn("Vitest mocker cannot work if Vite didn't establish WS connection."); +} +function rpc(event, data) { + hot.send(event, data); + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + reject(new Error(`Failed to resolve ${event} in time`)); + }, 5e3); + hot.on(`${event}:result`, function r(data) { + resolve(data); + clearTimeout(timeout); + hot.off(`${event}:result`, r); + }); + }); +} + +const { now } = Date; +class ModuleMocker { + registry = new MockerRegistry(); + queue = new Set(); + mockedIds = new Set(); + constructor(interceptor, rpc, spyOn, config) { + this.interceptor = interceptor; + this.rpc = rpc; + this.spyOn = spyOn; + this.config = config; + } + async prepare() { + if (!this.queue.size) { + return; + } + await Promise.all([...this.queue.values()]); + } + async resolveFactoryModule(id) { + const mock = this.registry.get(id); + if (!mock || mock.type !== "manual") { + throw new Error(`Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.`); + } + const result = await mock.resolve(); + return result; + } + getFactoryModule(id) { + const mock = this.registry.get(id); + if (!mock || mock.type !== "manual") { + throw new Error(`Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.`); + } + if (!mock.cache) { + throw new Error(`Mock ${id} wasn't resolved. This is probably a Vitest error. Please, open a new issue with reproduction.`); + } + return mock.cache; + } + async invalidate() { + const ids = Array.from(this.mockedIds); + if (!ids.length) { + return; + } + await this.rpc.invalidate(ids); + await this.interceptor.invalidate(); + this.registry.clear(); + } + async importActual(id, importer) { + const resolved = await this.rpc.resolveId(id, importer); + if (resolved == null) { + throw new Error(`[vitest] Cannot resolve "${id}" imported from "${importer}"`); + } + const ext = extname(resolved.id); + const url = new URL(resolved.url, location.href); + const query = `_vitest_original&ext${ext}`; + const actualUrl = `${url.pathname}${url.search ? `${url.search}&${query}` : `?${query}`}${url.hash}`; + return this.wrapDynamicImport(() => import( + /* @vite-ignore */ + actualUrl +)).then((mod) => { + if (!resolved.optimized || typeof mod.default === "undefined") { + return mod; + } + // vite injects this helper for optimized modules, so we try to follow the same behavior + const m = mod.default; + return (m === null || m === void 0 ? void 0 : m.__esModule) ? m : { + ...typeof m === "object" && !Array.isArray(m) || typeof m === "function" ? m : {}, + default: m + }; + }); + } + async importMock(rawId, importer) { + await this.prepare(); + const { resolvedId, resolvedUrl, redirectUrl } = await this.rpc.resolveMock(rawId, importer, { mock: "auto" }); + const mockUrl = this.resolveMockPath(cleanVersion(resolvedUrl)); + let mock = this.registry.get(mockUrl); + if (!mock) { + if (redirectUrl) { + const resolvedRedirect = new URL(this.resolveMockPath(cleanVersion(redirectUrl)), location.href).toString(); + mock = new RedirectedModule(rawId, resolvedId, mockUrl, resolvedRedirect); + } else { + mock = new AutomockedModule(rawId, resolvedId, mockUrl); + } + } + if (mock.type === "manual") { + return await mock.resolve(); + } + if (mock.type === "automock" || mock.type === "autospy") { + const url = new URL(`/@id/${resolvedId}`, location.href); + const query = url.search ? `${url.search}&t=${now()}` : `?t=${now()}`; + const moduleObject = await import( + /* @vite-ignore */ + `${url.pathname}${query}&mock=${mock.type}${url.hash}` +); + return this.mockObject(moduleObject, mock.type); + } + return import( + /* @vite-ignore */ + mock.redirect +); + } + mockObject(object, moduleType = "automock") { + return mockObject({ + globalConstructors: { + Object, + Function, + Array, + Map, + RegExp + }, + spyOn: this.spyOn, + type: moduleType + }, object); + } + queueMock(rawId, importer, factoryOrOptions) { + const promise = this.rpc.resolveMock(rawId, importer, { mock: typeof factoryOrOptions === "function" ? "factory" : (factoryOrOptions === null || factoryOrOptions === void 0 ? void 0 : factoryOrOptions.spy) ? "spy" : "auto" }).then(async ({ redirectUrl, resolvedId, resolvedUrl, needsInterop, mockType }) => { + const mockUrl = this.resolveMockPath(cleanVersion(resolvedUrl)); + this.mockedIds.add(resolvedId); + const factory = typeof factoryOrOptions === "function" ? async () => { + const data = await factoryOrOptions(); + // vite wraps all external modules that have "needsInterop" in a function that + // merges all exports from default into the module object + return needsInterop ? { default: data } : data; + } : undefined; + const mockRedirect = typeof redirectUrl === "string" ? new URL(this.resolveMockPath(cleanVersion(redirectUrl)), location.href).toString() : null; + let module; + if (mockType === "manual") { + module = this.registry.register("manual", rawId, resolvedId, mockUrl, factory); + } else if (mockType === "autospy") { + module = this.registry.register("autospy", rawId, resolvedId, mockUrl); + } else if (mockType === "redirect") { + module = this.registry.register("redirect", rawId, resolvedId, mockUrl, mockRedirect); + } else { + module = this.registry.register("automock", rawId, resolvedId, mockUrl); + } + await this.interceptor.register(module); + }).finally(() => { + this.queue.delete(promise); + }); + this.queue.add(promise); + } + queueUnmock(id, importer) { + const promise = this.rpc.resolveId(id, importer).then(async (resolved) => { + if (!resolved) { + return; + } + const mockUrl = this.resolveMockPath(cleanVersion(resolved.url)); + this.mockedIds.add(resolved.id); + this.registry.delete(mockUrl); + await this.interceptor.delete(mockUrl); + }).finally(() => { + this.queue.delete(promise); + }); + this.queue.add(promise); + } + // We need to await mock registration before importing the actual module + // In case there is a mocked module in the import chain + wrapDynamicImport(moduleFactory) { + if (typeof moduleFactory === "function") { + const promise = new Promise((resolve, reject) => { + this.prepare().finally(() => { + moduleFactory().then(resolve, reject); + }); + }); + return promise; + } + return moduleFactory; + } + resolveMockPath(path) { + const config = this.config; + const fsRoot = join("/@fs/", config.root); + // URL can be /file/path.js, but path is resolved to /file/path + if (path.startsWith(config.root)) { + return path.slice(config.root.length); + } + if (path.startsWith(fsRoot)) { + return path.slice(fsRoot.length); + } + return path; + } +} +const versionRegexp = /(\?|&)v=\w{8}/; +function cleanVersion(url) { + return url.replace(versionRegexp, ""); +} + +export { ModuleMocker as M, createCompilerHints as c, hot as h, rpc as r }; diff --git a/node_modules/@vitest/mocker/dist/chunk-pathe.M-eThtNZ.js b/node_modules/@vitest/mocker/dist/chunk-pathe.M-eThtNZ.js new file mode 100644 index 0000000000..11a98f06c3 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/chunk-pathe.M-eThtNZ.js @@ -0,0 +1,174 @@ +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _EXTNAME_RE = /.(\.[^./]+|\.)$/; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...segments) { + let path = ""; + for (const seg of segments) { + if (!seg) { + continue; + } + if (path.length > 0) { + const pathTrailing = path[path.length - 1] === "/"; + const segLeading = seg[0] === "/"; + const both = pathTrailing && segLeading; + if (both) { + path += seg.slice(1); + } else { + path += pathTrailing || segLeading ? seg : `/${seg}`; + } + } else { + path += seg; + } + } + return normalize(path); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const extname = function(p) { + if (p === "..") return ""; + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { + segments[0] += "/"; + } + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const basename = function(p, extension) { + const segments = normalizeWindowsPath(p).split("/"); + let lastSegment = ""; + for (let i = segments.length - 1; i >= 0; i--) { + const val = segments[i]; + if (val) { + lastSegment = val; + break; + } + } + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; + +export { basename as b, dirname as d, extname as e, isAbsolute as i, join as j, resolve as r }; diff --git a/node_modules/@vitest/mocker/dist/chunk-registry.js b/node_modules/@vitest/mocker/dist/chunk-registry.js new file mode 100644 index 0000000000..7996ea53ff --- /dev/null +++ b/node_modules/@vitest/mocker/dist/chunk-registry.js @@ -0,0 +1,182 @@ +class MockerRegistry { + registryByUrl = new Map(); + registryById = new Map(); + clear() { + this.registryByUrl.clear(); + this.registryById.clear(); + } + keys() { + return this.registryByUrl.keys(); + } + add(mock) { + this.registryByUrl.set(mock.url, mock); + this.registryById.set(mock.id, mock); + } + register(typeOrEvent, raw, id, url, factoryOrRedirect) { + const type = typeof typeOrEvent === "object" ? typeOrEvent.type : typeOrEvent; + if (typeof typeOrEvent === "object") { + const event = typeOrEvent; + if (event instanceof AutomockedModule || event instanceof AutospiedModule || event instanceof ManualMockedModule || event instanceof RedirectedModule) { + throw new TypeError(`[vitest] Cannot register a mock that is already defined. ` + `Expected a JSON representation from \`MockedModule.toJSON\`, instead got "${event.type}". ` + `Use "registry.add()" to update a mock instead.`); + } + if (event.type === "automock") { + const module = AutomockedModule.fromJSON(event); + this.add(module); + return module; + } else if (event.type === "autospy") { + const module = AutospiedModule.fromJSON(event); + this.add(module); + return module; + } else if (event.type === "redirect") { + const module = RedirectedModule.fromJSON(event); + this.add(module); + return module; + } else if (event.type === "manual") { + throw new Error(`Cannot set serialized manual mock. Define a factory function manually with \`ManualMockedModule.fromJSON()\`.`); + } else { + throw new Error(`Unknown mock type: ${event.type}`); + } + } + if (typeof raw !== "string") { + throw new TypeError("[vitest] Mocks require a raw string."); + } + if (typeof url !== "string") { + throw new TypeError("[vitest] Mocks require a url string."); + } + if (typeof id !== "string") { + throw new TypeError("[vitest] Mocks require an id string."); + } + if (type === "manual") { + if (typeof factoryOrRedirect !== "function") { + throw new TypeError("[vitest] Manual mocks require a factory function."); + } + const mock = new ManualMockedModule(raw, id, url, factoryOrRedirect); + this.add(mock); + return mock; + } else if (type === "automock" || type === "autospy") { + const mock = type === "automock" ? new AutomockedModule(raw, id, url) : new AutospiedModule(raw, id, url); + this.add(mock); + return mock; + } else if (type === "redirect") { + if (typeof factoryOrRedirect !== "string") { + throw new TypeError("[vitest] Redirect mocks require a redirect string."); + } + const mock = new RedirectedModule(raw, id, url, factoryOrRedirect); + this.add(mock); + return mock; + } else { + throw new Error(`[vitest] Unknown mock type: ${type}`); + } + } + delete(id) { + this.registryByUrl.delete(id); + } + get(id) { + return this.registryByUrl.get(id); + } + getById(id) { + return this.registryById.get(id); + } + has(id) { + return this.registryByUrl.has(id); + } +} +class AutomockedModule { + type = "automock"; + constructor(raw, id, url) { + this.raw = raw; + this.id = id; + this.url = url; + } + static fromJSON(data) { + return new AutospiedModule(data.raw, data.id, data.url); + } + toJSON() { + return { + type: this.type, + url: this.url, + raw: this.raw, + id: this.id + }; + } +} +class AutospiedModule { + type = "autospy"; + constructor(raw, id, url) { + this.raw = raw; + this.id = id; + this.url = url; + } + static fromJSON(data) { + return new AutospiedModule(data.raw, data.id, data.url); + } + toJSON() { + return { + type: this.type, + url: this.url, + id: this.id, + raw: this.raw + }; + } +} +class RedirectedModule { + type = "redirect"; + constructor(raw, id, url, redirect) { + this.raw = raw; + this.id = id; + this.url = url; + this.redirect = redirect; + } + static fromJSON(data) { + return new RedirectedModule(data.raw, data.id, data.url, data.redirect); + } + toJSON() { + return { + type: this.type, + url: this.url, + raw: this.raw, + id: this.id, + redirect: this.redirect + }; + } +} +class ManualMockedModule { + cache; + type = "manual"; + constructor(raw, id, url, factory) { + this.raw = raw; + this.id = id; + this.url = url; + this.factory = factory; + } + async resolve() { + if (this.cache) { + return this.cache; + } + let exports; + try { + exports = await this.factory(); + } catch (err) { + const vitestError = new Error("[vitest] There was an error when mocking a module. " + "If you are using \"vi.mock\" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. " + "Read more: https://vitest.dev/api/vi.html#vi-mock"); + vitestError.cause = err; + throw vitestError; + } + if (exports === null || typeof exports !== "object" || Array.isArray(exports)) { + throw new TypeError(`[vitest] vi.mock("${this.raw}", factory?: () => unknown) is not returning an object. Did you mean to return an object with a "default" key?`); + } + return this.cache = exports; + } + static fromJSON(data, factory) { + return new ManualMockedModule(data.raw, data.id, data.url, factory); + } + toJSON() { + return { + type: this.type, + url: this.url, + id: this.id, + raw: this.raw + }; + } +} + +export { AutomockedModule as A, MockerRegistry as M, RedirectedModule as R, ManualMockedModule as a, AutospiedModule as b }; diff --git a/node_modules/@vitest/mocker/dist/chunk-utils.js b/node_modules/@vitest/mocker/dist/chunk-utils.js new file mode 100644 index 0000000000..3916d3851d --- /dev/null +++ b/node_modules/@vitest/mocker/dist/chunk-utils.js @@ -0,0 +1,16 @@ +const postfixRE = /[?#].*$/; +function cleanUrl(url) { + return url.replace(postfixRE, ""); +} +function createManualModuleSource(moduleUrl, exports, globalAccessor = "\"__vitest_mocker__\"") { + const source = `const module = globalThis[${globalAccessor}].getFactoryModule("${moduleUrl}");`; + const keys = exports.map((name) => { + if (name === "default") { + return `export default module["default"];`; + } + return `export const ${name} = module["${name}"];`; + }).join("\n"); + return `${source}\n${keys}`; +} + +export { cleanUrl as a, createManualModuleSource as c }; diff --git a/node_modules/@vitest/mocker/dist/index.d.ts b/node_modules/@vitest/mocker/dist/index.d.ts new file mode 100644 index 0000000000..c091364992 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/index.d.ts @@ -0,0 +1,21 @@ +import { M as MockedModuleType } from './registry.d-D765pazg.js'; +export { A as AutomockedModule, d as AutomockedModuleSerialized, a as AutospiedModule, e as AutospiedModuleSerialized, b as ManualMockedModule, f as ManualMockedModuleSerialized, g as MockedModule, h as MockedModuleSerialized, c as MockerRegistry, R as RedirectedModule, i as RedirectedModuleSerialized } from './registry.d-D765pazg.js'; +export { M as ModuleMockFactory, a as ModuleMockFactoryWithHelper, b as ModuleMockOptions } from './types.d-D_aRZRdy.js'; + +type Key = string | symbol; +interface MockObjectOptions { + type: MockedModuleType; + globalConstructors: GlobalConstructors; + spyOn: (obj: any, prop: Key) => any; +} +declare function mockObject(options: MockObjectOptions, object: Record, mockExports?: Record): Record; +interface GlobalConstructors { + Object: ObjectConstructor; + Function: FunctionConstructor; + RegExp: RegExpConstructor; + Array: ArrayConstructor; + Map: MapConstructor; +} + +export { MockedModuleType, mockObject }; +export type { GlobalConstructors, MockObjectOptions }; diff --git a/node_modules/@vitest/mocker/dist/index.js b/node_modules/@vitest/mocker/dist/index.js new file mode 100644 index 0000000000..994ea213b5 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/index.js @@ -0,0 +1,174 @@ +export { A as AutomockedModule, b as AutospiedModule, a as ManualMockedModule, M as MockerRegistry, R as RedirectedModule } from './chunk-registry.js'; + +function mockObject(options, object, mockExports = {}) { + const finalizers = new Array(); + const refs = new RefTracker(); + const define = (container, key, value) => { + try { + container[key] = value; + return true; + } catch { + return false; + } + }; + const mockPropertiesOf = (container, newContainer) => { + const containerType = getType(container); + const isModule = containerType === "Module" || !!container.__esModule; + for (const { key: property, descriptor } of getAllMockableProperties(container, isModule, options.globalConstructors)) { + // Modules define their exports as getters. We want to process those. + if (!isModule && descriptor.get) { + try { + Object.defineProperty(newContainer, property, descriptor); + } catch {} + continue; + } + // Skip special read-only props, we don't want to mess with those. + if (isSpecialProp(property, containerType)) { + continue; + } + const value = container[property]; + // Special handling of references we've seen before to prevent infinite + // recursion in circular objects. + const refId = refs.getId(value); + if (refId !== undefined) { + finalizers.push(() => define(newContainer, property, refs.getMockedValue(refId))); + continue; + } + const type = getType(value); + if (Array.isArray(value)) { + define(newContainer, property, []); + continue; + } + const isFunction = type.includes("Function") && typeof value === "function"; + if ((!isFunction || value._isMockFunction) && type !== "Object" && type !== "Module") { + define(newContainer, property, value); + continue; + } + // Sometimes this assignment fails for some unknown reason. If it does, + // just move along. + if (!define(newContainer, property, isFunction ? value : {})) { + continue; + } + if (isFunction) { + if (!options.spyOn) { + throw new Error("[@vitest/mocker] `spyOn` is not defined. This is a Vitest error. Please open a new issue with reproduction."); + } + const spyOn = options.spyOn; + function mockFunction() { + // detect constructor call and mock each instance's methods + // so that mock states between prototype/instances don't affect each other + // (jest reference https://github.com/jestjs/jest/blob/2c3d2409879952157433de215ae0eee5188a4384/packages/jest-mock/src/index.ts#L678-L691) + if (this instanceof newContainer[property]) { + for (const { key, descriptor } of getAllMockableProperties(this, false, options.globalConstructors)) { + // skip getter since it's not mocked on prototype as well + if (descriptor.get) { + continue; + } + const value = this[key]; + const type = getType(value); + const isFunction = type.includes("Function") && typeof value === "function"; + if (isFunction) { + // mock and delegate calls to original prototype method, which should be also mocked already + const original = this[key]; + const mock = spyOn(this, key).mockImplementation(original); + const origMockReset = mock.mockReset; + mock.mockRestore = mock.mockReset = () => { + origMockReset.call(mock); + mock.mockImplementation(original); + return mock; + }; + } + } + } + } + const mock = spyOn(newContainer, property); + if (options.type === "automock") { + mock.mockImplementation(mockFunction); + const origMockReset = mock.mockReset; + mock.mockRestore = mock.mockReset = () => { + origMockReset.call(mock); + mock.mockImplementation(mockFunction); + return mock; + }; + } + // tinyspy retains length, but jest doesn't. + Object.defineProperty(newContainer[property], "length", { value: 0 }); + } + refs.track(value, newContainer[property]); + mockPropertiesOf(value, newContainer[property]); + } + }; + const mockedObject = mockExports; + mockPropertiesOf(object, mockedObject); + // Plug together refs + for (const finalizer of finalizers) { + finalizer(); + } + return mockedObject; +} +class RefTracker { + idMap = new Map(); + mockedValueMap = new Map(); + getId(value) { + return this.idMap.get(value); + } + getMockedValue(id) { + return this.mockedValueMap.get(id); + } + track(originalValue, mockedValue) { + const newId = this.idMap.size; + this.idMap.set(originalValue, newId); + this.mockedValueMap.set(newId, mockedValue); + return newId; + } +} +function getType(value) { + return Object.prototype.toString.apply(value).slice(8, -1); +} +function isSpecialProp(prop, parentType) { + return parentType.includes("Function") && typeof prop === "string" && [ + "arguments", + "callee", + "caller", + "length", + "name" + ].includes(prop); +} +function getAllMockableProperties(obj, isModule, constructors) { + const { Map, Object, Function, RegExp, Array } = constructors; + const allProps = new Map(); + let curr = obj; + do { + // we don't need properties from these + if (curr === Object.prototype || curr === Function.prototype || curr === RegExp.prototype) { + break; + } + collectOwnProperties(curr, (key) => { + const descriptor = Object.getOwnPropertyDescriptor(curr, key); + if (descriptor) { + allProps.set(key, { + key, + descriptor + }); + } + }); + } while (curr = Object.getPrototypeOf(curr)); + // default is not specified in ownKeys, if module is interoped + if (isModule && !allProps.has("default") && "default" in obj) { + const descriptor = Object.getOwnPropertyDescriptor(obj, "default"); + if (descriptor) { + allProps.set("default", { + key: "default", + descriptor + }); + } + } + return Array.from(allProps.values()); +} +function collectOwnProperties(obj, collector) { + const collect = typeof collector === "function" ? collector : (key) => collector.add(key); + Object.getOwnPropertyNames(obj).forEach(collect); + Object.getOwnPropertySymbols(obj).forEach(collect); +} + +export { mockObject }; diff --git a/node_modules/@vitest/mocker/dist/mocker.d-Ce9_ySj5.d.ts b/node_modules/@vitest/mocker/dist/mocker.d-Ce9_ySj5.d.ts new file mode 100644 index 0000000000..0a905a0070 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/mocker.d-Ce9_ySj5.d.ts @@ -0,0 +1,83 @@ +import { MaybeMockedDeep } from '@vitest/spy'; +import { b as ModuleMockOptions, a as ModuleMockFactoryWithHelper } from './types.d-D_aRZRdy.js'; +import { g as MockedModule, c as MockerRegistry, M as MockedModuleType } from './registry.d-D765pazg.js'; + +interface CompilerHintsOptions { + /** + * This is the key used to access the globalThis object in the worker. + * Unlike `globalThisAccessor` in other APIs, this is not injected into the script. + * ```ts + * // globalThisKey: '__my_variable__' produces: + * globalThis['__my_variable__'] + * // globalThisKey: '"__my_variable__"' produces: + * globalThis['"__my_variable__"'] // notice double quotes + * ``` + * @default '__vitest_mocker__' + */ + globalThisKey?: string; +} +interface ModuleMockerCompilerHints { + hoisted: (factory: () => T) => T; + mock: (path: string | Promise, factory?: ModuleMockOptions | ModuleMockFactoryWithHelper) => void; + unmock: (path: string | Promise) => void; + doMock: (path: string | Promise, factory?: ModuleMockOptions | ModuleMockFactoryWithHelper) => void; + doUnmock: (path: string | Promise) => void; + importActual: (path: string) => Promise; + importMock: (path: string) => Promise>; +} +declare function createCompilerHints(options?: CompilerHintsOptions): ModuleMockerCompilerHints; + +interface ModuleMockerInterceptor { + register: (module: MockedModule) => Promise; + delete: (url: string) => Promise; + invalidate: () => Promise; +} + +declare class ModuleMocker { + private interceptor; + private rpc; + private spyOn; + private config; + protected registry: MockerRegistry; + private queue; + private mockedIds; + constructor(interceptor: ModuleMockerInterceptor, rpc: ModuleMockerRPC, spyOn: (obj: any, method: string | symbol) => any, config: ModuleMockerConfig); + prepare(): Promise; + resolveFactoryModule(id: string): Promise>; + getFactoryModule(id: string): any; + invalidate(): Promise; + importActual(id: string, importer: string): Promise; + importMock(rawId: string, importer: string): Promise; + mockObject(object: Record, moduleType?: MockedModuleType): Record; + queueMock(rawId: string, importer: string, factoryOrOptions?: ModuleMockOptions | (() => any)): void; + queueUnmock(id: string, importer: string): void; + // We need to await mock registration before importing the actual module + // In case there is a mocked module in the import chain + wrapDynamicImport(moduleFactory: () => Promise): Promise; + private resolveMockPath; +} +interface ResolveIdResult { + id: string; + url: string; + optimized: boolean; +} +interface ResolveMockResult { + mockType: MockedModuleType; + resolvedId: string; + resolvedUrl: string; + redirectUrl?: string | null; + needsInterop?: boolean; +} +interface ModuleMockerRPC { + invalidate: (ids: string[]) => Promise; + resolveId: (id: string, importer: string) => Promise; + resolveMock: (id: string, importer: string, options: { + mock: "spy" | "factory" | "auto" + }) => Promise; +} +interface ModuleMockerConfig { + root: string; +} + +export { ModuleMocker as b, createCompilerHints as c }; +export type { CompilerHintsOptions as C, ModuleMockerInterceptor as M, ResolveIdResult as R, ModuleMockerCompilerHints as a, ModuleMockerConfig as d, ModuleMockerRPC as e, ResolveMockResult as f }; diff --git a/node_modules/@vitest/mocker/dist/node.d.ts b/node_modules/@vitest/mocker/dist/node.d.ts new file mode 100644 index 0000000000..c7b3bc4211 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/node.d.ts @@ -0,0 +1,821 @@ +import { Plugin, Rollup, ViteDevServer } from 'vite'; +import MagicString, { SourceMap } from 'magic-string'; +import { c as MockerRegistry } from './registry.d-D765pazg.js'; +export { findMockRedirect } from './redirect.js'; + +declare function createManualModuleSource(moduleUrl: string, exports: string[], globalAccessor?: string): string; + +interface AutomockPluginOptions { + /** + * @default "__vitest_mocker__" + */ + globalThisAccessor?: string; +} +declare function automockPlugin(options?: AutomockPluginOptions): Plugin; +// TODO: better source map replacement +declare function automockModule(code: string, mockType: "automock" | "autospy", parse: (code: string) => any, options?: AutomockPluginOptions): MagicString; + +interface DynamicImportPluginOptions { + /** + * @default `"__vitest_mocker__"` + */ + globalThisAccessor?: string; + filter?: (id: string) => boolean; +} +declare function dynamicImportPlugin(options?: DynamicImportPluginOptions): Plugin; + +// This definition file follows a somewhat unusual format. ESTree allows +// runtime type checks based on the `type` parameter. In order to explain this +// to typescript we want to use discriminated union types: +// https://github.com/Microsoft/TypeScript/pull/9163 +// +// For ESTree this is a bit tricky because the high level interfaces like +// Node or Function are pulling double duty. We want to pass common fields down +// to the interfaces that extend them (like Identifier or +// ArrowFunctionExpression), but you can't extend a type union or enforce +// common fields on them. So we've split the high level interfaces into two +// types, a base type which passes down inherited fields, and a type union of +// all types which extend the base type. Only the type union is exported, and +// the union is how other types refer to the collection of inheriting types. +// +// This makes the definitions file here somewhat more difficult to maintain, +// but it has the notable advantage of making ESTree much easier to use as +// an end user. + +interface BaseNodeWithoutComments { + // Every leaf interface that extends BaseNode must specify a type property. + // The type property should be a string literal. For example, Identifier + // has: `type: "Identifier"` + type: string; + loc?: SourceLocation | null | undefined; + range?: [number, number] | undefined; +} + +interface BaseNode extends BaseNodeWithoutComments { + leadingComments?: Comment[] | undefined; + trailingComments?: Comment[] | undefined; +} + +interface NodeMap { + AssignmentProperty: AssignmentProperty; + CatchClause: CatchClause; + Class: Class; + ClassBody: ClassBody; + Expression: Expression; + Function: Function; + Identifier: Identifier; + Literal: Literal; + MethodDefinition: MethodDefinition; + ModuleDeclaration: ModuleDeclaration; + ModuleSpecifier: ModuleSpecifier; + Pattern: Pattern; + PrivateIdentifier: PrivateIdentifier; + Program: Program; + Property: Property; + PropertyDefinition: PropertyDefinition; + SpreadElement: SpreadElement; + Statement: Statement; + Super: Super; + SwitchCase: SwitchCase; + TemplateElement: TemplateElement; + VariableDeclarator: VariableDeclarator; +} + +type Node$1 = NodeMap[keyof NodeMap]; + +interface Comment extends BaseNodeWithoutComments { + type: "Line" | "Block"; + value: string; +} + +interface SourceLocation { + source?: string | null | undefined; + start: Position; + end: Position; +} + +interface Position { + /** >= 1 */ + line: number; + /** >= 0 */ + column: number; +} + +interface Program extends BaseNode { + type: "Program"; + sourceType: "script" | "module"; + body: Array; + comments?: Comment[] | undefined; +} + +interface Directive extends BaseNode { + type: "ExpressionStatement"; + expression: Literal; + directive: string; +} + +interface BaseFunction extends BaseNode { + params: Pattern[]; + generator?: boolean | undefined; + async?: boolean | undefined; + // The body is either BlockStatement or Expression because arrow functions + // can have a body that's either. FunctionDeclarations and + // FunctionExpressions have only BlockStatement bodies. + body: BlockStatement | Expression; +} + +type Function = FunctionDeclaration | FunctionExpression | ArrowFunctionExpression; + +type Statement = + | ExpressionStatement + | BlockStatement + | StaticBlock + | EmptyStatement + | DebuggerStatement + | WithStatement + | ReturnStatement + | LabeledStatement + | BreakStatement + | ContinueStatement + | IfStatement + | SwitchStatement + | ThrowStatement + | TryStatement + | WhileStatement + | DoWhileStatement + | ForStatement + | ForInStatement + | ForOfStatement + | Declaration; + +interface BaseStatement extends BaseNode {} + +interface EmptyStatement extends BaseStatement { + type: "EmptyStatement"; +} + +interface BlockStatement extends BaseStatement { + type: "BlockStatement"; + body: Statement[]; + innerComments?: Comment[] | undefined; +} + +interface StaticBlock extends Omit { + type: "StaticBlock"; +} + +interface ExpressionStatement extends BaseStatement { + type: "ExpressionStatement"; + expression: Expression; +} + +interface IfStatement extends BaseStatement { + type: "IfStatement"; + test: Expression; + consequent: Statement; + alternate?: Statement | null | undefined; +} + +interface LabeledStatement extends BaseStatement { + type: "LabeledStatement"; + label: Identifier; + body: Statement; +} + +interface BreakStatement extends BaseStatement { + type: "BreakStatement"; + label?: Identifier | null | undefined; +} + +interface ContinueStatement extends BaseStatement { + type: "ContinueStatement"; + label?: Identifier | null | undefined; +} + +interface WithStatement extends BaseStatement { + type: "WithStatement"; + object: Expression; + body: Statement; +} + +interface SwitchStatement extends BaseStatement { + type: "SwitchStatement"; + discriminant: Expression; + cases: SwitchCase[]; +} + +interface ReturnStatement extends BaseStatement { + type: "ReturnStatement"; + argument?: Expression | null | undefined; +} + +interface ThrowStatement extends BaseStatement { + type: "ThrowStatement"; + argument: Expression; +} + +interface TryStatement extends BaseStatement { + type: "TryStatement"; + block: BlockStatement; + handler?: CatchClause | null | undefined; + finalizer?: BlockStatement | null | undefined; +} + +interface WhileStatement extends BaseStatement { + type: "WhileStatement"; + test: Expression; + body: Statement; +} + +interface DoWhileStatement extends BaseStatement { + type: "DoWhileStatement"; + body: Statement; + test: Expression; +} + +interface ForStatement extends BaseStatement { + type: "ForStatement"; + init?: VariableDeclaration | Expression | null | undefined; + test?: Expression | null | undefined; + update?: Expression | null | undefined; + body: Statement; +} + +interface BaseForXStatement extends BaseStatement { + left: VariableDeclaration | Pattern; + right: Expression; + body: Statement; +} + +interface ForInStatement extends BaseForXStatement { + type: "ForInStatement"; +} + +interface DebuggerStatement extends BaseStatement { + type: "DebuggerStatement"; +} + +type Declaration = FunctionDeclaration | VariableDeclaration | ClassDeclaration; + +interface BaseDeclaration extends BaseStatement {} + +interface MaybeNamedFunctionDeclaration extends BaseFunction, BaseDeclaration { + type: "FunctionDeclaration"; + /** It is null when a function declaration is a part of the `export default function` statement */ + id: Identifier | null; + body: BlockStatement; +} + +interface FunctionDeclaration extends MaybeNamedFunctionDeclaration { + id: Identifier; +} + +interface VariableDeclaration extends BaseDeclaration { + type: "VariableDeclaration"; + declarations: VariableDeclarator[]; + kind: "var" | "let" | "const" | "using" | "await using"; +} + +interface VariableDeclarator extends BaseNode { + type: "VariableDeclarator"; + id: Pattern; + init?: Expression | null | undefined; +} + +interface ExpressionMap { + ArrayExpression: ArrayExpression; + ArrowFunctionExpression: ArrowFunctionExpression; + AssignmentExpression: AssignmentExpression; + AwaitExpression: AwaitExpression; + BinaryExpression: BinaryExpression; + CallExpression: CallExpression; + ChainExpression: ChainExpression; + ClassExpression: ClassExpression; + ConditionalExpression: ConditionalExpression; + FunctionExpression: FunctionExpression; + Identifier: Identifier; + ImportExpression: ImportExpression; + Literal: Literal; + LogicalExpression: LogicalExpression; + MemberExpression: MemberExpression; + MetaProperty: MetaProperty; + NewExpression: NewExpression; + ObjectExpression: ObjectExpression; + SequenceExpression: SequenceExpression; + TaggedTemplateExpression: TaggedTemplateExpression; + TemplateLiteral: TemplateLiteral; + ThisExpression: ThisExpression; + UnaryExpression: UnaryExpression; + UpdateExpression: UpdateExpression; + YieldExpression: YieldExpression; +} + +type Expression = ExpressionMap[keyof ExpressionMap]; + +interface BaseExpression extends BaseNode {} + +type ChainElement = SimpleCallExpression | MemberExpression; + +interface ChainExpression extends BaseExpression { + type: "ChainExpression"; + expression: ChainElement; +} + +interface ThisExpression extends BaseExpression { + type: "ThisExpression"; +} + +interface ArrayExpression extends BaseExpression { + type: "ArrayExpression"; + elements: Array; +} + +interface ObjectExpression extends BaseExpression { + type: "ObjectExpression"; + properties: Array; +} + +interface PrivateIdentifier extends BaseNode { + type: "PrivateIdentifier"; + name: string; +} + +interface Property extends BaseNode { + type: "Property"; + key: Expression | PrivateIdentifier; + value: Expression | Pattern; // Could be an AssignmentProperty + kind: "init" | "get" | "set"; + method: boolean; + shorthand: boolean; + computed: boolean; +} + +interface PropertyDefinition extends BaseNode { + type: "PropertyDefinition"; + key: Expression | PrivateIdentifier; + value?: Expression | null | undefined; + computed: boolean; + static: boolean; +} + +interface FunctionExpression extends BaseFunction, BaseExpression { + id?: Identifier | null | undefined; + type: "FunctionExpression"; + body: BlockStatement; +} + +interface SequenceExpression extends BaseExpression { + type: "SequenceExpression"; + expressions: Expression[]; +} + +interface UnaryExpression extends BaseExpression { + type: "UnaryExpression"; + operator: UnaryOperator; + prefix: true; + argument: Expression; +} + +interface BinaryExpression extends BaseExpression { + type: "BinaryExpression"; + operator: BinaryOperator; + left: Expression | PrivateIdentifier; + right: Expression; +} + +interface AssignmentExpression extends BaseExpression { + type: "AssignmentExpression"; + operator: AssignmentOperator; + left: Pattern | MemberExpression; + right: Expression; +} + +interface UpdateExpression extends BaseExpression { + type: "UpdateExpression"; + operator: UpdateOperator; + argument: Expression; + prefix: boolean; +} + +interface LogicalExpression extends BaseExpression { + type: "LogicalExpression"; + operator: LogicalOperator; + left: Expression; + right: Expression; +} + +interface ConditionalExpression extends BaseExpression { + type: "ConditionalExpression"; + test: Expression; + alternate: Expression; + consequent: Expression; +} + +interface BaseCallExpression extends BaseExpression { + callee: Expression | Super; + arguments: Array; +} +type CallExpression = SimpleCallExpression | NewExpression; + +interface SimpleCallExpression extends BaseCallExpression { + type: "CallExpression"; + optional: boolean; +} + +interface NewExpression extends BaseCallExpression { + type: "NewExpression"; +} + +interface MemberExpression extends BaseExpression, BasePattern { + type: "MemberExpression"; + object: Expression | Super; + property: Expression | PrivateIdentifier; + computed: boolean; + optional: boolean; +} + +type Pattern = Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression; + +interface BasePattern extends BaseNode {} + +interface SwitchCase extends BaseNode { + type: "SwitchCase"; + test?: Expression | null | undefined; + consequent: Statement[]; +} + +interface CatchClause extends BaseNode { + type: "CatchClause"; + param: Pattern | null; + body: BlockStatement; +} + +interface Identifier extends BaseNode, BaseExpression, BasePattern { + type: "Identifier"; + name: string; +} + +type Literal = SimpleLiteral | RegExpLiteral | BigIntLiteral; + +interface SimpleLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value: string | boolean | number | null; + raw?: string | undefined; +} + +interface RegExpLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value?: RegExp | null | undefined; + regex: { + pattern: string; + flags: string; + }; + raw?: string | undefined; +} + +interface BigIntLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value?: bigint | null | undefined; + bigint: string; + raw?: string | undefined; +} + +type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; + +type BinaryOperator = + | "==" + | "!=" + | "===" + | "!==" + | "<" + | "<=" + | ">" + | ">=" + | "<<" + | ">>" + | ">>>" + | "+" + | "-" + | "*" + | "/" + | "%" + | "**" + | "|" + | "^" + | "&" + | "in" + | "instanceof"; + +type LogicalOperator = "||" | "&&" | "??"; + +type AssignmentOperator = + | "=" + | "+=" + | "-=" + | "*=" + | "/=" + | "%=" + | "**=" + | "<<=" + | ">>=" + | ">>>=" + | "|=" + | "^=" + | "&=" + | "||=" + | "&&=" + | "??="; + +type UpdateOperator = "++" | "--"; + +interface ForOfStatement extends BaseForXStatement { + type: "ForOfStatement"; + await: boolean; +} + +interface Super extends BaseNode { + type: "Super"; +} + +interface SpreadElement extends BaseNode { + type: "SpreadElement"; + argument: Expression; +} + +interface ArrowFunctionExpression extends BaseExpression, BaseFunction { + type: "ArrowFunctionExpression"; + expression: boolean; + body: BlockStatement | Expression; +} + +interface YieldExpression extends BaseExpression { + type: "YieldExpression"; + argument?: Expression | null | undefined; + delegate: boolean; +} + +interface TemplateLiteral extends BaseExpression { + type: "TemplateLiteral"; + quasis: TemplateElement[]; + expressions: Expression[]; +} + +interface TaggedTemplateExpression extends BaseExpression { + type: "TaggedTemplateExpression"; + tag: Expression; + quasi: TemplateLiteral; +} + +interface TemplateElement extends BaseNode { + type: "TemplateElement"; + tail: boolean; + value: { + /** It is null when the template literal is tagged and the text has an invalid escape (e.g. - tag`\unicode and \u{55}`) */ + cooked?: string | null | undefined; + raw: string; + }; +} + +interface AssignmentProperty extends Property { + value: Pattern; + kind: "init"; + method: boolean; // false +} + +interface ObjectPattern extends BasePattern { + type: "ObjectPattern"; + properties: Array; +} + +interface ArrayPattern extends BasePattern { + type: "ArrayPattern"; + elements: Array; +} + +interface RestElement extends BasePattern { + type: "RestElement"; + argument: Pattern; +} + +interface AssignmentPattern extends BasePattern { + type: "AssignmentPattern"; + left: Pattern; + right: Expression; +} + +type Class = ClassDeclaration | ClassExpression; +interface BaseClass extends BaseNode { + superClass?: Expression | null | undefined; + body: ClassBody; +} + +interface ClassBody extends BaseNode { + type: "ClassBody"; + body: Array; +} + +interface MethodDefinition extends BaseNode { + type: "MethodDefinition"; + key: Expression | PrivateIdentifier; + value: FunctionExpression; + kind: "constructor" | "method" | "get" | "set"; + computed: boolean; + static: boolean; +} + +interface MaybeNamedClassDeclaration extends BaseClass, BaseDeclaration { + type: "ClassDeclaration"; + /** It is null when a class declaration is a part of the `export default class` statement */ + id: Identifier | null; +} + +interface ClassDeclaration extends MaybeNamedClassDeclaration { + id: Identifier; +} + +interface ClassExpression extends BaseClass, BaseExpression { + type: "ClassExpression"; + id?: Identifier | null | undefined; +} + +interface MetaProperty extends BaseExpression { + type: "MetaProperty"; + meta: Identifier; + property: Identifier; +} + +type ModuleDeclaration = + | ImportDeclaration + | ExportNamedDeclaration + | ExportDefaultDeclaration + | ExportAllDeclaration; +interface BaseModuleDeclaration extends BaseNode {} + +type ModuleSpecifier = ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier; +interface BaseModuleSpecifier extends BaseNode { + local: Identifier; +} + +interface ImportDeclaration extends BaseModuleDeclaration { + type: "ImportDeclaration"; + specifiers: Array; + attributes: ImportAttribute[]; + source: Literal; +} + +interface ImportSpecifier extends BaseModuleSpecifier { + type: "ImportSpecifier"; + imported: Identifier | Literal; +} + +interface ImportAttribute extends BaseNode { + type: "ImportAttribute"; + key: Identifier | Literal; + value: Literal; +} + +interface ImportExpression extends BaseExpression { + type: "ImportExpression"; + source: Expression; + options?: Expression | null | undefined; +} + +interface ImportDefaultSpecifier extends BaseModuleSpecifier { + type: "ImportDefaultSpecifier"; +} + +interface ImportNamespaceSpecifier extends BaseModuleSpecifier { + type: "ImportNamespaceSpecifier"; +} + +interface ExportNamedDeclaration extends BaseModuleDeclaration { + type: "ExportNamedDeclaration"; + declaration?: Declaration | null | undefined; + specifiers: ExportSpecifier[]; + attributes: ImportAttribute[]; + source?: Literal | null | undefined; +} + +interface ExportSpecifier extends Omit { + type: "ExportSpecifier"; + local: Identifier | Literal; + exported: Identifier | Literal; +} + +interface ExportDefaultDeclaration extends BaseModuleDeclaration { + type: "ExportDefaultDeclaration"; + declaration: MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | Expression; +} + +interface ExportAllDeclaration extends BaseModuleDeclaration { + type: "ExportAllDeclaration"; + exported: Identifier | Literal | null; + attributes: ImportAttribute[]; + source: Literal; +} + +interface AwaitExpression extends BaseExpression { + type: "AwaitExpression"; + argument: Expression; +} + +type Positioned = T & { + start: number + end: number +}; +type Node = Positioned; + +interface HoistMocksOptions { + /** + * List of modules that should always be imported before compiler hints. + * @default 'vitest' + */ + hoistedModule?: string; + /** + * @default ["vi", "vitest"] + */ + utilsObjectNames?: string[]; + /** + * @default ["mock", "unmock"] + */ + hoistableMockMethodNames?: string[]; + /** + * @default ["mock", "unmock", "doMock", "doUnmock"] + */ + dynamicImportMockMethodNames?: string[]; + /** + * @default ["hoisted"] + */ + hoistedMethodNames?: string[]; + regexpHoistable?: RegExp; + codeFrameGenerator?: CodeFrameGenerator; +} +interface HoistMocksPluginOptions extends Omit { + include?: string | RegExp | (string | RegExp)[]; + exclude?: string | RegExp | (string | RegExp)[]; + /** + * overrides include/exclude options + */ + filter?: (id: string) => boolean; +} +declare function hoistMocksPlugin(options?: HoistMocksPluginOptions): Plugin; +interface HoistMocksResult { + code: string; + map: SourceMap; +} +interface CodeFrameGenerator { + (node: Positioned, id: string, code: string): string; +} +// this is a fork of Vite SSR transform +declare function hoistMocks(code: string, id: string, parse: Rollup.PluginContext["parse"], options?: HoistMocksOptions): HoistMocksResult | undefined; + +interface InterceptorPluginOptions { + /** + * @default "__vitest_mocker__" + */ + globalThisAccessor?: string; + registry?: MockerRegistry; +} +declare function interceptorPlugin(options?: InterceptorPluginOptions): Plugin; + +interface MockerPluginOptions extends AutomockPluginOptions { + hoistMocks?: HoistMocksPluginOptions; +} +// this is an implementation for public usage +// vitest doesn't use this plugin directly +declare function mockerPlugin(options?: MockerPluginOptions): Plugin[]; + +interface ServerResolverOptions { + /** + * @default ['/node_modules/'] + */ + moduleDirectories?: string[]; +} +declare class ServerMockResolver { + private server; + private options; + constructor(server: ViteDevServer, options?: ServerResolverOptions); + resolveMock(rawId: string, importer: string, options: { + mock: "spy" | "factory" | "auto" + }): Promise; + invalidate(ids: string[]): void; + resolveId(id: string, importer?: string): Promise; + private normalizeResolveIdToUrl; + private resolveMockId; + private resolveModule; +} +interface ServerMockResolution { + mockType: "manual" | "redirect" | "automock" | "autospy"; + resolvedId: string; + resolvedUrl: string; + needsInterop?: boolean; + redirectUrl?: string | null; +} +interface ServerIdResolution { + id: string; + url: string; + optimized: boolean; +} + +export { ServerMockResolver, automockModule, automockPlugin, createManualModuleSource, dynamicImportPlugin, hoistMocks, hoistMocksPlugin, interceptorPlugin, mockerPlugin }; +export type { AutomockPluginOptions, HoistMocksPluginOptions, HoistMocksResult, InterceptorPluginOptions, ServerIdResolution, ServerMockResolution, ServerResolverOptions }; diff --git a/node_modules/@vitest/mocker/dist/node.js b/node_modules/@vitest/mocker/dist/node.js new file mode 100644 index 0000000000..f7dad3e28e --- /dev/null +++ b/node_modules/@vitest/mocker/dist/node.js @@ -0,0 +1,1306 @@ +import { a as cleanUrl, c as createManualModuleSource } from './chunk-utils.js'; +import MagicString from 'magic-string'; +import { walk } from 'estree-walker'; +import { createFilter } from 'vite'; +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path/posix'; +import { M as MockerRegistry, a as ManualMockedModule } from './chunk-registry.js'; +import { fileURLToPath } from 'node:url'; +import { existsSync, readFileSync } from 'node:fs'; +import { findMockRedirect } from './redirect.js'; +import { i as isAbsolute, j as join$1, r as resolve } from './chunk-pathe.M-eThtNZ.js'; +import 'node:module'; + +const isNodeInPatternWeakSet = new WeakSet(); +function setIsNodeInPattern(node) { + return isNodeInPatternWeakSet.add(node); +} +function isNodeInPattern(node) { + return isNodeInPatternWeakSet.has(node); +} +/** +* Same logic from \@vue/compiler-core & \@vue/compiler-sfc +* Except this is using acorn AST +*/ +function esmWalker(root, { onIdentifier, onImportMeta, onDynamicImport, onCallExpression }) { + const parentStack = []; + const varKindStack = []; + const scopeMap = new WeakMap(); + const identifiers = []; + const setScope = (node, name) => { + let scopeIds = scopeMap.get(node); + if (scopeIds && scopeIds.has(name)) { + return; + } + if (!scopeIds) { + scopeIds = new Set(); + scopeMap.set(node, scopeIds); + } + scopeIds.add(name); + }; + function isInScope(name, parents) { + return parents.some((node) => { + var _scopeMap$get; + return node && ((_scopeMap$get = scopeMap.get(node)) === null || _scopeMap$get === void 0 ? void 0 : _scopeMap$get.has(name)); + }); + } + function handlePattern(p, parentScope) { + if (p.type === "Identifier") { + setScope(parentScope, p.name); + } else if (p.type === "RestElement") { + handlePattern(p.argument, parentScope); + } else if (p.type === "ObjectPattern") { + p.properties.forEach((property) => { + if (property.type === "RestElement") { + setScope(parentScope, property.argument.name); + } else { + handlePattern(property.value, parentScope); + } + }); + } else if (p.type === "ArrayPattern") { + p.elements.forEach((element) => { + if (element) { + handlePattern(element, parentScope); + } + }); + } else if (p.type === "AssignmentPattern") { + handlePattern(p.left, parentScope); + } else { + setScope(parentScope, p.name); + } + } + walk(root, { + enter(node, parent) { + if (node.type === "ImportDeclaration") { + return this.skip(); + } + // track parent stack, skip for "else-if"/"else" branches as acorn nests + // the ast within "if" nodes instead of flattening them + if (parent && !(parent.type === "IfStatement" && node === parent.alternate)) { + parentStack.unshift(parent); + } + // track variable declaration kind stack used by VariableDeclarator + if (node.type === "VariableDeclaration") { + varKindStack.unshift(node.kind); + } + if (node.type === "CallExpression") { + onCallExpression === null || onCallExpression === void 0 ? void 0 : onCallExpression(node); + } + if (node.type === "MetaProperty" && node.meta.name === "import") { + onImportMeta === null || onImportMeta === void 0 ? void 0 : onImportMeta(node); + } else if (node.type === "ImportExpression") { + onDynamicImport === null || onDynamicImport === void 0 ? void 0 : onDynamicImport(node); + } + if (node.type === "Identifier") { + if (!isInScope(node.name, parentStack) && isRefIdentifier(node, parent, parentStack)) { + // record the identifier, for DFS -> BFS + identifiers.push([node, parentStack.slice(0)]); + } + } else if (isFunctionNode(node)) { + // If it is a function declaration, it could be shadowing an import + // Add its name to the scope so it won't get replaced + if (node.type === "FunctionDeclaration") { + const parentScope = findParentScope(parentStack); + if (parentScope) { + setScope(parentScope, node.id.name); + } + } + // walk function expressions and add its arguments to known identifiers + // so that we don't prefix them + node.params.forEach((p) => { + if (p.type === "ObjectPattern" || p.type === "ArrayPattern") { + handlePattern(p, node); + return; + } + walk(p.type === "AssignmentPattern" ? p.left : p, { enter(child, parent) { + // skip params default value of destructure + if ((parent === null || parent === void 0 ? void 0 : parent.type) === "AssignmentPattern" && (parent === null || parent === void 0 ? void 0 : parent.right) === child) { + return this.skip(); + } + if (child.type !== "Identifier") { + return; + } + // do not record as scope variable if is a destructuring keyword + if (isStaticPropertyKey(child, parent)) { + return; + } + // do not record if this is a default value + // assignment of a destructuring variable + if ((parent === null || parent === void 0 ? void 0 : parent.type) === "TemplateLiteral" && (parent === null || parent === void 0 ? void 0 : parent.expressions.includes(child)) || (parent === null || parent === void 0 ? void 0 : parent.type) === "CallExpression" && (parent === null || parent === void 0 ? void 0 : parent.callee) === child) { + return; + } + setScope(node, child.name); + } }); + }); + } else if (node.type === "Property" && parent.type === "ObjectPattern") { + // mark property in destructuring pattern + setIsNodeInPattern(node); + } else if (node.type === "VariableDeclarator") { + const parentFunction = findParentScope(parentStack, varKindStack[0] === "var"); + if (parentFunction) { + handlePattern(node.id, parentFunction); + } + } else if (node.type === "CatchClause" && node.param) { + handlePattern(node.param, node); + } + }, + leave(node, parent) { + // untrack parent stack from above + if (parent && !(parent.type === "IfStatement" && node === parent.alternate)) { + parentStack.shift(); + } + if (node.type === "VariableDeclaration") { + varKindStack.shift(); + } + } + }); + // emit the identifier events in BFS so the hoisted declarations + // can be captured correctly + identifiers.forEach(([node, stack]) => { + if (!isInScope(node.name, stack)) { + const parent = stack[0]; + const grandparent = stack[1]; + const hasBindingShortcut = isStaticProperty(parent) && parent.shorthand && (!isNodeInPattern(parent) || isInDestructuringAssignment(parent, parentStack)); + const classDeclaration = parent.type === "PropertyDefinition" && (grandparent === null || grandparent === void 0 ? void 0 : grandparent.type) === "ClassBody" || parent.type === "ClassDeclaration" && node === parent.superClass; + const classExpression = parent.type === "ClassExpression" && node === parent.id; + onIdentifier === null || onIdentifier === void 0 ? void 0 : onIdentifier(node, { + hasBindingShortcut, + classDeclaration, + classExpression + }, stack); + } + }); +} +function isRefIdentifier(id, parent, parentStack) { + // declaration id + if (parent.type === "CatchClause" || (parent.type === "VariableDeclarator" || parent.type === "ClassDeclaration") && parent.id === id) { + return false; + } + if (isFunctionNode(parent)) { + // function declaration/expression id + if (parent.id === id) { + return false; + } + // params list + if (parent.params.includes(id)) { + return false; + } + } + // class method name + if (parent.type === "MethodDefinition" && !parent.computed) { + return false; + } + // property key + if (isStaticPropertyKey(id, parent)) { + return false; + } + // object destructuring pattern + if (isNodeInPattern(parent) && parent.value === id) { + return false; + } + // non-assignment array destructuring pattern + if (parent.type === "ArrayPattern" && !isInDestructuringAssignment(parent, parentStack)) { + return false; + } + // member expression property + if (parent.type === "MemberExpression" && parent.property === id && !parent.computed) { + return false; + } + if (parent.type === "ExportSpecifier") { + return false; + } + // is a special keyword but parsed as identifier + if (id.name === "arguments") { + return false; + } + return true; +} +function isStaticProperty(node) { + return node && node.type === "Property" && !node.computed; +} +function isStaticPropertyKey(node, parent) { + return isStaticProperty(parent) && parent.key === node; +} +const functionNodeTypeRE = /Function(?:Expression|Declaration)$|Method$/; +function isFunctionNode(node) { + return functionNodeTypeRE.test(node.type); +} +const blockNodeTypeRE = /^BlockStatement$|^For(?:In|Of)?Statement$/; +function isBlock(node) { + return blockNodeTypeRE.test(node.type); +} +function findParentScope(parentStack, isVar = false) { + return parentStack.find(isVar ? isFunctionNode : isBlock); +} +function isInDestructuringAssignment(parent, parentStack) { + if (parent && (parent.type === "Property" || parent.type === "ArrayPattern")) { + return parentStack.some((i) => i.type === "AssignmentExpression"); + } + return false; +} +function getArbitraryModuleIdentifier(node) { + return node.type === "Identifier" ? node.name : node.raw; +} + +function automockPlugin(options = {}) { + return { + name: "vitest:automock", + enforce: "post", + transform(code, id) { + if (id.includes("mock=automock") || id.includes("mock=autospy")) { + const mockType = id.includes("mock=automock") ? "automock" : "autospy"; + const ms = automockModule(code, mockType, this.parse, options); + return { + code: ms.toString(), + map: ms.generateMap({ + hires: "boundary", + source: cleanUrl(id) + }) + }; + } + } + }; +} +// TODO: better source map replacement +function automockModule(code, mockType, parse, options = {}) { + const globalThisAccessor = options.globalThisAccessor || "\"__vitest_mocker__\""; + const ast = parse(code); + const m = new MagicString(code); + const allSpecifiers = []; + let importIndex = 0; + for (const _node of ast.body) { + if (_node.type === "ExportAllDeclaration") { + throw new Error(`automocking files with \`export *\` is not supported in browser mode because it cannot be statically analysed`); + } + if (_node.type === "ExportNamedDeclaration") { + const node = _node; + const declaration = node.declaration; + function traversePattern(expression) { + // export const test = '1' + if (expression.type === "Identifier") { + allSpecifiers.push({ name: expression.name }); + } else if (expression.type === "ArrayPattern") { + expression.elements.forEach((element) => { + if (!element) { + return; + } + traversePattern(element); + }); + } else if (expression.type === "ObjectPattern") { + expression.properties.forEach((property) => { + // export const { ...rest } = {} + if (property.type === "RestElement") { + traversePattern(property); + } else if (property.type === "Property") { + traversePattern(property.value); + } else ; + }); + } else if (expression.type === "RestElement") { + traversePattern(expression.argument); + } else if (expression.type === "AssignmentPattern") { + throw new Error(`AssignmentPattern is not supported. Please open a new bug report.`); + } else if (expression.type === "MemberExpression") { + throw new Error(`MemberExpression is not supported. Please open a new bug report.`); + } else ; + } + if (declaration) { + if (declaration.type === "FunctionDeclaration") { + allSpecifiers.push({ name: declaration.id.name }); + } else if (declaration.type === "VariableDeclaration") { + declaration.declarations.forEach((declaration) => { + traversePattern(declaration.id); + }); + } else if (declaration.type === "ClassDeclaration") { + allSpecifiers.push({ name: declaration.id.name }); + } else ; + m.remove(node.start, declaration.start); + } + const specifiers = node.specifiers || []; + const source = node.source; + if (!source && specifiers.length) { + specifiers.forEach((specifier) => { + allSpecifiers.push({ + alias: getArbitraryModuleIdentifier(specifier.exported), + name: getArbitraryModuleIdentifier(specifier.local) + }); + }); + m.remove(node.start, node.end); + } else if (source && specifiers.length) { + const importNames = []; + specifiers.forEach((specifier) => { + const importedName = `__vitest_imported_${importIndex++}__`; + importNames.push([getArbitraryModuleIdentifier(specifier.local), importedName]); + allSpecifiers.push({ + name: importedName, + alias: getArbitraryModuleIdentifier(specifier.exported) + }); + }); + const importString = `import { ${importNames.map(([name, alias]) => `${name} as ${alias}`).join(", ")} } from '${source.value}'`; + m.overwrite(node.start, node.end, importString); + } + } + if (_node.type === "ExportDefaultDeclaration") { + const node = _node; + const declaration = node.declaration; + allSpecifiers.push({ + name: "__vitest_default", + alias: "default" + }); + m.overwrite(node.start, declaration.start, `const __vitest_default = `); + } + } + const moduleObject = ` +const __vitest_current_es_module__ = { + __esModule: true, + ${allSpecifiers.map(({ name }) => `["${name}"]: ${name},`).join("\n ")} +} +const __vitest_mocked_module__ = globalThis[${globalThisAccessor}].mockObject(__vitest_current_es_module__, "${mockType}") +`; + const assigning = allSpecifiers.map(({ name }, index) => { + return `const __vitest_mocked_${index}__ = __vitest_mocked_module__["${name}"]`; + }).join("\n"); + const redeclarations = allSpecifiers.map(({ name, alias }, index) => { + return ` __vitest_mocked_${index}__ as ${alias || name},`; + }).join("\n"); + const specifiersExports = ` +export { +${redeclarations} +} +`; + m.append(moduleObject + assigning + specifiersExports); + return m; +} + +const regexDynamicImport = /import\s*\(/; +function dynamicImportPlugin(options = {}) { + return { + name: "vitest:browser:esm-injector", + enforce: "post", + transform(source, id) { + // TODO: test is not called for static imports + if (!regexDynamicImport.test(source)) { + return; + } + if (options.filter && !options.filter(id)) { + return; + } + return injectDynamicImport(source, id, this.parse, options); + } + }; +} +function injectDynamicImport(code, id, parse, options = {}) { + const s = new MagicString(code); + let ast; + try { + ast = parse(code); + } catch (err) { + console.error(`Cannot parse ${id}:\n${err.message}`); + return; + } + // 3. convert references to import bindings & import.meta references + esmWalker(ast, { + onImportMeta() { + // s.update(node.start, node.end, viImportMetaKey) + }, + onDynamicImport(node) { + const globalThisAccessor = options.globalThisAccessor || "\"__vitest_mocker__\""; + const replaceString = `globalThis[${globalThisAccessor}].wrapDynamicImport(() => import(`; + const importSubstring = code.substring(node.start, node.end); + const hasIgnore = importSubstring.includes("/* @vite-ignore */"); + s.overwrite(node.start, node.source.start, replaceString + (hasIgnore ? "/* @vite-ignore */ " : "")); + s.overwrite(node.end - 1, node.end, "))"); + } + }); + return { + code: s.toString(), + map: s.generateMap({ + hires: "boundary", + source: id + }) + }; +} + +// AST walker module for ESTree compatible trees + + +function makeTest(test) { + if (typeof test === "string") + { return function (type) { return type === test; } } + else if (!test) + { return function () { return true; } } + else + { return test } +} + +var Found = function Found(node, state) { this.node = node; this.state = state; }; + +// Find the innermost node of a given type that contains the given +// position. Interface similar to findNodeAt. +function findNodeAround(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + var type = override || node.type; + if (node.start > pos || node.end < pos) { return } + baseVisitor[type](node, st, c); + if (test(type, node)) { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +function skipThrough(node, st, c) { c(node, st); } +function ignore(_node, _st, _c) {} + +// Node walkers. + +var base = {}; + +base.Program = base.BlockStatement = base.StaticBlock = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var stmt = list[i]; + + c(stmt, st, "Statement"); + } +}; +base.Statement = skipThrough; +base.EmptyStatement = ignore; +base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression = + function (node, st, c) { return c(node.expression, st, "Expression"); }; +base.IfStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Statement"); + if (node.alternate) { c(node.alternate, st, "Statement"); } +}; +base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); }; +base.BreakStatement = base.ContinueStatement = ignore; +base.WithStatement = function (node, st, c) { + c(node.object, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.SwitchStatement = function (node, st, c) { + c(node.discriminant, st, "Expression"); + for (var i = 0, list = node.cases; i < list.length; i += 1) { + var cs = list[i]; + + c(cs, st); + } +}; +base.SwitchCase = function (node, st, c) { + if (node.test) { c(node.test, st, "Expression"); } + for (var i = 0, list = node.consequent; i < list.length; i += 1) + { + var cons = list[i]; + + c(cons, st, "Statement"); + } +}; +base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) { + if (node.argument) { c(node.argument, st, "Expression"); } +}; +base.ThrowStatement = base.SpreadElement = + function (node, st, c) { return c(node.argument, st, "Expression"); }; +base.TryStatement = function (node, st, c) { + c(node.block, st, "Statement"); + if (node.handler) { c(node.handler, st); } + if (node.finalizer) { c(node.finalizer, st, "Statement"); } +}; +base.CatchClause = function (node, st, c) { + if (node.param) { c(node.param, st, "Pattern"); } + c(node.body, st, "Statement"); +}; +base.WhileStatement = base.DoWhileStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForStatement = function (node, st, c) { + if (node.init) { c(node.init, st, "ForInit"); } + if (node.test) { c(node.test, st, "Expression"); } + if (node.update) { c(node.update, st, "Expression"); } + c(node.body, st, "Statement"); +}; +base.ForInStatement = base.ForOfStatement = function (node, st, c) { + c(node.left, st, "ForInit"); + c(node.right, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForInit = function (node, st, c) { + if (node.type === "VariableDeclaration") { c(node, st); } + else { c(node, st, "Expression"); } +}; +base.DebuggerStatement = ignore; + +base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); }; +base.VariableDeclaration = function (node, st, c) { + for (var i = 0, list = node.declarations; i < list.length; i += 1) + { + var decl = list[i]; + + c(decl, st); + } +}; +base.VariableDeclarator = function (node, st, c) { + c(node.id, st, "Pattern"); + if (node.init) { c(node.init, st, "Expression"); } +}; + +base.Function = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + c(param, st, "Pattern"); + } + c(node.body, st, node.expression ? "Expression" : "Statement"); +}; + +base.Pattern = function (node, st, c) { + if (node.type === "Identifier") + { c(node, st, "VariablePattern"); } + else if (node.type === "MemberExpression") + { c(node, st, "MemberPattern"); } + else + { c(node, st); } +}; +base.VariablePattern = ignore; +base.MemberPattern = skipThrough; +base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); }; +base.ArrayPattern = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Pattern"); } + } +}; +base.ObjectPattern = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + if (prop.type === "Property") { + if (prop.computed) { c(prop.key, st, "Expression"); } + c(prop.value, st, "Pattern"); + } else if (prop.type === "RestElement") { + c(prop.argument, st, "Pattern"); + } + } +}; + +base.Expression = skipThrough; +base.ThisExpression = base.Super = base.MetaProperty = ignore; +base.ArrayExpression = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Expression"); } + } +}; +base.ObjectExpression = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) + { + var prop = list[i]; + + c(prop, st); + } +}; +base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration; +base.SequenceExpression = function (node, st, c) { + for (var i = 0, list = node.expressions; i < list.length; i += 1) + { + var expr = list[i]; + + c(expr, st, "Expression"); + } +}; +base.TemplateLiteral = function (node, st, c) { + for (var i = 0, list = node.quasis; i < list.length; i += 1) + { + var quasi = list[i]; + + c(quasi, st); + } + + for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1) + { + var expr = list$1[i$1]; + + c(expr, st, "Expression"); + } +}; +base.TemplateElement = ignore; +base.UnaryExpression = base.UpdateExpression = function (node, st, c) { + c(node.argument, st, "Expression"); +}; +base.BinaryExpression = base.LogicalExpression = function (node, st, c) { + c(node.left, st, "Expression"); + c(node.right, st, "Expression"); +}; +base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) { + c(node.left, st, "Pattern"); + c(node.right, st, "Expression"); +}; +base.ConditionalExpression = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Expression"); + c(node.alternate, st, "Expression"); +}; +base.NewExpression = base.CallExpression = function (node, st, c) { + c(node.callee, st, "Expression"); + if (node.arguments) + { for (var i = 0, list = node.arguments; i < list.length; i += 1) + { + var arg = list[i]; + + c(arg, st, "Expression"); + } } +}; +base.MemberExpression = function (node, st, c) { + c(node.object, st, "Expression"); + if (node.computed) { c(node.property, st, "Expression"); } +}; +base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) { + if (node.declaration) + { c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); } + if (node.source) { c(node.source, st, "Expression"); } +}; +base.ExportAllDeclaration = function (node, st, c) { + if (node.exported) + { c(node.exported, st); } + c(node.source, st, "Expression"); +}; +base.ImportDeclaration = function (node, st, c) { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) + { + var spec = list[i]; + + c(spec, st); + } + c(node.source, st, "Expression"); +}; +base.ImportExpression = function (node, st, c) { + c(node.source, st, "Expression"); +}; +base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore; + +base.TaggedTemplateExpression = function (node, st, c) { + c(node.tag, st, "Expression"); + c(node.quasi, st, "Expression"); +}; +base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); }; +base.Class = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + if (node.superClass) { c(node.superClass, st, "Expression"); } + c(node.body, st); +}; +base.ClassBody = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var elt = list[i]; + + c(elt, st); + } +}; +base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) { + if (node.computed) { c(node.key, st, "Expression"); } + if (node.value) { c(node.value, st, "Expression"); } +}; + +function hoistMocksPlugin(options = {}) { + const filter = options.filter || createFilter(options.include, options.exclude); + const { hoistableMockMethodNames = ["mock", "unmock"], dynamicImportMockMethodNames = [ + "mock", + "unmock", + "doMock", + "doUnmock" + ], hoistedMethodNames = ["hoisted"], utilsObjectNames = ["vi", "vitest"] } = options; + const methods = new Set([ + ...hoistableMockMethodNames, + ...hoistedMethodNames, + ...dynamicImportMockMethodNames + ]); + const regexpHoistable = new RegExp(`\\b(?:${utilsObjectNames.join("|")})\\s*\.\\s*(?:${Array.from(methods).join("|")})\\(`); + return { + name: "vitest:mocks", + enforce: "post", + transform(code, id) { + if (!filter(id)) { + return; + } + return hoistMocks(code, id, this.parse, { + regexpHoistable, + hoistableMockMethodNames, + hoistedMethodNames, + utilsObjectNames, + dynamicImportMockMethodNames, + ...options + }); + } + }; +} +const API_NOT_FOUND_ERROR = `There are some problems in resolving the mocks API. +You may encounter this issue when importing the mocks API from another module other than 'vitest'. +To fix this issue you can either: +- import the mocks API directly from 'vitest' +- enable the 'globals' options`; +function API_NOT_FOUND_CHECK(names) { + return `\nif (${names.map((name) => `typeof globalThis["${name}"] === "undefined"`).join(" && ")}) ` + `{ throw new Error(${JSON.stringify(API_NOT_FOUND_ERROR)}) }\n`; +} +function isIdentifier(node) { + return node.type === "Identifier"; +} +function getNodeTail(code, node) { + let end = node.end; + if (code[node.end] === ";") { + end += 1; + } + if (code[node.end] === "\n") { + return end + 1; + } + if (code[node.end + 1] === "\n") { + end += 1; + } + return end; +} +const regexpHoistable = /\b(?:vi|vitest)\s*\.\s*(?:mock|unmock|hoisted|doMock|doUnmock)\(/; +const hashbangRE = /^#!.*\n/; +// this is a fork of Vite SSR transform +function hoistMocks(code, id, parse, options = {}) { + var _hashbangRE$exec; + const needHoisting = (options.regexpHoistable || regexpHoistable).test(code); + if (!needHoisting) { + return; + } + const s = new MagicString(code); + let ast; + try { + ast = parse(code); + } catch (err) { + console.error(`Cannot parse ${id}:\n${err.message}.`); + return; + } + const { hoistableMockMethodNames = ["mock", "unmock"], dynamicImportMockMethodNames = [ + "mock", + "unmock", + "doMock", + "doUnmock" + ], hoistedMethodNames = ["hoisted"], utilsObjectNames = ["vi", "vitest"], hoistedModule = "vitest" } = options; + // hoist at the start of the file, after the hashbang + let hoistIndex = ((_hashbangRE$exec = hashbangRE.exec(code)) === null || _hashbangRE$exec === void 0 ? void 0 : _hashbangRE$exec[0].length) ?? 0; + let hoistedModuleImported = false; + let uid = 0; + const idToImportMap = new Map(); + const imports = []; + // this will transform import statements into dynamic ones, if there are imports + // it will keep the import as is, if we don't need to mock anything + // in browser environment it will wrap the module value with "vitest_wrap_module" function + // that returns a proxy to the module so that named exports can be mocked + function defineImport(importNode) { + const source = importNode.source.value; + // always hoist vitest import to top of the file, so + // "vi" helpers can access it + if (hoistedModule === source) { + hoistedModuleImported = true; + return; + } + const importId = `__vi_import_${uid++}__`; + imports.push({ + id: importId, + node: importNode + }); + return importId; + } + // 1. check all import statements and record id -> importName map + for (const node of ast.body) { + // import foo from 'foo' --> foo -> __import_foo__.default + // import { baz } from 'foo' --> baz -> __import_foo__.baz + // import * as ok from 'foo' --> ok -> __import_foo__ + if (node.type === "ImportDeclaration") { + const importId = defineImport(node); + if (!importId) { + continue; + } + for (const spec of node.specifiers) { + if (spec.type === "ImportSpecifier") { + if (spec.imported.type === "Identifier") { + idToImportMap.set(spec.local.name, `${importId}.${spec.imported.name}`); + } else { + idToImportMap.set(spec.local.name, `${importId}[${JSON.stringify(spec.imported.value)}]`); + } + } else if (spec.type === "ImportDefaultSpecifier") { + idToImportMap.set(spec.local.name, `${importId}.default`); + } else { + // namespace specifier + idToImportMap.set(spec.local.name, importId); + } + } + } + } + const declaredConst = new Set(); + const hoistedNodes = []; + function createSyntaxError(node, message) { + const _error = new SyntaxError(message); + Error.captureStackTrace(_error, createSyntaxError); + const serializedError = { + name: "SyntaxError", + message: _error.message, + stack: _error.stack + }; + if (options.codeFrameGenerator) { + serializedError.frame = options.codeFrameGenerator(node, id, code); + } + return serializedError; + } + function assertNotDefaultExport(node, error) { + var _findNodeAround; + const defaultExport = (_findNodeAround = findNodeAround(ast, node.start, "ExportDefaultDeclaration")) === null || _findNodeAround === void 0 ? void 0 : _findNodeAround.node; + if ((defaultExport === null || defaultExport === void 0 ? void 0 : defaultExport.declaration) === node || (defaultExport === null || defaultExport === void 0 ? void 0 : defaultExport.declaration.type) === "AwaitExpression" && defaultExport.declaration.argument === node) { + throw createSyntaxError(defaultExport, error); + } + } + function assertNotNamedExport(node, error) { + var _findNodeAround2; + const nodeExported = (_findNodeAround2 = findNodeAround(ast, node.start, "ExportNamedDeclaration")) === null || _findNodeAround2 === void 0 ? void 0 : _findNodeAround2.node; + if ((nodeExported === null || nodeExported === void 0 ? void 0 : nodeExported.declaration) === node) { + throw createSyntaxError(nodeExported, error); + } + } + function getVariableDeclaration(node) { + var _findNodeAround3, _declarationNode$decl; + const declarationNode = (_findNodeAround3 = findNodeAround(ast, node.start, "VariableDeclaration")) === null || _findNodeAround3 === void 0 ? void 0 : _findNodeAround3.node; + const init = declarationNode === null || declarationNode === void 0 || (_declarationNode$decl = declarationNode.declarations[0]) === null || _declarationNode$decl === void 0 ? void 0 : _declarationNode$decl.init; + if (init && (init === node || init.type === "AwaitExpression" && init.argument === node)) { + return declarationNode; + } + } + const usedUtilityExports = new Set(); + esmWalker(ast, { + onIdentifier(id, info, parentStack) { + const binding = idToImportMap.get(id.name); + if (!binding) { + return; + } + if (info.hasBindingShortcut) { + s.appendLeft(id.end, `: ${binding}`); + } else if (info.classDeclaration) { + if (!declaredConst.has(id.name)) { + declaredConst.add(id.name); + // locate the top-most node containing the class declaration + const topNode = parentStack[parentStack.length - 2]; + s.prependRight(topNode.start, `const ${id.name} = ${binding};\n`); + } + } else if (!info.classExpression) { + s.update(id.start, id.end, binding); + } + }, + onCallExpression(node) { + if (node.callee.type === "MemberExpression" && isIdentifier(node.callee.object) && utilsObjectNames.includes(node.callee.object.name) && isIdentifier(node.callee.property)) { + const methodName = node.callee.property.name; + usedUtilityExports.add(node.callee.object.name); + if (hoistableMockMethodNames.includes(methodName)) { + const method = `${node.callee.object.name}.${methodName}`; + assertNotDefaultExport(node, `Cannot export the result of "${method}". Remove export declaration because "${method}" doesn\'t return anything.`); + const declarationNode = getVariableDeclaration(node); + if (declarationNode) { + assertNotNamedExport(declarationNode, `Cannot export the result of "${method}". Remove export declaration because "${method}" doesn\'t return anything.`); + } + // rewrite vi.mock(import('..')) into vi.mock('..') + if (node.type === "CallExpression" && node.callee.type === "MemberExpression" && dynamicImportMockMethodNames.includes(node.callee.property.name)) { + const moduleInfo = node.arguments[0]; + // vi.mock(import('./path')) -> vi.mock('./path') + if (moduleInfo.type === "ImportExpression") { + const source = moduleInfo.source; + s.overwrite(moduleInfo.start, moduleInfo.end, s.slice(source.start, source.end)); + } + // vi.mock(await import('./path')) -> vi.mock('./path') + if (moduleInfo.type === "AwaitExpression" && moduleInfo.argument.type === "ImportExpression") { + const source = moduleInfo.argument.source; + s.overwrite(moduleInfo.start, moduleInfo.end, s.slice(source.start, source.end)); + } + } + hoistedNodes.push(node); + } else if (dynamicImportMockMethodNames.includes(methodName)) { + const moduleInfo = node.arguments[0]; + let source = null; + if (moduleInfo.type === "ImportExpression") { + source = moduleInfo.source; + } + if (moduleInfo.type === "AwaitExpression" && moduleInfo.argument.type === "ImportExpression") { + source = moduleInfo.argument.source; + } + if (source) { + s.overwrite(moduleInfo.start, moduleInfo.end, s.slice(source.start, source.end)); + } + } + if (hoistedMethodNames.includes(methodName)) { + assertNotDefaultExport(node, "Cannot export hoisted variable. You can control hoisting behavior by placing the import from this file first."); + const declarationNode = getVariableDeclaration(node); + if (declarationNode) { + assertNotNamedExport(declarationNode, "Cannot export hoisted variable. You can control hoisting behavior by placing the import from this file first."); + // hoist "const variable = vi.hoisted(() => {})" + hoistedNodes.push(declarationNode); + } else { + var _findNodeAround4; + const awaitedExpression = (_findNodeAround4 = findNodeAround(ast, node.start, "AwaitExpression")) === null || _findNodeAround4 === void 0 ? void 0 : _findNodeAround4.node; + // hoist "await vi.hoisted(async () => {})" or "vi.hoisted(() => {})" + const moveNode = (awaitedExpression === null || awaitedExpression === void 0 ? void 0 : awaitedExpression.argument) === node ? awaitedExpression : node; + hoistedNodes.push(moveNode); + } + } + } + } + }); + function getNodeName(node) { + const callee = node.callee || {}; + if (callee.type === "MemberExpression" && isIdentifier(callee.property) && isIdentifier(callee.object)) { + return `${callee.object.name}.${callee.property.name}()`; + } + return "\"hoisted method\""; + } + function getNodeCall(node) { + if (node.type === "CallExpression") { + return node; + } + if (node.type === "VariableDeclaration") { + const { declarations } = node; + const init = declarations[0].init; + if (init) { + return getNodeCall(init); + } + } + if (node.type === "AwaitExpression") { + const { argument } = node; + if (argument.type === "CallExpression") { + return getNodeCall(argument); + } + } + return node; + } + function createError(outsideNode, insideNode) { + const outsideCall = getNodeCall(outsideNode); + const insideCall = getNodeCall(insideNode); + throw createSyntaxError(insideCall, `Cannot call ${getNodeName(insideCall)} inside ${getNodeName(outsideCall)}: both methods are hoisted to the top of the file and not actually called inside each other.`); + } + // validate hoistedNodes doesn't have nodes inside other nodes + for (let i = 0; i < hoistedNodes.length; i++) { + const node = hoistedNodes[i]; + for (let j = i + 1; j < hoistedNodes.length; j++) { + const otherNode = hoistedNodes[j]; + if (node.start >= otherNode.start && node.end <= otherNode.end) { + throw createError(otherNode, node); + } + if (otherNode.start >= node.start && otherNode.end <= node.end) { + throw createError(node, otherNode); + } + } + } + // hoist vi.mock/vi.hoisted + for (const node of hoistedNodes) { + const end = getNodeTail(code, node); + // don't hoist into itself if it's already at the top + if (hoistIndex === end || hoistIndex === node.start) { + hoistIndex = end; + } else { + s.move(node.start, end, hoistIndex); + } + } + // hoist actual dynamic imports last so they are inserted after all hoisted mocks + for (const { node: importNode, id: importId } of imports) { + const source = importNode.source.value; + s.update(importNode.start, importNode.end, `const ${importId} = await import(${JSON.stringify(source)});\n`); + if (importNode.start === hoistIndex) { + // no need to hoist, but update hoistIndex to keep the order + hoistIndex = importNode.end; + } else { + // There will be an error if the module is called before it is imported, + // so the module import statement is hoisted to the top + s.move(importNode.start, importNode.end, hoistIndex); + } + } + if (!hoistedModuleImported && hoistedNodes.length) { + const utilityImports = [...usedUtilityExports]; + // "vi" or "vitest" is imported from a module other than "vitest" + if (utilityImports.some((name) => idToImportMap.has(name))) { + s.prepend(API_NOT_FOUND_CHECK(utilityImports)); + } else if (utilityImports.length) { + s.prepend(`import { ${[...usedUtilityExports].join(", ")} } from ${JSON.stringify(hoistedModule)}\n`); + } + } + return { + code: s.toString(), + map: s.generateMap({ + hires: "boundary", + source: id + }) + }; +} + +function interceptorPlugin(options = {}) { + const registry = options.registry || new MockerRegistry(); + return { + name: "vitest:mocks:interceptor", + enforce: "pre", + load: { + order: "pre", + async handler(id) { + const mock = registry.getById(id); + if (!mock) { + return; + } + if (mock.type === "manual") { + const exports = Object.keys(await mock.resolve()); + const accessor = options.globalThisAccessor || "\"__vitest_mocker__\""; + return createManualModuleSource(mock.url, exports, accessor); + } + if (mock.type === "redirect") { + return readFile(mock.redirect, "utf-8"); + } + } + }, + transform: { + order: "post", + handler(code, id) { + const mock = registry.getById(id); + if (!mock) { + return; + } + if (mock.type === "automock" || mock.type === "autospy") { + const m = automockModule(code, mock.type, this.parse, { globalThisAccessor: options.globalThisAccessor }); + return { + code: m.toString(), + map: m.generateMap({ + hires: "boundary", + source: cleanUrl(id) + }) + }; + } + } + }, + configureServer(server) { + server.ws.on("vitest:interceptor:register", (event) => { + if (event.type === "manual") { + const module = ManualMockedModule.fromJSON(event, async () => { + const keys = await getFactoryExports(event.url); + return Object.fromEntries(keys.map((key) => [key, null])); + }); + registry.add(module); + } else { + if (event.type === "redirect") { + const redirectUrl = new URL(event.redirect); + event.redirect = join(server.config.root, redirectUrl.pathname); + } + registry.register(event); + } + server.ws.send("vitest:interceptor:register:result"); + }); + server.ws.on("vitest:interceptor:delete", (id) => { + registry.delete(id); + server.ws.send("vitest:interceptor:delete:result"); + }); + server.ws.on("vitest:interceptor:invalidate", () => { + registry.clear(); + server.ws.send("vitest:interceptor:invalidate:result"); + }); + function getFactoryExports(url) { + server.ws.send("vitest:interceptor:resolve", url); + let timeout; + return new Promise((resolve, reject) => { + timeout = setTimeout(() => { + reject(new Error(`Timeout while waiting for factory exports of ${url}`)); + }, 1e4); + server.ws.on("vitest:interceptor:resolved", ({ url: resolvedUrl, keys }) => { + if (resolvedUrl === url) { + clearTimeout(timeout); + resolve(keys); + } + }); + }); + } + } + }; +} + +const VALID_ID_PREFIX = "/@id/"; +class ServerMockResolver { + constructor(server, options = {}) { + this.server = server; + this.options = options; + } + async resolveMock(rawId, importer, options) { + const { id, fsPath, external } = await this.resolveMockId(rawId, importer); + const resolvedUrl = this.normalizeResolveIdToUrl({ id }).url; + if (options.mock === "factory") { + var _manifest$fsPath; + const manifest = getViteDepsManifest(this.server.config); + const needsInterop = (manifest === null || manifest === void 0 || (_manifest$fsPath = manifest[fsPath]) === null || _manifest$fsPath === void 0 ? void 0 : _manifest$fsPath.needsInterop) ?? false; + return { + mockType: "manual", + resolvedId: id, + resolvedUrl, + needsInterop + }; + } + if (options.mock === "spy") { + return { + mockType: "autospy", + resolvedId: id, + resolvedUrl + }; + } + const redirectUrl = findMockRedirect(this.server.config.root, fsPath, external); + return { + mockType: redirectUrl === null ? "automock" : "redirect", + redirectUrl, + resolvedId: id, + resolvedUrl + }; + } + invalidate(ids) { + ids.forEach((id) => { + const moduleGraph = this.server.moduleGraph; + const module = moduleGraph.getModuleById(id); + if (module) { + module.transformResult = null; + } + }); + } + async resolveId(id, importer) { + const resolved = await this.server.pluginContainer.resolveId(id, importer, { ssr: false }); + if (!resolved) { + return null; + } + return this.normalizeResolveIdToUrl(resolved); + } + normalizeResolveIdToUrl(resolved) { + const isOptimized = resolved.id.startsWith(withTrailingSlash(this.server.config.cacheDir)); + let url; + // normalise the URL to be acceptable by the browser + // https://github.com/vitejs/vite/blob/14027b0f2a9b01c14815c38aab22baf5b29594bb/packages/vite/src/node/plugins/importAnalysis.ts#L103 + const root = this.server.config.root; + if (resolved.id.startsWith(withTrailingSlash(root))) { + url = resolved.id.slice(root.length); + } else if (resolved.id !== "/@react-refresh" && isAbsolute(resolved.id) && existsSync(cleanUrl(resolved.id))) { + url = join$1("/@fs/", resolved.id); + } else { + url = resolved.id; + } + if (url[0] !== "." && url[0] !== "/") { + url = resolved.id.startsWith(VALID_ID_PREFIX) ? resolved.id : VALID_ID_PREFIX + resolved.id.replace("\0", "__x00__"); + } + return { + id: resolved.id, + url, + optimized: isOptimized + }; + } + async resolveMockId(rawId, importer) { + if (!this.server.moduleGraph.getModuleById(importer) && !importer.startsWith(this.server.config.root)) { + importer = join$1(this.server.config.root, importer); + } + const resolved = await this.server.pluginContainer.resolveId(rawId, importer, { ssr: false }); + return this.resolveModule(rawId, resolved); + } + resolveModule(rawId, resolved) { + const id = (resolved === null || resolved === void 0 ? void 0 : resolved.id) || rawId; + const external = !isAbsolute(id) || isModuleDirectory(this.options, id) ? rawId : null; + return { + id, + fsPath: cleanUrl(id), + external + }; + } +} +function isModuleDirectory(config, path) { + const moduleDirectories = config.moduleDirectories || ["/node_modules/"]; + return moduleDirectories.some((dir) => path.includes(dir)); +} +const metadata = new WeakMap(); +function getViteDepsManifest(config) { + if (metadata.has(config)) { + return metadata.get(config); + } + const cacheDirPath = getDepsCacheDir(config); + const metadataPath = resolve(cacheDirPath, "_metadata.json"); + if (!existsSync(metadataPath)) { + return null; + } + const { optimized } = JSON.parse(readFileSync(metadataPath, "utf-8")); + const newManifest = {}; + for (const name in optimized) { + const dep = optimized[name]; + const file = resolve(cacheDirPath, dep.file); + newManifest[file] = { + hash: dep.fileHash, + needsInterop: dep.needsInterop + }; + } + metadata.set(config, newManifest); + return newManifest; +} +function getDepsCacheDir(config) { + return resolve(config.cacheDir, "deps"); +} +function withTrailingSlash(path) { + if (path[path.length - 1] !== "/") { + return `${path}/`; + } + return path; +} + +// this is an implementation for public usage +// vitest doesn't use this plugin directly +function mockerPlugin(options = {}) { + let server; + const registerPath = resolve(fileURLToPath(new URL("./register.js", import.meta.url))); + return [ + { + name: "vitest:mocker:ws-rpc", + config(_, { command }) { + if (command !== "serve") { + return; + } + return { + server: { preTransformRequests: false }, + optimizeDeps: { exclude: ["@vitest/mocker/register", "@vitest/mocker/browser"] } + }; + }, + configureServer(server_) { + server = server_; + const mockResolver = new ServerMockResolver(server); + server.ws.on("vitest:mocks:resolveId", async ({ id, importer }) => { + const resolved = await mockResolver.resolveId(id, importer); + server.ws.send("vitest:mocks:resolvedId:result", resolved); + }); + server.ws.on("vitest:mocks:resolveMock", async ({ id, importer, options }) => { + const resolved = await mockResolver.resolveMock(id, importer, options); + server.ws.send("vitest:mocks:resolveMock:result", resolved); + }); + server.ws.on("vitest:mocks:invalidate", async ({ ids }) => { + mockResolver.invalidate(ids); + server.ws.send("vitest:mocks:invalidate:result"); + }); + }, + async load(id) { + if (id !== registerPath) { + return; + } + if (!server) { + // mocker doesn't work during build + return "export {}"; + } + const content = await readFile(registerPath, "utf-8"); + const result = content.replace(/__VITEST_GLOBAL_THIS_ACCESSOR__/g, options.globalThisAccessor ?? "\"__vitest_mocker__\"").replace("__VITEST_MOCKER_ROOT__", JSON.stringify(server.config.root)); + return result; + } + }, + hoistMocksPlugin(options.hoistMocks), + interceptorPlugin(options), + automockPlugin(options), + dynamicImportPlugin(options) + ]; +} + +export { ServerMockResolver, automockModule, automockPlugin, createManualModuleSource, dynamicImportPlugin, findMockRedirect, hoistMocks, hoistMocksPlugin, interceptorPlugin, mockerPlugin }; diff --git a/node_modules/@vitest/mocker/dist/redirect.d.ts b/node_modules/@vitest/mocker/dist/redirect.d.ts new file mode 100644 index 0000000000..1f8256badd --- /dev/null +++ b/node_modules/@vitest/mocker/dist/redirect.d.ts @@ -0,0 +1,3 @@ +declare function findMockRedirect(root: string, mockPath: string, external: string | null): string | null; + +export { findMockRedirect }; diff --git a/node_modules/@vitest/mocker/dist/redirect.js b/node_modules/@vitest/mocker/dist/redirect.js new file mode 100644 index 0000000000..2281e6c3f0 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/redirect.js @@ -0,0 +1,75 @@ +import fs from 'node:fs'; +import { builtinModules } from 'node:module'; +import { d as dirname, j as join, b as basename, r as resolve, e as extname } from './chunk-pathe.M-eThtNZ.js'; + +const { existsSync, readdirSync, statSync } = fs; +function findMockRedirect(root, mockPath, external) { + const path = external || mockPath; + // it's a node_module alias + // all mocks should be inside /__mocks__ + if (external || isNodeBuiltin(mockPath) || !existsSync(mockPath)) { + const mockDirname = dirname(path); + const mockFolder = join(root, "__mocks__", mockDirname); + if (!existsSync(mockFolder)) { + return null; + } + const baseOriginal = basename(path); + function findFile(mockFolder, baseOriginal) { + const files = readdirSync(mockFolder); + for (const file of files) { + const baseFile = basename(file, extname(file)); + if (baseFile === baseOriginal) { + const path = resolve(mockFolder, file); + // if the same name, return the file + if (statSync(path).isFile()) { + return path; + } else { + // find folder/index.{js,ts} + const indexFile = findFile(path, "index"); + if (indexFile) { + return indexFile; + } + } + } + } + return null; + } + return findFile(mockFolder, baseOriginal); + } + const dir = dirname(path); + const baseId = basename(path); + const fullPath = resolve(dir, "__mocks__", baseId); + return existsSync(fullPath) ? fullPath : null; +} +const builtins = new Set([ + ...builtinModules, + "assert/strict", + "diagnostics_channel", + "dns/promises", + "fs/promises", + "path/posix", + "path/win32", + "readline/promises", + "stream/consumers", + "stream/promises", + "stream/web", + "timers/promises", + "util/types", + "wasi" +]); +// https://nodejs.org/api/modules.html#built-in-modules-with-mandatory-node-prefix +const prefixedBuiltins = new Set([ + "node:sea", + "node:sqlite", + "node:test", + "node:test/reporters" +]); +const NODE_BUILTIN_NAMESPACE = "node:"; +function isNodeBuiltin(id) { + if (prefixedBuiltins.has(id)) { + return true; + } + return builtins.has(id.startsWith(NODE_BUILTIN_NAMESPACE) ? id.slice(NODE_BUILTIN_NAMESPACE.length) : id); +} + +export { findMockRedirect }; diff --git a/node_modules/@vitest/mocker/dist/register.d.ts b/node_modules/@vitest/mocker/dist/register.d.ts new file mode 100644 index 0000000000..e644d7fac7 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/register.d.ts @@ -0,0 +1,9 @@ +import { M as ModuleMockerInterceptor, a as ModuleMockerCompilerHints, b as ModuleMocker } from './mocker.d-Ce9_ySj5.js'; +import '@vitest/spy'; +import './types.d-D_aRZRdy.js'; +import './registry.d-D765pazg.js'; + +declare function registerModuleMocker(interceptor: (accessor: string) => ModuleMockerInterceptor): ModuleMockerCompilerHints; +declare function registerNativeFactoryResolver(mocker: ModuleMocker): void; + +export { registerModuleMocker, registerNativeFactoryResolver }; diff --git a/node_modules/@vitest/mocker/dist/register.js b/node_modules/@vitest/mocker/dist/register.js new file mode 100644 index 0000000000..a45bf84d46 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/register.js @@ -0,0 +1,41 @@ +import { spyOn } from '@vitest/spy'; +import { M as ModuleMocker, r as rpc, c as createCompilerHints, h as hot } from './chunk-mocker.js'; +import './index.js'; +import './chunk-registry.js'; +import './chunk-pathe.M-eThtNZ.js'; + +function registerModuleMocker(interceptor) { + const mocker = new ModuleMocker(interceptor(__VITEST_GLOBAL_THIS_ACCESSOR__), { + resolveId(id, importer) { + return rpc("vitest:mocks:resolveId", { + id, + importer + }); + }, + resolveMock(id, importer, options) { + return rpc("vitest:mocks:resolveMock", { + id, + importer, + options + }); + }, + async invalidate(ids) { + return rpc("vitest:mocks:invalidate", { ids }); + } + }, spyOn, { root: __VITEST_MOCKER_ROOT__ }); + globalThis[__VITEST_GLOBAL_THIS_ACCESSOR__] = mocker; + registerNativeFactoryResolver(mocker); + return createCompilerHints({ globalThisKey: __VITEST_GLOBAL_THIS_ACCESSOR__ }); +} +function registerNativeFactoryResolver(mocker) { + hot.on("vitest:interceptor:resolve", async (url) => { + const exports = await mocker.resolveFactoryModule(url); + const keys = Object.keys(exports); + hot.send("vitest:interceptor:resolved", { + url, + keys + }); + }); +} + +export { registerModuleMocker, registerNativeFactoryResolver }; diff --git a/node_modules/@vitest/mocker/dist/registry.d-D765pazg.d.ts b/node_modules/@vitest/mocker/dist/registry.d-D765pazg.d.ts new file mode 100644 index 0000000000..b0346d08dd --- /dev/null +++ b/node_modules/@vitest/mocker/dist/registry.d-D765pazg.d.ts @@ -0,0 +1,87 @@ +declare class MockerRegistry { + private readonly registryByUrl; + private readonly registryById; + clear(): void; + keys(): IterableIterator; + add(mock: MockedModule): void; + register(json: MockedModuleSerialized): MockedModule; + register(type: "redirect", raw: string, id: string, url: string, redirect: string): RedirectedModule; + register(type: "manual", raw: string, id: string, url: string, factory: () => any): ManualMockedModule; + register(type: "automock", raw: string, id: string, url: string): AutomockedModule; + register(type: "autospy", id: string, raw: string, url: string): AutospiedModule; + delete(id: string): void; + get(id: string): MockedModule | undefined; + getById(id: string): MockedModule | undefined; + has(id: string): boolean; +} +type MockedModule = AutomockedModule | AutospiedModule | ManualMockedModule | RedirectedModule; +type MockedModuleType = "automock" | "autospy" | "manual" | "redirect"; +type MockedModuleSerialized = AutomockedModuleSerialized | AutospiedModuleSerialized | ManualMockedModuleSerialized | RedirectedModuleSerialized; +declare class AutomockedModule { + raw: string; + id: string; + url: string; + readonly type = "automock"; + constructor(raw: string, id: string, url: string); + static fromJSON(data: AutomockedModuleSerialized): AutospiedModule; + toJSON(): AutomockedModuleSerialized; +} +interface AutomockedModuleSerialized { + type: "automock"; + url: string; + raw: string; + id: string; +} +declare class AutospiedModule { + raw: string; + id: string; + url: string; + readonly type = "autospy"; + constructor(raw: string, id: string, url: string); + static fromJSON(data: AutospiedModuleSerialized): AutospiedModule; + toJSON(): AutospiedModuleSerialized; +} +interface AutospiedModuleSerialized { + type: "autospy"; + url: string; + raw: string; + id: string; +} +declare class RedirectedModule { + raw: string; + id: string; + url: string; + redirect: string; + readonly type = "redirect"; + constructor(raw: string, id: string, url: string, redirect: string); + static fromJSON(data: RedirectedModuleSerialized): RedirectedModule; + toJSON(): RedirectedModuleSerialized; +} +interface RedirectedModuleSerialized { + type: "redirect"; + url: string; + id: string; + raw: string; + redirect: string; +} +declare class ManualMockedModule { + raw: string; + id: string; + url: string; + factory: () => any; + cache: Record | undefined; + readonly type = "manual"; + constructor(raw: string, id: string, url: string, factory: () => any); + resolve(): Promise>; + static fromJSON(data: ManualMockedModuleSerialized, factory: () => any): ManualMockedModule; + toJSON(): ManualMockedModuleSerialized; +} +interface ManualMockedModuleSerialized { + type: "manual"; + url: string; + id: string; + raw: string; +} + +export { AutomockedModule as A, RedirectedModule as R, AutospiedModule as a, ManualMockedModule as b, MockerRegistry as c }; +export type { MockedModuleType as M, AutomockedModuleSerialized as d, AutospiedModuleSerialized as e, ManualMockedModuleSerialized as f, MockedModule as g, MockedModuleSerialized as h, RedirectedModuleSerialized as i }; diff --git a/node_modules/@vitest/mocker/dist/types.d-D_aRZRdy.d.ts b/node_modules/@vitest/mocker/dist/types.d-D_aRZRdy.d.ts new file mode 100644 index 0000000000..80ba117b35 --- /dev/null +++ b/node_modules/@vitest/mocker/dist/types.d-D_aRZRdy.d.ts @@ -0,0 +1,8 @@ +type Awaitable = T | PromiseLike; +type ModuleMockFactoryWithHelper = (importOriginal: () => Promise) => Awaitable>; +type ModuleMockFactory = () => any; +interface ModuleMockOptions { + spy?: boolean; +} + +export type { ModuleMockFactory as M, ModuleMockFactoryWithHelper as a, ModuleMockOptions as b }; diff --git a/node_modules/@vitest/mocker/package.json b/node_modules/@vitest/mocker/package.json new file mode 100644 index 0000000000..cb8c0b9834 --- /dev/null +++ b/node_modules/@vitest/mocker/package.json @@ -0,0 +1,82 @@ +{ + "name": "@vitest/mocker", + "type": "module", + "version": "3.2.4", + "description": "Vitest module mocker implementation", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/mocker#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/mocker" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./node": { + "types": "./dist/node.d.ts", + "default": "./dist/node.js" + }, + "./browser": { + "types": "./dist/browser.d.ts", + "default": "./dist/browser.js" + }, + "./redirect": { + "types": "./dist/redirect.d.ts", + "default": "./dist/redirect.js" + }, + "./register": { + "types": "./dist/register.d.ts", + "default": "./dist/register.js" + }, + "./auto-register": { + "types": "./dist/register.d.ts", + "default": "./dist/register.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "*.d.ts", + "dist" + ], + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + }, + "dependencies": { + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17", + "@vitest/spy": "3.2.4" + }, + "devDependencies": { + "@types/estree": "^1.0.8", + "acorn-walk": "^8.3.4", + "msw": "^2.10.2", + "pathe": "^2.0.3", + "vite": "^5.4.0", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/pretty-format/LICENSE b/node_modules/@vitest/pretty-format/LICENSE new file mode 100644 index 0000000000..5ae481fdb8 --- /dev/null +++ b/node_modules/@vitest/pretty-format/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/pretty-format/dist/index.d.ts b/node_modules/@vitest/pretty-format/dist/index.d.ts new file mode 100644 index 0000000000..206e69c97b --- /dev/null +++ b/node_modules/@vitest/pretty-format/dist/index.d.ts @@ -0,0 +1,119 @@ +/** +* Copyright (c) Meta Platforms, Inc. and affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ +interface Colors { + comment: { + close: string + open: string + }; + content: { + close: string + open: string + }; + prop: { + close: string + open: string + }; + tag: { + close: string + open: string + }; + value: { + close: string + open: string + }; +} +type Indent = (arg0: string) => string; +type Refs = Array; +type Print = (arg0: unknown) => string; +type Theme = Required<{ + comment?: string + content?: string + prop?: string + tag?: string + value?: string +}>; +type CompareKeys = ((a: string, b: string) => number) | null | undefined; +type RequiredOptions = Required; +interface Options extends Omit { + compareKeys: CompareKeys; + theme: Theme; +} +interface PrettyFormatOptions { + callToJSON?: boolean; + escapeRegex?: boolean; + escapeString?: boolean; + highlight?: boolean; + indent?: number; + maxDepth?: number; + maxWidth?: number; + min?: boolean; + printBasicPrototype?: boolean; + printFunctionName?: boolean; + compareKeys?: CompareKeys; + plugins?: Plugins; +} +type OptionsReceived = PrettyFormatOptions; +interface Config { + callToJSON: boolean; + compareKeys: CompareKeys; + colors: Colors; + escapeRegex: boolean; + escapeString: boolean; + indent: string; + maxDepth: number; + maxWidth: number; + min: boolean; + plugins: Plugins; + printBasicPrototype: boolean; + printFunctionName: boolean; + spacingInner: string; + spacingOuter: string; +} +type Printer = (val: unknown, config: Config, indentation: string, depth: number, refs: Refs, hasCalledToJSON?: boolean) => string; +type Test = (arg0: any) => boolean; +interface NewPlugin { + serialize: (val: any, config: Config, indentation: string, depth: number, refs: Refs, printer: Printer) => string; + test: Test; +} +interface PluginOptions { + edgeSpacing: string; + min: boolean; + spacing: string; +} +interface OldPlugin { + print: (val: unknown, print: Print, indent: Indent, options: PluginOptions, colors: Colors) => string; + test: Test; +} +type Plugin = NewPlugin | OldPlugin; +type Plugins = Array; + +/** +* Copyright (c) Meta Platforms, Inc. and affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + +declare const DEFAULT_OPTIONS: Options; +/** +* Returns a presentation string of your `val` object +* @param val any potential JavaScript object +* @param options Custom settings +*/ +declare function format(val: unknown, options?: OptionsReceived): string; +declare const plugins: { + AsymmetricMatcher: NewPlugin + DOMCollection: NewPlugin + DOMElement: NewPlugin + Immutable: NewPlugin + ReactElement: NewPlugin + ReactTestComponent: NewPlugin + Error: NewPlugin +}; + +export { DEFAULT_OPTIONS, format, plugins }; +export type { Colors, CompareKeys, Config, NewPlugin, OldPlugin, Options, OptionsReceived, Plugin, Plugins, PrettyFormatOptions, Printer, Refs, Theme }; diff --git a/node_modules/@vitest/pretty-format/dist/index.js b/node_modules/@vitest/pretty-format/dist/index.js new file mode 100644 index 0000000000..35f8c01ff0 --- /dev/null +++ b/node_modules/@vitest/pretty-format/dist/index.js @@ -0,0 +1,1387 @@ +import styles from 'tinyrainbow'; + +function _mergeNamespaces(n, m) { + m.forEach(function (e) { + e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) { + if (k !== 'default' && !(k in n)) { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: function () { return e[k]; } + }); + } + }); + }); + return Object.freeze(n); +} + +function getKeysOfEnumerableProperties(object, compareKeys) { + const rawKeys = Object.keys(object); + const keys = compareKeys === null ? rawKeys : rawKeys.sort(compareKeys); + if (Object.getOwnPropertySymbols) { + for (const symbol of Object.getOwnPropertySymbols(object)) { + if (Object.getOwnPropertyDescriptor(object, symbol).enumerable) { + keys.push(symbol); + } + } + } + return keys; +} +/** +* Return entries (for example, of a map) +* with spacing, indentation, and comma +* without surrounding punctuation (for example, braces) +*/ +function printIteratorEntries(iterator, config, indentation, depth, refs, printer, separator = ": ") { + let result = ""; + let width = 0; + let current = iterator.next(); + if (!current.done) { + result += config.spacingOuter; + const indentationNext = indentation + config.indent; + while (!current.done) { + result += indentationNext; + if (width++ === config.maxWidth) { + result += "…"; + break; + } + const name = printer(current.value[0], config, indentationNext, depth, refs); + const value = printer(current.value[1], config, indentationNext, depth, refs); + result += name + separator + value; + current = iterator.next(); + if (!current.done) { + result += `,${config.spacingInner}`; + } else if (!config.min) { + result += ","; + } + } + result += config.spacingOuter + indentation; + } + return result; +} +/** +* Return values (for example, of a set) +* with spacing, indentation, and comma +* without surrounding punctuation (braces or brackets) +*/ +function printIteratorValues(iterator, config, indentation, depth, refs, printer) { + let result = ""; + let width = 0; + let current = iterator.next(); + if (!current.done) { + result += config.spacingOuter; + const indentationNext = indentation + config.indent; + while (!current.done) { + result += indentationNext; + if (width++ === config.maxWidth) { + result += "…"; + break; + } + result += printer(current.value, config, indentationNext, depth, refs); + current = iterator.next(); + if (!current.done) { + result += `,${config.spacingInner}`; + } else if (!config.min) { + result += ","; + } + } + result += config.spacingOuter + indentation; + } + return result; +} +/** +* Return items (for example, of an array) +* with spacing, indentation, and comma +* without surrounding punctuation (for example, brackets) +*/ +function printListItems(list, config, indentation, depth, refs, printer) { + let result = ""; + list = list instanceof ArrayBuffer ? new DataView(list) : list; + const isDataView = (l) => l instanceof DataView; + const length = isDataView(list) ? list.byteLength : list.length; + if (length > 0) { + result += config.spacingOuter; + const indentationNext = indentation + config.indent; + for (let i = 0; i < length; i++) { + result += indentationNext; + if (i === config.maxWidth) { + result += "…"; + break; + } + if (isDataView(list) || i in list) { + result += printer(isDataView(list) ? list.getInt8(i) : list[i], config, indentationNext, depth, refs); + } + if (i < length - 1) { + result += `,${config.spacingInner}`; + } else if (!config.min) { + result += ","; + } + } + result += config.spacingOuter + indentation; + } + return result; +} +/** +* Return properties of an object +* with spacing, indentation, and comma +* without surrounding punctuation (for example, braces) +*/ +function printObjectProperties(val, config, indentation, depth, refs, printer) { + let result = ""; + const keys = getKeysOfEnumerableProperties(val, config.compareKeys); + if (keys.length > 0) { + result += config.spacingOuter; + const indentationNext = indentation + config.indent; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const name = printer(key, config, indentationNext, depth, refs); + const value = printer(val[key], config, indentationNext, depth, refs); + result += `${indentationNext + name}: ${value}`; + if (i < keys.length - 1) { + result += `,${config.spacingInner}`; + } else if (!config.min) { + result += ","; + } + } + result += config.spacingOuter + indentation; + } + return result; +} + +const asymmetricMatcher = typeof Symbol === "function" && Symbol.for ? Symbol.for("jest.asymmetricMatcher") : 1267621; +const SPACE$2 = " "; +const serialize$5 = (val, config, indentation, depth, refs, printer) => { + const stringedValue = val.toString(); + if (stringedValue === "ArrayContaining" || stringedValue === "ArrayNotContaining") { + if (++depth > config.maxDepth) { + return `[${stringedValue}]`; + } + return `${stringedValue + SPACE$2}[${printListItems(val.sample, config, indentation, depth, refs, printer)}]`; + } + if (stringedValue === "ObjectContaining" || stringedValue === "ObjectNotContaining") { + if (++depth > config.maxDepth) { + return `[${stringedValue}]`; + } + return `${stringedValue + SPACE$2}{${printObjectProperties(val.sample, config, indentation, depth, refs, printer)}}`; + } + if (stringedValue === "StringMatching" || stringedValue === "StringNotMatching") { + return stringedValue + SPACE$2 + printer(val.sample, config, indentation, depth, refs); + } + if (stringedValue === "StringContaining" || stringedValue === "StringNotContaining") { + return stringedValue + SPACE$2 + printer(val.sample, config, indentation, depth, refs); + } + if (typeof val.toAsymmetricMatcher !== "function") { + throw new TypeError(`Asymmetric matcher ${val.constructor.name} does not implement toAsymmetricMatcher()`); + } + return val.toAsymmetricMatcher(); +}; +const test$5 = (val) => val && val.$$typeof === asymmetricMatcher; +const plugin$5 = { + serialize: serialize$5, + test: test$5 +}; + +const SPACE$1 = " "; +const OBJECT_NAMES = new Set(["DOMStringMap", "NamedNodeMap"]); +const ARRAY_REGEXP = /^(?:HTML\w*Collection|NodeList)$/; +function testName(name) { + return OBJECT_NAMES.has(name) || ARRAY_REGEXP.test(name); +} +const test$4 = (val) => val && val.constructor && !!val.constructor.name && testName(val.constructor.name); +function isNamedNodeMap(collection) { + return collection.constructor.name === "NamedNodeMap"; +} +const serialize$4 = (collection, config, indentation, depth, refs, printer) => { + const name = collection.constructor.name; + if (++depth > config.maxDepth) { + return `[${name}]`; + } + return (config.min ? "" : name + SPACE$1) + (OBJECT_NAMES.has(name) ? `{${printObjectProperties(isNamedNodeMap(collection) ? [...collection].reduce((props, attribute) => { + props[attribute.name] = attribute.value; + return props; + }, {}) : { ...collection }, config, indentation, depth, refs, printer)}}` : `[${printListItems([...collection], config, indentation, depth, refs, printer)}]`); +}; +const plugin$4 = { + serialize: serialize$4, + test: test$4 +}; + +/** +* Copyright (c) Meta Platforms, Inc. and affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ +function escapeHTML(str) { + return str.replaceAll("<", "<").replaceAll(">", ">"); +} + +// Return empty string if keys is empty. +function printProps(keys, props, config, indentation, depth, refs, printer) { + const indentationNext = indentation + config.indent; + const colors = config.colors; + return keys.map((key) => { + const value = props[key]; + let printed = printer(value, config, indentationNext, depth, refs); + if (typeof value !== "string") { + if (printed.includes("\n")) { + printed = config.spacingOuter + indentationNext + printed + config.spacingOuter + indentation; + } + printed = `{${printed}}`; + } + return `${config.spacingInner + indentation + colors.prop.open + key + colors.prop.close}=${colors.value.open}${printed}${colors.value.close}`; + }).join(""); +} +// Return empty string if children is empty. +function printChildren(children, config, indentation, depth, refs, printer) { + return children.map((child) => config.spacingOuter + indentation + (typeof child === "string" ? printText(child, config) : printer(child, config, indentation, depth, refs))).join(""); +} +function printText(text, config) { + const contentColor = config.colors.content; + return contentColor.open + escapeHTML(text) + contentColor.close; +} +function printComment(comment, config) { + const commentColor = config.colors.comment; + return `${commentColor.open}${commentColor.close}`; +} +// Separate the functions to format props, children, and element, +// so a plugin could override a particular function, if needed. +// Too bad, so sad: the traditional (but unnecessary) space +// in a self-closing tagColor requires a second test of printedProps. +function printElement(type, printedProps, printedChildren, config, indentation) { + const tagColor = config.colors.tag; + return `${tagColor.open}<${type}${printedProps && tagColor.close + printedProps + config.spacingOuter + indentation + tagColor.open}${printedChildren ? `>${tagColor.close}${printedChildren}${config.spacingOuter}${indentation}${tagColor.open}${tagColor.close}`; +} +function printElementAsLeaf(type, config) { + const tagColor = config.colors.tag; + return `${tagColor.open}<${type}${tagColor.close} …${tagColor.open} />${tagColor.close}`; +} + +const ELEMENT_NODE = 1; +const TEXT_NODE = 3; +const COMMENT_NODE = 8; +const FRAGMENT_NODE = 11; +const ELEMENT_REGEXP = /^(?:(?:HTML|SVG)\w*)?Element$/; +function testHasAttribute(val) { + try { + return typeof val.hasAttribute === "function" && val.hasAttribute("is"); + } catch { + return false; + } +} +function testNode(val) { + const constructorName = val.constructor.name; + const { nodeType, tagName } = val; + const isCustomElement = typeof tagName === "string" && tagName.includes("-") || testHasAttribute(val); + return nodeType === ELEMENT_NODE && (ELEMENT_REGEXP.test(constructorName) || isCustomElement) || nodeType === TEXT_NODE && constructorName === "Text" || nodeType === COMMENT_NODE && constructorName === "Comment" || nodeType === FRAGMENT_NODE && constructorName === "DocumentFragment"; +} +const test$3 = (val) => { + var _val$constructor; + return (val === null || val === void 0 || (_val$constructor = val.constructor) === null || _val$constructor === void 0 ? void 0 : _val$constructor.name) && testNode(val); +}; +function nodeIsText(node) { + return node.nodeType === TEXT_NODE; +} +function nodeIsComment(node) { + return node.nodeType === COMMENT_NODE; +} +function nodeIsFragment(node) { + return node.nodeType === FRAGMENT_NODE; +} +const serialize$3 = (node, config, indentation, depth, refs, printer) => { + if (nodeIsText(node)) { + return printText(node.data, config); + } + if (nodeIsComment(node)) { + return printComment(node.data, config); + } + const type = nodeIsFragment(node) ? "DocumentFragment" : node.tagName.toLowerCase(); + if (++depth > config.maxDepth) { + return printElementAsLeaf(type, config); + } + return printElement(type, printProps(nodeIsFragment(node) ? [] : Array.from(node.attributes, (attr) => attr.name).sort(), nodeIsFragment(node) ? {} : [...node.attributes].reduce((props, attribute) => { + props[attribute.name] = attribute.value; + return props; + }, {}), config, indentation + config.indent, depth, refs, printer), printChildren(Array.prototype.slice.call(node.childNodes || node.children), config, indentation + config.indent, depth, refs, printer), config, indentation); +}; +const plugin$3 = { + serialize: serialize$3, + test: test$3 +}; + +// SENTINEL constants are from https://github.com/facebook/immutable-js +const IS_ITERABLE_SENTINEL = "@@__IMMUTABLE_ITERABLE__@@"; +const IS_LIST_SENTINEL = "@@__IMMUTABLE_LIST__@@"; +const IS_KEYED_SENTINEL = "@@__IMMUTABLE_KEYED__@@"; +const IS_MAP_SENTINEL = "@@__IMMUTABLE_MAP__@@"; +const IS_ORDERED_SENTINEL = "@@__IMMUTABLE_ORDERED__@@"; +const IS_RECORD_SENTINEL = "@@__IMMUTABLE_RECORD__@@"; +const IS_SEQ_SENTINEL = "@@__IMMUTABLE_SEQ__@@"; +const IS_SET_SENTINEL = "@@__IMMUTABLE_SET__@@"; +const IS_STACK_SENTINEL = "@@__IMMUTABLE_STACK__@@"; +const getImmutableName = (name) => `Immutable.${name}`; +const printAsLeaf = (name) => `[${name}]`; +const SPACE = " "; +const LAZY = "…"; +function printImmutableEntries(val, config, indentation, depth, refs, printer, type) { + return ++depth > config.maxDepth ? printAsLeaf(getImmutableName(type)) : `${getImmutableName(type) + SPACE}{${printIteratorEntries(val.entries(), config, indentation, depth, refs, printer)}}`; +} +// Record has an entries method because it is a collection in immutable v3. +// Return an iterator for Immutable Record from version v3 or v4. +function getRecordEntries(val) { + let i = 0; + return { next() { + if (i < val._keys.length) { + const key = val._keys[i++]; + return { + done: false, + value: [key, val.get(key)] + }; + } + return { + done: true, + value: undefined + }; + } }; +} +function printImmutableRecord(val, config, indentation, depth, refs, printer) { + // _name property is defined only for an Immutable Record instance + // which was constructed with a second optional descriptive name arg + const name = getImmutableName(val._name || "Record"); + return ++depth > config.maxDepth ? printAsLeaf(name) : `${name + SPACE}{${printIteratorEntries(getRecordEntries(val), config, indentation, depth, refs, printer)}}`; +} +function printImmutableSeq(val, config, indentation, depth, refs, printer) { + const name = getImmutableName("Seq"); + if (++depth > config.maxDepth) { + return printAsLeaf(name); + } + if (val[IS_KEYED_SENTINEL]) { + return `${name + SPACE}{${val._iter || val._object ? printIteratorEntries(val.entries(), config, indentation, depth, refs, printer) : LAZY}}`; + } + return `${name + SPACE}[${val._iter || val._array || val._collection || val._iterable ? printIteratorValues(val.values(), config, indentation, depth, refs, printer) : LAZY}]`; +} +function printImmutableValues(val, config, indentation, depth, refs, printer, type) { + return ++depth > config.maxDepth ? printAsLeaf(getImmutableName(type)) : `${getImmutableName(type) + SPACE}[${printIteratorValues(val.values(), config, indentation, depth, refs, printer)}]`; +} +const serialize$2 = (val, config, indentation, depth, refs, printer) => { + if (val[IS_MAP_SENTINEL]) { + return printImmutableEntries(val, config, indentation, depth, refs, printer, val[IS_ORDERED_SENTINEL] ? "OrderedMap" : "Map"); + } + if (val[IS_LIST_SENTINEL]) { + return printImmutableValues(val, config, indentation, depth, refs, printer, "List"); + } + if (val[IS_SET_SENTINEL]) { + return printImmutableValues(val, config, indentation, depth, refs, printer, val[IS_ORDERED_SENTINEL] ? "OrderedSet" : "Set"); + } + if (val[IS_STACK_SENTINEL]) { + return printImmutableValues(val, config, indentation, depth, refs, printer, "Stack"); + } + if (val[IS_SEQ_SENTINEL]) { + return printImmutableSeq(val, config, indentation, depth, refs, printer); + } + // For compatibility with immutable v3 and v4, let record be the default. + return printImmutableRecord(val, config, indentation, depth, refs, printer); +}; +// Explicitly comparing sentinel properties to true avoids false positive +// when mock identity-obj-proxy returns the key as the value for any key. +const test$2 = (val) => val && (val[IS_ITERABLE_SENTINEL] === true || val[IS_RECORD_SENTINEL] === true); +const plugin$2 = { + serialize: serialize$2, + test: test$2 +}; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +var reactIs$1 = {exports: {}}; + +var reactIs_production = {}; + +/** + * @license React + * react-is.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +var hasRequiredReactIs_production; + +function requireReactIs_production () { + if (hasRequiredReactIs_production) return reactIs_production; + hasRequiredReactIs_production = 1; + var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), + REACT_PORTAL_TYPE = Symbol.for("react.portal"), + REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), + REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), + REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), + REACT_CONTEXT_TYPE = Symbol.for("react.context"), + REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), + REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), + REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), + REACT_MEMO_TYPE = Symbol.for("react.memo"), + REACT_LAZY_TYPE = Symbol.for("react.lazy"), + REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"), + REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"); + function typeOf(object) { + if ("object" === typeof object && null !== object) { + var $$typeof = object.$$typeof; + switch ($$typeof) { + case REACT_ELEMENT_TYPE: + switch (((object = object.type), object)) { + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: + case REACT_SUSPENSE_LIST_TYPE: + case REACT_VIEW_TRANSITION_TYPE: + return object; + default: + switch (((object = object && object.$$typeof), object)) { + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_LAZY_TYPE: + case REACT_MEMO_TYPE: + return object; + case REACT_CONSUMER_TYPE: + return object; + default: + return $$typeof; + } + } + case REACT_PORTAL_TYPE: + return $$typeof; + } + } + } + reactIs_production.ContextConsumer = REACT_CONSUMER_TYPE; + reactIs_production.ContextProvider = REACT_CONTEXT_TYPE; + reactIs_production.Element = REACT_ELEMENT_TYPE; + reactIs_production.ForwardRef = REACT_FORWARD_REF_TYPE; + reactIs_production.Fragment = REACT_FRAGMENT_TYPE; + reactIs_production.Lazy = REACT_LAZY_TYPE; + reactIs_production.Memo = REACT_MEMO_TYPE; + reactIs_production.Portal = REACT_PORTAL_TYPE; + reactIs_production.Profiler = REACT_PROFILER_TYPE; + reactIs_production.StrictMode = REACT_STRICT_MODE_TYPE; + reactIs_production.Suspense = REACT_SUSPENSE_TYPE; + reactIs_production.SuspenseList = REACT_SUSPENSE_LIST_TYPE; + reactIs_production.isContextConsumer = function (object) { + return typeOf(object) === REACT_CONSUMER_TYPE; + }; + reactIs_production.isContextProvider = function (object) { + return typeOf(object) === REACT_CONTEXT_TYPE; + }; + reactIs_production.isElement = function (object) { + return ( + "object" === typeof object && + null !== object && + object.$$typeof === REACT_ELEMENT_TYPE + ); + }; + reactIs_production.isForwardRef = function (object) { + return typeOf(object) === REACT_FORWARD_REF_TYPE; + }; + reactIs_production.isFragment = function (object) { + return typeOf(object) === REACT_FRAGMENT_TYPE; + }; + reactIs_production.isLazy = function (object) { + return typeOf(object) === REACT_LAZY_TYPE; + }; + reactIs_production.isMemo = function (object) { + return typeOf(object) === REACT_MEMO_TYPE; + }; + reactIs_production.isPortal = function (object) { + return typeOf(object) === REACT_PORTAL_TYPE; + }; + reactIs_production.isProfiler = function (object) { + return typeOf(object) === REACT_PROFILER_TYPE; + }; + reactIs_production.isStrictMode = function (object) { + return typeOf(object) === REACT_STRICT_MODE_TYPE; + }; + reactIs_production.isSuspense = function (object) { + return typeOf(object) === REACT_SUSPENSE_TYPE; + }; + reactIs_production.isSuspenseList = function (object) { + return typeOf(object) === REACT_SUSPENSE_LIST_TYPE; + }; + reactIs_production.isValidElementType = function (type) { + return "string" === typeof type || + "function" === typeof type || + type === REACT_FRAGMENT_TYPE || + type === REACT_PROFILER_TYPE || + type === REACT_STRICT_MODE_TYPE || + type === REACT_SUSPENSE_TYPE || + type === REACT_SUSPENSE_LIST_TYPE || + ("object" === typeof type && + null !== type && + (type.$$typeof === REACT_LAZY_TYPE || + type.$$typeof === REACT_MEMO_TYPE || + type.$$typeof === REACT_CONTEXT_TYPE || + type.$$typeof === REACT_CONSUMER_TYPE || + type.$$typeof === REACT_FORWARD_REF_TYPE || + type.$$typeof === REACT_CLIENT_REFERENCE || + void 0 !== type.getModuleId)) + ? true + : false; + }; + reactIs_production.typeOf = typeOf; + return reactIs_production; +} + +var reactIs_development$1 = {}; + +/** + * @license React + * react-is.development.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +var hasRequiredReactIs_development$1; + +function requireReactIs_development$1 () { + if (hasRequiredReactIs_development$1) return reactIs_development$1; + hasRequiredReactIs_development$1 = 1; + "production" !== process.env.NODE_ENV && + (function () { + function typeOf(object) { + if ("object" === typeof object && null !== object) { + var $$typeof = object.$$typeof; + switch ($$typeof) { + case REACT_ELEMENT_TYPE: + switch (((object = object.type), object)) { + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: + case REACT_SUSPENSE_LIST_TYPE: + case REACT_VIEW_TRANSITION_TYPE: + return object; + default: + switch (((object = object && object.$$typeof), object)) { + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_LAZY_TYPE: + case REACT_MEMO_TYPE: + return object; + case REACT_CONSUMER_TYPE: + return object; + default: + return $$typeof; + } + } + case REACT_PORTAL_TYPE: + return $$typeof; + } + } + } + var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), + REACT_PORTAL_TYPE = Symbol.for("react.portal"), + REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), + REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), + REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), + REACT_CONTEXT_TYPE = Symbol.for("react.context"), + REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), + REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), + REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), + REACT_MEMO_TYPE = Symbol.for("react.memo"), + REACT_LAZY_TYPE = Symbol.for("react.lazy"), + REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"), + REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"); + reactIs_development$1.ContextConsumer = REACT_CONSUMER_TYPE; + reactIs_development$1.ContextProvider = REACT_CONTEXT_TYPE; + reactIs_development$1.Element = REACT_ELEMENT_TYPE; + reactIs_development$1.ForwardRef = REACT_FORWARD_REF_TYPE; + reactIs_development$1.Fragment = REACT_FRAGMENT_TYPE; + reactIs_development$1.Lazy = REACT_LAZY_TYPE; + reactIs_development$1.Memo = REACT_MEMO_TYPE; + reactIs_development$1.Portal = REACT_PORTAL_TYPE; + reactIs_development$1.Profiler = REACT_PROFILER_TYPE; + reactIs_development$1.StrictMode = REACT_STRICT_MODE_TYPE; + reactIs_development$1.Suspense = REACT_SUSPENSE_TYPE; + reactIs_development$1.SuspenseList = REACT_SUSPENSE_LIST_TYPE; + reactIs_development$1.isContextConsumer = function (object) { + return typeOf(object) === REACT_CONSUMER_TYPE; + }; + reactIs_development$1.isContextProvider = function (object) { + return typeOf(object) === REACT_CONTEXT_TYPE; + }; + reactIs_development$1.isElement = function (object) { + return ( + "object" === typeof object && + null !== object && + object.$$typeof === REACT_ELEMENT_TYPE + ); + }; + reactIs_development$1.isForwardRef = function (object) { + return typeOf(object) === REACT_FORWARD_REF_TYPE; + }; + reactIs_development$1.isFragment = function (object) { + return typeOf(object) === REACT_FRAGMENT_TYPE; + }; + reactIs_development$1.isLazy = function (object) { + return typeOf(object) === REACT_LAZY_TYPE; + }; + reactIs_development$1.isMemo = function (object) { + return typeOf(object) === REACT_MEMO_TYPE; + }; + reactIs_development$1.isPortal = function (object) { + return typeOf(object) === REACT_PORTAL_TYPE; + }; + reactIs_development$1.isProfiler = function (object) { + return typeOf(object) === REACT_PROFILER_TYPE; + }; + reactIs_development$1.isStrictMode = function (object) { + return typeOf(object) === REACT_STRICT_MODE_TYPE; + }; + reactIs_development$1.isSuspense = function (object) { + return typeOf(object) === REACT_SUSPENSE_TYPE; + }; + reactIs_development$1.isSuspenseList = function (object) { + return typeOf(object) === REACT_SUSPENSE_LIST_TYPE; + }; + reactIs_development$1.isValidElementType = function (type) { + return "string" === typeof type || + "function" === typeof type || + type === REACT_FRAGMENT_TYPE || + type === REACT_PROFILER_TYPE || + type === REACT_STRICT_MODE_TYPE || + type === REACT_SUSPENSE_TYPE || + type === REACT_SUSPENSE_LIST_TYPE || + ("object" === typeof type && + null !== type && + (type.$$typeof === REACT_LAZY_TYPE || + type.$$typeof === REACT_MEMO_TYPE || + type.$$typeof === REACT_CONTEXT_TYPE || + type.$$typeof === REACT_CONSUMER_TYPE || + type.$$typeof === REACT_FORWARD_REF_TYPE || + type.$$typeof === REACT_CLIENT_REFERENCE || + void 0 !== type.getModuleId)) + ? true + : false; + }; + reactIs_development$1.typeOf = typeOf; + })(); + return reactIs_development$1; +} + +var hasRequiredReactIs$1; + +function requireReactIs$1 () { + if (hasRequiredReactIs$1) return reactIs$1.exports; + hasRequiredReactIs$1 = 1; + + if (process.env.NODE_ENV === 'production') { + reactIs$1.exports = requireReactIs_production(); + } else { + reactIs$1.exports = requireReactIs_development$1(); + } + return reactIs$1.exports; +} + +var reactIsExports$1 = requireReactIs$1(); +var index$1 = /*@__PURE__*/getDefaultExportFromCjs(reactIsExports$1); + +var ReactIs19 = /*#__PURE__*/_mergeNamespaces({ + __proto__: null, + default: index$1 +}, [reactIsExports$1]); + +var reactIs = {exports: {}}; + +var reactIs_production_min = {}; + +/** + * @license React + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +var hasRequiredReactIs_production_min; + +function requireReactIs_production_min () { + if (hasRequiredReactIs_production_min) return reactIs_production_min; + hasRequiredReactIs_production_min = 1; +var b=Symbol.for("react.element"),c=Symbol.for("react.portal"),d=Symbol.for("react.fragment"),e=Symbol.for("react.strict_mode"),f=Symbol.for("react.profiler"),g=Symbol.for("react.provider"),h=Symbol.for("react.context"),k=Symbol.for("react.server_context"),l=Symbol.for("react.forward_ref"),m=Symbol.for("react.suspense"),n=Symbol.for("react.suspense_list"),p=Symbol.for("react.memo"),q=Symbol.for("react.lazy"),t=Symbol.for("react.offscreen"),u;u=Symbol.for("react.module.reference"); + function v(a){if("object"===typeof a&&null!==a){var r=a.$$typeof;switch(r){case b:switch(a=a.type,a){case d:case f:case e:case m:case n:return a;default:switch(a=a&&a.$$typeof,a){case k:case h:case l:case q:case p:case g:return a;default:return r}}case c:return r}}}reactIs_production_min.ContextConsumer=h;reactIs_production_min.ContextProvider=g;reactIs_production_min.Element=b;reactIs_production_min.ForwardRef=l;reactIs_production_min.Fragment=d;reactIs_production_min.Lazy=q;reactIs_production_min.Memo=p;reactIs_production_min.Portal=c;reactIs_production_min.Profiler=f;reactIs_production_min.StrictMode=e;reactIs_production_min.Suspense=m; + reactIs_production_min.SuspenseList=n;reactIs_production_min.isAsyncMode=function(){return false};reactIs_production_min.isConcurrentMode=function(){return false};reactIs_production_min.isContextConsumer=function(a){return v(a)===h};reactIs_production_min.isContextProvider=function(a){return v(a)===g};reactIs_production_min.isElement=function(a){return "object"===typeof a&&null!==a&&a.$$typeof===b};reactIs_production_min.isForwardRef=function(a){return v(a)===l};reactIs_production_min.isFragment=function(a){return v(a)===d};reactIs_production_min.isLazy=function(a){return v(a)===q};reactIs_production_min.isMemo=function(a){return v(a)===p}; + reactIs_production_min.isPortal=function(a){return v(a)===c};reactIs_production_min.isProfiler=function(a){return v(a)===f};reactIs_production_min.isStrictMode=function(a){return v(a)===e};reactIs_production_min.isSuspense=function(a){return v(a)===m};reactIs_production_min.isSuspenseList=function(a){return v(a)===n}; + reactIs_production_min.isValidElementType=function(a){return "string"===typeof a||"function"===typeof a||a===d||a===f||a===e||a===m||a===n||a===t||"object"===typeof a&&null!==a&&(a.$$typeof===q||a.$$typeof===p||a.$$typeof===g||a.$$typeof===h||a.$$typeof===l||a.$$typeof===u||void 0!==a.getModuleId)?true:false};reactIs_production_min.typeOf=v; + return reactIs_production_min; +} + +var reactIs_development = {}; + +/** + * @license React + * react-is.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +var hasRequiredReactIs_development; + +function requireReactIs_development () { + if (hasRequiredReactIs_development) return reactIs_development; + hasRequiredReactIs_development = 1; + + if (process.env.NODE_ENV !== "production") { + (function() { + + // ATTENTION + // When adding new symbols to this file, + // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols' + // The Symbol used to tag the ReactElement-like types. + var REACT_ELEMENT_TYPE = Symbol.for('react.element'); + var REACT_PORTAL_TYPE = Symbol.for('react.portal'); + var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment'); + var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode'); + var REACT_PROFILER_TYPE = Symbol.for('react.profiler'); + var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); + var REACT_CONTEXT_TYPE = Symbol.for('react.context'); + var REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context'); + var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref'); + var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense'); + var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list'); + var REACT_MEMO_TYPE = Symbol.for('react.memo'); + var REACT_LAZY_TYPE = Symbol.for('react.lazy'); + var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen'); + + // ----------------------------------------------------------------------------- + + var enableScopeAPI = false; // Experimental Create Event Handle API. + var enableCacheElement = false; + var enableTransitionTracing = false; // No known bugs, but needs performance testing + + var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber + // stuff. Intended to enable React core members to more easily debug scheduling + // issues in DEV builds. + + var enableDebugTracing = false; // Track which Fiber(s) schedule render work. + + var REACT_MODULE_REFERENCE; + + { + REACT_MODULE_REFERENCE = Symbol.for('react.module.reference'); + } + + function isValidElementType(type) { + if (typeof type === 'string' || typeof type === 'function') { + return true; + } // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill). + + + if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden || type === REACT_OFFSCREEN_TYPE || enableScopeAPI || enableCacheElement || enableTransitionTracing ) { + return true; + } + + if (typeof type === 'object' && type !== null) { + if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object + // types supported by any Flight configuration anywhere since + // we don't know which Flight build this will end up being used + // with. + type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== undefined) { + return true; + } + } + + return false; + } + + function typeOf(object) { + if (typeof object === 'object' && object !== null) { + var $$typeof = object.$$typeof; + + switch ($$typeof) { + case REACT_ELEMENT_TYPE: + var type = object.type; + + switch (type) { + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: + case REACT_SUSPENSE_LIST_TYPE: + return type; + + default: + var $$typeofType = type && type.$$typeof; + + switch ($$typeofType) { + case REACT_SERVER_CONTEXT_TYPE: + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_LAZY_TYPE: + case REACT_MEMO_TYPE: + case REACT_PROVIDER_TYPE: + return $$typeofType; + + default: + return $$typeof; + } + + } + + case REACT_PORTAL_TYPE: + return $$typeof; + } + } + + return undefined; + } + var ContextConsumer = REACT_CONTEXT_TYPE; + var ContextProvider = REACT_PROVIDER_TYPE; + var Element = REACT_ELEMENT_TYPE; + var ForwardRef = REACT_FORWARD_REF_TYPE; + var Fragment = REACT_FRAGMENT_TYPE; + var Lazy = REACT_LAZY_TYPE; + var Memo = REACT_MEMO_TYPE; + var Portal = REACT_PORTAL_TYPE; + var Profiler = REACT_PROFILER_TYPE; + var StrictMode = REACT_STRICT_MODE_TYPE; + var Suspense = REACT_SUSPENSE_TYPE; + var SuspenseList = REACT_SUSPENSE_LIST_TYPE; + var hasWarnedAboutDeprecatedIsAsyncMode = false; + var hasWarnedAboutDeprecatedIsConcurrentMode = false; // AsyncMode should be deprecated + + function isAsyncMode(object) { + { + if (!hasWarnedAboutDeprecatedIsAsyncMode) { + hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint + + console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 18+.'); + } + } + + return false; + } + function isConcurrentMode(object) { + { + if (!hasWarnedAboutDeprecatedIsConcurrentMode) { + hasWarnedAboutDeprecatedIsConcurrentMode = true; // Using console['warn'] to evade Babel and ESLint + + console['warn']('The ReactIs.isConcurrentMode() alias has been deprecated, ' + 'and will be removed in React 18+.'); + } + } + + return false; + } + function isContextConsumer(object) { + return typeOf(object) === REACT_CONTEXT_TYPE; + } + function isContextProvider(object) { + return typeOf(object) === REACT_PROVIDER_TYPE; + } + function isElement(object) { + return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; + } + function isForwardRef(object) { + return typeOf(object) === REACT_FORWARD_REF_TYPE; + } + function isFragment(object) { + return typeOf(object) === REACT_FRAGMENT_TYPE; + } + function isLazy(object) { + return typeOf(object) === REACT_LAZY_TYPE; + } + function isMemo(object) { + return typeOf(object) === REACT_MEMO_TYPE; + } + function isPortal(object) { + return typeOf(object) === REACT_PORTAL_TYPE; + } + function isProfiler(object) { + return typeOf(object) === REACT_PROFILER_TYPE; + } + function isStrictMode(object) { + return typeOf(object) === REACT_STRICT_MODE_TYPE; + } + function isSuspense(object) { + return typeOf(object) === REACT_SUSPENSE_TYPE; + } + function isSuspenseList(object) { + return typeOf(object) === REACT_SUSPENSE_LIST_TYPE; + } + + reactIs_development.ContextConsumer = ContextConsumer; + reactIs_development.ContextProvider = ContextProvider; + reactIs_development.Element = Element; + reactIs_development.ForwardRef = ForwardRef; + reactIs_development.Fragment = Fragment; + reactIs_development.Lazy = Lazy; + reactIs_development.Memo = Memo; + reactIs_development.Portal = Portal; + reactIs_development.Profiler = Profiler; + reactIs_development.StrictMode = StrictMode; + reactIs_development.Suspense = Suspense; + reactIs_development.SuspenseList = SuspenseList; + reactIs_development.isAsyncMode = isAsyncMode; + reactIs_development.isConcurrentMode = isConcurrentMode; + reactIs_development.isContextConsumer = isContextConsumer; + reactIs_development.isContextProvider = isContextProvider; + reactIs_development.isElement = isElement; + reactIs_development.isForwardRef = isForwardRef; + reactIs_development.isFragment = isFragment; + reactIs_development.isLazy = isLazy; + reactIs_development.isMemo = isMemo; + reactIs_development.isPortal = isPortal; + reactIs_development.isProfiler = isProfiler; + reactIs_development.isStrictMode = isStrictMode; + reactIs_development.isSuspense = isSuspense; + reactIs_development.isSuspenseList = isSuspenseList; + reactIs_development.isValidElementType = isValidElementType; + reactIs_development.typeOf = typeOf; + })(); + } + return reactIs_development; +} + +var hasRequiredReactIs; + +function requireReactIs () { + if (hasRequiredReactIs) return reactIs.exports; + hasRequiredReactIs = 1; + + if (process.env.NODE_ENV === 'production') { + reactIs.exports = requireReactIs_production_min(); + } else { + reactIs.exports = requireReactIs_development(); + } + return reactIs.exports; +} + +var reactIsExports = requireReactIs(); +var index = /*@__PURE__*/getDefaultExportFromCjs(reactIsExports); + +var ReactIs18 = /*#__PURE__*/_mergeNamespaces({ + __proto__: null, + default: index +}, [reactIsExports]); + +const reactIsMethods = [ + "isAsyncMode", + "isConcurrentMode", + "isContextConsumer", + "isContextProvider", + "isElement", + "isForwardRef", + "isFragment", + "isLazy", + "isMemo", + "isPortal", + "isProfiler", + "isStrictMode", + "isSuspense", + "isSuspenseList", + "isValidElementType" +]; +const ReactIs = Object.fromEntries(reactIsMethods.map((m) => [m, (v) => ReactIs18[m](v) || ReactIs19[m](v)])); +// Given element.props.children, or subtree during recursive traversal, +// return flattened array of children. +function getChildren(arg, children = []) { + if (Array.isArray(arg)) { + for (const item of arg) { + getChildren(item, children); + } + } else if (arg != null && arg !== false && arg !== "") { + children.push(arg); + } + return children; +} +function getType(element) { + const type = element.type; + if (typeof type === "string") { + return type; + } + if (typeof type === "function") { + return type.displayName || type.name || "Unknown"; + } + if (ReactIs.isFragment(element)) { + return "React.Fragment"; + } + if (ReactIs.isSuspense(element)) { + return "React.Suspense"; + } + if (typeof type === "object" && type !== null) { + if (ReactIs.isContextProvider(element)) { + return "Context.Provider"; + } + if (ReactIs.isContextConsumer(element)) { + return "Context.Consumer"; + } + if (ReactIs.isForwardRef(element)) { + if (type.displayName) { + return type.displayName; + } + const functionName = type.render.displayName || type.render.name || ""; + return functionName === "" ? "ForwardRef" : `ForwardRef(${functionName})`; + } + if (ReactIs.isMemo(element)) { + const functionName = type.displayName || type.type.displayName || type.type.name || ""; + return functionName === "" ? "Memo" : `Memo(${functionName})`; + } + } + return "UNDEFINED"; +} +function getPropKeys$1(element) { + const { props } = element; + return Object.keys(props).filter((key) => key !== "children" && props[key] !== undefined).sort(); +} +const serialize$1 = (element, config, indentation, depth, refs, printer) => ++depth > config.maxDepth ? printElementAsLeaf(getType(element), config) : printElement(getType(element), printProps(getPropKeys$1(element), element.props, config, indentation + config.indent, depth, refs, printer), printChildren(getChildren(element.props.children), config, indentation + config.indent, depth, refs, printer), config, indentation); +const test$1 = (val) => val != null && ReactIs.isElement(val); +const plugin$1 = { + serialize: serialize$1, + test: test$1 +}; + +const testSymbol = typeof Symbol === "function" && Symbol.for ? Symbol.for("react.test.json") : 245830487; +function getPropKeys(object) { + const { props } = object; + return props ? Object.keys(props).filter((key) => props[key] !== undefined).sort() : []; +} +const serialize = (object, config, indentation, depth, refs, printer) => ++depth > config.maxDepth ? printElementAsLeaf(object.type, config) : printElement(object.type, object.props ? printProps(getPropKeys(object), object.props, config, indentation + config.indent, depth, refs, printer) : "", object.children ? printChildren(object.children, config, indentation + config.indent, depth, refs, printer) : "", config, indentation); +const test = (val) => val && val.$$typeof === testSymbol; +const plugin = { + serialize, + test +}; + +const toString = Object.prototype.toString; +const toISOString = Date.prototype.toISOString; +const errorToString = Error.prototype.toString; +const regExpToString = RegExp.prototype.toString; +/** +* Explicitly comparing typeof constructor to function avoids undefined as name +* when mock identity-obj-proxy returns the key as the value for any key. +*/ +function getConstructorName(val) { + return typeof val.constructor === "function" && val.constructor.name || "Object"; +} +/** Is val is equal to global window object? Works even if it does not exist :) */ +function isWindow(val) { + return typeof window !== "undefined" && val === window; +} +// eslint-disable-next-line regexp/no-super-linear-backtracking +const SYMBOL_REGEXP = /^Symbol\((.*)\)(.*)$/; +const NEWLINE_REGEXP = /\n/g; +class PrettyFormatPluginError extends Error { + constructor(message, stack) { + super(message); + this.stack = stack; + this.name = this.constructor.name; + } +} +function isToStringedArrayType(toStringed) { + return toStringed === "[object Array]" || toStringed === "[object ArrayBuffer]" || toStringed === "[object DataView]" || toStringed === "[object Float32Array]" || toStringed === "[object Float64Array]" || toStringed === "[object Int8Array]" || toStringed === "[object Int16Array]" || toStringed === "[object Int32Array]" || toStringed === "[object Uint8Array]" || toStringed === "[object Uint8ClampedArray]" || toStringed === "[object Uint16Array]" || toStringed === "[object Uint32Array]"; +} +function printNumber(val) { + return Object.is(val, -0) ? "-0" : String(val); +} +function printBigInt(val) { + return String(`${val}n`); +} +function printFunction(val, printFunctionName) { + if (!printFunctionName) { + return "[Function]"; + } + return `[Function ${val.name || "anonymous"}]`; +} +function printSymbol(val) { + return String(val).replace(SYMBOL_REGEXP, "Symbol($1)"); +} +function printError(val) { + return `[${errorToString.call(val)}]`; +} +/** +* The first port of call for printing an object, handles most of the +* data-types in JS. +*/ +function printBasicValue(val, printFunctionName, escapeRegex, escapeString) { + if (val === true || val === false) { + return `${val}`; + } + if (val === undefined) { + return "undefined"; + } + if (val === null) { + return "null"; + } + const typeOf = typeof val; + if (typeOf === "number") { + return printNumber(val); + } + if (typeOf === "bigint") { + return printBigInt(val); + } + if (typeOf === "string") { + if (escapeString) { + return `"${val.replaceAll(/"|\\/g, "\\$&")}"`; + } + return `"${val}"`; + } + if (typeOf === "function") { + return printFunction(val, printFunctionName); + } + if (typeOf === "symbol") { + return printSymbol(val); + } + const toStringed = toString.call(val); + if (toStringed === "[object WeakMap]") { + return "WeakMap {}"; + } + if (toStringed === "[object WeakSet]") { + return "WeakSet {}"; + } + if (toStringed === "[object Function]" || toStringed === "[object GeneratorFunction]") { + return printFunction(val, printFunctionName); + } + if (toStringed === "[object Symbol]") { + return printSymbol(val); + } + if (toStringed === "[object Date]") { + return Number.isNaN(+val) ? "Date { NaN }" : toISOString.call(val); + } + if (toStringed === "[object Error]") { + return printError(val); + } + if (toStringed === "[object RegExp]") { + if (escapeRegex) { + // https://github.com/benjamingr/RegExp.escape/blob/main/polyfill.js + return regExpToString.call(val).replaceAll(/[$()*+.?[\\\]^{|}]/g, "\\$&"); + } + return regExpToString.call(val); + } + if (val instanceof Error) { + return printError(val); + } + return null; +} +/** +* Handles more complex objects ( such as objects with circular references. +* maps and sets etc ) +*/ +function printComplexValue(val, config, indentation, depth, refs, hasCalledToJSON) { + if (refs.includes(val)) { + return "[Circular]"; + } + refs = [...refs]; + refs.push(val); + const hitMaxDepth = ++depth > config.maxDepth; + const min = config.min; + if (config.callToJSON && !hitMaxDepth && val.toJSON && typeof val.toJSON === "function" && !hasCalledToJSON) { + return printer(val.toJSON(), config, indentation, depth, refs, true); + } + const toStringed = toString.call(val); + if (toStringed === "[object Arguments]") { + return hitMaxDepth ? "[Arguments]" : `${min ? "" : "Arguments "}[${printListItems(val, config, indentation, depth, refs, printer)}]`; + } + if (isToStringedArrayType(toStringed)) { + return hitMaxDepth ? `[${val.constructor.name}]` : `${min ? "" : !config.printBasicPrototype && val.constructor.name === "Array" ? "" : `${val.constructor.name} `}[${printListItems(val, config, indentation, depth, refs, printer)}]`; + } + if (toStringed === "[object Map]") { + return hitMaxDepth ? "[Map]" : `Map {${printIteratorEntries(val.entries(), config, indentation, depth, refs, printer, " => ")}}`; + } + if (toStringed === "[object Set]") { + return hitMaxDepth ? "[Set]" : `Set {${printIteratorValues(val.values(), config, indentation, depth, refs, printer)}}`; + } + // Avoid failure to serialize global window object in jsdom test environment. + // For example, not even relevant if window is prop of React element. + return hitMaxDepth || isWindow(val) ? `[${getConstructorName(val)}]` : `${min ? "" : !config.printBasicPrototype && getConstructorName(val) === "Object" ? "" : `${getConstructorName(val)} `}{${printObjectProperties(val, config, indentation, depth, refs, printer)}}`; +} +const ErrorPlugin = { + test: (val) => val && val instanceof Error, + serialize(val, config, indentation, depth, refs, printer) { + if (refs.includes(val)) { + return "[Circular]"; + } + refs = [...refs, val]; + const hitMaxDepth = ++depth > config.maxDepth; + const { message, cause,...rest } = val; + const entries = { + message, + ...typeof cause !== "undefined" ? { cause } : {}, + ...val instanceof AggregateError ? { errors: val.errors } : {}, + ...rest + }; + const name = val.name !== "Error" ? val.name : getConstructorName(val); + return hitMaxDepth ? `[${name}]` : `${name} {${printIteratorEntries(Object.entries(entries).values(), config, indentation, depth, refs, printer)}}`; + } +}; +function isNewPlugin(plugin) { + return plugin.serialize != null; +} +function printPlugin(plugin, val, config, indentation, depth, refs) { + let printed; + try { + printed = isNewPlugin(plugin) ? plugin.serialize(val, config, indentation, depth, refs, printer) : plugin.print(val, (valChild) => printer(valChild, config, indentation, depth, refs), (str) => { + const indentationNext = indentation + config.indent; + return indentationNext + str.replaceAll(NEWLINE_REGEXP, `\n${indentationNext}`); + }, { + edgeSpacing: config.spacingOuter, + min: config.min, + spacing: config.spacingInner + }, config.colors); + } catch (error) { + throw new PrettyFormatPluginError(error.message, error.stack); + } + if (typeof printed !== "string") { + throw new TypeError(`pretty-format: Plugin must return type "string" but instead returned "${typeof printed}".`); + } + return printed; +} +function findPlugin(plugins, val) { + for (const plugin of plugins) { + try { + if (plugin.test(val)) { + return plugin; + } + } catch (error) { + throw new PrettyFormatPluginError(error.message, error.stack); + } + } + return null; +} +function printer(val, config, indentation, depth, refs, hasCalledToJSON) { + const plugin = findPlugin(config.plugins, val); + if (plugin !== null) { + return printPlugin(plugin, val, config, indentation, depth, refs); + } + const basicResult = printBasicValue(val, config.printFunctionName, config.escapeRegex, config.escapeString); + if (basicResult !== null) { + return basicResult; + } + return printComplexValue(val, config, indentation, depth, refs, hasCalledToJSON); +} +const DEFAULT_THEME = { + comment: "gray", + content: "reset", + prop: "yellow", + tag: "cyan", + value: "green" +}; +const DEFAULT_THEME_KEYS = Object.keys(DEFAULT_THEME); +const DEFAULT_OPTIONS = { + callToJSON: true, + compareKeys: undefined, + escapeRegex: false, + escapeString: true, + highlight: false, + indent: 2, + maxDepth: Number.POSITIVE_INFINITY, + maxWidth: Number.POSITIVE_INFINITY, + min: false, + plugins: [], + printBasicPrototype: true, + printFunctionName: true, + theme: DEFAULT_THEME +}; +function validateOptions(options) { + for (const key of Object.keys(options)) { + if (!Object.prototype.hasOwnProperty.call(DEFAULT_OPTIONS, key)) { + throw new Error(`pretty-format: Unknown option "${key}".`); + } + } + if (options.min && options.indent !== undefined && options.indent !== 0) { + throw new Error("pretty-format: Options \"min\" and \"indent\" cannot be used together."); + } +} +function getColorsHighlight() { + return DEFAULT_THEME_KEYS.reduce((colors, key) => { + const value = DEFAULT_THEME[key]; + const color = value && styles[value]; + if (color && typeof color.close === "string" && typeof color.open === "string") { + colors[key] = color; + } else { + throw new Error(`pretty-format: Option "theme" has a key "${key}" whose value "${value}" is undefined in ansi-styles.`); + } + return colors; + }, Object.create(null)); +} +function getColorsEmpty() { + return DEFAULT_THEME_KEYS.reduce((colors, key) => { + colors[key] = { + close: "", + open: "" + }; + return colors; + }, Object.create(null)); +} +function getPrintFunctionName(options) { + return (options === null || options === void 0 ? void 0 : options.printFunctionName) ?? DEFAULT_OPTIONS.printFunctionName; +} +function getEscapeRegex(options) { + return (options === null || options === void 0 ? void 0 : options.escapeRegex) ?? DEFAULT_OPTIONS.escapeRegex; +} +function getEscapeString(options) { + return (options === null || options === void 0 ? void 0 : options.escapeString) ?? DEFAULT_OPTIONS.escapeString; +} +function getConfig(options) { + return { + callToJSON: (options === null || options === void 0 ? void 0 : options.callToJSON) ?? DEFAULT_OPTIONS.callToJSON, + colors: (options === null || options === void 0 ? void 0 : options.highlight) ? getColorsHighlight() : getColorsEmpty(), + compareKeys: typeof (options === null || options === void 0 ? void 0 : options.compareKeys) === "function" || (options === null || options === void 0 ? void 0 : options.compareKeys) === null ? options.compareKeys : DEFAULT_OPTIONS.compareKeys, + escapeRegex: getEscapeRegex(options), + escapeString: getEscapeString(options), + indent: (options === null || options === void 0 ? void 0 : options.min) ? "" : createIndent((options === null || options === void 0 ? void 0 : options.indent) ?? DEFAULT_OPTIONS.indent), + maxDepth: (options === null || options === void 0 ? void 0 : options.maxDepth) ?? DEFAULT_OPTIONS.maxDepth, + maxWidth: (options === null || options === void 0 ? void 0 : options.maxWidth) ?? DEFAULT_OPTIONS.maxWidth, + min: (options === null || options === void 0 ? void 0 : options.min) ?? DEFAULT_OPTIONS.min, + plugins: (options === null || options === void 0 ? void 0 : options.plugins) ?? DEFAULT_OPTIONS.plugins, + printBasicPrototype: (options === null || options === void 0 ? void 0 : options.printBasicPrototype) ?? true, + printFunctionName: getPrintFunctionName(options), + spacingInner: (options === null || options === void 0 ? void 0 : options.min) ? " " : "\n", + spacingOuter: (options === null || options === void 0 ? void 0 : options.min) ? "" : "\n" + }; +} +function createIndent(indent) { + return Array.from({ length: indent + 1 }).join(" "); +} +/** +* Returns a presentation string of your `val` object +* @param val any potential JavaScript object +* @param options Custom settings +*/ +function format(val, options) { + if (options) { + validateOptions(options); + if (options.plugins) { + const plugin = findPlugin(options.plugins, val); + if (plugin !== null) { + return printPlugin(plugin, val, getConfig(options), "", 0, []); + } + } + } + const basicResult = printBasicValue(val, getPrintFunctionName(options), getEscapeRegex(options), getEscapeString(options)); + if (basicResult !== null) { + return basicResult; + } + return printComplexValue(val, getConfig(options), "", 0, []); +} +const plugins = { + AsymmetricMatcher: plugin$5, + DOMCollection: plugin$4, + DOMElement: plugin$3, + Immutable: plugin$2, + ReactElement: plugin$1, + ReactTestComponent: plugin, + Error: ErrorPlugin +}; + +export { DEFAULT_OPTIONS, format, plugins }; diff --git a/node_modules/@vitest/pretty-format/package.json b/node_modules/@vitest/pretty-format/package.json new file mode 100644 index 0000000000..6de6a1a651 --- /dev/null +++ b/node_modules/@vitest/pretty-format/package.json @@ -0,0 +1,44 @@ +{ + "name": "@vitest/pretty-format", + "type": "module", + "version": "3.2.4", + "description": "Fork of pretty-format with support for ESM", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/utils#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/pretty-format" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "*.d.ts", + "dist" + ], + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "devDependencies": { + "@types/react-is": "^19.0.0", + "react-is": "^19.1.0", + "react-is-18": "npm:react-is@18.3.1" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/runner/LICENSE b/node_modules/@vitest/runner/LICENSE new file mode 100644 index 0000000000..5ae481fdb8 --- /dev/null +++ b/node_modules/@vitest/runner/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/runner/README.md b/node_modules/@vitest/runner/README.md new file mode 100644 index 0000000000..2796b6aacd --- /dev/null +++ b/node_modules/@vitest/runner/README.md @@ -0,0 +1,5 @@ +# @vitest/runner + +Vitest mechanism to collect and run tasks. + +[GitHub](https://github.com/vitest-dev/vitest) | [Documentation](https://vitest.dev/advanced/runner) diff --git a/node_modules/@vitest/runner/dist/chunk-hooks.js b/node_modules/@vitest/runner/dist/chunk-hooks.js new file mode 100644 index 0000000000..59908e26ff --- /dev/null +++ b/node_modules/@vitest/runner/dist/chunk-hooks.js @@ -0,0 +1,2254 @@ +import { isObject, createDefer, toArray, isNegativeNaN, format, objectAttr, objDisplay, getSafeTimers, shuffle, assertTypes } from '@vitest/utils'; +import { parseSingleStack } from '@vitest/utils/source-map'; +import { processError } from '@vitest/utils/error'; +import { stripLiteral } from 'strip-literal'; +import { relative } from 'pathe'; + +class PendingError extends Error { + code = "VITEST_PENDING"; + taskId; + constructor(message, task, note) { + super(message); + this.message = message; + this.note = note; + this.taskId = task.id; + } +} +class TestRunAbortError extends Error { + name = "TestRunAbortError"; + reason; + constructor(message, reason) { + super(message); + this.reason = reason; + } +} + +// use WeakMap here to make the Test and Suite object serializable +const fnMap = new WeakMap(); +const testFixtureMap = new WeakMap(); +const hooksMap = new WeakMap(); +function setFn(key, fn) { + fnMap.set(key, fn); +} +function getFn(key) { + return fnMap.get(key); +} +function setTestFixture(key, fixture) { + testFixtureMap.set(key, fixture); +} +function getTestFixture(key) { + return testFixtureMap.get(key); +} +function setHooks(key, hooks) { + hooksMap.set(key, hooks); +} +function getHooks(key) { + return hooksMap.get(key); +} + +async function runSetupFiles(config, files, runner) { + if (config.sequence.setupFiles === "parallel") { + await Promise.all(files.map(async (fsPath) => { + await runner.importFile(fsPath, "setup"); + })); + } else { + for (const fsPath of files) { + await runner.importFile(fsPath, "setup"); + } + } +} + +function mergeScopedFixtures(testFixtures, scopedFixtures) { + const scopedFixturesMap = scopedFixtures.reduce((map, fixture) => { + map[fixture.prop] = fixture; + return map; + }, {}); + const newFixtures = {}; + testFixtures.forEach((fixture) => { + const useFixture = scopedFixturesMap[fixture.prop] || { ...fixture }; + newFixtures[useFixture.prop] = useFixture; + }); + for (const fixtureKep in newFixtures) { + var _fixture$deps; + const fixture = newFixtures[fixtureKep]; + // if the fixture was define before the scope, then its dep + // will reference the original fixture instead of the scope + fixture.deps = (_fixture$deps = fixture.deps) === null || _fixture$deps === void 0 ? void 0 : _fixture$deps.map((dep) => newFixtures[dep.prop]); + } + return Object.values(newFixtures); +} +function mergeContextFixtures(fixtures, context, runner) { + const fixtureOptionKeys = [ + "auto", + "injected", + "scope" + ]; + const fixtureArray = Object.entries(fixtures).map(([prop, value]) => { + const fixtureItem = { value }; + if (Array.isArray(value) && value.length >= 2 && isObject(value[1]) && Object.keys(value[1]).some((key) => fixtureOptionKeys.includes(key))) { + var _runner$injectValue; + // fixture with options + Object.assign(fixtureItem, value[1]); + const userValue = value[0]; + fixtureItem.value = fixtureItem.injected ? ((_runner$injectValue = runner.injectValue) === null || _runner$injectValue === void 0 ? void 0 : _runner$injectValue.call(runner, prop)) ?? userValue : userValue; + } + fixtureItem.scope = fixtureItem.scope || "test"; + if (fixtureItem.scope === "worker" && !runner.getWorkerContext) { + fixtureItem.scope = "file"; + } + fixtureItem.prop = prop; + fixtureItem.isFn = typeof fixtureItem.value === "function"; + return fixtureItem; + }); + if (Array.isArray(context.fixtures)) { + context.fixtures = context.fixtures.concat(fixtureArray); + } else { + context.fixtures = fixtureArray; + } + // Update dependencies of fixture functions + fixtureArray.forEach((fixture) => { + if (fixture.isFn) { + const usedProps = getUsedProps(fixture.value); + if (usedProps.length) { + fixture.deps = context.fixtures.filter(({ prop }) => prop !== fixture.prop && usedProps.includes(prop)); + } + // test can access anything, so we ignore it + if (fixture.scope !== "test") { + var _fixture$deps2; + (_fixture$deps2 = fixture.deps) === null || _fixture$deps2 === void 0 ? void 0 : _fixture$deps2.forEach((dep) => { + if (!dep.isFn) { + // non fn fixtures are always resolved and available to anyone + return; + } + // worker scope can only import from worker scope + if (fixture.scope === "worker" && dep.scope === "worker") { + return; + } + // file scope an import from file and worker scopes + if (fixture.scope === "file" && dep.scope !== "test") { + return; + } + throw new SyntaxError(`cannot use the ${dep.scope} fixture "${dep.prop}" inside the ${fixture.scope} fixture "${fixture.prop}"`); + }); + } + } + }); + return context; +} +const fixtureValueMaps = new Map(); +const cleanupFnArrayMap = new Map(); +async function callFixtureCleanup(context) { + const cleanupFnArray = cleanupFnArrayMap.get(context) ?? []; + for (const cleanup of cleanupFnArray.reverse()) { + await cleanup(); + } + cleanupFnArrayMap.delete(context); +} +function withFixtures(runner, fn, testContext) { + return (hookContext) => { + const context = hookContext || testContext; + if (!context) { + return fn({}); + } + const fixtures = getTestFixture(context); + if (!(fixtures === null || fixtures === void 0 ? void 0 : fixtures.length)) { + return fn(context); + } + const usedProps = getUsedProps(fn); + const hasAutoFixture = fixtures.some(({ auto }) => auto); + if (!usedProps.length && !hasAutoFixture) { + return fn(context); + } + if (!fixtureValueMaps.get(context)) { + fixtureValueMaps.set(context, new Map()); + } + const fixtureValueMap = fixtureValueMaps.get(context); + if (!cleanupFnArrayMap.has(context)) { + cleanupFnArrayMap.set(context, []); + } + const cleanupFnArray = cleanupFnArrayMap.get(context); + const usedFixtures = fixtures.filter(({ prop, auto }) => auto || usedProps.includes(prop)); + const pendingFixtures = resolveDeps(usedFixtures); + if (!pendingFixtures.length) { + return fn(context); + } + async function resolveFixtures() { + for (const fixture of pendingFixtures) { + // fixture could be already initialized during "before" hook + if (fixtureValueMap.has(fixture)) { + continue; + } + const resolvedValue = await resolveFixtureValue(runner, fixture, context, cleanupFnArray); + context[fixture.prop] = resolvedValue; + fixtureValueMap.set(fixture, resolvedValue); + if (fixture.scope === "test") { + cleanupFnArray.unshift(() => { + fixtureValueMap.delete(fixture); + }); + } + } + } + return resolveFixtures().then(() => fn(context)); + }; +} +const globalFixturePromise = new WeakMap(); +function resolveFixtureValue(runner, fixture, context, cleanupFnArray) { + var _runner$getWorkerCont; + const fileContext = getFileContext(context.task.file); + const workerContext = (_runner$getWorkerCont = runner.getWorkerContext) === null || _runner$getWorkerCont === void 0 ? void 0 : _runner$getWorkerCont.call(runner); + if (!fixture.isFn) { + var _fixture$prop; + fileContext[_fixture$prop = fixture.prop] ?? (fileContext[_fixture$prop] = fixture.value); + if (workerContext) { + var _fixture$prop2; + workerContext[_fixture$prop2 = fixture.prop] ?? (workerContext[_fixture$prop2] = fixture.value); + } + return fixture.value; + } + if (fixture.scope === "test") { + return resolveFixtureFunction(fixture.value, context, cleanupFnArray); + } + // in case the test runs in parallel + if (globalFixturePromise.has(fixture)) { + return globalFixturePromise.get(fixture); + } + let fixtureContext; + if (fixture.scope === "worker") { + if (!workerContext) { + throw new TypeError("[@vitest/runner] The worker context is not available in the current test runner. Please, provide the `getWorkerContext` method when initiating the runner."); + } + fixtureContext = workerContext; + } else { + fixtureContext = fileContext; + } + if (fixture.prop in fixtureContext) { + return fixtureContext[fixture.prop]; + } + if (!cleanupFnArrayMap.has(fixtureContext)) { + cleanupFnArrayMap.set(fixtureContext, []); + } + const cleanupFnFileArray = cleanupFnArrayMap.get(fixtureContext); + const promise = resolveFixtureFunction(fixture.value, fixtureContext, cleanupFnFileArray).then((value) => { + fixtureContext[fixture.prop] = value; + globalFixturePromise.delete(fixture); + return value; + }); + globalFixturePromise.set(fixture, promise); + return promise; +} +async function resolveFixtureFunction(fixtureFn, context, cleanupFnArray) { + // wait for `use` call to extract fixture value + const useFnArgPromise = createDefer(); + let isUseFnArgResolved = false; + const fixtureReturn = fixtureFn(context, async (useFnArg) => { + // extract `use` argument + isUseFnArgResolved = true; + useFnArgPromise.resolve(useFnArg); + // suspend fixture teardown by holding off `useReturnPromise` resolution until cleanup + const useReturnPromise = createDefer(); + cleanupFnArray.push(async () => { + // start teardown by resolving `use` Promise + useReturnPromise.resolve(); + // wait for finishing teardown + await fixtureReturn; + }); + await useReturnPromise; + }).catch((e) => { + // treat fixture setup error as test failure + if (!isUseFnArgResolved) { + useFnArgPromise.reject(e); + return; + } + // otherwise re-throw to avoid silencing error during cleanup + throw e; + }); + return useFnArgPromise; +} +function resolveDeps(fixtures, depSet = new Set(), pendingFixtures = []) { + fixtures.forEach((fixture) => { + if (pendingFixtures.includes(fixture)) { + return; + } + if (!fixture.isFn || !fixture.deps) { + pendingFixtures.push(fixture); + return; + } + if (depSet.has(fixture)) { + throw new Error(`Circular fixture dependency detected: ${fixture.prop} <- ${[...depSet].reverse().map((d) => d.prop).join(" <- ")}`); + } + depSet.add(fixture); + resolveDeps(fixture.deps, depSet, pendingFixtures); + pendingFixtures.push(fixture); + depSet.clear(); + }); + return pendingFixtures; +} +function getUsedProps(fn) { + let fnString = stripLiteral(fn.toString()); + // match lowered async function and strip it off + // example code on esbuild-try https://esbuild.github.io/try/#YgAwLjI0LjAALS1zdXBwb3J0ZWQ6YXN5bmMtYXdhaXQ9ZmFsc2UAZQBlbnRyeS50cwBjb25zdCBvID0gewogIGYxOiBhc3luYyAoKSA9PiB7fSwKICBmMjogYXN5bmMgKGEpID0+IHt9LAogIGYzOiBhc3luYyAoYSwgYikgPT4ge30sCiAgZjQ6IGFzeW5jIGZ1bmN0aW9uKGEpIHt9LAogIGY1OiBhc3luYyBmdW5jdGlvbiBmZihhKSB7fSwKICBhc3luYyBmNihhKSB7fSwKCiAgZzE6IGFzeW5jICgpID0+IHt9LAogIGcyOiBhc3luYyAoeyBhIH0pID0+IHt9LAogIGczOiBhc3luYyAoeyBhIH0sIGIpID0+IHt9LAogIGc0OiBhc3luYyBmdW5jdGlvbiAoeyBhIH0pIHt9LAogIGc1OiBhc3luYyBmdW5jdGlvbiBnZyh7IGEgfSkge30sCiAgYXN5bmMgZzYoeyBhIH0pIHt9LAoKICBoMTogYXN5bmMgKCkgPT4ge30sCiAgLy8gY29tbWVudCBiZXR3ZWVuCiAgaDI6IGFzeW5jIChhKSA9PiB7fSwKfQ + // __async(this, null, function* + // __async(this, arguments, function* + // __async(this, [_0, _1], function* + if (/__async\((?:this|null), (?:null|arguments|\[[_0-9, ]*\]), function\*/.test(fnString)) { + fnString = fnString.split(/__async\((?:this|null),/)[1]; + } + const match = fnString.match(/[^(]*\(([^)]*)/); + if (!match) { + return []; + } + const args = splitByComma(match[1]); + if (!args.length) { + return []; + } + let first = args[0]; + if ("__VITEST_FIXTURE_INDEX__" in fn) { + first = args[fn.__VITEST_FIXTURE_INDEX__]; + if (!first) { + return []; + } + } + if (!(first.startsWith("{") && first.endsWith("}"))) { + throw new Error(`The first argument inside a fixture must use object destructuring pattern, e.g. ({ test } => {}). Instead, received "${first}".`); + } + const _first = first.slice(1, -1).replace(/\s/g, ""); + const props = splitByComma(_first).map((prop) => { + return prop.replace(/:.*|=.*/g, ""); + }); + const last = props.at(-1); + if (last && last.startsWith("...")) { + throw new Error(`Rest parameters are not supported in fixtures, received "${last}".`); + } + return props; +} +function splitByComma(s) { + const result = []; + const stack = []; + let start = 0; + for (let i = 0; i < s.length; i++) { + if (s[i] === "{" || s[i] === "[") { + stack.push(s[i] === "{" ? "}" : "]"); + } else if (s[i] === stack[stack.length - 1]) { + stack.pop(); + } else if (!stack.length && s[i] === ",") { + const token = s.substring(start, i).trim(); + if (token) { + result.push(token); + } + start = i + 1; + } + } + const lastToken = s.substring(start).trim(); + if (lastToken) { + result.push(lastToken); + } + return result; +} + +let _test; +function setCurrentTest(test) { + _test = test; +} +function getCurrentTest() { + return _test; +} +const tests = []; +function addRunningTest(test) { + tests.push(test); + return () => { + tests.splice(tests.indexOf(test)); + }; +} +function getRunningTests() { + return tests; +} + +function createChainable(keys, fn) { + function create(context) { + const chain = function(...args) { + return fn.apply(context, args); + }; + Object.assign(chain, fn); + chain.withContext = () => chain.bind(context); + chain.setContext = (key, value) => { + context[key] = value; + }; + chain.mergeContext = (ctx) => { + Object.assign(context, ctx); + }; + for (const key of keys) { + Object.defineProperty(chain, key, { get() { + return create({ + ...context, + [key]: true + }); + } }); + } + return chain; + } + const chain = create({}); + chain.fn = fn; + return chain; +} + +/** +* Creates a suite of tests, allowing for grouping and hierarchical organization of tests. +* Suites can contain both tests and other suites, enabling complex test structures. +* +* @param {string} name - The name of the suite, used for identification and reporting. +* @param {Function} fn - A function that defines the tests and suites within this suite. +* @example +* ```ts +* // Define a suite with two tests +* suite('Math operations', () => { +* test('should add two numbers', () => { +* expect(add(1, 2)).toBe(3); +* }); +* +* test('should subtract two numbers', () => { +* expect(subtract(5, 2)).toBe(3); +* }); +* }); +* ``` +* @example +* ```ts +* // Define nested suites +* suite('String operations', () => { +* suite('Trimming', () => { +* test('should trim whitespace from start and end', () => { +* expect(' hello '.trim()).toBe('hello'); +* }); +* }); +* +* suite('Concatenation', () => { +* test('should concatenate two strings', () => { +* expect('hello' + ' ' + 'world').toBe('hello world'); +* }); +* }); +* }); +* ``` +*/ +const suite = createSuite(); +/** +* Defines a test case with a given name and test function. The test function can optionally be configured with test options. +* +* @param {string | Function} name - The name of the test or a function that will be used as a test name. +* @param {TestOptions | TestFunction} [optionsOrFn] - Optional. The test options or the test function if no explicit name is provided. +* @param {number | TestOptions | TestFunction} [optionsOrTest] - Optional. The test function or options, depending on the previous parameters. +* @throws {Error} If called inside another test function. +* @example +* ```ts +* // Define a simple test +* test('should add two numbers', () => { +* expect(add(1, 2)).toBe(3); +* }); +* ``` +* @example +* ```ts +* // Define a test with options +* test('should subtract two numbers', { retry: 3 }, () => { +* expect(subtract(5, 2)).toBe(3); +* }); +* ``` +*/ +const test = createTest(function(name, optionsOrFn, optionsOrTest) { + if (getCurrentTest()) { + throw new Error("Calling the test function inside another test function is not allowed. Please put it inside \"describe\" or \"suite\" so it can be properly collected."); + } + getCurrentSuite().test.fn.call(this, formatName(name), optionsOrFn, optionsOrTest); +}); +/** +* Creates a suite of tests, allowing for grouping and hierarchical organization of tests. +* Suites can contain both tests and other suites, enabling complex test structures. +* +* @param {string} name - The name of the suite, used for identification and reporting. +* @param {Function} fn - A function that defines the tests and suites within this suite. +* @example +* ```ts +* // Define a suite with two tests +* describe('Math operations', () => { +* test('should add two numbers', () => { +* expect(add(1, 2)).toBe(3); +* }); +* +* test('should subtract two numbers', () => { +* expect(subtract(5, 2)).toBe(3); +* }); +* }); +* ``` +* @example +* ```ts +* // Define nested suites +* describe('String operations', () => { +* describe('Trimming', () => { +* test('should trim whitespace from start and end', () => { +* expect(' hello '.trim()).toBe('hello'); +* }); +* }); +* +* describe('Concatenation', () => { +* test('should concatenate two strings', () => { +* expect('hello' + ' ' + 'world').toBe('hello world'); +* }); +* }); +* }); +* ``` +*/ +const describe = suite; +/** +* Defines a test case with a given name and test function. The test function can optionally be configured with test options. +* +* @param {string | Function} name - The name of the test or a function that will be used as a test name. +* @param {TestOptions | TestFunction} [optionsOrFn] - Optional. The test options or the test function if no explicit name is provided. +* @param {number | TestOptions | TestFunction} [optionsOrTest] - Optional. The test function or options, depending on the previous parameters. +* @throws {Error} If called inside another test function. +* @example +* ```ts +* // Define a simple test +* it('adds two numbers', () => { +* expect(add(1, 2)).toBe(3); +* }); +* ``` +* @example +* ```ts +* // Define a test with options +* it('subtracts two numbers', { retry: 3 }, () => { +* expect(subtract(5, 2)).toBe(3); +* }); +* ``` +*/ +const it = test; +let runner; +let defaultSuite; +let currentTestFilepath; +function assert(condition, message) { + if (!condition) { + throw new Error(`Vitest failed to find ${message}. This is a bug in Vitest. Please, open an issue with reproduction.`); + } +} +function getDefaultSuite() { + assert(defaultSuite, "the default suite"); + return defaultSuite; +} +function getTestFilepath() { + return currentTestFilepath; +} +function getRunner() { + assert(runner, "the runner"); + return runner; +} +function createDefaultSuite(runner) { + const config = runner.config.sequence; + const collector = suite("", { concurrent: config.concurrent }, () => {}); + // no parent suite for top-level tests + delete collector.suite; + return collector; +} +function clearCollectorContext(filepath, currentRunner) { + if (!defaultSuite) { + defaultSuite = createDefaultSuite(currentRunner); + } + runner = currentRunner; + currentTestFilepath = filepath; + collectorContext.tasks.length = 0; + defaultSuite.clear(); + collectorContext.currentSuite = defaultSuite; +} +function getCurrentSuite() { + const currentSuite = collectorContext.currentSuite || defaultSuite; + assert(currentSuite, "the current suite"); + return currentSuite; +} +function createSuiteHooks() { + return { + beforeAll: [], + afterAll: [], + beforeEach: [], + afterEach: [] + }; +} +function parseArguments(optionsOrFn, optionsOrTest) { + let options = {}; + let fn = () => {}; + // it('', () => {}, { retry: 2 }) + if (typeof optionsOrTest === "object") { + // it('', { retry: 2 }, { retry: 3 }) + if (typeof optionsOrFn === "object") { + throw new TypeError("Cannot use two objects as arguments. Please provide options and a function callback in that order."); + } + console.warn("Using an object as a third argument is deprecated. Vitest 4 will throw an error if the third argument is not a timeout number. Please use the second argument for options. See more at https://vitest.dev/guide/migration"); + options = optionsOrTest; + } else if (typeof optionsOrTest === "number") { + options = { timeout: optionsOrTest }; + } else if (typeof optionsOrFn === "object") { + options = optionsOrFn; + } + if (typeof optionsOrFn === "function") { + if (typeof optionsOrTest === "function") { + throw new TypeError("Cannot use two functions as arguments. Please use the second argument for options."); + } + fn = optionsOrFn; + } else if (typeof optionsOrTest === "function") { + fn = optionsOrTest; + } + return { + options, + handler: fn + }; +} +// implementations +function createSuiteCollector(name, factory = () => {}, mode, each, suiteOptions, parentCollectorFixtures) { + const tasks = []; + let suite; + initSuite(true); + const task = function(name = "", options = {}) { + var _collectorContext$cur; + const timeout = (options === null || options === void 0 ? void 0 : options.timeout) ?? runner.config.testTimeout; + const task = { + id: "", + name, + suite: (_collectorContext$cur = collectorContext.currentSuite) === null || _collectorContext$cur === void 0 ? void 0 : _collectorContext$cur.suite, + each: options.each, + fails: options.fails, + context: undefined, + type: "test", + file: undefined, + timeout, + retry: options.retry ?? runner.config.retry, + repeats: options.repeats, + mode: options.only ? "only" : options.skip ? "skip" : options.todo ? "todo" : "run", + meta: options.meta ?? Object.create(null), + annotations: [] + }; + const handler = options.handler; + if (options.concurrent || !options.sequential && runner.config.sequence.concurrent) { + task.concurrent = true; + } + task.shuffle = suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.shuffle; + const context = createTestContext(task, runner); + // create test context + Object.defineProperty(task, "context", { + value: context, + enumerable: false + }); + setTestFixture(context, options.fixtures); + // custom can be called from any place, let's assume the limit is 15 stacks + const limit = Error.stackTraceLimit; + Error.stackTraceLimit = 15; + const stackTraceError = new Error("STACK_TRACE_ERROR"); + Error.stackTraceLimit = limit; + if (handler) { + setFn(task, withTimeout(withAwaitAsyncAssertions(withFixtures(runner, handler, context), task), timeout, false, stackTraceError, (_, error) => abortIfTimeout([context], error))); + } + if (runner.config.includeTaskLocation) { + const error = stackTraceError.stack; + const stack = findTestFileStackTrace(error); + if (stack) { + task.location = stack; + } + } + tasks.push(task); + return task; + }; + const test = createTest(function(name, optionsOrFn, optionsOrTest) { + let { options, handler } = parseArguments(optionsOrFn, optionsOrTest); + // inherit repeats, retry, timeout from suite + if (typeof suiteOptions === "object") { + options = Object.assign({}, suiteOptions, options); + } + // inherit concurrent / sequential from suite + options.concurrent = this.concurrent || !this.sequential && (options === null || options === void 0 ? void 0 : options.concurrent); + options.sequential = this.sequential || !this.concurrent && (options === null || options === void 0 ? void 0 : options.sequential); + const test = task(formatName(name), { + ...this, + ...options, + handler + }); + test.type = "test"; + }); + let collectorFixtures = parentCollectorFixtures; + const collector = { + type: "collector", + name, + mode, + suite, + options: suiteOptions, + test, + tasks, + collect, + task, + clear, + on: addHook, + fixtures() { + return collectorFixtures; + }, + scoped(fixtures) { + const parsed = mergeContextFixtures(fixtures, { fixtures: collectorFixtures }, runner); + if (parsed.fixtures) { + collectorFixtures = parsed.fixtures; + } + } + }; + function addHook(name, ...fn) { + getHooks(suite)[name].push(...fn); + } + function initSuite(includeLocation) { + var _collectorContext$cur2; + if (typeof suiteOptions === "number") { + suiteOptions = { timeout: suiteOptions }; + } + suite = { + id: "", + type: "suite", + name, + suite: (_collectorContext$cur2 = collectorContext.currentSuite) === null || _collectorContext$cur2 === void 0 ? void 0 : _collectorContext$cur2.suite, + mode, + each, + file: undefined, + shuffle: suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.shuffle, + tasks: [], + meta: Object.create(null), + concurrent: suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.concurrent + }; + if (runner && includeLocation && runner.config.includeTaskLocation) { + const limit = Error.stackTraceLimit; + Error.stackTraceLimit = 15; + const error = new Error("stacktrace").stack; + Error.stackTraceLimit = limit; + const stack = findTestFileStackTrace(error); + if (stack) { + suite.location = stack; + } + } + setHooks(suite, createSuiteHooks()); + } + function clear() { + tasks.length = 0; + initSuite(false); + } + async function collect(file) { + if (!file) { + throw new TypeError("File is required to collect tasks."); + } + if (factory) { + await runWithSuite(collector, () => factory(test)); + } + const allChildren = []; + for (const i of tasks) { + allChildren.push(i.type === "collector" ? await i.collect(file) : i); + } + suite.file = file; + suite.tasks = allChildren; + allChildren.forEach((task) => { + task.file = file; + }); + return suite; + } + collectTask(collector); + return collector; +} +function withAwaitAsyncAssertions(fn, task) { + return async (...args) => { + const fnResult = await fn(...args); + // some async expect will be added to this array, in case user forget to await them + if (task.promises) { + const result = await Promise.allSettled(task.promises); + const errors = result.map((r) => r.status === "rejected" ? r.reason : undefined).filter(Boolean); + if (errors.length) { + throw errors; + } + } + return fnResult; + }; +} +function createSuite() { + function suiteFn(name, factoryOrOptions, optionsOrFactory) { + var _currentSuite$options; + const mode = this.only ? "only" : this.skip ? "skip" : this.todo ? "todo" : "run"; + const currentSuite = collectorContext.currentSuite || defaultSuite; + let { options, handler: factory } = parseArguments(factoryOrOptions, optionsOrFactory); + const isConcurrentSpecified = options.concurrent || this.concurrent || options.sequential === false; + const isSequentialSpecified = options.sequential || this.sequential || options.concurrent === false; + // inherit options from current suite + options = { + ...currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.options, + ...options, + shuffle: this.shuffle ?? options.shuffle ?? (currentSuite === null || currentSuite === void 0 || (_currentSuite$options = currentSuite.options) === null || _currentSuite$options === void 0 ? void 0 : _currentSuite$options.shuffle) ?? (runner === null || runner === void 0 ? void 0 : runner.config.sequence.shuffle) + }; + // inherit concurrent / sequential from suite + const isConcurrent = isConcurrentSpecified || options.concurrent && !isSequentialSpecified; + const isSequential = isSequentialSpecified || options.sequential && !isConcurrentSpecified; + options.concurrent = isConcurrent && !isSequential; + options.sequential = isSequential && !isConcurrent; + return createSuiteCollector(formatName(name), factory, mode, this.each, options, currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.fixtures()); + } + suiteFn.each = function(cases, ...args) { + const suite = this.withContext(); + this.setContext("each", true); + if (Array.isArray(cases) && args.length) { + cases = formatTemplateString(cases, args); + } + return (name, optionsOrFn, fnOrOptions) => { + const _name = formatName(name); + const arrayOnlyCases = cases.every(Array.isArray); + const { options, handler } = parseArguments(optionsOrFn, fnOrOptions); + const fnFirst = typeof optionsOrFn === "function" && typeof fnOrOptions === "object"; + cases.forEach((i, idx) => { + const items = Array.isArray(i) ? i : [i]; + if (fnFirst) { + if (arrayOnlyCases) { + suite(formatTitle(_name, items, idx), () => handler(...items), options); + } else { + suite(formatTitle(_name, items, idx), () => handler(i), options); + } + } else { + if (arrayOnlyCases) { + suite(formatTitle(_name, items, idx), options, () => handler(...items)); + } else { + suite(formatTitle(_name, items, idx), options, () => handler(i)); + } + } + }); + this.setContext("each", undefined); + }; + }; + suiteFn.for = function(cases, ...args) { + if (Array.isArray(cases) && args.length) { + cases = formatTemplateString(cases, args); + } + return (name, optionsOrFn, fnOrOptions) => { + const name_ = formatName(name); + const { options, handler } = parseArguments(optionsOrFn, fnOrOptions); + cases.forEach((item, idx) => { + suite(formatTitle(name_, toArray(item), idx), options, () => handler(item)); + }); + }; + }; + suiteFn.skipIf = (condition) => condition ? suite.skip : suite; + suiteFn.runIf = (condition) => condition ? suite : suite.skip; + return createChainable([ + "concurrent", + "sequential", + "shuffle", + "skip", + "only", + "todo" + ], suiteFn); +} +function createTaskCollector(fn, context) { + const taskFn = fn; + taskFn.each = function(cases, ...args) { + const test = this.withContext(); + this.setContext("each", true); + if (Array.isArray(cases) && args.length) { + cases = formatTemplateString(cases, args); + } + return (name, optionsOrFn, fnOrOptions) => { + const _name = formatName(name); + const arrayOnlyCases = cases.every(Array.isArray); + const { options, handler } = parseArguments(optionsOrFn, fnOrOptions); + const fnFirst = typeof optionsOrFn === "function" && typeof fnOrOptions === "object"; + cases.forEach((i, idx) => { + const items = Array.isArray(i) ? i : [i]; + if (fnFirst) { + if (arrayOnlyCases) { + test(formatTitle(_name, items, idx), () => handler(...items), options); + } else { + test(formatTitle(_name, items, idx), () => handler(i), options); + } + } else { + if (arrayOnlyCases) { + test(formatTitle(_name, items, idx), options, () => handler(...items)); + } else { + test(formatTitle(_name, items, idx), options, () => handler(i)); + } + } + }); + this.setContext("each", undefined); + }; + }; + taskFn.for = function(cases, ...args) { + const test = this.withContext(); + if (Array.isArray(cases) && args.length) { + cases = formatTemplateString(cases, args); + } + return (name, optionsOrFn, fnOrOptions) => { + const _name = formatName(name); + const { options, handler } = parseArguments(optionsOrFn, fnOrOptions); + cases.forEach((item, idx) => { + // monkey-patch handler to allow parsing fixture + const handlerWrapper = (ctx) => handler(item, ctx); + handlerWrapper.__VITEST_FIXTURE_INDEX__ = 1; + handlerWrapper.toString = () => handler.toString(); + test(formatTitle(_name, toArray(item), idx), options, handlerWrapper); + }); + }; + }; + taskFn.skipIf = function(condition) { + return condition ? this.skip : this; + }; + taskFn.runIf = function(condition) { + return condition ? this : this.skip; + }; + taskFn.scoped = function(fixtures) { + const collector = getCurrentSuite(); + collector.scoped(fixtures); + }; + taskFn.extend = function(fixtures) { + const _context = mergeContextFixtures(fixtures, context || {}, runner); + const originalWrapper = fn; + return createTest(function(name, optionsOrFn, optionsOrTest) { + const collector = getCurrentSuite(); + const scopedFixtures = collector.fixtures(); + const context = { ...this }; + if (scopedFixtures) { + context.fixtures = mergeScopedFixtures(context.fixtures || [], scopedFixtures); + } + const { handler, options } = parseArguments(optionsOrFn, optionsOrTest); + const timeout = options.timeout ?? (runner === null || runner === void 0 ? void 0 : runner.config.testTimeout); + originalWrapper.call(context, formatName(name), handler, timeout); + }, _context); + }; + const _test = createChainable([ + "concurrent", + "sequential", + "skip", + "only", + "todo", + "fails" + ], taskFn); + if (context) { + _test.mergeContext(context); + } + return _test; +} +function createTest(fn, context) { + return createTaskCollector(fn, context); +} +function formatName(name) { + return typeof name === "string" ? name : typeof name === "function" ? name.name || "" : String(name); +} +function formatTitle(template, items, idx) { + if (template.includes("%#") || template.includes("%$")) { + // '%#' match index of the test case + template = template.replace(/%%/g, "__vitest_escaped_%__").replace(/%#/g, `${idx}`).replace(/%\$/g, `${idx + 1}`).replace(/__vitest_escaped_%__/g, "%%"); + } + const count = template.split("%").length - 1; + if (template.includes("%f")) { + const placeholders = template.match(/%f/g) || []; + placeholders.forEach((_, i) => { + if (isNegativeNaN(items[i]) || Object.is(items[i], -0)) { + // Replace the i-th occurrence of '%f' with '-%f' + let occurrence = 0; + template = template.replace(/%f/g, (match) => { + occurrence++; + return occurrence === i + 1 ? "-%f" : match; + }); + } + }); + } + let formatted = format(template, ...items.slice(0, count)); + const isObjectItem = isObject(items[0]); + formatted = formatted.replace(/\$([$\w.]+)/g, (_, key) => { + var _runner$config; + const isArrayKey = /^\d+$/.test(key); + if (!isObjectItem && !isArrayKey) { + return `$${key}`; + } + const arrayElement = isArrayKey ? objectAttr(items, key) : undefined; + const value = isObjectItem ? objectAttr(items[0], key, arrayElement) : arrayElement; + return objDisplay(value, { truncate: runner === null || runner === void 0 || (_runner$config = runner.config) === null || _runner$config === void 0 || (_runner$config = _runner$config.chaiConfig) === null || _runner$config === void 0 ? void 0 : _runner$config.truncateThreshold }); + }); + return formatted; +} +function formatTemplateString(cases, args) { + const header = cases.join("").trim().replace(/ /g, "").split("\n").map((i) => i.split("|"))[0]; + const res = []; + for (let i = 0; i < Math.floor(args.length / header.length); i++) { + const oneCase = {}; + for (let j = 0; j < header.length; j++) { + oneCase[header[j]] = args[i * header.length + j]; + } + res.push(oneCase); + } + return res; +} +function findTestFileStackTrace(error) { + const testFilePath = getTestFilepath(); + // first line is the error message + const lines = error.split("\n").slice(1); + for (const line of lines) { + const stack = parseSingleStack(line); + if (stack && stack.file === testFilePath) { + return { + line: stack.line, + column: stack.column + }; + } + } +} + +/** +* If any tasks been marked as `only`, mark all other tasks as `skip`. +*/ +function interpretTaskModes(file, namePattern, testLocations, onlyMode, parentIsOnly, allowOnly) { + const matchedLocations = []; + const traverseSuite = (suite, parentIsOnly, parentMatchedWithLocation) => { + const suiteIsOnly = parentIsOnly || suite.mode === "only"; + suite.tasks.forEach((t) => { + // Check if either the parent suite or the task itself are marked as included + const includeTask = suiteIsOnly || t.mode === "only"; + if (onlyMode) { + if (t.type === "suite" && (includeTask || someTasksAreOnly(t))) { + // Don't skip this suite + if (t.mode === "only") { + checkAllowOnly(t, allowOnly); + t.mode = "run"; + } + } else if (t.mode === "run" && !includeTask) { + t.mode = "skip"; + } else if (t.mode === "only") { + checkAllowOnly(t, allowOnly); + t.mode = "run"; + } + } + let hasLocationMatch = parentMatchedWithLocation; + // Match test location against provided locations, only run if present + // in `testLocations`. Note: if `includeTaskLocations` is not enabled, + // all test will be skipped. + if (testLocations !== undefined && testLocations.length !== 0) { + if (t.location && (testLocations === null || testLocations === void 0 ? void 0 : testLocations.includes(t.location.line))) { + t.mode = "run"; + matchedLocations.push(t.location.line); + hasLocationMatch = true; + } else if (parentMatchedWithLocation) { + t.mode = "run"; + } else if (t.type === "test") { + t.mode = "skip"; + } + } + if (t.type === "test") { + if (namePattern && !getTaskFullName(t).match(namePattern)) { + t.mode = "skip"; + } + } else if (t.type === "suite") { + if (t.mode === "skip") { + skipAllTasks(t); + } else if (t.mode === "todo") { + todoAllTasks(t); + } else { + traverseSuite(t, includeTask, hasLocationMatch); + } + } + }); + // if all subtasks are skipped, mark as skip + if (suite.mode === "run" || suite.mode === "queued") { + if (suite.tasks.length && suite.tasks.every((i) => i.mode !== "run" && i.mode !== "queued")) { + suite.mode = "skip"; + } + } + }; + traverseSuite(file, parentIsOnly, false); + const nonMatching = testLocations === null || testLocations === void 0 ? void 0 : testLocations.filter((loc) => !matchedLocations.includes(loc)); + if (nonMatching && nonMatching.length !== 0) { + const message = nonMatching.length === 1 ? `line ${nonMatching[0]}` : `lines ${nonMatching.join(", ")}`; + if (file.result === undefined) { + file.result = { + state: "fail", + errors: [] + }; + } + if (file.result.errors === undefined) { + file.result.errors = []; + } + file.result.errors.push(processError(new Error(`No test found in ${file.name} in ${message}`))); + } +} +function getTaskFullName(task) { + return `${task.suite ? `${getTaskFullName(task.suite)} ` : ""}${task.name}`; +} +function someTasksAreOnly(suite) { + return suite.tasks.some((t) => t.mode === "only" || t.type === "suite" && someTasksAreOnly(t)); +} +function skipAllTasks(suite) { + suite.tasks.forEach((t) => { + if (t.mode === "run" || t.mode === "queued") { + t.mode = "skip"; + if (t.type === "suite") { + skipAllTasks(t); + } + } + }); +} +function todoAllTasks(suite) { + suite.tasks.forEach((t) => { + if (t.mode === "run" || t.mode === "queued") { + t.mode = "todo"; + if (t.type === "suite") { + todoAllTasks(t); + } + } + }); +} +function checkAllowOnly(task, allowOnly) { + if (allowOnly) { + return; + } + const error = processError(new Error("[Vitest] Unexpected .only modifier. Remove it or pass --allowOnly argument to bypass this error")); + task.result = { + state: "fail", + errors: [error] + }; +} +function generateHash(str) { + let hash = 0; + if (str.length === 0) { + return `${hash}`; + } + for (let i = 0; i < str.length; i++) { + const char = str.charCodeAt(i); + hash = (hash << 5) - hash + char; + hash = hash & hash; + } + return `${hash}`; +} +function calculateSuiteHash(parent) { + parent.tasks.forEach((t, idx) => { + t.id = `${parent.id}_${idx}`; + if (t.type === "suite") { + calculateSuiteHash(t); + } + }); +} +function createFileTask(filepath, root, projectName, pool) { + const path = relative(root, filepath); + const file = { + id: generateFileHash(path, projectName), + name: path, + type: "suite", + mode: "queued", + filepath, + tasks: [], + meta: Object.create(null), + projectName, + file: undefined, + pool + }; + file.file = file; + setFileContext(file, Object.create(null)); + return file; +} +/** +* Generate a unique ID for a file based on its path and project name +* @param file File relative to the root of the project to keep ID the same between different machines +* @param projectName The name of the test project +*/ +function generateFileHash(file, projectName) { + return generateHash(`${file}${projectName || ""}`); +} + +const now$2 = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now; +async function collectTests(specs, runner) { + const files = []; + const config = runner.config; + for (const spec of specs) { + var _runner$onCollectStar; + const filepath = typeof spec === "string" ? spec : spec.filepath; + const testLocations = typeof spec === "string" ? undefined : spec.testLocations; + const file = createFileTask(filepath, config.root, config.name, runner.pool); + file.shuffle = config.sequence.shuffle; + (_runner$onCollectStar = runner.onCollectStart) === null || _runner$onCollectStar === void 0 ? void 0 : _runner$onCollectStar.call(runner, file); + clearCollectorContext(filepath, runner); + try { + var _runner$getImportDura; + const setupFiles = toArray(config.setupFiles); + if (setupFiles.length) { + const setupStart = now$2(); + await runSetupFiles(config, setupFiles, runner); + const setupEnd = now$2(); + file.setupDuration = setupEnd - setupStart; + } else { + file.setupDuration = 0; + } + const collectStart = now$2(); + await runner.importFile(filepath, "collect"); + const durations = (_runner$getImportDura = runner.getImportDurations) === null || _runner$getImportDura === void 0 ? void 0 : _runner$getImportDura.call(runner); + if (durations) { + file.importDurations = durations; + } + const defaultTasks = await getDefaultSuite().collect(file); + const fileHooks = createSuiteHooks(); + mergeHooks(fileHooks, getHooks(defaultTasks)); + for (const c of [...defaultTasks.tasks, ...collectorContext.tasks]) { + if (c.type === "test" || c.type === "suite") { + file.tasks.push(c); + } else if (c.type === "collector") { + const suite = await c.collect(file); + if (suite.name || suite.tasks.length) { + mergeHooks(fileHooks, getHooks(suite)); + file.tasks.push(suite); + } + } else { + // check that types are exhausted + c; + } + } + setHooks(file, fileHooks); + file.collectDuration = now$2() - collectStart; + } catch (e) { + var _runner$getImportDura2; + const error = processError(e); + file.result = { + state: "fail", + errors: [error] + }; + const durations = (_runner$getImportDura2 = runner.getImportDurations) === null || _runner$getImportDura2 === void 0 ? void 0 : _runner$getImportDura2.call(runner); + if (durations) { + file.importDurations = durations; + } + } + calculateSuiteHash(file); + const hasOnlyTasks = someTasksAreOnly(file); + interpretTaskModes(file, config.testNamePattern, testLocations, hasOnlyTasks, false, config.allowOnly); + if (file.mode === "queued") { + file.mode = "run"; + } + files.push(file); + } + return files; +} +function mergeHooks(baseHooks, hooks) { + for (const _key in hooks) { + const key = _key; + baseHooks[key].push(...hooks[key]); + } + return baseHooks; +} + +/** +* Return a function for running multiple async operations with limited concurrency. +*/ +function limitConcurrency(concurrency = Infinity) { + // The number of currently active + pending tasks. + let count = 0; + // The head and tail of the pending task queue, built using a singly linked list. + // Both head and tail are initially undefined, signifying an empty queue. + // They both become undefined again whenever there are no pending tasks. + let head; + let tail; + // A bookkeeping function executed whenever a task has been run to completion. + const finish = () => { + count--; + // Check if there are further pending tasks in the queue. + if (head) { + // Allow the next pending task to run and pop it from the queue. + head[0](); + head = head[1]; + // The head may now be undefined if there are no further pending tasks. + // In that case, set tail to undefined as well. + tail = head && tail; + } + }; + return (func, ...args) => { + // Create a promise chain that: + // 1. Waits for its turn in the task queue (if necessary). + // 2. Runs the task. + // 3. Allows the next pending task (if any) to run. + return new Promise((resolve) => { + if (count++ < concurrency) { + // No need to queue if fewer than maxConcurrency tasks are running. + resolve(); + } else if (tail) { + // There are pending tasks, so append to the queue. + tail = tail[1] = [resolve]; + } else { + // No other pending tasks, initialize the queue with a new tail and head. + head = tail = [resolve]; + } + }).then(() => { + // Running func here ensures that even a non-thenable result or an + // immediately thrown error gets wrapped into a Promise. + return func(...args); + }).finally(finish); + }; +} + +/** +* Partition in tasks groups by consecutive concurrent +*/ +function partitionSuiteChildren(suite) { + let tasksGroup = []; + const tasksGroups = []; + for (const c of suite.tasks) { + if (tasksGroup.length === 0 || c.concurrent === tasksGroup[0].concurrent) { + tasksGroup.push(c); + } else { + tasksGroups.push(tasksGroup); + tasksGroup = [c]; + } + } + if (tasksGroup.length > 0) { + tasksGroups.push(tasksGroup); + } + return tasksGroups; +} + +/** +* @deprecated use `isTestCase` instead +*/ +function isAtomTest(s) { + return isTestCase(s); +} +function isTestCase(s) { + return s.type === "test"; +} +function getTests(suite) { + const tests = []; + const arraySuites = toArray(suite); + for (const s of arraySuites) { + if (isTestCase(s)) { + tests.push(s); + } else { + for (const task of s.tasks) { + if (isTestCase(task)) { + tests.push(task); + } else { + const taskTests = getTests(task); + for (const test of taskTests) { + tests.push(test); + } + } + } + } + } + return tests; +} +function getTasks(tasks = []) { + return toArray(tasks).flatMap((s) => isTestCase(s) ? [s] : [s, ...getTasks(s.tasks)]); +} +function getSuites(suite) { + return toArray(suite).flatMap((s) => s.type === "suite" ? [s, ...getSuites(s.tasks)] : []); +} +function hasTests(suite) { + return toArray(suite).some((s) => s.tasks.some((c) => isTestCase(c) || hasTests(c))); +} +function hasFailed(suite) { + return toArray(suite).some((s) => { + var _s$result; + return ((_s$result = s.result) === null || _s$result === void 0 ? void 0 : _s$result.state) === "fail" || s.type === "suite" && hasFailed(s.tasks); + }); +} +function getNames(task) { + const names = [task.name]; + let current = task; + while (current === null || current === void 0 ? void 0 : current.suite) { + current = current.suite; + if (current === null || current === void 0 ? void 0 : current.name) { + names.unshift(current.name); + } + } + if (current !== task.file) { + names.unshift(task.file.name); + } + return names; +} +function getFullName(task, separator = " > ") { + return getNames(task).join(separator); +} +function getTestName(task, separator = " > ") { + return getNames(task).slice(1).join(separator); +} + +const now$1 = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now; +const unixNow = Date.now; +const { clearTimeout, setTimeout } = getSafeTimers(); +function updateSuiteHookState(task, name, state, runner) { + if (!task.result) { + task.result = { state: "run" }; + } + if (!task.result.hooks) { + task.result.hooks = {}; + } + const suiteHooks = task.result.hooks; + if (suiteHooks) { + suiteHooks[name] = state; + let event = state === "run" ? "before-hook-start" : "before-hook-end"; + if (name === "afterAll" || name === "afterEach") { + event = state === "run" ? "after-hook-start" : "after-hook-end"; + } + updateTask(event, task, runner); + } +} +function getSuiteHooks(suite, name, sequence) { + const hooks = getHooks(suite)[name]; + if (sequence === "stack" && (name === "afterAll" || name === "afterEach")) { + return hooks.slice().reverse(); + } + return hooks; +} +async function callTestHooks(runner, test, hooks, sequence) { + if (sequence === "stack") { + hooks = hooks.slice().reverse(); + } + if (!hooks.length) { + return; + } + const context = test.context; + const onTestFailed = test.context.onTestFailed; + const onTestFinished = test.context.onTestFinished; + context.onTestFailed = () => { + throw new Error(`Cannot call "onTestFailed" inside a test hook.`); + }; + context.onTestFinished = () => { + throw new Error(`Cannot call "onTestFinished" inside a test hook.`); + }; + if (sequence === "parallel") { + try { + await Promise.all(hooks.map((fn) => fn(test.context))); + } catch (e) { + failTask(test.result, e, runner.config.diffOptions); + } + } else { + for (const fn of hooks) { + try { + await fn(test.context); + } catch (e) { + failTask(test.result, e, runner.config.diffOptions); + } + } + } + context.onTestFailed = onTestFailed; + context.onTestFinished = onTestFinished; +} +async function callSuiteHook(suite, currentTask, name, runner, args) { + const sequence = runner.config.sequence.hooks; + const callbacks = []; + // stop at file level + const parentSuite = "filepath" in suite ? null : suite.suite || suite.file; + if (name === "beforeEach" && parentSuite) { + callbacks.push(...await callSuiteHook(parentSuite, currentTask, name, runner, args)); + } + const hooks = getSuiteHooks(suite, name, sequence); + if (hooks.length > 0) { + updateSuiteHookState(currentTask, name, "run", runner); + } + async function runHook(hook) { + return getBeforeHookCleanupCallback(hook, await hook(...args), name === "beforeEach" ? args[0] : undefined); + } + if (sequence === "parallel") { + callbacks.push(...await Promise.all(hooks.map((hook) => runHook(hook)))); + } else { + for (const hook of hooks) { + callbacks.push(await runHook(hook)); + } + } + if (hooks.length > 0) { + updateSuiteHookState(currentTask, name, "pass", runner); + } + if (name === "afterEach" && parentSuite) { + callbacks.push(...await callSuiteHook(parentSuite, currentTask, name, runner, args)); + } + return callbacks; +} +const packs = new Map(); +const eventsPacks = []; +const pendingTasksUpdates = []; +function sendTasksUpdate(runner) { + if (packs.size) { + var _runner$onTaskUpdate; + const taskPacks = Array.from(packs).map(([id, task]) => { + return [ + id, + task[0], + task[1] + ]; + }); + const p = (_runner$onTaskUpdate = runner.onTaskUpdate) === null || _runner$onTaskUpdate === void 0 ? void 0 : _runner$onTaskUpdate.call(runner, taskPacks, eventsPacks); + if (p) { + pendingTasksUpdates.push(p); + // remove successful promise to not grow array indefnitely, + // but keep rejections so finishSendTasksUpdate can handle them + p.then(() => pendingTasksUpdates.splice(pendingTasksUpdates.indexOf(p), 1), () => {}); + } + eventsPacks.length = 0; + packs.clear(); + } +} +async function finishSendTasksUpdate(runner) { + sendTasksUpdate(runner); + await Promise.all(pendingTasksUpdates); +} +function throttle(fn, ms) { + let last = 0; + let pendingCall; + return function call(...args) { + const now = unixNow(); + if (now - last > ms) { + last = now; + clearTimeout(pendingCall); + pendingCall = undefined; + return fn.apply(this, args); + } + // Make sure fn is still called even if there are no further calls + pendingCall ?? (pendingCall = setTimeout(() => call.bind(this)(...args), ms)); + }; +} +// throttle based on summary reporter's DURATION_UPDATE_INTERVAL_MS +const sendTasksUpdateThrottled = throttle(sendTasksUpdate, 100); +function updateTask(event, task, runner) { + eventsPacks.push([ + task.id, + event, + undefined + ]); + packs.set(task.id, [task.result, task.meta]); + sendTasksUpdateThrottled(runner); +} +async function callCleanupHooks(runner, cleanups) { + const sequence = runner.config.sequence.hooks; + if (sequence === "stack") { + cleanups = cleanups.slice().reverse(); + } + if (sequence === "parallel") { + await Promise.all(cleanups.map(async (fn) => { + if (typeof fn !== "function") { + return; + } + await fn(); + })); + } else { + for (const fn of cleanups) { + if (typeof fn !== "function") { + continue; + } + await fn(); + } + } +} +async function runTest(test, runner) { + var _runner$onBeforeRunTa, _test$result, _runner$onAfterRunTas; + await ((_runner$onBeforeRunTa = runner.onBeforeRunTask) === null || _runner$onBeforeRunTa === void 0 ? void 0 : _runner$onBeforeRunTa.call(runner, test)); + if (test.mode !== "run" && test.mode !== "queued") { + updateTask("test-prepare", test, runner); + updateTask("test-finished", test, runner); + return; + } + if (((_test$result = test.result) === null || _test$result === void 0 ? void 0 : _test$result.state) === "fail") { + // should not be possible to get here, I think this is just copy pasted from suite + // TODO: maybe someone fails tests in `beforeAll` hooks? + // https://github.com/vitest-dev/vitest/pull/7069 + updateTask("test-failed-early", test, runner); + return; + } + const start = now$1(); + test.result = { + state: "run", + startTime: unixNow(), + retryCount: 0 + }; + updateTask("test-prepare", test, runner); + const cleanupRunningTest = addRunningTest(test); + setCurrentTest(test); + const suite = test.suite || test.file; + const repeats = test.repeats ?? 0; + for (let repeatCount = 0; repeatCount <= repeats; repeatCount++) { + const retry = test.retry ?? 0; + for (let retryCount = 0; retryCount <= retry; retryCount++) { + var _test$result2, _test$result3; + let beforeEachCleanups = []; + try { + var _runner$onBeforeTryTa, _runner$onAfterTryTas; + await ((_runner$onBeforeTryTa = runner.onBeforeTryTask) === null || _runner$onBeforeTryTa === void 0 ? void 0 : _runner$onBeforeTryTa.call(runner, test, { + retry: retryCount, + repeats: repeatCount + })); + test.result.repeatCount = repeatCount; + beforeEachCleanups = await callSuiteHook(suite, test, "beforeEach", runner, [test.context, suite]); + if (runner.runTask) { + await runner.runTask(test); + } else { + const fn = getFn(test); + if (!fn) { + throw new Error("Test function is not found. Did you add it using `setFn`?"); + } + await fn(); + } + await ((_runner$onAfterTryTas = runner.onAfterTryTask) === null || _runner$onAfterTryTas === void 0 ? void 0 : _runner$onAfterTryTas.call(runner, test, { + retry: retryCount, + repeats: repeatCount + })); + if (test.result.state !== "fail") { + if (!test.repeats) { + test.result.state = "pass"; + } else if (test.repeats && retry === retryCount) { + test.result.state = "pass"; + } + } + } catch (e) { + failTask(test.result, e, runner.config.diffOptions); + } + try { + var _runner$onTaskFinishe; + await ((_runner$onTaskFinishe = runner.onTaskFinished) === null || _runner$onTaskFinishe === void 0 ? void 0 : _runner$onTaskFinishe.call(runner, test)); + } catch (e) { + failTask(test.result, e, runner.config.diffOptions); + } + try { + await callSuiteHook(suite, test, "afterEach", runner, [test.context, suite]); + await callCleanupHooks(runner, beforeEachCleanups); + await callFixtureCleanup(test.context); + } catch (e) { + failTask(test.result, e, runner.config.diffOptions); + } + await callTestHooks(runner, test, test.onFinished || [], "stack"); + if (test.result.state === "fail") { + await callTestHooks(runner, test, test.onFailed || [], runner.config.sequence.hooks); + } + test.onFailed = undefined; + test.onFinished = undefined; + // skipped with new PendingError + if (((_test$result2 = test.result) === null || _test$result2 === void 0 ? void 0 : _test$result2.pending) || ((_test$result3 = test.result) === null || _test$result3 === void 0 ? void 0 : _test$result3.state) === "skip") { + var _test$result4; + test.mode = "skip"; + test.result = { + state: "skip", + note: (_test$result4 = test.result) === null || _test$result4 === void 0 ? void 0 : _test$result4.note, + pending: true, + duration: now$1() - start + }; + updateTask("test-finished", test, runner); + setCurrentTest(undefined); + cleanupRunningTest(); + return; + } + if (test.result.state === "pass") { + break; + } + if (retryCount < retry) { + // reset state when retry test + test.result.state = "run"; + test.result.retryCount = (test.result.retryCount ?? 0) + 1; + } + // update retry info + updateTask("test-retried", test, runner); + } + } + // if test is marked to be failed, flip the result + if (test.fails) { + if (test.result.state === "pass") { + const error = processError(new Error("Expect test to fail")); + test.result.state = "fail"; + test.result.errors = [error]; + } else { + test.result.state = "pass"; + test.result.errors = undefined; + } + } + cleanupRunningTest(); + setCurrentTest(undefined); + test.result.duration = now$1() - start; + await ((_runner$onAfterRunTas = runner.onAfterRunTask) === null || _runner$onAfterRunTas === void 0 ? void 0 : _runner$onAfterRunTas.call(runner, test)); + updateTask("test-finished", test, runner); +} +function failTask(result, err, diffOptions) { + if (err instanceof PendingError) { + result.state = "skip"; + result.note = err.note; + result.pending = true; + return; + } + result.state = "fail"; + const errors = Array.isArray(err) ? err : [err]; + for (const e of errors) { + const error = processError(e, diffOptions); + result.errors ?? (result.errors = []); + result.errors.push(error); + } +} +function markTasksAsSkipped(suite, runner) { + suite.tasks.forEach((t) => { + t.mode = "skip"; + t.result = { + ...t.result, + state: "skip" + }; + updateTask("test-finished", t, runner); + if (t.type === "suite") { + markTasksAsSkipped(t, runner); + } + }); +} +async function runSuite(suite, runner) { + var _runner$onBeforeRunSu, _suite$result; + await ((_runner$onBeforeRunSu = runner.onBeforeRunSuite) === null || _runner$onBeforeRunSu === void 0 ? void 0 : _runner$onBeforeRunSu.call(runner, suite)); + if (((_suite$result = suite.result) === null || _suite$result === void 0 ? void 0 : _suite$result.state) === "fail") { + markTasksAsSkipped(suite, runner); + // failed during collection + updateTask("suite-failed-early", suite, runner); + return; + } + const start = now$1(); + const mode = suite.mode; + suite.result = { + state: mode === "skip" || mode === "todo" ? mode : "run", + startTime: unixNow() + }; + updateTask("suite-prepare", suite, runner); + let beforeAllCleanups = []; + if (suite.mode === "skip") { + suite.result.state = "skip"; + updateTask("suite-finished", suite, runner); + } else if (suite.mode === "todo") { + suite.result.state = "todo"; + updateTask("suite-finished", suite, runner); + } else { + var _runner$onAfterRunSui; + try { + try { + beforeAllCleanups = await callSuiteHook(suite, suite, "beforeAll", runner, [suite]); + } catch (e) { + markTasksAsSkipped(suite, runner); + throw e; + } + if (runner.runSuite) { + await runner.runSuite(suite); + } else { + for (let tasksGroup of partitionSuiteChildren(suite)) { + if (tasksGroup[0].concurrent === true) { + await Promise.all(tasksGroup.map((c) => runSuiteChild(c, runner))); + } else { + const { sequence } = runner.config; + if (suite.shuffle) { + // run describe block independently from tests + const suites = tasksGroup.filter((group) => group.type === "suite"); + const tests = tasksGroup.filter((group) => group.type === "test"); + const groups = shuffle([suites, tests], sequence.seed); + tasksGroup = groups.flatMap((group) => shuffle(group, sequence.seed)); + } + for (const c of tasksGroup) { + await runSuiteChild(c, runner); + } + } + } + } + } catch (e) { + failTask(suite.result, e, runner.config.diffOptions); + } + try { + await callSuiteHook(suite, suite, "afterAll", runner, [suite]); + await callCleanupHooks(runner, beforeAllCleanups); + if (suite.file === suite) { + const context = getFileContext(suite); + await callFixtureCleanup(context); + } + } catch (e) { + failTask(suite.result, e, runner.config.diffOptions); + } + if (suite.mode === "run" || suite.mode === "queued") { + if (!runner.config.passWithNoTests && !hasTests(suite)) { + var _suite$result$errors; + suite.result.state = "fail"; + if (!((_suite$result$errors = suite.result.errors) === null || _suite$result$errors === void 0 ? void 0 : _suite$result$errors.length)) { + const error = processError(new Error(`No test found in suite ${suite.name}`)); + suite.result.errors = [error]; + } + } else if (hasFailed(suite)) { + suite.result.state = "fail"; + } else { + suite.result.state = "pass"; + } + } + suite.result.duration = now$1() - start; + updateTask("suite-finished", suite, runner); + await ((_runner$onAfterRunSui = runner.onAfterRunSuite) === null || _runner$onAfterRunSui === void 0 ? void 0 : _runner$onAfterRunSui.call(runner, suite)); + } +} +let limitMaxConcurrency; +async function runSuiteChild(c, runner) { + if (c.type === "test") { + return limitMaxConcurrency(() => runTest(c, runner)); + } else if (c.type === "suite") { + return runSuite(c, runner); + } +} +async function runFiles(files, runner) { + limitMaxConcurrency ?? (limitMaxConcurrency = limitConcurrency(runner.config.maxConcurrency)); + for (const file of files) { + if (!file.tasks.length && !runner.config.passWithNoTests) { + var _file$result; + if (!((_file$result = file.result) === null || _file$result === void 0 || (_file$result = _file$result.errors) === null || _file$result === void 0 ? void 0 : _file$result.length)) { + const error = processError(new Error(`No test suite found in file ${file.filepath}`)); + file.result = { + state: "fail", + errors: [error] + }; + } + } + await runSuite(file, runner); + } +} +const workerRunners = new WeakSet(); +async function startTests(specs, runner) { + var _runner$cancel; + const cancel = (_runner$cancel = runner.cancel) === null || _runner$cancel === void 0 ? void 0 : _runner$cancel.bind(runner); + // Ideally, we need to have an event listener for this, but only have a runner here. + // Adding another onCancel felt wrong (maybe it needs to be refactored) + runner.cancel = (reason) => { + // We intentionally create only one error since there is only one test run that can be cancelled + const error = new TestRunAbortError("The test run was aborted by the user.", reason); + getRunningTests().forEach((test) => abortContextSignal(test.context, error)); + return cancel === null || cancel === void 0 ? void 0 : cancel(reason); + }; + if (!workerRunners.has(runner)) { + var _runner$onCleanupWork; + (_runner$onCleanupWork = runner.onCleanupWorkerContext) === null || _runner$onCleanupWork === void 0 ? void 0 : _runner$onCleanupWork.call(runner, async () => { + var _runner$getWorkerCont; + const context = (_runner$getWorkerCont = runner.getWorkerContext) === null || _runner$getWorkerCont === void 0 ? void 0 : _runner$getWorkerCont.call(runner); + if (context) { + await callFixtureCleanup(context); + } + }); + workerRunners.add(runner); + } + try { + var _runner$onBeforeColle, _runner$onCollected, _runner$onBeforeRunFi, _runner$onAfterRunFil; + const paths = specs.map((f) => typeof f === "string" ? f : f.filepath); + await ((_runner$onBeforeColle = runner.onBeforeCollect) === null || _runner$onBeforeColle === void 0 ? void 0 : _runner$onBeforeColle.call(runner, paths)); + const files = await collectTests(specs, runner); + await ((_runner$onCollected = runner.onCollected) === null || _runner$onCollected === void 0 ? void 0 : _runner$onCollected.call(runner, files)); + await ((_runner$onBeforeRunFi = runner.onBeforeRunFiles) === null || _runner$onBeforeRunFi === void 0 ? void 0 : _runner$onBeforeRunFi.call(runner, files)); + await runFiles(files, runner); + await ((_runner$onAfterRunFil = runner.onAfterRunFiles) === null || _runner$onAfterRunFil === void 0 ? void 0 : _runner$onAfterRunFil.call(runner, files)); + await finishSendTasksUpdate(runner); + return files; + } finally { + runner.cancel = cancel; + } +} +async function publicCollect(specs, runner) { + var _runner$onBeforeColle2, _runner$onCollected2; + const paths = specs.map((f) => typeof f === "string" ? f : f.filepath); + await ((_runner$onBeforeColle2 = runner.onBeforeCollect) === null || _runner$onBeforeColle2 === void 0 ? void 0 : _runner$onBeforeColle2.call(runner, paths)); + const files = await collectTests(specs, runner); + await ((_runner$onCollected2 = runner.onCollected) === null || _runner$onCollected2 === void 0 ? void 0 : _runner$onCollected2.call(runner, files)); + return files; +} + +const now = Date.now; +const collectorContext = { + tasks: [], + currentSuite: null +}; +function collectTask(task) { + var _collectorContext$cur; + (_collectorContext$cur = collectorContext.currentSuite) === null || _collectorContext$cur === void 0 ? void 0 : _collectorContext$cur.tasks.push(task); +} +async function runWithSuite(suite, fn) { + const prev = collectorContext.currentSuite; + collectorContext.currentSuite = suite; + await fn(); + collectorContext.currentSuite = prev; +} +function withTimeout(fn, timeout, isHook = false, stackTraceError, onTimeout) { + if (timeout <= 0 || timeout === Number.POSITIVE_INFINITY) { + return fn; + } + const { setTimeout, clearTimeout } = getSafeTimers(); + // this function name is used to filter error in test/cli/test/fails.test.ts + return function runWithTimeout(...args) { + const startTime = now(); + const runner = getRunner(); + runner._currentTaskStartTime = startTime; + runner._currentTaskTimeout = timeout; + return new Promise((resolve_, reject_) => { + var _timer$unref; + const timer = setTimeout(() => { + clearTimeout(timer); + rejectTimeoutError(); + }, timeout); + // `unref` might not exist in browser + (_timer$unref = timer.unref) === null || _timer$unref === void 0 ? void 0 : _timer$unref.call(timer); + function rejectTimeoutError() { + const error = makeTimeoutError(isHook, timeout, stackTraceError); + onTimeout === null || onTimeout === void 0 ? void 0 : onTimeout(args, error); + reject_(error); + } + function resolve(result) { + runner._currentTaskStartTime = undefined; + runner._currentTaskTimeout = undefined; + clearTimeout(timer); + // if test/hook took too long in microtask, setTimeout won't be triggered, + // but we still need to fail the test, see + // https://github.com/vitest-dev/vitest/issues/2920 + if (now() - startTime >= timeout) { + rejectTimeoutError(); + return; + } + resolve_(result); + } + function reject(error) { + runner._currentTaskStartTime = undefined; + runner._currentTaskTimeout = undefined; + clearTimeout(timer); + reject_(error); + } + // sync test/hook will be caught by try/catch + try { + const result = fn(...args); + // the result is a thenable, we don't wrap this in Promise.resolve + // to avoid creating new promises + if (typeof result === "object" && result != null && typeof result.then === "function") { + result.then(resolve, reject); + } else { + resolve(result); + } + } + // user sync test/hook throws an error +catch (error) { + reject(error); + } + }); + }; +} +const abortControllers = new WeakMap(); +function abortIfTimeout([context], error) { + if (context) { + abortContextSignal(context, error); + } +} +function abortContextSignal(context, error) { + const abortController = abortControllers.get(context); + abortController === null || abortController === void 0 ? void 0 : abortController.abort(error); +} +function createTestContext(test, runner) { + var _runner$extendTaskCon; + const context = function() { + throw new Error("done() callback is deprecated, use promise instead"); + }; + let abortController = abortControllers.get(context); + if (!abortController) { + abortController = new AbortController(); + abortControllers.set(context, abortController); + } + context.signal = abortController.signal; + context.task = test; + context.skip = (condition, note) => { + if (condition === false) { + // do nothing + return undefined; + } + test.result ?? (test.result = { state: "skip" }); + test.result.pending = true; + throw new PendingError("test is skipped; abort execution", test, typeof condition === "string" ? condition : note); + }; + async function annotate(message, location, type, attachment) { + const annotation = { + message, + type: type || "notice" + }; + if (attachment) { + if (!attachment.body && !attachment.path) { + throw new TypeError(`Test attachment requires body or path to be set. Both are missing.`); + } + if (attachment.body && attachment.path) { + throw new TypeError(`Test attachment requires only one of "body" or "path" to be set. Both are specified.`); + } + annotation.attachment = attachment; + // convert to a string so it's easier to serialise + if (attachment.body instanceof Uint8Array) { + attachment.body = encodeUint8Array(attachment.body); + } + } + if (location) { + annotation.location = location; + } + if (!runner.onTestAnnotate) { + throw new Error(`Test runner doesn't support test annotations.`); + } + await finishSendTasksUpdate(runner); + const resolvedAnnotation = await runner.onTestAnnotate(test, annotation); + test.annotations.push(resolvedAnnotation); + return resolvedAnnotation; + } + context.annotate = (message, type, attachment) => { + if (test.result && test.result.state !== "run") { + throw new Error(`Cannot annotate tests outside of the test run. The test "${test.name}" finished running with the "${test.result.state}" state already.`); + } + let location; + const stack = new Error("STACK_TRACE").stack; + const index = stack.includes("STACK_TRACE") ? 2 : 1; + const stackLine = stack.split("\n")[index]; + const parsed = parseSingleStack(stackLine); + if (parsed) { + location = { + file: parsed.file, + line: parsed.line, + column: parsed.column + }; + } + if (typeof type === "object") { + return recordAsyncAnnotation(test, annotate(message, location, undefined, type)); + } else { + return recordAsyncAnnotation(test, annotate(message, location, type, attachment)); + } + }; + context.onTestFailed = (handler, timeout) => { + test.onFailed || (test.onFailed = []); + test.onFailed.push(withTimeout(handler, timeout ?? runner.config.hookTimeout, true, new Error("STACK_TRACE_ERROR"), (_, error) => abortController.abort(error))); + }; + context.onTestFinished = (handler, timeout) => { + test.onFinished || (test.onFinished = []); + test.onFinished.push(withTimeout(handler, timeout ?? runner.config.hookTimeout, true, new Error("STACK_TRACE_ERROR"), (_, error) => abortController.abort(error))); + }; + return ((_runner$extendTaskCon = runner.extendTaskContext) === null || _runner$extendTaskCon === void 0 ? void 0 : _runner$extendTaskCon.call(runner, context)) || context; +} +function makeTimeoutError(isHook, timeout, stackTraceError) { + const message = `${isHook ? "Hook" : "Test"} timed out in ${timeout}ms.\nIf this is a long-running ${isHook ? "hook" : "test"}, pass a timeout value as the last argument or configure it globally with "${isHook ? "hookTimeout" : "testTimeout"}".`; + const error = new Error(message); + if (stackTraceError === null || stackTraceError === void 0 ? void 0 : stackTraceError.stack) { + error.stack = stackTraceError.stack.replace(error.message, stackTraceError.message); + } + return error; +} +const fileContexts = new WeakMap(); +function getFileContext(file) { + const context = fileContexts.get(file); + if (!context) { + throw new Error(`Cannot find file context for ${file.name}`); + } + return context; +} +function setFileContext(file, context) { + fileContexts.set(file, context); +} +const table = []; +for (let i = 65; i < 91; i++) { + table.push(String.fromCharCode(i)); +} +for (let i = 97; i < 123; i++) { + table.push(String.fromCharCode(i)); +} +for (let i = 0; i < 10; i++) { + table.push(i.toString(10)); +} +function encodeUint8Array(bytes) { + let base64 = ""; + const len = bytes.byteLength; + for (let i = 0; i < len; i += 3) { + if (len === i + 1) { + const a = (bytes[i] & 252) >> 2; + const b = (bytes[i] & 3) << 4; + base64 += table[a]; + base64 += table[b]; + base64 += "=="; + } else if (len === i + 2) { + const a = (bytes[i] & 252) >> 2; + const b = (bytes[i] & 3) << 4 | (bytes[i + 1] & 240) >> 4; + const c = (bytes[i + 1] & 15) << 2; + base64 += table[a]; + base64 += table[b]; + base64 += table[c]; + base64 += "="; + } else { + const a = (bytes[i] & 252) >> 2; + const b = (bytes[i] & 3) << 4 | (bytes[i + 1] & 240) >> 4; + const c = (bytes[i + 1] & 15) << 2 | (bytes[i + 2] & 192) >> 6; + const d = bytes[i + 2] & 63; + base64 += table[a]; + base64 += table[b]; + base64 += table[c]; + base64 += table[d]; + } + } + return base64; +} +function recordAsyncAnnotation(test, promise) { + // if promise is explicitly awaited, remove it from the list + promise = promise.finally(() => { + if (!test.promises) { + return; + } + const index = test.promises.indexOf(promise); + if (index !== -1) { + test.promises.splice(index, 1); + } + }); + // record promise + if (!test.promises) { + test.promises = []; + } + test.promises.push(promise); + return promise; +} + +function getDefaultHookTimeout() { + return getRunner().config.hookTimeout; +} +const CLEANUP_TIMEOUT_KEY = Symbol.for("VITEST_CLEANUP_TIMEOUT"); +const CLEANUP_STACK_TRACE_KEY = Symbol.for("VITEST_CLEANUP_STACK_TRACE"); +function getBeforeHookCleanupCallback(hook, result, context) { + if (typeof result === "function") { + const timeout = CLEANUP_TIMEOUT_KEY in hook && typeof hook[CLEANUP_TIMEOUT_KEY] === "number" ? hook[CLEANUP_TIMEOUT_KEY] : getDefaultHookTimeout(); + const stackTraceError = CLEANUP_STACK_TRACE_KEY in hook && hook[CLEANUP_STACK_TRACE_KEY] instanceof Error ? hook[CLEANUP_STACK_TRACE_KEY] : undefined; + return withTimeout(result, timeout, true, stackTraceError, (_, error) => { + if (context) { + abortContextSignal(context, error); + } + }); + } +} +/** +* Registers a callback function to be executed once before all tests within the current suite. +* This hook is useful for scenarios where you need to perform setup operations that are common to all tests in a suite, such as initializing a database connection or setting up a test environment. +* +* **Note:** The `beforeAll` hooks are executed in the order they are defined one after another. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed before all tests. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @returns {void} +* @example +* ```ts +* // Example of using beforeAll to set up a database connection +* beforeAll(async () => { +* await database.connect(); +* }); +* ``` +*/ +function beforeAll(fn, timeout = getDefaultHookTimeout()) { + assertTypes(fn, "\"beforeAll\" callback", ["function"]); + const stackTraceError = new Error("STACK_TRACE_ERROR"); + return getCurrentSuite().on("beforeAll", Object.assign(withTimeout(fn, timeout, true, stackTraceError), { + [CLEANUP_TIMEOUT_KEY]: timeout, + [CLEANUP_STACK_TRACE_KEY]: stackTraceError + })); +} +/** +* Registers a callback function to be executed once after all tests within the current suite have completed. +* This hook is useful for scenarios where you need to perform cleanup operations after all tests in a suite have run, such as closing database connections or cleaning up temporary files. +* +* **Note:** The `afterAll` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed after all tests. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @returns {void} +* @example +* ```ts +* // Example of using afterAll to close a database connection +* afterAll(async () => { +* await database.disconnect(); +* }); +* ``` +*/ +function afterAll(fn, timeout) { + assertTypes(fn, "\"afterAll\" callback", ["function"]); + return getCurrentSuite().on("afterAll", withTimeout(fn, timeout ?? getDefaultHookTimeout(), true, new Error("STACK_TRACE_ERROR"))); +} +/** +* Registers a callback function to be executed before each test within the current suite. +* This hook is useful for scenarios where you need to reset or reinitialize the test environment before each test runs, such as resetting database states, clearing caches, or reinitializing variables. +* +* **Note:** The `beforeEach` hooks are executed in the order they are defined one after another. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed before each test. This function receives an `TestContext` parameter if additional test context is needed. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @returns {void} +* @example +* ```ts +* // Example of using beforeEach to reset a database state +* beforeEach(async () => { +* await database.reset(); +* }); +* ``` +*/ +function beforeEach(fn, timeout = getDefaultHookTimeout()) { + assertTypes(fn, "\"beforeEach\" callback", ["function"]); + const stackTraceError = new Error("STACK_TRACE_ERROR"); + const runner = getRunner(); + return getCurrentSuite().on("beforeEach", Object.assign(withTimeout(withFixtures(runner, fn), timeout ?? getDefaultHookTimeout(), true, stackTraceError, abortIfTimeout), { + [CLEANUP_TIMEOUT_KEY]: timeout, + [CLEANUP_STACK_TRACE_KEY]: stackTraceError + })); +} +/** +* Registers a callback function to be executed after each test within the current suite has completed. +* This hook is useful for scenarios where you need to clean up or reset the test environment after each test runs, such as deleting temporary files, clearing test-specific database entries, or resetting mocked functions. +* +* **Note:** The `afterEach` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed after each test. This function receives an `TestContext` parameter if additional test context is needed. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @returns {void} +* @example +* ```ts +* // Example of using afterEach to delete temporary files created during a test +* afterEach(async () => { +* await fileSystem.deleteTempFiles(); +* }); +* ``` +*/ +function afterEach(fn, timeout) { + assertTypes(fn, "\"afterEach\" callback", ["function"]); + const runner = getRunner(); + return getCurrentSuite().on("afterEach", withTimeout(withFixtures(runner, fn), timeout ?? getDefaultHookTimeout(), true, new Error("STACK_TRACE_ERROR"), abortIfTimeout)); +} +/** +* Registers a callback function to be executed when a test fails within the current suite. +* This function allows for custom actions to be performed in response to test failures, such as logging, cleanup, or additional diagnostics. +* +* **Note:** The `onTestFailed` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed upon a test failure. The function receives the test result (including errors). +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @throws {Error} Throws an error if the function is not called within a test. +* @returns {void} +* @example +* ```ts +* // Example of using onTestFailed to log failure details +* onTestFailed(({ errors }) => { +* console.log(`Test failed: ${test.name}`, errors); +* }); +* ``` +*/ +const onTestFailed = createTestHook("onTestFailed", (test, handler, timeout) => { + test.onFailed || (test.onFailed = []); + test.onFailed.push(withTimeout(handler, timeout ?? getDefaultHookTimeout(), true, new Error("STACK_TRACE_ERROR"), abortIfTimeout)); +}); +/** +* Registers a callback function to be executed when the current test finishes, regardless of the outcome (pass or fail). +* This function is ideal for performing actions that should occur after every test execution, such as cleanup, logging, or resetting shared resources. +* +* This hook is useful if you have access to a resource in the test itself and you want to clean it up after the test finishes. It is a more compact way to clean up resources than using the combination of `beforeEach` and `afterEach`. +* +* **Note:** The `onTestFinished` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. +* +* **Note:** The `onTestFinished` hook is not called if the test is canceled with a dynamic `ctx.skip()` call. +* +* @param {Function} fn - The callback function to be executed after a test finishes. The function can receive parameters providing details about the completed test, including its success or failure status. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @throws {Error} Throws an error if the function is not called within a test. +* @returns {void} +* @example +* ```ts +* // Example of using onTestFinished for cleanup +* const db = await connectToDatabase(); +* onTestFinished(async () => { +* await db.disconnect(); +* }); +* ``` +*/ +const onTestFinished = createTestHook("onTestFinished", (test, handler, timeout) => { + test.onFinished || (test.onFinished = []); + test.onFinished.push(withTimeout(handler, timeout ?? getDefaultHookTimeout(), true, new Error("STACK_TRACE_ERROR"), abortIfTimeout)); +}); +function createTestHook(name, handler) { + return (fn, timeout) => { + assertTypes(fn, `"${name}" callback`, ["function"]); + const current = getCurrentTest(); + if (!current) { + throw new Error(`Hook ${name}() can only be called inside a test`); + } + return handler(current, fn, timeout); + }; +} + +export { someTasksAreOnly as A, limitConcurrency as B, partitionSuiteChildren as C, getFullName as D, getNames as E, getSuites as F, getTasks as G, getTestName as H, getTests as I, hasFailed as J, hasTests as K, isAtomTest as L, isTestCase as M, afterAll as a, afterEach as b, beforeAll as c, beforeEach as d, onTestFinished as e, getHooks as f, getFn as g, setHooks as h, startTests as i, createTaskCollector as j, describe as k, getCurrentSuite as l, it as m, suite as n, onTestFailed as o, publicCollect as p, getCurrentTest as q, createChainable as r, setFn as s, test as t, updateTask as u, calculateSuiteHash as v, createFileTask as w, generateFileHash as x, generateHash as y, interpretTaskModes as z }; diff --git a/node_modules/@vitest/runner/dist/index.d.ts b/node_modules/@vitest/runner/dist/index.d.ts new file mode 100644 index 0000000000..a3ab107a1b --- /dev/null +++ b/node_modules/@vitest/runner/dist/index.d.ts @@ -0,0 +1,261 @@ +import { A as AfterAllListener, b as AfterEachListener, B as BeforeAllListener, d as BeforeEachListener, e as TaskHook, O as OnTestFailedHandler, f as OnTestFinishedHandler, a as Test, g as Custom, S as Suite, h as SuiteHooks, F as File, i as TaskUpdateEvent, T as Task, j as TestAPI, k as SuiteAPI, l as SuiteCollector } from './tasks.d-CkscK4of.js'; +export { D as DoneCallback, E as ExtendedContext, m as Fixture, n as FixtureFn, o as FixtureOptions, p as Fixtures, H as HookCleanupCallback, q as HookListener, I as ImportDuration, r as InferFixturesTypes, R as RunMode, s as RuntimeContext, t as SequenceHooks, u as SequenceSetupFiles, v as SuiteFactory, w as TaskBase, x as TaskContext, y as TaskCustomOptions, z as TaskEventPack, G as TaskMeta, J as TaskPopulated, K as TaskResult, L as TaskResultPack, M as TaskState, N as TestAnnotation, P as TestAnnotationLocation, Q as TestAttachment, U as TestContext, V as TestFunction, W as TestOptions, X as Use } from './tasks.d-CkscK4of.js'; +import { Awaitable } from '@vitest/utils'; +import { FileSpecification, VitestRunner } from './types.js'; +export { CancelReason, VitestRunnerConfig, VitestRunnerConstructor, VitestRunnerImportSource } from './types.js'; +export { processError } from '@vitest/utils/error'; +import '@vitest/utils/diff'; + +/** +* Registers a callback function to be executed once before all tests within the current suite. +* This hook is useful for scenarios where you need to perform setup operations that are common to all tests in a suite, such as initializing a database connection or setting up a test environment. +* +* **Note:** The `beforeAll` hooks are executed in the order they are defined one after another. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed before all tests. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @returns {void} +* @example +* ```ts +* // Example of using beforeAll to set up a database connection +* beforeAll(async () => { +* await database.connect(); +* }); +* ``` +*/ +declare function beforeAll(fn: BeforeAllListener, timeout?: number): void; +/** +* Registers a callback function to be executed once after all tests within the current suite have completed. +* This hook is useful for scenarios where you need to perform cleanup operations after all tests in a suite have run, such as closing database connections or cleaning up temporary files. +* +* **Note:** The `afterAll` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed after all tests. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @returns {void} +* @example +* ```ts +* // Example of using afterAll to close a database connection +* afterAll(async () => { +* await database.disconnect(); +* }); +* ``` +*/ +declare function afterAll(fn: AfterAllListener, timeout?: number): void; +/** +* Registers a callback function to be executed before each test within the current suite. +* This hook is useful for scenarios where you need to reset or reinitialize the test environment before each test runs, such as resetting database states, clearing caches, or reinitializing variables. +* +* **Note:** The `beforeEach` hooks are executed in the order they are defined one after another. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed before each test. This function receives an `TestContext` parameter if additional test context is needed. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @returns {void} +* @example +* ```ts +* // Example of using beforeEach to reset a database state +* beforeEach(async () => { +* await database.reset(); +* }); +* ``` +*/ +declare function beforeEach(fn: BeforeEachListener, timeout?: number): void; +/** +* Registers a callback function to be executed after each test within the current suite has completed. +* This hook is useful for scenarios where you need to clean up or reset the test environment after each test runs, such as deleting temporary files, clearing test-specific database entries, or resetting mocked functions. +* +* **Note:** The `afterEach` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed after each test. This function receives an `TestContext` parameter if additional test context is needed. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @returns {void} +* @example +* ```ts +* // Example of using afterEach to delete temporary files created during a test +* afterEach(async () => { +* await fileSystem.deleteTempFiles(); +* }); +* ``` +*/ +declare function afterEach(fn: AfterEachListener, timeout?: number): void; +/** +* Registers a callback function to be executed when a test fails within the current suite. +* This function allows for custom actions to be performed in response to test failures, such as logging, cleanup, or additional diagnostics. +* +* **Note:** The `onTestFailed` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. +* +* @param {Function} fn - The callback function to be executed upon a test failure. The function receives the test result (including errors). +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @throws {Error} Throws an error if the function is not called within a test. +* @returns {void} +* @example +* ```ts +* // Example of using onTestFailed to log failure details +* onTestFailed(({ errors }) => { +* console.log(`Test failed: ${test.name}`, errors); +* }); +* ``` +*/ +declare const onTestFailed: TaskHook; +/** +* Registers a callback function to be executed when the current test finishes, regardless of the outcome (pass or fail). +* This function is ideal for performing actions that should occur after every test execution, such as cleanup, logging, or resetting shared resources. +* +* This hook is useful if you have access to a resource in the test itself and you want to clean it up after the test finishes. It is a more compact way to clean up resources than using the combination of `beforeEach` and `afterEach`. +* +* **Note:** The `onTestFinished` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. +* +* **Note:** The `onTestFinished` hook is not called if the test is canceled with a dynamic `ctx.skip()` call. +* +* @param {Function} fn - The callback function to be executed after a test finishes. The function can receive parameters providing details about the completed test, including its success or failure status. +* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. +* @throws {Error} Throws an error if the function is not called within a test. +* @returns {void} +* @example +* ```ts +* // Example of using onTestFinished for cleanup +* const db = await connectToDatabase(); +* onTestFinished(async () => { +* await db.disconnect(); +* }); +* ``` +*/ +declare const onTestFinished: TaskHook; + +declare function setFn(key: Test | Custom, fn: () => Awaitable): void; +declare function getFn(key: Task): () => Awaitable; +declare function setHooks(key: Suite, hooks: SuiteHooks): void; +declare function getHooks(key: Suite): SuiteHooks; + +declare function updateTask(event: TaskUpdateEvent, task: Task, runner: VitestRunner): void; +declare function startTests(specs: string[] | FileSpecification[], runner: VitestRunner): Promise; +declare function publicCollect(specs: string[] | FileSpecification[], runner: VitestRunner): Promise; + +/** +* Creates a suite of tests, allowing for grouping and hierarchical organization of tests. +* Suites can contain both tests and other suites, enabling complex test structures. +* +* @param {string} name - The name of the suite, used for identification and reporting. +* @param {Function} fn - A function that defines the tests and suites within this suite. +* @example +* ```ts +* // Define a suite with two tests +* suite('Math operations', () => { +* test('should add two numbers', () => { +* expect(add(1, 2)).toBe(3); +* }); +* +* test('should subtract two numbers', () => { +* expect(subtract(5, 2)).toBe(3); +* }); +* }); +* ``` +* @example +* ```ts +* // Define nested suites +* suite('String operations', () => { +* suite('Trimming', () => { +* test('should trim whitespace from start and end', () => { +* expect(' hello '.trim()).toBe('hello'); +* }); +* }); +* +* suite('Concatenation', () => { +* test('should concatenate two strings', () => { +* expect('hello' + ' ' + 'world').toBe('hello world'); +* }); +* }); +* }); +* ``` +*/ +declare const suite: SuiteAPI; +/** +* Defines a test case with a given name and test function. The test function can optionally be configured with test options. +* +* @param {string | Function} name - The name of the test or a function that will be used as a test name. +* @param {TestOptions | TestFunction} [optionsOrFn] - Optional. The test options or the test function if no explicit name is provided. +* @param {number | TestOptions | TestFunction} [optionsOrTest] - Optional. The test function or options, depending on the previous parameters. +* @throws {Error} If called inside another test function. +* @example +* ```ts +* // Define a simple test +* test('should add two numbers', () => { +* expect(add(1, 2)).toBe(3); +* }); +* ``` +* @example +* ```ts +* // Define a test with options +* test('should subtract two numbers', { retry: 3 }, () => { +* expect(subtract(5, 2)).toBe(3); +* }); +* ``` +*/ +declare const test: TestAPI; +/** +* Creates a suite of tests, allowing for grouping and hierarchical organization of tests. +* Suites can contain both tests and other suites, enabling complex test structures. +* +* @param {string} name - The name of the suite, used for identification and reporting. +* @param {Function} fn - A function that defines the tests and suites within this suite. +* @example +* ```ts +* // Define a suite with two tests +* describe('Math operations', () => { +* test('should add two numbers', () => { +* expect(add(1, 2)).toBe(3); +* }); +* +* test('should subtract two numbers', () => { +* expect(subtract(5, 2)).toBe(3); +* }); +* }); +* ``` +* @example +* ```ts +* // Define nested suites +* describe('String operations', () => { +* describe('Trimming', () => { +* test('should trim whitespace from start and end', () => { +* expect(' hello '.trim()).toBe('hello'); +* }); +* }); +* +* describe('Concatenation', () => { +* test('should concatenate two strings', () => { +* expect('hello' + ' ' + 'world').toBe('hello world'); +* }); +* }); +* }); +* ``` +*/ +declare const describe: SuiteAPI; +/** +* Defines a test case with a given name and test function. The test function can optionally be configured with test options. +* +* @param {string | Function} name - The name of the test or a function that will be used as a test name. +* @param {TestOptions | TestFunction} [optionsOrFn] - Optional. The test options or the test function if no explicit name is provided. +* @param {number | TestOptions | TestFunction} [optionsOrTest] - Optional. The test function or options, depending on the previous parameters. +* @throws {Error} If called inside another test function. +* @example +* ```ts +* // Define a simple test +* it('adds two numbers', () => { +* expect(add(1, 2)).toBe(3); +* }); +* ``` +* @example +* ```ts +* // Define a test with options +* it('subtracts two numbers', { retry: 3 }, () => { +* expect(subtract(5, 2)).toBe(3); +* }); +* ``` +*/ +declare const it: TestAPI; +declare function getCurrentSuite(): SuiteCollector; +declare function createTaskCollector(fn: (...args: any[]) => any, context?: Record): TestAPI; + +declare function getCurrentTest(): T; + +export { AfterAllListener, AfterEachListener, BeforeAllListener, BeforeEachListener, Custom, TestAPI as CustomAPI, File, FileSpecification, OnTestFailedHandler, OnTestFinishedHandler, Suite, SuiteAPI, SuiteCollector, SuiteHooks, Task, TaskHook, TaskUpdateEvent, Test, TestAPI, VitestRunner, afterAll, afterEach, beforeAll, beforeEach, publicCollect as collectTests, createTaskCollector, describe, getCurrentSuite, getCurrentTest, getFn, getHooks, it, onTestFailed, onTestFinished, setFn, setHooks, startTests, suite, test, updateTask }; diff --git a/node_modules/@vitest/runner/dist/index.js b/node_modules/@vitest/runner/dist/index.js new file mode 100644 index 0000000000..069be464f0 --- /dev/null +++ b/node_modules/@vitest/runner/dist/index.js @@ -0,0 +1,6 @@ +export { a as afterAll, b as afterEach, c as beforeAll, d as beforeEach, p as collectTests, j as createTaskCollector, k as describe, l as getCurrentSuite, q as getCurrentTest, g as getFn, f as getHooks, m as it, o as onTestFailed, e as onTestFinished, s as setFn, h as setHooks, i as startTests, n as suite, t as test, u as updateTask } from './chunk-hooks.js'; +export { processError } from '@vitest/utils/error'; +import '@vitest/utils'; +import '@vitest/utils/source-map'; +import 'strip-literal'; +import 'pathe'; diff --git a/node_modules/@vitest/runner/dist/tasks.d-CkscK4of.d.ts b/node_modules/@vitest/runner/dist/tasks.d-CkscK4of.d.ts new file mode 100644 index 0000000000..f32846a052 --- /dev/null +++ b/node_modules/@vitest/runner/dist/tasks.d-CkscK4of.d.ts @@ -0,0 +1,558 @@ +import { ErrorWithDiff, Awaitable } from '@vitest/utils'; + +interface FixtureItem extends FixtureOptions { + prop: string; + value: any; + scope: "test" | "file" | "worker"; + /** + * Indicates whether the fixture is a function + */ + isFn: boolean; + /** + * The dependencies(fixtures) of current fixture function. + */ + deps?: FixtureItem[]; +} + +type ChainableFunction< + T extends string, + F extends (...args: any) => any, + C = object +> = F & { [x in T] : ChainableFunction } & { + fn: (this: Record, ...args: Parameters) => ReturnType +} & C; +declare function createChainable< + T extends string, + Args extends any[], + R = any +>(keys: T[], fn: (this: Record, ...args: Args) => R): ChainableFunction R>; + +type RunMode = "run" | "skip" | "only" | "todo" | "queued"; +type TaskState = RunMode | "pass" | "fail"; +interface TaskBase { + /** + * Unique task identifier. Based on the file id and the position of the task. + * The id of the file task is based on the file path relative to root and project name. + * It will not change between runs. + * @example `1201091390`, `1201091390_0`, `1201091390_0_1` + */ + id: string; + /** + * Task name provided by the user. If no name was provided, it will be an empty string. + */ + name: string; + /** + * Task mode. + * - **skip**: task is skipped + * - **only**: only this task and other tasks with `only` mode will run + * - **todo**: task is marked as a todo, alias for `skip` + * - **run**: task will run or already ran + * - **queued**: task will start running next. It can only exist on the File + */ + mode: RunMode; + /** + * Custom metadata for the task. JSON reporter will save this data. + */ + meta: TaskMeta; + /** + * Whether the task was produced with `.each()` method. + */ + each?: boolean; + /** + * Whether the task should run concurrently with other tasks. + */ + concurrent?: boolean; + /** + * Whether the tasks of the suite run in a random order. + */ + shuffle?: boolean; + /** + * Suite that this task is part of. File task or the global suite will have no parent. + */ + suite?: Suite; + /** + * Result of the task. Suite and file tasks will only have the result if there + * was an error during collection or inside `afterAll`/`beforeAll`. + */ + result?: TaskResult; + /** + * The amount of times the task should be retried if it fails. + * @default 0 + */ + retry?: number; + /** + * The amount of times the task should be repeated after the successful run. + * If the task fails, it will not be retried unless `retry` is specified. + * @default 0 + */ + repeats?: number; + /** + * Location of the task in the file. This field is populated only if + * `includeTaskLocation` option is set. It is generated by calling `new Error` + * and parsing the stack trace, so the location might differ depending on the runtime. + */ + location?: { + line: number + column: number + }; +} +interface TaskPopulated extends TaskBase { + /** + * File task. It's the root task of the file. + */ + file: File; + /** + * Whether the task should succeed if it fails. If the task fails, it will be marked as passed. + */ + fails?: boolean; + /** + * Store promises (from async expects) to wait for them before finishing the test + */ + promises?: Promise[]; +} +/** +* Custom metadata that can be used in reporters. +*/ +interface TaskMeta {} +/** +* The result of calling a task. +*/ +interface TaskResult { + /** + * State of the task. Inherits the `task.mode` during collection. + * When the task has finished, it will be changed to `pass` or `fail`. + * - **pass**: task ran successfully + * - **fail**: task failed + */ + state: TaskState; + /** + * Errors that occurred during the task execution. It is possible to have several errors + * if `expect.soft()` failed multiple times or `retry` was triggered. + */ + errors?: ErrorWithDiff[]; + /** + * How long in milliseconds the task took to run. + */ + duration?: number; + /** + * Time in milliseconds when the task started running. + */ + startTime?: number; + /** + * Heap size in bytes after the task finished. + * Only available if `logHeapUsage` option is set and `process.memoryUsage` is defined. + */ + heap?: number; + /** + * State of related to this task hooks. Useful during reporting. + */ + hooks?: Partial>; + /** + * The amount of times the task was retried. The task is retried only if it + * failed and `retry` option is set. + */ + retryCount?: number; + /** + * The amount of times the task was repeated. The task is repeated only if + * `repeats` option is set. This number also contains `retryCount`. + */ + repeatCount?: number; +} +/** The time spent importing & executing a non-externalized file. */ +interface ImportDuration { + /** The time spent importing & executing the file itself, not counting all non-externalized imports that the file does. */ + selfTime: number; + /** The time spent importing & executing the file and all its imports. */ + totalTime: number; +} +/** +* The tuple representing a single task update. +* Usually reported after the task finishes. +*/ +type TaskResultPack = [id: string, result: TaskResult | undefined, meta: TaskMeta]; +interface TaskEventData { + annotation?: TestAnnotation | undefined; +} +type TaskEventPack = [id: string, event: TaskUpdateEvent, data: TaskEventData | undefined]; +type TaskUpdateEvent = "test-failed-early" | "suite-failed-early" | "test-prepare" | "test-finished" | "test-retried" | "suite-prepare" | "suite-finished" | "before-hook-start" | "before-hook-end" | "after-hook-start" | "after-hook-end" | "test-annotation"; +interface Suite extends TaskBase { + type: "suite"; + /** + * File task. It's the root task of the file. + */ + file: File; + /** + * An array of tasks that are part of the suite. + */ + tasks: Task[]; +} +interface File extends Suite { + /** + * The name of the pool that the file belongs to. + * @default 'forks' + */ + pool?: string; + /** + * The path to the file in UNIX format. + */ + filepath: string; + /** + * The name of the workspace project the file belongs to. + */ + projectName: string | undefined; + /** + * The time it took to collect all tests in the file. + * This time also includes importing all the file dependencies. + */ + collectDuration?: number; + /** + * The time it took to import the setup file. + */ + setupDuration?: number; + /** The time spent importing every non-externalized dependency that Vitest has processed. */ + importDurations?: Record; +} +interface Test extends TaskPopulated { + type: "test"; + /** + * Test context that will be passed to the test function. + */ + context: TestContext & ExtraContext; + /** + * The test timeout in milliseconds. + */ + timeout: number; + /** + * An array of custom annotations. + */ + annotations: TestAnnotation[]; +} +interface TestAttachment { + contentType?: string; + path?: string; + body?: string | Uint8Array; +} +interface TestAnnotationLocation { + line: number; + column: number; + file: string; +} +interface TestAnnotation { + message: string; + type: string; + location?: TestAnnotationLocation; + attachment?: TestAttachment; +} +/** +* @deprecated Use `Test` instead. `type: 'custom'` is not used since 2.2 +*/ +type Custom = Test; +type Task = Test | Suite | File; +/** +* @deprecated Vitest doesn't provide `done()` anymore +*/ +type DoneCallback = (error?: any) => void; +type TestFunction = (context: TestContext & ExtraContext) => Awaitable | void; +// jest's ExtractEachCallbackArgs +type ExtractEachCallbackArgs> = { + 1: [T[0]] + 2: [T[0], T[1]] + 3: [T[0], T[1], T[2]] + 4: [T[0], T[1], T[2], T[3]] + 5: [T[0], T[1], T[2], T[3], T[4]] + 6: [T[0], T[1], T[2], T[3], T[4], T[5]] + 7: [T[0], T[1], T[2], T[3], T[4], T[5], T[6]] + 8: [T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7]] + 9: [T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]] + 10: [T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]] + fallback: Array ? U : any> +}[T extends Readonly<[any]> ? 1 : T extends Readonly<[any, any]> ? 2 : T extends Readonly<[any, any, any]> ? 3 : T extends Readonly<[any, any, any, any]> ? 4 : T extends Readonly<[any, any, any, any, any]> ? 5 : T extends Readonly<[any, any, any, any, any, any]> ? 6 : T extends Readonly<[any, any, any, any, any, any, any]> ? 7 : T extends Readonly<[any, any, any, any, any, any, any, any]> ? 8 : T extends Readonly<[any, any, any, any, any, any, any, any, any]> ? 9 : T extends Readonly<[any, any, any, any, any, any, any, any, any, any]> ? 10 : "fallback"]; +interface EachFunctionReturn { + /** + * @deprecated Use options as the second argument instead + */ + (name: string | Function, fn: (...args: T) => Awaitable, options: TestCollectorOptions): void; + (name: string | Function, fn: (...args: T) => Awaitable, options?: number | TestCollectorOptions): void; + (name: string | Function, options: TestCollectorOptions, fn: (...args: T) => Awaitable): void; +} +interface TestEachFunction { + (cases: ReadonlyArray): EachFunctionReturn; + >(cases: ReadonlyArray): EachFunctionReturn>; + (cases: ReadonlyArray): EachFunctionReturn; + (...args: [TemplateStringsArray, ...any]): EachFunctionReturn; +} +interface TestForFunctionReturn< + Arg, + Context +> { + (name: string | Function, fn: (arg: Arg, context: Context) => Awaitable): void; + (name: string | Function, options: TestCollectorOptions, fn: (args: Arg, context: Context) => Awaitable): void; +} +interface TestForFunction { + // test.for([1, 2, 3]) + // test.for([[1, 2], [3, 4, 5]]) + (cases: ReadonlyArray): TestForFunctionReturn; + // test.for` + // a | b + // {1} | {2} + // {3} | {4} + // ` + (strings: TemplateStringsArray, ...values: any[]): TestForFunctionReturn; +} +interface SuiteForFunction { + (cases: ReadonlyArray): EachFunctionReturn<[T]>; + (...args: [TemplateStringsArray, ...any]): EachFunctionReturn; +} +interface TestCollectorCallable { + /** + * @deprecated Use options as the second argument instead + */ + (name: string | Function, fn: TestFunction, options: TestCollectorOptions): void; + (name: string | Function, fn?: TestFunction, options?: number | TestCollectorOptions): void; + (name: string | Function, options?: TestCollectorOptions, fn?: TestFunction): void; +} +type ChainableTestAPI = ChainableFunction<"concurrent" | "sequential" | "only" | "skip" | "todo" | "fails", TestCollectorCallable, { + each: TestEachFunction + for: TestForFunction +}>; +type TestCollectorOptions = Omit; +interface TestOptions { + /** + * Test timeout. + */ + timeout?: number; + /** + * Times to retry the test if fails. Useful for making flaky tests more stable. + * When retries is up, the last test error will be thrown. + * + * @default 0 + */ + retry?: number; + /** + * How many times the test will run again. + * Only inner tests will repeat if set on `describe()`, nested `describe()` will inherit parent's repeat by default. + * + * @default 0 + */ + repeats?: number; + /** + * Whether suites and tests run concurrently. + * Tests inherit `concurrent` from `describe()` and nested `describe()` will inherit from parent's `concurrent`. + */ + concurrent?: boolean; + /** + * Whether tests run sequentially. + * Tests inherit `sequential` from `describe()` and nested `describe()` will inherit from parent's `sequential`. + */ + sequential?: boolean; + /** + * Whether the tasks of the suite run in a random order. + */ + shuffle?: boolean; + /** + * Whether the test should be skipped. + */ + skip?: boolean; + /** + * Should this test be the only one running in a suite. + */ + only?: boolean; + /** + * Whether the test should be skipped and marked as a todo. + */ + todo?: boolean; + /** + * Whether the test is expected to fail. If it does, the test will pass, otherwise it will fail. + */ + fails?: boolean; +} +interface ExtendedAPI { + skipIf: (condition: any) => ChainableTestAPI; + runIf: (condition: any) => ChainableTestAPI; +} +type TestAPI = ChainableTestAPI & ExtendedAPI & { + extend: = object>(fixtures: Fixtures) => TestAPI<{ [K in keyof T | keyof ExtraContext] : K extends keyof T ? T[K] : K extends keyof ExtraContext ? ExtraContext[K] : never }> + scoped: (fixtures: Fixtures>) => void +}; + +interface FixtureOptions { + /** + * Whether to automatically set up current fixture, even though it's not being used in tests. + * @default false + */ + auto?: boolean; + /** + * Indicated if the injected value from the config should be preferred over the fixture value + */ + injected?: boolean; + /** + * When should the fixture be set up. + * - **test**: fixture will be set up before every test + * - **worker**: fixture will be set up once per worker + * - **file**: fixture will be set up once per file + * + * **Warning:** The `vmThreads` and `vmForks` pools initiate worker fixtures once per test file. + * @default 'test' + */ + scope?: "test" | "worker" | "file"; +} +type Use = (value: T) => Promise; +type FixtureFn< + T, + K extends keyof T, + ExtraContext +> = (context: Omit & ExtraContext, use: Use) => Promise; +type Fixture< + T, + K extends keyof T, + ExtraContext = object +> = ((...args: any) => any) extends T[K] ? T[K] extends any ? FixtureFn>> : never : T[K] | (T[K] extends any ? FixtureFn>> : never); +type Fixtures< + T extends Record, + ExtraContext = object +> = { [K in keyof T] : Fixture | [Fixture, FixtureOptions?] }; +type InferFixturesTypes = T extends TestAPI ? C : T; +interface SuiteCollectorCallable { + /** + * @deprecated Use options as the second argument instead + */ + (name: string | Function, fn: SuiteFactory, options: TestOptions): SuiteCollector; + (name: string | Function, fn?: SuiteFactory, options?: number | TestOptions): SuiteCollector; + (name: string | Function, options: TestOptions, fn?: SuiteFactory): SuiteCollector; +} +type ChainableSuiteAPI = ChainableFunction<"concurrent" | "sequential" | "only" | "skip" | "todo" | "shuffle", SuiteCollectorCallable, { + each: TestEachFunction + for: SuiteForFunction +}>; +type SuiteAPI = ChainableSuiteAPI & { + skipIf: (condition: any) => ChainableSuiteAPI + runIf: (condition: any) => ChainableSuiteAPI +}; +/** +* @deprecated +*/ +type HookListener< + T extends any[], + Return = void +> = (...args: T) => Awaitable; +/** +* @deprecated +*/ +type HookCleanupCallback = unknown; +interface BeforeAllListener { + (suite: Readonly): Awaitable; +} +interface AfterAllListener { + (suite: Readonly): Awaitable; +} +interface BeforeEachListener { + (context: TestContext & ExtraContext, suite: Readonly): Awaitable; +} +interface AfterEachListener { + (context: TestContext & ExtraContext, suite: Readonly): Awaitable; +} +interface SuiteHooks { + beforeAll: BeforeAllListener[]; + afterAll: AfterAllListener[]; + beforeEach: BeforeEachListener[]; + afterEach: AfterEachListener[]; +} +interface TaskCustomOptions extends TestOptions { + /** + * Whether the task was produced with `.each()` method. + */ + each?: boolean; + /** + * Custom metadata for the task that will be assigned to `task.meta`. + */ + meta?: Record; + /** + * Task fixtures. + */ + fixtures?: FixtureItem[]; + /** + * Function that will be called when the task is executed. + * If nothing is provided, the runner will try to get the function using `getFn(task)`. + * If the runner cannot find the function, the task will be marked as failed. + */ + handler?: (context: TestContext) => Awaitable; +} +interface SuiteCollector { + readonly name: string; + readonly mode: RunMode; + options?: TestOptions; + type: "collector"; + test: TestAPI; + tasks: (Suite | Test | SuiteCollector)[]; + scoped: (fixtures: Fixtures) => void; + fixtures: () => FixtureItem[] | undefined; + suite?: Suite; + task: (name: string, options?: TaskCustomOptions) => Test; + collect: (file: File) => Promise; + clear: () => void; + on: >(name: T, ...fn: SuiteHooks[T]) => void; +} +type SuiteFactory = (test: TestAPI) => Awaitable; +interface RuntimeContext { + tasks: (SuiteCollector | Test)[]; + currentSuite: SuiteCollector | null; +} +/** +* User's custom test context. +*/ +interface TestContext { + /** + * Metadata of the current test + */ + readonly task: Readonly; + /** + * An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that will be aborted if the test times out or + * the test run was cancelled. + * @see {@link https://vitest.dev/guide/test-context#signal} + */ + readonly signal: AbortSignal; + /** + * Extract hooks on test failed + * @see {@link https://vitest.dev/guide/test-context#ontestfailed} + */ + readonly onTestFailed: (fn: OnTestFailedHandler, timeout?: number) => void; + /** + * Extract hooks on test failed + * @see {@link https://vitest.dev/guide/test-context#ontestfinished} + */ + readonly onTestFinished: (fn: OnTestFinishedHandler, timeout?: number) => void; + /** + * Mark tests as skipped. All execution after this call will be skipped. + * This function throws an error, so make sure you are not catching it accidentally. + * @see {@link https://vitest.dev/guide/test-context#skip} + */ + readonly skip: { + (note?: string): never + (condition: boolean, note?: string): void + }; + /** + * Add a test annotation that will be displayed by your reporter. + * @see {@link https://vitest.dev/guide/test-context#annotate} + */ + readonly annotate: { + (message: string, type?: string, attachment?: TestAttachment): Promise + (message: string, attachment?: TestAttachment): Promise + }; +} +/** +* Context that's always available in the test function. +* @deprecated use `TestContext` instead +*/ +interface TaskContext extends TestContext {} +/** @deprecated use `TestContext` instead */ +type ExtendedContext = TaskContext & TestContext; +type OnTestFailedHandler = (context: TestContext) => Awaitable; +type OnTestFinishedHandler = (context: TestContext) => Awaitable; +interface TaskHook { + (fn: HookListener, timeout?: number): void; +} +type SequenceHooks = "stack" | "list" | "parallel"; +type SequenceSetupFiles = "list" | "parallel"; + +export { createChainable as c }; +export type { AfterAllListener as A, BeforeAllListener as B, ChainableFunction as C, DoneCallback as D, ExtendedContext as E, File as F, TaskMeta as G, HookCleanupCallback as H, ImportDuration as I, TaskPopulated as J, TaskResult as K, TaskResultPack as L, TaskState as M, TestAnnotation as N, OnTestFailedHandler as O, TestAnnotationLocation as P, TestAttachment as Q, RunMode as R, Suite as S, Task as T, TestContext as U, TestFunction as V, TestOptions as W, Use as X, Test as a, AfterEachListener as b, BeforeEachListener as d, TaskHook as e, OnTestFinishedHandler as f, Custom as g, SuiteHooks as h, TaskUpdateEvent as i, TestAPI as j, SuiteAPI as k, SuiteCollector as l, Fixture as m, FixtureFn as n, FixtureOptions as o, Fixtures as p, HookListener as q, InferFixturesTypes as r, RuntimeContext as s, SequenceHooks as t, SequenceSetupFiles as u, SuiteFactory as v, TaskBase as w, TaskContext as x, TaskCustomOptions as y, TaskEventPack as z }; diff --git a/node_modules/@vitest/runner/dist/types.d.ts b/node_modules/@vitest/runner/dist/types.d.ts new file mode 100644 index 0000000000..61cdd658be --- /dev/null +++ b/node_modules/@vitest/runner/dist/types.d.ts @@ -0,0 +1,163 @@ +import { DiffOptions } from '@vitest/utils/diff'; +import { F as File, a as Test, S as Suite, L as TaskResultPack, z as TaskEventPack, N as TestAnnotation, U as TestContext, I as ImportDuration, t as SequenceHooks, u as SequenceSetupFiles } from './tasks.d-CkscK4of.js'; +export { A as AfterAllListener, b as AfterEachListener, B as BeforeAllListener, d as BeforeEachListener, g as Custom, j as CustomAPI, D as DoneCallback, E as ExtendedContext, m as Fixture, n as FixtureFn, o as FixtureOptions, p as Fixtures, H as HookCleanupCallback, q as HookListener, r as InferFixturesTypes, O as OnTestFailedHandler, f as OnTestFinishedHandler, R as RunMode, s as RuntimeContext, k as SuiteAPI, l as SuiteCollector, v as SuiteFactory, h as SuiteHooks, T as Task, w as TaskBase, x as TaskContext, y as TaskCustomOptions, e as TaskHook, G as TaskMeta, J as TaskPopulated, K as TaskResult, M as TaskState, i as TaskUpdateEvent, j as TestAPI, P as TestAnnotationLocation, Q as TestAttachment, V as TestFunction, W as TestOptions, X as Use } from './tasks.d-CkscK4of.js'; +import '@vitest/utils'; + +/** +* This is a subset of Vitest config that's required for the runner to work. +*/ +interface VitestRunnerConfig { + root: string; + setupFiles: string[]; + name?: string; + passWithNoTests: boolean; + testNamePattern?: RegExp; + allowOnly?: boolean; + sequence: { + shuffle?: boolean + concurrent?: boolean + seed: number + hooks: SequenceHooks + setupFiles: SequenceSetupFiles + }; + chaiConfig?: { + truncateThreshold?: number + }; + maxConcurrency: number; + testTimeout: number; + hookTimeout: number; + retry: number; + includeTaskLocation?: boolean; + diffOptions?: DiffOptions; +} +/** +* Possible options to run a single file in a test. +*/ +interface FileSpecification { + filepath: string; + testLocations: number[] | undefined; +} +type VitestRunnerImportSource = "collect" | "setup"; +interface VitestRunnerConstructor { + new (config: VitestRunnerConfig): VitestRunner; +} +type CancelReason = "keyboard-input" | "test-failure" | (string & Record); +interface VitestRunner { + /** + * First thing that's getting called before actually collecting and running tests. + */ + onBeforeCollect?: (paths: string[]) => unknown; + /** + * Called after the file task was created but not collected yet. + */ + onCollectStart?: (file: File) => unknown; + /** + * Called after collecting tests and before "onBeforeRun". + */ + onCollected?: (files: File[]) => unknown; + /** + * Called when test runner should cancel next test runs. + * Runner should listen for this method and mark tests and suites as skipped in + * "onBeforeRunSuite" and "onBeforeRunTask" when called. + */ + cancel?: (reason: CancelReason) => unknown; + /** + * Called before running a single test. Doesn't have "result" yet. + */ + onBeforeRunTask?: (test: Test) => unknown; + /** + * Called before actually running the test function. Already has "result" with "state" and "startTime". + */ + onBeforeTryTask?: (test: Test, options: { + retry: number + repeats: number + }) => unknown; + /** + * When the task has finished running, but before cleanup hooks are called + */ + onTaskFinished?: (test: Test) => unknown; + /** + * Called after result and state are set. + */ + onAfterRunTask?: (test: Test) => unknown; + /** + * Called right after running the test function. Doesn't have new state yet. Will not be called, if the test function throws. + */ + onAfterTryTask?: (test: Test, options: { + retry: number + repeats: number + }) => unknown; + /** + * Called before running a single suite. Doesn't have "result" yet. + */ + onBeforeRunSuite?: (suite: Suite) => unknown; + /** + * Called after running a single suite. Has state and result. + */ + onAfterRunSuite?: (suite: Suite) => unknown; + /** + * If defined, will be called instead of usual Vitest suite partition and handling. + * "before" and "after" hooks will not be ignored. + */ + runSuite?: (suite: Suite) => Promise; + /** + * If defined, will be called instead of usual Vitest handling. Useful, if you have your custom test function. + * "before" and "after" hooks will not be ignored. + */ + runTask?: (test: Test) => Promise; + /** + * Called, when a task is updated. The same as "onTaskUpdate" in a reporter, but this is running in the same thread as tests. + */ + onTaskUpdate?: (task: TaskResultPack[], events: TaskEventPack[]) => Promise; + /** + * Called when annotation is added via the `context.annotate` method. + */ + onTestAnnotate?: (test: Test, annotation: TestAnnotation) => Promise; + /** + * Called before running all tests in collected paths. + */ + onBeforeRunFiles?: (files: File[]) => unknown; + /** + * Called right after running all tests in collected paths. + */ + onAfterRunFiles?: (files: File[]) => unknown; + /** + * Called when new context for a test is defined. Useful if you want to add custom properties to the context. + * If you only want to define custom context, consider using "beforeAll" in "setupFiles" instead. + * + * @see https://vitest.dev/advanced/runner#your-task-function + */ + extendTaskContext?: (context: TestContext) => TestContext; + /** + * Called when test and setup files are imported. Can be called in two situations: when collecting tests and when importing setup files. + */ + importFile: (filepath: string, source: VitestRunnerImportSource) => unknown; + /** + * Function that is called when the runner attempts to get the value when `test.extend` is used with `{ injected: true }` + */ + injectValue?: (key: string) => unknown; + /** + * Gets the time spent importing each individual non-externalized file that Vitest collected. + */ + getImportDurations?: () => Record; + /** + * Publicly available configuration. + */ + config: VitestRunnerConfig; + /** + * The name of the current pool. Can affect how stack trace is inferred on the server side. + */ + pool?: string; + /** + * Return the worker context for fixtures specified with `scope: 'worker'` + */ + getWorkerContext?: () => Record; + onCleanupWorkerContext?: (cleanup: () => unknown) => void; + /** @private */ + _currentTaskStartTime?: number; + /** @private */ + _currentTaskTimeout?: number; +} + +export { File, ImportDuration, SequenceHooks, SequenceSetupFiles, Suite, TaskEventPack, TaskResultPack, Test, TestAnnotation, TestContext }; +export type { CancelReason, FileSpecification, VitestRunner, VitestRunnerConfig, VitestRunnerConstructor, VitestRunnerImportSource }; diff --git a/node_modules/@vitest/runner/dist/types.js b/node_modules/@vitest/runner/dist/types.js new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/node_modules/@vitest/runner/dist/types.js @@ -0,0 +1 @@ + diff --git a/node_modules/@vitest/runner/dist/utils.d.ts b/node_modules/@vitest/runner/dist/utils.d.ts new file mode 100644 index 0000000000..52b193a0eb --- /dev/null +++ b/node_modules/@vitest/runner/dist/utils.d.ts @@ -0,0 +1,47 @@ +import { S as Suite, F as File, T as Task, a as Test } from './tasks.d-CkscK4of.js'; +export { C as ChainableFunction, c as createChainable } from './tasks.d-CkscK4of.js'; +import { Arrayable } from '@vitest/utils'; + +/** +* If any tasks been marked as `only`, mark all other tasks as `skip`. +*/ +declare function interpretTaskModes(file: Suite, namePattern?: string | RegExp, testLocations?: number[] | undefined, onlyMode?: boolean, parentIsOnly?: boolean, allowOnly?: boolean): void; +declare function someTasksAreOnly(suite: Suite): boolean; +declare function generateHash(str: string): string; +declare function calculateSuiteHash(parent: Suite): void; +declare function createFileTask(filepath: string, root: string, projectName: string | undefined, pool?: string): File; +/** +* Generate a unique ID for a file based on its path and project name +* @param file File relative to the root of the project to keep ID the same between different machines +* @param projectName The name of the test project +*/ +declare function generateFileHash(file: string, projectName: string | undefined): string; + +/** +* Return a function for running multiple async operations with limited concurrency. +*/ +declare function limitConcurrency(concurrency?: number): < + Args extends unknown[], + T +>(func: (...args: Args) => PromiseLike | T, ...args: Args) => Promise; + +/** +* Partition in tasks groups by consecutive concurrent +*/ +declare function partitionSuiteChildren(suite: Suite): Task[][]; + +/** +* @deprecated use `isTestCase` instead +*/ +declare function isAtomTest(s: Task): s is Test; +declare function isTestCase(s: Task): s is Test; +declare function getTests(suite: Arrayable): Test[]; +declare function getTasks(tasks?: Arrayable): Task[]; +declare function getSuites(suite: Arrayable): Suite[]; +declare function hasTests(suite: Arrayable): boolean; +declare function hasFailed(suite: Arrayable): boolean; +declare function getNames(task: Task): string[]; +declare function getFullName(task: Task, separator?: string): string; +declare function getTestName(task: Task, separator?: string): string; + +export { calculateSuiteHash, createFileTask, generateFileHash, generateHash, getFullName, getNames, getSuites, getTasks, getTestName, getTests, hasFailed, hasTests, interpretTaskModes, isAtomTest, isTestCase, limitConcurrency, partitionSuiteChildren, someTasksAreOnly }; diff --git a/node_modules/@vitest/runner/dist/utils.js b/node_modules/@vitest/runner/dist/utils.js new file mode 100644 index 0000000000..46f081c6ce --- /dev/null +++ b/node_modules/@vitest/runner/dist/utils.js @@ -0,0 +1,6 @@ +export { v as calculateSuiteHash, r as createChainable, w as createFileTask, x as generateFileHash, y as generateHash, D as getFullName, E as getNames, F as getSuites, G as getTasks, H as getTestName, I as getTests, J as hasFailed, K as hasTests, z as interpretTaskModes, L as isAtomTest, M as isTestCase, B as limitConcurrency, C as partitionSuiteChildren, A as someTasksAreOnly } from './chunk-hooks.js'; +import '@vitest/utils'; +import '@vitest/utils/source-map'; +import '@vitest/utils/error'; +import 'strip-literal'; +import 'pathe'; diff --git a/node_modules/@vitest/runner/package.json b/node_modules/@vitest/runner/package.json new file mode 100644 index 0000000000..65ff131c66 --- /dev/null +++ b/node_modules/@vitest/runner/package.json @@ -0,0 +1,49 @@ +{ + "name": "@vitest/runner", + "type": "module", + "version": "3.2.4", + "description": "Vitest test runner", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/runner#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/runner" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": true, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./utils": { + "types": "./dist/utils.d.ts", + "default": "./dist/utils.js" + }, + "./types": { + "types": "./dist/types.d.ts", + "default": "./dist/types.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "*.d.ts", + "dist" + ], + "dependencies": { + "pathe": "^2.0.3", + "strip-literal": "^3.0.0", + "@vitest/utils": "3.2.4" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/runner/types.d.ts b/node_modules/@vitest/runner/types.d.ts new file mode 100644 index 0000000000..26a125423d --- /dev/null +++ b/node_modules/@vitest/runner/types.d.ts @@ -0,0 +1 @@ +export * from './dist/types.js' diff --git a/node_modules/@vitest/runner/utils.d.ts b/node_modules/@vitest/runner/utils.d.ts new file mode 100644 index 0000000000..e3f344e48a --- /dev/null +++ b/node_modules/@vitest/runner/utils.d.ts @@ -0,0 +1 @@ +export * from './dist/utils.js' diff --git a/node_modules/@vitest/snapshot/LICENSE b/node_modules/@vitest/snapshot/LICENSE new file mode 100644 index 0000000000..5ae481fdb8 --- /dev/null +++ b/node_modules/@vitest/snapshot/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/snapshot/README.md b/node_modules/@vitest/snapshot/README.md new file mode 100644 index 0000000000..edf0817399 --- /dev/null +++ b/node_modules/@vitest/snapshot/README.md @@ -0,0 +1,84 @@ +# @vitest/snapshot + +Lightweight implementation of Jest's snapshots. + +## Usage + +```js +import { SnapshotClient } from '@vitest/snapshot' +import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment' +import { SnapshotManager } from '@vitest/snapshot/manager' + +const client = new SnapshotClient({ + // you need to provide your own equality check implementation if you use it + // this function is called when `.toMatchSnapshot({ property: 1 })` is called + isEqual: (received, expected) => + equals(received, expected, [iterableEquality, subsetEquality]), +}) + +// class that implements snapshot saving and reading +// by default uses fs module, but you can provide your own implementation depending on the environment +const environment = new NodeSnapshotEnvironment() + +// you need to implement this yourselves, +// this depends on your runner +function getCurrentFilepath() { + return '/file.spec.js' +} +function getCurrentTestName() { + return 'test1' +} + +// example for inline snapshots, nothing is required to support regular snapshots, +// just call `assert` with `isInline: false` +function wrapper(received) { + function __INLINE_SNAPSHOT__(inlineSnapshot, message) { + client.assert({ + received, + message, + isInline: true, + inlineSnapshot, + filepath: getCurrentFilepath(), + name: getCurrentTestName(), + }) + } + return { + // the name is hard-coded, it should be inside another function, so Vitest can find the actual test file where it was called (parses call stack trace + 2) + // you can override this behaviour in SnapshotState's `_inferInlineSnapshotStack` method by providing your own SnapshotState to SnapshotClient constructor + toMatchInlineSnapshot: (...args) => __INLINE_SNAPSHOT__(...args), + } +} + +const options = { + updateSnapshot: 'new', + snapshotEnvironment: environment, +} + +await client.startCurrentRun( + getCurrentFilepath(), + getCurrentTestName(), + options +) + +// this will save snapshot to a file which is returned by "snapshotEnvironment.resolvePath" +client.assert({ + received: 'some text', + isInline: false, +}) + +// uses "pretty-format", so it requires quotes +// also naming is hard-coded when parsing test files +wrapper('text 1').toMatchInlineSnapshot() +wrapper('text 2').toMatchInlineSnapshot('"text 2"') + +const result = await client.finishCurrentRun() // this saves files and returns SnapshotResult + +// you can use manager to manage several clients +const manager = new SnapshotManager(options) +manager.add(result) + +// do something +// and then read the summary + +console.log(manager.summary) +``` diff --git a/node_modules/@vitest/snapshot/dist/environment.d-DHdQ1Csl.d.ts b/node_modules/@vitest/snapshot/dist/environment.d-DHdQ1Csl.d.ts new file mode 100644 index 0000000000..435ae4fc06 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/environment.d-DHdQ1Csl.d.ts @@ -0,0 +1,22 @@ +interface ParsedStack { + method: string; + file: string; + line: number; + column: number; +} + +interface SnapshotEnvironment { + getVersion: () => string; + getHeader: () => string; + resolvePath: (filepath: string) => Promise; + resolveRawPath: (testPath: string, rawPath: string) => Promise; + saveSnapshotFile: (filepath: string, snapshot: string) => Promise; + readSnapshotFile: (filepath: string) => Promise; + removeSnapshotFile: (filepath: string) => Promise; + processStackTrace?: (stack: ParsedStack) => ParsedStack; +} +interface SnapshotEnvironmentOptions { + snapshotsDirName?: string; +} + +export type { ParsedStack as P, SnapshotEnvironment as S, SnapshotEnvironmentOptions as a }; diff --git a/node_modules/@vitest/snapshot/dist/environment.d.ts b/node_modules/@vitest/snapshot/dist/environment.d.ts new file mode 100644 index 0000000000..efa86bc4c7 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/environment.d.ts @@ -0,0 +1,16 @@ +import { S as SnapshotEnvironment, a as SnapshotEnvironmentOptions } from './environment.d-DHdQ1Csl.js'; + +declare class NodeSnapshotEnvironment implements SnapshotEnvironment { + private options; + constructor(options?: SnapshotEnvironmentOptions); + getVersion(): string; + getHeader(): string; + resolveRawPath(testPath: string, rawPath: string): Promise; + resolvePath(filepath: string): Promise; + prepareDirectory(dirPath: string): Promise; + saveSnapshotFile(filepath: string, snapshot: string): Promise; + readSnapshotFile(filepath: string): Promise; + removeSnapshotFile(filepath: string): Promise; +} + +export { NodeSnapshotEnvironment, SnapshotEnvironment }; diff --git a/node_modules/@vitest/snapshot/dist/environment.js b/node_modules/@vitest/snapshot/dist/environment.js new file mode 100644 index 0000000000..079b478912 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/environment.js @@ -0,0 +1,40 @@ +import { promises, existsSync } from 'node:fs'; +import { resolve, isAbsolute, dirname, join, basename } from 'pathe'; + +class NodeSnapshotEnvironment { + constructor(options = {}) { + this.options = options; + } + getVersion() { + return "1"; + } + getHeader() { + return `// Snapshot v${this.getVersion()}`; + } + async resolveRawPath(testPath, rawPath) { + return isAbsolute(rawPath) ? rawPath : resolve(dirname(testPath), rawPath); + } + async resolvePath(filepath) { + return join(join(dirname(filepath), this.options.snapshotsDirName ?? "__snapshots__"), `${basename(filepath)}.snap`); + } + async prepareDirectory(dirPath) { + await promises.mkdir(dirPath, { recursive: true }); + } + async saveSnapshotFile(filepath, snapshot) { + await promises.mkdir(dirname(filepath), { recursive: true }); + await promises.writeFile(filepath, snapshot, "utf-8"); + } + async readSnapshotFile(filepath) { + if (!existsSync(filepath)) { + return null; + } + return promises.readFile(filepath, "utf-8"); + } + async removeSnapshotFile(filepath) { + if (existsSync(filepath)) { + await promises.unlink(filepath); + } + } +} + +export { NodeSnapshotEnvironment }; diff --git a/node_modules/@vitest/snapshot/dist/index.d.ts b/node_modules/@vitest/snapshot/dist/index.d.ts new file mode 100644 index 0000000000..c34bada260 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/index.d.ts @@ -0,0 +1,137 @@ +import { S as SnapshotStateOptions, a as SnapshotMatchOptions, b as SnapshotResult, R as RawSnapshotInfo } from './rawSnapshot.d-lFsMJFUd.js'; +export { c as SnapshotData, d as SnapshotSerializer, e as SnapshotSummary, f as SnapshotUpdateState, U as UncheckedSnapshot } from './rawSnapshot.d-lFsMJFUd.js'; +import { S as SnapshotEnvironment, P as ParsedStack } from './environment.d-DHdQ1Csl.js'; +import { Plugin, Plugins } from '@vitest/pretty-format'; + +/** +* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + +declare class DefaultMap< + K, + V +> extends Map { + private defaultFn; + constructor(defaultFn: (key: K) => V, entries?: Iterable); + get(key: K): V; +} +declare class CounterMap extends DefaultMap { + constructor(); + // compat for jest-image-snapshot https://github.com/vitest-dev/vitest/issues/7322 + // `valueOf` and `Snapshot.added` setter allows + // snapshotState.added = snapshotState.added + 1 + // to function as + // snapshotState.added.total_ = snapshotState.added.total() + 1 + _total: number | undefined; + valueOf(): number; + increment(key: K): void; + total(): number; +} + +interface SnapshotReturnOptions { + actual: string; + count: number; + expected?: string; + key: string; + pass: boolean; +} +interface SaveStatus { + deleted: boolean; + saved: boolean; +} +declare class SnapshotState { + testFilePath: string; + snapshotPath: string; + private _counters; + private _dirty; + private _updateSnapshot; + private _snapshotData; + private _initialData; + private _inlineSnapshots; + private _inlineSnapshotStacks; + private _testIdToKeys; + private _rawSnapshots; + private _uncheckedKeys; + private _snapshotFormat; + private _environment; + private _fileExists; + expand: boolean; + // getter/setter for jest-image-snapshot compat + // https://github.com/vitest-dev/vitest/issues/7322 + private _added; + private _matched; + private _unmatched; + private _updated; + get added(): CounterMap; + set added(value: CounterMap); + get matched(): CounterMap; + set matched(value: CounterMap); + get unmatched(): CounterMap; + set unmatched(value: CounterMap); + get updated(): CounterMap; + set updated(value: CounterMap); + private constructor(); + static create(testFilePath: string, options: SnapshotStateOptions): Promise; + get environment(): SnapshotEnvironment; + markSnapshotsAsCheckedForTest(testName: string): void; + clearTest(testId: string): void; + protected _inferInlineSnapshotStack(stacks: ParsedStack[]): ParsedStack | null; + private _addSnapshot; + save(): Promise; + getUncheckedCount(): number; + getUncheckedKeys(): Array; + removeUncheckedKeys(): void; + match({ testId, testName, received, key, inlineSnapshot, isInline, error, rawSnapshot }: SnapshotMatchOptions): SnapshotReturnOptions; + pack(): Promise; +} + +interface AssertOptions { + received: unknown; + filepath: string; + name: string; + /** + * Not required but needed for `SnapshotClient.clearTest` to implement test-retry behavior. + * @default name + */ + testId?: string; + message?: string; + isInline?: boolean; + properties?: object; + inlineSnapshot?: string; + error?: Error; + errorMessage?: string; + rawSnapshot?: RawSnapshotInfo; +} +interface SnapshotClientOptions { + isEqual?: (received: unknown, expected: unknown) => boolean; +} +declare class SnapshotClient { + private options; + snapshotStateMap: Map; + constructor(options?: SnapshotClientOptions); + setup(filepath: string, options: SnapshotStateOptions): Promise; + finish(filepath: string): Promise; + skipTest(filepath: string, testName: string): void; + clearTest(filepath: string, testId: string): void; + getSnapshotState(filepath: string): SnapshotState; + assert(options: AssertOptions): void; + assertRaw(options: AssertOptions): Promise; + clear(): void; +} + +declare function stripSnapshotIndentation(inlineSnapshot: string): string; + +/** +* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + +declare function addSerializer(plugin: Plugin): void; +declare function getSerializers(): Plugins; + +export { SnapshotClient, SnapshotMatchOptions, SnapshotResult, SnapshotState, SnapshotStateOptions, addSerializer, getSerializers, stripSnapshotIndentation }; diff --git a/node_modules/@vitest/snapshot/dist/index.js b/node_modules/@vitest/snapshot/dist/index.js new file mode 100644 index 0000000000..ca697ee4e0 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/index.js @@ -0,0 +1,2305 @@ +import { resolve as resolve$2 } from 'pathe'; +import { plugins, format } from '@vitest/pretty-format'; + +const comma = ','.charCodeAt(0); +const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +const intToChar = new Uint8Array(64); // 64 possible chars. +const charToInt = new Uint8Array(128); // z is 122 in ASCII +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decodeInteger(reader, relative) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -2147483648 | -value; + } + return relative + value; +} +function hasMoreVlq(reader, max) { + if (reader.pos >= max) + return false; + return reader.peek() !== comma; +} +class StringReader { + constructor(buffer) { + this.pos = 0; + this.buffer = buffer; + } + next() { + return this.buffer.charCodeAt(this.pos++); + } + peek() { + return this.buffer.charCodeAt(this.pos); + } + indexOf(char) { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +} + +function decode(mappings) { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + do { + const semi = reader.indexOf(';'); + const line = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + while (reader.pos < semi) { + let seg; + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) + sorted = false; + lastCol = genColumn; + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } + else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } + else { + seg = [genColumn]; + } + line.push(seg); + reader.pos++; + } + if (!sorted) + sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + return decoded; +} +function sort(line) { + line.sort(sortComparator$1); +} +function sortComparator$1(a, b) { + return a[0] - b[0]; +} + +// Matches the scheme of a URL, eg "http://" +const schemeRegex = /^[\w+.-]+:\/\//; +/** + * Matches the parts of a URL: + * 1. Scheme, including ":", guaranteed. + * 2. User/password, including "@", optional. + * 3. Host, guaranteed. + * 4. Port, including ":", optional. + * 5. Path, including "/", optional. + * 6. Query, including "?", optional. + * 7. Hash, including "#", optional. + */ +const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/; +/** + * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start + * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive). + * + * 1. Host, optional. + * 2. Path, which may include "/", guaranteed. + * 3. Query, including "?", optional. + * 4. Hash, including "#", optional. + */ +const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i; +var UrlType; +(function (UrlType) { + UrlType[UrlType["Empty"] = 1] = "Empty"; + UrlType[UrlType["Hash"] = 2] = "Hash"; + UrlType[UrlType["Query"] = 3] = "Query"; + UrlType[UrlType["RelativePath"] = 4] = "RelativePath"; + UrlType[UrlType["AbsolutePath"] = 5] = "AbsolutePath"; + UrlType[UrlType["SchemeRelative"] = 6] = "SchemeRelative"; + UrlType[UrlType["Absolute"] = 7] = "Absolute"; +})(UrlType || (UrlType = {})); +function isAbsoluteUrl(input) { + return schemeRegex.test(input); +} +function isSchemeRelativeUrl(input) { + return input.startsWith('//'); +} +function isAbsolutePath(input) { + return input.startsWith('/'); +} +function isFileUrl(input) { + return input.startsWith('file:'); +} +function isRelative(input) { + return /^[.?#]/.test(input); +} +function parseAbsoluteUrl(input) { + const match = urlRegex.exec(input); + return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || ''); +} +function parseFileUrl(input) { + const match = fileRegex.exec(input); + const path = match[2]; + return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || ''); +} +function makeUrl(scheme, user, host, port, path, query, hash) { + return { + scheme, + user, + host, + port, + path, + query, + hash, + type: UrlType.Absolute, + }; +} +function parseUrl(input) { + if (isSchemeRelativeUrl(input)) { + const url = parseAbsoluteUrl('http:' + input); + url.scheme = ''; + url.type = UrlType.SchemeRelative; + return url; + } + if (isAbsolutePath(input)) { + const url = parseAbsoluteUrl('http://foo.com' + input); + url.scheme = ''; + url.host = ''; + url.type = UrlType.AbsolutePath; + return url; + } + if (isFileUrl(input)) + return parseFileUrl(input); + if (isAbsoluteUrl(input)) + return parseAbsoluteUrl(input); + const url = parseAbsoluteUrl('http://foo.com/' + input); + url.scheme = ''; + url.host = ''; + url.type = input + ? input.startsWith('?') + ? UrlType.Query + : input.startsWith('#') + ? UrlType.Hash + : UrlType.RelativePath + : UrlType.Empty; + return url; +} +function stripPathFilename(path) { + // If a path ends with a parent directory "..", then it's a relative path with excess parent + // paths. It's not a file, so we can't strip it. + if (path.endsWith('/..')) + return path; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} +function mergePaths(url, base) { + normalizePath(base, base.type); + // If the path is just a "/", then it was an empty path to begin with (remember, we're a relative + // path). + if (url.path === '/') { + url.path = base.path; + } + else { + // Resolution happens relative to the base path's directory, not the file. + url.path = stripPathFilename(base.path) + url.path; + } +} +/** + * The path can have empty directories "//", unneeded parents "foo/..", or current directory + * "foo/.". We need to normalize to a standard representation. + */ +function normalizePath(url, type) { + const rel = type <= UrlType.RelativePath; + const pieces = url.path.split('/'); + // We need to preserve the first piece always, so that we output a leading slash. The item at + // pieces[0] is an empty string. + let pointer = 1; + // Positive is the number of real directories we've output, used for popping a parent directory. + // Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo". + let positive = 0; + // We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will + // generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a + // real directory, we won't need to append, unless the other conditions happen again. + let addTrailingSlash = false; + for (let i = 1; i < pieces.length; i++) { + const piece = pieces[i]; + // An empty directory, could be a trailing slash, or just a double "//" in the path. + if (!piece) { + addTrailingSlash = true; + continue; + } + // If we encounter a real directory, then we don't need to append anymore. + addTrailingSlash = false; + // A current directory, which we can always drop. + if (piece === '.') + continue; + // A parent directory, we need to see if there are any real directories we can pop. Else, we + // have an excess of parents, and we'll need to keep the "..". + if (piece === '..') { + if (positive) { + addTrailingSlash = true; + positive--; + pointer--; + } + else if (rel) { + // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute + // URL, protocol relative URL, or an absolute path, we don't need to keep excess. + pieces[pointer++] = piece; + } + continue; + } + // We've encountered a real directory. Move it to the next insertion pointer, which accounts for + // any popped or dropped directories. + pieces[pointer++] = piece; + positive++; + } + let path = ''; + for (let i = 1; i < pointer; i++) { + path += '/' + pieces[i]; + } + if (!path || (addTrailingSlash && !path.endsWith('/..'))) { + path += '/'; + } + url.path = path; +} +/** + * Attempts to resolve `input` URL/path relative to `base`. + */ +function resolve$1(input, base) { + if (!input && !base) + return ''; + const url = parseUrl(input); + let inputType = url.type; + if (base && inputType !== UrlType.Absolute) { + const baseUrl = parseUrl(base); + const baseType = baseUrl.type; + switch (inputType) { + case UrlType.Empty: + url.hash = baseUrl.hash; + // fall through + case UrlType.Hash: + url.query = baseUrl.query; + // fall through + case UrlType.Query: + case UrlType.RelativePath: + mergePaths(url, baseUrl); + // fall through + case UrlType.AbsolutePath: + // The host, user, and port are joined, you can't copy one without the others. + url.user = baseUrl.user; + url.host = baseUrl.host; + url.port = baseUrl.port; + // fall through + case UrlType.SchemeRelative: + // The input doesn't have a schema at least, so we need to copy at least that over. + url.scheme = baseUrl.scheme; + } + if (baseType > inputType) + inputType = baseType; + } + normalizePath(url, inputType); + const queryHash = url.query + url.hash; + switch (inputType) { + // This is impossible, because of the empty checks at the start of the function. + // case UrlType.Empty: + case UrlType.Hash: + case UrlType.Query: + return queryHash; + case UrlType.RelativePath: { + // The first char is always a "/", and we need it to be relative. + const path = url.path.slice(1); + if (!path) + return queryHash || '.'; + if (isRelative(base || input) && !isRelative(path)) { + // If base started with a leading ".", or there is no base and input started with a ".", + // then we need to ensure that the relative path starts with a ".". We don't know if + // relative starts with a "..", though, so check before prepending. + return './' + path + queryHash; + } + return path + queryHash; + } + case UrlType.AbsolutePath: + return url.path + queryHash; + default: + return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash; + } +} + +function resolve(input, base) { + // The base is always treated as a directory, if it's not empty. + // https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327 + // https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401 + if (base && !base.endsWith('/')) + base += '/'; + return resolve$1(input, base); +} + +/** + * Removes everything after the last "/", but leaves the slash. + */ +function stripFilename(path) { + if (!path) + return ''; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} + +const COLUMN = 0; +const SOURCES_INDEX = 1; +const SOURCE_LINE = 2; +const SOURCE_COLUMN = 3; +const NAMES_INDEX = 4; + +function maybeSort(mappings, owned) { + const unsortedIndex = nextUnsortedSegmentLine(mappings, 0); + if (unsortedIndex === mappings.length) + return mappings; + // If we own the array (meaning we parsed it from JSON), then we're free to directly mutate it. If + // not, we do not want to modify the consumer's input array. + if (!owned) + mappings = mappings.slice(); + for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) { + mappings[i] = sortSegments(mappings[i], owned); + } + return mappings; +} +function nextUnsortedSegmentLine(mappings, start) { + for (let i = start; i < mappings.length; i++) { + if (!isSorted(mappings[i])) + return i; + } + return mappings.length; +} +function isSorted(line) { + for (let j = 1; j < line.length; j++) { + if (line[j][COLUMN] < line[j - 1][COLUMN]) { + return false; + } + } + return true; +} +function sortSegments(line, owned) { + if (!owned) + line = line.slice(); + return line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[COLUMN] - b[COLUMN]; +} + +let found = false; +/** + * A binary search implementation that returns the index if a match is found. + * If no match is found, then the left-index (the index associated with the item that comes just + * before the desired index) is returned. To maintain proper sort order, a splice would happen at + * the next index: + * + * ```js + * const array = [1, 3]; + * const needle = 2; + * const index = binarySearch(array, needle, (item, needle) => item - needle); + * + * assert.equal(index, 0); + * array.splice(index + 1, 0, needle); + * assert.deepEqual(array, [1, 2, 3]); + * ``` + */ +function binarySearch(haystack, needle, low, high) { + while (low <= high) { + const mid = low + ((high - low) >> 1); + const cmp = haystack[mid][COLUMN] - needle; + if (cmp === 0) { + found = true; + return mid; + } + if (cmp < 0) { + low = mid + 1; + } + else { + high = mid - 1; + } + } + found = false; + return low - 1; +} +function upperBound(haystack, needle, index) { + for (let i = index + 1; i < haystack.length; index = i++) { + if (haystack[i][COLUMN] !== needle) + break; + } + return index; +} +function lowerBound(haystack, needle, index) { + for (let i = index - 1; i >= 0; index = i--) { + if (haystack[i][COLUMN] !== needle) + break; + } + return index; +} +function memoizedState() { + return { + lastKey: -1, + lastNeedle: -1, + lastIndex: -1, + }; +} +/** + * This overly complicated beast is just to record the last tested line/column and the resulting + * index, allowing us to skip a few tests if mappings are monotonically increasing. + */ +function memoizedBinarySearch(haystack, needle, state, key) { + const { lastKey, lastNeedle, lastIndex } = state; + let low = 0; + let high = haystack.length - 1; + if (key === lastKey) { + if (needle === lastNeedle) { + found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; + return lastIndex; + } + if (needle >= lastNeedle) { + // lastIndex may be -1 if the previous needle was not found. + low = lastIndex === -1 ? 0 : lastIndex; + } + else { + high = lastIndex; + } + } + state.lastKey = key; + state.lastNeedle = needle; + return (state.lastIndex = binarySearch(haystack, needle, low, high)); +} + +const LINE_GTR_ZERO = '`line` must be greater than 0 (lines start at line 1)'; +const COL_GTR_EQ_ZERO = '`column` must be greater than or equal to 0 (columns start at column 0)'; +const LEAST_UPPER_BOUND = -1; +const GREATEST_LOWER_BOUND = 1; +class TraceMap { + constructor(map, mapUrl) { + const isString = typeof map === 'string'; + if (!isString && map._decodedMemo) + return map; + const parsed = (isString ? JSON.parse(map) : map); + const { version, file, names, sourceRoot, sources, sourcesContent } = parsed; + this.version = version; + this.file = file; + this.names = names || []; + this.sourceRoot = sourceRoot; + this.sources = sources; + this.sourcesContent = sourcesContent; + this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || undefined; + const from = resolve(sourceRoot || '', stripFilename(mapUrl)); + this.resolvedSources = sources.map((s) => resolve(s || '', from)); + const { mappings } = parsed; + if (typeof mappings === 'string') { + this._encoded = mappings; + this._decoded = undefined; + } + else { + this._encoded = undefined; + this._decoded = maybeSort(mappings, isString); + } + this._decodedMemo = memoizedState(); + this._bySources = undefined; + this._bySourceMemos = undefined; + } +} +/** + * Typescript doesn't allow friend access to private fields, so this just casts the map into a type + * with public access modifiers. + */ +function cast(map) { + return map; +} +/** + * Returns the decoded (array of lines of segments) form of the SourceMap's mappings field. + */ +function decodedMappings(map) { + var _a; + return ((_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded))); +} +/** + * A higher-level API to find the source/line/column associated with a generated line/column + * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in + * `source-map` library. + */ +function originalPositionFor(map, needle) { + let { line, column, bias } = needle; + line--; + if (line < 0) + throw new Error(LINE_GTR_ZERO); + if (column < 0) + throw new Error(COL_GTR_EQ_ZERO); + const decoded = decodedMappings(map); + // It's common for parent source maps to have pointers to lines that have no + // mapping (like a "//# sourceMappingURL=") at the end of the child file. + if (line >= decoded.length) + return OMapping(null, null, null, null); + const segments = decoded[line]; + const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND); + if (index === -1) + return OMapping(null, null, null, null); + const segment = segments[index]; + if (segment.length === 1) + return OMapping(null, null, null, null); + const { names, resolvedSources } = map; + return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null); +} +function OMapping(source, line, column, name) { + return { source, line, column, name }; +} +function traceSegmentInternal(segments, memo, line, column, bias) { + let index = memoizedBinarySearch(segments, column, memo, line); + if (found) { + index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index); + } + else if (bias === LEAST_UPPER_BOUND) + index++; + if (index === -1 || index === segments.length) + return -1; + return index; +} + +/** +* Get original stacktrace without source map support the most performant way. +* - Create only 1 stack frame. +* - Rewrite prepareStackTrace to bypass "support-stack-trace" (usually takes ~250ms). +*/ +function notNullish(v) { + return v != null; +} +function isPrimitive(value) { + return value === null || typeof value !== "function" && typeof value !== "object"; +} +function isObject(item) { + return item != null && typeof item === "object" && !Array.isArray(item); +} +/** +* If code starts with a function call, will return its last index, respecting arguments. +* This will return 25 - last ending character of toMatch ")" +* Also works with callbacks +* ``` +* toMatch({ test: '123' }); +* toBeAliased('123') +* ``` +*/ +function getCallLastIndex(code) { + let charIndex = -1; + let inString = null; + let startedBracers = 0; + let endedBracers = 0; + let beforeChar = null; + while (charIndex <= code.length) { + beforeChar = code[charIndex]; + charIndex++; + const char = code[charIndex]; + const isCharString = char === "\"" || char === "'" || char === "`"; + if (isCharString && beforeChar !== "\\") { + if (inString === char) { + inString = null; + } else if (!inString) { + inString = char; + } + } + if (!inString) { + if (char === "(") { + startedBracers++; + } + if (char === ")") { + endedBracers++; + } + } + if (startedBracers && endedBracers && startedBracers === endedBracers) { + return charIndex; + } + } + return null; +} + +const CHROME_IE_STACK_REGEXP = /^\s*at .*(?:\S:\d+|\(native\))/m; +const SAFARI_NATIVE_CODE_REGEXP = /^(?:eval@)?(?:\[native code\])?$/; +const stackIgnorePatterns = [ + "node:internal", + /\/packages\/\w+\/dist\//, + /\/@vitest\/\w+\/dist\//, + "/vitest/dist/", + "/vitest/src/", + "/vite-node/dist/", + "/vite-node/src/", + "/node_modules/chai/", + "/node_modules/tinypool/", + "/node_modules/tinyspy/", + "/deps/chunk-", + "/deps/@vitest", + "/deps/loupe", + "/deps/chai", + /node:\w+/, + /__vitest_test__/, + /__vitest_browser__/, + /\/deps\/vitest_/ +]; +function extractLocation(urlLike) { + // Fail-fast but return locations like "(native)" + if (!urlLike.includes(":")) { + return [urlLike]; + } + const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/; + const parts = regExp.exec(urlLike.replace(/^\(|\)$/g, "")); + if (!parts) { + return [urlLike]; + } + let url = parts[1]; + if (url.startsWith("async ")) { + url = url.slice(6); + } + if (url.startsWith("http:") || url.startsWith("https:")) { + const urlObj = new URL(url); + urlObj.searchParams.delete("import"); + urlObj.searchParams.delete("browserv"); + url = urlObj.pathname + urlObj.hash + urlObj.search; + } + if (url.startsWith("/@fs/")) { + const isWindows = /^\/@fs\/[a-zA-Z]:\//.test(url); + url = url.slice(isWindows ? 5 : 4); + } + return [ + url, + parts[2] || undefined, + parts[3] || undefined + ]; +} +function parseSingleFFOrSafariStack(raw) { + let line = raw.trim(); + if (SAFARI_NATIVE_CODE_REGEXP.test(line)) { + return null; + } + if (line.includes(" > eval")) { + line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1"); + } + if (!line.includes("@") && !line.includes(":")) { + return null; + } + // eslint-disable-next-line regexp/no-super-linear-backtracking, regexp/optimal-quantifier-concatenation + const functionNameRegex = /((.*".+"[^@]*)?[^@]*)(@)/; + const matches = line.match(functionNameRegex); + const functionName = matches && matches[1] ? matches[1] : undefined; + const [url, lineNumber, columnNumber] = extractLocation(line.replace(functionNameRegex, "")); + if (!url || !lineNumber || !columnNumber) { + return null; + } + return { + file: url, + method: functionName || "", + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} +// Based on https://github.com/stacktracejs/error-stack-parser +// Credit to stacktracejs +function parseSingleV8Stack(raw) { + let line = raw.trim(); + if (!CHROME_IE_STACK_REGEXP.test(line)) { + return null; + } + if (line.includes("(eval ")) { + line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, ""); + } + let sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, ""); + // capture and preserve the parenthesized location "(/foo/my bar.js:12:87)" in + // case it has spaces in it, as the string is split on \s+ later on + const location = sanitizedLine.match(/ (\(.+\)$)/); + // remove the parenthesized location from the line, if it was matched + sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine; + // if a location was matched, pass it to extractLocation() otherwise pass all sanitizedLine + // because this line doesn't have function name + const [url, lineNumber, columnNumber] = extractLocation(location ? location[1] : sanitizedLine); + let method = location && sanitizedLine || ""; + let file = url && ["eval", ""].includes(url) ? undefined : url; + if (!file || !lineNumber || !columnNumber) { + return null; + } + if (method.startsWith("async ")) { + method = method.slice(6); + } + if (file.startsWith("file://")) { + file = file.slice(7); + } + // normalize Windows path (\ -> /) + file = file.startsWith("node:") || file.startsWith("internal:") ? file : resolve$2(file); + if (method) { + method = method.replace(/__vite_ssr_import_\d+__\./g, ""); + } + return { + method, + file, + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} +function parseStacktrace(stack, options = {}) { + const { ignoreStackEntries = stackIgnorePatterns } = options; + const stacks = !CHROME_IE_STACK_REGEXP.test(stack) ? parseFFOrSafariStackTrace(stack) : parseV8Stacktrace(stack); + return stacks.map((stack) => { + var _options$getSourceMap; + if (options.getUrlId) { + stack.file = options.getUrlId(stack.file); + } + const map = (_options$getSourceMap = options.getSourceMap) === null || _options$getSourceMap === void 0 ? void 0 : _options$getSourceMap.call(options, stack.file); + if (!map || typeof map !== "object" || !map.version) { + return shouldFilter(ignoreStackEntries, stack.file) ? null : stack; + } + const traceMap = new TraceMap(map); + const { line, column, source, name } = originalPositionFor(traceMap, stack); + let file = stack.file; + if (source) { + const fileUrl = stack.file.startsWith("file://") ? stack.file : `file://${stack.file}`; + const sourceRootUrl = map.sourceRoot ? new URL(map.sourceRoot, fileUrl) : fileUrl; + file = new URL(source, sourceRootUrl).pathname; + // if the file path is on windows, we need to remove the leading slash + if (file.match(/\/\w:\//)) { + file = file.slice(1); + } + } + if (shouldFilter(ignoreStackEntries, file)) { + return null; + } + if (line != null && column != null) { + return { + line, + column, + file, + method: name || stack.method + }; + } + return stack; + }).filter((s) => s != null); +} +function shouldFilter(ignoreStackEntries, file) { + return ignoreStackEntries.some((p) => file.match(p)); +} +function parseFFOrSafariStackTrace(stack) { + return stack.split("\n").map((line) => parseSingleFFOrSafariStack(line)).filter(notNullish); +} +function parseV8Stacktrace(stack) { + return stack.split("\n").map((line) => parseSingleV8Stack(line)).filter(notNullish); +} +function parseErrorStacktrace(e, options = {}) { + if (!e || isPrimitive(e)) { + return []; + } + if (e.stacks) { + return e.stacks; + } + const stackStr = e.stack || ""; + // if "stack" property was overwritten at runtime to be something else, + // ignore the value because we don't know how to process it + let stackFrames = typeof stackStr === "string" ? parseStacktrace(stackStr, options) : []; + if (!stackFrames.length) { + const e_ = e; + if (e_.fileName != null && e_.lineNumber != null && e_.columnNumber != null) { + stackFrames = parseStacktrace(`${e_.fileName}:${e_.lineNumber}:${e_.columnNumber}`, options); + } + if (e_.sourceURL != null && e_.line != null && e_._column != null) { + stackFrames = parseStacktrace(`${e_.sourceURL}:${e_.line}:${e_.column}`, options); + } + } + if (options.frameFilter) { + stackFrames = stackFrames.filter((f) => options.frameFilter(e, f) !== false); + } + e.stacks = stackFrames; + return stackFrames; +} + +let getPromiseValue = () => 'Promise{…}'; +try { + // @ts-ignore + const { getPromiseDetails, kPending, kRejected } = process.binding('util'); + if (Array.isArray(getPromiseDetails(Promise.resolve()))) { + getPromiseValue = (value, options) => { + const [state, innerValue] = getPromiseDetails(value); + if (state === kPending) { + return 'Promise{}'; + } + return `Promise${state === kRejected ? '!' : ''}{${options.inspect(innerValue, options)}}`; + }; + } +} +catch (notNode) { + /* ignore */ +} + +const { AsymmetricMatcher: AsymmetricMatcher$1, DOMCollection: DOMCollection$1, DOMElement: DOMElement$1, Immutable: Immutable$1, ReactElement: ReactElement$1, ReactTestComponent: ReactTestComponent$1 } = plugins; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +var jsTokens_1; +var hasRequiredJsTokens; + +function requireJsTokens () { + if (hasRequiredJsTokens) return jsTokens_1; + hasRequiredJsTokens = 1; + // Copyright 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Simon Lydell + // License: MIT. + var Identifier, JSXIdentifier, JSXPunctuator, JSXString, JSXText, KeywordsWithExpressionAfter, KeywordsWithNoLineTerminatorAfter, LineTerminatorSequence, MultiLineComment, Newline, NumericLiteral, Punctuator, RegularExpressionLiteral, SingleLineComment, StringLiteral, Template, TokensNotPrecedingObjectLiteral, TokensPrecedingExpression, WhiteSpace; + RegularExpressionLiteral = /\/(?![*\/])(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\\]).|\\.)*(\/[$_\u200C\u200D\p{ID_Continue}]*|\\)?/yu; + Punctuator = /--|\+\+|=>|\.{3}|\??\.(?!\d)|(?:&&|\|\||\?\?|[+\-%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2}|\/(?![\/*]))=?|[?~,:;[\](){}]/y; + Identifier = /(\x23?)(?=[$_\p{ID_Start}\\])(?:[$_\u200C\u200D\p{ID_Continue}]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+/yu; + StringLiteral = /(['"])(?:(?!\1)[^\\\n\r]|\\(?:\r\n|[^]))*(\1)?/y; + NumericLiteral = /(?:0[xX][\da-fA-F](?:_?[\da-fA-F])*|0[oO][0-7](?:_?[0-7])*|0[bB][01](?:_?[01])*)n?|0n|[1-9](?:_?\d)*n|(?:(?:0(?!\d)|0\d*[89]\d*|[1-9](?:_?\d)*)(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?|0[0-7]+/y; + Template = /[`}](?:[^`\\$]|\\[^]|\$(?!\{))*(`|\$\{)?/y; + WhiteSpace = /[\t\v\f\ufeff\p{Zs}]+/yu; + LineTerminatorSequence = /\r?\n|[\r\u2028\u2029]/y; + MultiLineComment = /\/\*(?:[^*]|\*(?!\/))*(\*\/)?/y; + SingleLineComment = /\/\/.*/y; + JSXPunctuator = /[<>.:={}]|\/(?![\/*])/y; + JSXIdentifier = /[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}-]*/yu; + JSXString = /(['"])(?:(?!\1)[^])*(\1)?/y; + JSXText = /[^<>{}]+/y; + TokensPrecedingExpression = /^(?:[\/+-]|\.{3}|\?(?:InterpolationIn(?:JSX|Template)|NoLineTerminatorHere|NonExpressionParenEnd|UnaryIncDec))?$|[{}([,;<>=*%&|^!~?:]$/; + TokensNotPrecedingObjectLiteral = /^(?:=>|[;\]){}]|else|\?(?:NoLineTerminatorHere|NonExpressionParenEnd))?$/; + KeywordsWithExpressionAfter = /^(?:await|case|default|delete|do|else|instanceof|new|return|throw|typeof|void|yield)$/; + KeywordsWithNoLineTerminatorAfter = /^(?:return|throw|yield)$/; + Newline = RegExp(LineTerminatorSequence.source); + jsTokens_1 = function*(input, {jsx = false} = {}) { + var braces, firstCodePoint, isExpression, lastIndex, lastSignificantToken, length, match, mode, nextLastIndex, nextLastSignificantToken, parenNesting, postfixIncDec, punctuator, stack; + ({length} = input); + lastIndex = 0; + lastSignificantToken = ""; + stack = [ + {tag: "JS"} + ]; + braces = []; + parenNesting = 0; + postfixIncDec = false; + while (lastIndex < length) { + mode = stack[stack.length - 1]; + switch (mode.tag) { + case "JS": + case "JSNonExpressionParen": + case "InterpolationInTemplate": + case "InterpolationInJSX": + if (input[lastIndex] === "/" && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + RegularExpressionLiteral.lastIndex = lastIndex; + if (match = RegularExpressionLiteral.exec(input)) { + lastIndex = RegularExpressionLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "RegularExpressionLiteral", + value: match[0], + closed: match[1] !== void 0 && match[1] !== "\\" + }); + continue; + } + } + Punctuator.lastIndex = lastIndex; + if (match = Punctuator.exec(input)) { + punctuator = match[0]; + nextLastIndex = Punctuator.lastIndex; + nextLastSignificantToken = punctuator; + switch (punctuator) { + case "(": + if (lastSignificantToken === "?NonExpressionParenKeyword") { + stack.push({ + tag: "JSNonExpressionParen", + nesting: parenNesting + }); + } + parenNesting++; + postfixIncDec = false; + break; + case ")": + parenNesting--; + postfixIncDec = true; + if (mode.tag === "JSNonExpressionParen" && parenNesting === mode.nesting) { + stack.pop(); + nextLastSignificantToken = "?NonExpressionParenEnd"; + postfixIncDec = false; + } + break; + case "{": + Punctuator.lastIndex = 0; + isExpression = !TokensNotPrecedingObjectLiteral.test(lastSignificantToken) && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken)); + braces.push(isExpression); + postfixIncDec = false; + break; + case "}": + switch (mode.tag) { + case "InterpolationInTemplate": + if (braces.length === mode.nesting) { + Template.lastIndex = lastIndex; + match = Template.exec(input); + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + postfixIncDec = false; + yield ({ + type: "TemplateMiddle", + value: match[0] + }); + } else { + stack.pop(); + postfixIncDec = true; + yield ({ + type: "TemplateTail", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "InterpolationInJSX": + if (braces.length === mode.nesting) { + stack.pop(); + lastIndex += 1; + lastSignificantToken = "}"; + yield ({ + type: "JSXPunctuator", + value: "}" + }); + continue; + } + } + postfixIncDec = braces.pop(); + nextLastSignificantToken = postfixIncDec ? "?ExpressionBraceEnd" : "}"; + break; + case "]": + postfixIncDec = true; + break; + case "++": + case "--": + nextLastSignificantToken = postfixIncDec ? "?PostfixIncDec" : "?UnaryIncDec"; + break; + case "<": + if (jsx && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + stack.push({tag: "JSXTag"}); + lastIndex += 1; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: punctuator + }); + continue; + } + postfixIncDec = false; + break; + default: + postfixIncDec = false; + } + lastIndex = nextLastIndex; + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "Punctuator", + value: punctuator + }); + continue; + } + Identifier.lastIndex = lastIndex; + if (match = Identifier.exec(input)) { + lastIndex = Identifier.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "for": + case "if": + case "while": + case "with": + if (lastSignificantToken !== "." && lastSignificantToken !== "?.") { + nextLastSignificantToken = "?NonExpressionParenKeyword"; + } + } + lastSignificantToken = nextLastSignificantToken; + postfixIncDec = !KeywordsWithExpressionAfter.test(match[0]); + yield ({ + type: match[1] === "#" ? "PrivateIdentifier" : "IdentifierName", + value: match[0] + }); + continue; + } + StringLiteral.lastIndex = lastIndex; + if (match = StringLiteral.exec(input)) { + lastIndex = StringLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "StringLiteral", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + NumericLiteral.lastIndex = lastIndex; + if (match = NumericLiteral.exec(input)) { + lastIndex = NumericLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "NumericLiteral", + value: match[0] + }); + continue; + } + Template.lastIndex = lastIndex; + if (match = Template.exec(input)) { + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + stack.push({ + tag: "InterpolationInTemplate", + nesting: braces.length + }); + postfixIncDec = false; + yield ({ + type: "TemplateHead", + value: match[0] + }); + } else { + postfixIncDec = true; + yield ({ + type: "NoSubstitutionTemplate", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "JSXTag": + case "JSXTagEnd": + JSXPunctuator.lastIndex = lastIndex; + if (match = JSXPunctuator.exec(input)) { + lastIndex = JSXPunctuator.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "<": + stack.push({tag: "JSXTag"}); + break; + case ">": + stack.pop(); + if (lastSignificantToken === "/" || mode.tag === "JSXTagEnd") { + nextLastSignificantToken = "?JSX"; + postfixIncDec = true; + } else { + stack.push({tag: "JSXChildren"}); + } + break; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + nextLastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + break; + case "/": + if (lastSignificantToken === "<") { + stack.pop(); + if (stack[stack.length - 1].tag === "JSXChildren") { + stack.pop(); + } + stack.push({tag: "JSXTagEnd"}); + } + } + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "JSXPunctuator", + value: match[0] + }); + continue; + } + JSXIdentifier.lastIndex = lastIndex; + if (match = JSXIdentifier.exec(input)) { + lastIndex = JSXIdentifier.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXIdentifier", + value: match[0] + }); + continue; + } + JSXString.lastIndex = lastIndex; + if (match = JSXString.exec(input)) { + lastIndex = JSXString.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXString", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + break; + case "JSXChildren": + JSXText.lastIndex = lastIndex; + if (match = JSXText.exec(input)) { + lastIndex = JSXText.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXText", + value: match[0] + }); + continue; + } + switch (input[lastIndex]) { + case "<": + stack.push({tag: "JSXTag"}); + lastIndex++; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: "<" + }); + continue; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + lastIndex++; + lastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + yield ({ + type: "JSXPunctuator", + value: "{" + }); + continue; + } + } + WhiteSpace.lastIndex = lastIndex; + if (match = WhiteSpace.exec(input)) { + lastIndex = WhiteSpace.lastIndex; + yield ({ + type: "WhiteSpace", + value: match[0] + }); + continue; + } + LineTerminatorSequence.lastIndex = lastIndex; + if (match = LineTerminatorSequence.exec(input)) { + lastIndex = LineTerminatorSequence.lastIndex; + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + yield ({ + type: "LineTerminatorSequence", + value: match[0] + }); + continue; + } + MultiLineComment.lastIndex = lastIndex; + if (match = MultiLineComment.exec(input)) { + lastIndex = MultiLineComment.lastIndex; + if (Newline.test(match[0])) { + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + } + yield ({ + type: "MultiLineComment", + value: match[0], + closed: match[1] !== void 0 + }); + continue; + } + SingleLineComment.lastIndex = lastIndex; + if (match = SingleLineComment.exec(input)) { + lastIndex = SingleLineComment.lastIndex; + postfixIncDec = false; + yield ({ + type: "SingleLineComment", + value: match[0] + }); + continue; + } + firstCodePoint = String.fromCodePoint(input.codePointAt(lastIndex)); + lastIndex += firstCodePoint.length; + lastSignificantToken = firstCodePoint; + postfixIncDec = false; + yield ({ + type: mode.tag.startsWith("JSX") ? "JSXInvalid" : "Invalid", + value: firstCodePoint + }); + } + return void 0; + }; + return jsTokens_1; +} + +requireJsTokens(); + +// src/index.ts +var reservedWords = { + keyword: [ + "break", + "case", + "catch", + "continue", + "debugger", + "default", + "do", + "else", + "finally", + "for", + "function", + "if", + "return", + "switch", + "throw", + "try", + "var", + "const", + "while", + "with", + "new", + "this", + "super", + "class", + "extends", + "export", + "import", + "null", + "true", + "false", + "in", + "instanceof", + "typeof", + "void", + "delete" + ], + strict: [ + "implements", + "interface", + "let", + "package", + "private", + "protected", + "public", + "static", + "yield" + ] +}; new Set(reservedWords.keyword); new Set(reservedWords.strict); + +// src/index.ts +var f = { + reset: [0, 0], + bold: [1, 22, "\x1B[22m\x1B[1m"], + dim: [2, 22, "\x1B[22m\x1B[2m"], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29], + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], + blackBright: [90, 39], + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39], + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] +}, h = Object.entries(f); +function a(n) { + return String(n); +} +a.open = ""; +a.close = ""; +function C(n = false) { + let e = typeof process != "undefined" ? process : void 0, i = (e == null ? void 0 : e.env) || {}, g = (e == null ? void 0 : e.argv) || []; + return !("NO_COLOR" in i || g.includes("--no-color")) && ("FORCE_COLOR" in i || g.includes("--color") || (e == null ? void 0 : e.platform) === "win32" || n && i.TERM !== "dumb" || "CI" in i) || typeof window != "undefined" && !!window.chrome; +} +function p(n = false) { + let e = C(n), i = (r, t, c, o) => { + let l = "", s = 0; + do + l += r.substring(s, o) + c, s = o + t.length, o = r.indexOf(t, s); + while (~o); + return l + r.substring(s); + }, g = (r, t, c = r) => { + let o = (l) => { + let s = String(l), b = s.indexOf(t, r.length); + return ~b ? r + i(s, t, c, b) + t : r + s + t; + }; + return o.open = r, o.close = t, o; + }, u = { + isColorSupported: e + }, d = (r) => `\x1B[${r}m`; + for (let [r, t] of h) + u[r] = e ? g( + d(t[0]), + d(t[1]), + t[2] + ) : a; + return u; +} + +p(); + +const lineSplitRE = /\r?\n/; +function positionToOffset(source, lineNumber, columnNumber) { + const lines = source.split(lineSplitRE); + const nl = /\r\n/.test(source) ? 2 : 1; + let start = 0; + if (lineNumber > lines.length) { + return source.length; + } + for (let i = 0; i < lineNumber - 1; i++) { + start += lines[i].length + nl; + } + return start + columnNumber; +} +function offsetToLineNumber(source, offset) { + if (offset > source.length) { + throw new Error(`offset is longer than source length! offset ${offset} > length ${source.length}`); + } + const lines = source.split(lineSplitRE); + const nl = /\r\n/.test(source) ? 2 : 1; + let counted = 0; + let line = 0; + for (; line < lines.length; line++) { + const lineLength = lines[line].length + nl; + if (counted + lineLength >= offset) { + break; + } + counted += lineLength; + } + return line + 1; +} + +async function saveInlineSnapshots(environment, snapshots) { + const MagicString = (await import('magic-string')).default; + const files = new Set(snapshots.map((i) => i.file)); + await Promise.all(Array.from(files).map(async (file) => { + const snaps = snapshots.filter((i) => i.file === file); + const code = await environment.readSnapshotFile(file); + const s = new MagicString(code); + for (const snap of snaps) { + const index = positionToOffset(code, snap.line, snap.column); + replaceInlineSnap(code, s, index, snap.snapshot); + } + const transformed = s.toString(); + if (transformed !== code) { + await environment.saveSnapshotFile(file, transformed); + } + })); +} +const startObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*\{/; +function replaceObjectSnap(code, s, index, newSnap) { + let _code = code.slice(index); + const startMatch = startObjectRegex.exec(_code); + if (!startMatch) { + return false; + } + _code = _code.slice(startMatch.index); + let callEnd = getCallLastIndex(_code); + if (callEnd === null) { + return false; + } + callEnd += index + startMatch.index; + const shapeStart = index + startMatch.index + startMatch[0].length; + const shapeEnd = getObjectShapeEndIndex(code, shapeStart); + const snap = `, ${prepareSnapString(newSnap, code, index)}`; + if (shapeEnd === callEnd) { + // toMatchInlineSnapshot({ foo: expect.any(String) }) + s.appendLeft(callEnd, snap); + } else { + // toMatchInlineSnapshot({ foo: expect.any(String) }, ``) + s.overwrite(shapeEnd, callEnd, snap); + } + return true; +} +function getObjectShapeEndIndex(code, index) { + let startBraces = 1; + let endBraces = 0; + while (startBraces !== endBraces && index < code.length) { + const s = code[index++]; + if (s === "{") { + startBraces++; + } else if (s === "}") { + endBraces++; + } + } + return index; +} +function prepareSnapString(snap, source, index) { + const lineNumber = offsetToLineNumber(source, index); + const line = source.split(lineSplitRE)[lineNumber - 1]; + const indent = line.match(/^\s*/)[0] || ""; + const indentNext = indent.includes(" ") ? `${indent}\t` : `${indent} `; + const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g); + const isOneline = lines.length <= 1; + const quote = "`"; + if (isOneline) { + return `${quote}${lines.join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}${quote}`; + } + return `${quote}\n${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}\n${indent}${quote}`; +} +const toMatchInlineName = "toMatchInlineSnapshot"; +const toThrowErrorMatchingInlineName = "toThrowErrorMatchingInlineSnapshot"; +// on webkit, the line number is at the end of the method, not at the start +function getCodeStartingAtIndex(code, index) { + const indexInline = index - toMatchInlineName.length; + if (code.slice(indexInline, index) === toMatchInlineName) { + return { + code: code.slice(indexInline), + index: indexInline + }; + } + const indexThrowInline = index - toThrowErrorMatchingInlineName.length; + if (code.slice(index - indexThrowInline, index) === toThrowErrorMatchingInlineName) { + return { + code: code.slice(index - indexThrowInline), + index: index - indexThrowInline + }; + } + return { + code: code.slice(index), + index + }; +} +const startRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*[\w$]*(['"`)])/; +function replaceInlineSnap(code, s, currentIndex, newSnap) { + const { code: codeStartingAtIndex, index } = getCodeStartingAtIndex(code, currentIndex); + const startMatch = startRegex.exec(codeStartingAtIndex); + const firstKeywordMatch = /toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot/.exec(codeStartingAtIndex); + if (!startMatch || startMatch.index !== (firstKeywordMatch === null || firstKeywordMatch === void 0 ? void 0 : firstKeywordMatch.index)) { + return replaceObjectSnap(code, s, index, newSnap); + } + const quote = startMatch[1]; + const startIndex = index + startMatch.index + startMatch[0].length; + const snapString = prepareSnapString(newSnap, code, index); + if (quote === ")") { + s.appendRight(startIndex - 1, snapString); + return true; + } + const quoteEndRE = new RegExp(`(?:^|[^\\\\])${quote}`); + const endMatch = quoteEndRE.exec(code.slice(startIndex)); + if (!endMatch) { + return false; + } + const endIndex = startIndex + endMatch.index + endMatch[0].length; + s.overwrite(startIndex - 1, endIndex, snapString); + return true; +} +const INDENTATION_REGEX = /^([^\S\n]*)\S/m; +function stripSnapshotIndentation(inlineSnapshot) { + // Find indentation if exists. + const match = inlineSnapshot.match(INDENTATION_REGEX); + if (!match || !match[1]) { + // No indentation. + return inlineSnapshot; + } + const indentation = match[1]; + const lines = inlineSnapshot.split(/\n/g); + if (lines.length <= 2) { + // Must be at least 3 lines. + return inlineSnapshot; + } + if (lines[0].trim() !== "" || lines[lines.length - 1].trim() !== "") { + // If not blank first and last lines, abort. + return inlineSnapshot; + } + for (let i = 1; i < lines.length - 1; i++) { + if (lines[i] !== "") { + if (lines[i].indexOf(indentation) !== 0) { + // All lines except first and last should either be blank or have the same + // indent as the first line (or more). If this isn't the case we don't + // want to touch the snapshot at all. + return inlineSnapshot; + } + lines[i] = lines[i].substring(indentation.length); + } + } + // Last line is a special case because it won't have the same indent as others + // but may still have been given some indent to line up. + lines[lines.length - 1] = ""; + // Return inline snapshot, now at indent 0. + inlineSnapshot = lines.join("\n"); + return inlineSnapshot; +} + +async function saveRawSnapshots(environment, snapshots) { + await Promise.all(snapshots.map(async (snap) => { + if (!snap.readonly) { + await environment.saveSnapshotFile(snap.file, snap.snapshot); + } + })); +} + +var naturalCompare$1 = {exports: {}}; + +var hasRequiredNaturalCompare; + +function requireNaturalCompare () { + if (hasRequiredNaturalCompare) return naturalCompare$1.exports; + hasRequiredNaturalCompare = 1; + /* + * @version 1.4.0 + * @date 2015-10-26 + * @stability 3 - Stable + * @author Lauri Rooden (https://github.com/litejs/natural-compare-lite) + * @license MIT License + */ + + + var naturalCompare = function(a, b) { + var i, codeA + , codeB = 1 + , posA = 0 + , posB = 0 + , alphabet = String.alphabet; + + function getCode(str, pos, code) { + if (code) { + for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i; + return +str.slice(pos - 1, i) + } + code = alphabet && alphabet.indexOf(str.charAt(pos)); + return code > -1 ? code + 76 : ((code = str.charCodeAt(pos) || 0), code < 45 || code > 127) ? code + : code < 46 ? 65 // - + : code < 48 ? code - 1 + : code < 58 ? code + 18 // 0-9 + : code < 65 ? code - 11 + : code < 91 ? code + 11 // A-Z + : code < 97 ? code - 37 + : code < 123 ? code + 5 // a-z + : code - 63 + } + + + if ((a+="") != (b+="")) for (;codeB;) { + codeA = getCode(a, posA++); + codeB = getCode(b, posB++); + + if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) { + codeA = getCode(a, posA, posA); + codeB = getCode(b, posB, posA = i); + posB = i; + } + + if (codeA != codeB) return (codeA < codeB) ? -1 : 1 + } + return 0 + }; + + try { + naturalCompare$1.exports = naturalCompare; + } catch (e) { + String.naturalCompare = naturalCompare; + } + return naturalCompare$1.exports; +} + +var naturalCompareExports = requireNaturalCompare(); +var naturalCompare = /*@__PURE__*/getDefaultExportFromCjs(naturalCompareExports); + +const serialize$1 = (val, config, indentation, depth, refs, printer) => { + // Serialize a non-default name, even if config.printFunctionName is false. + const name = val.getMockName(); + const nameString = name === "vi.fn()" ? "" : ` ${name}`; + let callsString = ""; + if (val.mock.calls.length !== 0) { + const indentationNext = indentation + config.indent; + callsString = ` {${config.spacingOuter}${indentationNext}"calls": ${printer(val.mock.calls, config, indentationNext, depth, refs)}${config.min ? ", " : ","}${config.spacingOuter}${indentationNext}"results": ${printer(val.mock.results, config, indentationNext, depth, refs)}${config.min ? "" : ","}${config.spacingOuter}${indentation}}`; + } + return `[MockFunction${nameString}]${callsString}`; +}; +const test = (val) => val && !!val._isMockFunction; +const plugin = { + serialize: serialize$1, + test +}; + +const { DOMCollection, DOMElement, Immutable, ReactElement, ReactTestComponent, AsymmetricMatcher } = plugins; +let PLUGINS = [ + ReactTestComponent, + ReactElement, + DOMElement, + DOMCollection, + Immutable, + AsymmetricMatcher, + plugin +]; +function addSerializer(plugin) { + PLUGINS = [plugin].concat(PLUGINS); +} +function getSerializers() { + return PLUGINS; +} + +// TODO: rewrite and clean up +function testNameToKey(testName, count) { + return `${testName} ${count}`; +} +function keyToTestName(key) { + if (!/ \d+$/.test(key)) { + throw new Error("Snapshot keys must end with a number."); + } + return key.replace(/ \d+$/, ""); +} +function getSnapshotData(content, options) { + const update = options.updateSnapshot; + const data = Object.create(null); + let snapshotContents = ""; + let dirty = false; + if (content != null) { + try { + snapshotContents = content; + // eslint-disable-next-line no-new-func + const populate = new Function("exports", snapshotContents); + populate(data); + } catch {} + } + // const validationResult = validateSnapshotVersion(snapshotContents) + const isInvalid = snapshotContents; + // if (update === 'none' && isInvalid) + // throw validationResult + if ((update === "all" || update === "new") && isInvalid) { + dirty = true; + } + return { + data, + dirty + }; +} +// Add extra line breaks at beginning and end of multiline snapshot +// to make the content easier to read. +function addExtraLineBreaks(string) { + return string.includes("\n") ? `\n${string}\n` : string; +} +// Remove extra line breaks at beginning and end of multiline snapshot. +// Instead of trim, which can remove additional newlines or spaces +// at beginning or end of the content from a custom serializer. +function removeExtraLineBreaks(string) { + return string.length > 2 && string.startsWith("\n") && string.endsWith("\n") ? string.slice(1, -1) : string; +} +// export const removeLinesBeforeExternalMatcherTrap = (stack: string): string => { +// const lines = stack.split('\n') +// for (let i = 0; i < lines.length; i += 1) { +// // It's a function name specified in `packages/expect/src/index.ts` +// // for external custom matchers. +// if (lines[i].includes('__EXTERNAL_MATCHER_TRAP__')) +// return lines.slice(i + 1).join('\n') +// } +// return stack +// } +const escapeRegex = true; +const printFunctionName = false; +function serialize(val, indent = 2, formatOverrides = {}) { + return normalizeNewlines(format(val, { + escapeRegex, + indent, + plugins: getSerializers(), + printFunctionName, + ...formatOverrides + })); +} +function escapeBacktickString(str) { + return str.replace(/`|\\|\$\{/g, "\\$&"); +} +function printBacktickString(str) { + return `\`${escapeBacktickString(str)}\``; +} +function normalizeNewlines(string) { + return string.replace(/\r\n|\r/g, "\n"); +} +async function saveSnapshotFile(environment, snapshotData, snapshotPath) { + const snapshots = Object.keys(snapshotData).sort(naturalCompare).map((key) => `exports[${printBacktickString(key)}] = ${printBacktickString(normalizeNewlines(snapshotData[key]))};`); + const content = `${environment.getHeader()}\n\n${snapshots.join("\n\n")}\n`; + const oldContent = await environment.readSnapshotFile(snapshotPath); + const skipWriting = oldContent != null && oldContent === content; + if (skipWriting) { + return; + } + await environment.saveSnapshotFile(snapshotPath, content); +} +function deepMergeArray(target = [], source = []) { + const mergedOutput = Array.from(target); + source.forEach((sourceElement, index) => { + const targetElement = mergedOutput[index]; + if (Array.isArray(target[index])) { + mergedOutput[index] = deepMergeArray(target[index], sourceElement); + } else if (isObject(targetElement)) { + mergedOutput[index] = deepMergeSnapshot(target[index], sourceElement); + } else { + // Source does not exist in target or target is primitive and cannot be deep merged + mergedOutput[index] = sourceElement; + } + }); + return mergedOutput; +} +/** +* Deep merge, but considers asymmetric matchers. Unlike base util's deep merge, +* will merge any object-like instance. +* Compatible with Jest's snapshot matcher. Should not be used outside of snapshot. +* +* @example +* ```ts +* toMatchSnapshot({ +* name: expect.stringContaining('text') +* }) +* ``` +*/ +function deepMergeSnapshot(target, source) { + if (isObject(target) && isObject(source)) { + const mergedOutput = { ...target }; + Object.keys(source).forEach((key) => { + if (isObject(source[key]) && !source[key].$$typeof) { + if (!(key in target)) { + Object.assign(mergedOutput, { [key]: source[key] }); + } else { + mergedOutput[key] = deepMergeSnapshot(target[key], source[key]); + } + } else if (Array.isArray(source[key])) { + mergedOutput[key] = deepMergeArray(target[key], source[key]); + } else { + Object.assign(mergedOutput, { [key]: source[key] }); + } + }); + return mergedOutput; + } else if (Array.isArray(target) && Array.isArray(source)) { + return deepMergeArray(target, source); + } + return target; +} +class DefaultMap extends Map { + constructor(defaultFn, entries) { + super(entries); + this.defaultFn = defaultFn; + } + get(key) { + if (!this.has(key)) { + this.set(key, this.defaultFn(key)); + } + return super.get(key); + } +} +class CounterMap extends DefaultMap { + constructor() { + super(() => 0); + } + // compat for jest-image-snapshot https://github.com/vitest-dev/vitest/issues/7322 + // `valueOf` and `Snapshot.added` setter allows + // snapshotState.added = snapshotState.added + 1 + // to function as + // snapshotState.added.total_ = snapshotState.added.total() + 1 + _total; + valueOf() { + return this._total = this.total(); + } + increment(key) { + if (typeof this._total !== "undefined") { + this._total++; + } + this.set(key, this.get(key) + 1); + } + total() { + if (typeof this._total !== "undefined") { + return this._total; + } + let total = 0; + for (const x of this.values()) { + total += x; + } + return total; + } +} + +function isSameStackPosition(x, y) { + return x.file === y.file && x.column === y.column && x.line === y.line; +} +class SnapshotState { + _counters = new CounterMap(); + _dirty; + _updateSnapshot; + _snapshotData; + _initialData; + _inlineSnapshots; + _inlineSnapshotStacks; + _testIdToKeys = new DefaultMap(() => []); + _rawSnapshots; + _uncheckedKeys; + _snapshotFormat; + _environment; + _fileExists; + expand; + // getter/setter for jest-image-snapshot compat + // https://github.com/vitest-dev/vitest/issues/7322 + _added = new CounterMap(); + _matched = new CounterMap(); + _unmatched = new CounterMap(); + _updated = new CounterMap(); + get added() { + return this._added; + } + set added(value) { + this._added._total = value; + } + get matched() { + return this._matched; + } + set matched(value) { + this._matched._total = value; + } + get unmatched() { + return this._unmatched; + } + set unmatched(value) { + this._unmatched._total = value; + } + get updated() { + return this._updated; + } + set updated(value) { + this._updated._total = value; + } + constructor(testFilePath, snapshotPath, snapshotContent, options) { + this.testFilePath = testFilePath; + this.snapshotPath = snapshotPath; + const { data, dirty } = getSnapshotData(snapshotContent, options); + this._fileExists = snapshotContent != null; + this._initialData = { ...data }; + this._snapshotData = { ...data }; + this._dirty = dirty; + this._inlineSnapshots = []; + this._inlineSnapshotStacks = []; + this._rawSnapshots = []; + this._uncheckedKeys = new Set(Object.keys(this._snapshotData)); + this.expand = options.expand || false; + this._updateSnapshot = options.updateSnapshot; + this._snapshotFormat = { + printBasicPrototype: false, + escapeString: false, + ...options.snapshotFormat + }; + this._environment = options.snapshotEnvironment; + } + static async create(testFilePath, options) { + const snapshotPath = await options.snapshotEnvironment.resolvePath(testFilePath); + const content = await options.snapshotEnvironment.readSnapshotFile(snapshotPath); + return new SnapshotState(testFilePath, snapshotPath, content, options); + } + get environment() { + return this._environment; + } + markSnapshotsAsCheckedForTest(testName) { + this._uncheckedKeys.forEach((uncheckedKey) => { + // skip snapshots with following keys + // testName n + // testName > xxx n (this is for toMatchSnapshot("xxx") API) + if (/ \d+$| > /.test(uncheckedKey.slice(testName.length))) { + this._uncheckedKeys.delete(uncheckedKey); + } + }); + } + clearTest(testId) { + // clear inline + this._inlineSnapshots = this._inlineSnapshots.filter((s) => s.testId !== testId); + this._inlineSnapshotStacks = this._inlineSnapshotStacks.filter((s) => s.testId !== testId); + // clear file + for (const key of this._testIdToKeys.get(testId)) { + const name = keyToTestName(key); + const count = this._counters.get(name); + if (count > 0) { + if (key in this._snapshotData || key in this._initialData) { + this._snapshotData[key] = this._initialData[key]; + } + this._counters.set(name, count - 1); + } + } + this._testIdToKeys.delete(testId); + // clear stats + this.added.delete(testId); + this.updated.delete(testId); + this.matched.delete(testId); + this.unmatched.delete(testId); + } + _inferInlineSnapshotStack(stacks) { + // if called inside resolves/rejects, stacktrace is different + const promiseIndex = stacks.findIndex((i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/)); + if (promiseIndex !== -1) { + return stacks[promiseIndex + 3]; + } + // inline snapshot function is called __INLINE_SNAPSHOT__ + // in integrations/snapshot/chai.ts + const stackIndex = stacks.findIndex((i) => i.method.includes("__INLINE_SNAPSHOT__")); + return stackIndex !== -1 ? stacks[stackIndex + 2] : null; + } + _addSnapshot(key, receivedSerialized, options) { + this._dirty = true; + if (options.stack) { + this._inlineSnapshots.push({ + snapshot: receivedSerialized, + testId: options.testId, + ...options.stack + }); + } else if (options.rawSnapshot) { + this._rawSnapshots.push({ + ...options.rawSnapshot, + snapshot: receivedSerialized + }); + } else { + this._snapshotData[key] = receivedSerialized; + } + } + async save() { + const hasExternalSnapshots = Object.keys(this._snapshotData).length; + const hasInlineSnapshots = this._inlineSnapshots.length; + const hasRawSnapshots = this._rawSnapshots.length; + const isEmpty = !hasExternalSnapshots && !hasInlineSnapshots && !hasRawSnapshots; + const status = { + deleted: false, + saved: false + }; + if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) { + if (hasExternalSnapshots) { + await saveSnapshotFile(this._environment, this._snapshotData, this.snapshotPath); + this._fileExists = true; + } + if (hasInlineSnapshots) { + await saveInlineSnapshots(this._environment, this._inlineSnapshots); + } + if (hasRawSnapshots) { + await saveRawSnapshots(this._environment, this._rawSnapshots); + } + status.saved = true; + } else if (!hasExternalSnapshots && this._fileExists) { + if (this._updateSnapshot === "all") { + await this._environment.removeSnapshotFile(this.snapshotPath); + this._fileExists = false; + } + status.deleted = true; + } + return status; + } + getUncheckedCount() { + return this._uncheckedKeys.size || 0; + } + getUncheckedKeys() { + return Array.from(this._uncheckedKeys); + } + removeUncheckedKeys() { + if (this._updateSnapshot === "all" && this._uncheckedKeys.size) { + this._dirty = true; + this._uncheckedKeys.forEach((key) => delete this._snapshotData[key]); + this._uncheckedKeys.clear(); + } + } + match({ testId, testName, received, key, inlineSnapshot, isInline, error, rawSnapshot }) { + // this also increments counter for inline snapshots. maybe we shouldn't? + this._counters.increment(testName); + const count = this._counters.get(testName); + if (!key) { + key = testNameToKey(testName, count); + } + this._testIdToKeys.get(testId).push(key); + // Do not mark the snapshot as "checked" if the snapshot is inline and + // there's an external snapshot. This way the external snapshot can be + // removed with `--updateSnapshot`. + if (!(isInline && this._snapshotData[key] !== undefined)) { + this._uncheckedKeys.delete(key); + } + let receivedSerialized = rawSnapshot && typeof received === "string" ? received : serialize(received, undefined, this._snapshotFormat); + if (!rawSnapshot) { + receivedSerialized = addExtraLineBreaks(receivedSerialized); + } + if (rawSnapshot) { + // normalize EOL when snapshot contains CRLF but received is LF + if (rawSnapshot.content && rawSnapshot.content.match(/\r\n/) && !receivedSerialized.match(/\r\n/)) { + rawSnapshot.content = normalizeNewlines(rawSnapshot.content); + } + } + const expected = isInline ? inlineSnapshot : rawSnapshot ? rawSnapshot.content : this._snapshotData[key]; + const expectedTrimmed = rawSnapshot ? expected : expected === null || expected === void 0 ? void 0 : expected.trim(); + const pass = expectedTrimmed === (rawSnapshot ? receivedSerialized : receivedSerialized.trim()); + const hasSnapshot = expected !== undefined; + const snapshotIsPersisted = isInline || this._fileExists || rawSnapshot && rawSnapshot.content != null; + if (pass && !isInline && !rawSnapshot) { + // Executing a snapshot file as JavaScript and writing the strings back + // when other snapshots have changed loses the proper escaping for some + // characters. Since we check every snapshot in every test, use the newly + // generated formatted string. + // Note that this is only relevant when a snapshot is added and the dirty + // flag is set. + this._snapshotData[key] = receivedSerialized; + } + // find call site of toMatchInlineSnapshot + let stack; + if (isInline) { + var _this$environment$pro, _this$environment; + const stacks = parseErrorStacktrace(error || new Error("snapshot"), { ignoreStackEntries: [] }); + const _stack = this._inferInlineSnapshotStack(stacks); + if (!_stack) { + throw new Error(`@vitest/snapshot: Couldn't infer stack frame for inline snapshot.\n${JSON.stringify(stacks)}`); + } + stack = ((_this$environment$pro = (_this$environment = this.environment).processStackTrace) === null || _this$environment$pro === void 0 ? void 0 : _this$environment$pro.call(_this$environment, _stack)) || _stack; + // removing 1 column, because source map points to the wrong + // location for js files, but `column-1` points to the same in both js/ts + // https://github.com/vitejs/vite/issues/8657 + stack.column--; + // reject multiple inline snapshots at the same location if snapshot is different + const snapshotsWithSameStack = this._inlineSnapshotStacks.filter((s) => isSameStackPosition(s, stack)); + if (snapshotsWithSameStack.length > 0) { + // ensure only one snapshot will be written at the same location + this._inlineSnapshots = this._inlineSnapshots.filter((s) => !isSameStackPosition(s, stack)); + const differentSnapshot = snapshotsWithSameStack.find((s) => s.snapshot !== receivedSerialized); + if (differentSnapshot) { + throw Object.assign(new Error("toMatchInlineSnapshot with different snapshots cannot be called at the same location"), { + actual: receivedSerialized, + expected: differentSnapshot.snapshot + }); + } + } + this._inlineSnapshotStacks.push({ + ...stack, + testId, + snapshot: receivedSerialized + }); + } + // These are the conditions on when to write snapshots: + // * There's no snapshot file in a non-CI environment. + // * There is a snapshot file and we decided to update the snapshot. + // * There is a snapshot file, but it doesn't have this snapshot. + // These are the conditions on when not to write snapshots: + // * The update flag is set to 'none'. + // * There's no snapshot file or a file without this snapshot on a CI environment. + if (hasSnapshot && this._updateSnapshot === "all" || (!hasSnapshot || !snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) { + if (this._updateSnapshot === "all") { + if (!pass) { + if (hasSnapshot) { + this.updated.increment(testId); + } else { + this.added.increment(testId); + } + this._addSnapshot(key, receivedSerialized, { + stack, + testId, + rawSnapshot + }); + } else { + this.matched.increment(testId); + } + } else { + this._addSnapshot(key, receivedSerialized, { + stack, + testId, + rawSnapshot + }); + this.added.increment(testId); + } + return { + actual: "", + count, + expected: "", + key, + pass: true + }; + } else { + if (!pass) { + this.unmatched.increment(testId); + return { + actual: rawSnapshot ? receivedSerialized : removeExtraLineBreaks(receivedSerialized), + count, + expected: expectedTrimmed !== undefined ? rawSnapshot ? expectedTrimmed : removeExtraLineBreaks(expectedTrimmed) : undefined, + key, + pass: false + }; + } else { + this.matched.increment(testId); + return { + actual: "", + count, + expected: "", + key, + pass: true + }; + } + } + } + async pack() { + const snapshot = { + filepath: this.testFilePath, + added: 0, + fileDeleted: false, + matched: 0, + unchecked: 0, + uncheckedKeys: [], + unmatched: 0, + updated: 0 + }; + const uncheckedCount = this.getUncheckedCount(); + const uncheckedKeys = this.getUncheckedKeys(); + if (uncheckedCount) { + this.removeUncheckedKeys(); + } + const status = await this.save(); + snapshot.fileDeleted = status.deleted; + snapshot.added = this.added.total(); + snapshot.matched = this.matched.total(); + snapshot.unmatched = this.unmatched.total(); + snapshot.updated = this.updated.total(); + snapshot.unchecked = !status.deleted ? uncheckedCount : 0; + snapshot.uncheckedKeys = Array.from(uncheckedKeys); + return snapshot; + } +} + +function createMismatchError(message, expand, actual, expected) { + const error = new Error(message); + Object.defineProperty(error, "actual", { + value: actual, + enumerable: true, + configurable: true, + writable: true + }); + Object.defineProperty(error, "expected", { + value: expected, + enumerable: true, + configurable: true, + writable: true + }); + Object.defineProperty(error, "diffOptions", { value: { expand } }); + return error; +} +class SnapshotClient { + snapshotStateMap = new Map(); + constructor(options = {}) { + this.options = options; + } + async setup(filepath, options) { + if (this.snapshotStateMap.has(filepath)) { + return; + } + this.snapshotStateMap.set(filepath, await SnapshotState.create(filepath, options)); + } + async finish(filepath) { + const state = this.getSnapshotState(filepath); + const result = await state.pack(); + this.snapshotStateMap.delete(filepath); + return result; + } + skipTest(filepath, testName) { + const state = this.getSnapshotState(filepath); + state.markSnapshotsAsCheckedForTest(testName); + } + clearTest(filepath, testId) { + const state = this.getSnapshotState(filepath); + state.clearTest(testId); + } + getSnapshotState(filepath) { + const state = this.snapshotStateMap.get(filepath); + if (!state) { + throw new Error(`The snapshot state for '${filepath}' is not found. Did you call 'SnapshotClient.setup()'?`); + } + return state; + } + assert(options) { + const { filepath, name, testId = name, message, isInline = false, properties, inlineSnapshot, error, errorMessage, rawSnapshot } = options; + let { received } = options; + if (!filepath) { + throw new Error("Snapshot cannot be used outside of test"); + } + const snapshotState = this.getSnapshotState(filepath); + if (typeof properties === "object") { + if (typeof received !== "object" || !received) { + throw new Error("Received value must be an object when the matcher has properties"); + } + try { + var _this$options$isEqual, _this$options; + const pass = ((_this$options$isEqual = (_this$options = this.options).isEqual) === null || _this$options$isEqual === void 0 ? void 0 : _this$options$isEqual.call(_this$options, received, properties)) ?? false; + // const pass = equals(received, properties, [iterableEquality, subsetEquality]) + if (!pass) { + throw createMismatchError("Snapshot properties mismatched", snapshotState.expand, received, properties); + } else { + received = deepMergeSnapshot(received, properties); + } + } catch (err) { + err.message = errorMessage || "Snapshot mismatched"; + throw err; + } + } + const testName = [name, ...message ? [message] : []].join(" > "); + const { actual, expected, key, pass } = snapshotState.match({ + testId, + testName, + received, + isInline, + error, + inlineSnapshot, + rawSnapshot + }); + if (!pass) { + throw createMismatchError(`Snapshot \`${key || "unknown"}\` mismatched`, snapshotState.expand, rawSnapshot ? actual : actual === null || actual === void 0 ? void 0 : actual.trim(), rawSnapshot ? expected : expected === null || expected === void 0 ? void 0 : expected.trim()); + } + } + async assertRaw(options) { + if (!options.rawSnapshot) { + throw new Error("Raw snapshot is required"); + } + const { filepath, rawSnapshot } = options; + if (rawSnapshot.content == null) { + if (!filepath) { + throw new Error("Snapshot cannot be used outside of test"); + } + const snapshotState = this.getSnapshotState(filepath); + // save the filepath, so it don't lose even if the await make it out-of-context + options.filepath || (options.filepath = filepath); + // resolve and read the raw snapshot file + rawSnapshot.file = await snapshotState.environment.resolveRawPath(filepath, rawSnapshot.file); + rawSnapshot.content = await snapshotState.environment.readSnapshotFile(rawSnapshot.file) ?? undefined; + } + return this.assert(options); + } + clear() { + this.snapshotStateMap.clear(); + } +} + +export { SnapshotClient, SnapshotState, addSerializer, getSerializers, stripSnapshotIndentation }; diff --git a/node_modules/@vitest/snapshot/dist/manager.d.ts b/node_modules/@vitest/snapshot/dist/manager.d.ts new file mode 100644 index 0000000000..a782935dfd --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/manager.d.ts @@ -0,0 +1,18 @@ +import { S as SnapshotStateOptions, e as SnapshotSummary, b as SnapshotResult } from './rawSnapshot.d-lFsMJFUd.js'; +import '@vitest/pretty-format'; +import './environment.d-DHdQ1Csl.js'; + +declare class SnapshotManager { + options: Omit; + summary: SnapshotSummary; + extension: string; + constructor(options: Omit); + clear(): void; + add(result: SnapshotResult): void; + resolvePath(testPath: string, context?: T): string; + resolveRawPath(testPath: string, rawPath: string): string; +} +declare function emptySummary(options: Omit): SnapshotSummary; +declare function addSnapshotResult(summary: SnapshotSummary, result: SnapshotResult): void; + +export { SnapshotManager, addSnapshotResult, emptySummary }; diff --git a/node_modules/@vitest/snapshot/dist/manager.js b/node_modules/@vitest/snapshot/dist/manager.js new file mode 100644 index 0000000000..90a36a3ee3 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/manager.js @@ -0,0 +1,73 @@ +import { join, dirname, basename, resolve, isAbsolute } from 'pathe'; + +class SnapshotManager { + summary; + extension = ".snap"; + constructor(options) { + this.options = options; + this.clear(); + } + clear() { + this.summary = emptySummary(this.options); + } + add(result) { + addSnapshotResult(this.summary, result); + } + resolvePath(testPath, context) { + const resolver = this.options.resolveSnapshotPath || (() => { + return join(join(dirname(testPath), "__snapshots__"), `${basename(testPath)}${this.extension}`); + }); + const path = resolver(testPath, this.extension, context); + return path; + } + resolveRawPath(testPath, rawPath) { + return isAbsolute(rawPath) ? rawPath : resolve(dirname(testPath), rawPath); + } +} +function emptySummary(options) { + const summary = { + added: 0, + failure: false, + filesAdded: 0, + filesRemoved: 0, + filesRemovedList: [], + filesUnmatched: 0, + filesUpdated: 0, + matched: 0, + total: 0, + unchecked: 0, + uncheckedKeysByFile: [], + unmatched: 0, + updated: 0, + didUpdate: options.updateSnapshot === "all" + }; + return summary; +} +function addSnapshotResult(summary, result) { + if (result.added) { + summary.filesAdded++; + } + if (result.fileDeleted) { + summary.filesRemoved++; + } + if (result.unmatched) { + summary.filesUnmatched++; + } + if (result.updated) { + summary.filesUpdated++; + } + summary.added += result.added; + summary.matched += result.matched; + summary.unchecked += result.unchecked; + if (result.uncheckedKeys && result.uncheckedKeys.length > 0) { + summary.uncheckedKeysByFile.push({ + filePath: result.filepath, + keys: result.uncheckedKeys + }); + } + summary.unmatched += result.unmatched; + summary.updated += result.updated; + summary.total += result.added + result.matched + result.unmatched + result.updated; +} + +export { SnapshotManager, addSnapshotResult, emptySummary }; diff --git a/node_modules/@vitest/snapshot/dist/rawSnapshot.d-lFsMJFUd.d.ts b/node_modules/@vitest/snapshot/dist/rawSnapshot.d-lFsMJFUd.d.ts new file mode 100644 index 0000000000..96fa2ddbd6 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/rawSnapshot.d-lFsMJFUd.d.ts @@ -0,0 +1,61 @@ +import { OptionsReceived, Plugin } from '@vitest/pretty-format'; +import { S as SnapshotEnvironment } from './environment.d-DHdQ1Csl.js'; + +type SnapshotData = Record; +type SnapshotUpdateState = "all" | "new" | "none"; +type SnapshotSerializer = Plugin; +interface SnapshotStateOptions { + updateSnapshot: SnapshotUpdateState; + snapshotEnvironment: SnapshotEnvironment; + expand?: boolean; + snapshotFormat?: OptionsReceived; + resolveSnapshotPath?: (path: string, extension: string, context?: any) => string; +} +interface SnapshotMatchOptions { + testId: string; + testName: string; + received: unknown; + key?: string; + inlineSnapshot?: string; + isInline: boolean; + error?: Error; + rawSnapshot?: RawSnapshotInfo; +} +interface SnapshotResult { + filepath: string; + added: number; + fileDeleted: boolean; + matched: number; + unchecked: number; + uncheckedKeys: Array; + unmatched: number; + updated: number; +} +interface UncheckedSnapshot { + filePath: string; + keys: Array; +} +interface SnapshotSummary { + added: number; + didUpdate: boolean; + failure: boolean; + filesAdded: number; + filesRemoved: number; + filesRemovedList: Array; + filesUnmatched: number; + filesUpdated: number; + matched: number; + total: number; + unchecked: number; + uncheckedKeysByFile: Array; + unmatched: number; + updated: number; +} + +interface RawSnapshotInfo { + file: string; + readonly?: boolean; + content?: string; +} + +export type { RawSnapshotInfo as R, SnapshotStateOptions as S, UncheckedSnapshot as U, SnapshotMatchOptions as a, SnapshotResult as b, SnapshotData as c, SnapshotSerializer as d, SnapshotSummary as e, SnapshotUpdateState as f }; diff --git a/node_modules/@vitest/snapshot/environment.d.ts b/node_modules/@vitest/snapshot/environment.d.ts new file mode 100644 index 0000000000..855f0d10a8 --- /dev/null +++ b/node_modules/@vitest/snapshot/environment.d.ts @@ -0,0 +1 @@ +export * from './dist/environment.js' diff --git a/node_modules/@vitest/snapshot/manager.d.ts b/node_modules/@vitest/snapshot/manager.d.ts new file mode 100644 index 0000000000..f3e80774b8 --- /dev/null +++ b/node_modules/@vitest/snapshot/manager.d.ts @@ -0,0 +1 @@ +export * from './dist/manager.js' diff --git a/node_modules/@vitest/snapshot/package.json b/node_modules/@vitest/snapshot/package.json new file mode 100644 index 0000000000..502789720f --- /dev/null +++ b/node_modules/@vitest/snapshot/package.json @@ -0,0 +1,54 @@ +{ + "name": "@vitest/snapshot", + "type": "module", + "version": "3.2.4", + "description": "Vitest snapshot manager", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/snapshot#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/snapshot" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./environment": { + "types": "./dist/environment.d.ts", + "default": "./dist/environment.js" + }, + "./manager": { + "types": "./dist/manager.d.ts", + "default": "./dist/manager.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "*.d.ts", + "dist" + ], + "dependencies": { + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "@vitest/pretty-format": "3.2.4" + }, + "devDependencies": { + "@types/natural-compare": "^1.4.3", + "natural-compare": "^1.4.0", + "@vitest/utils": "3.2.4" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/spy/LICENSE b/node_modules/@vitest/spy/LICENSE new file mode 100644 index 0000000000..5ae481fdb8 --- /dev/null +++ b/node_modules/@vitest/spy/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/spy/README.md b/node_modules/@vitest/spy/README.md new file mode 100644 index 0000000000..5d23c876f4 --- /dev/null +++ b/node_modules/@vitest/spy/README.md @@ -0,0 +1,3 @@ +# @vitest/spy + +Lightweight Jest compatible spy implementation. diff --git a/node_modules/@vitest/spy/dist/index.d.ts b/node_modules/@vitest/spy/dist/index.d.ts new file mode 100644 index 0000000000..daf9b04a43 --- /dev/null +++ b/node_modules/@vitest/spy/dist/index.d.ts @@ -0,0 +1,356 @@ +interface MockResultReturn { + type: "return"; + /** + * The value that was returned from the function. If function returned a Promise, then this will be a resolved value. + */ + value: T; +} +interface MockResultIncomplete { + type: "incomplete"; + value: undefined; +} +interface MockResultThrow { + type: "throw"; + /** + * An error that was thrown during function execution. + */ + value: any; +} +interface MockSettledResultFulfilled { + type: "fulfilled"; + value: T; +} +interface MockSettledResultRejected { + type: "rejected"; + value: any; +} +type MockResult = MockResultReturn | MockResultThrow | MockResultIncomplete; +type MockSettledResult = MockSettledResultFulfilled | MockSettledResultRejected; +interface MockContext { + /** + * This is an array containing all arguments for each call. One item of the array is the arguments of that call. + * + * @see https://vitest.dev/api/mock#mock-calls + * @example + * const fn = vi.fn() + * + * fn('arg1', 'arg2') + * fn('arg3') + * + * fn.mock.calls === [ + * ['arg1', 'arg2'], // first call + * ['arg3'], // second call + * ] + */ + calls: Parameters[]; + /** + * This is an array containing all instances that were instantiated when mock was called with a `new` keyword. Note that this is an actual context (`this`) of the function, not a return value. + * @see https://vitest.dev/api/mock#mock-instances + */ + instances: ReturnType[]; + /** + * An array of `this` values that were used during each call to the mock function. + * @see https://vitest.dev/api/mock#mock-contexts + */ + contexts: ThisParameterType[]; + /** + * The order of mock's execution. This returns an array of numbers which are shared between all defined mocks. + * + * @see https://vitest.dev/api/mock#mock-invocationcallorder + * @example + * const fn1 = vi.fn() + * const fn2 = vi.fn() + * + * fn1() + * fn2() + * fn1() + * + * fn1.mock.invocationCallOrder === [1, 3] + * fn2.mock.invocationCallOrder === [2] + */ + invocationCallOrder: number[]; + /** + * This is an array containing all values that were `returned` from the function. + * + * The `value` property contains the returned value or thrown error. If the function returned a `Promise`, then `result` will always be `'return'` even if the promise was rejected. + * + * @see https://vitest.dev/api/mock#mock-results + * @example + * const fn = vi.fn() + * .mockReturnValueOnce('result') + * .mockImplementationOnce(() => { throw new Error('thrown error') }) + * + * const result = fn() + * + * try { + * fn() + * } + * catch {} + * + * fn.mock.results === [ + * { + * type: 'return', + * value: 'result', + * }, + * { + * type: 'throw', + * value: Error, + * }, + * ] + */ + results: MockResult>[]; + /** + * An array containing all values that were `resolved` or `rejected` from the function. + * + * This array will be empty if the function was never resolved or rejected. + * + * @see https://vitest.dev/api/mock#mock-settledresults + * @example + * const fn = vi.fn().mockResolvedValueOnce('result') + * + * const result = fn() + * + * fn.mock.settledResults === [] + * fn.mock.results === [ + * { + * type: 'return', + * value: Promise<'result'>, + * }, + * ] + * + * await result + * + * fn.mock.settledResults === [ + * { + * type: 'fulfilled', + * value: 'result', + * }, + * ] + */ + settledResults: MockSettledResult>>[]; + /** + * This contains the arguments of the last call. If spy wasn't called, will return `undefined`. + * @see https://vitest.dev/api/mock#mock-lastcall + */ + lastCall: Parameters | undefined; +} +type Procedure = (...args: any[]) => any; +// pick a single function type from function overloads, unions, etc... +type NormalizedProcedure = (...args: Parameters) => ReturnType; +type Methods = keyof { [K in keyof T as T[K] extends Procedure ? K : never] : T[K] }; +type Properties = { [K in keyof T] : T[K] extends Procedure ? never : K }[keyof T] & (string | symbol); +type Classes = { [K in keyof T] : T[K] extends new (...args: any[]) => any ? K : never }[keyof T] & (string | symbol); +/* +cf. https://typescript-eslint.io/rules/method-signature-style/ + +Typescript assignability is different between +{ foo: (f: T) => U } (this is "method-signature-style") +and +{ foo(f: T): U } + +Jest uses the latter for `MockInstance.mockImplementation` etc... and it allows assignment such as: +const boolFn: Jest.Mock<() => boolean> = jest.fn<() => true>(() => true) +*/ +/* eslint-disable ts/method-signature-style */ +interface MockInstance extends Disposable { + /** + * Use it to return the name assigned to the mock with the `.mockName(name)` method. By default, it will return `vi.fn()`. + * @see https://vitest.dev/api/mock#getmockname + */ + getMockName(): string; + /** + * Sets the internal mock name. This is useful for identifying the mock when an assertion fails. + * @see https://vitest.dev/api/mock#mockname + */ + mockName(name: string): this; + /** + * Current context of the mock. It stores information about all invocation calls, instances, and results. + */ + mock: MockContext; + /** + * Clears all information about every call. After calling it, all properties on `.mock` will return to their initial state. This method does not reset implementations. It is useful for cleaning up mocks between different assertions. + * + * To automatically call this method before each test, enable the [`clearMocks`](https://vitest.dev/config/#clearmocks) setting in the configuration. + * @see https://vitest.dev/api/mock#mockclear + */ + mockClear(): this; + /** + * Does what `mockClear` does and resets inner implementation to the original function. This also resets all "once" implementations. + * + * Note that resetting a mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. + * Resetting a mock from `vi.fn(impl)` will set implementation to `impl`. It is useful for completely resetting a mock to its default state. + * + * To automatically call this method before each test, enable the [`mockReset`](https://vitest.dev/config/#mockreset) setting in the configuration. + * @see https://vitest.dev/api/mock#mockreset + */ + mockReset(): this; + /** + * Does what `mockReset` does and restores original descriptors of spied-on objects. + * + * Note that restoring mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. Restoring a `vi.fn(impl)` will restore implementation to `impl`. + * @see https://vitest.dev/api/mock#mockrestore + */ + mockRestore(): void; + /** + * Returns current permanent mock implementation if there is one. + * + * If mock was created with `vi.fn`, it will consider passed down method as a mock implementation. + * + * If mock was created with `vi.spyOn`, it will return `undefined` unless a custom implementation was provided. + */ + getMockImplementation(): NormalizedProcedure | undefined; + /** + * Accepts a function to be used as the mock implementation. TypeScript expects the arguments and return type to match those of the original function. + * @see https://vitest.dev/api/mock#mockimplementation + * @example + * const increment = vi.fn().mockImplementation(count => count + 1); + * expect(increment(3)).toBe(4); + */ + mockImplementation(fn: NormalizedProcedure): this; + /** + * Accepts a function to be used as the mock implementation. TypeScript expects the arguments and return type to match those of the original function. This method can be chained to produce different results for multiple function calls. + * + * When the mocked function runs out of implementations, it will invoke the default implementation set with `vi.fn(() => defaultValue)` or `.mockImplementation(() => defaultValue)` if they were called. + * @see https://vitest.dev/api/mock#mockimplementationonce + * @example + * const fn = vi.fn(count => count).mockImplementationOnce(count => count + 1); + * expect(fn(3)).toBe(4); + * expect(fn(3)).toBe(3); + */ + mockImplementationOnce(fn: NormalizedProcedure): this; + /** + * Overrides the original mock implementation temporarily while the callback is being executed. + * + * Note that this method takes precedence over the [`mockImplementationOnce`](https://vitest.dev/api/mock#mockimplementationonce). + * @see https://vitest.dev/api/mock#withimplementation + * @example + * const myMockFn = vi.fn(() => 'original') + * + * myMockFn.withImplementation(() => 'temp', () => { + * myMockFn() // 'temp' + * }) + * + * myMockFn() // 'original' + */ + withImplementation(fn: NormalizedProcedure, cb: () => T2): T2 extends Promise ? Promise : this; + /** + * Use this if you need to return the `this` context from the method without invoking the actual implementation. + * @see https://vitest.dev/api/mock#mockreturnthis + */ + mockReturnThis(): this; + /** + * Accepts a value that will be returned whenever the mock function is called. TypeScript will only accept values that match the return type of the original function. + * @see https://vitest.dev/api/mock#mockreturnvalue + * @example + * const mock = vi.fn() + * mock.mockReturnValue(42) + * mock() // 42 + * mock.mockReturnValue(43) + * mock() // 43 + */ + mockReturnValue(value: ReturnType): this; + /** + * Accepts a value that will be returned whenever the mock function is called. TypeScript will only accept values that match the return type of the original function. + * + * When the mocked function runs out of implementations, it will invoke the default implementation set with `vi.fn(() => defaultValue)` or `.mockImplementation(() => defaultValue)` if they were called. + * @example + * const myMockFn = vi + * .fn() + * .mockReturnValue('default') + * .mockReturnValueOnce('first call') + * .mockReturnValueOnce('second call') + * + * // 'first call', 'second call', 'default' + * console.log(myMockFn(), myMockFn(), myMockFn()) + */ + mockReturnValueOnce(value: ReturnType): this; + /** + * Accepts a value that will be resolved when the async function is called. TypeScript will only accept values that match the return type of the original function. + * @example + * const asyncMock = vi.fn().mockResolvedValue(42) + * asyncMock() // Promise<42> + */ + mockResolvedValue(value: Awaited>): this; + /** + * Accepts a value that will be resolved during the next function call. TypeScript will only accept values that match the return type of the original function. If chained, each consecutive call will resolve the specified value. + * @example + * const myMockFn = vi + * .fn() + * .mockResolvedValue('default') + * .mockResolvedValueOnce('first call') + * .mockResolvedValueOnce('second call') + * + * // Promise<'first call'>, Promise<'second call'>, Promise<'default'> + * console.log(myMockFn(), myMockFn(), myMockFn()) + */ + mockResolvedValueOnce(value: Awaited>): this; + /** + * Accepts an error that will be rejected when async function is called. + * @example + * const asyncMock = vi.fn().mockRejectedValue(new Error('Async error')) + * await asyncMock() // throws Error<'Async error'> + */ + mockRejectedValue(error: unknown): this; + /** + * Accepts a value that will be rejected during the next function call. If chained, each consecutive call will reject the specified value. + * @example + * const asyncMock = vi + * .fn() + * .mockResolvedValueOnce('first call') + * .mockRejectedValueOnce(new Error('Async error')) + * + * await asyncMock() // first call + * await asyncMock() // throws Error<'Async error'> + */ + mockRejectedValueOnce(error: unknown): this; +} +/* eslint-enable ts/method-signature-style */ +interface Mock extends MockInstance { + new (...args: Parameters): ReturnType; + (...args: Parameters): ReturnType; +} +type PartialMaybePromise = T extends Promise> ? Promise>> : Partial; +interface PartialMock extends MockInstance<(...args: Parameters) => PartialMaybePromise>> { + new (...args: Parameters): ReturnType; + (...args: Parameters): ReturnType; +} +type MaybeMockedConstructor = T extends new (...args: Array) => infer R ? Mock<(...args: ConstructorParameters) => R> : T; +type MockedFunction = Mock & { [K in keyof T] : T[K] }; +type PartiallyMockedFunction = PartialMock & { [K in keyof T] : T[K] }; +type MockedFunctionDeep = Mock & MockedObjectDeep; +type PartiallyMockedFunctionDeep = PartialMock & MockedObjectDeep; +type MockedObject = MaybeMockedConstructor & { [K in Methods] : T[K] extends Procedure ? MockedFunction : T[K] } & { [K in Properties] : T[K] }; +type MockedObjectDeep = MaybeMockedConstructor & { [K in Methods] : T[K] extends Procedure ? MockedFunctionDeep : T[K] } & { [K in Properties] : MaybeMockedDeep }; +type MaybeMockedDeep = T extends Procedure ? MockedFunctionDeep : T extends object ? MockedObjectDeep : T; +type MaybePartiallyMockedDeep = T extends Procedure ? PartiallyMockedFunctionDeep : T extends object ? MockedObjectDeep : T; +type MaybeMocked = T extends Procedure ? MockedFunction : T extends object ? MockedObject : T; +type MaybePartiallyMocked = T extends Procedure ? PartiallyMockedFunction : T extends object ? MockedObject : T; +interface Constructable { + new (...args: any[]): any; +} +type MockedClass = MockInstance<(...args: ConstructorParameters) => InstanceType> & { + prototype: T extends { + prototype: any + } ? Mocked : never +} & T; +type Mocked = { [P in keyof T] : T[P] extends Procedure ? MockInstance : T[P] extends Constructable ? MockedClass : T[P] } & T; +declare const mocks: Set>; +declare function isMockFunction(fn: any): fn is MockInstance; +declare function spyOn< + T, + S extends Properties> +>(obj: T, methodName: S, accessType: "get"): MockInstance<() => T[S]>; +declare function spyOn< + T, + G extends Properties> +>(obj: T, methodName: G, accessType: "set"): MockInstance<(arg: T[G]) => void>; +declare function spyOn< + T, + M extends Classes> | Methods> +>(obj: T, methodName: M): Required[M] extends { + new (...args: infer A): infer R +} ? MockInstance<(this: R, ...args: A) => R> : T[M] extends Procedure ? MockInstance : never; +declare function fn(implementation?: T): Mock; + +export { fn, isMockFunction, mocks, spyOn }; +export type { MaybeMocked, MaybeMockedConstructor, MaybeMockedDeep, MaybePartiallyMocked, MaybePartiallyMockedDeep, Mock, MockContext, MockInstance, MockResult, MockSettledResult, Mocked, MockedClass, MockedFunction, MockedFunctionDeep, MockedObject, MockedObjectDeep, PartialMock, PartiallyMockedFunction, PartiallyMockedFunctionDeep }; diff --git a/node_modules/@vitest/spy/dist/index.js b/node_modules/@vitest/spy/dist/index.js new file mode 100644 index 0000000000..f9cfa1750d --- /dev/null +++ b/node_modules/@vitest/spy/dist/index.js @@ -0,0 +1,191 @@ +import * as tinyspy from 'tinyspy'; + +const mocks = new Set(); +function isMockFunction(fn) { + return typeof fn === "function" && "_isMockFunction" in fn && fn._isMockFunction; +} +function spyOn(obj, method, accessType) { + const dictionary = { + get: "getter", + set: "setter" + }; + const objMethod = accessType ? { [dictionary[accessType]]: method } : method; + let state; + const descriptor = getDescriptor(obj, method); + const fn = descriptor && descriptor[accessType || "value"]; + // inherit implementations if it was already mocked + if (isMockFunction(fn)) { + state = fn.mock._state(); + } + try { + const stub = tinyspy.internalSpyOn(obj, objMethod); + const spy = enhanceSpy(stub); + if (state) { + spy.mock._state(state); + } + return spy; + } catch (error) { + if (error instanceof TypeError && Symbol.toStringTag && obj[Symbol.toStringTag] === "Module" && (error.message.includes("Cannot redefine property") || error.message.includes("Cannot replace module namespace") || error.message.includes("can't redefine non-configurable property"))) { + throw new TypeError(`Cannot spy on export "${String(objMethod)}". Module namespace is not configurable in ESM. See: https://vitest.dev/guide/browser/#limitations`, { cause: error }); + } + throw error; + } +} +let callOrder = 0; +function enhanceSpy(spy) { + const stub = spy; + let implementation; + let onceImplementations = []; + let implementationChangedTemporarily = false; + let instances = []; + let contexts = []; + let invocations = []; + const state = tinyspy.getInternalState(spy); + const mockContext = { + get calls() { + return state.calls; + }, + get contexts() { + return contexts; + }, + get instances() { + return instances; + }, + get invocationCallOrder() { + return invocations; + }, + get results() { + return state.results.map(([callType, value]) => { + const type = callType === "error" ? "throw" : "return"; + return { + type, + value + }; + }); + }, + get settledResults() { + return state.resolves.map(([callType, value]) => { + const type = callType === "error" ? "rejected" : "fulfilled"; + return { + type, + value + }; + }); + }, + get lastCall() { + return state.calls[state.calls.length - 1]; + }, + _state(state) { + if (state) { + implementation = state.implementation; + onceImplementations = state.onceImplementations; + implementationChangedTemporarily = state.implementationChangedTemporarily; + } + return { + implementation, + onceImplementations, + implementationChangedTemporarily + }; + } + }; + function mockCall(...args) { + instances.push(this); + contexts.push(this); + invocations.push(++callOrder); + const impl = implementationChangedTemporarily ? implementation : onceImplementations.shift() || implementation || state.getOriginal() || (() => {}); + return impl.apply(this, args); + } + let name = stub.name; + stub.getMockName = () => name || "vi.fn()"; + stub.mockName = (n) => { + name = n; + return stub; + }; + stub.mockClear = () => { + state.reset(); + instances = []; + contexts = []; + invocations = []; + return stub; + }; + stub.mockReset = () => { + stub.mockClear(); + implementation = undefined; + onceImplementations = []; + return stub; + }; + stub.mockRestore = () => { + stub.mockReset(); + state.restore(); + return stub; + }; + if (Symbol.dispose) { + stub[Symbol.dispose] = () => stub.mockRestore(); + } + stub.getMockImplementation = () => implementationChangedTemporarily ? implementation : onceImplementations.at(0) || implementation; + stub.mockImplementation = (fn) => { + implementation = fn; + state.willCall(mockCall); + return stub; + }; + stub.mockImplementationOnce = (fn) => { + onceImplementations.push(fn); + return stub; + }; + function withImplementation(fn, cb) { + const originalImplementation = implementation; + implementation = fn; + state.willCall(mockCall); + implementationChangedTemporarily = true; + const reset = () => { + implementation = originalImplementation; + implementationChangedTemporarily = false; + }; + const result = cb(); + if (typeof result === "object" && result && typeof result.then === "function") { + return result.then(() => { + reset(); + return stub; + }); + } + reset(); + return stub; + } + stub.withImplementation = withImplementation; + stub.mockReturnThis = () => stub.mockImplementation(function() { + return this; + }); + stub.mockReturnValue = (val) => stub.mockImplementation(() => val); + stub.mockReturnValueOnce = (val) => stub.mockImplementationOnce(() => val); + stub.mockResolvedValue = (val) => stub.mockImplementation(() => Promise.resolve(val)); + stub.mockResolvedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.resolve(val)); + stub.mockRejectedValue = (val) => stub.mockImplementation(() => Promise.reject(val)); + stub.mockRejectedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.reject(val)); + Object.defineProperty(stub, "mock", { get: () => mockContext }); + state.willCall(mockCall); + mocks.add(stub); + return stub; +} +function fn(implementation) { + const enhancedSpy = enhanceSpy(tinyspy.internalSpyOn({ spy: implementation || function() {} }, "spy")); + if (implementation) { + enhancedSpy.mockImplementation(implementation); + } + return enhancedSpy; +} +function getDescriptor(obj, method) { + const objDescriptor = Object.getOwnPropertyDescriptor(obj, method); + if (objDescriptor) { + return objDescriptor; + } + let currentProto = Object.getPrototypeOf(obj); + while (currentProto !== null) { + const descriptor = Object.getOwnPropertyDescriptor(currentProto, method); + if (descriptor) { + return descriptor; + } + currentProto = Object.getPrototypeOf(currentProto); + } +} + +export { fn, isMockFunction, mocks, spyOn }; diff --git a/node_modules/@vitest/spy/package.json b/node_modules/@vitest/spy/package.json new file mode 100644 index 0000000000..4962a78d17 --- /dev/null +++ b/node_modules/@vitest/spy/package.json @@ -0,0 +1,38 @@ +{ + "name": "@vitest/spy", + "type": "module", + "version": "3.2.4", + "description": "Lightweight Jest compatible spy implementation", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/spy#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/spy" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "dependencies": { + "tinyspy": "^4.0.3" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/utils/LICENSE b/node_modules/@vitest/utils/LICENSE new file mode 100644 index 0000000000..5ae481fdb8 --- /dev/null +++ b/node_modules/@vitest/utils/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/utils/diff.d.ts b/node_modules/@vitest/utils/diff.d.ts new file mode 100644 index 0000000000..0a66b86595 --- /dev/null +++ b/node_modules/@vitest/utils/diff.d.ts @@ -0,0 +1 @@ +export * from './dist/diff.js' diff --git a/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js b/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js new file mode 100644 index 0000000000..a8647550ee --- /dev/null +++ b/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js @@ -0,0 +1,158 @@ +import { plugins, format as format$1 } from '@vitest/pretty-format'; +import * as loupe from 'loupe'; + +const { AsymmetricMatcher, DOMCollection, DOMElement, Immutable, ReactElement, ReactTestComponent } = plugins; +const PLUGINS = [ + ReactTestComponent, + ReactElement, + DOMElement, + DOMCollection, + Immutable, + AsymmetricMatcher +]; +function stringify(object, maxDepth = 10, { maxLength,...options } = {}) { + const MAX_LENGTH = maxLength ?? 1e4; + let result; + try { + result = format$1(object, { + maxDepth, + escapeString: false, + plugins: PLUGINS, + ...options + }); + } catch { + result = format$1(object, { + callToJSON: false, + maxDepth, + escapeString: false, + plugins: PLUGINS, + ...options + }); + } + // Prevents infinite loop https://github.com/vitest-dev/vitest/issues/7249 + return result.length >= MAX_LENGTH && maxDepth > 1 ? stringify(object, Math.floor(Math.min(maxDepth, Number.MAX_SAFE_INTEGER) / 2), { + maxLength, + ...options + }) : result; +} +const formatRegExp = /%[sdjifoOc%]/g; +function format(...args) { + if (typeof args[0] !== "string") { + const objects = []; + for (let i = 0; i < args.length; i++) { + objects.push(inspect(args[i], { + depth: 0, + colors: false + })); + } + return objects.join(" "); + } + const len = args.length; + let i = 1; + const template = args[0]; + let str = String(template).replace(formatRegExp, (x) => { + if (x === "%%") { + return "%"; + } + if (i >= len) { + return x; + } + switch (x) { + case "%s": { + const value = args[i++]; + if (typeof value === "bigint") { + return `${value.toString()}n`; + } + if (typeof value === "number" && value === 0 && 1 / value < 0) { + return "-0"; + } + if (typeof value === "object" && value !== null) { + if (typeof value.toString === "function" && value.toString !== Object.prototype.toString) { + return value.toString(); + } + return inspect(value, { + depth: 0, + colors: false + }); + } + return String(value); + } + case "%d": { + const value = args[i++]; + if (typeof value === "bigint") { + return `${value.toString()}n`; + } + return Number(value).toString(); + } + case "%i": { + const value = args[i++]; + if (typeof value === "bigint") { + return `${value.toString()}n`; + } + return Number.parseInt(String(value)).toString(); + } + case "%f": return Number.parseFloat(String(args[i++])).toString(); + case "%o": return inspect(args[i++], { + showHidden: true, + showProxy: true + }); + case "%O": return inspect(args[i++]); + case "%c": { + i++; + return ""; + } + case "%j": try { + return JSON.stringify(args[i++]); + } catch (err) { + const m = err.message; + if (m.includes("circular structure") || m.includes("cyclic structures") || m.includes("cyclic object")) { + return "[Circular]"; + } + throw err; + } + default: return x; + } + }); + for (let x = args[i]; i < len; x = args[++i]) { + if (x === null || typeof x !== "object") { + str += ` ${x}`; + } else { + str += ` ${inspect(x)}`; + } + } + return str; +} +function inspect(obj, options = {}) { + if (options.truncate === 0) { + options.truncate = Number.POSITIVE_INFINITY; + } + return loupe.inspect(obj, options); +} +function objDisplay(obj, options = {}) { + if (typeof options.truncate === "undefined") { + options.truncate = 40; + } + const str = inspect(obj, options); + const type = Object.prototype.toString.call(obj); + if (options.truncate && str.length >= options.truncate) { + if (type === "[object Function]") { + const fn = obj; + return !fn.name ? "[Function]" : `[Function: ${fn.name}]`; + } else if (type === "[object Array]") { + return `[ Array(${obj.length}) ]`; + } else if (type === "[object Object]") { + const keys = Object.keys(obj); + const kstr = keys.length > 2 ? `${keys.splice(0, 2).join(", ")}, ...` : keys.join(", "); + return `{ Object (${kstr}) }`; + } else { + return str; + } + } + return str; +} + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +export { format as f, getDefaultExportFromCjs as g, inspect as i, objDisplay as o, stringify as s }; diff --git a/node_modules/@vitest/utils/dist/diff.d.ts b/node_modules/@vitest/utils/dist/diff.d.ts new file mode 100644 index 0000000000..b8addc3701 --- /dev/null +++ b/node_modules/@vitest/utils/dist/diff.d.ts @@ -0,0 +1,104 @@ +import { D as DiffOptions } from './types.d-BCElaP-c.js'; +export { a as DiffOptionsColor, S as SerializedDiffOptions } from './types.d-BCElaP-c.js'; +import '@vitest/pretty-format'; + +/** +* Diff Match and Patch +* Copyright 2018 The diff-match-patch Authors. +* https://github.com/google/diff-match-patch +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** +* @fileoverview Computes the difference between two texts to create a patch. +* Applies the patch onto another text, allowing for errors. +* @author fraser@google.com (Neil Fraser) +*/ +/** +* CHANGES by pedrottimark to diff_match_patch_uncompressed.ts file: +* +* 1. Delete anything not needed to use diff_cleanupSemantic method +* 2. Convert from prototype properties to var declarations +* 3. Convert Diff to class from constructor and prototype +* 4. Add type annotations for arguments and return values +* 5. Add exports +*/ +/** +* The data structure representing a diff is an array of tuples: +* [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']] +* which means: delete 'Hello', add 'Goodbye' and keep ' world.' +*/ +declare const DIFF_DELETE = -1; +declare const DIFF_INSERT = 1; +declare const DIFF_EQUAL = 0; +/** +* Class representing one diff tuple. +* Attempts to look like a two-element array (which is what this used to be). +* @param {number} op Operation, one of: DIFF_DELETE, DIFF_INSERT, DIFF_EQUAL. +* @param {string} text Text to be deleted, inserted, or retained. +* @constructor +*/ +declare class Diff { + 0: number; + 1: string; + constructor(op: number, text: string); +} + +/** +* Copyright (c) Meta Platforms, Inc. and affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + +// Compare two arrays of strings line-by-line. Format as comparison lines. +declare function diffLinesUnified(aLines: Array, bLines: Array, options?: DiffOptions): string; +// Given two pairs of arrays of strings: +// Compare the pair of comparison arrays line-by-line. +// Format the corresponding lines in the pair of displayable arrays. +declare function diffLinesUnified2(aLinesDisplay: Array, bLinesDisplay: Array, aLinesCompare: Array, bLinesCompare: Array, options?: DiffOptions): string; +// Compare two arrays of strings line-by-line. +declare function diffLinesRaw(aLines: Array, bLines: Array, options?: DiffOptions): [Array, boolean]; + +/** +* Copyright (c) Meta Platforms, Inc. and affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + +// Compare two strings character-by-character. +// Format as comparison lines in which changed substrings have inverse colors. +declare function diffStringsUnified(a: string, b: string, options?: DiffOptions): string; +// Compare two strings character-by-character. +// Optionally clean up small common substrings, also known as chaff. +declare function diffStringsRaw(a: string, b: string, cleanup: boolean, options?: DiffOptions): [Array, boolean]; + +// Generate a string that will highlight the difference between two values +// with green and red. (similar to how github does code diffing) +/** +* @param a Expected value +* @param b Received value +* @param options Diff options +* @returns {string | null} a string diff +*/ +declare function diff(a: any, b: any, options?: DiffOptions): string | undefined; +declare function printDiffOrStringify(received: unknown, expected: unknown, options?: DiffOptions): string | undefined; +declare function replaceAsymmetricMatcher(actual: any, expected: any, actualReplaced?: WeakSet, expectedReplaced?: WeakSet): { + replacedActual: any + replacedExpected: any +}; +type PrintLabel = (string: string) => string; +declare function getLabelPrinter(...strings: Array): PrintLabel; + +export { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff, DiffOptions, diff, diffLinesRaw, diffLinesUnified, diffLinesUnified2, diffStringsRaw, diffStringsUnified, getLabelPrinter, printDiffOrStringify, replaceAsymmetricMatcher }; diff --git a/node_modules/@vitest/utils/dist/diff.js b/node_modules/@vitest/utils/dist/diff.js new file mode 100644 index 0000000000..0974891a66 --- /dev/null +++ b/node_modules/@vitest/utils/dist/diff.js @@ -0,0 +1,2185 @@ +import { plugins, format } from '@vitest/pretty-format'; +import c from 'tinyrainbow'; +import { g as getDefaultExportFromCjs, s as stringify } from './chunk-_commonjsHelpers.js'; +import { deepClone, getOwnProperties, getType as getType$1 } from './helpers.js'; +import 'loupe'; + +/** +* Diff Match and Patch +* Copyright 2018 The diff-match-patch Authors. +* https://github.com/google/diff-match-patch +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** +* @fileoverview Computes the difference between two texts to create a patch. +* Applies the patch onto another text, allowing for errors. +* @author fraser@google.com (Neil Fraser) +*/ +/** +* CHANGES by pedrottimark to diff_match_patch_uncompressed.ts file: +* +* 1. Delete anything not needed to use diff_cleanupSemantic method +* 2. Convert from prototype properties to var declarations +* 3. Convert Diff to class from constructor and prototype +* 4. Add type annotations for arguments and return values +* 5. Add exports +*/ +/** +* The data structure representing a diff is an array of tuples: +* [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']] +* which means: delete 'Hello', add 'Goodbye' and keep ' world.' +*/ +const DIFF_DELETE = -1; +const DIFF_INSERT = 1; +const DIFF_EQUAL = 0; +/** +* Class representing one diff tuple. +* Attempts to look like a two-element array (which is what this used to be). +* @param {number} op Operation, one of: DIFF_DELETE, DIFF_INSERT, DIFF_EQUAL. +* @param {string} text Text to be deleted, inserted, or retained. +* @constructor +*/ +class Diff { + 0; + 1; + constructor(op, text) { + this[0] = op; + this[1] = text; + } +} +/** +* Determine the common prefix of two strings. +* @param {string} text1 First string. +* @param {string} text2 Second string. +* @return {number} The number of characters common to the start of each +* string. +*/ +function diff_commonPrefix(text1, text2) { + // Quick check for common null cases. + if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) { + return 0; + } + // Binary search. + // Performance analysis: https://neil.fraser.name/news/2007/10/09/ + let pointermin = 0; + let pointermax = Math.min(text1.length, text2.length); + let pointermid = pointermax; + let pointerstart = 0; + while (pointermin < pointermid) { + if (text1.substring(pointerstart, pointermid) === text2.substring(pointerstart, pointermid)) { + pointermin = pointermid; + pointerstart = pointermin; + } else { + pointermax = pointermid; + } + pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); + } + return pointermid; +} +/** +* Determine the common suffix of two strings. +* @param {string} text1 First string. +* @param {string} text2 Second string. +* @return {number} The number of characters common to the end of each string. +*/ +function diff_commonSuffix(text1, text2) { + // Quick check for common null cases. + if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) { + return 0; + } + // Binary search. + // Performance analysis: https://neil.fraser.name/news/2007/10/09/ + let pointermin = 0; + let pointermax = Math.min(text1.length, text2.length); + let pointermid = pointermax; + let pointerend = 0; + while (pointermin < pointermid) { + if (text1.substring(text1.length - pointermid, text1.length - pointerend) === text2.substring(text2.length - pointermid, text2.length - pointerend)) { + pointermin = pointermid; + pointerend = pointermin; + } else { + pointermax = pointermid; + } + pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); + } + return pointermid; +} +/** +* Determine if the suffix of one string is the prefix of another. +* @param {string} text1 First string. +* @param {string} text2 Second string. +* @return {number} The number of characters common to the end of the first +* string and the start of the second string. +* @private +*/ +function diff_commonOverlap_(text1, text2) { + // Cache the text lengths to prevent multiple calls. + const text1_length = text1.length; + const text2_length = text2.length; + // Eliminate the null case. + if (text1_length === 0 || text2_length === 0) { + return 0; + } + // Truncate the longer string. + if (text1_length > text2_length) { + text1 = text1.substring(text1_length - text2_length); + } else if (text1_length < text2_length) { + text2 = text2.substring(0, text1_length); + } + const text_length = Math.min(text1_length, text2_length); + // Quick check for the worst case. + if (text1 === text2) { + return text_length; + } + // Start by looking for a single character match + // and increase length until no match is found. + // Performance analysis: https://neil.fraser.name/news/2010/11/04/ + let best = 0; + let length = 1; + while (true) { + const pattern = text1.substring(text_length - length); + const found = text2.indexOf(pattern); + if (found === -1) { + return best; + } + length += found; + if (found === 0 || text1.substring(text_length - length) === text2.substring(0, length)) { + best = length; + length++; + } + } +} +/** +* Reduce the number of edits by eliminating semantically trivial equalities. +* @param {!Array.} diffs Array of diff tuples. +*/ +function diff_cleanupSemantic(diffs) { + let changes = false; + const equalities = []; + let equalitiesLength = 0; + /** @type {?string} */ + let lastEquality = null; + // Always equal to diffs[equalities[equalitiesLength - 1]][1] + let pointer = 0; + // Number of characters that changed prior to the equality. + let length_insertions1 = 0; + let length_deletions1 = 0; + // Number of characters that changed after the equality. + let length_insertions2 = 0; + let length_deletions2 = 0; + while (pointer < diffs.length) { + if (diffs[pointer][0] === DIFF_EQUAL) { + // Equality found. + equalities[equalitiesLength++] = pointer; + length_insertions1 = length_insertions2; + length_deletions1 = length_deletions2; + length_insertions2 = 0; + length_deletions2 = 0; + lastEquality = diffs[pointer][1]; + } else { + // An insertion or deletion. + if (diffs[pointer][0] === DIFF_INSERT) { + length_insertions2 += diffs[pointer][1].length; + } else { + length_deletions2 += diffs[pointer][1].length; + } + // Eliminate an equality that is smaller or equal to the edits on both + // sides of it. + if (lastEquality && lastEquality.length <= Math.max(length_insertions1, length_deletions1) && lastEquality.length <= Math.max(length_insertions2, length_deletions2)) { + // Duplicate record. + diffs.splice(equalities[equalitiesLength - 1], 0, new Diff(DIFF_DELETE, lastEquality)); + // Change second copy to insert. + diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT; + // Throw away the equality we just deleted. + equalitiesLength--; + // Throw away the previous equality (it needs to be reevaluated). + equalitiesLength--; + pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1; + length_insertions1 = 0; + length_deletions1 = 0; + length_insertions2 = 0; + length_deletions2 = 0; + lastEquality = null; + changes = true; + } + } + pointer++; + } + // Normalize the diff. + if (changes) { + diff_cleanupMerge(diffs); + } + diff_cleanupSemanticLossless(diffs); + // Find any overlaps between deletions and insertions. + // e.g: abcxxxxxxdef + // -> abcxxxdef + // e.g: xxxabcdefxxx + // -> defxxxabc + // Only extract an overlap if it is as big as the edit ahead or behind it. + pointer = 1; + while (pointer < diffs.length) { + if (diffs[pointer - 1][0] === DIFF_DELETE && diffs[pointer][0] === DIFF_INSERT) { + const deletion = diffs[pointer - 1][1]; + const insertion = diffs[pointer][1]; + const overlap_length1 = diff_commonOverlap_(deletion, insertion); + const overlap_length2 = diff_commonOverlap_(insertion, deletion); + if (overlap_length1 >= overlap_length2) { + if (overlap_length1 >= deletion.length / 2 || overlap_length1 >= insertion.length / 2) { + // Overlap found. Insert an equality and trim the surrounding edits. + diffs.splice(pointer, 0, new Diff(DIFF_EQUAL, insertion.substring(0, overlap_length1))); + diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlap_length1); + diffs[pointer + 1][1] = insertion.substring(overlap_length1); + pointer++; + } + } else { + if (overlap_length2 >= deletion.length / 2 || overlap_length2 >= insertion.length / 2) { + // Reverse overlap found. + // Insert an equality and swap and trim the surrounding edits. + diffs.splice(pointer, 0, new Diff(DIFF_EQUAL, deletion.substring(0, overlap_length2))); + diffs[pointer - 1][0] = DIFF_INSERT; + diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlap_length2); + diffs[pointer + 1][0] = DIFF_DELETE; + diffs[pointer + 1][1] = deletion.substring(overlap_length2); + pointer++; + } + } + pointer++; + } + pointer++; + } +} +// Define some regex patterns for matching boundaries. +const nonAlphaNumericRegex_ = /[^a-z0-9]/i; +const whitespaceRegex_ = /\s/; +const linebreakRegex_ = /[\r\n]/; +const blanklineEndRegex_ = /\n\r?\n$/; +const blanklineStartRegex_ = /^\r?\n\r?\n/; +/** +* Look for single edits surrounded on both sides by equalities +* which can be shifted sideways to align the edit to a word boundary. +* e.g: The cat came. -> The cat came. +* @param {!Array.} diffs Array of diff tuples. +*/ +function diff_cleanupSemanticLossless(diffs) { + let pointer = 1; + // Intentionally ignore the first and last element (don't need checking). + while (pointer < diffs.length - 1) { + if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) { + // This is a single edit surrounded by equalities. + let equality1 = diffs[pointer - 1][1]; + let edit = diffs[pointer][1]; + let equality2 = diffs[pointer + 1][1]; + // First, shift the edit as far left as possible. + const commonOffset = diff_commonSuffix(equality1, edit); + if (commonOffset) { + const commonString = edit.substring(edit.length - commonOffset); + equality1 = equality1.substring(0, equality1.length - commonOffset); + edit = commonString + edit.substring(0, edit.length - commonOffset); + equality2 = commonString + equality2; + } + // Second, step character by character right, looking for the best fit. + let bestEquality1 = equality1; + let bestEdit = edit; + let bestEquality2 = equality2; + let bestScore = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2); + while (edit.charAt(0) === equality2.charAt(0)) { + equality1 += edit.charAt(0); + edit = edit.substring(1) + equality2.charAt(0); + equality2 = equality2.substring(1); + const score = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2); + // The >= encourages trailing rather than leading whitespace on edits. + if (score >= bestScore) { + bestScore = score; + bestEquality1 = equality1; + bestEdit = edit; + bestEquality2 = equality2; + } + } + if (diffs[pointer - 1][1] !== bestEquality1) { + // We have an improvement, save it back to the diff. + if (bestEquality1) { + diffs[pointer - 1][1] = bestEquality1; + } else { + diffs.splice(pointer - 1, 1); + pointer--; + } + diffs[pointer][1] = bestEdit; + if (bestEquality2) { + diffs[pointer + 1][1] = bestEquality2; + } else { + diffs.splice(pointer + 1, 1); + pointer--; + } + } + } + pointer++; + } +} +/** +* Reorder and merge like edit sections. Merge equalities. +* Any edit section can move as long as it doesn't cross an equality. +* @param {!Array.} diffs Array of diff tuples. +*/ +function diff_cleanupMerge(diffs) { + // Add a dummy entry at the end. + diffs.push(new Diff(DIFF_EQUAL, "")); + let pointer = 0; + let count_delete = 0; + let count_insert = 0; + let text_delete = ""; + let text_insert = ""; + let commonlength; + while (pointer < diffs.length) { + switch (diffs[pointer][0]) { + case DIFF_INSERT: + count_insert++; + text_insert += diffs[pointer][1]; + pointer++; + break; + case DIFF_DELETE: + count_delete++; + text_delete += diffs[pointer][1]; + pointer++; + break; + case DIFF_EQUAL: + // Upon reaching an equality, check for prior redundancies. + if (count_delete + count_insert > 1) { + if (count_delete !== 0 && count_insert !== 0) { + // Factor out any common prefixes. + commonlength = diff_commonPrefix(text_insert, text_delete); + if (commonlength !== 0) { + if (pointer - count_delete - count_insert > 0 && diffs[pointer - count_delete - count_insert - 1][0] === DIFF_EQUAL) { + diffs[pointer - count_delete - count_insert - 1][1] += text_insert.substring(0, commonlength); + } else { + diffs.splice(0, 0, new Diff(DIFF_EQUAL, text_insert.substring(0, commonlength))); + pointer++; + } + text_insert = text_insert.substring(commonlength); + text_delete = text_delete.substring(commonlength); + } + // Factor out any common suffixes. + commonlength = diff_commonSuffix(text_insert, text_delete); + if (commonlength !== 0) { + diffs[pointer][1] = text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1]; + text_insert = text_insert.substring(0, text_insert.length - commonlength); + text_delete = text_delete.substring(0, text_delete.length - commonlength); + } + } + // Delete the offending records and add the merged ones. + pointer -= count_delete + count_insert; + diffs.splice(pointer, count_delete + count_insert); + if (text_delete.length) { + diffs.splice(pointer, 0, new Diff(DIFF_DELETE, text_delete)); + pointer++; + } + if (text_insert.length) { + diffs.splice(pointer, 0, new Diff(DIFF_INSERT, text_insert)); + pointer++; + } + pointer++; + } else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) { + // Merge this equality with the previous one. + diffs[pointer - 1][1] += diffs[pointer][1]; + diffs.splice(pointer, 1); + } else { + pointer++; + } + count_insert = 0; + count_delete = 0; + text_delete = ""; + text_insert = ""; + break; + } + } + if (diffs[diffs.length - 1][1] === "") { + diffs.pop(); + } + // Second pass: look for single edits surrounded on both sides by equalities + // which can be shifted sideways to eliminate an equality. + // e.g: ABAC -> ABAC + let changes = false; + pointer = 1; + // Intentionally ignore the first and last element (don't need checking). + while (pointer < diffs.length - 1) { + if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) { + // This is a single edit surrounded by equalities. + if (diffs[pointer][1].substring(diffs[pointer][1].length - diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) { + // Shift the edit over the previous equality. + diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length); + diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1]; + diffs.splice(pointer - 1, 1); + changes = true; + } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1]) { + // Shift the edit over the next equality. + diffs[pointer - 1][1] += diffs[pointer + 1][1]; + diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1]; + diffs.splice(pointer + 1, 1); + changes = true; + } + } + pointer++; + } + // If shifts were made, the diff needs reordering and another shift sweep. + if (changes) { + diff_cleanupMerge(diffs); + } +} +/** +* Given two strings, compute a score representing whether the internal +* boundary falls on logical boundaries. +* Scores range from 6 (best) to 0 (worst). +* Closure, but does not reference any external variables. +* @param {string} one First string. +* @param {string} two Second string. +* @return {number} The score. +* @private +*/ +function diff_cleanupSemanticScore_(one, two) { + if (!one || !two) { + // Edges are the best. + return 6; + } + // Each port of this function behaves slightly differently due to + // subtle differences in each language's definition of things like + // 'whitespace'. Since this function's purpose is largely cosmetic, + // the choice has been made to use each language's native features + // rather than force total conformity. + const char1 = one.charAt(one.length - 1); + const char2 = two.charAt(0); + const nonAlphaNumeric1 = char1.match(nonAlphaNumericRegex_); + const nonAlphaNumeric2 = char2.match(nonAlphaNumericRegex_); + const whitespace1 = nonAlphaNumeric1 && char1.match(whitespaceRegex_); + const whitespace2 = nonAlphaNumeric2 && char2.match(whitespaceRegex_); + const lineBreak1 = whitespace1 && char1.match(linebreakRegex_); + const lineBreak2 = whitespace2 && char2.match(linebreakRegex_); + const blankLine1 = lineBreak1 && one.match(blanklineEndRegex_); + const blankLine2 = lineBreak2 && two.match(blanklineStartRegex_); + if (blankLine1 || blankLine2) { + // Five points for blank lines. + return 5; + } else if (lineBreak1 || lineBreak2) { + // Four points for line breaks. + return 4; + } else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) { + // Three points for end of sentences. + return 3; + } else if (whitespace1 || whitespace2) { + // Two points for whitespace. + return 2; + } else if (nonAlphaNumeric1 || nonAlphaNumeric2) { + // One point for non-alphanumeric. + return 1; + } + return 0; +} + +/** +* Copyright (c) Meta Platforms, Inc. and affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ +const NO_DIFF_MESSAGE = "Compared values have no visual difference."; +const SIMILAR_MESSAGE = "Compared values serialize to the same structure.\n" + "Printing internal object structure without calling `toJSON` instead."; + +var build = {}; + +var hasRequiredBuild; + +function requireBuild () { + if (hasRequiredBuild) return build; + hasRequiredBuild = 1; + + Object.defineProperty(build, '__esModule', { + value: true + }); + build.default = diffSequence; + /** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + + // This diff-sequences package implements the linear space variation in + // An O(ND) Difference Algorithm and Its Variations by Eugene W. Myers + + // Relationship in notation between Myers paper and this package: + // A is a + // N is aLength, aEnd - aStart, and so on + // x is aIndex, aFirst, aLast, and so on + // B is b + // M is bLength, bEnd - bStart, and so on + // y is bIndex, bFirst, bLast, and so on + // Δ = N - M is negative of baDeltaLength = bLength - aLength + // D is d + // k is kF + // k + Δ is kF = kR - baDeltaLength + // V is aIndexesF or aIndexesR (see comment below about Indexes type) + // index intervals [1, N] and [1, M] are [0, aLength) and [0, bLength) + // starting point in forward direction (0, 0) is (-1, -1) + // starting point in reverse direction (N + 1, M + 1) is (aLength, bLength) + + // The “edit graph” for sequences a and b corresponds to items: + // in a on the horizontal axis + // in b on the vertical axis + // + // Given a-coordinate of a point in a diagonal, you can compute b-coordinate. + // + // Forward diagonals kF: + // zero diagonal intersects top left corner + // positive diagonals intersect top edge + // negative diagonals insersect left edge + // + // Reverse diagonals kR: + // zero diagonal intersects bottom right corner + // positive diagonals intersect right edge + // negative diagonals intersect bottom edge + + // The graph contains a directed acyclic graph of edges: + // horizontal: delete an item from a + // vertical: insert an item from b + // diagonal: common item in a and b + // + // The algorithm solves dual problems in the graph analogy: + // Find longest common subsequence: path with maximum number of diagonal edges + // Find shortest edit script: path with minimum number of non-diagonal edges + + // Input callback function compares items at indexes in the sequences. + + // Output callback function receives the number of adjacent items + // and starting indexes of each common subsequence. + // Either original functions or wrapped to swap indexes if graph is transposed. + // Indexes in sequence a of last point of forward or reverse paths in graph. + // Myers algorithm indexes by diagonal k which for negative is bad deopt in V8. + // This package indexes by iF and iR which are greater than or equal to zero. + // and also updates the index arrays in place to cut memory in half. + // kF = 2 * iF - d + // kR = d - 2 * iR + // Division of index intervals in sequences a and b at the middle change. + // Invariant: intervals do not have common items at the start or end. + const pkg = 'diff-sequences'; // for error messages + const NOT_YET_SET = 0; // small int instead of undefined to avoid deopt in V8 + + // Return the number of common items that follow in forward direction. + // The length of what Myers paper calls a “snake” in a forward path. + const countCommonItemsF = (aIndex, aEnd, bIndex, bEnd, isCommon) => { + let nCommon = 0; + while (aIndex < aEnd && bIndex < bEnd && isCommon(aIndex, bIndex)) { + aIndex += 1; + bIndex += 1; + nCommon += 1; + } + return nCommon; + }; + + // Return the number of common items that precede in reverse direction. + // The length of what Myers paper calls a “snake” in a reverse path. + const countCommonItemsR = (aStart, aIndex, bStart, bIndex, isCommon) => { + let nCommon = 0; + while (aStart <= aIndex && bStart <= bIndex && isCommon(aIndex, bIndex)) { + aIndex -= 1; + bIndex -= 1; + nCommon += 1; + } + return nCommon; + }; + + // A simple function to extend forward paths from (d - 1) to d changes + // when forward and reverse paths cannot yet overlap. + const extendPathsF = ( + d, + aEnd, + bEnd, + bF, + isCommon, + aIndexesF, + iMaxF // return the value because optimization might decrease it + ) => { + // Unroll the first iteration. + let iF = 0; + let kF = -d; // kF = 2 * iF - d + let aFirst = aIndexesF[iF]; // in first iteration always insert + let aIndexPrev1 = aFirst; // prev value of [iF - 1] in next iteration + aIndexesF[iF] += countCommonItemsF( + aFirst + 1, + aEnd, + bF + aFirst - kF + 1, + bEnd, + isCommon + ); + + // Optimization: skip diagonals in which paths cannot ever overlap. + const nF = d < iMaxF ? d : iMaxF; + + // The diagonals kF are odd when d is odd and even when d is even. + for (iF += 1, kF += 2; iF <= nF; iF += 1, kF += 2) { + // To get first point of path segment, move one change in forward direction + // from last point of previous path segment in an adjacent diagonal. + // In last possible iteration when iF === d and kF === d always delete. + if (iF !== d && aIndexPrev1 < aIndexesF[iF]) { + aFirst = aIndexesF[iF]; // vertical to insert from b + } else { + aFirst = aIndexPrev1 + 1; // horizontal to delete from a + + if (aEnd <= aFirst) { + // Optimization: delete moved past right of graph. + return iF - 1; + } + } + + // To get last point of path segment, move along diagonal of common items. + aIndexPrev1 = aIndexesF[iF]; + aIndexesF[iF] = + aFirst + + countCommonItemsF(aFirst + 1, aEnd, bF + aFirst - kF + 1, bEnd, isCommon); + } + return iMaxF; + }; + + // A simple function to extend reverse paths from (d - 1) to d changes + // when reverse and forward paths cannot yet overlap. + const extendPathsR = ( + d, + aStart, + bStart, + bR, + isCommon, + aIndexesR, + iMaxR // return the value because optimization might decrease it + ) => { + // Unroll the first iteration. + let iR = 0; + let kR = d; // kR = d - 2 * iR + let aFirst = aIndexesR[iR]; // in first iteration always insert + let aIndexPrev1 = aFirst; // prev value of [iR - 1] in next iteration + aIndexesR[iR] -= countCommonItemsR( + aStart, + aFirst - 1, + bStart, + bR + aFirst - kR - 1, + isCommon + ); + + // Optimization: skip diagonals in which paths cannot ever overlap. + const nR = d < iMaxR ? d : iMaxR; + + // The diagonals kR are odd when d is odd and even when d is even. + for (iR += 1, kR -= 2; iR <= nR; iR += 1, kR -= 2) { + // To get first point of path segment, move one change in reverse direction + // from last point of previous path segment in an adjacent diagonal. + // In last possible iteration when iR === d and kR === -d always delete. + if (iR !== d && aIndexesR[iR] < aIndexPrev1) { + aFirst = aIndexesR[iR]; // vertical to insert from b + } else { + aFirst = aIndexPrev1 - 1; // horizontal to delete from a + + if (aFirst < aStart) { + // Optimization: delete moved past left of graph. + return iR - 1; + } + } + + // To get last point of path segment, move along diagonal of common items. + aIndexPrev1 = aIndexesR[iR]; + aIndexesR[iR] = + aFirst - + countCommonItemsR( + aStart, + aFirst - 1, + bStart, + bR + aFirst - kR - 1, + isCommon + ); + } + return iMaxR; + }; + + // A complete function to extend forward paths from (d - 1) to d changes. + // Return true if a path overlaps reverse path of (d - 1) changes in its diagonal. + const extendOverlappablePathsF = ( + d, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + iMaxF, + aIndexesR, + iMaxR, + division // update prop values if return true + ) => { + const bF = bStart - aStart; // bIndex = bF + aIndex - kF + const aLength = aEnd - aStart; + const bLength = bEnd - bStart; + const baDeltaLength = bLength - aLength; // kF = kR - baDeltaLength + + // Range of diagonals in which forward and reverse paths might overlap. + const kMinOverlapF = -baDeltaLength - (d - 1); // -(d - 1) <= kR + const kMaxOverlapF = -baDeltaLength + (d - 1); // kR <= (d - 1) + + let aIndexPrev1 = NOT_YET_SET; // prev value of [iF - 1] in next iteration + + // Optimization: skip diagonals in which paths cannot ever overlap. + const nF = d < iMaxF ? d : iMaxF; + + // The diagonals kF = 2 * iF - d are odd when d is odd and even when d is even. + for (let iF = 0, kF = -d; iF <= nF; iF += 1, kF += 2) { + // To get first point of path segment, move one change in forward direction + // from last point of previous path segment in an adjacent diagonal. + // In first iteration when iF === 0 and kF === -d always insert. + // In last possible iteration when iF === d and kF === d always delete. + const insert = iF === 0 || (iF !== d && aIndexPrev1 < aIndexesF[iF]); + const aLastPrev = insert ? aIndexesF[iF] : aIndexPrev1; + const aFirst = insert + ? aLastPrev // vertical to insert from b + : aLastPrev + 1; // horizontal to delete from a + + // To get last point of path segment, move along diagonal of common items. + const bFirst = bF + aFirst - kF; + const nCommonF = countCommonItemsF( + aFirst + 1, + aEnd, + bFirst + 1, + bEnd, + isCommon + ); + const aLast = aFirst + nCommonF; + aIndexPrev1 = aIndexesF[iF]; + aIndexesF[iF] = aLast; + if (kMinOverlapF <= kF && kF <= kMaxOverlapF) { + // Solve for iR of reverse path with (d - 1) changes in diagonal kF: + // kR = kF + baDeltaLength + // kR = (d - 1) - 2 * iR + const iR = (d - 1 - (kF + baDeltaLength)) / 2; + + // If this forward path overlaps the reverse path in this diagonal, + // then this is the middle change of the index intervals. + if (iR <= iMaxR && aIndexesR[iR] - 1 <= aLast) { + // Unlike the Myers algorithm which finds only the middle “snake” + // this package can find two common subsequences per division. + // Last point of previous path segment is on an adjacent diagonal. + const bLastPrev = bF + aLastPrev - (insert ? kF + 1 : kF - 1); + + // Because of invariant that intervals preceding the middle change + // cannot have common items at the end, + // move in reverse direction along a diagonal of common items. + const nCommonR = countCommonItemsR( + aStart, + aLastPrev, + bStart, + bLastPrev, + isCommon + ); + const aIndexPrevFirst = aLastPrev - nCommonR; + const bIndexPrevFirst = bLastPrev - nCommonR; + const aEndPreceding = aIndexPrevFirst + 1; + const bEndPreceding = bIndexPrevFirst + 1; + division.nChangePreceding = d - 1; + if (d - 1 === aEndPreceding + bEndPreceding - aStart - bStart) { + // Optimization: number of preceding changes in forward direction + // is equal to number of items in preceding interval, + // therefore it cannot contain any common items. + division.aEndPreceding = aStart; + division.bEndPreceding = bStart; + } else { + division.aEndPreceding = aEndPreceding; + division.bEndPreceding = bEndPreceding; + } + division.nCommonPreceding = nCommonR; + if (nCommonR !== 0) { + division.aCommonPreceding = aEndPreceding; + division.bCommonPreceding = bEndPreceding; + } + division.nCommonFollowing = nCommonF; + if (nCommonF !== 0) { + division.aCommonFollowing = aFirst + 1; + division.bCommonFollowing = bFirst + 1; + } + const aStartFollowing = aLast + 1; + const bStartFollowing = bFirst + nCommonF + 1; + division.nChangeFollowing = d - 1; + if (d - 1 === aEnd + bEnd - aStartFollowing - bStartFollowing) { + // Optimization: number of changes in reverse direction + // is equal to number of items in following interval, + // therefore it cannot contain any common items. + division.aStartFollowing = aEnd; + division.bStartFollowing = bEnd; + } else { + division.aStartFollowing = aStartFollowing; + division.bStartFollowing = bStartFollowing; + } + return true; + } + } + } + return false; + }; + + // A complete function to extend reverse paths from (d - 1) to d changes. + // Return true if a path overlaps forward path of d changes in its diagonal. + const extendOverlappablePathsR = ( + d, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + iMaxF, + aIndexesR, + iMaxR, + division // update prop values if return true + ) => { + const bR = bEnd - aEnd; // bIndex = bR + aIndex - kR + const aLength = aEnd - aStart; + const bLength = bEnd - bStart; + const baDeltaLength = bLength - aLength; // kR = kF + baDeltaLength + + // Range of diagonals in which forward and reverse paths might overlap. + const kMinOverlapR = baDeltaLength - d; // -d <= kF + const kMaxOverlapR = baDeltaLength + d; // kF <= d + + let aIndexPrev1 = NOT_YET_SET; // prev value of [iR - 1] in next iteration + + // Optimization: skip diagonals in which paths cannot ever overlap. + const nR = d < iMaxR ? d : iMaxR; + + // The diagonals kR = d - 2 * iR are odd when d is odd and even when d is even. + for (let iR = 0, kR = d; iR <= nR; iR += 1, kR -= 2) { + // To get first point of path segment, move one change in reverse direction + // from last point of previous path segment in an adjacent diagonal. + // In first iteration when iR === 0 and kR === d always insert. + // In last possible iteration when iR === d and kR === -d always delete. + const insert = iR === 0 || (iR !== d && aIndexesR[iR] < aIndexPrev1); + const aLastPrev = insert ? aIndexesR[iR] : aIndexPrev1; + const aFirst = insert + ? aLastPrev // vertical to insert from b + : aLastPrev - 1; // horizontal to delete from a + + // To get last point of path segment, move along diagonal of common items. + const bFirst = bR + aFirst - kR; + const nCommonR = countCommonItemsR( + aStart, + aFirst - 1, + bStart, + bFirst - 1, + isCommon + ); + const aLast = aFirst - nCommonR; + aIndexPrev1 = aIndexesR[iR]; + aIndexesR[iR] = aLast; + if (kMinOverlapR <= kR && kR <= kMaxOverlapR) { + // Solve for iF of forward path with d changes in diagonal kR: + // kF = kR - baDeltaLength + // kF = 2 * iF - d + const iF = (d + (kR - baDeltaLength)) / 2; + + // If this reverse path overlaps the forward path in this diagonal, + // then this is a middle change of the index intervals. + if (iF <= iMaxF && aLast - 1 <= aIndexesF[iF]) { + const bLast = bFirst - nCommonR; + division.nChangePreceding = d; + if (d === aLast + bLast - aStart - bStart) { + // Optimization: number of changes in reverse direction + // is equal to number of items in preceding interval, + // therefore it cannot contain any common items. + division.aEndPreceding = aStart; + division.bEndPreceding = bStart; + } else { + division.aEndPreceding = aLast; + division.bEndPreceding = bLast; + } + division.nCommonPreceding = nCommonR; + if (nCommonR !== 0) { + // The last point of reverse path segment is start of common subsequence. + division.aCommonPreceding = aLast; + division.bCommonPreceding = bLast; + } + division.nChangeFollowing = d - 1; + if (d === 1) { + // There is no previous path segment. + division.nCommonFollowing = 0; + division.aStartFollowing = aEnd; + division.bStartFollowing = bEnd; + } else { + // Unlike the Myers algorithm which finds only the middle “snake” + // this package can find two common subsequences per division. + // Last point of previous path segment is on an adjacent diagonal. + const bLastPrev = bR + aLastPrev - (insert ? kR - 1 : kR + 1); + + // Because of invariant that intervals following the middle change + // cannot have common items at the start, + // move in forward direction along a diagonal of common items. + const nCommonF = countCommonItemsF( + aLastPrev, + aEnd, + bLastPrev, + bEnd, + isCommon + ); + division.nCommonFollowing = nCommonF; + if (nCommonF !== 0) { + // The last point of reverse path segment is start of common subsequence. + division.aCommonFollowing = aLastPrev; + division.bCommonFollowing = bLastPrev; + } + const aStartFollowing = aLastPrev + nCommonF; // aFirstPrev + const bStartFollowing = bLastPrev + nCommonF; // bFirstPrev + + if (d - 1 === aEnd + bEnd - aStartFollowing - bStartFollowing) { + // Optimization: number of changes in forward direction + // is equal to number of items in following interval, + // therefore it cannot contain any common items. + division.aStartFollowing = aEnd; + division.bStartFollowing = bEnd; + } else { + division.aStartFollowing = aStartFollowing; + division.bStartFollowing = bStartFollowing; + } + } + return true; + } + } + } + return false; + }; + + // Given index intervals and input function to compare items at indexes, + // divide at the middle change. + // + // DO NOT CALL if start === end, because interval cannot contain common items + // and because this function will throw the “no overlap” error. + const divide = ( + nChange, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + aIndexesR, + division // output + ) => { + const bF = bStart - aStart; // bIndex = bF + aIndex - kF + const bR = bEnd - aEnd; // bIndex = bR + aIndex - kR + const aLength = aEnd - aStart; + const bLength = bEnd - bStart; + + // Because graph has square or portrait orientation, + // length difference is minimum number of items to insert from b. + // Corresponding forward and reverse diagonals in graph + // depend on length difference of the sequences: + // kF = kR - baDeltaLength + // kR = kF + baDeltaLength + const baDeltaLength = bLength - aLength; + + // Optimization: max diagonal in graph intersects corner of shorter side. + let iMaxF = aLength; + let iMaxR = aLength; + + // Initialize no changes yet in forward or reverse direction: + aIndexesF[0] = aStart - 1; // at open start of interval, outside closed start + aIndexesR[0] = aEnd; // at open end of interval + + if (baDeltaLength % 2 === 0) { + // The number of changes in paths is 2 * d if length difference is even. + const dMin = (nChange || baDeltaLength) / 2; + const dMax = (aLength + bLength) / 2; + for (let d = 1; d <= dMax; d += 1) { + iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF); + if (d < dMin) { + iMaxR = extendPathsR(d, aStart, bStart, bR, isCommon, aIndexesR, iMaxR); + } else if ( + // If a reverse path overlaps a forward path in the same diagonal, + // return a division of the index intervals at the middle change. + extendOverlappablePathsR( + d, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + iMaxF, + aIndexesR, + iMaxR, + division + ) + ) { + return; + } + } + } else { + // The number of changes in paths is 2 * d - 1 if length difference is odd. + const dMin = ((nChange || baDeltaLength) + 1) / 2; + const dMax = (aLength + bLength + 1) / 2; + + // Unroll first half iteration so loop extends the relevant pairs of paths. + // Because of invariant that intervals have no common items at start or end, + // and limitation not to call divide with empty intervals, + // therefore it cannot be called if a forward path with one change + // would overlap a reverse path with no changes, even if dMin === 1. + let d = 1; + iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF); + for (d += 1; d <= dMax; d += 1) { + iMaxR = extendPathsR( + d - 1, + aStart, + bStart, + bR, + isCommon, + aIndexesR, + iMaxR + ); + if (d < dMin) { + iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF); + } else if ( + // If a forward path overlaps a reverse path in the same diagonal, + // return a division of the index intervals at the middle change. + extendOverlappablePathsF( + d, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + iMaxF, + aIndexesR, + iMaxR, + division + ) + ) { + return; + } + } + } + + /* istanbul ignore next */ + throw new Error( + `${pkg}: no overlap aStart=${aStart} aEnd=${aEnd} bStart=${bStart} bEnd=${bEnd}` + ); + }; + + // Given index intervals and input function to compare items at indexes, + // return by output function the number of adjacent items and starting indexes + // of each common subsequence. Divide and conquer with only linear space. + // + // The index intervals are half open [start, end) like array slice method. + // DO NOT CALL if start === end, because interval cannot contain common items + // and because divide function will throw the “no overlap” error. + const findSubsequences = ( + nChange, + aStart, + aEnd, + bStart, + bEnd, + transposed, + callbacks, + aIndexesF, + aIndexesR, + division // temporary memory, not input nor output + ) => { + if (bEnd - bStart < aEnd - aStart) { + // Transpose graph so it has portrait instead of landscape orientation. + // Always compare shorter to longer sequence for consistency and optimization. + transposed = !transposed; + if (transposed && callbacks.length === 1) { + // Lazily wrap callback functions to swap args if graph is transposed. + const {foundSubsequence, isCommon} = callbacks[0]; + callbacks[1] = { + foundSubsequence: (nCommon, bCommon, aCommon) => { + foundSubsequence(nCommon, aCommon, bCommon); + }, + isCommon: (bIndex, aIndex) => isCommon(aIndex, bIndex) + }; + } + const tStart = aStart; + const tEnd = aEnd; + aStart = bStart; + aEnd = bEnd; + bStart = tStart; + bEnd = tEnd; + } + const {foundSubsequence, isCommon} = callbacks[transposed ? 1 : 0]; + + // Divide the index intervals at the middle change. + divide( + nChange, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + aIndexesR, + division + ); + const { + nChangePreceding, + aEndPreceding, + bEndPreceding, + nCommonPreceding, + aCommonPreceding, + bCommonPreceding, + nCommonFollowing, + aCommonFollowing, + bCommonFollowing, + nChangeFollowing, + aStartFollowing, + bStartFollowing + } = division; + + // Unless either index interval is empty, they might contain common items. + if (aStart < aEndPreceding && bStart < bEndPreceding) { + // Recursely find and return common subsequences preceding the division. + findSubsequences( + nChangePreceding, + aStart, + aEndPreceding, + bStart, + bEndPreceding, + transposed, + callbacks, + aIndexesF, + aIndexesR, + division + ); + } + + // Return common subsequences that are adjacent to the middle change. + if (nCommonPreceding !== 0) { + foundSubsequence(nCommonPreceding, aCommonPreceding, bCommonPreceding); + } + if (nCommonFollowing !== 0) { + foundSubsequence(nCommonFollowing, aCommonFollowing, bCommonFollowing); + } + + // Unless either index interval is empty, they might contain common items. + if (aStartFollowing < aEnd && bStartFollowing < bEnd) { + // Recursely find and return common subsequences following the division. + findSubsequences( + nChangeFollowing, + aStartFollowing, + aEnd, + bStartFollowing, + bEnd, + transposed, + callbacks, + aIndexesF, + aIndexesR, + division + ); + } + }; + const validateLength = (name, arg) => { + if (typeof arg !== 'number') { + throw new TypeError(`${pkg}: ${name} typeof ${typeof arg} is not a number`); + } + if (!Number.isSafeInteger(arg)) { + throw new RangeError(`${pkg}: ${name} value ${arg} is not a safe integer`); + } + if (arg < 0) { + throw new RangeError(`${pkg}: ${name} value ${arg} is a negative integer`); + } + }; + const validateCallback = (name, arg) => { + const type = typeof arg; + if (type !== 'function') { + throw new TypeError(`${pkg}: ${name} typeof ${type} is not a function`); + } + }; + + // Compare items in two sequences to find a longest common subsequence. + // Given lengths of sequences and input function to compare items at indexes, + // return by output function the number of adjacent items and starting indexes + // of each common subsequence. + function diffSequence(aLength, bLength, isCommon, foundSubsequence) { + validateLength('aLength', aLength); + validateLength('bLength', bLength); + validateCallback('isCommon', isCommon); + validateCallback('foundSubsequence', foundSubsequence); + + // Count common items from the start in the forward direction. + const nCommonF = countCommonItemsF(0, aLength, 0, bLength, isCommon); + if (nCommonF !== 0) { + foundSubsequence(nCommonF, 0, 0); + } + + // Unless both sequences consist of common items only, + // find common items in the half-trimmed index intervals. + if (aLength !== nCommonF || bLength !== nCommonF) { + // Invariant: intervals do not have common items at the start. + // The start of an index interval is closed like array slice method. + const aStart = nCommonF; + const bStart = nCommonF; + + // Count common items from the end in the reverse direction. + const nCommonR = countCommonItemsR( + aStart, + aLength - 1, + bStart, + bLength - 1, + isCommon + ); + + // Invariant: intervals do not have common items at the end. + // The end of an index interval is open like array slice method. + const aEnd = aLength - nCommonR; + const bEnd = bLength - nCommonR; + + // Unless one sequence consists of common items only, + // therefore the other trimmed index interval consists of changes only, + // find common items in the trimmed index intervals. + const nCommonFR = nCommonF + nCommonR; + if (aLength !== nCommonFR && bLength !== nCommonFR) { + const nChange = 0; // number of change items is not yet known + const transposed = false; // call the original unwrapped functions + const callbacks = [ + { + foundSubsequence, + isCommon + } + ]; + + // Indexes in sequence a of last points in furthest reaching paths + // from outside the start at top left in the forward direction: + const aIndexesF = [NOT_YET_SET]; + // from the end at bottom right in the reverse direction: + const aIndexesR = [NOT_YET_SET]; + + // Initialize one object as output of all calls to divide function. + const division = { + aCommonFollowing: NOT_YET_SET, + aCommonPreceding: NOT_YET_SET, + aEndPreceding: NOT_YET_SET, + aStartFollowing: NOT_YET_SET, + bCommonFollowing: NOT_YET_SET, + bCommonPreceding: NOT_YET_SET, + bEndPreceding: NOT_YET_SET, + bStartFollowing: NOT_YET_SET, + nChangeFollowing: NOT_YET_SET, + nChangePreceding: NOT_YET_SET, + nCommonFollowing: NOT_YET_SET, + nCommonPreceding: NOT_YET_SET + }; + + // Find and return common subsequences in the trimmed index intervals. + findSubsequences( + nChange, + aStart, + aEnd, + bStart, + bEnd, + transposed, + callbacks, + aIndexesF, + aIndexesR, + division + ); + } + if (nCommonR !== 0) { + foundSubsequence(nCommonR, aEnd, bEnd); + } + } + } + return build; +} + +var buildExports = requireBuild(); +var diffSequences = /*@__PURE__*/getDefaultExportFromCjs(buildExports); + +function formatTrailingSpaces(line, trailingSpaceFormatter) { + return line.replace(/\s+$/, (match) => trailingSpaceFormatter(match)); +} +function printDiffLine(line, isFirstOrLast, color, indicator, trailingSpaceFormatter, emptyFirstOrLastLinePlaceholder) { + return line.length !== 0 ? color(`${indicator} ${formatTrailingSpaces(line, trailingSpaceFormatter)}`) : indicator !== " " ? color(indicator) : isFirstOrLast && emptyFirstOrLastLinePlaceholder.length !== 0 ? color(`${indicator} ${emptyFirstOrLastLinePlaceholder}`) : ""; +} +function printDeleteLine(line, isFirstOrLast, { aColor, aIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder }) { + return printDiffLine(line, isFirstOrLast, aColor, aIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder); +} +function printInsertLine(line, isFirstOrLast, { bColor, bIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder }) { + return printDiffLine(line, isFirstOrLast, bColor, bIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder); +} +function printCommonLine(line, isFirstOrLast, { commonColor, commonIndicator, commonLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder }) { + return printDiffLine(line, isFirstOrLast, commonColor, commonIndicator, commonLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder); +} +// In GNU diff format, indexes are one-based instead of zero-based. +function createPatchMark(aStart, aEnd, bStart, bEnd, { patchColor }) { + return patchColor(`@@ -${aStart + 1},${aEnd - aStart} +${bStart + 1},${bEnd - bStart} @@`); +} +// jest --no-expand +// +// Given array of aligned strings with inverse highlight formatting, +// return joined lines with diff formatting (and patch marks, if needed). +function joinAlignedDiffsNoExpand(diffs, options) { + const iLength = diffs.length; + const nContextLines = options.contextLines; + const nContextLines2 = nContextLines + nContextLines; + // First pass: count output lines and see if it has patches. + let jLength = iLength; + let hasExcessAtStartOrEnd = false; + let nExcessesBetweenChanges = 0; + let i = 0; + while (i !== iLength) { + const iStart = i; + while (i !== iLength && diffs[i][0] === DIFF_EQUAL) { + i += 1; + } + if (iStart !== i) { + if (iStart === 0) { + // at start + if (i > nContextLines) { + jLength -= i - nContextLines; + hasExcessAtStartOrEnd = true; + } + } else if (i === iLength) { + // at end + const n = i - iStart; + if (n > nContextLines) { + jLength -= n - nContextLines; + hasExcessAtStartOrEnd = true; + } + } else { + // between changes + const n = i - iStart; + if (n > nContextLines2) { + jLength -= n - nContextLines2; + nExcessesBetweenChanges += 1; + } + } + } + while (i !== iLength && diffs[i][0] !== DIFF_EQUAL) { + i += 1; + } + } + const hasPatch = nExcessesBetweenChanges !== 0 || hasExcessAtStartOrEnd; + if (nExcessesBetweenChanges !== 0) { + jLength += nExcessesBetweenChanges + 1; + } else if (hasExcessAtStartOrEnd) { + jLength += 1; + } + const jLast = jLength - 1; + const lines = []; + let jPatchMark = 0; + if (hasPatch) { + lines.push(""); + } + // Indexes of expected or received lines in current patch: + let aStart = 0; + let bStart = 0; + let aEnd = 0; + let bEnd = 0; + const pushCommonLine = (line) => { + const j = lines.length; + lines.push(printCommonLine(line, j === 0 || j === jLast, options)); + aEnd += 1; + bEnd += 1; + }; + const pushDeleteLine = (line) => { + const j = lines.length; + lines.push(printDeleteLine(line, j === 0 || j === jLast, options)); + aEnd += 1; + }; + const pushInsertLine = (line) => { + const j = lines.length; + lines.push(printInsertLine(line, j === 0 || j === jLast, options)); + bEnd += 1; + }; + // Second pass: push lines with diff formatting (and patch marks, if needed). + i = 0; + while (i !== iLength) { + let iStart = i; + while (i !== iLength && diffs[i][0] === DIFF_EQUAL) { + i += 1; + } + if (iStart !== i) { + if (iStart === 0) { + // at beginning + if (i > nContextLines) { + iStart = i - nContextLines; + aStart = iStart; + bStart = iStart; + aEnd = aStart; + bEnd = bStart; + } + for (let iCommon = iStart; iCommon !== i; iCommon += 1) { + pushCommonLine(diffs[iCommon][1]); + } + } else if (i === iLength) { + // at end + const iEnd = i - iStart > nContextLines ? iStart + nContextLines : i; + for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) { + pushCommonLine(diffs[iCommon][1]); + } + } else { + // between changes + const nCommon = i - iStart; + if (nCommon > nContextLines2) { + const iEnd = iStart + nContextLines; + for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) { + pushCommonLine(diffs[iCommon][1]); + } + lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options); + jPatchMark = lines.length; + lines.push(""); + const nOmit = nCommon - nContextLines2; + aStart = aEnd + nOmit; + bStart = bEnd + nOmit; + aEnd = aStart; + bEnd = bStart; + for (let iCommon = i - nContextLines; iCommon !== i; iCommon += 1) { + pushCommonLine(diffs[iCommon][1]); + } + } else { + for (let iCommon = iStart; iCommon !== i; iCommon += 1) { + pushCommonLine(diffs[iCommon][1]); + } + } + } + } + while (i !== iLength && diffs[i][0] === DIFF_DELETE) { + pushDeleteLine(diffs[i][1]); + i += 1; + } + while (i !== iLength && diffs[i][0] === DIFF_INSERT) { + pushInsertLine(diffs[i][1]); + i += 1; + } + } + if (hasPatch) { + lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options); + } + return lines.join("\n"); +} +// jest --expand +// +// Given array of aligned strings with inverse highlight formatting, +// return joined lines with diff formatting. +function joinAlignedDiffsExpand(diffs, options) { + return diffs.map((diff, i, diffs) => { + const line = diff[1]; + const isFirstOrLast = i === 0 || i === diffs.length - 1; + switch (diff[0]) { + case DIFF_DELETE: return printDeleteLine(line, isFirstOrLast, options); + case DIFF_INSERT: return printInsertLine(line, isFirstOrLast, options); + default: return printCommonLine(line, isFirstOrLast, options); + } + }).join("\n"); +} + +const noColor = (string) => string; +const DIFF_CONTEXT_DEFAULT = 5; +const DIFF_TRUNCATE_THRESHOLD_DEFAULT = 0; +function getDefaultOptions() { + return { + aAnnotation: "Expected", + aColor: c.green, + aIndicator: "-", + bAnnotation: "Received", + bColor: c.red, + bIndicator: "+", + changeColor: c.inverse, + changeLineTrailingSpaceColor: noColor, + commonColor: c.dim, + commonIndicator: " ", + commonLineTrailingSpaceColor: noColor, + compareKeys: undefined, + contextLines: DIFF_CONTEXT_DEFAULT, + emptyFirstOrLastLinePlaceholder: "", + expand: false, + includeChangeCounts: false, + omitAnnotationLines: false, + patchColor: c.yellow, + printBasicPrototype: false, + truncateThreshold: DIFF_TRUNCATE_THRESHOLD_DEFAULT, + truncateAnnotation: "... Diff result is truncated", + truncateAnnotationColor: noColor + }; +} +function getCompareKeys(compareKeys) { + return compareKeys && typeof compareKeys === "function" ? compareKeys : undefined; +} +function getContextLines(contextLines) { + return typeof contextLines === "number" && Number.isSafeInteger(contextLines) && contextLines >= 0 ? contextLines : DIFF_CONTEXT_DEFAULT; +} +// Pure function returns options with all properties. +function normalizeDiffOptions(options = {}) { + return { + ...getDefaultOptions(), + ...options, + compareKeys: getCompareKeys(options.compareKeys), + contextLines: getContextLines(options.contextLines) + }; +} + +function isEmptyString(lines) { + return lines.length === 1 && lines[0].length === 0; +} +function countChanges(diffs) { + let a = 0; + let b = 0; + diffs.forEach((diff) => { + switch (diff[0]) { + case DIFF_DELETE: + a += 1; + break; + case DIFF_INSERT: + b += 1; + break; + } + }); + return { + a, + b + }; +} +function printAnnotation({ aAnnotation, aColor, aIndicator, bAnnotation, bColor, bIndicator, includeChangeCounts, omitAnnotationLines }, changeCounts) { + if (omitAnnotationLines) { + return ""; + } + let aRest = ""; + let bRest = ""; + if (includeChangeCounts) { + const aCount = String(changeCounts.a); + const bCount = String(changeCounts.b); + // Padding right aligns the ends of the annotations. + const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length; + const aAnnotationPadding = " ".repeat(Math.max(0, baAnnotationLengthDiff)); + const bAnnotationPadding = " ".repeat(Math.max(0, -baAnnotationLengthDiff)); + // Padding left aligns the ends of the counts. + const baCountLengthDiff = bCount.length - aCount.length; + const aCountPadding = " ".repeat(Math.max(0, baCountLengthDiff)); + const bCountPadding = " ".repeat(Math.max(0, -baCountLengthDiff)); + aRest = `${aAnnotationPadding} ${aIndicator} ${aCountPadding}${aCount}`; + bRest = `${bAnnotationPadding} ${bIndicator} ${bCountPadding}${bCount}`; + } + const a = `${aIndicator} ${aAnnotation}${aRest}`; + const b = `${bIndicator} ${bAnnotation}${bRest}`; + return `${aColor(a)}\n${bColor(b)}\n\n`; +} +function printDiffLines(diffs, truncated, options) { + return printAnnotation(options, countChanges(diffs)) + (options.expand ? joinAlignedDiffsExpand(diffs, options) : joinAlignedDiffsNoExpand(diffs, options)) + (truncated ? options.truncateAnnotationColor(`\n${options.truncateAnnotation}`) : ""); +} +// Compare two arrays of strings line-by-line. Format as comparison lines. +function diffLinesUnified(aLines, bLines, options) { + const normalizedOptions = normalizeDiffOptions(options); + const [diffs, truncated] = diffLinesRaw(isEmptyString(aLines) ? [] : aLines, isEmptyString(bLines) ? [] : bLines, normalizedOptions); + return printDiffLines(diffs, truncated, normalizedOptions); +} +// Given two pairs of arrays of strings: +// Compare the pair of comparison arrays line-by-line. +// Format the corresponding lines in the pair of displayable arrays. +function diffLinesUnified2(aLinesDisplay, bLinesDisplay, aLinesCompare, bLinesCompare, options) { + if (isEmptyString(aLinesDisplay) && isEmptyString(aLinesCompare)) { + aLinesDisplay = []; + aLinesCompare = []; + } + if (isEmptyString(bLinesDisplay) && isEmptyString(bLinesCompare)) { + bLinesDisplay = []; + bLinesCompare = []; + } + if (aLinesDisplay.length !== aLinesCompare.length || bLinesDisplay.length !== bLinesCompare.length) { + // Fall back to diff of display lines. + return diffLinesUnified(aLinesDisplay, bLinesDisplay, options); + } + const [diffs, truncated] = diffLinesRaw(aLinesCompare, bLinesCompare, options); + // Replace comparison lines with displayable lines. + let aIndex = 0; + let bIndex = 0; + diffs.forEach((diff) => { + switch (diff[0]) { + case DIFF_DELETE: + diff[1] = aLinesDisplay[aIndex]; + aIndex += 1; + break; + case DIFF_INSERT: + diff[1] = bLinesDisplay[bIndex]; + bIndex += 1; + break; + default: + diff[1] = bLinesDisplay[bIndex]; + aIndex += 1; + bIndex += 1; + } + }); + return printDiffLines(diffs, truncated, normalizeDiffOptions(options)); +} +// Compare two arrays of strings line-by-line. +function diffLinesRaw(aLines, bLines, options) { + const truncate = (options === null || options === void 0 ? void 0 : options.truncateThreshold) ?? false; + const truncateThreshold = Math.max(Math.floor((options === null || options === void 0 ? void 0 : options.truncateThreshold) ?? 0), 0); + const aLength = truncate ? Math.min(aLines.length, truncateThreshold) : aLines.length; + const bLength = truncate ? Math.min(bLines.length, truncateThreshold) : bLines.length; + const truncated = aLength !== aLines.length || bLength !== bLines.length; + const isCommon = (aIndex, bIndex) => aLines[aIndex] === bLines[bIndex]; + const diffs = []; + let aIndex = 0; + let bIndex = 0; + const foundSubsequence = (nCommon, aCommon, bCommon) => { + for (; aIndex !== aCommon; aIndex += 1) { + diffs.push(new Diff(DIFF_DELETE, aLines[aIndex])); + } + for (; bIndex !== bCommon; bIndex += 1) { + diffs.push(new Diff(DIFF_INSERT, bLines[bIndex])); + } + for (; nCommon !== 0; nCommon -= 1, aIndex += 1, bIndex += 1) { + diffs.push(new Diff(DIFF_EQUAL, bLines[bIndex])); + } + }; + diffSequences(aLength, bLength, isCommon, foundSubsequence); + // After the last common subsequence, push remaining change items. + for (; aIndex !== aLength; aIndex += 1) { + diffs.push(new Diff(DIFF_DELETE, aLines[aIndex])); + } + for (; bIndex !== bLength; bIndex += 1) { + diffs.push(new Diff(DIFF_INSERT, bLines[bIndex])); + } + return [diffs, truncated]; +} + +// get the type of a value with handling the edge cases like `typeof []` +// and `typeof null` +function getType(value) { + if (value === undefined) { + return "undefined"; + } else if (value === null) { + return "null"; + } else if (Array.isArray(value)) { + return "array"; + } else if (typeof value === "boolean") { + return "boolean"; + } else if (typeof value === "function") { + return "function"; + } else if (typeof value === "number") { + return "number"; + } else if (typeof value === "string") { + return "string"; + } else if (typeof value === "bigint") { + return "bigint"; + } else if (typeof value === "object") { + if (value != null) { + if (value.constructor === RegExp) { + return "regexp"; + } else if (value.constructor === Map) { + return "map"; + } else if (value.constructor === Set) { + return "set"; + } else if (value.constructor === Date) { + return "date"; + } + } + return "object"; + } else if (typeof value === "symbol") { + return "symbol"; + } + throw new Error(`value of unknown type: ${value}`); +} + +// platforms compatible +function getNewLineSymbol(string) { + return string.includes("\r\n") ? "\r\n" : "\n"; +} +function diffStrings(a, b, options) { + const truncate = (options === null || options === void 0 ? void 0 : options.truncateThreshold) ?? false; + const truncateThreshold = Math.max(Math.floor((options === null || options === void 0 ? void 0 : options.truncateThreshold) ?? 0), 0); + let aLength = a.length; + let bLength = b.length; + if (truncate) { + const aMultipleLines = a.includes("\n"); + const bMultipleLines = b.includes("\n"); + const aNewLineSymbol = getNewLineSymbol(a); + const bNewLineSymbol = getNewLineSymbol(b); + // multiple-lines string expects a newline to be appended at the end + const _a = aMultipleLines ? `${a.split(aNewLineSymbol, truncateThreshold).join(aNewLineSymbol)}\n` : a; + const _b = bMultipleLines ? `${b.split(bNewLineSymbol, truncateThreshold).join(bNewLineSymbol)}\n` : b; + aLength = _a.length; + bLength = _b.length; + } + const truncated = aLength !== a.length || bLength !== b.length; + const isCommon = (aIndex, bIndex) => a[aIndex] === b[bIndex]; + let aIndex = 0; + let bIndex = 0; + const diffs = []; + const foundSubsequence = (nCommon, aCommon, bCommon) => { + if (aIndex !== aCommon) { + diffs.push(new Diff(DIFF_DELETE, a.slice(aIndex, aCommon))); + } + if (bIndex !== bCommon) { + diffs.push(new Diff(DIFF_INSERT, b.slice(bIndex, bCommon))); + } + aIndex = aCommon + nCommon; + bIndex = bCommon + nCommon; + diffs.push(new Diff(DIFF_EQUAL, b.slice(bCommon, bIndex))); + }; + diffSequences(aLength, bLength, isCommon, foundSubsequence); + // After the last common subsequence, push remaining change items. + if (aIndex !== aLength) { + diffs.push(new Diff(DIFF_DELETE, a.slice(aIndex))); + } + if (bIndex !== bLength) { + diffs.push(new Diff(DIFF_INSERT, b.slice(bIndex))); + } + return [diffs, truncated]; +} + +// Given change op and array of diffs, return concatenated string: +// * include common strings +// * include change strings which have argument op with changeColor +// * exclude change strings which have opposite op +function concatenateRelevantDiffs(op, diffs, changeColor) { + return diffs.reduce((reduced, diff) => reduced + (diff[0] === DIFF_EQUAL ? diff[1] : diff[0] === op && diff[1].length !== 0 ? changeColor(diff[1]) : ""), ""); +} +// Encapsulate change lines until either a common newline or the end. +class ChangeBuffer { + op; + line; + lines; + changeColor; + constructor(op, changeColor) { + this.op = op; + this.line = []; + this.lines = []; + this.changeColor = changeColor; + } + pushSubstring(substring) { + this.pushDiff(new Diff(this.op, substring)); + } + pushLine() { + // Assume call only if line has at least one diff, + // therefore an empty line must have a diff which has an empty string. + // If line has multiple diffs, then assume it has a common diff, + // therefore change diffs have change color; + // otherwise then it has line color only. + this.lines.push(this.line.length !== 1 ? new Diff(this.op, concatenateRelevantDiffs(this.op, this.line, this.changeColor)) : this.line[0][0] === this.op ? this.line[0] : new Diff(this.op, this.line[0][1])); + this.line.length = 0; + } + isLineEmpty() { + return this.line.length === 0; + } + // Minor input to buffer. + pushDiff(diff) { + this.line.push(diff); + } + // Main input to buffer. + align(diff) { + const string = diff[1]; + if (string.includes("\n")) { + const substrings = string.split("\n"); + const iLast = substrings.length - 1; + substrings.forEach((substring, i) => { + if (i < iLast) { + // The first substring completes the current change line. + // A middle substring is a change line. + this.pushSubstring(substring); + this.pushLine(); + } else if (substring.length !== 0) { + // The last substring starts a change line, if it is not empty. + // Important: This non-empty condition also automatically omits + // the newline appended to the end of expected and received strings. + this.pushSubstring(substring); + } + }); + } else { + // Append non-multiline string to current change line. + this.pushDiff(diff); + } + } + // Output from buffer. + moveLinesTo(lines) { + if (!this.isLineEmpty()) { + this.pushLine(); + } + lines.push(...this.lines); + this.lines.length = 0; + } +} +// Encapsulate common and change lines. +class CommonBuffer { + deleteBuffer; + insertBuffer; + lines; + constructor(deleteBuffer, insertBuffer) { + this.deleteBuffer = deleteBuffer; + this.insertBuffer = insertBuffer; + this.lines = []; + } + pushDiffCommonLine(diff) { + this.lines.push(diff); + } + pushDiffChangeLines(diff) { + const isDiffEmpty = diff[1].length === 0; + // An empty diff string is redundant, unless a change line is empty. + if (!isDiffEmpty || this.deleteBuffer.isLineEmpty()) { + this.deleteBuffer.pushDiff(diff); + } + if (!isDiffEmpty || this.insertBuffer.isLineEmpty()) { + this.insertBuffer.pushDiff(diff); + } + } + flushChangeLines() { + this.deleteBuffer.moveLinesTo(this.lines); + this.insertBuffer.moveLinesTo(this.lines); + } + // Input to buffer. + align(diff) { + const op = diff[0]; + const string = diff[1]; + if (string.includes("\n")) { + const substrings = string.split("\n"); + const iLast = substrings.length - 1; + substrings.forEach((substring, i) => { + if (i === 0) { + const subdiff = new Diff(op, substring); + if (this.deleteBuffer.isLineEmpty() && this.insertBuffer.isLineEmpty()) { + // If both current change lines are empty, + // then the first substring is a common line. + this.flushChangeLines(); + this.pushDiffCommonLine(subdiff); + } else { + // If either current change line is non-empty, + // then the first substring completes the change lines. + this.pushDiffChangeLines(subdiff); + this.flushChangeLines(); + } + } else if (i < iLast) { + // A middle substring is a common line. + this.pushDiffCommonLine(new Diff(op, substring)); + } else if (substring.length !== 0) { + // The last substring starts a change line, if it is not empty. + // Important: This non-empty condition also automatically omits + // the newline appended to the end of expected and received strings. + this.pushDiffChangeLines(new Diff(op, substring)); + } + }); + } else { + // Append non-multiline string to current change lines. + // Important: It cannot be at the end following empty change lines, + // because newline appended to the end of expected and received strings. + this.pushDiffChangeLines(diff); + } + } + // Output from buffer. + getLines() { + this.flushChangeLines(); + return this.lines; + } +} +// Given diffs from expected and received strings, +// return new array of diffs split or joined into lines. +// +// To correctly align a change line at the end, the algorithm: +// * assumes that a newline was appended to the strings +// * omits the last newline from the output array +// +// Assume the function is not called: +// * if either expected or received is empty string +// * if neither expected nor received is multiline string +function getAlignedDiffs(diffs, changeColor) { + const deleteBuffer = new ChangeBuffer(DIFF_DELETE, changeColor); + const insertBuffer = new ChangeBuffer(DIFF_INSERT, changeColor); + const commonBuffer = new CommonBuffer(deleteBuffer, insertBuffer); + diffs.forEach((diff) => { + switch (diff[0]) { + case DIFF_DELETE: + deleteBuffer.align(diff); + break; + case DIFF_INSERT: + insertBuffer.align(diff); + break; + default: commonBuffer.align(diff); + } + }); + return commonBuffer.getLines(); +} + +function hasCommonDiff(diffs, isMultiline) { + if (isMultiline) { + // Important: Ignore common newline that was appended to multiline strings! + const iLast = diffs.length - 1; + return diffs.some((diff, i) => diff[0] === DIFF_EQUAL && (i !== iLast || diff[1] !== "\n")); + } + return diffs.some((diff) => diff[0] === DIFF_EQUAL); +} +// Compare two strings character-by-character. +// Format as comparison lines in which changed substrings have inverse colors. +function diffStringsUnified(a, b, options) { + if (a !== b && a.length !== 0 && b.length !== 0) { + const isMultiline = a.includes("\n") || b.includes("\n"); + // getAlignedDiffs assumes that a newline was appended to the strings. + const [diffs, truncated] = diffStringsRaw(isMultiline ? `${a}\n` : a, isMultiline ? `${b}\n` : b, true, options); + if (hasCommonDiff(diffs, isMultiline)) { + const optionsNormalized = normalizeDiffOptions(options); + const lines = getAlignedDiffs(diffs, optionsNormalized.changeColor); + return printDiffLines(lines, truncated, optionsNormalized); + } + } + // Fall back to line-by-line diff. + return diffLinesUnified(a.split("\n"), b.split("\n"), options); +} +// Compare two strings character-by-character. +// Optionally clean up small common substrings, also known as chaff. +function diffStringsRaw(a, b, cleanup, options) { + const [diffs, truncated] = diffStrings(a, b, options); + if (cleanup) { + diff_cleanupSemantic(diffs); + } + return [diffs, truncated]; +} + +function getCommonMessage(message, options) { + const { commonColor } = normalizeDiffOptions(options); + return commonColor(message); +} +const { AsymmetricMatcher, DOMCollection, DOMElement, Immutable, ReactElement, ReactTestComponent } = plugins; +const PLUGINS = [ + ReactTestComponent, + ReactElement, + DOMElement, + DOMCollection, + Immutable, + AsymmetricMatcher, + plugins.Error +]; +const FORMAT_OPTIONS = { + maxDepth: 20, + plugins: PLUGINS +}; +const FALLBACK_FORMAT_OPTIONS = { + callToJSON: false, + maxDepth: 8, + plugins: PLUGINS +}; +// Generate a string that will highlight the difference between two values +// with green and red. (similar to how github does code diffing) +/** +* @param a Expected value +* @param b Received value +* @param options Diff options +* @returns {string | null} a string diff +*/ +function diff(a, b, options) { + if (Object.is(a, b)) { + return ""; + } + const aType = getType(a); + let expectedType = aType; + let omitDifference = false; + if (aType === "object" && typeof a.asymmetricMatch === "function") { + if (a.$$typeof !== Symbol.for("jest.asymmetricMatcher")) { + // Do not know expected type of user-defined asymmetric matcher. + return undefined; + } + if (typeof a.getExpectedType !== "function") { + // For example, expect.anything() matches either null or undefined + return undefined; + } + expectedType = a.getExpectedType(); + // Primitive types boolean and number omit difference below. + // For example, omit difference for expect.stringMatching(regexp) + omitDifference = expectedType === "string"; + } + if (expectedType !== getType(b)) { + const { aAnnotation, aColor, aIndicator, bAnnotation, bColor, bIndicator } = normalizeDiffOptions(options); + const formatOptions = getFormatOptions(FALLBACK_FORMAT_OPTIONS, options); + let aDisplay = format(a, formatOptions); + let bDisplay = format(b, formatOptions); + // even if prettyFormat prints successfully big objects, + // large string can choke later on (concatenation? RPC?), + // so truncate it to a reasonable length here. + // (For example, playwright's ElementHandle can become about 200_000_000 length string) + const MAX_LENGTH = 1e5; + function truncate(s) { + return s.length <= MAX_LENGTH ? s : `${s.slice(0, MAX_LENGTH)}...`; + } + aDisplay = truncate(aDisplay); + bDisplay = truncate(bDisplay); + const aDiff = `${aColor(`${aIndicator} ${aAnnotation}:`)} \n${aDisplay}`; + const bDiff = `${bColor(`${bIndicator} ${bAnnotation}:`)} \n${bDisplay}`; + return `${aDiff}\n\n${bDiff}`; + } + if (omitDifference) { + return undefined; + } + switch (aType) { + case "string": return diffLinesUnified(a.split("\n"), b.split("\n"), options); + case "boolean": + case "number": return comparePrimitive(a, b, options); + case "map": return compareObjects(sortMap(a), sortMap(b), options); + case "set": return compareObjects(sortSet(a), sortSet(b), options); + default: return compareObjects(a, b, options); + } +} +function comparePrimitive(a, b, options) { + const aFormat = format(a, FORMAT_OPTIONS); + const bFormat = format(b, FORMAT_OPTIONS); + return aFormat === bFormat ? "" : diffLinesUnified(aFormat.split("\n"), bFormat.split("\n"), options); +} +function sortMap(map) { + return new Map(Array.from(map.entries()).sort()); +} +function sortSet(set) { + return new Set(Array.from(set.values()).sort()); +} +function compareObjects(a, b, options) { + let difference; + let hasThrown = false; + try { + const formatOptions = getFormatOptions(FORMAT_OPTIONS, options); + difference = getObjectsDifference(a, b, formatOptions, options); + } catch { + hasThrown = true; + } + const noDiffMessage = getCommonMessage(NO_DIFF_MESSAGE, options); + // If the comparison yields no results, compare again but this time + // without calling `toJSON`. It's also possible that toJSON might throw. + if (difference === undefined || difference === noDiffMessage) { + const formatOptions = getFormatOptions(FALLBACK_FORMAT_OPTIONS, options); + difference = getObjectsDifference(a, b, formatOptions, options); + if (difference !== noDiffMessage && !hasThrown) { + difference = `${getCommonMessage(SIMILAR_MESSAGE, options)}\n\n${difference}`; + } + } + return difference; +} +function getFormatOptions(formatOptions, options) { + const { compareKeys, printBasicPrototype, maxDepth } = normalizeDiffOptions(options); + return { + ...formatOptions, + compareKeys, + printBasicPrototype, + maxDepth: maxDepth ?? formatOptions.maxDepth + }; +} +function getObjectsDifference(a, b, formatOptions, options) { + const formatOptionsZeroIndent = { + ...formatOptions, + indent: 0 + }; + const aCompare = format(a, formatOptionsZeroIndent); + const bCompare = format(b, formatOptionsZeroIndent); + if (aCompare === bCompare) { + return getCommonMessage(NO_DIFF_MESSAGE, options); + } else { + const aDisplay = format(a, formatOptions); + const bDisplay = format(b, formatOptions); + return diffLinesUnified2(aDisplay.split("\n"), bDisplay.split("\n"), aCompare.split("\n"), bCompare.split("\n"), options); + } +} +const MAX_DIFF_STRING_LENGTH = 2e4; +function isAsymmetricMatcher(data) { + const type = getType$1(data); + return type === "Object" && typeof data.asymmetricMatch === "function"; +} +function isReplaceable(obj1, obj2) { + const obj1Type = getType$1(obj1); + const obj2Type = getType$1(obj2); + return obj1Type === obj2Type && (obj1Type === "Object" || obj1Type === "Array"); +} +function printDiffOrStringify(received, expected, options) { + const { aAnnotation, bAnnotation } = normalizeDiffOptions(options); + if (typeof expected === "string" && typeof received === "string" && expected.length > 0 && received.length > 0 && expected.length <= MAX_DIFF_STRING_LENGTH && received.length <= MAX_DIFF_STRING_LENGTH && expected !== received) { + if (expected.includes("\n") || received.includes("\n")) { + return diffStringsUnified(expected, received, options); + } + const [diffs] = diffStringsRaw(expected, received, true); + const hasCommonDiff = diffs.some((diff) => diff[0] === DIFF_EQUAL); + const printLabel = getLabelPrinter(aAnnotation, bAnnotation); + const expectedLine = printLabel(aAnnotation) + printExpected(getCommonAndChangedSubstrings(diffs, DIFF_DELETE, hasCommonDiff)); + const receivedLine = printLabel(bAnnotation) + printReceived(getCommonAndChangedSubstrings(diffs, DIFF_INSERT, hasCommonDiff)); + return `${expectedLine}\n${receivedLine}`; + } + // if (isLineDiffable(expected, received)) { + const clonedExpected = deepClone(expected, { forceWritable: true }); + const clonedReceived = deepClone(received, { forceWritable: true }); + const { replacedExpected, replacedActual } = replaceAsymmetricMatcher(clonedReceived, clonedExpected); + const difference = diff(replacedExpected, replacedActual, options); + return difference; + // } + // const printLabel = getLabelPrinter(aAnnotation, bAnnotation) + // const expectedLine = printLabel(aAnnotation) + printExpected(expected) + // const receivedLine + // = printLabel(bAnnotation) + // + (stringify(expected) === stringify(received) + // ? 'serializes to the same string' + // : printReceived(received)) + // return `${expectedLine}\n${receivedLine}` +} +function replaceAsymmetricMatcher(actual, expected, actualReplaced = new WeakSet(), expectedReplaced = new WeakSet()) { + // handle asymmetric Error.cause diff + if (actual instanceof Error && expected instanceof Error && typeof actual.cause !== "undefined" && typeof expected.cause === "undefined") { + delete actual.cause; + return { + replacedActual: actual, + replacedExpected: expected + }; + } + if (!isReplaceable(actual, expected)) { + return { + replacedActual: actual, + replacedExpected: expected + }; + } + if (actualReplaced.has(actual) || expectedReplaced.has(expected)) { + return { + replacedActual: actual, + replacedExpected: expected + }; + } + actualReplaced.add(actual); + expectedReplaced.add(expected); + getOwnProperties(expected).forEach((key) => { + const expectedValue = expected[key]; + const actualValue = actual[key]; + if (isAsymmetricMatcher(expectedValue)) { + if (expectedValue.asymmetricMatch(actualValue)) { + actual[key] = expectedValue; + } + } else if (isAsymmetricMatcher(actualValue)) { + if (actualValue.asymmetricMatch(expectedValue)) { + expected[key] = actualValue; + } + } else if (isReplaceable(actualValue, expectedValue)) { + const replaced = replaceAsymmetricMatcher(actualValue, expectedValue, actualReplaced, expectedReplaced); + actual[key] = replaced.replacedActual; + expected[key] = replaced.replacedExpected; + } + }); + return { + replacedActual: actual, + replacedExpected: expected + }; +} +function getLabelPrinter(...strings) { + const maxLength = strings.reduce((max, string) => string.length > max ? string.length : max, 0); + return (string) => `${string}: ${" ".repeat(maxLength - string.length)}`; +} +const SPACE_SYMBOL = "·"; +function replaceTrailingSpaces(text) { + return text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length)); +} +function printReceived(object) { + return c.red(replaceTrailingSpaces(stringify(object))); +} +function printExpected(value) { + return c.green(replaceTrailingSpaces(stringify(value))); +} +function getCommonAndChangedSubstrings(diffs, op, hasCommonDiff) { + return diffs.reduce((reduced, diff) => reduced + (diff[0] === DIFF_EQUAL ? diff[1] : diff[0] === op ? hasCommonDiff ? c.inverse(diff[1]) : diff[1] : ""), ""); +} + +export { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff, diff, diffLinesRaw, diffLinesUnified, diffLinesUnified2, diffStringsRaw, diffStringsUnified, getLabelPrinter, printDiffOrStringify, replaceAsymmetricMatcher }; diff --git a/node_modules/@vitest/utils/dist/error.d.ts b/node_modules/@vitest/utils/dist/error.d.ts new file mode 100644 index 0000000000..bceeaf0801 --- /dev/null +++ b/node_modules/@vitest/utils/dist/error.d.ts @@ -0,0 +1,9 @@ +import { D as DiffOptions } from './types.d-BCElaP-c.js'; +import '@vitest/pretty-format'; + +// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm +declare function serializeValue(val: any, seen?: WeakMap): any; + +declare function processError(_err: any, diffOptions?: DiffOptions, seen?: WeakSet): any; + +export { processError, serializeValue as serializeError, serializeValue }; diff --git a/node_modules/@vitest/utils/dist/error.js b/node_modules/@vitest/utils/dist/error.js new file mode 100644 index 0000000000..42a6d4c8d0 --- /dev/null +++ b/node_modules/@vitest/utils/dist/error.js @@ -0,0 +1,162 @@ +import { printDiffOrStringify } from './diff.js'; +import { f as format, s as stringify } from './chunk-_commonjsHelpers.js'; +import '@vitest/pretty-format'; +import 'tinyrainbow'; +import './helpers.js'; +import 'loupe'; + +const IS_RECORD_SYMBOL = "@@__IMMUTABLE_RECORD__@@"; +const IS_COLLECTION_SYMBOL = "@@__IMMUTABLE_ITERABLE__@@"; +function isImmutable(v) { + return v && (v[IS_COLLECTION_SYMBOL] || v[IS_RECORD_SYMBOL]); +} +const OBJECT_PROTO = Object.getPrototypeOf({}); +function getUnserializableMessage(err) { + if (err instanceof Error) { + return `: ${err.message}`; + } + if (typeof err === "string") { + return `: ${err}`; + } + return ""; +} +// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm +function serializeValue(val, seen = new WeakMap()) { + if (!val || typeof val === "string") { + return val; + } + if (val instanceof Error && "toJSON" in val && typeof val.toJSON === "function") { + const jsonValue = val.toJSON(); + if (jsonValue && jsonValue !== val && typeof jsonValue === "object") { + if (typeof val.message === "string") { + safe(() => jsonValue.message ?? (jsonValue.message = val.message)); + } + if (typeof val.stack === "string") { + safe(() => jsonValue.stack ?? (jsonValue.stack = val.stack)); + } + if (typeof val.name === "string") { + safe(() => jsonValue.name ?? (jsonValue.name = val.name)); + } + if (val.cause != null) { + safe(() => jsonValue.cause ?? (jsonValue.cause = serializeValue(val.cause, seen))); + } + } + return serializeValue(jsonValue, seen); + } + if (typeof val === "function") { + return `Function<${val.name || "anonymous"}>`; + } + if (typeof val === "symbol") { + return val.toString(); + } + if (typeof val !== "object") { + return val; + } + if (typeof Buffer !== "undefined" && val instanceof Buffer) { + return ``; + } + if (typeof Uint8Array !== "undefined" && val instanceof Uint8Array) { + return ``; + } + // cannot serialize immutables as immutables + if (isImmutable(val)) { + return serializeValue(val.toJSON(), seen); + } + if (val instanceof Promise || val.constructor && val.constructor.prototype === "AsyncFunction") { + return "Promise"; + } + if (typeof Element !== "undefined" && val instanceof Element) { + return val.tagName; + } + if (typeof val.asymmetricMatch === "function") { + return `${val.toString()} ${format(val.sample)}`; + } + if (typeof val.toJSON === "function") { + return serializeValue(val.toJSON(), seen); + } + if (seen.has(val)) { + return seen.get(val); + } + if (Array.isArray(val)) { + // eslint-disable-next-line unicorn/no-new-array -- we need to keep sparse arrays ([1,,3]) + const clone = new Array(val.length); + seen.set(val, clone); + val.forEach((e, i) => { + try { + clone[i] = serializeValue(e, seen); + } catch (err) { + clone[i] = getUnserializableMessage(err); + } + }); + return clone; + } else { + // Objects with `Error` constructors appear to cause problems during worker communication + // using `MessagePort`, so the serialized error object is being recreated as plain object. + const clone = Object.create(null); + seen.set(val, clone); + let obj = val; + while (obj && obj !== OBJECT_PROTO) { + Object.getOwnPropertyNames(obj).forEach((key) => { + if (key in clone) { + return; + } + try { + clone[key] = serializeValue(val[key], seen); + } catch (err) { + // delete in case it has a setter from prototype that might throw + delete clone[key]; + clone[key] = getUnserializableMessage(err); + } + }); + obj = Object.getPrototypeOf(obj); + } + return clone; + } +} +function safe(fn) { + try { + return fn(); + } catch {} +} +function normalizeErrorMessage(message) { + return message.replace(/__(vite_ssr_import|vi_import)_\d+__\./g, ""); +} +function processError(_err, diffOptions, seen = new WeakSet()) { + if (!_err || typeof _err !== "object") { + return { message: String(_err) }; + } + const err = _err; + if (err.showDiff || err.showDiff === undefined && err.expected !== undefined && err.actual !== undefined) { + err.diff = printDiffOrStringify(err.actual, err.expected, { + ...diffOptions, + ...err.diffOptions + }); + } + if ("expected" in err && typeof err.expected !== "string") { + err.expected = stringify(err.expected, 10); + } + if ("actual" in err && typeof err.actual !== "string") { + err.actual = stringify(err.actual, 10); + } + // some Error implementations don't allow rewriting message + try { + if (typeof err.message === "string") { + err.message = normalizeErrorMessage(err.message); + } + } catch {} + // some Error implementations may not allow rewriting cause + // in most cases, the assignment will lead to "err.cause = err.cause" + try { + if (!seen.has(err) && typeof err.cause === "object") { + seen.add(err); + err.cause = processError(err.cause, diffOptions, seen); + } + } catch {} + try { + return serializeValue(err); + } catch (e) { + return serializeValue(new Error(`Failed to fully serialize error: ${e === null || e === void 0 ? void 0 : e.message}\nInner error message: ${err === null || err === void 0 ? void 0 : err.message}`)); + } +} + +export { processError, serializeValue as serializeError, serializeValue }; diff --git a/node_modules/@vitest/utils/dist/helpers.d.ts b/node_modules/@vitest/utils/dist/helpers.d.ts new file mode 100644 index 0000000000..d9f90dc575 --- /dev/null +++ b/node_modules/@vitest/utils/dist/helpers.d.ts @@ -0,0 +1,56 @@ +import { Nullable, Arrayable } from './types.js'; + +interface CloneOptions { + forceWritable?: boolean; +} +interface ErrorOptions { + message?: string; + stackTraceLimit?: number; +} +/** +* Get original stacktrace without source map support the most performant way. +* - Create only 1 stack frame. +* - Rewrite prepareStackTrace to bypass "support-stack-trace" (usually takes ~250ms). +*/ +declare function createSimpleStackTrace(options?: ErrorOptions): string; +declare function notNullish(v: T | null | undefined): v is NonNullable; +declare function assertTypes(value: unknown, name: string, types: string[]): void; +declare function isPrimitive(value: unknown): boolean; +declare function slash(path: string): string; +// convert RegExp.toString to RegExp +declare function parseRegexp(input: string): RegExp; +declare function toArray(array?: Nullable>): Array; +declare function isObject(item: unknown): boolean; +declare function getType(value: unknown): string; +declare function getOwnProperties(obj: any): (string | symbol)[]; +declare function deepClone(val: T, options?: CloneOptions): T; +declare function clone(val: T, seen: WeakMap, options?: CloneOptions): T; +declare function noop(): void; +declare function objectAttr(source: any, path: string, defaultValue?: undefined): any; +type DeferPromise = Promise & { + resolve: (value: T | PromiseLike) => void + reject: (reason?: any) => void +}; +declare function createDefer(): DeferPromise; +/** +* If code starts with a function call, will return its last index, respecting arguments. +* This will return 25 - last ending character of toMatch ")" +* Also works with callbacks +* ``` +* toMatch({ test: '123' }); +* toBeAliased('123') +* ``` +*/ +declare function getCallLastIndex(code: string): number | null; +declare function isNegativeNaN(val: number): boolean; +/** +* Deep merge :P +* +* Will merge objects only if they are plain +* +* Do not merge types - it is very expensive and usually it's better to case a type here +*/ +declare function deepMerge(target: T, ...sources: any[]): T; + +export { assertTypes, clone, createDefer, createSimpleStackTrace, deepClone, deepMerge, getCallLastIndex, getOwnProperties, getType, isNegativeNaN, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray }; +export type { DeferPromise }; diff --git a/node_modules/@vitest/utils/dist/helpers.js b/node_modules/@vitest/utils/dist/helpers.js new file mode 100644 index 0000000000..678668a084 --- /dev/null +++ b/node_modules/@vitest/utils/dist/helpers.js @@ -0,0 +1,251 @@ +/** +* Get original stacktrace without source map support the most performant way. +* - Create only 1 stack frame. +* - Rewrite prepareStackTrace to bypass "support-stack-trace" (usually takes ~250ms). +*/ +function createSimpleStackTrace(options) { + const { message = "$$stack trace error", stackTraceLimit = 1 } = options || {}; + const limit = Error.stackTraceLimit; + const prepareStackTrace = Error.prepareStackTrace; + Error.stackTraceLimit = stackTraceLimit; + Error.prepareStackTrace = (e) => e.stack; + const err = new Error(message); + const stackTrace = err.stack || ""; + Error.prepareStackTrace = prepareStackTrace; + Error.stackTraceLimit = limit; + return stackTrace; +} +function notNullish(v) { + return v != null; +} +function assertTypes(value, name, types) { + const receivedType = typeof value; + const pass = types.includes(receivedType); + if (!pass) { + throw new TypeError(`${name} value must be ${types.join(" or ")}, received "${receivedType}"`); + } +} +function isPrimitive(value) { + return value === null || typeof value !== "function" && typeof value !== "object"; +} +function slash(path) { + return path.replace(/\\/g, "/"); +} +// convert RegExp.toString to RegExp +function parseRegexp(input) { + // Parse input + // eslint-disable-next-line regexp/no-misleading-capturing-group + const m = input.match(/(\/?)(.+)\1([a-z]*)/i); + // match nothing + if (!m) { + return /$^/; + } + // Invalid flags + // eslint-disable-next-line regexp/optimal-quantifier-concatenation + if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) { + return new RegExp(input); + } + // Create the regular expression + return new RegExp(m[2], m[3]); +} +function toArray(array) { + if (array === null || array === undefined) { + array = []; + } + if (Array.isArray(array)) { + return array; + } + return [array]; +} +function isObject(item) { + return item != null && typeof item === "object" && !Array.isArray(item); +} +function isFinalObj(obj) { + return obj === Object.prototype || obj === Function.prototype || obj === RegExp.prototype; +} +function getType(value) { + return Object.prototype.toString.apply(value).slice(8, -1); +} +function collectOwnProperties(obj, collector) { + const collect = typeof collector === "function" ? collector : (key) => collector.add(key); + Object.getOwnPropertyNames(obj).forEach(collect); + Object.getOwnPropertySymbols(obj).forEach(collect); +} +function getOwnProperties(obj) { + const ownProps = new Set(); + if (isFinalObj(obj)) { + return []; + } + collectOwnProperties(obj, ownProps); + return Array.from(ownProps); +} +const defaultCloneOptions = { forceWritable: false }; +function deepClone(val, options = defaultCloneOptions) { + const seen = new WeakMap(); + return clone(val, seen, options); +} +function clone(val, seen, options = defaultCloneOptions) { + let k, out; + if (seen.has(val)) { + return seen.get(val); + } + if (Array.isArray(val)) { + out = Array.from({ length: k = val.length }); + seen.set(val, out); + while (k--) { + out[k] = clone(val[k], seen, options); + } + return out; + } + if (Object.prototype.toString.call(val) === "[object Object]") { + out = Object.create(Object.getPrototypeOf(val)); + seen.set(val, out); + // we don't need properties from prototype + const props = getOwnProperties(val); + for (const k of props) { + const descriptor = Object.getOwnPropertyDescriptor(val, k); + if (!descriptor) { + continue; + } + const cloned = clone(val[k], seen, options); + if (options.forceWritable) { + Object.defineProperty(out, k, { + enumerable: descriptor.enumerable, + configurable: true, + writable: true, + value: cloned + }); + } else if ("get" in descriptor) { + Object.defineProperty(out, k, { + ...descriptor, + get() { + return cloned; + } + }); + } else { + Object.defineProperty(out, k, { + ...descriptor, + value: cloned + }); + } + } + return out; + } + return val; +} +function noop() {} +function objectAttr(source, path, defaultValue = undefined) { + // a[3].b -> a.3.b + const paths = path.replace(/\[(\d+)\]/g, ".$1").split("."); + let result = source; + for (const p of paths) { + result = new Object(result)[p]; + if (result === undefined) { + return defaultValue; + } + } + return result; +} +function createDefer() { + let resolve = null; + let reject = null; + const p = new Promise((_resolve, _reject) => { + resolve = _resolve; + reject = _reject; + }); + p.resolve = resolve; + p.reject = reject; + return p; +} +/** +* If code starts with a function call, will return its last index, respecting arguments. +* This will return 25 - last ending character of toMatch ")" +* Also works with callbacks +* ``` +* toMatch({ test: '123' }); +* toBeAliased('123') +* ``` +*/ +function getCallLastIndex(code) { + let charIndex = -1; + let inString = null; + let startedBracers = 0; + let endedBracers = 0; + let beforeChar = null; + while (charIndex <= code.length) { + beforeChar = code[charIndex]; + charIndex++; + const char = code[charIndex]; + const isCharString = char === "\"" || char === "'" || char === "`"; + if (isCharString && beforeChar !== "\\") { + if (inString === char) { + inString = null; + } else if (!inString) { + inString = char; + } + } + if (!inString) { + if (char === "(") { + startedBracers++; + } + if (char === ")") { + endedBracers++; + } + } + if (startedBracers && endedBracers && startedBracers === endedBracers) { + return charIndex; + } + } + return null; +} +function isNegativeNaN(val) { + if (!Number.isNaN(val)) { + return false; + } + const f64 = new Float64Array(1); + f64[0] = val; + const u32 = new Uint32Array(f64.buffer); + const isNegative = u32[1] >>> 31 === 1; + return isNegative; +} +function toString(v) { + return Object.prototype.toString.call(v); +} +function isPlainObject(val) { + return toString(val) === "[object Object]" && (!val.constructor || val.constructor.name === "Object"); +} +function isMergeableObject(item) { + return isPlainObject(item) && !Array.isArray(item); +} +/** +* Deep merge :P +* +* Will merge objects only if they are plain +* +* Do not merge types - it is very expensive and usually it's better to case a type here +*/ +function deepMerge(target, ...sources) { + if (!sources.length) { + return target; + } + const source = sources.shift(); + if (source === undefined) { + return target; + } + if (isMergeableObject(target) && isMergeableObject(source)) { + Object.keys(source).forEach((key) => { + const _source = source; + if (isMergeableObject(_source[key])) { + if (!target[key]) { + target[key] = {}; + } + deepMerge(target[key], _source[key]); + } else { + target[key] = _source[key]; + } + }); + } + return deepMerge(target, ...sources); +} + +export { assertTypes, clone, createDefer, createSimpleStackTrace, deepClone, deepMerge, getCallLastIndex, getOwnProperties, getType, isNegativeNaN, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray }; diff --git a/node_modules/@vitest/utils/dist/index.d.ts b/node_modules/@vitest/utils/dist/index.d.ts new file mode 100644 index 0000000000..c90d90611d --- /dev/null +++ b/node_modules/@vitest/utils/dist/index.d.ts @@ -0,0 +1,57 @@ +import { PrettyFormatOptions } from '@vitest/pretty-format'; +export { DeferPromise, assertTypes, clone, createDefer, createSimpleStackTrace, deepClone, deepMerge, getCallLastIndex, getOwnProperties, getType, isNegativeNaN, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray } from './helpers.js'; +import { Colors } from 'tinyrainbow'; +export { ArgumentsType, Arrayable, Awaitable, Constructable, DeepMerge, ErrorWithDiff, MergeInsertions, MutableArray, Nullable, ParsedStack, SerializedError, TestError } from './types.js'; + +type Inspect = (value: unknown, options: Options) => string; +interface Options { + showHidden: boolean; + depth: number; + colors: boolean; + customInspect: boolean; + showProxy: boolean; + maxArrayLength: number; + breakLength: number; + truncate: number; + seen: unknown[]; + inspect: Inspect; + stylize: (value: string, styleType: string) => string; +} +type LoupeOptions = Partial; +interface StringifyOptions extends PrettyFormatOptions { + maxLength?: number; +} +declare function stringify(object: unknown, maxDepth?: number, { maxLength,...options }?: StringifyOptions): string; +declare function format(...args: unknown[]): string; +declare function inspect(obj: unknown, options?: LoupeOptions): string; +declare function objDisplay(obj: unknown, options?: LoupeOptions): string; + +interface HighlightOptions { + jsx?: boolean; + colors?: Colors; +} +declare function highlight(code: string, options?: HighlightOptions): string; + +declare function nanoid(size?: number): string; + +declare const lineSplitRE: RegExp; +declare function positionToOffset(source: string, lineNumber: number, columnNumber: number): number; +declare function offsetToLineNumber(source: string, offset: number): number; + +declare function shuffle(array: T[], seed?: number): T[]; + +interface SafeTimers { + nextTick: (cb: () => void) => void; + setTimeout: typeof setTimeout; + setInterval: typeof setInterval; + clearInterval: typeof clearInterval; + clearTimeout: typeof clearTimeout; + setImmediate: typeof setImmediate; + clearImmediate: typeof clearImmediate; + queueMicrotask: typeof queueMicrotask; +} +declare function getSafeTimers(): SafeTimers; +declare function setSafeTimers(): void; + +export { format, getSafeTimers, highlight, inspect, lineSplitRE, nanoid, objDisplay, offsetToLineNumber, positionToOffset, setSafeTimers, shuffle, stringify }; +export type { LoupeOptions, SafeTimers, StringifyOptions }; diff --git a/node_modules/@vitest/utils/dist/index.js b/node_modules/@vitest/utils/dist/index.js new file mode 100644 index 0000000000..fa7d21eadc --- /dev/null +++ b/node_modules/@vitest/utils/dist/index.js @@ -0,0 +1,633 @@ +import { g as getDefaultExportFromCjs } from './chunk-_commonjsHelpers.js'; +export { f as format, i as inspect, o as objDisplay, s as stringify } from './chunk-_commonjsHelpers.js'; +export { assertTypes, clone, createDefer, createSimpleStackTrace, deepClone, deepMerge, getCallLastIndex, getOwnProperties, getType, isNegativeNaN, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray } from './helpers.js'; +import c from 'tinyrainbow'; +import '@vitest/pretty-format'; +import 'loupe'; + +var jsTokens_1; +var hasRequiredJsTokens; + +function requireJsTokens () { + if (hasRequiredJsTokens) return jsTokens_1; + hasRequiredJsTokens = 1; + // Copyright 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Simon Lydell + // License: MIT. + var Identifier, JSXIdentifier, JSXPunctuator, JSXString, JSXText, KeywordsWithExpressionAfter, KeywordsWithNoLineTerminatorAfter, LineTerminatorSequence, MultiLineComment, Newline, NumericLiteral, Punctuator, RegularExpressionLiteral, SingleLineComment, StringLiteral, Template, TokensNotPrecedingObjectLiteral, TokensPrecedingExpression, WhiteSpace; + RegularExpressionLiteral = /\/(?![*\/])(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\\]).|\\.)*(\/[$_\u200C\u200D\p{ID_Continue}]*|\\)?/yu; + Punctuator = /--|\+\+|=>|\.{3}|\??\.(?!\d)|(?:&&|\|\||\?\?|[+\-%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2}|\/(?![\/*]))=?|[?~,:;[\](){}]/y; + Identifier = /(\x23?)(?=[$_\p{ID_Start}\\])(?:[$_\u200C\u200D\p{ID_Continue}]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+/yu; + StringLiteral = /(['"])(?:(?!\1)[^\\\n\r]|\\(?:\r\n|[^]))*(\1)?/y; + NumericLiteral = /(?:0[xX][\da-fA-F](?:_?[\da-fA-F])*|0[oO][0-7](?:_?[0-7])*|0[bB][01](?:_?[01])*)n?|0n|[1-9](?:_?\d)*n|(?:(?:0(?!\d)|0\d*[89]\d*|[1-9](?:_?\d)*)(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?|0[0-7]+/y; + Template = /[`}](?:[^`\\$]|\\[^]|\$(?!\{))*(`|\$\{)?/y; + WhiteSpace = /[\t\v\f\ufeff\p{Zs}]+/yu; + LineTerminatorSequence = /\r?\n|[\r\u2028\u2029]/y; + MultiLineComment = /\/\*(?:[^*]|\*(?!\/))*(\*\/)?/y; + SingleLineComment = /\/\/.*/y; + JSXPunctuator = /[<>.:={}]|\/(?![\/*])/y; + JSXIdentifier = /[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}-]*/yu; + JSXString = /(['"])(?:(?!\1)[^])*(\1)?/y; + JSXText = /[^<>{}]+/y; + TokensPrecedingExpression = /^(?:[\/+-]|\.{3}|\?(?:InterpolationIn(?:JSX|Template)|NoLineTerminatorHere|NonExpressionParenEnd|UnaryIncDec))?$|[{}([,;<>=*%&|^!~?:]$/; + TokensNotPrecedingObjectLiteral = /^(?:=>|[;\]){}]|else|\?(?:NoLineTerminatorHere|NonExpressionParenEnd))?$/; + KeywordsWithExpressionAfter = /^(?:await|case|default|delete|do|else|instanceof|new|return|throw|typeof|void|yield)$/; + KeywordsWithNoLineTerminatorAfter = /^(?:return|throw|yield)$/; + Newline = RegExp(LineTerminatorSequence.source); + jsTokens_1 = function*(input, {jsx = false} = {}) { + var braces, firstCodePoint, isExpression, lastIndex, lastSignificantToken, length, match, mode, nextLastIndex, nextLastSignificantToken, parenNesting, postfixIncDec, punctuator, stack; + ({length} = input); + lastIndex = 0; + lastSignificantToken = ""; + stack = [ + {tag: "JS"} + ]; + braces = []; + parenNesting = 0; + postfixIncDec = false; + while (lastIndex < length) { + mode = stack[stack.length - 1]; + switch (mode.tag) { + case "JS": + case "JSNonExpressionParen": + case "InterpolationInTemplate": + case "InterpolationInJSX": + if (input[lastIndex] === "/" && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + RegularExpressionLiteral.lastIndex = lastIndex; + if (match = RegularExpressionLiteral.exec(input)) { + lastIndex = RegularExpressionLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "RegularExpressionLiteral", + value: match[0], + closed: match[1] !== void 0 && match[1] !== "\\" + }); + continue; + } + } + Punctuator.lastIndex = lastIndex; + if (match = Punctuator.exec(input)) { + punctuator = match[0]; + nextLastIndex = Punctuator.lastIndex; + nextLastSignificantToken = punctuator; + switch (punctuator) { + case "(": + if (lastSignificantToken === "?NonExpressionParenKeyword") { + stack.push({ + tag: "JSNonExpressionParen", + nesting: parenNesting + }); + } + parenNesting++; + postfixIncDec = false; + break; + case ")": + parenNesting--; + postfixIncDec = true; + if (mode.tag === "JSNonExpressionParen" && parenNesting === mode.nesting) { + stack.pop(); + nextLastSignificantToken = "?NonExpressionParenEnd"; + postfixIncDec = false; + } + break; + case "{": + Punctuator.lastIndex = 0; + isExpression = !TokensNotPrecedingObjectLiteral.test(lastSignificantToken) && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken)); + braces.push(isExpression); + postfixIncDec = false; + break; + case "}": + switch (mode.tag) { + case "InterpolationInTemplate": + if (braces.length === mode.nesting) { + Template.lastIndex = lastIndex; + match = Template.exec(input); + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + postfixIncDec = false; + yield ({ + type: "TemplateMiddle", + value: match[0] + }); + } else { + stack.pop(); + postfixIncDec = true; + yield ({ + type: "TemplateTail", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "InterpolationInJSX": + if (braces.length === mode.nesting) { + stack.pop(); + lastIndex += 1; + lastSignificantToken = "}"; + yield ({ + type: "JSXPunctuator", + value: "}" + }); + continue; + } + } + postfixIncDec = braces.pop(); + nextLastSignificantToken = postfixIncDec ? "?ExpressionBraceEnd" : "}"; + break; + case "]": + postfixIncDec = true; + break; + case "++": + case "--": + nextLastSignificantToken = postfixIncDec ? "?PostfixIncDec" : "?UnaryIncDec"; + break; + case "<": + if (jsx && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + stack.push({tag: "JSXTag"}); + lastIndex += 1; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: punctuator + }); + continue; + } + postfixIncDec = false; + break; + default: + postfixIncDec = false; + } + lastIndex = nextLastIndex; + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "Punctuator", + value: punctuator + }); + continue; + } + Identifier.lastIndex = lastIndex; + if (match = Identifier.exec(input)) { + lastIndex = Identifier.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "for": + case "if": + case "while": + case "with": + if (lastSignificantToken !== "." && lastSignificantToken !== "?.") { + nextLastSignificantToken = "?NonExpressionParenKeyword"; + } + } + lastSignificantToken = nextLastSignificantToken; + postfixIncDec = !KeywordsWithExpressionAfter.test(match[0]); + yield ({ + type: match[1] === "#" ? "PrivateIdentifier" : "IdentifierName", + value: match[0] + }); + continue; + } + StringLiteral.lastIndex = lastIndex; + if (match = StringLiteral.exec(input)) { + lastIndex = StringLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "StringLiteral", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + NumericLiteral.lastIndex = lastIndex; + if (match = NumericLiteral.exec(input)) { + lastIndex = NumericLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "NumericLiteral", + value: match[0] + }); + continue; + } + Template.lastIndex = lastIndex; + if (match = Template.exec(input)) { + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + stack.push({ + tag: "InterpolationInTemplate", + nesting: braces.length + }); + postfixIncDec = false; + yield ({ + type: "TemplateHead", + value: match[0] + }); + } else { + postfixIncDec = true; + yield ({ + type: "NoSubstitutionTemplate", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "JSXTag": + case "JSXTagEnd": + JSXPunctuator.lastIndex = lastIndex; + if (match = JSXPunctuator.exec(input)) { + lastIndex = JSXPunctuator.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "<": + stack.push({tag: "JSXTag"}); + break; + case ">": + stack.pop(); + if (lastSignificantToken === "/" || mode.tag === "JSXTagEnd") { + nextLastSignificantToken = "?JSX"; + postfixIncDec = true; + } else { + stack.push({tag: "JSXChildren"}); + } + break; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + nextLastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + break; + case "/": + if (lastSignificantToken === "<") { + stack.pop(); + if (stack[stack.length - 1].tag === "JSXChildren") { + stack.pop(); + } + stack.push({tag: "JSXTagEnd"}); + } + } + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "JSXPunctuator", + value: match[0] + }); + continue; + } + JSXIdentifier.lastIndex = lastIndex; + if (match = JSXIdentifier.exec(input)) { + lastIndex = JSXIdentifier.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXIdentifier", + value: match[0] + }); + continue; + } + JSXString.lastIndex = lastIndex; + if (match = JSXString.exec(input)) { + lastIndex = JSXString.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXString", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + break; + case "JSXChildren": + JSXText.lastIndex = lastIndex; + if (match = JSXText.exec(input)) { + lastIndex = JSXText.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXText", + value: match[0] + }); + continue; + } + switch (input[lastIndex]) { + case "<": + stack.push({tag: "JSXTag"}); + lastIndex++; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: "<" + }); + continue; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + lastIndex++; + lastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + yield ({ + type: "JSXPunctuator", + value: "{" + }); + continue; + } + } + WhiteSpace.lastIndex = lastIndex; + if (match = WhiteSpace.exec(input)) { + lastIndex = WhiteSpace.lastIndex; + yield ({ + type: "WhiteSpace", + value: match[0] + }); + continue; + } + LineTerminatorSequence.lastIndex = lastIndex; + if (match = LineTerminatorSequence.exec(input)) { + lastIndex = LineTerminatorSequence.lastIndex; + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + yield ({ + type: "LineTerminatorSequence", + value: match[0] + }); + continue; + } + MultiLineComment.lastIndex = lastIndex; + if (match = MultiLineComment.exec(input)) { + lastIndex = MultiLineComment.lastIndex; + if (Newline.test(match[0])) { + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + } + yield ({ + type: "MultiLineComment", + value: match[0], + closed: match[1] !== void 0 + }); + continue; + } + SingleLineComment.lastIndex = lastIndex; + if (match = SingleLineComment.exec(input)) { + lastIndex = SingleLineComment.lastIndex; + postfixIncDec = false; + yield ({ + type: "SingleLineComment", + value: match[0] + }); + continue; + } + firstCodePoint = String.fromCodePoint(input.codePointAt(lastIndex)); + lastIndex += firstCodePoint.length; + lastSignificantToken = firstCodePoint; + postfixIncDec = false; + yield ({ + type: mode.tag.startsWith("JSX") ? "JSXInvalid" : "Invalid", + value: firstCodePoint + }); + } + return void 0; + }; + return jsTokens_1; +} + +var jsTokensExports = requireJsTokens(); +var jsTokens = /*@__PURE__*/getDefaultExportFromCjs(jsTokensExports); + +// src/index.ts +var reservedWords = { + keyword: [ + "break", + "case", + "catch", + "continue", + "debugger", + "default", + "do", + "else", + "finally", + "for", + "function", + "if", + "return", + "switch", + "throw", + "try", + "var", + "const", + "while", + "with", + "new", + "this", + "super", + "class", + "extends", + "export", + "import", + "null", + "true", + "false", + "in", + "instanceof", + "typeof", + "void", + "delete" + ], + strict: [ + "implements", + "interface", + "let", + "package", + "private", + "protected", + "public", + "static", + "yield" + ] +}, keywords = new Set(reservedWords.keyword), reservedWordsStrictSet = new Set(reservedWords.strict), sometimesKeywords = /* @__PURE__ */ new Set(["as", "async", "from", "get", "of", "set"]); +function isReservedWord(word) { + return word === "await" || word === "enum"; +} +function isStrictReservedWord(word) { + return isReservedWord(word) || reservedWordsStrictSet.has(word); +} +function isKeyword(word) { + return keywords.has(word); +} +var BRACKET = /^[()[\]{}]$/, getTokenType = function(token) { + if (token.type === "IdentifierName") { + if (isKeyword(token.value) || isStrictReservedWord(token.value) || sometimesKeywords.has(token.value)) + return "Keyword"; + if (token.value[0] && token.value[0] !== token.value[0].toLowerCase()) + return "IdentifierCapitalized"; + } + return token.type === "Punctuator" && BRACKET.test(token.value) ? "Bracket" : token.type === "Invalid" && (token.value === "@" || token.value === "#") ? "Punctuator" : token.type; +}; +function getCallableType(token) { + if (token.type === "IdentifierName") + return "IdentifierCallable"; + if (token.type === "PrivateIdentifier") + return "PrivateIdentifierCallable"; + throw new Error("Not a callable token"); +} +var colorize = (defs, type, value) => { + let colorize2 = defs[type]; + return colorize2 ? colorize2(value) : value; +}, highlightTokens = (defs, text, jsx) => { + let highlighted = "", lastPotentialCallable = null, stackedHighlight = ""; + for (let token of jsTokens(text, { jsx })) { + let type = getTokenType(token); + if (type === "IdentifierName" || type === "PrivateIdentifier") { + lastPotentialCallable && (highlighted += colorize(defs, getTokenType(lastPotentialCallable), lastPotentialCallable.value) + stackedHighlight, stackedHighlight = ""), lastPotentialCallable = token; + continue; + } + if (lastPotentialCallable && (token.type === "WhiteSpace" || token.type === "LineTerminatorSequence" || token.type === "Punctuator" && (token.value === "?." || token.value === "!"))) { + stackedHighlight += colorize(defs, type, token.value); + continue; + } + if (stackedHighlight && !lastPotentialCallable && (highlighted += stackedHighlight, stackedHighlight = ""), lastPotentialCallable) { + let type2 = token.type === "Punctuator" && token.value === "(" ? getCallableType(lastPotentialCallable) : getTokenType(lastPotentialCallable); + highlighted += colorize(defs, type2, lastPotentialCallable.value) + stackedHighlight, stackedHighlight = "", lastPotentialCallable = null; + } + highlighted += colorize(defs, type, token.value); + } + return highlighted; +}; +function highlight$1(code, options = { jsx: false, colors: {} }) { + return code && highlightTokens(options.colors || {}, code, options.jsx); +} + +function getDefs(c) { + const Invalid = (text) => c.white(c.bgRed(c.bold(text))); + return { + Keyword: c.magenta, + IdentifierCapitalized: c.yellow, + Punctuator: c.yellow, + StringLiteral: c.green, + NoSubstitutionTemplate: c.green, + MultiLineComment: c.gray, + SingleLineComment: c.gray, + RegularExpressionLiteral: c.cyan, + NumericLiteral: c.blue, + TemplateHead: (text) => c.green(text.slice(0, text.length - 2)) + c.cyan(text.slice(-2)), + TemplateTail: (text) => c.cyan(text.slice(0, 1)) + c.green(text.slice(1)), + TemplateMiddle: (text) => c.cyan(text.slice(0, 1)) + c.green(text.slice(1, text.length - 2)) + c.cyan(text.slice(-2)), + IdentifierCallable: c.blue, + PrivateIdentifierCallable: (text) => `#${c.blue(text.slice(1))}`, + Invalid, + JSXString: c.green, + JSXIdentifier: c.yellow, + JSXInvalid: Invalid, + JSXPunctuator: c.yellow + }; +} +function highlight(code, options = { jsx: false }) { + return highlight$1(code, { + jsx: options.jsx, + colors: getDefs(options.colors || c) + }); +} + +// port from nanoid +// https://github.com/ai/nanoid +const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; +function nanoid(size = 21) { + let id = ""; + let i = size; + while (i--) { + id += urlAlphabet[Math.random() * 64 | 0]; + } + return id; +} + +const lineSplitRE = /\r?\n/; +function positionToOffset(source, lineNumber, columnNumber) { + const lines = source.split(lineSplitRE); + const nl = /\r\n/.test(source) ? 2 : 1; + let start = 0; + if (lineNumber > lines.length) { + return source.length; + } + for (let i = 0; i < lineNumber - 1; i++) { + start += lines[i].length + nl; + } + return start + columnNumber; +} +function offsetToLineNumber(source, offset) { + if (offset > source.length) { + throw new Error(`offset is longer than source length! offset ${offset} > length ${source.length}`); + } + const lines = source.split(lineSplitRE); + const nl = /\r\n/.test(source) ? 2 : 1; + let counted = 0; + let line = 0; + for (; line < lines.length; line++) { + const lineLength = lines[line].length + nl; + if (counted + lineLength >= offset) { + break; + } + counted += lineLength; + } + return line + 1; +} + +const RealDate = Date; +function random(seed) { + const x = Math.sin(seed++) * 1e4; + return x - Math.floor(x); +} +function shuffle(array, seed = RealDate.now()) { + let length = array.length; + while (length) { + const index = Math.floor(random(seed) * length--); + const previous = array[length]; + array[length] = array[index]; + array[index] = previous; + ++seed; + } + return array; +} + +const SAFE_TIMERS_SYMBOL = Symbol("vitest:SAFE_TIMERS"); +function getSafeTimers() { + const { setTimeout: safeSetTimeout, setInterval: safeSetInterval, clearInterval: safeClearInterval, clearTimeout: safeClearTimeout, setImmediate: safeSetImmediate, clearImmediate: safeClearImmediate, queueMicrotask: safeQueueMicrotask } = globalThis[SAFE_TIMERS_SYMBOL] || globalThis; + const { nextTick: safeNextTick } = globalThis[SAFE_TIMERS_SYMBOL] || globalThis.process || { nextTick: (cb) => cb() }; + return { + nextTick: safeNextTick, + setTimeout: safeSetTimeout, + setInterval: safeSetInterval, + clearInterval: safeClearInterval, + clearTimeout: safeClearTimeout, + setImmediate: safeSetImmediate, + clearImmediate: safeClearImmediate, + queueMicrotask: safeQueueMicrotask + }; +} +function setSafeTimers() { + const { setTimeout: safeSetTimeout, setInterval: safeSetInterval, clearInterval: safeClearInterval, clearTimeout: safeClearTimeout, setImmediate: safeSetImmediate, clearImmediate: safeClearImmediate, queueMicrotask: safeQueueMicrotask } = globalThis; + const { nextTick: safeNextTick } = globalThis.process || { nextTick: (cb) => cb() }; + const timers = { + nextTick: safeNextTick, + setTimeout: safeSetTimeout, + setInterval: safeSetInterval, + clearInterval: safeClearInterval, + clearTimeout: safeClearTimeout, + setImmediate: safeSetImmediate, + clearImmediate: safeClearImmediate, + queueMicrotask: safeQueueMicrotask + }; + globalThis[SAFE_TIMERS_SYMBOL] = timers; +} + +export { getSafeTimers, highlight, lineSplitRE, nanoid, offsetToLineNumber, positionToOffset, setSafeTimers, shuffle }; diff --git a/node_modules/@vitest/utils/dist/source-map.d.ts b/node_modules/@vitest/utils/dist/source-map.d.ts new file mode 100644 index 0000000000..0dbf924aa9 --- /dev/null +++ b/node_modules/@vitest/utils/dist/source-map.d.ts @@ -0,0 +1,139 @@ +import { ErrorWithDiff, ParsedStack } from './types.js'; + +type GeneratedColumn = number; +type SourcesIndex = number; +type SourceLine = number; +type SourceColumn = number; +type NamesIndex = number; +type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex]; + +interface SourceMapV3 { + file?: string | null; + names: string[]; + sourceRoot?: string; + sources: (string | null)[]; + sourcesContent?: (string | null)[]; + version: 3; + ignoreList?: number[]; +} +interface EncodedSourceMap extends SourceMapV3 { + mappings: string; +} +interface DecodedSourceMap extends SourceMapV3 { + mappings: SourceMapSegment[][]; +} +type OriginalMapping = { + source: string | null; + line: number; + column: number; + name: string | null; +}; +type InvalidOriginalMapping = { + source: null; + line: null; + column: null; + name: null; +}; +type GeneratedMapping = { + line: number; + column: number; +}; +type InvalidGeneratedMapping = { + line: null; + column: null; +}; +type Bias = typeof GREATEST_LOWER_BOUND | typeof LEAST_UPPER_BOUND; +type XInput = { + x_google_ignoreList?: SourceMapV3['ignoreList']; +}; +type EncodedSourceMapXInput = EncodedSourceMap & XInput; +type DecodedSourceMapXInput = DecodedSourceMap & XInput; +type SourceMapInput = string | EncodedSourceMapXInput | DecodedSourceMapXInput | TraceMap; +type Needle = { + line: number; + column: number; + bias?: Bias; +}; +type SourceNeedle = { + source: string; + line: number; + column: number; + bias?: Bias; +}; +type EachMapping = { + generatedLine: number; + generatedColumn: number; + source: null; + originalLine: null; + originalColumn: null; + name: null; +} | { + generatedLine: number; + generatedColumn: number; + source: string | null; + originalLine: number; + originalColumn: number; + name: string | null; +}; +declare abstract class SourceMap { + version: SourceMapV3['version']; + file: SourceMapV3['file']; + names: SourceMapV3['names']; + sourceRoot: SourceMapV3['sourceRoot']; + sources: SourceMapV3['sources']; + sourcesContent: SourceMapV3['sourcesContent']; + resolvedSources: SourceMapV3['sources']; + ignoreList: SourceMapV3['ignoreList']; +} + +declare const LEAST_UPPER_BOUND = -1; +declare const GREATEST_LOWER_BOUND = 1; + +declare class TraceMap implements SourceMap { + version: SourceMapV3['version']; + file: SourceMapV3['file']; + names: SourceMapV3['names']; + sourceRoot: SourceMapV3['sourceRoot']; + sources: SourceMapV3['sources']; + sourcesContent: SourceMapV3['sourcesContent']; + ignoreList: SourceMapV3['ignoreList']; + resolvedSources: string[]; + private _encoded; + private _decoded; + private _decodedMemo; + private _bySources; + private _bySourceMemos; + constructor(map: SourceMapInput, mapUrl?: string | null); +} +/** + * A higher-level API to find the source/line/column associated with a generated line/column + * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in + * `source-map` library. + */ +declare function originalPositionFor(map: TraceMap, needle: Needle): OriginalMapping | InvalidOriginalMapping; +/** + * Finds the generated line/column position of the provided source/line/column source position. + */ +declare function generatedPositionFor(map: TraceMap, needle: SourceNeedle): GeneratedMapping | InvalidGeneratedMapping; +/** + * Iterates each mapping in generated position order. + */ +declare function eachMapping(map: TraceMap, cb: (mapping: EachMapping) => void): void; + +interface StackTraceParserOptions { + ignoreStackEntries?: (RegExp | string)[]; + getSourceMap?: (file: string) => unknown; + getUrlId?: (id: string) => string; + frameFilter?: (error: ErrorWithDiff, frame: ParsedStack) => boolean | void; +} +declare function parseSingleFFOrSafariStack(raw: string): ParsedStack | null; +declare function parseSingleStack(raw: string): ParsedStack | null; +// Based on https://github.com/stacktracejs/error-stack-parser +// Credit to stacktracejs +declare function parseSingleV8Stack(raw: string): ParsedStack | null; +declare function createStackString(stacks: ParsedStack[]): string; +declare function parseStacktrace(stack: string, options?: StackTraceParserOptions): ParsedStack[]; +declare function parseErrorStacktrace(e: ErrorWithDiff, options?: StackTraceParserOptions): ParsedStack[]; + +export { TraceMap, createStackString, eachMapping, generatedPositionFor, originalPositionFor, parseErrorStacktrace, parseSingleFFOrSafariStack, parseSingleStack, parseSingleV8Stack, parseStacktrace }; +export type { EachMapping, SourceMapInput, StackTraceParserOptions }; diff --git a/node_modules/@vitest/utils/dist/source-map.js b/node_modules/@vitest/utils/dist/source-map.js new file mode 100644 index 0000000000..7352dbfca8 --- /dev/null +++ b/node_modules/@vitest/utils/dist/source-map.js @@ -0,0 +1,996 @@ +import { isPrimitive, notNullish } from './helpers.js'; + +const comma = ','.charCodeAt(0); +const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +const intToChar = new Uint8Array(64); // 64 possible chars. +const charToInt = new Uint8Array(128); // z is 122 in ASCII +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decodeInteger(reader, relative) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -2147483648 | -value; + } + return relative + value; +} +function hasMoreVlq(reader, max) { + if (reader.pos >= max) + return false; + return reader.peek() !== comma; +} +class StringReader { + constructor(buffer) { + this.pos = 0; + this.buffer = buffer; + } + next() { + return this.buffer.charCodeAt(this.pos++); + } + peek() { + return this.buffer.charCodeAt(this.pos); + } + indexOf(char) { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +} + +function decode(mappings) { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + do { + const semi = reader.indexOf(';'); + const line = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + while (reader.pos < semi) { + let seg; + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) + sorted = false; + lastCol = genColumn; + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } + else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } + else { + seg = [genColumn]; + } + line.push(seg); + reader.pos++; + } + if (!sorted) + sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + return decoded; +} +function sort(line) { + line.sort(sortComparator$1); +} +function sortComparator$1(a, b) { + return a[0] - b[0]; +} + +// Matches the scheme of a URL, eg "http://" +const schemeRegex = /^[\w+.-]+:\/\//; +/** + * Matches the parts of a URL: + * 1. Scheme, including ":", guaranteed. + * 2. User/password, including "@", optional. + * 3. Host, guaranteed. + * 4. Port, including ":", optional. + * 5. Path, including "/", optional. + * 6. Query, including "?", optional. + * 7. Hash, including "#", optional. + */ +const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/; +/** + * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start + * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive). + * + * 1. Host, optional. + * 2. Path, which may include "/", guaranteed. + * 3. Query, including "?", optional. + * 4. Hash, including "#", optional. + */ +const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i; +var UrlType; +(function (UrlType) { + UrlType[UrlType["Empty"] = 1] = "Empty"; + UrlType[UrlType["Hash"] = 2] = "Hash"; + UrlType[UrlType["Query"] = 3] = "Query"; + UrlType[UrlType["RelativePath"] = 4] = "RelativePath"; + UrlType[UrlType["AbsolutePath"] = 5] = "AbsolutePath"; + UrlType[UrlType["SchemeRelative"] = 6] = "SchemeRelative"; + UrlType[UrlType["Absolute"] = 7] = "Absolute"; +})(UrlType || (UrlType = {})); +function isAbsoluteUrl(input) { + return schemeRegex.test(input); +} +function isSchemeRelativeUrl(input) { + return input.startsWith('//'); +} +function isAbsolutePath(input) { + return input.startsWith('/'); +} +function isFileUrl(input) { + return input.startsWith('file:'); +} +function isRelative(input) { + return /^[.?#]/.test(input); +} +function parseAbsoluteUrl(input) { + const match = urlRegex.exec(input); + return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || ''); +} +function parseFileUrl(input) { + const match = fileRegex.exec(input); + const path = match[2]; + return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || ''); +} +function makeUrl(scheme, user, host, port, path, query, hash) { + return { + scheme, + user, + host, + port, + path, + query, + hash, + type: UrlType.Absolute, + }; +} +function parseUrl(input) { + if (isSchemeRelativeUrl(input)) { + const url = parseAbsoluteUrl('http:' + input); + url.scheme = ''; + url.type = UrlType.SchemeRelative; + return url; + } + if (isAbsolutePath(input)) { + const url = parseAbsoluteUrl('http://foo.com' + input); + url.scheme = ''; + url.host = ''; + url.type = UrlType.AbsolutePath; + return url; + } + if (isFileUrl(input)) + return parseFileUrl(input); + if (isAbsoluteUrl(input)) + return parseAbsoluteUrl(input); + const url = parseAbsoluteUrl('http://foo.com/' + input); + url.scheme = ''; + url.host = ''; + url.type = input + ? input.startsWith('?') + ? UrlType.Query + : input.startsWith('#') + ? UrlType.Hash + : UrlType.RelativePath + : UrlType.Empty; + return url; +} +function stripPathFilename(path) { + // If a path ends with a parent directory "..", then it's a relative path with excess parent + // paths. It's not a file, so we can't strip it. + if (path.endsWith('/..')) + return path; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} +function mergePaths(url, base) { + normalizePath(base, base.type); + // If the path is just a "/", then it was an empty path to begin with (remember, we're a relative + // path). + if (url.path === '/') { + url.path = base.path; + } + else { + // Resolution happens relative to the base path's directory, not the file. + url.path = stripPathFilename(base.path) + url.path; + } +} +/** + * The path can have empty directories "//", unneeded parents "foo/..", or current directory + * "foo/.". We need to normalize to a standard representation. + */ +function normalizePath(url, type) { + const rel = type <= UrlType.RelativePath; + const pieces = url.path.split('/'); + // We need to preserve the first piece always, so that we output a leading slash. The item at + // pieces[0] is an empty string. + let pointer = 1; + // Positive is the number of real directories we've output, used for popping a parent directory. + // Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo". + let positive = 0; + // We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will + // generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a + // real directory, we won't need to append, unless the other conditions happen again. + let addTrailingSlash = false; + for (let i = 1; i < pieces.length; i++) { + const piece = pieces[i]; + // An empty directory, could be a trailing slash, or just a double "//" in the path. + if (!piece) { + addTrailingSlash = true; + continue; + } + // If we encounter a real directory, then we don't need to append anymore. + addTrailingSlash = false; + // A current directory, which we can always drop. + if (piece === '.') + continue; + // A parent directory, we need to see if there are any real directories we can pop. Else, we + // have an excess of parents, and we'll need to keep the "..". + if (piece === '..') { + if (positive) { + addTrailingSlash = true; + positive--; + pointer--; + } + else if (rel) { + // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute + // URL, protocol relative URL, or an absolute path, we don't need to keep excess. + pieces[pointer++] = piece; + } + continue; + } + // We've encountered a real directory. Move it to the next insertion pointer, which accounts for + // any popped or dropped directories. + pieces[pointer++] = piece; + positive++; + } + let path = ''; + for (let i = 1; i < pointer; i++) { + path += '/' + pieces[i]; + } + if (!path || (addTrailingSlash && !path.endsWith('/..'))) { + path += '/'; + } + url.path = path; +} +/** + * Attempts to resolve `input` URL/path relative to `base`. + */ +function resolve$2(input, base) { + if (!input && !base) + return ''; + const url = parseUrl(input); + let inputType = url.type; + if (base && inputType !== UrlType.Absolute) { + const baseUrl = parseUrl(base); + const baseType = baseUrl.type; + switch (inputType) { + case UrlType.Empty: + url.hash = baseUrl.hash; + // fall through + case UrlType.Hash: + url.query = baseUrl.query; + // fall through + case UrlType.Query: + case UrlType.RelativePath: + mergePaths(url, baseUrl); + // fall through + case UrlType.AbsolutePath: + // The host, user, and port are joined, you can't copy one without the others. + url.user = baseUrl.user; + url.host = baseUrl.host; + url.port = baseUrl.port; + // fall through + case UrlType.SchemeRelative: + // The input doesn't have a schema at least, so we need to copy at least that over. + url.scheme = baseUrl.scheme; + } + if (baseType > inputType) + inputType = baseType; + } + normalizePath(url, inputType); + const queryHash = url.query + url.hash; + switch (inputType) { + // This is impossible, because of the empty checks at the start of the function. + // case UrlType.Empty: + case UrlType.Hash: + case UrlType.Query: + return queryHash; + case UrlType.RelativePath: { + // The first char is always a "/", and we need it to be relative. + const path = url.path.slice(1); + if (!path) + return queryHash || '.'; + if (isRelative(base || input) && !isRelative(path)) { + // If base started with a leading ".", or there is no base and input started with a ".", + // then we need to ensure that the relative path starts with a ".". We don't know if + // relative starts with a "..", though, so check before prepending. + return './' + path + queryHash; + } + return path + queryHash; + } + case UrlType.AbsolutePath: + return url.path + queryHash; + default: + return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash; + } +} + +function resolve$1(input, base) { + // The base is always treated as a directory, if it's not empty. + // https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327 + // https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401 + if (base && !base.endsWith('/')) + base += '/'; + return resolve$2(input, base); +} + +/** + * Removes everything after the last "/", but leaves the slash. + */ +function stripFilename(path) { + if (!path) + return ''; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} + +const COLUMN = 0; +const SOURCES_INDEX = 1; +const SOURCE_LINE = 2; +const SOURCE_COLUMN = 3; +const NAMES_INDEX = 4; +const REV_GENERATED_LINE = 1; +const REV_GENERATED_COLUMN = 2; + +function maybeSort(mappings, owned) { + const unsortedIndex = nextUnsortedSegmentLine(mappings, 0); + if (unsortedIndex === mappings.length) + return mappings; + // If we own the array (meaning we parsed it from JSON), then we're free to directly mutate it. If + // not, we do not want to modify the consumer's input array. + if (!owned) + mappings = mappings.slice(); + for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) { + mappings[i] = sortSegments(mappings[i], owned); + } + return mappings; +} +function nextUnsortedSegmentLine(mappings, start) { + for (let i = start; i < mappings.length; i++) { + if (!isSorted(mappings[i])) + return i; + } + return mappings.length; +} +function isSorted(line) { + for (let j = 1; j < line.length; j++) { + if (line[j][COLUMN] < line[j - 1][COLUMN]) { + return false; + } + } + return true; +} +function sortSegments(line, owned) { + if (!owned) + line = line.slice(); + return line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[COLUMN] - b[COLUMN]; +} + +let found = false; +/** + * A binary search implementation that returns the index if a match is found. + * If no match is found, then the left-index (the index associated with the item that comes just + * before the desired index) is returned. To maintain proper sort order, a splice would happen at + * the next index: + * + * ```js + * const array = [1, 3]; + * const needle = 2; + * const index = binarySearch(array, needle, (item, needle) => item - needle); + * + * assert.equal(index, 0); + * array.splice(index + 1, 0, needle); + * assert.deepEqual(array, [1, 2, 3]); + * ``` + */ +function binarySearch(haystack, needle, low, high) { + while (low <= high) { + const mid = low + ((high - low) >> 1); + const cmp = haystack[mid][COLUMN] - needle; + if (cmp === 0) { + found = true; + return mid; + } + if (cmp < 0) { + low = mid + 1; + } + else { + high = mid - 1; + } + } + found = false; + return low - 1; +} +function upperBound(haystack, needle, index) { + for (let i = index + 1; i < haystack.length; index = i++) { + if (haystack[i][COLUMN] !== needle) + break; + } + return index; +} +function lowerBound(haystack, needle, index) { + for (let i = index - 1; i >= 0; index = i--) { + if (haystack[i][COLUMN] !== needle) + break; + } + return index; +} +function memoizedState() { + return { + lastKey: -1, + lastNeedle: -1, + lastIndex: -1, + }; +} +/** + * This overly complicated beast is just to record the last tested line/column and the resulting + * index, allowing us to skip a few tests if mappings are monotonically increasing. + */ +function memoizedBinarySearch(haystack, needle, state, key) { + const { lastKey, lastNeedle, lastIndex } = state; + let low = 0; + let high = haystack.length - 1; + if (key === lastKey) { + if (needle === lastNeedle) { + found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; + return lastIndex; + } + if (needle >= lastNeedle) { + // lastIndex may be -1 if the previous needle was not found. + low = lastIndex === -1 ? 0 : lastIndex; + } + else { + high = lastIndex; + } + } + state.lastKey = key; + state.lastNeedle = needle; + return (state.lastIndex = binarySearch(haystack, needle, low, high)); +} + +// Rebuilds the original source files, with mappings that are ordered by source line/column instead +// of generated line/column. +function buildBySources(decoded, memos) { + const sources = memos.map(buildNullArray); + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + if (seg.length === 1) + continue; + const sourceIndex = seg[SOURCES_INDEX]; + const sourceLine = seg[SOURCE_LINE]; + const sourceColumn = seg[SOURCE_COLUMN]; + const originalSource = sources[sourceIndex]; + const originalLine = (originalSource[sourceLine] || (originalSource[sourceLine] = [])); + const memo = memos[sourceIndex]; + // The binary search either found a match, or it found the left-index just before where the + // segment should go. Either way, we want to insert after that. And there may be multiple + // generated segments associated with an original location, so there may need to move several + // indexes before we find where we need to insert. + let index = upperBound(originalLine, sourceColumn, memoizedBinarySearch(originalLine, sourceColumn, memo, sourceLine)); + memo.lastIndex = ++index; + insert(originalLine, index, [sourceColumn, i, seg[COLUMN]]); + } + } + return sources; +} +function insert(array, index, value) { + for (let i = array.length; i > index; i--) { + array[i] = array[i - 1]; + } + array[index] = value; +} +// Null arrays allow us to use ordered index keys without actually allocating contiguous memory like +// a real array. We use a null-prototype object to avoid prototype pollution and deoptimizations. +// Numeric properties on objects are magically sorted in ascending order by the engine regardless of +// the insertion order. So, by setting any numeric keys, even out of order, we'll get ascending +// order when iterating with for-in. +function buildNullArray() { + return { __proto__: null }; +} + +const LINE_GTR_ZERO = '`line` must be greater than 0 (lines start at line 1)'; +const COL_GTR_EQ_ZERO = '`column` must be greater than or equal to 0 (columns start at column 0)'; +const LEAST_UPPER_BOUND = -1; +const GREATEST_LOWER_BOUND = 1; +class TraceMap { + constructor(map, mapUrl) { + const isString = typeof map === 'string'; + if (!isString && map._decodedMemo) + return map; + const parsed = (isString ? JSON.parse(map) : map); + const { version, file, names, sourceRoot, sources, sourcesContent } = parsed; + this.version = version; + this.file = file; + this.names = names || []; + this.sourceRoot = sourceRoot; + this.sources = sources; + this.sourcesContent = sourcesContent; + this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || undefined; + const from = resolve$1(sourceRoot || '', stripFilename(mapUrl)); + this.resolvedSources = sources.map((s) => resolve$1(s || '', from)); + const { mappings } = parsed; + if (typeof mappings === 'string') { + this._encoded = mappings; + this._decoded = undefined; + } + else { + this._encoded = undefined; + this._decoded = maybeSort(mappings, isString); + } + this._decodedMemo = memoizedState(); + this._bySources = undefined; + this._bySourceMemos = undefined; + } +} +/** + * Typescript doesn't allow friend access to private fields, so this just casts the map into a type + * with public access modifiers. + */ +function cast(map) { + return map; +} +/** + * Returns the decoded (array of lines of segments) form of the SourceMap's mappings field. + */ +function decodedMappings(map) { + var _a; + return ((_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded))); +} +/** + * A higher-level API to find the source/line/column associated with a generated line/column + * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in + * `source-map` library. + */ +function originalPositionFor(map, needle) { + let { line, column, bias } = needle; + line--; + if (line < 0) + throw new Error(LINE_GTR_ZERO); + if (column < 0) + throw new Error(COL_GTR_EQ_ZERO); + const decoded = decodedMappings(map); + // It's common for parent source maps to have pointers to lines that have no + // mapping (like a "//# sourceMappingURL=") at the end of the child file. + if (line >= decoded.length) + return OMapping(null, null, null, null); + const segments = decoded[line]; + const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND); + if (index === -1) + return OMapping(null, null, null, null); + const segment = segments[index]; + if (segment.length === 1) + return OMapping(null, null, null, null); + const { names, resolvedSources } = map; + return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null); +} +/** + * Finds the generated line/column position of the provided source/line/column source position. + */ +function generatedPositionFor(map, needle) { + const { source, line, column, bias } = needle; + return generatedPosition(map, source, line, column, bias || GREATEST_LOWER_BOUND, false); +} +/** + * Iterates each mapping in generated position order. + */ +function eachMapping(map, cb) { + const decoded = decodedMappings(map); + const { names, resolvedSources } = map; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + const generatedLine = i + 1; + const generatedColumn = seg[0]; + let source = null; + let originalLine = null; + let originalColumn = null; + let name = null; + if (seg.length !== 1) { + source = resolvedSources[seg[1]]; + originalLine = seg[2] + 1; + originalColumn = seg[3]; + } + if (seg.length === 5) + name = names[seg[4]]; + cb({ + generatedLine, + generatedColumn, + source, + originalLine, + originalColumn, + name, + }); + } + } +} +function OMapping(source, line, column, name) { + return { source, line, column, name }; +} +function GMapping(line, column) { + return { line, column }; +} +function traceSegmentInternal(segments, memo, line, column, bias) { + let index = memoizedBinarySearch(segments, column, memo, line); + if (found) { + index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index); + } + else if (bias === LEAST_UPPER_BOUND) + index++; + if (index === -1 || index === segments.length) + return -1; + return index; +} +function generatedPosition(map, source, line, column, bias, all) { + var _a; + line--; + if (line < 0) + throw new Error(LINE_GTR_ZERO); + if (column < 0) + throw new Error(COL_GTR_EQ_ZERO); + const { sources, resolvedSources } = map; + let sourceIndex = sources.indexOf(source); + if (sourceIndex === -1) + sourceIndex = resolvedSources.indexOf(source); + if (sourceIndex === -1) + return all ? [] : GMapping(null, null); + const generated = ((_a = cast(map))._bySources || (_a._bySources = buildBySources(decodedMappings(map), (cast(map)._bySourceMemos = sources.map(memoizedState))))); + const segments = generated[sourceIndex][line]; + if (segments == null) + return all ? [] : GMapping(null, null); + const memo = cast(map)._bySourceMemos[sourceIndex]; + const index = traceSegmentInternal(segments, memo, line, column, bias); + if (index === -1) + return GMapping(null, null); + const segment = segments[index]; + return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]); +} + +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; + +const CHROME_IE_STACK_REGEXP = /^\s*at .*(?:\S:\d+|\(native\))/m; +const SAFARI_NATIVE_CODE_REGEXP = /^(?:eval@)?(?:\[native code\])?$/; +const stackIgnorePatterns = [ + "node:internal", + /\/packages\/\w+\/dist\//, + /\/@vitest\/\w+\/dist\//, + "/vitest/dist/", + "/vitest/src/", + "/vite-node/dist/", + "/vite-node/src/", + "/node_modules/chai/", + "/node_modules/tinypool/", + "/node_modules/tinyspy/", + "/deps/chunk-", + "/deps/@vitest", + "/deps/loupe", + "/deps/chai", + /node:\w+/, + /__vitest_test__/, + /__vitest_browser__/, + /\/deps\/vitest_/ +]; +function extractLocation(urlLike) { + // Fail-fast but return locations like "(native)" + if (!urlLike.includes(":")) { + return [urlLike]; + } + const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/; + const parts = regExp.exec(urlLike.replace(/^\(|\)$/g, "")); + if (!parts) { + return [urlLike]; + } + let url = parts[1]; + if (url.startsWith("async ")) { + url = url.slice(6); + } + if (url.startsWith("http:") || url.startsWith("https:")) { + const urlObj = new URL(url); + urlObj.searchParams.delete("import"); + urlObj.searchParams.delete("browserv"); + url = urlObj.pathname + urlObj.hash + urlObj.search; + } + if (url.startsWith("/@fs/")) { + const isWindows = /^\/@fs\/[a-zA-Z]:\//.test(url); + url = url.slice(isWindows ? 5 : 4); + } + return [ + url, + parts[2] || undefined, + parts[3] || undefined + ]; +} +function parseSingleFFOrSafariStack(raw) { + let line = raw.trim(); + if (SAFARI_NATIVE_CODE_REGEXP.test(line)) { + return null; + } + if (line.includes(" > eval")) { + line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1"); + } + if (!line.includes("@") && !line.includes(":")) { + return null; + } + // eslint-disable-next-line regexp/no-super-linear-backtracking, regexp/optimal-quantifier-concatenation + const functionNameRegex = /((.*".+"[^@]*)?[^@]*)(@)/; + const matches = line.match(functionNameRegex); + const functionName = matches && matches[1] ? matches[1] : undefined; + const [url, lineNumber, columnNumber] = extractLocation(line.replace(functionNameRegex, "")); + if (!url || !lineNumber || !columnNumber) { + return null; + } + return { + file: url, + method: functionName || "", + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} +function parseSingleStack(raw) { + const line = raw.trim(); + if (!CHROME_IE_STACK_REGEXP.test(line)) { + return parseSingleFFOrSafariStack(line); + } + return parseSingleV8Stack(line); +} +// Based on https://github.com/stacktracejs/error-stack-parser +// Credit to stacktracejs +function parseSingleV8Stack(raw) { + let line = raw.trim(); + if (!CHROME_IE_STACK_REGEXP.test(line)) { + return null; + } + if (line.includes("(eval ")) { + line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, ""); + } + let sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, ""); + // capture and preserve the parenthesized location "(/foo/my bar.js:12:87)" in + // case it has spaces in it, as the string is split on \s+ later on + const location = sanitizedLine.match(/ (\(.+\)$)/); + // remove the parenthesized location from the line, if it was matched + sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine; + // if a location was matched, pass it to extractLocation() otherwise pass all sanitizedLine + // because this line doesn't have function name + const [url, lineNumber, columnNumber] = extractLocation(location ? location[1] : sanitizedLine); + let method = location && sanitizedLine || ""; + let file = url && ["eval", ""].includes(url) ? undefined : url; + if (!file || !lineNumber || !columnNumber) { + return null; + } + if (method.startsWith("async ")) { + method = method.slice(6); + } + if (file.startsWith("file://")) { + file = file.slice(7); + } + // normalize Windows path (\ -> /) + file = file.startsWith("node:") || file.startsWith("internal:") ? file : resolve(file); + if (method) { + method = method.replace(/__vite_ssr_import_\d+__\./g, ""); + } + return { + method, + file, + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} +function createStackString(stacks) { + return stacks.map((stack) => { + const line = `${stack.file}:${stack.line}:${stack.column}`; + if (stack.method) { + return ` at ${stack.method}(${line})`; + } + return ` at ${line}`; + }).join("\n"); +} +function parseStacktrace(stack, options = {}) { + const { ignoreStackEntries = stackIgnorePatterns } = options; + const stacks = !CHROME_IE_STACK_REGEXP.test(stack) ? parseFFOrSafariStackTrace(stack) : parseV8Stacktrace(stack); + return stacks.map((stack) => { + var _options$getSourceMap; + if (options.getUrlId) { + stack.file = options.getUrlId(stack.file); + } + const map = (_options$getSourceMap = options.getSourceMap) === null || _options$getSourceMap === void 0 ? void 0 : _options$getSourceMap.call(options, stack.file); + if (!map || typeof map !== "object" || !map.version) { + return shouldFilter(ignoreStackEntries, stack.file) ? null : stack; + } + const traceMap = new TraceMap(map); + const { line, column, source, name } = originalPositionFor(traceMap, stack); + let file = stack.file; + if (source) { + const fileUrl = stack.file.startsWith("file://") ? stack.file : `file://${stack.file}`; + const sourceRootUrl = map.sourceRoot ? new URL(map.sourceRoot, fileUrl) : fileUrl; + file = new URL(source, sourceRootUrl).pathname; + // if the file path is on windows, we need to remove the leading slash + if (file.match(/\/\w:\//)) { + file = file.slice(1); + } + } + if (shouldFilter(ignoreStackEntries, file)) { + return null; + } + if (line != null && column != null) { + return { + line, + column, + file, + method: name || stack.method + }; + } + return stack; + }).filter((s) => s != null); +} +function shouldFilter(ignoreStackEntries, file) { + return ignoreStackEntries.some((p) => file.match(p)); +} +function parseFFOrSafariStackTrace(stack) { + return stack.split("\n").map((line) => parseSingleFFOrSafariStack(line)).filter(notNullish); +} +function parseV8Stacktrace(stack) { + return stack.split("\n").map((line) => parseSingleV8Stack(line)).filter(notNullish); +} +function parseErrorStacktrace(e, options = {}) { + if (!e || isPrimitive(e)) { + return []; + } + if (e.stacks) { + return e.stacks; + } + const stackStr = e.stack || ""; + // if "stack" property was overwritten at runtime to be something else, + // ignore the value because we don't know how to process it + let stackFrames = typeof stackStr === "string" ? parseStacktrace(stackStr, options) : []; + if (!stackFrames.length) { + const e_ = e; + if (e_.fileName != null && e_.lineNumber != null && e_.columnNumber != null) { + stackFrames = parseStacktrace(`${e_.fileName}:${e_.lineNumber}:${e_.columnNumber}`, options); + } + if (e_.sourceURL != null && e_.line != null && e_._column != null) { + stackFrames = parseStacktrace(`${e_.sourceURL}:${e_.line}:${e_.column}`, options); + } + } + if (options.frameFilter) { + stackFrames = stackFrames.filter((f) => options.frameFilter(e, f) !== false); + } + e.stacks = stackFrames; + return stackFrames; +} + +export { TraceMap, createStackString, eachMapping, generatedPositionFor, originalPositionFor, parseErrorStacktrace, parseSingleFFOrSafariStack, parseSingleStack, parseSingleV8Stack, parseStacktrace }; diff --git a/node_modules/@vitest/utils/dist/types.d-BCElaP-c.d.ts b/node_modules/@vitest/utils/dist/types.d-BCElaP-c.d.ts new file mode 100644 index 0000000000..cba06c6c34 --- /dev/null +++ b/node_modules/@vitest/utils/dist/types.d-BCElaP-c.d.ts @@ -0,0 +1,53 @@ +import { CompareKeys } from '@vitest/pretty-format'; + +/** +* Copyright (c) Meta Platforms, Inc. and affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + +type DiffOptionsColor = (arg: string) => string; +interface DiffOptions { + aAnnotation?: string; + aColor?: DiffOptionsColor; + aIndicator?: string; + bAnnotation?: string; + bColor?: DiffOptionsColor; + bIndicator?: string; + changeColor?: DiffOptionsColor; + changeLineTrailingSpaceColor?: DiffOptionsColor; + commonColor?: DiffOptionsColor; + commonIndicator?: string; + commonLineTrailingSpaceColor?: DiffOptionsColor; + contextLines?: number; + emptyFirstOrLastLinePlaceholder?: string; + expand?: boolean; + includeChangeCounts?: boolean; + omitAnnotationLines?: boolean; + patchColor?: DiffOptionsColor; + printBasicPrototype?: boolean; + maxDepth?: number; + compareKeys?: CompareKeys; + truncateThreshold?: number; + truncateAnnotation?: string; + truncateAnnotationColor?: DiffOptionsColor; +} +interface SerializedDiffOptions { + aAnnotation?: string; + aIndicator?: string; + bAnnotation?: string; + bIndicator?: string; + commonIndicator?: string; + contextLines?: number; + emptyFirstOrLastLinePlaceholder?: string; + expand?: boolean; + includeChangeCounts?: boolean; + omitAnnotationLines?: boolean; + printBasicPrototype?: boolean; + maxDepth?: number; + truncateThreshold?: number; + truncateAnnotation?: string; +} + +export type { DiffOptions as D, SerializedDiffOptions as S, DiffOptionsColor as a }; diff --git a/node_modules/@vitest/utils/dist/types.d.ts b/node_modules/@vitest/utils/dist/types.d.ts new file mode 100644 index 0000000000..c341e7a8de --- /dev/null +++ b/node_modules/@vitest/utils/dist/types.d.ts @@ -0,0 +1,53 @@ +type Awaitable = T | PromiseLike; +type Nullable = T | null | undefined; +type Arrayable = T | Array; +type ArgumentsType = T extends (...args: infer U) => any ? U : never; +type MergeInsertions = T extends object ? { [K in keyof T] : MergeInsertions } : T; +type DeepMerge< + F, + S +> = MergeInsertions<{ [K in keyof F | keyof S] : K extends keyof S & keyof F ? DeepMerge : K extends keyof S ? S[K] : K extends keyof F ? F[K] : never }>; +type MutableArray = { -readonly [k in keyof T] : T[k] }; +interface Constructable { + new (...args: any[]): any; +} +interface ParsedStack { + method: string; + file: string; + line: number; + column: number; +} +interface SerializedError { + message: string; + stack?: string; + name?: string; + stacks?: ParsedStack[]; + cause?: SerializedError; + [key: string]: unknown; +} +interface TestError extends SerializedError { + cause?: TestError; + diff?: string; + actual?: string; + expected?: string; +} +/** +* @deprecated Use `TestError` instead +*/ +interface ErrorWithDiff { + message: string; + name?: string; + cause?: unknown; + stack?: string; + stacks?: ParsedStack[]; + showDiff?: boolean; + actual?: any; + expected?: any; + operator?: string; + type?: string; + frame?: string; + diff?: string; + codeFrame?: string; +} + +export type { ArgumentsType, Arrayable, Awaitable, Constructable, DeepMerge, ErrorWithDiff, MergeInsertions, MutableArray, Nullable, ParsedStack, SerializedError, TestError }; diff --git a/node_modules/@vitest/utils/dist/types.js b/node_modules/@vitest/utils/dist/types.js new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/node_modules/@vitest/utils/dist/types.js @@ -0,0 +1 @@ + diff --git a/node_modules/@vitest/utils/error.d.ts b/node_modules/@vitest/utils/error.d.ts new file mode 100644 index 0000000000..9329baa87d --- /dev/null +++ b/node_modules/@vitest/utils/error.d.ts @@ -0,0 +1 @@ +export * from './dist/error.js' diff --git a/node_modules/@vitest/utils/helpers.d.ts b/node_modules/@vitest/utils/helpers.d.ts new file mode 100644 index 0000000000..0add1d0f2b --- /dev/null +++ b/node_modules/@vitest/utils/helpers.d.ts @@ -0,0 +1 @@ +export * from './dist/helpers.js' diff --git a/node_modules/@vitest/utils/package.json b/node_modules/@vitest/utils/package.json new file mode 100644 index 0000000000..a84a2c68e1 --- /dev/null +++ b/node_modules/@vitest/utils/package.json @@ -0,0 +1,77 @@ +{ + "name": "@vitest/utils", + "type": "module", + "version": "3.2.4", + "description": "Shared Vitest utility functions", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/utils#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/utils" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./diff": { + "types": "./dist/diff.d.ts", + "default": "./dist/diff.js" + }, + "./ast": { + "types": "./dist/ast.d.ts", + "default": "./dist/ast.js" + }, + "./error": { + "types": "./dist/error.d.ts", + "default": "./dist/error.js" + }, + "./helpers": { + "types": "./dist/helpers.d.ts", + "default": "./dist/helpers.js" + }, + "./source-map": { + "types": "./dist/source-map.d.ts", + "default": "./dist/source-map.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "typesVersions": { + "*": { + "ast": [ + "dist/ast.d.ts" + ], + "source-map": [ + "dist/source-map.d.ts" + ] + } + }, + "files": [ + "*.d.ts", + "dist" + ], + "dependencies": { + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0", + "@vitest/pretty-format": "3.2.4" + }, + "devDependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "@types/estree": "^1.0.8", + "diff-sequences": "^29.6.3", + "tinyhighlight": "^0.3.2" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/assertion-error/LICENSE b/node_modules/assertion-error/LICENSE new file mode 100644 index 0000000000..5e9f3ac637 --- /dev/null +++ b/node_modules/assertion-error/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013 Jake Luer jake@qualiancy.com (http://qualiancy.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/assertion-error/README.md b/node_modules/assertion-error/README.md new file mode 100644 index 0000000000..37c392879a --- /dev/null +++ b/node_modules/assertion-error/README.md @@ -0,0 +1,68 @@ +

+ AssertionError and AssertionResult classes. +

+ +

+ + build:? + + downloads:? + + devDependencies:none + +

+ +## What is AssertionError? + +Assertion Error is a module that contains two classes: `AssertionError`, which +is an instance of an `Error`, and `AssertionResult` which is not an instance of +Error. + +These can be useful for returning from a function - if the function "succeeds" +return an `AssertionResult` and if the function fails return (or throw) an +`AssertionError`. + +Both `AssertionError` and `AssertionResult` implement the `Result` interface: + +```typescript +interface Result { + name: "AssertionError" | "AssertionResult"; + ok: boolean; + toJSON(...args: unknown[]): Record; +} +``` + +So if a function returns `AssertionResult | AssertionError` it is easy to check +_which_ one is returned by checking either `.name` or `.ok`, or check +`instanceof Error`. + +## Installation + +### Node.js + +`assertion-error` is available on [npm](http://npmjs.org). + +``` +$ npm install --save assertion-error +``` + +### Deno + +`assertion_error` is available on +[Deno.land](https://deno.land/x/assertion_error) + +```typescript +import { + AssertionError, + AssertionResult, +} from "https://deno.land/x/assertion_error@2.0.0/mod.ts"; +``` diff --git a/node_modules/assertion-error/index.d.ts b/node_modules/assertion-error/index.d.ts new file mode 100644 index 0000000000..d8fda2c783 --- /dev/null +++ b/node_modules/assertion-error/index.d.ts @@ -0,0 +1,27 @@ +interface Result { + name: "AssertionError" | "AssertionResult"; + ok: boolean; + toJSON(...args: unknown[]): Record; +} + +declare class AssertionError extends Error implements Result { + [key: string]: unknown + name: "AssertionError"; + ok: false; + message: string; + // deno-lint-ignore ban-types + constructor(message: string, props?: T, ssf?: Function); + stack: string; + toJSON(stack?: boolean): Record; +} + +declare class AssertionResult implements Result { + [key: string]: unknown + name: "AssertionResult"; + ok: true; + message: string; + constructor(props?: T); + toJSON(): Record; +} + +export { AssertionError, AssertionResult, Result }; diff --git a/node_modules/assertion-error/index.js b/node_modules/assertion-error/index.js new file mode 100644 index 0000000000..2bfcb81ed4 --- /dev/null +++ b/node_modules/assertion-error/index.js @@ -0,0 +1,60 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file +// This code was bundled using `deno bundle` and it's not recommended to edit it manually + +const canElideFrames = "captureStackTrace" in Error; +class AssertionError extends Error { + message; + get name() { + return "AssertionError"; + } + get ok() { + return false; + } + constructor(message = "Unspecified AssertionError", props, ssf){ + super(message); + this.message = message; + if (canElideFrames) { + Error.captureStackTrace(this, ssf || AssertionError); + } + for(const key in props){ + if (!(key in this)) { + this[key] = props[key]; + } + } + } + toJSON(stack) { + return { + ...this, + name: this.name, + message: this.message, + ok: false, + stack: stack !== false ? this.stack : undefined + }; + } +} +class AssertionResult { + get name() { + return "AssertionResult"; + } + get ok() { + return true; + } + constructor(props){ + for(const key in props){ + if (!(key in this)) { + this[key] = props[key]; + } + } + } + toJSON() { + return { + ...this, + name: this.name, + ok: this.ok + }; + } +} +export { AssertionError as AssertionError }; +export { AssertionResult as AssertionResult }; + diff --git a/node_modules/assertion-error/package.json b/node_modules/assertion-error/package.json new file mode 100644 index 0000000000..02dc0f5b6b --- /dev/null +++ b/node_modules/assertion-error/package.json @@ -0,0 +1,32 @@ +{ + "name": "assertion-error", + "version": "2.0.1", + "description": "Error constructor for test and validation frameworks that implements standardized AssertionError specification.", + "author": "Jake Luer (http://qualiancy.com)", + "license": "MIT", + "types": "./index.d.ts", + "keywords": [ + "test", + "assertion", + "assertion-error" + ], + "repository": { + "type": "git", + "url": "git@github.com:chaijs/assertion-error.git" + }, + "engines": { + "node": ">=12" + }, + "files": [ + "index.d.ts" + ], + "type": "module", + "module": "index.js", + "main": "index.js", + "scripts": { + "build": "deno bundle mod.ts > index.js", + "pretest": "rm -rf coverage/", + "test": "deno test --coverage=coverage", + "posttest": "deno coverage coverage --lcov > coverage/lcov.info && lcov --summary coverage/lcov.info" + } +} diff --git a/node_modules/cac/LICENSE b/node_modules/cac/LICENSE new file mode 100644 index 0000000000..0fa9bb5114 --- /dev/null +++ b/node_modules/cac/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) EGOIST <0x142857@gmail.com> (https://github.com/egoist) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/cac/README.md b/node_modules/cac/README.md new file mode 100644 index 0000000000..3fd3d16614 --- /dev/null +++ b/node_modules/cac/README.md @@ -0,0 +1,536 @@ +2017-07-26 9 27 05 + +[![NPM version](https://img.shields.io/npm/v/cac.svg?style=flat)](https://npmjs.com/package/cac) [![NPM downloads](https://img.shields.io/npm/dm/cac.svg?style=flat)](https://npmjs.com/package/cac) [![CircleCI](https://circleci.com/gh/cacjs/cac/tree/master.svg?style=shield)](https://circleci.com/gh/cacjs/cac/tree/master) [![Codecov](https://badgen.net/codecov/c/github/cacjs/cac/master)](https://codecov.io/gh/cacjs/cac) [![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000&style=flat)](https://github.com/egoist/donate) [![chat](https://img.shields.io/badge/chat-on%20discord-7289DA.svg?style=flat)](https://chat.egoist.moe) [![install size](https://badgen.net/packagephobia/install/cac)](https://packagephobia.now.sh/result?p=cac) + +## Introduction + +**C**ommand **A**nd **C**onquer is a JavaScript library for building CLI apps. + +## Features + +- **Super light-weight**: No dependency, just a single file. +- **Easy to learn**. There're only 4 APIs you need to learn for building simple CLIs: `cli.option` `cli.version` `cli.help` `cli.parse`. +- **Yet so powerful**. Enable features like default command, git-like subcommands, validation for required arguments and options, variadic arguments, dot-nested options, automated help message generation and so on. +- **Developer friendly**. Written in TypeScript. + +## Table of Contents + + + +- [Install](#install) +- [Usage](#usage) + - [Simple Parsing](#simple-parsing) + - [Display Help Message and Version](#display-help-message-and-version) + - [Command-specific Options](#command-specific-options) + - [Dash in option names](#dash-in-option-names) + - [Brackets](#brackets) + - [Negated Options](#negated-options) + - [Variadic Arguments](#variadic-arguments) + - [Dot-nested Options](#dot-nested-options) + - [Default Command](#default-command) + - [Supply an array as option value](#supply-an-array-as-option-value) + - [Error Handling](#error-handling) + - [With TypeScript](#with-typescript) + - [With Deno](#with-deno) +- [Projects Using CAC](#projects-using-cac) +- [References](#references) + - [CLI Instance](#cli-instance) + - [cac(name?)](#cacname) + - [cli.command(name, description, config?)](#clicommandname-description-config) + - [cli.option(name, description, config?)](#clioptionname-description-config) + - [cli.parse(argv?)](#cliparseargv) + - [cli.version(version, customFlags?)](#cliversionversion-customflags) + - [cli.help(callback?)](#clihelpcallback) + - [cli.outputHelp()](#clioutputhelp) + - [cli.usage(text)](#cliusagetext) + - [Command Instance](#command-instance) + - [command.option()](#commandoption) + - [command.action(callback)](#commandactioncallback) + - [command.alias(name)](#commandaliasname) + - [command.allowUnknownOptions()](#commandallowunknownoptions) + - [command.example(example)](#commandexampleexample) + - [command.usage(text)](#commandusagetext) + - [Events](#events) +- [FAQ](#faq) + - [How is the name written and pronounced?](#how-is-the-name-written-and-pronounced) + - [Why not use Commander.js?](#why-not-use-commanderjs) +- [Project Stats](#project-stats) +- [Contributing](#contributing) +- [Author](#author) + + + +## Install + +```bash +yarn add cac +``` + +## Usage + +### Simple Parsing + +Use CAC as simple argument parser: + +```js +// examples/basic-usage.js +const cli = require('cac')() + +cli.option('--type ', 'Choose a project type', { + default: 'node', +}) + +const parsed = cli.parse() + +console.log(JSON.stringify(parsed, null, 2)) +``` + +2018-11-26 12 28 03 + +### Display Help Message and Version + +```js +// examples/help.js +const cli = require('cac')() + +cli.option('--type [type]', 'Choose a project type', { + default: 'node', +}) +cli.option('--name ', 'Provide your name') + +cli.command('lint [...files]', 'Lint files').action((files, options) => { + console.log(files, options) +}) + +// Display help message when `-h` or `--help` appears +cli.help() +// Display version number when `-v` or `--version` appears +// It's also used in help message +cli.version('0.0.0') + +cli.parse() +``` + +2018-11-25 8 21 14 + +### Command-specific Options + +You can attach options to a command. + +```js +const cli = require('cac')() + +cli + .command('rm ', 'Remove a dir') + .option('-r, --recursive', 'Remove recursively') + .action((dir, options) => { + console.log('remove ' + dir + (options.recursive ? ' recursively' : '')) + }) + +cli.help() + +cli.parse() +``` + +A command's options are validated when the command is used. Any unknown options will be reported as an error. However, if an action-based command does not define an action, then the options are not validated. If you really want to use unknown options, use [`command.allowUnknownOptions`](#commandallowunknownoptions). + +command options + +### Dash in option names + +Options in kebab-case should be referenced in camelCase in your code: + +```js +cli + .command('dev', 'Start dev server') + .option('--clear-screen', 'Clear screen') + .action((options) => { + console.log(options.clearScreen) + }) +``` + +In fact `--clear-screen` and `--clearScreen` are both mapped to `options.clearScreen`. + +### Brackets + +When using brackets in command name, angled brackets indicate required command arguments, while square bracket indicate optional arguments. + +When using brackets in option name, angled brackets indicate that a string / number value is required, while square bracket indicate that the value can also be `true`. + +```js +const cli = require('cac')() + +cli + .command('deploy ', 'Deploy a folder to AWS') + .option('--scale [level]', 'Scaling level') + .action((folder, options) => { + // ... + }) + +cli + .command('build [project]', 'Build a project') + .option('--out ', 'Output directory') + .action((folder, options) => { + // ... + }) + +cli.parse() +``` + +### Negated Options + +To allow an option whose value is `false`, you need to manually specify a negated option: + +```js +cli + .command('build [project]', 'Build a project') + .option('--no-config', 'Disable config file') + .option('--config ', 'Use a custom config file') +``` + +This will let CAC set the default value of `config` to true, and you can use `--no-config` flag to set it to `false`. + +### Variadic Arguments + +The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to add `...` to the start of argument name, just like the rest operator in JavaScript. Here is an example: + +```js +const cli = require('cac')() + +cli + .command('build [...otherFiles]', 'Build your app') + .option('--foo', 'Foo option') + .action((entry, otherFiles, options) => { + console.log(entry) + console.log(otherFiles) + console.log(options) + }) + +cli.help() + +cli.parse() +``` + +2018-11-25 8 25 30 + +### Dot-nested Options + +Dot-nested options will be merged into a single option. + +```js +const cli = require('cac')() + +cli + .command('build', 'desc') + .option('--env ', 'Set envs') + .example('--env.API_SECRET xxx') + .action((options) => { + console.log(options) + }) + +cli.help() + +cli.parse() +``` + +2018-11-25 9 37 53 + +### Default Command + +Register a command that will be used when no other command is matched. + +```js +const cli = require('cac')() + +cli + // Simply omit the command name, just brackets + .command('[...files]', 'Build files') + .option('--minimize', 'Minimize output') + .action((files, options) => { + console.log(files) + console.log(options.minimize) + }) + +cli.parse() +``` + +### Supply an array as option value + +```bash +node cli.js --include project-a +# The parsed options will be: +# { include: 'project-a' } + +node cli.js --include project-a --include project-b +# The parsed options will be: +# { include: ['project-a', 'project-b'] } +``` + +### Error Handling + +To handle command errors globally: + +```js +try { + // Parse CLI args without running the command + cli.parse(process.argv, { run: false }) + // Run the command yourself + // You only need `await` when your command action returns a Promise + await cli.runMatchedCommand() +} catch (error) { + // Handle error here.. + // e.g. + // console.error(error.stack) + // process.exit(1) +} +``` + +### With TypeScript + +First you need `@types/node` to be installed as a dev dependency in your project: + +```bash +yarn add @types/node --dev +``` + +Then everything just works out of the box: + +```js +const { cac } = require('cac') +// OR ES modules +import { cac } from 'cac' +``` + +### With Deno + +```ts +import { cac } from 'https://unpkg.com/cac/mod.ts' + +const cli = cac('my-program') +``` + +## Projects Using CAC + +Projects that use **CAC**: + +- [VuePress](https://github.com/vuejs/vuepress): :memo: Minimalistic Vue-powered static site generator. +- [SAO](https://github.com/egoist/sao): ⚔️ Futuristic scaffolding tool. +- [DocPad](https://github.com/docpad/docpad): 🏹 Powerful Static Site Generator. +- [Poi](https://github.com/egoist/poi): ⚡️ Delightful web development. +- [bili](https://github.com/egoist/bili): 🥂 Schweizer Armeemesser for bundling JavaScript libraries. +- [Lad](https://github.com/ladjs/lad): 👦 Lad scaffolds a Koa webapp and API framework for Node.js. +- [Lass](https://github.com/lassjs/lass): 💁🏻 Scaffold a modern package boilerplate for Node.js. +- [Foy](https://github.com/zaaack/foy): 🏗 A lightweight and modern task runner and build tool for general purpose. +- [Vuese](https://github.com/vuese/vuese): 🤗 One-stop solution for vue component documentation. +- [NUT](https://github.com/nut-project/nut): 🌰 A framework born for microfrontends +- Feel free to add yours here... + +## References + +**💁 Check out [the generated docs](https://cac-api-doc.egoist.sh/classes/_cac_.cac.html) from source code if you want a more in-depth API references.** + +Below is a brief overview. + +### CLI Instance + +CLI instance is created by invoking the `cac` function: + +```js +const cac = require('cac') +const cli = cac() +``` + +#### cac(name?) + +Create a CLI instance, optionally specify the program name which will be used to display in help and version message. When not set we use the basename of `argv[1]`. + +#### cli.command(name, description, config?) + +- Type: `(name: string, description: string) => Command` + +Create a command instance. + +The option also accepts a third argument `config` for additional command config: + +- `config.allowUnknownOptions`: `boolean` Allow unknown options in this command. +- `config.ignoreOptionDefaultValue`: `boolean` Don't use the options's default value in parsed options, only display them in help message. + +#### cli.option(name, description, config?) + +- Type: `(name: string, description: string, config?: OptionConfig) => CLI` + +Add a global option. + +The option also accepts a third argument `config` for additional option config: + +- `config.default`: Default value for the option. +- `config.type`: `any[]` When set to `[]`, the option value returns an array type. You can also use a conversion function such as `[String]`, which will invoke the option value with `String`. + +#### cli.parse(argv?) + +- Type: `(argv = process.argv) => ParsedArgv` + +```ts +interface ParsedArgv { + args: string[] + options: { + [k: string]: any + } +} +``` + +When this method is called, `cli.rawArgs` `cli.args` `cli.options` `cli.matchedCommand` will also be available. + +#### cli.version(version, customFlags?) + +- Type: `(version: string, customFlags = '-v, --version') => CLI` + +Output version number when `-v, --version` flag appears. + +#### cli.help(callback?) + +- Type: `(callback?: HelpCallback) => CLI` + +Output help message when `-h, --help` flag appears. + +Optional `callback` allows post-processing of help text before it is displayed: + +```ts +type HelpCallback = (sections: HelpSection[]) => void + +interface HelpSection { + title?: string + body: string +} +``` + +#### cli.outputHelp() + +- Type: `() => CLI` + +Output help message. + +#### cli.usage(text) + +- Type: `(text: string) => CLI` + +Add a global usage text. This is not used by sub-commands. + +### Command Instance + +Command instance is created by invoking the `cli.command` method: + +```js +const command = cli.command('build [...files]', 'Build given files') +``` + +#### command.option() + +Basically the same as `cli.option` but this adds the option to specific command. + +#### command.action(callback) + +- Type: `(callback: ActionCallback) => Command` + +Use a callback function as the command action when the command matches user inputs. + +```ts +type ActionCallback = ( + // Parsed CLI args + // The last arg will be an array if it's a variadic argument + ...args: string | string[] | number | number[] + // Parsed CLI options + options: Options +) => any + +interface Options { + [k: string]: any +} +``` + +#### command.alias(name) + +- Type: `(name: string) => Command` + +Add an alias name to this command, the `name` here can't contain brackets. + +#### command.allowUnknownOptions() + +- Type: `() => Command` + +Allow unknown options in this command, by default CAC will log an error when unknown options are used. + +#### command.example(example) + +- Type: `(example: CommandExample) => Command` + +Add an example which will be displayed at the end of help message. + +```ts +type CommandExample = ((name: string) => string) | string +``` + +#### command.usage(text) + +- Type: `(text: string) => Command` + +Add a usage text for this command. + +### Events + +Listen to commands: + +```js +// Listen to the `foo` command +cli.on('command:foo', () => { + // Do something +}) + +// Listen to the default command +cli.on('command:!', () => { + // Do something +}) + +// Listen to unknown commands +cli.on('command:*', () => { + console.error('Invalid command: %s', cli.args.join(' ')) + process.exit(1) +}) +``` + +## FAQ + +### How is the name written and pronounced? + +CAC, or cac, pronounced `C-A-C`. + +This project is dedicated to our lovely C.C. sama. Maybe CAC stands for C&C as well :P + + + +### Why not use Commander.js? + +CAC is very similar to Commander.js, while the latter does not support dot nested options, i.e. something like `--env.API_SECRET foo`. Besides, you can't use unknown options in Commander.js either. + +_And maybe more..._ + +Basically I made CAC to fulfill my own needs for building CLI apps like [Poi](https://poi.js.org), [SAO](https://sao.vercel.app) and all my CLI apps. It's small, simple but powerful :P + +## Project Stats + +![Alt](https://repobeats.axiom.co/api/embed/58caf6203631bcdb9bbe22f0728a0af1683dc0bb.svg 'Repobeats analytics image') + +## Contributing + +1. Fork it! +2. Create your feature branch: `git checkout -b my-new-feature` +3. Commit your changes: `git commit -am 'Add some feature'` +4. Push to the branch: `git push origin my-new-feature` +5. Submit a pull request :D + +## Author + +**CAC** © [EGOIST](https://github.com/egoist), Released under the [MIT](./LICENSE) License.
+Authored and maintained by egoist with help from contributors ([list](https://github.com/cacjs/cac/contributors)). + +> [Website](https://egoist.sh) · GitHub [@egoist](https://github.com/egoist) · Twitter [@\_egoistlily](https://twitter.com/_egoistlily) diff --git a/node_modules/cac/deno/CAC.ts b/node_modules/cac/deno/CAC.ts new file mode 100644 index 0000000000..0ced3b1f69 --- /dev/null +++ b/node_modules/cac/deno/CAC.ts @@ -0,0 +1,331 @@ +import { EventEmitter } from "https://deno.land/std@0.114.0/node/events.ts"; +import mri from "https://cdn.skypack.dev/mri"; +import Command, { GlobalCommand, CommandConfig, HelpCallback, CommandExample } from "./Command.ts"; +import { OptionConfig } from "./Option.ts"; +import { getMriOptions, setDotProp, setByType, getFileName, camelcaseOptionName } from "./utils.ts"; +import { processArgs } from "./deno.ts"; +interface ParsedArgv { + args: ReadonlyArray; + options: { + [k: string]: any; + }; +} + +class CAC extends EventEmitter { + /** The program name to display in help and version message */ + name: string; + commands: Command[]; + globalCommand: GlobalCommand; + matchedCommand?: Command; + matchedCommandName?: string; + /** + * Raw CLI arguments + */ + + rawArgs: string[]; + /** + * Parsed CLI arguments + */ + + args: ParsedArgv['args']; + /** + * Parsed CLI options, camelCased + */ + + options: ParsedArgv['options']; + showHelpOnExit?: boolean; + showVersionOnExit?: boolean; + /** + * @param name The program name to display in help and version message + */ + + constructor(name = '') { + super(); + this.name = name; + this.commands = []; + this.rawArgs = []; + this.args = []; + this.options = {}; + this.globalCommand = new GlobalCommand(this); + this.globalCommand.usage(' [options]'); + } + /** + * Add a global usage text. + * + * This is not used by sub-commands. + */ + + + usage(text: string) { + this.globalCommand.usage(text); + return this; + } + /** + * Add a sub-command + */ + + + command(rawName: string, description?: string, config?: CommandConfig) { + const command = new Command(rawName, description || '', config, this); + command.globalCommand = this.globalCommand; + this.commands.push(command); + return command; + } + /** + * Add a global CLI option. + * + * Which is also applied to sub-commands. + */ + + + option(rawName: string, description: string, config?: OptionConfig) { + this.globalCommand.option(rawName, description, config); + return this; + } + /** + * Show help message when `-h, --help` flags appear. + * + */ + + + help(callback?: HelpCallback) { + this.globalCommand.option('-h, --help', 'Display this message'); + this.globalCommand.helpCallback = callback; + this.showHelpOnExit = true; + return this; + } + /** + * Show version number when `-v, --version` flags appear. + * + */ + + + version(version: string, customFlags = '-v, --version') { + this.globalCommand.version(version, customFlags); + this.showVersionOnExit = true; + return this; + } + /** + * Add a global example. + * + * This example added here will not be used by sub-commands. + */ + + + example(example: CommandExample) { + this.globalCommand.example(example); + return this; + } + /** + * Output the corresponding help message + * When a sub-command is matched, output the help message for the command + * Otherwise output the global one. + * + */ + + + outputHelp() { + if (this.matchedCommand) { + this.matchedCommand.outputHelp(); + } else { + this.globalCommand.outputHelp(); + } + } + /** + * Output the version number. + * + */ + + + outputVersion() { + this.globalCommand.outputVersion(); + } + + private setParsedInfo({ + args, + options + }: ParsedArgv, matchedCommand?: Command, matchedCommandName?: string) { + this.args = args; + this.options = options; + + if (matchedCommand) { + this.matchedCommand = matchedCommand; + } + + if (matchedCommandName) { + this.matchedCommandName = matchedCommandName; + } + + return this; + } + + unsetMatchedCommand() { + this.matchedCommand = undefined; + this.matchedCommandName = undefined; + } + /** + * Parse argv + */ + + + parse(argv = processArgs, { + /** Whether to run the action for matched command */ + run = true + } = {}): ParsedArgv { + this.rawArgs = argv; + + if (!this.name) { + this.name = argv[1] ? getFileName(argv[1]) : 'cli'; + } + + let shouldParse = true; // Search sub-commands + + for (const command of this.commands) { + const parsed = this.mri(argv.slice(2), command); + const commandName = parsed.args[0]; + + if (command.isMatched(commandName)) { + shouldParse = false; + const parsedInfo = { ...parsed, + args: parsed.args.slice(1) + }; + this.setParsedInfo(parsedInfo, command, commandName); + this.emit(`command:${commandName}`, command); + } + } + + if (shouldParse) { + // Search the default command + for (const command of this.commands) { + if (command.name === '') { + shouldParse = false; + const parsed = this.mri(argv.slice(2), command); + this.setParsedInfo(parsed, command); + this.emit(`command:!`, command); + } + } + } + + if (shouldParse) { + const parsed = this.mri(argv.slice(2)); + this.setParsedInfo(parsed); + } + + if (this.options.help && this.showHelpOnExit) { + this.outputHelp(); + run = false; + this.unsetMatchedCommand(); + } + + if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) { + this.outputVersion(); + run = false; + this.unsetMatchedCommand(); + } + + const parsedArgv = { + args: this.args, + options: this.options + }; + + if (run) { + this.runMatchedCommand(); + } + + if (!this.matchedCommand && this.args[0]) { + this.emit('command:*'); + } + + return parsedArgv; + } + + private mri(argv: string[], + /** Matched command */ + command?: Command): ParsedArgv { + // All added options + const cliOptions = [...this.globalCommand.options, ...(command ? command.options : [])]; + const mriOptions = getMriOptions(cliOptions); // Extract everything after `--` since mri doesn't support it + + let argsAfterDoubleDashes: string[] = []; + const doubleDashesIndex = argv.indexOf('--'); + + if (doubleDashesIndex > -1) { + argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1); + argv = argv.slice(0, doubleDashesIndex); + } + + let parsed = mri(argv, mriOptions); + parsed = Object.keys(parsed).reduce((res, name) => { + return { ...res, + [camelcaseOptionName(name)]: parsed[name] + }; + }, { + _: [] + }); + const args = parsed._; + const options: { + [k: string]: any; + } = { + '--': argsAfterDoubleDashes + }; // Set option default value + + const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue; + let transforms = Object.create(null); + + for (const cliOption of cliOptions) { + if (!ignoreDefault && cliOption.config.default !== undefined) { + for (const name of cliOption.names) { + options[name] = cliOption.config.default; + } + } // If options type is defined + + + if (Array.isArray(cliOption.config.type)) { + if (transforms[cliOption.name] === undefined) { + transforms[cliOption.name] = Object.create(null); + transforms[cliOption.name]['shouldTransform'] = true; + transforms[cliOption.name]['transformFunction'] = cliOption.config.type[0]; + } + } + } // Set option values (support dot-nested property name) + + + for (const key of Object.keys(parsed)) { + if (key !== '_') { + const keys = key.split('.'); + setDotProp(options, keys, parsed[key]); + setByType(options, transforms); + } + } + + return { + args, + options + }; + } + + runMatchedCommand() { + const { + args, + options, + matchedCommand: command + } = this; + if (!command || !command.commandAction) return; + command.checkUnknownOptions(); + command.checkOptionValue(); + command.checkRequiredArgs(); + const actionArgs: any[] = []; + command.args.forEach((arg, index) => { + if (arg.variadic) { + actionArgs.push(args.slice(index)); + } else { + actionArgs.push(args[index]); + } + }); + actionArgs.push(options); + return command.commandAction.apply(this, actionArgs); + } + +} + +export default CAC; \ No newline at end of file diff --git a/node_modules/cac/deno/Command.ts b/node_modules/cac/deno/Command.ts new file mode 100644 index 0000000000..3fd04a058a --- /dev/null +++ b/node_modules/cac/deno/Command.ts @@ -0,0 +1,269 @@ +import CAC from "./CAC.ts"; +import Option, { OptionConfig } from "./Option.ts"; +import { removeBrackets, findAllBrackets, findLongest, padRight, CACError } from "./utils.ts"; +import { platformInfo } from "./deno.ts"; +interface CommandArg { + required: boolean; + value: string; + variadic: boolean; +} +interface HelpSection { + title?: string; + body: string; +} +interface CommandConfig { + allowUnknownOptions?: boolean; + ignoreOptionDefaultValue?: boolean; +} +type HelpCallback = (sections: HelpSection[]) => void | HelpSection[]; +type CommandExample = ((bin: string) => string) | string; + +class Command { + options: Option[]; + aliasNames: string[]; + /* Parsed command name */ + + name: string; + args: CommandArg[]; + commandAction?: (...args: any[]) => any; + usageText?: string; + versionNumber?: string; + examples: CommandExample[]; + helpCallback?: HelpCallback; + globalCommand?: GlobalCommand; + + constructor(public rawName: string, public description: string, public config: CommandConfig = {}, public cli: CAC) { + this.options = []; + this.aliasNames = []; + this.name = removeBrackets(rawName); + this.args = findAllBrackets(rawName); + this.examples = []; + } + + usage(text: string) { + this.usageText = text; + return this; + } + + allowUnknownOptions() { + this.config.allowUnknownOptions = true; + return this; + } + + ignoreOptionDefaultValue() { + this.config.ignoreOptionDefaultValue = true; + return this; + } + + version(version: string, customFlags = '-v, --version') { + this.versionNumber = version; + this.option(customFlags, 'Display version number'); + return this; + } + + example(example: CommandExample) { + this.examples.push(example); + return this; + } + /** + * Add a option for this command + * @param rawName Raw option name(s) + * @param description Option description + * @param config Option config + */ + + + option(rawName: string, description: string, config?: OptionConfig) { + const option = new Option(rawName, description, config); + this.options.push(option); + return this; + } + + alias(name: string) { + this.aliasNames.push(name); + return this; + } + + action(callback: (...args: any[]) => any) { + this.commandAction = callback; + return this; + } + /** + * Check if a command name is matched by this command + * @param name Command name + */ + + + isMatched(name: string) { + return this.name === name || this.aliasNames.includes(name); + } + + get isDefaultCommand() { + return this.name === '' || this.aliasNames.includes('!'); + } + + get isGlobalCommand(): boolean { + return this instanceof GlobalCommand; + } + /** + * Check if an option is registered in this command + * @param name Option name + */ + + + hasOption(name: string) { + name = name.split('.')[0]; + return this.options.find(option => { + return option.names.includes(name); + }); + } + + outputHelp() { + const { + name, + commands + } = this.cli; + const { + versionNumber, + options: globalOptions, + helpCallback + } = this.cli.globalCommand; + let sections: HelpSection[] = [{ + body: `${name}${versionNumber ? `/${versionNumber}` : ''}` + }]; + sections.push({ + title: 'Usage', + body: ` $ ${name} ${this.usageText || this.rawName}` + }); + const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0; + + if (showCommands) { + const longestCommandName = findLongest(commands.map(command => command.rawName)); + sections.push({ + title: 'Commands', + body: commands.map(command => { + return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`; + }).join('\n') + }); + sections.push({ + title: `For more info, run any command with the \`--help\` flag`, + body: commands.map(command => ` $ ${name}${command.name === '' ? '' : ` ${command.name}`} --help`).join('\n') + }); + } + + let options = this.isGlobalCommand ? globalOptions : [...this.options, ...(globalOptions || [])]; + + if (!this.isGlobalCommand && !this.isDefaultCommand) { + options = options.filter(option => option.name !== 'version'); + } + + if (options.length > 0) { + const longestOptionName = findLongest(options.map(option => option.rawName)); + sections.push({ + title: 'Options', + body: options.map(option => { + return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === undefined ? '' : `(default: ${option.config.default})`}`; + }).join('\n') + }); + } + + if (this.examples.length > 0) { + sections.push({ + title: 'Examples', + body: this.examples.map(example => { + if (typeof example === 'function') { + return example(name); + } + + return example; + }).join('\n') + }); + } + + if (helpCallback) { + sections = helpCallback(sections) || sections; + } + + console.log(sections.map(section => { + return section.title ? `${section.title}:\n${section.body}` : section.body; + }).join('\n\n')); + } + + outputVersion() { + const { + name + } = this.cli; + const { + versionNumber + } = this.cli.globalCommand; + + if (versionNumber) { + console.log(`${name}/${versionNumber} ${platformInfo}`); + } + } + + checkRequiredArgs() { + const minimalArgsCount = this.args.filter(arg => arg.required).length; + + if (this.cli.args.length < minimalArgsCount) { + throw new CACError(`missing required args for command \`${this.rawName}\``); + } + } + /** + * Check if the parsed options contain any unknown options + * + * Exit and output error when true + */ + + + checkUnknownOptions() { + const { + options, + globalCommand + } = this.cli; + + if (!this.config.allowUnknownOptions) { + for (const name of Object.keys(options)) { + if (name !== '--' && !this.hasOption(name) && !globalCommand.hasOption(name)) { + throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``); + } + } + } + } + /** + * Check if the required string-type options exist + */ + + + checkOptionValue() { + const { + options: parsedOptions, + globalCommand + } = this.cli; + const options = [...globalCommand.options, ...this.options]; + + for (const option of options) { + const value = parsedOptions[option.name.split('.')[0]]; // Check required option value + + if (option.required) { + const hasNegated = options.some(o => o.negated && o.names.includes(option.name)); + + if (value === true || value === false && !hasNegated) { + throw new CACError(`option \`${option.rawName}\` value is missing`); + } + } + } + } + +} + +class GlobalCommand extends Command { + constructor(cli: CAC) { + super('@@global@@', '', {}, cli); + } + +} + +export type { HelpCallback, CommandExample, CommandConfig }; +export { GlobalCommand }; +export default Command; \ No newline at end of file diff --git a/node_modules/cac/deno/Option.ts b/node_modules/cac/deno/Option.ts new file mode 100644 index 0000000000..ee7ed2d834 --- /dev/null +++ b/node_modules/cac/deno/Option.ts @@ -0,0 +1,52 @@ +import { removeBrackets, camelcaseOptionName } from "./utils.ts"; +interface OptionConfig { + default?: any; + type?: any[]; +} +export default class Option { + /** Option name */ + name: string; + /** Option name and aliases */ + + names: string[]; + isBoolean?: boolean; // `required` will be a boolean for options with brackets + + required?: boolean; + config: OptionConfig; + negated: boolean; + + constructor(public rawName: string, public description: string, config?: OptionConfig) { + this.config = Object.assign({}, config); // You may use cli.option('--env.* [value]', 'desc') to denote a dot-nested option + + rawName = rawName.replace(/\.\*/g, ''); + this.negated = false; + this.names = removeBrackets(rawName).split(',').map((v: string) => { + let name = v.trim().replace(/^-{1,2}/, ''); + + if (name.startsWith('no-')) { + this.negated = true; + name = name.replace(/^no-/, ''); + } + + return camelcaseOptionName(name); + }).sort((a, b) => a.length > b.length ? 1 : -1); // Sort names + // Use the longest name (last one) as actual option name + + this.name = this.names[this.names.length - 1]; + + if (this.negated && this.config.default == null) { + this.config.default = true; + } + + if (rawName.includes('<')) { + this.required = true; + } else if (rawName.includes('[')) { + this.required = false; + } else { + // No arg needed, it's boolean flag + this.isBoolean = true; + } + } + +} +export type { OptionConfig }; \ No newline at end of file diff --git a/node_modules/cac/deno/deno.ts b/node_modules/cac/deno/deno.ts new file mode 100644 index 0000000000..2f8e7d9b9a --- /dev/null +++ b/node_modules/cac/deno/deno.ts @@ -0,0 +1,4 @@ +// Ignore the TypeScript errors +// Since this file will only be used in Deno runtime +export const processArgs = ['deno', 'cli'].concat(Deno.args); +export const platformInfo = `${Deno.build.os}-${Deno.build.arch} deno-${Deno.version.deno}`; \ No newline at end of file diff --git a/node_modules/cac/deno/index.ts b/node_modules/cac/deno/index.ts new file mode 100644 index 0000000000..55aa29b7db --- /dev/null +++ b/node_modules/cac/deno/index.ts @@ -0,0 +1,10 @@ +import CAC from "./CAC.ts"; +import Command from "./Command.ts"; +/** + * @param name The program name to display in help and version message + */ + +const cac = (name = '') => new CAC(name); + +export default cac; +export { cac, CAC, Command }; \ No newline at end of file diff --git a/node_modules/cac/deno/utils.ts b/node_modules/cac/deno/utils.ts new file mode 100644 index 0000000000..d75847b5aa --- /dev/null +++ b/node_modules/cac/deno/utils.ts @@ -0,0 +1,145 @@ +import Option from "./Option.ts"; +export const removeBrackets = (v: string) => v.replace(/[<[].+/, '').trim(); +export const findAllBrackets = (v: string) => { + const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g; + const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g; + const res = []; + + const parse = (match: string[]) => { + let variadic = false; + let value = match[1]; + + if (value.startsWith('...')) { + value = value.slice(3); + variadic = true; + } + + return { + required: match[0].startsWith('<'), + value, + variadic + }; + }; + + let angledMatch; + + while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(angledMatch)); + } + + let squareMatch; + + while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(squareMatch)); + } + + return res; +}; +interface MriOptions { + alias: { + [k: string]: string[]; + }; + boolean: string[]; +} +export const getMriOptions = (options: Option[]) => { + const result: MriOptions = { + alias: {}, + boolean: [] + }; + + for (const [index, option] of options.entries()) { + // We do not set default values in mri options + // Since its type (typeof) will be used to cast parsed arguments. + // Which mean `--foo foo` will be parsed as `{foo: true}` if we have `{default:{foo: true}}` + // Set alias + if (option.names.length > 1) { + result.alias[option.names[0]] = option.names.slice(1); + } // Set boolean + + + if (option.isBoolean) { + if (option.negated) { + // For negated option + // We only set it to `boolean` type when there's no string-type option with the same name + const hasStringTypeOption = options.some((o, i) => { + return i !== index && o.names.some(name => option.names.includes(name)) && typeof o.required === 'boolean'; + }); + + if (!hasStringTypeOption) { + result.boolean.push(option.names[0]); + } + } else { + result.boolean.push(option.names[0]); + } + } + } + + return result; +}; +export const findLongest = (arr: string[]) => { + return arr.sort((a, b) => { + return a.length > b.length ? -1 : 1; + })[0]; +}; +export const padRight = (str: string, length: number) => { + return str.length >= length ? str : `${str}${' '.repeat(length - str.length)}`; +}; +export const camelcase = (input: string) => { + return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => { + return p1 + p2.toUpperCase(); + }); +}; +export const setDotProp = (obj: { + [k: string]: any; +}, keys: string[], val: any) => { + let i = 0; + let length = keys.length; + let t = obj; + let x; + + for (; i < length; ++i) { + x = t[keys[i]]; + t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf('.') || !(+keys[i + 1] > -1) ? {} : []; + } +}; +export const setByType = (obj: { + [k: string]: any; +}, transforms: { + [k: string]: any; +}) => { + for (const key of Object.keys(transforms)) { + const transform = transforms[key]; + + if (transform.shouldTransform) { + obj[key] = Array.prototype.concat.call([], obj[key]); + + if (typeof transform.transformFunction === 'function') { + obj[key] = obj[key].map(transform.transformFunction); + } + } + } +}; +export const getFileName = (input: string) => { + const m = /([^\\\/]+)$/.exec(input); + return m ? m[1] : ''; +}; +export const camelcaseOptionName = (name: string) => { + // Camelcase the option name + // Don't camelcase anything after the dot `.` + return name.split('.').map((v, i) => { + return i === 0 ? camelcase(v) : v; + }).join('.'); +}; +export class CACError extends Error { + constructor(message: string) { + super(message); + this.name = this.constructor.name; + + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = new Error(message).stack; + } + } + +} \ No newline at end of file diff --git a/node_modules/cac/dist/index.d.ts b/node_modules/cac/dist/index.d.ts new file mode 100644 index 0000000000..84dcb6642e --- /dev/null +++ b/node_modules/cac/dist/index.d.ts @@ -0,0 +1,191 @@ +import { EventEmitter } from 'events'; + +interface OptionConfig { + default?: any; + type?: any[]; +} +declare class Option { + rawName: string; + description: string; + /** Option name */ + name: string; + /** Option name and aliases */ + names: string[]; + isBoolean?: boolean; + required?: boolean; + config: OptionConfig; + negated: boolean; + constructor(rawName: string, description: string, config?: OptionConfig); +} + +interface CommandArg { + required: boolean; + value: string; + variadic: boolean; +} +interface HelpSection { + title?: string; + body: string; +} +interface CommandConfig { + allowUnknownOptions?: boolean; + ignoreOptionDefaultValue?: boolean; +} +declare type HelpCallback = (sections: HelpSection[]) => void | HelpSection[]; +declare type CommandExample = ((bin: string) => string) | string; +declare class Command { + rawName: string; + description: string; + config: CommandConfig; + cli: CAC; + options: Option[]; + aliasNames: string[]; + name: string; + args: CommandArg[]; + commandAction?: (...args: any[]) => any; + usageText?: string; + versionNumber?: string; + examples: CommandExample[]; + helpCallback?: HelpCallback; + globalCommand?: GlobalCommand; + constructor(rawName: string, description: string, config: CommandConfig, cli: CAC); + usage(text: string): this; + allowUnknownOptions(): this; + ignoreOptionDefaultValue(): this; + version(version: string, customFlags?: string): this; + example(example: CommandExample): this; + /** + * Add a option for this command + * @param rawName Raw option name(s) + * @param description Option description + * @param config Option config + */ + option(rawName: string, description: string, config?: OptionConfig): this; + alias(name: string): this; + action(callback: (...args: any[]) => any): this; + /** + * Check if a command name is matched by this command + * @param name Command name + */ + isMatched(name: string): boolean; + get isDefaultCommand(): boolean; + get isGlobalCommand(): boolean; + /** + * Check if an option is registered in this command + * @param name Option name + */ + hasOption(name: string): Option | undefined; + outputHelp(): void; + outputVersion(): void; + checkRequiredArgs(): void; + /** + * Check if the parsed options contain any unknown options + * + * Exit and output error when true + */ + checkUnknownOptions(): void; + /** + * Check if the required string-type options exist + */ + checkOptionValue(): void; +} +declare class GlobalCommand extends Command { + constructor(cli: CAC); +} + +interface ParsedArgv { + args: ReadonlyArray; + options: { + [k: string]: any; + }; +} +declare class CAC extends EventEmitter { + /** The program name to display in help and version message */ + name: string; + commands: Command[]; + globalCommand: GlobalCommand; + matchedCommand?: Command; + matchedCommandName?: string; + /** + * Raw CLI arguments + */ + rawArgs: string[]; + /** + * Parsed CLI arguments + */ + args: ParsedArgv['args']; + /** + * Parsed CLI options, camelCased + */ + options: ParsedArgv['options']; + showHelpOnExit?: boolean; + showVersionOnExit?: boolean; + /** + * @param name The program name to display in help and version message + */ + constructor(name?: string); + /** + * Add a global usage text. + * + * This is not used by sub-commands. + */ + usage(text: string): this; + /** + * Add a sub-command + */ + command(rawName: string, description?: string, config?: CommandConfig): Command; + /** + * Add a global CLI option. + * + * Which is also applied to sub-commands. + */ + option(rawName: string, description: string, config?: OptionConfig): this; + /** + * Show help message when `-h, --help` flags appear. + * + */ + help(callback?: HelpCallback): this; + /** + * Show version number when `-v, --version` flags appear. + * + */ + version(version: string, customFlags?: string): this; + /** + * Add a global example. + * + * This example added here will not be used by sub-commands. + */ + example(example: CommandExample): this; + /** + * Output the corresponding help message + * When a sub-command is matched, output the help message for the command + * Otherwise output the global one. + * + */ + outputHelp(): void; + /** + * Output the version number. + * + */ + outputVersion(): void; + private setParsedInfo; + unsetMatchedCommand(): void; + /** + * Parse argv + */ + parse(argv?: string[], { + /** Whether to run the action for matched command */ + run, }?: { + run?: boolean | undefined; + }): ParsedArgv; + private mri; + runMatchedCommand(): any; +} + +/** + * @param name The program name to display in help and version message + */ +declare const cac: (name?: string) => CAC; + +export default cac; +export { CAC, Command, cac }; diff --git a/node_modules/cac/dist/index.js b/node_modules/cac/dist/index.js new file mode 100644 index 0000000000..8582dbf62d --- /dev/null +++ b/node_modules/cac/dist/index.js @@ -0,0 +1,623 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var events = require('events'); + +function toArr(any) { + return any == null ? [] : Array.isArray(any) ? any : [any]; +} + +function toVal(out, key, val, opts) { + var x, old=out[key], nxt=( + !!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val)) + : typeof val === 'boolean' ? val + : !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val)) + : (x = +val,x * 0 === 0) ? x : val + ); + out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]); +} + +function mri2 (args, opts) { + args = args || []; + opts = opts || {}; + + var k, arr, arg, name, val, out={ _:[] }; + var i=0, j=0, idx=0, len=args.length; + + const alibi = opts.alias !== void 0; + const strict = opts.unknown !== void 0; + const defaults = opts.default !== void 0; + + opts.alias = opts.alias || {}; + opts.string = toArr(opts.string); + opts.boolean = toArr(opts.boolean); + + if (alibi) { + for (k in opts.alias) { + arr = opts.alias[k] = toArr(opts.alias[k]); + for (i=0; i < arr.length; i++) { + (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1); + } + } + } + + for (i=opts.boolean.length; i-- > 0;) { + arr = opts.alias[opts.boolean[i]] || []; + for (j=arr.length; j-- > 0;) opts.boolean.push(arr[j]); + } + + for (i=opts.string.length; i-- > 0;) { + arr = opts.alias[opts.string[i]] || []; + for (j=arr.length; j-- > 0;) opts.string.push(arr[j]); + } + + if (defaults) { + for (k in opts.default) { + name = typeof opts.default[k]; + arr = opts.alias[k] = opts.alias[k] || []; + if (opts[name] !== void 0) { + opts[name].push(k); + for (i=0; i < arr.length; i++) { + opts[name].push(arr[i]); + } + } + } + } + + const keys = strict ? Object.keys(opts.alias) : []; + + for (i=0; i < len; i++) { + arg = args[i]; + + if (arg === '--') { + out._ = out._.concat(args.slice(++i)); + break; + } + + for (j=0; j < arg.length; j++) { + if (arg.charCodeAt(j) !== 45) break; // "-" + } + + if (j === 0) { + out._.push(arg); + } else if (arg.substring(j, j + 3) === 'no-') { + name = arg.substring(j + 3); + if (strict && !~keys.indexOf(name)) { + return opts.unknown(arg); + } + out[name] = false; + } else { + for (idx=j+1; idx < arg.length; idx++) { + if (arg.charCodeAt(idx) === 61) break; // "=" + } + + name = arg.substring(j, idx); + val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]); + arr = (j === 2 ? [name] : name); + + for (idx=0; idx < arr.length; idx++) { + name = arr[idx]; + if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name); + toVal(out, name, (idx + 1 < arr.length) || val, opts); + } + } + } + + if (defaults) { + for (k in opts.default) { + if (out[k] === void 0) { + out[k] = opts.default[k]; + } + } + } + + if (alibi) { + for (k in out) { + arr = opts.alias[k] || []; + while (arr.length > 0) { + out[arr.shift()] = out[k]; + } + } + } + + return out; +} + +const removeBrackets = (v) => v.replace(/[<[].+/, "").trim(); +const findAllBrackets = (v) => { + const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g; + const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g; + const res = []; + const parse = (match) => { + let variadic = false; + let value = match[1]; + if (value.startsWith("...")) { + value = value.slice(3); + variadic = true; + } + return { + required: match[0].startsWith("<"), + value, + variadic + }; + }; + let angledMatch; + while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(angledMatch)); + } + let squareMatch; + while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(squareMatch)); + } + return res; +}; +const getMriOptions = (options) => { + const result = {alias: {}, boolean: []}; + for (const [index, option] of options.entries()) { + if (option.names.length > 1) { + result.alias[option.names[0]] = option.names.slice(1); + } + if (option.isBoolean) { + if (option.negated) { + const hasStringTypeOption = options.some((o, i) => { + return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean"; + }); + if (!hasStringTypeOption) { + result.boolean.push(option.names[0]); + } + } else { + result.boolean.push(option.names[0]); + } + } + } + return result; +}; +const findLongest = (arr) => { + return arr.sort((a, b) => { + return a.length > b.length ? -1 : 1; + })[0]; +}; +const padRight = (str, length) => { + return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`; +}; +const camelcase = (input) => { + return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => { + return p1 + p2.toUpperCase(); + }); +}; +const setDotProp = (obj, keys, val) => { + let i = 0; + let length = keys.length; + let t = obj; + let x; + for (; i < length; ++i) { + x = t[keys[i]]; + t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : []; + } +}; +const setByType = (obj, transforms) => { + for (const key of Object.keys(transforms)) { + const transform = transforms[key]; + if (transform.shouldTransform) { + obj[key] = Array.prototype.concat.call([], obj[key]); + if (typeof transform.transformFunction === "function") { + obj[key] = obj[key].map(transform.transformFunction); + } + } + } +}; +const getFileName = (input) => { + const m = /([^\\\/]+)$/.exec(input); + return m ? m[1] : ""; +}; +const camelcaseOptionName = (name) => { + return name.split(".").map((v, i) => { + return i === 0 ? camelcase(v) : v; + }).join("."); +}; +class CACError extends Error { + constructor(message) { + super(message); + this.name = this.constructor.name; + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = new Error(message).stack; + } + } +} + +class Option { + constructor(rawName, description, config) { + this.rawName = rawName; + this.description = description; + this.config = Object.assign({}, config); + rawName = rawName.replace(/\.\*/g, ""); + this.negated = false; + this.names = removeBrackets(rawName).split(",").map((v) => { + let name = v.trim().replace(/^-{1,2}/, ""); + if (name.startsWith("no-")) { + this.negated = true; + name = name.replace(/^no-/, ""); + } + return camelcaseOptionName(name); + }).sort((a, b) => a.length > b.length ? 1 : -1); + this.name = this.names[this.names.length - 1]; + if (this.negated && this.config.default == null) { + this.config.default = true; + } + if (rawName.includes("<")) { + this.required = true; + } else if (rawName.includes("[")) { + this.required = false; + } else { + this.isBoolean = true; + } + } +} + +const processArgs = process.argv; +const platformInfo = `${process.platform}-${process.arch} node-${process.version}`; + +class Command { + constructor(rawName, description, config = {}, cli) { + this.rawName = rawName; + this.description = description; + this.config = config; + this.cli = cli; + this.options = []; + this.aliasNames = []; + this.name = removeBrackets(rawName); + this.args = findAllBrackets(rawName); + this.examples = []; + } + usage(text) { + this.usageText = text; + return this; + } + allowUnknownOptions() { + this.config.allowUnknownOptions = true; + return this; + } + ignoreOptionDefaultValue() { + this.config.ignoreOptionDefaultValue = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.versionNumber = version; + this.option(customFlags, "Display version number"); + return this; + } + example(example) { + this.examples.push(example); + return this; + } + option(rawName, description, config) { + const option = new Option(rawName, description, config); + this.options.push(option); + return this; + } + alias(name) { + this.aliasNames.push(name); + return this; + } + action(callback) { + this.commandAction = callback; + return this; + } + isMatched(name) { + return this.name === name || this.aliasNames.includes(name); + } + get isDefaultCommand() { + return this.name === "" || this.aliasNames.includes("!"); + } + get isGlobalCommand() { + return this instanceof GlobalCommand; + } + hasOption(name) { + name = name.split(".")[0]; + return this.options.find((option) => { + return option.names.includes(name); + }); + } + outputHelp() { + const {name, commands} = this.cli; + const { + versionNumber, + options: globalOptions, + helpCallback + } = this.cli.globalCommand; + let sections = [ + { + body: `${name}${versionNumber ? `/${versionNumber}` : ""}` + } + ]; + sections.push({ + title: "Usage", + body: ` $ ${name} ${this.usageText || this.rawName}` + }); + const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0; + if (showCommands) { + const longestCommandName = findLongest(commands.map((command) => command.rawName)); + sections.push({ + title: "Commands", + body: commands.map((command) => { + return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`; + }).join("\n") + }); + sections.push({ + title: `For more info, run any command with the \`--help\` flag`, + body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join("\n") + }); + } + let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []]; + if (!this.isGlobalCommand && !this.isDefaultCommand) { + options = options.filter((option) => option.name !== "version"); + } + if (options.length > 0) { + const longestOptionName = findLongest(options.map((option) => option.rawName)); + sections.push({ + title: "Options", + body: options.map((option) => { + return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? "" : `(default: ${option.config.default})`}`; + }).join("\n") + }); + } + if (this.examples.length > 0) { + sections.push({ + title: "Examples", + body: this.examples.map((example) => { + if (typeof example === "function") { + return example(name); + } + return example; + }).join("\n") + }); + } + if (helpCallback) { + sections = helpCallback(sections) || sections; + } + console.log(sections.map((section) => { + return section.title ? `${section.title}: +${section.body}` : section.body; + }).join("\n\n")); + } + outputVersion() { + const {name} = this.cli; + const {versionNumber} = this.cli.globalCommand; + if (versionNumber) { + console.log(`${name}/${versionNumber} ${platformInfo}`); + } + } + checkRequiredArgs() { + const minimalArgsCount = this.args.filter((arg) => arg.required).length; + if (this.cli.args.length < minimalArgsCount) { + throw new CACError(`missing required args for command \`${this.rawName}\``); + } + } + checkUnknownOptions() { + const {options, globalCommand} = this.cli; + if (!this.config.allowUnknownOptions) { + for (const name of Object.keys(options)) { + if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) { + throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``); + } + } + } + } + checkOptionValue() { + const {options: parsedOptions, globalCommand} = this.cli; + const options = [...globalCommand.options, ...this.options]; + for (const option of options) { + const value = parsedOptions[option.name.split(".")[0]]; + if (option.required) { + const hasNegated = options.some((o) => o.negated && o.names.includes(option.name)); + if (value === true || value === false && !hasNegated) { + throw new CACError(`option \`${option.rawName}\` value is missing`); + } + } + } + } +} +class GlobalCommand extends Command { + constructor(cli) { + super("@@global@@", "", {}, cli); + } +} + +var __assign = Object.assign; +class CAC extends events.EventEmitter { + constructor(name = "") { + super(); + this.name = name; + this.commands = []; + this.rawArgs = []; + this.args = []; + this.options = {}; + this.globalCommand = new GlobalCommand(this); + this.globalCommand.usage(" [options]"); + } + usage(text) { + this.globalCommand.usage(text); + return this; + } + command(rawName, description, config) { + const command = new Command(rawName, description || "", config, this); + command.globalCommand = this.globalCommand; + this.commands.push(command); + return command; + } + option(rawName, description, config) { + this.globalCommand.option(rawName, description, config); + return this; + } + help(callback) { + this.globalCommand.option("-h, --help", "Display this message"); + this.globalCommand.helpCallback = callback; + this.showHelpOnExit = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.globalCommand.version(version, customFlags); + this.showVersionOnExit = true; + return this; + } + example(example) { + this.globalCommand.example(example); + return this; + } + outputHelp() { + if (this.matchedCommand) { + this.matchedCommand.outputHelp(); + } else { + this.globalCommand.outputHelp(); + } + } + outputVersion() { + this.globalCommand.outputVersion(); + } + setParsedInfo({args, options}, matchedCommand, matchedCommandName) { + this.args = args; + this.options = options; + if (matchedCommand) { + this.matchedCommand = matchedCommand; + } + if (matchedCommandName) { + this.matchedCommandName = matchedCommandName; + } + return this; + } + unsetMatchedCommand() { + this.matchedCommand = void 0; + this.matchedCommandName = void 0; + } + parse(argv = processArgs, { + run = true + } = {}) { + this.rawArgs = argv; + if (!this.name) { + this.name = argv[1] ? getFileName(argv[1]) : "cli"; + } + let shouldParse = true; + for (const command of this.commands) { + const parsed = this.mri(argv.slice(2), command); + const commandName = parsed.args[0]; + if (command.isMatched(commandName)) { + shouldParse = false; + const parsedInfo = __assign(__assign({}, parsed), { + args: parsed.args.slice(1) + }); + this.setParsedInfo(parsedInfo, command, commandName); + this.emit(`command:${commandName}`, command); + } + } + if (shouldParse) { + for (const command of this.commands) { + if (command.name === "") { + shouldParse = false; + const parsed = this.mri(argv.slice(2), command); + this.setParsedInfo(parsed, command); + this.emit(`command:!`, command); + } + } + } + if (shouldParse) { + const parsed = this.mri(argv.slice(2)); + this.setParsedInfo(parsed); + } + if (this.options.help && this.showHelpOnExit) { + this.outputHelp(); + run = false; + this.unsetMatchedCommand(); + } + if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) { + this.outputVersion(); + run = false; + this.unsetMatchedCommand(); + } + const parsedArgv = {args: this.args, options: this.options}; + if (run) { + this.runMatchedCommand(); + } + if (!this.matchedCommand && this.args[0]) { + this.emit("command:*"); + } + return parsedArgv; + } + mri(argv, command) { + const cliOptions = [ + ...this.globalCommand.options, + ...command ? command.options : [] + ]; + const mriOptions = getMriOptions(cliOptions); + let argsAfterDoubleDashes = []; + const doubleDashesIndex = argv.indexOf("--"); + if (doubleDashesIndex > -1) { + argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1); + argv = argv.slice(0, doubleDashesIndex); + } + let parsed = mri2(argv, mriOptions); + parsed = Object.keys(parsed).reduce((res, name) => { + return __assign(__assign({}, res), { + [camelcaseOptionName(name)]: parsed[name] + }); + }, {_: []}); + const args = parsed._; + const options = { + "--": argsAfterDoubleDashes + }; + const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue; + let transforms = Object.create(null); + for (const cliOption of cliOptions) { + if (!ignoreDefault && cliOption.config.default !== void 0) { + for (const name of cliOption.names) { + options[name] = cliOption.config.default; + } + } + if (Array.isArray(cliOption.config.type)) { + if (transforms[cliOption.name] === void 0) { + transforms[cliOption.name] = Object.create(null); + transforms[cliOption.name]["shouldTransform"] = true; + transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0]; + } + } + } + for (const key of Object.keys(parsed)) { + if (key !== "_") { + const keys = key.split("."); + setDotProp(options, keys, parsed[key]); + setByType(options, transforms); + } + } + return { + args, + options + }; + } + runMatchedCommand() { + const {args, options, matchedCommand: command} = this; + if (!command || !command.commandAction) + return; + command.checkUnknownOptions(); + command.checkOptionValue(); + command.checkRequiredArgs(); + const actionArgs = []; + command.args.forEach((arg, index) => { + if (arg.variadic) { + actionArgs.push(args.slice(index)); + } else { + actionArgs.push(args[index]); + } + }); + actionArgs.push(options); + return command.commandAction.apply(this, actionArgs); + } +} + +const cac = (name = "") => new CAC(name); + +exports.CAC = CAC; +exports.Command = Command; +exports.cac = cac; +exports.default = cac; diff --git a/node_modules/cac/dist/index.mjs b/node_modules/cac/dist/index.mjs new file mode 100644 index 0000000000..7c1c4440c6 --- /dev/null +++ b/node_modules/cac/dist/index.mjs @@ -0,0 +1,617 @@ +import { EventEmitter } from 'events'; + +function toArr(any) { + return any == null ? [] : Array.isArray(any) ? any : [any]; +} + +function toVal(out, key, val, opts) { + var x, old=out[key], nxt=( + !!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val)) + : typeof val === 'boolean' ? val + : !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val)) + : (x = +val,x * 0 === 0) ? x : val + ); + out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]); +} + +function mri2 (args, opts) { + args = args || []; + opts = opts || {}; + + var k, arr, arg, name, val, out={ _:[] }; + var i=0, j=0, idx=0, len=args.length; + + const alibi = opts.alias !== void 0; + const strict = opts.unknown !== void 0; + const defaults = opts.default !== void 0; + + opts.alias = opts.alias || {}; + opts.string = toArr(opts.string); + opts.boolean = toArr(opts.boolean); + + if (alibi) { + for (k in opts.alias) { + arr = opts.alias[k] = toArr(opts.alias[k]); + for (i=0; i < arr.length; i++) { + (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1); + } + } + } + + for (i=opts.boolean.length; i-- > 0;) { + arr = opts.alias[opts.boolean[i]] || []; + for (j=arr.length; j-- > 0;) opts.boolean.push(arr[j]); + } + + for (i=opts.string.length; i-- > 0;) { + arr = opts.alias[opts.string[i]] || []; + for (j=arr.length; j-- > 0;) opts.string.push(arr[j]); + } + + if (defaults) { + for (k in opts.default) { + name = typeof opts.default[k]; + arr = opts.alias[k] = opts.alias[k] || []; + if (opts[name] !== void 0) { + opts[name].push(k); + for (i=0; i < arr.length; i++) { + opts[name].push(arr[i]); + } + } + } + } + + const keys = strict ? Object.keys(opts.alias) : []; + + for (i=0; i < len; i++) { + arg = args[i]; + + if (arg === '--') { + out._ = out._.concat(args.slice(++i)); + break; + } + + for (j=0; j < arg.length; j++) { + if (arg.charCodeAt(j) !== 45) break; // "-" + } + + if (j === 0) { + out._.push(arg); + } else if (arg.substring(j, j + 3) === 'no-') { + name = arg.substring(j + 3); + if (strict && !~keys.indexOf(name)) { + return opts.unknown(arg); + } + out[name] = false; + } else { + for (idx=j+1; idx < arg.length; idx++) { + if (arg.charCodeAt(idx) === 61) break; // "=" + } + + name = arg.substring(j, idx); + val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]); + arr = (j === 2 ? [name] : name); + + for (idx=0; idx < arr.length; idx++) { + name = arr[idx]; + if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name); + toVal(out, name, (idx + 1 < arr.length) || val, opts); + } + } + } + + if (defaults) { + for (k in opts.default) { + if (out[k] === void 0) { + out[k] = opts.default[k]; + } + } + } + + if (alibi) { + for (k in out) { + arr = opts.alias[k] || []; + while (arr.length > 0) { + out[arr.shift()] = out[k]; + } + } + } + + return out; +} + +const removeBrackets = (v) => v.replace(/[<[].+/, "").trim(); +const findAllBrackets = (v) => { + const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g; + const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g; + const res = []; + const parse = (match) => { + let variadic = false; + let value = match[1]; + if (value.startsWith("...")) { + value = value.slice(3); + variadic = true; + } + return { + required: match[0].startsWith("<"), + value, + variadic + }; + }; + let angledMatch; + while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(angledMatch)); + } + let squareMatch; + while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(squareMatch)); + } + return res; +}; +const getMriOptions = (options) => { + const result = {alias: {}, boolean: []}; + for (const [index, option] of options.entries()) { + if (option.names.length > 1) { + result.alias[option.names[0]] = option.names.slice(1); + } + if (option.isBoolean) { + if (option.negated) { + const hasStringTypeOption = options.some((o, i) => { + return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean"; + }); + if (!hasStringTypeOption) { + result.boolean.push(option.names[0]); + } + } else { + result.boolean.push(option.names[0]); + } + } + } + return result; +}; +const findLongest = (arr) => { + return arr.sort((a, b) => { + return a.length > b.length ? -1 : 1; + })[0]; +}; +const padRight = (str, length) => { + return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`; +}; +const camelcase = (input) => { + return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => { + return p1 + p2.toUpperCase(); + }); +}; +const setDotProp = (obj, keys, val) => { + let i = 0; + let length = keys.length; + let t = obj; + let x; + for (; i < length; ++i) { + x = t[keys[i]]; + t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : []; + } +}; +const setByType = (obj, transforms) => { + for (const key of Object.keys(transforms)) { + const transform = transforms[key]; + if (transform.shouldTransform) { + obj[key] = Array.prototype.concat.call([], obj[key]); + if (typeof transform.transformFunction === "function") { + obj[key] = obj[key].map(transform.transformFunction); + } + } + } +}; +const getFileName = (input) => { + const m = /([^\\\/]+)$/.exec(input); + return m ? m[1] : ""; +}; +const camelcaseOptionName = (name) => { + return name.split(".").map((v, i) => { + return i === 0 ? camelcase(v) : v; + }).join("."); +}; +class CACError extends Error { + constructor(message) { + super(message); + this.name = this.constructor.name; + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = new Error(message).stack; + } + } +} + +class Option { + constructor(rawName, description, config) { + this.rawName = rawName; + this.description = description; + this.config = Object.assign({}, config); + rawName = rawName.replace(/\.\*/g, ""); + this.negated = false; + this.names = removeBrackets(rawName).split(",").map((v) => { + let name = v.trim().replace(/^-{1,2}/, ""); + if (name.startsWith("no-")) { + this.negated = true; + name = name.replace(/^no-/, ""); + } + return camelcaseOptionName(name); + }).sort((a, b) => a.length > b.length ? 1 : -1); + this.name = this.names[this.names.length - 1]; + if (this.negated && this.config.default == null) { + this.config.default = true; + } + if (rawName.includes("<")) { + this.required = true; + } else if (rawName.includes("[")) { + this.required = false; + } else { + this.isBoolean = true; + } + } +} + +const processArgs = process.argv; +const platformInfo = `${process.platform}-${process.arch} node-${process.version}`; + +class Command { + constructor(rawName, description, config = {}, cli) { + this.rawName = rawName; + this.description = description; + this.config = config; + this.cli = cli; + this.options = []; + this.aliasNames = []; + this.name = removeBrackets(rawName); + this.args = findAllBrackets(rawName); + this.examples = []; + } + usage(text) { + this.usageText = text; + return this; + } + allowUnknownOptions() { + this.config.allowUnknownOptions = true; + return this; + } + ignoreOptionDefaultValue() { + this.config.ignoreOptionDefaultValue = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.versionNumber = version; + this.option(customFlags, "Display version number"); + return this; + } + example(example) { + this.examples.push(example); + return this; + } + option(rawName, description, config) { + const option = new Option(rawName, description, config); + this.options.push(option); + return this; + } + alias(name) { + this.aliasNames.push(name); + return this; + } + action(callback) { + this.commandAction = callback; + return this; + } + isMatched(name) { + return this.name === name || this.aliasNames.includes(name); + } + get isDefaultCommand() { + return this.name === "" || this.aliasNames.includes("!"); + } + get isGlobalCommand() { + return this instanceof GlobalCommand; + } + hasOption(name) { + name = name.split(".")[0]; + return this.options.find((option) => { + return option.names.includes(name); + }); + } + outputHelp() { + const {name, commands} = this.cli; + const { + versionNumber, + options: globalOptions, + helpCallback + } = this.cli.globalCommand; + let sections = [ + { + body: `${name}${versionNumber ? `/${versionNumber}` : ""}` + } + ]; + sections.push({ + title: "Usage", + body: ` $ ${name} ${this.usageText || this.rawName}` + }); + const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0; + if (showCommands) { + const longestCommandName = findLongest(commands.map((command) => command.rawName)); + sections.push({ + title: "Commands", + body: commands.map((command) => { + return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`; + }).join("\n") + }); + sections.push({ + title: `For more info, run any command with the \`--help\` flag`, + body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join("\n") + }); + } + let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []]; + if (!this.isGlobalCommand && !this.isDefaultCommand) { + options = options.filter((option) => option.name !== "version"); + } + if (options.length > 0) { + const longestOptionName = findLongest(options.map((option) => option.rawName)); + sections.push({ + title: "Options", + body: options.map((option) => { + return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? "" : `(default: ${option.config.default})`}`; + }).join("\n") + }); + } + if (this.examples.length > 0) { + sections.push({ + title: "Examples", + body: this.examples.map((example) => { + if (typeof example === "function") { + return example(name); + } + return example; + }).join("\n") + }); + } + if (helpCallback) { + sections = helpCallback(sections) || sections; + } + console.log(sections.map((section) => { + return section.title ? `${section.title}: +${section.body}` : section.body; + }).join("\n\n")); + } + outputVersion() { + const {name} = this.cli; + const {versionNumber} = this.cli.globalCommand; + if (versionNumber) { + console.log(`${name}/${versionNumber} ${platformInfo}`); + } + } + checkRequiredArgs() { + const minimalArgsCount = this.args.filter((arg) => arg.required).length; + if (this.cli.args.length < minimalArgsCount) { + throw new CACError(`missing required args for command \`${this.rawName}\``); + } + } + checkUnknownOptions() { + const {options, globalCommand} = this.cli; + if (!this.config.allowUnknownOptions) { + for (const name of Object.keys(options)) { + if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) { + throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``); + } + } + } + } + checkOptionValue() { + const {options: parsedOptions, globalCommand} = this.cli; + const options = [...globalCommand.options, ...this.options]; + for (const option of options) { + const value = parsedOptions[option.name.split(".")[0]]; + if (option.required) { + const hasNegated = options.some((o) => o.negated && o.names.includes(option.name)); + if (value === true || value === false && !hasNegated) { + throw new CACError(`option \`${option.rawName}\` value is missing`); + } + } + } + } +} +class GlobalCommand extends Command { + constructor(cli) { + super("@@global@@", "", {}, cli); + } +} + +var __assign = Object.assign; +class CAC extends EventEmitter { + constructor(name = "") { + super(); + this.name = name; + this.commands = []; + this.rawArgs = []; + this.args = []; + this.options = {}; + this.globalCommand = new GlobalCommand(this); + this.globalCommand.usage(" [options]"); + } + usage(text) { + this.globalCommand.usage(text); + return this; + } + command(rawName, description, config) { + const command = new Command(rawName, description || "", config, this); + command.globalCommand = this.globalCommand; + this.commands.push(command); + return command; + } + option(rawName, description, config) { + this.globalCommand.option(rawName, description, config); + return this; + } + help(callback) { + this.globalCommand.option("-h, --help", "Display this message"); + this.globalCommand.helpCallback = callback; + this.showHelpOnExit = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.globalCommand.version(version, customFlags); + this.showVersionOnExit = true; + return this; + } + example(example) { + this.globalCommand.example(example); + return this; + } + outputHelp() { + if (this.matchedCommand) { + this.matchedCommand.outputHelp(); + } else { + this.globalCommand.outputHelp(); + } + } + outputVersion() { + this.globalCommand.outputVersion(); + } + setParsedInfo({args, options}, matchedCommand, matchedCommandName) { + this.args = args; + this.options = options; + if (matchedCommand) { + this.matchedCommand = matchedCommand; + } + if (matchedCommandName) { + this.matchedCommandName = matchedCommandName; + } + return this; + } + unsetMatchedCommand() { + this.matchedCommand = void 0; + this.matchedCommandName = void 0; + } + parse(argv = processArgs, { + run = true + } = {}) { + this.rawArgs = argv; + if (!this.name) { + this.name = argv[1] ? getFileName(argv[1]) : "cli"; + } + let shouldParse = true; + for (const command of this.commands) { + const parsed = this.mri(argv.slice(2), command); + const commandName = parsed.args[0]; + if (command.isMatched(commandName)) { + shouldParse = false; + const parsedInfo = __assign(__assign({}, parsed), { + args: parsed.args.slice(1) + }); + this.setParsedInfo(parsedInfo, command, commandName); + this.emit(`command:${commandName}`, command); + } + } + if (shouldParse) { + for (const command of this.commands) { + if (command.name === "") { + shouldParse = false; + const parsed = this.mri(argv.slice(2), command); + this.setParsedInfo(parsed, command); + this.emit(`command:!`, command); + } + } + } + if (shouldParse) { + const parsed = this.mri(argv.slice(2)); + this.setParsedInfo(parsed); + } + if (this.options.help && this.showHelpOnExit) { + this.outputHelp(); + run = false; + this.unsetMatchedCommand(); + } + if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) { + this.outputVersion(); + run = false; + this.unsetMatchedCommand(); + } + const parsedArgv = {args: this.args, options: this.options}; + if (run) { + this.runMatchedCommand(); + } + if (!this.matchedCommand && this.args[0]) { + this.emit("command:*"); + } + return parsedArgv; + } + mri(argv, command) { + const cliOptions = [ + ...this.globalCommand.options, + ...command ? command.options : [] + ]; + const mriOptions = getMriOptions(cliOptions); + let argsAfterDoubleDashes = []; + const doubleDashesIndex = argv.indexOf("--"); + if (doubleDashesIndex > -1) { + argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1); + argv = argv.slice(0, doubleDashesIndex); + } + let parsed = mri2(argv, mriOptions); + parsed = Object.keys(parsed).reduce((res, name) => { + return __assign(__assign({}, res), { + [camelcaseOptionName(name)]: parsed[name] + }); + }, {_: []}); + const args = parsed._; + const options = { + "--": argsAfterDoubleDashes + }; + const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue; + let transforms = Object.create(null); + for (const cliOption of cliOptions) { + if (!ignoreDefault && cliOption.config.default !== void 0) { + for (const name of cliOption.names) { + options[name] = cliOption.config.default; + } + } + if (Array.isArray(cliOption.config.type)) { + if (transforms[cliOption.name] === void 0) { + transforms[cliOption.name] = Object.create(null); + transforms[cliOption.name]["shouldTransform"] = true; + transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0]; + } + } + } + for (const key of Object.keys(parsed)) { + if (key !== "_") { + const keys = key.split("."); + setDotProp(options, keys, parsed[key]); + setByType(options, transforms); + } + } + return { + args, + options + }; + } + runMatchedCommand() { + const {args, options, matchedCommand: command} = this; + if (!command || !command.commandAction) + return; + command.checkUnknownOptions(); + command.checkOptionValue(); + command.checkRequiredArgs(); + const actionArgs = []; + command.args.forEach((arg, index) => { + if (arg.variadic) { + actionArgs.push(args.slice(index)); + } else { + actionArgs.push(args[index]); + } + }); + actionArgs.push(options); + return command.commandAction.apply(this, actionArgs); + } +} + +const cac = (name = "") => new CAC(name); + +export default cac; +export { CAC, Command, cac }; diff --git a/node_modules/cac/index-compat.js b/node_modules/cac/index-compat.js new file mode 100644 index 0000000000..6b8a78d3a5 --- /dev/null +++ b/node_modules/cac/index-compat.js @@ -0,0 +1,11 @@ +const { cac, CAC, Command } = require('./dist/index') + +// For backwards compatibility +module.exports = cac + +Object.assign(module.exports, { + default: cac, + cac, + CAC, + Command, +}) diff --git a/node_modules/cac/mod.js b/node_modules/cac/mod.js new file mode 100644 index 0000000000..9d0e8943d5 --- /dev/null +++ b/node_modules/cac/mod.js @@ -0,0 +1,2 @@ +// Deno users should use mod.ts instead +export * from './deno/index.ts' \ No newline at end of file diff --git a/node_modules/cac/mod.ts b/node_modules/cac/mod.ts new file mode 100644 index 0000000000..8fac7d9f05 --- /dev/null +++ b/node_modules/cac/mod.ts @@ -0,0 +1,2 @@ +// For Deno +export * from './deno/index.ts' diff --git a/node_modules/cac/package.json b/node_modules/cac/package.json new file mode 100644 index 0000000000..2306bf35bb --- /dev/null +++ b/node_modules/cac/package.json @@ -0,0 +1,104 @@ +{ + "name": "cac", + "version": "6.7.14", + "description": "Simple yet powerful framework for building command-line apps.", + "repository": { + "url": "egoist/cac", + "type": "git" + }, + "main": "index-compat.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./index-compat.js" + }, + "./package.json": "./package.json", + "./*": "./*" + }, + "files": [ + "dist", + "!**/__test__/**", + "/mod.js", + "/mod.ts", + "/deno", + "/index-compat.js" + ], + "scripts": { + "test": "jest", + "test:cov": "jest --coverage", + "build:deno": "node -r sucrase/register scripts/build-deno.ts", + "build:node": "rollup -c", + "build": "yarn build:deno && yarn build:node", + "toc": "markdown-toc -i README.md", + "prepublishOnly": "npm run build && cp mod.js mod.mjs", + "docs:api": "typedoc --out api-doc --readme none --exclude \"**/__test__/**\" --theme minimal" + }, + "author": "egoist <0x142857@gmail.com>", + "license": "MIT", + "devDependencies": { + "@babel/core": "^7.12.10", + "@babel/plugin-syntax-typescript": "^7.12.1", + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.0.0", + "@types/fs-extra": "^9.0.5", + "@types/jest": "^26.0.19", + "@types/mri": "^1.1.0", + "cz-conventional-changelog": "^2.1.0", + "esbuild": "^0.8.21", + "eslint-config-rem": "^3.0.0", + "execa": "^5.0.0", + "fs-extra": "^9.0.1", + "globby": "^11.0.1", + "husky": "^1.2.0", + "jest": "^24.9.0", + "lint-staged": "^8.1.0", + "markdown-toc": "^1.2.0", + "mri": "^1.1.6", + "prettier": "^2.2.1", + "rollup": "^2.34.2", + "rollup-plugin-dts": "^2.0.1", + "rollup-plugin-esbuild": "^2.6.1", + "semantic-release": "^17.3.0", + "sucrase": "^3.16.0", + "ts-jest": "^26.4.4", + "ts-node": "^9.1.1", + "typedoc": "^0.19.2", + "typescript": "^4.1.2" + }, + "engines": { + "node": ">=8" + }, + "release": { + "branch": "master" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + }, + "lint-staged": { + "linters": { + "*.{js,json,ts}": [ + "prettier --write", + "git add" + ], + "*.md": [ + "markdown-toc -i", + "prettier --write", + "git add" + ] + }, + "ignore": [ + "dist/**", + "mod.js" + ] + }, + "husky": { + "hooks": { + "pre-commit": "npm t && lint-staged" + } + } +} diff --git a/node_modules/chai/LICENSE b/node_modules/chai/LICENSE new file mode 100644 index 0000000000..eedbe238ac --- /dev/null +++ b/node_modules/chai/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Chai.js Assertion Library + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/chai/README.md b/node_modules/chai/README.md new file mode 100644 index 0000000000..0a5c220e4e --- /dev/null +++ b/node_modules/chai/README.md @@ -0,0 +1,162 @@ +

+ + ChaiJS + +
+ chai +

+ +

+ Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework. +

+ +

+ + downloads:? + + + node:? + +
+ + Join the Slack chat + + + Join the Gitter chat + + + OpenCollective Backers + +

+ +For more information or to download plugins, view the [documentation](http://chaijs.com). + +## What is Chai? + +Chai is an _assertion library_, similar to Node's built-in `assert`. It makes testing much easier by giving you lots of assertions you can run against your code. + +## Installation + +### Node.js + +`chai` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install --save-dev chai + +### Browsers + +You can also use it within the browser; install via npm and use the `chai.js` file found within the download. For example: + +```html + +``` + +## Usage + +Import the library in your code, and then pick one of the styles you'd like to use - either `assert`, `expect` or `should`: + +```js +import { assert } from 'chai'; // Using Assert style +import { expect } from 'chai'; // Using Expect style +import { should } from 'chai'; // Using Should style +``` + +### Register the chai testing style globally + +```js +import 'chai/register-assert'; // Using Assert style +import 'chai/register-expect'; // Using Expect style +import 'chai/register-should'; // Using Should style +``` + +### Import assertion styles as local variables + +```js +import { assert } from 'chai'; // Using Assert style +import { expect } from 'chai'; // Using Expect style +import { should } from 'chai'; // Using Should style +should(); // Modifies `Object.prototype` + +import { expect, use } from 'chai'; // Creates local variables `expect` and `use`; useful for plugin use +``` + +### Usage with Mocha + +```bash +mocha spec.js --require chai/register-assert.js # Using Assert style +mocha spec.js --require chai/register-expect.js # Using Expect style +mocha spec.js --require chai/register-should.js # Using Should style +``` + +[Read more about these styles in our docs](http://chaijs.com/guide/styles/). + +## Plugins + +Chai offers a robust Plugin architecture for extending Chai's assertions and interfaces. + +- Need a plugin? View the [official plugin list](http://chaijs.com/plugins). +- Want to build a plugin? Read the [plugin api documentation](http://chaijs.com/guide/plugins/). +- Have a plugin and want it listed? Simply add the following keywords to your package.json: + - `chai-plugin` + - `browser` if your plugin works in the browser as well as Node.js + - `browser-only` if your plugin does not work with Node.js + +### Related Projects + +- [chaijs / chai-docs](https://github.com/chaijs/chai-docs): The chaijs.com website source code. +- [chaijs / assertion-error](https://github.com/chaijs/assertion-error): Custom `Error` constructor thrown upon an assertion failing. +- [chaijs / deep-eql](https://github.com/chaijs/deep-eql): Improved deep equality testing for Node.js and the browser. +- [chaijs / check-error](https://github.com/chaijs/check-error): Error comparison and information related utility for Node.js and the browser. +- [chaijs / loupe](https://github.com/chaijs/loupe): Inspect utility for Node.js and browsers. +- [chaijs / pathval](https://github.com/chaijs/pathval): Object value retrieval given a string path. + +### Contributing + +Thank you very much for considering to contribute! + +Please make sure you follow our [Code Of Conduct](https://github.com/chaijs/chai/blob/master/CODE_OF_CONDUCT.md) and we also strongly recommend reading our [Contributing Guide](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md). + +Here are a few issues other contributors frequently ran into when opening pull requests: + +- Please do not commit changes to the `chai.js` build. We do it once per release. +- Before pushing your commits, please make sure you [rebase](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md#pull-requests) them. + +### Contributors + +Please see the full +[Contributors Graph](https://github.com/chaijs/chai/graphs/contributors) for our +list of contributors. + +### Core Contributors + +Feel free to reach out to any of the core contributors with your questions or +concerns. We will do our best to respond in a timely manner. + +[![Keith Cirkel](https://avatars3.githubusercontent.com/u/118266?v=3&s=50)](https://github.com/keithamus) +[![James Garbutt](https://avatars3.githubusercontent.com/u/5677153?v=3&s=50)](https://github.com/43081j) +[![Kristján Oddsson](https://avatars3.githubusercontent.com/u/318208?v=3&s=50)](https://github.com/koddsson) + +### Core Contributor Alumni + +This project would not be what it is without the contributions from our prior +core contributors, for whom we are forever grateful: + +[![Jake Luer](https://avatars3.githubusercontent.com/u/58988?v=3&s=50)](https://github.com/logicalparadox) +[![Veselin Todorov](https://avatars3.githubusercontent.com/u/330048?v=3&s=50)](https://github.com/vesln) +[![Lucas Fernandes da Costa](https://avatars3.githubusercontent.com/u/6868147?v=3&s=50)](https://github.com/lucasfcosta) +[![Grant Snodgrass](https://avatars3.githubusercontent.com/u/17260989?v=3&s=50)](https://github.com/meeber) diff --git a/node_modules/chai/chai.js b/node_modules/chai/chai.js new file mode 100644 index 0000000000..ee01cc9bd3 --- /dev/null +++ b/node_modules/chai/chai.js @@ -0,0 +1 @@ +export * from './index.js'; diff --git a/node_modules/chai/index.js b/node_modules/chai/index.js new file mode 100644 index 0000000000..d492d453ff --- /dev/null +++ b/node_modules/chai/index.js @@ -0,0 +1,4381 @@ +var __defProp = Object.defineProperty; +var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; + +// lib/chai/utils/index.js +var utils_exports = {}; +__export(utils_exports, { + addChainableMethod: () => addChainableMethod, + addLengthGuard: () => addLengthGuard, + addMethod: () => addMethod, + addProperty: () => addProperty, + checkError: () => check_error_exports, + compareByInspect: () => compareByInspect, + eql: () => deep_eql_default, + expectTypes: () => expectTypes, + flag: () => flag, + getActual: () => getActual, + getMessage: () => getMessage2, + getName: () => getName, + getOperator: () => getOperator, + getOwnEnumerableProperties: () => getOwnEnumerableProperties, + getOwnEnumerablePropertySymbols: () => getOwnEnumerablePropertySymbols, + getPathInfo: () => getPathInfo, + hasProperty: () => hasProperty, + inspect: () => inspect2, + isNaN: () => isNaN2, + isNumeric: () => isNumeric, + isProxyEnabled: () => isProxyEnabled, + isRegExp: () => isRegExp2, + objDisplay: () => objDisplay, + overwriteChainableMethod: () => overwriteChainableMethod, + overwriteMethod: () => overwriteMethod, + overwriteProperty: () => overwriteProperty, + proxify: () => proxify, + test: () => test, + transferFlags: () => transferFlags, + type: () => type +}); + +// node_modules/check-error/index.js +var check_error_exports = {}; +__export(check_error_exports, { + compatibleConstructor: () => compatibleConstructor, + compatibleInstance: () => compatibleInstance, + compatibleMessage: () => compatibleMessage, + getConstructorName: () => getConstructorName, + getMessage: () => getMessage +}); +function isErrorInstance(obj) { + return obj instanceof Error || Object.prototype.toString.call(obj) === "[object Error]"; +} +__name(isErrorInstance, "isErrorInstance"); +function isRegExp(obj) { + return Object.prototype.toString.call(obj) === "[object RegExp]"; +} +__name(isRegExp, "isRegExp"); +function compatibleInstance(thrown, errorLike) { + return isErrorInstance(errorLike) && thrown === errorLike; +} +__name(compatibleInstance, "compatibleInstance"); +function compatibleConstructor(thrown, errorLike) { + if (isErrorInstance(errorLike)) { + return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; + } else if ((typeof errorLike === "object" || typeof errorLike === "function") && errorLike.prototype) { + return thrown.constructor === errorLike || thrown instanceof errorLike; + } + return false; +} +__name(compatibleConstructor, "compatibleConstructor"); +function compatibleMessage(thrown, errMatcher) { + const comparisonString = typeof thrown === "string" ? thrown : thrown.message; + if (isRegExp(errMatcher)) { + return errMatcher.test(comparisonString); + } else if (typeof errMatcher === "string") { + return comparisonString.indexOf(errMatcher) !== -1; + } + return false; +} +__name(compatibleMessage, "compatibleMessage"); +function getConstructorName(errorLike) { + let constructorName = errorLike; + if (isErrorInstance(errorLike)) { + constructorName = errorLike.constructor.name; + } else if (typeof errorLike === "function") { + constructorName = errorLike.name; + if (constructorName === "") { + const newConstructorName = new errorLike().name; + constructorName = newConstructorName || constructorName; + } + } + return constructorName; +} +__name(getConstructorName, "getConstructorName"); +function getMessage(errorLike) { + let msg = ""; + if (errorLike && errorLike.message) { + msg = errorLike.message; + } else if (typeof errorLike === "string") { + msg = errorLike; + } + return msg; +} +__name(getMessage, "getMessage"); + +// lib/chai/utils/flag.js +function flag(obj, key, value) { + let flags = obj.__flags || (obj.__flags = /* @__PURE__ */ Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +} +__name(flag, "flag"); + +// lib/chai/utils/test.js +function test(obj, args) { + let negate = flag(obj, "negate"), expr = args[0]; + return negate ? !expr : expr; +} +__name(test, "test"); + +// lib/chai/utils/type-detect.js +function type(obj) { + if (typeof obj === "undefined") { + return "undefined"; + } + if (obj === null) { + return "null"; + } + const stringTag = obj[Symbol.toStringTag]; + if (typeof stringTag === "string") { + return stringTag; + } + const type3 = Object.prototype.toString.call(obj).slice(8, -1); + return type3; +} +__name(type, "type"); + +// node_modules/assertion-error/index.js +var canElideFrames = "captureStackTrace" in Error; +var AssertionError = class _AssertionError extends Error { + static { + __name(this, "AssertionError"); + } + message; + get name() { + return "AssertionError"; + } + get ok() { + return false; + } + constructor(message = "Unspecified AssertionError", props, ssf) { + super(message); + this.message = message; + if (canElideFrames) { + Error.captureStackTrace(this, ssf || _AssertionError); + } + for (const key in props) { + if (!(key in this)) { + this[key] = props[key]; + } + } + } + toJSON(stack) { + return { + ...this, + name: this.name, + message: this.message, + ok: false, + stack: stack !== false ? this.stack : void 0 + }; + } +}; + +// lib/chai/utils/expectTypes.js +function expectTypes(obj, types) { + let flagMsg = flag(obj, "message"); + let ssfi = flag(obj, "ssfi"); + flagMsg = flagMsg ? flagMsg + ": " : ""; + obj = flag(obj, "object"); + types = types.map(function(t) { + return t.toLowerCase(); + }); + types.sort(); + let str = types.map(function(t, index) { + let art = ~["a", "e", "i", "o", "u"].indexOf(t.charAt(0)) ? "an" : "a"; + let or = types.length > 1 && index === types.length - 1 ? "or " : ""; + return or + art + " " + t; + }).join(", "); + let objType = type(obj).toLowerCase(); + if (!types.some(function(expected) { + return objType === expected; + })) { + throw new AssertionError( + flagMsg + "object tested must be " + str + ", but " + objType + " given", + void 0, + ssfi + ); + } +} +__name(expectTypes, "expectTypes"); + +// lib/chai/utils/getActual.js +function getActual(obj, args) { + return args.length > 4 ? args[4] : obj._obj; +} +__name(getActual, "getActual"); + +// node_modules/loupe/lib/helpers.js +var ansiColors = { + bold: ["1", "22"], + dim: ["2", "22"], + italic: ["3", "23"], + underline: ["4", "24"], + // 5 & 6 are blinking + inverse: ["7", "27"], + hidden: ["8", "28"], + strike: ["9", "29"], + // 10-20 are fonts + // 21-29 are resets for 1-9 + black: ["30", "39"], + red: ["31", "39"], + green: ["32", "39"], + yellow: ["33", "39"], + blue: ["34", "39"], + magenta: ["35", "39"], + cyan: ["36", "39"], + white: ["37", "39"], + brightblack: ["30;1", "39"], + brightred: ["31;1", "39"], + brightgreen: ["32;1", "39"], + brightyellow: ["33;1", "39"], + brightblue: ["34;1", "39"], + brightmagenta: ["35;1", "39"], + brightcyan: ["36;1", "39"], + brightwhite: ["37;1", "39"], + grey: ["90", "39"] +}; +var styles = { + special: "cyan", + number: "yellow", + bigint: "yellow", + boolean: "yellow", + undefined: "grey", + null: "bold", + string: "green", + symbol: "green", + date: "magenta", + regexp: "red" +}; +var truncator = "\u2026"; +function colorise(value, styleType) { + const color = ansiColors[styles[styleType]] || ansiColors[styleType] || ""; + if (!color) { + return String(value); + } + return `\x1B[${color[0]}m${String(value)}\x1B[${color[1]}m`; +} +__name(colorise, "colorise"); +function normaliseOptions({ + showHidden = false, + depth = 2, + colors = false, + customInspect = true, + showProxy = false, + maxArrayLength = Infinity, + breakLength = Infinity, + seen = [], + // eslint-disable-next-line no-shadow + truncate: truncate2 = Infinity, + stylize = String +} = {}, inspect3) { + const options = { + showHidden: Boolean(showHidden), + depth: Number(depth), + colors: Boolean(colors), + customInspect: Boolean(customInspect), + showProxy: Boolean(showProxy), + maxArrayLength: Number(maxArrayLength), + breakLength: Number(breakLength), + truncate: Number(truncate2), + seen, + inspect: inspect3, + stylize + }; + if (options.colors) { + options.stylize = colorise; + } + return options; +} +__name(normaliseOptions, "normaliseOptions"); +function isHighSurrogate(char) { + return char >= "\uD800" && char <= "\uDBFF"; +} +__name(isHighSurrogate, "isHighSurrogate"); +function truncate(string, length, tail = truncator) { + string = String(string); + const tailLength = tail.length; + const stringLength = string.length; + if (tailLength > length && stringLength > tailLength) { + return tail; + } + if (stringLength > length && stringLength > tailLength) { + let end = length - tailLength; + if (end > 0 && isHighSurrogate(string[end - 1])) { + end = end - 1; + } + return `${string.slice(0, end)}${tail}`; + } + return string; +} +__name(truncate, "truncate"); +function inspectList(list, options, inspectItem, separator = ", ") { + inspectItem = inspectItem || options.inspect; + const size = list.length; + if (size === 0) + return ""; + const originalLength = options.truncate; + let output = ""; + let peek = ""; + let truncated = ""; + for (let i = 0; i < size; i += 1) { + const last = i + 1 === list.length; + const secondToLast = i + 2 === list.length; + truncated = `${truncator}(${list.length - i})`; + const value = list[i]; + options.truncate = originalLength - output.length - (last ? 0 : separator.length); + const string = peek || inspectItem(value, options) + (last ? "" : separator); + const nextLength = output.length + string.length; + const truncatedLength = nextLength + truncated.length; + if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) { + break; + } + if (!last && !secondToLast && truncatedLength > originalLength) { + break; + } + peek = last ? "" : inspectItem(list[i + 1], options) + (secondToLast ? "" : separator); + if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) { + break; + } + output += string; + if (!last && !secondToLast && nextLength + peek.length >= originalLength) { + truncated = `${truncator}(${list.length - i - 1})`; + break; + } + truncated = ""; + } + return `${output}${truncated}`; +} +__name(inspectList, "inspectList"); +function quoteComplexKey(key) { + if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) { + return key; + } + return JSON.stringify(key).replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'"); +} +__name(quoteComplexKey, "quoteComplexKey"); +function inspectProperty([key, value], options) { + options.truncate -= 2; + if (typeof key === "string") { + key = quoteComplexKey(key); + } else if (typeof key !== "number") { + key = `[${options.inspect(key, options)}]`; + } + options.truncate -= key.length; + value = options.inspect(value, options); + return `${key}: ${value}`; +} +__name(inspectProperty, "inspectProperty"); + +// node_modules/loupe/lib/array.js +function inspectArray(array, options) { + const nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) + return "[]"; + options.truncate -= 4; + const listContents = inspectList(array, options); + options.truncate -= listContents.length; + let propertyContents = ""; + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map((key) => [key, array[key]]), options, inspectProperty); + } + return `[ ${listContents}${propertyContents ? `, ${propertyContents}` : ""} ]`; +} +__name(inspectArray, "inspectArray"); + +// node_modules/loupe/lib/typedarray.js +var getArrayName = /* @__PURE__ */ __name((array) => { + if (typeof Buffer === "function" && array instanceof Buffer) { + return "Buffer"; + } + if (array[Symbol.toStringTag]) { + return array[Symbol.toStringTag]; + } + return array.constructor.name; +}, "getArrayName"); +function inspectTypedArray(array, options) { + const name = getArrayName(array); + options.truncate -= name.length + 4; + const nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) + return `${name}[]`; + let output = ""; + for (let i = 0; i < array.length; i++) { + const string = `${options.stylize(truncate(array[i], options.truncate), "number")}${i === array.length - 1 ? "" : ", "}`; + options.truncate -= string.length; + if (array[i] !== array.length && options.truncate <= 3) { + output += `${truncator}(${array.length - array[i] + 1})`; + break; + } + output += string; + } + let propertyContents = ""; + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map((key) => [key, array[key]]), options, inspectProperty); + } + return `${name}[ ${output}${propertyContents ? `, ${propertyContents}` : ""} ]`; +} +__name(inspectTypedArray, "inspectTypedArray"); + +// node_modules/loupe/lib/date.js +function inspectDate(dateObject, options) { + const stringRepresentation = dateObject.toJSON(); + if (stringRepresentation === null) { + return "Invalid Date"; + } + const split = stringRepresentation.split("T"); + const date = split[0]; + return options.stylize(`${date}T${truncate(split[1], options.truncate - date.length - 1)}`, "date"); +} +__name(inspectDate, "inspectDate"); + +// node_modules/loupe/lib/function.js +function inspectFunction(func, options) { + const functionType = func[Symbol.toStringTag] || "Function"; + const name = func.name; + if (!name) { + return options.stylize(`[${functionType}]`, "special"); + } + return options.stylize(`[${functionType} ${truncate(name, options.truncate - 11)}]`, "special"); +} +__name(inspectFunction, "inspectFunction"); + +// node_modules/loupe/lib/map.js +function inspectMapEntry([key, value], options) { + options.truncate -= 4; + key = options.inspect(key, options); + options.truncate -= key.length; + value = options.inspect(value, options); + return `${key} => ${value}`; +} +__name(inspectMapEntry, "inspectMapEntry"); +function mapToEntries(map) { + const entries = []; + map.forEach((value, key) => { + entries.push([key, value]); + }); + return entries; +} +__name(mapToEntries, "mapToEntries"); +function inspectMap(map, options) { + if (map.size === 0) + return "Map{}"; + options.truncate -= 7; + return `Map{ ${inspectList(mapToEntries(map), options, inspectMapEntry)} }`; +} +__name(inspectMap, "inspectMap"); + +// node_modules/loupe/lib/number.js +var isNaN = Number.isNaN || ((i) => i !== i); +function inspectNumber(number, options) { + if (isNaN(number)) { + return options.stylize("NaN", "number"); + } + if (number === Infinity) { + return options.stylize("Infinity", "number"); + } + if (number === -Infinity) { + return options.stylize("-Infinity", "number"); + } + if (number === 0) { + return options.stylize(1 / number === Infinity ? "+0" : "-0", "number"); + } + return options.stylize(truncate(String(number), options.truncate), "number"); +} +__name(inspectNumber, "inspectNumber"); + +// node_modules/loupe/lib/bigint.js +function inspectBigInt(number, options) { + let nums = truncate(number.toString(), options.truncate - 1); + if (nums !== truncator) + nums += "n"; + return options.stylize(nums, "bigint"); +} +__name(inspectBigInt, "inspectBigInt"); + +// node_modules/loupe/lib/regexp.js +function inspectRegExp(value, options) { + const flags = value.toString().split("/")[2]; + const sourceLength = options.truncate - (2 + flags.length); + const source = value.source; + return options.stylize(`/${truncate(source, sourceLength)}/${flags}`, "regexp"); +} +__name(inspectRegExp, "inspectRegExp"); + +// node_modules/loupe/lib/set.js +function arrayFromSet(set2) { + const values = []; + set2.forEach((value) => { + values.push(value); + }); + return values; +} +__name(arrayFromSet, "arrayFromSet"); +function inspectSet(set2, options) { + if (set2.size === 0) + return "Set{}"; + options.truncate -= 7; + return `Set{ ${inspectList(arrayFromSet(set2), options)} }`; +} +__name(inspectSet, "inspectSet"); + +// node_modules/loupe/lib/string.js +var stringEscapeChars = new RegExp("['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]", "g"); +var escapeCharacters = { + "\b": "\\b", + " ": "\\t", + "\n": "\\n", + "\f": "\\f", + "\r": "\\r", + "'": "\\'", + "\\": "\\\\" +}; +var hex = 16; +var unicodeLength = 4; +function escape(char) { + return escapeCharacters[char] || `\\u${`0000${char.charCodeAt(0).toString(hex)}`.slice(-unicodeLength)}`; +} +__name(escape, "escape"); +function inspectString(string, options) { + if (stringEscapeChars.test(string)) { + string = string.replace(stringEscapeChars, escape); + } + return options.stylize(`'${truncate(string, options.truncate - 2)}'`, "string"); +} +__name(inspectString, "inspectString"); + +// node_modules/loupe/lib/symbol.js +function inspectSymbol(value) { + if ("description" in Symbol.prototype) { + return value.description ? `Symbol(${value.description})` : "Symbol()"; + } + return value.toString(); +} +__name(inspectSymbol, "inspectSymbol"); + +// node_modules/loupe/lib/promise.js +var getPromiseValue = /* @__PURE__ */ __name(() => "Promise{\u2026}", "getPromiseValue"); +var promise_default = getPromiseValue; + +// node_modules/loupe/lib/object.js +function inspectObject(object, options) { + const properties = Object.getOwnPropertyNames(object); + const symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : []; + if (properties.length === 0 && symbols.length === 0) { + return "{}"; + } + options.truncate -= 4; + options.seen = options.seen || []; + if (options.seen.includes(object)) { + return "[Circular]"; + } + options.seen.push(object); + const propertyContents = inspectList(properties.map((key) => [key, object[key]]), options, inspectProperty); + const symbolContents = inspectList(symbols.map((key) => [key, object[key]]), options, inspectProperty); + options.seen.pop(); + let sep = ""; + if (propertyContents && symbolContents) { + sep = ", "; + } + return `{ ${propertyContents}${sep}${symbolContents} }`; +} +__name(inspectObject, "inspectObject"); + +// node_modules/loupe/lib/class.js +var toStringTag = typeof Symbol !== "undefined" && Symbol.toStringTag ? Symbol.toStringTag : false; +function inspectClass(value, options) { + let name = ""; + if (toStringTag && toStringTag in value) { + name = value[toStringTag]; + } + name = name || value.constructor.name; + if (!name || name === "_class") { + name = ""; + } + options.truncate -= name.length; + return `${name}${inspectObject(value, options)}`; +} +__name(inspectClass, "inspectClass"); + +// node_modules/loupe/lib/arguments.js +function inspectArguments(args, options) { + if (args.length === 0) + return "Arguments[]"; + options.truncate -= 13; + return `Arguments[ ${inspectList(args, options)} ]`; +} +__name(inspectArguments, "inspectArguments"); + +// node_modules/loupe/lib/error.js +var errorKeys = [ + "stack", + "line", + "column", + "name", + "message", + "fileName", + "lineNumber", + "columnNumber", + "number", + "description", + "cause" +]; +function inspectObject2(error, options) { + const properties = Object.getOwnPropertyNames(error).filter((key) => errorKeys.indexOf(key) === -1); + const name = error.name; + options.truncate -= name.length; + let message = ""; + if (typeof error.message === "string") { + message = truncate(error.message, options.truncate); + } else { + properties.unshift("message"); + } + message = message ? `: ${message}` : ""; + options.truncate -= message.length + 5; + options.seen = options.seen || []; + if (options.seen.includes(error)) { + return "[Circular]"; + } + options.seen.push(error); + const propertyContents = inspectList(properties.map((key) => [key, error[key]]), options, inspectProperty); + return `${name}${message}${propertyContents ? ` { ${propertyContents} }` : ""}`; +} +__name(inspectObject2, "inspectObject"); + +// node_modules/loupe/lib/html.js +function inspectAttribute([key, value], options) { + options.truncate -= 3; + if (!value) { + return `${options.stylize(String(key), "yellow")}`; + } + return `${options.stylize(String(key), "yellow")}=${options.stylize(`"${value}"`, "string")}`; +} +__name(inspectAttribute, "inspectAttribute"); +function inspectNodeCollection(collection, options) { + return inspectList(collection, options, inspectNode, "\n"); +} +__name(inspectNodeCollection, "inspectNodeCollection"); +function inspectNode(node, options) { + switch (node.nodeType) { + case 1: + return inspectHTML(node, options); + case 3: + return options.inspect(node.data, options); + default: + return options.inspect(node, options); + } +} +__name(inspectNode, "inspectNode"); +function inspectHTML(element, options) { + const properties = element.getAttributeNames(); + const name = element.tagName.toLowerCase(); + const head = options.stylize(`<${name}`, "special"); + const headClose = options.stylize(`>`, "special"); + const tail = options.stylize(``, "special"); + options.truncate -= name.length * 2 + 5; + let propertyContents = ""; + if (properties.length > 0) { + propertyContents += " "; + propertyContents += inspectList(properties.map((key) => [key, element.getAttribute(key)]), options, inspectAttribute, " "); + } + options.truncate -= propertyContents.length; + const truncate2 = options.truncate; + let children = inspectNodeCollection(element.children, options); + if (children && children.length > truncate2) { + children = `${truncator}(${element.children.length})`; + } + return `${head}${propertyContents}${headClose}${children}${tail}`; +} +__name(inspectHTML, "inspectHTML"); + +// node_modules/loupe/lib/index.js +var symbolsSupported = typeof Symbol === "function" && typeof Symbol.for === "function"; +var chaiInspect = symbolsSupported ? Symbol.for("chai/inspect") : "@@chai/inspect"; +var nodeInspect = Symbol.for("nodejs.util.inspect.custom"); +var constructorMap = /* @__PURE__ */ new WeakMap(); +var stringTagMap = {}; +var baseTypesMap = { + undefined: /* @__PURE__ */ __name((value, options) => options.stylize("undefined", "undefined"), "undefined"), + null: /* @__PURE__ */ __name((value, options) => options.stylize("null", "null"), "null"), + boolean: /* @__PURE__ */ __name((value, options) => options.stylize(String(value), "boolean"), "boolean"), + Boolean: /* @__PURE__ */ __name((value, options) => options.stylize(String(value), "boolean"), "Boolean"), + number: inspectNumber, + Number: inspectNumber, + bigint: inspectBigInt, + BigInt: inspectBigInt, + string: inspectString, + String: inspectString, + function: inspectFunction, + Function: inspectFunction, + symbol: inspectSymbol, + // A Symbol polyfill will return `Symbol` not `symbol` from typedetect + Symbol: inspectSymbol, + Array: inspectArray, + Date: inspectDate, + Map: inspectMap, + Set: inspectSet, + RegExp: inspectRegExp, + Promise: promise_default, + // WeakSet, WeakMap are totally opaque to us + WeakSet: /* @__PURE__ */ __name((value, options) => options.stylize("WeakSet{\u2026}", "special"), "WeakSet"), + WeakMap: /* @__PURE__ */ __name((value, options) => options.stylize("WeakMap{\u2026}", "special"), "WeakMap"), + Arguments: inspectArguments, + Int8Array: inspectTypedArray, + Uint8Array: inspectTypedArray, + Uint8ClampedArray: inspectTypedArray, + Int16Array: inspectTypedArray, + Uint16Array: inspectTypedArray, + Int32Array: inspectTypedArray, + Uint32Array: inspectTypedArray, + Float32Array: inspectTypedArray, + Float64Array: inspectTypedArray, + Generator: /* @__PURE__ */ __name(() => "", "Generator"), + DataView: /* @__PURE__ */ __name(() => "", "DataView"), + ArrayBuffer: /* @__PURE__ */ __name(() => "", "ArrayBuffer"), + Error: inspectObject2, + HTMLCollection: inspectNodeCollection, + NodeList: inspectNodeCollection +}; +var inspectCustom = /* @__PURE__ */ __name((value, options, type3) => { + if (chaiInspect in value && typeof value[chaiInspect] === "function") { + return value[chaiInspect](options); + } + if (nodeInspect in value && typeof value[nodeInspect] === "function") { + return value[nodeInspect](options.depth, options); + } + if ("inspect" in value && typeof value.inspect === "function") { + return value.inspect(options.depth, options); + } + if ("constructor" in value && constructorMap.has(value.constructor)) { + return constructorMap.get(value.constructor)(value, options); + } + if (stringTagMap[type3]) { + return stringTagMap[type3](value, options); + } + return ""; +}, "inspectCustom"); +var toString = Object.prototype.toString; +function inspect(value, opts = {}) { + const options = normaliseOptions(opts, inspect); + const { customInspect } = options; + let type3 = value === null ? "null" : typeof value; + if (type3 === "object") { + type3 = toString.call(value).slice(8, -1); + } + if (type3 in baseTypesMap) { + return baseTypesMap[type3](value, options); + } + if (customInspect && value) { + const output = inspectCustom(value, options, type3); + if (output) { + if (typeof output === "string") + return output; + return inspect(output, options); + } + } + const proto = value ? Object.getPrototypeOf(value) : false; + if (proto === Object.prototype || proto === null) { + return inspectObject(value, options); + } + if (value && typeof HTMLElement === "function" && value instanceof HTMLElement) { + return inspectHTML(value, options); + } + if ("constructor" in value) { + if (value.constructor !== Object) { + return inspectClass(value, options); + } + return inspectObject(value, options); + } + if (value === Object(value)) { + return inspectObject(value, options); + } + return options.stylize(String(value), type3); +} +__name(inspect, "inspect"); + +// lib/chai/config.js +var config = { + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {boolean} + * @public + */ + includeStack: false, + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {boolean} + * @public + */ + showDiff: true, + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {number} + * @public + */ + truncateThreshold: 40, + /** + * ### config.useProxy + * + * User configurable property, defines if chai will use a Proxy to throw + * an error when a non-existent property is read, which protects users + * from typos when using property-based assertions. + * + * Set it to false if you want to disable this feature. + * + * chai.config.useProxy = false; // disable use of Proxy + * + * This feature is automatically disabled regardless of this config value + * in environments that don't support proxies. + * + * @param {boolean} + * @public + */ + useProxy: true, + /** + * ### config.proxyExcludedKeys + * + * User configurable property, defines which properties should be ignored + * instead of throwing an error if they do not exist on the assertion. + * This is only applied if the environment Chai is running in supports proxies and + * if the `useProxy` configuration setting is enabled. + * By default, `then` and `inspect` will not throw an error if they do not exist on the + * assertion object because the `.inspect` property is read by `util.inspect` (for example, when + * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. + * + * // By default these keys will not throw an error if they do not exist on the assertion object + * chai.config.proxyExcludedKeys = ['then', 'inspect']; + * + * @param {Array} + * @public + */ + proxyExcludedKeys: ["then", "catch", "inspect", "toJSON"], + /** + * ### config.deepEqual + * + * User configurable property, defines which a custom function to use for deepEqual + * comparisons. + * By default, the function used is the one from the `deep-eql` package without custom comparator. + * + * // use a custom comparator + * chai.config.deepEqual = (expected, actual) => { + * return chai.util.eql(expected, actual, { + * comparator: (expected, actual) => { + * // for non number comparison, use the default behavior + * if(typeof expected !== 'number') return null; + * // allow a difference of 10 between compared numbers + * return typeof actual === 'number' && Math.abs(actual - expected) < 10 + * } + * }) + * }; + * + * @param {Function} + * @public + */ + deepEqual: null +}; + +// lib/chai/utils/inspect.js +function inspect2(obj, showHidden, depth, colors) { + let options = { + colors, + depth: typeof depth === "undefined" ? 2 : depth, + showHidden, + truncate: config.truncateThreshold ? config.truncateThreshold : Infinity + }; + return inspect(obj, options); +} +__name(inspect2, "inspect"); + +// lib/chai/utils/objDisplay.js +function objDisplay(obj) { + let str = inspect2(obj), type3 = Object.prototype.toString.call(obj); + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type3 === "[object Function]") { + return !obj.name || obj.name === "" ? "[Function]" : "[Function: " + obj.name + "]"; + } else if (type3 === "[object Array]") { + return "[ Array(" + obj.length + ") ]"; + } else if (type3 === "[object Object]") { + let keys = Object.keys(obj), kstr = keys.length > 2 ? keys.splice(0, 2).join(", ") + ", ..." : keys.join(", "); + return "{ Object (" + kstr + ") }"; + } else { + return str; + } + } else { + return str; + } +} +__name(objDisplay, "objDisplay"); + +// lib/chai/utils/getMessage.js +function getMessage2(obj, args) { + let negate = flag(obj, "negate"); + let val = flag(obj, "object"); + let expected = args[3]; + let actual = getActual(obj, args); + let msg = negate ? args[2] : args[1]; + let flagMsg = flag(obj, "message"); + if (typeof msg === "function") msg = msg(); + msg = msg || ""; + msg = msg.replace(/#\{this\}/g, function() { + return objDisplay(val); + }).replace(/#\{act\}/g, function() { + return objDisplay(actual); + }).replace(/#\{exp\}/g, function() { + return objDisplay(expected); + }); + return flagMsg ? flagMsg + ": " + msg : msg; +} +__name(getMessage2, "getMessage"); + +// lib/chai/utils/transferFlags.js +function transferFlags(assertion, object, includeAll) { + let flags = assertion.__flags || (assertion.__flags = /* @__PURE__ */ Object.create(null)); + if (!object.__flags) { + object.__flags = /* @__PURE__ */ Object.create(null); + } + includeAll = arguments.length === 3 ? includeAll : true; + for (let flag3 in flags) { + if (includeAll || flag3 !== "object" && flag3 !== "ssfi" && flag3 !== "lockSsfi" && flag3 != "message") { + object.__flags[flag3] = flags[flag3]; + } + } +} +__name(transferFlags, "transferFlags"); + +// node_modules/deep-eql/index.js +function type2(obj) { + if (typeof obj === "undefined") { + return "undefined"; + } + if (obj === null) { + return "null"; + } + const stringTag = obj[Symbol.toStringTag]; + if (typeof stringTag === "string") { + return stringTag; + } + const sliceStart = 8; + const sliceEnd = -1; + return Object.prototype.toString.call(obj).slice(sliceStart, sliceEnd); +} +__name(type2, "type"); +function FakeMap() { + this._key = "chai/deep-eql__" + Math.random() + Date.now(); +} +__name(FakeMap, "FakeMap"); +FakeMap.prototype = { + get: /* @__PURE__ */ __name(function get(key) { + return key[this._key]; + }, "get"), + set: /* @__PURE__ */ __name(function set(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this._key, { + value, + configurable: true + }); + } + }, "set") +}; +var MemoizeMap = typeof WeakMap === "function" ? WeakMap : FakeMap; +function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return null; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + var result = leftHandMap.get(rightHandOperand); + if (typeof result === "boolean") { + return result; + } + } + return null; +} +__name(memoizeCompare, "memoizeCompare"); +function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + leftHandMap.set(rightHandOperand, result); + } else { + leftHandMap = new MemoizeMap(); + leftHandMap.set(rightHandOperand, result); + memoizeMap.set(leftHandOperand, leftHandMap); + } +} +__name(memoizeSet, "memoizeSet"); +var deep_eql_default = deepEqual; +function deepEqual(leftHandOperand, rightHandOperand, options) { + if (options && options.comparator) { + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); + } + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + return simpleResult; + } + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); +} +__name(deepEqual, "deepEqual"); +function simpleEqual(leftHandOperand, rightHandOperand) { + if (leftHandOperand === rightHandOperand) { + return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; + } + if (leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare + rightHandOperand !== rightHandOperand) { + return true; + } + if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return false; + } + return null; +} +__name(simpleEqual, "simpleEqual"); +function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { + options = options || {}; + options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); + var comparator = options && options.comparator; + var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); + if (memoizeResultLeft !== null) { + return memoizeResultLeft; + } + var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); + if (memoizeResultRight !== null) { + return memoizeResultRight; + } + if (comparator) { + var comparatorResult = comparator(leftHandOperand, rightHandOperand); + if (comparatorResult === false || comparatorResult === true) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); + return comparatorResult; + } + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + return simpleResult; + } + } + var leftHandType = type2(leftHandOperand); + if (leftHandType !== type2(rightHandOperand)) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); + return false; + } + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); + var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); + return result; +} +__name(extensiveDeepEqual, "extensiveDeepEqual"); +function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { + switch (leftHandType) { + case "String": + case "Number": + case "Boolean": + case "Date": + return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); + case "Promise": + case "Symbol": + case "function": + case "WeakMap": + case "WeakSet": + return leftHandOperand === rightHandOperand; + case "Error": + return keysEqual(leftHandOperand, rightHandOperand, ["name", "message", "code"], options); + case "Arguments": + case "Int8Array": + case "Uint8Array": + case "Uint8ClampedArray": + case "Int16Array": + case "Uint16Array": + case "Int32Array": + case "Uint32Array": + case "Float32Array": + case "Float64Array": + case "Array": + return iterableEqual(leftHandOperand, rightHandOperand, options); + case "RegExp": + return regexpEqual(leftHandOperand, rightHandOperand); + case "Generator": + return generatorEqual(leftHandOperand, rightHandOperand, options); + case "DataView": + return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); + case "ArrayBuffer": + return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); + case "Set": + return entriesEqual(leftHandOperand, rightHandOperand, options); + case "Map": + return entriesEqual(leftHandOperand, rightHandOperand, options); + case "Temporal.PlainDate": + case "Temporal.PlainTime": + case "Temporal.PlainDateTime": + case "Temporal.Instant": + case "Temporal.ZonedDateTime": + case "Temporal.PlainYearMonth": + case "Temporal.PlainMonthDay": + return leftHandOperand.equals(rightHandOperand); + case "Temporal.Duration": + return leftHandOperand.total("nanoseconds") === rightHandOperand.total("nanoseconds"); + case "Temporal.TimeZone": + case "Temporal.Calendar": + return leftHandOperand.toString() === rightHandOperand.toString(); + default: + return objectEqual(leftHandOperand, rightHandOperand, options); + } +} +__name(extensiveDeepEqualByType, "extensiveDeepEqualByType"); +function regexpEqual(leftHandOperand, rightHandOperand) { + return leftHandOperand.toString() === rightHandOperand.toString(); +} +__name(regexpEqual, "regexpEqual"); +function entriesEqual(leftHandOperand, rightHandOperand, options) { + try { + if (leftHandOperand.size !== rightHandOperand.size) { + return false; + } + if (leftHandOperand.size === 0) { + return true; + } + } catch (sizeError) { + return false; + } + var leftHandItems = []; + var rightHandItems = []; + leftHandOperand.forEach(/* @__PURE__ */ __name(function gatherEntries(key, value) { + leftHandItems.push([key, value]); + }, "gatherEntries")); + rightHandOperand.forEach(/* @__PURE__ */ __name(function gatherEntries(key, value) { + rightHandItems.push([key, value]); + }, "gatherEntries")); + return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); +} +__name(entriesEqual, "entriesEqual"); +function iterableEqual(leftHandOperand, rightHandOperand, options) { + var length = leftHandOperand.length; + if (length !== rightHandOperand.length) { + return false; + } + if (length === 0) { + return true; + } + var index = -1; + while (++index < length) { + if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { + return false; + } + } + return true; +} +__name(iterableEqual, "iterableEqual"); +function generatorEqual(leftHandOperand, rightHandOperand, options) { + return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); +} +__name(generatorEqual, "generatorEqual"); +function hasIteratorFunction(target) { + return typeof Symbol !== "undefined" && typeof target === "object" && typeof Symbol.iterator !== "undefined" && typeof target[Symbol.iterator] === "function"; +} +__name(hasIteratorFunction, "hasIteratorFunction"); +function getIteratorEntries(target) { + if (hasIteratorFunction(target)) { + try { + return getGeneratorEntries(target[Symbol.iterator]()); + } catch (iteratorError) { + return []; + } + } + return []; +} +__name(getIteratorEntries, "getIteratorEntries"); +function getGeneratorEntries(generator) { + var generatorResult = generator.next(); + var accumulator = [generatorResult.value]; + while (generatorResult.done === false) { + generatorResult = generator.next(); + accumulator.push(generatorResult.value); + } + return accumulator; +} +__name(getGeneratorEntries, "getGeneratorEntries"); +function getEnumerableKeys(target) { + var keys = []; + for (var key in target) { + keys.push(key); + } + return keys; +} +__name(getEnumerableKeys, "getEnumerableKeys"); +function getEnumerableSymbols(target) { + var keys = []; + var allKeys = Object.getOwnPropertySymbols(target); + for (var i = 0; i < allKeys.length; i += 1) { + var key = allKeys[i]; + if (Object.getOwnPropertyDescriptor(target, key).enumerable) { + keys.push(key); + } + } + return keys; +} +__name(getEnumerableSymbols, "getEnumerableSymbols"); +function keysEqual(leftHandOperand, rightHandOperand, keys, options) { + var length = keys.length; + if (length === 0) { + return true; + } + for (var i = 0; i < length; i += 1) { + if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { + return false; + } + } + return true; +} +__name(keysEqual, "keysEqual"); +function objectEqual(leftHandOperand, rightHandOperand, options) { + var leftHandKeys = getEnumerableKeys(leftHandOperand); + var rightHandKeys = getEnumerableKeys(rightHandOperand); + var leftHandSymbols = getEnumerableSymbols(leftHandOperand); + var rightHandSymbols = getEnumerableSymbols(rightHandOperand); + leftHandKeys = leftHandKeys.concat(leftHandSymbols); + rightHandKeys = rightHandKeys.concat(rightHandSymbols); + if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { + if (iterableEqual(mapSymbols(leftHandKeys).sort(), mapSymbols(rightHandKeys).sort()) === false) { + return false; + } + return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); + } + var leftHandEntries = getIteratorEntries(leftHandOperand); + var rightHandEntries = getIteratorEntries(rightHandOperand); + if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { + leftHandEntries.sort(); + rightHandEntries.sort(); + return iterableEqual(leftHandEntries, rightHandEntries, options); + } + if (leftHandKeys.length === 0 && leftHandEntries.length === 0 && rightHandKeys.length === 0 && rightHandEntries.length === 0) { + return true; + } + return false; +} +__name(objectEqual, "objectEqual"); +function isPrimitive(value) { + return value === null || typeof value !== "object"; +} +__name(isPrimitive, "isPrimitive"); +function mapSymbols(arr) { + return arr.map(/* @__PURE__ */ __name(function mapSymbol(entry) { + if (typeof entry === "symbol") { + return entry.toString(); + } + return entry; + }, "mapSymbol")); +} +__name(mapSymbols, "mapSymbols"); + +// node_modules/pathval/index.js +function hasProperty(obj, name) { + if (typeof obj === "undefined" || obj === null) { + return false; + } + return name in Object(obj); +} +__name(hasProperty, "hasProperty"); +function parsePath(path) { + const str = path.replace(/([^\\])\[/g, "$1.["); + const parts = str.match(/(\\\.|[^.]+?)+/g); + return parts.map((value) => { + if (value === "constructor" || value === "__proto__" || value === "prototype") { + return {}; + } + const regexp = /^\[(\d+)\]$/; + const mArr = regexp.exec(value); + let parsed = null; + if (mArr) { + parsed = { i: parseFloat(mArr[1]) }; + } else { + parsed = { p: value.replace(/\\([.[\]])/g, "$1") }; + } + return parsed; + }); +} +__name(parsePath, "parsePath"); +function internalGetPathValue(obj, parsed, pathDepth) { + let temporaryValue = obj; + let res = null; + pathDepth = typeof pathDepth === "undefined" ? parsed.length : pathDepth; + for (let i = 0; i < pathDepth; i++) { + const part = parsed[i]; + if (temporaryValue) { + if (typeof part.p === "undefined") { + temporaryValue = temporaryValue[part.i]; + } else { + temporaryValue = temporaryValue[part.p]; + } + if (i === pathDepth - 1) { + res = temporaryValue; + } + } + } + return res; +} +__name(internalGetPathValue, "internalGetPathValue"); +function getPathInfo(obj, path) { + const parsed = parsePath(path); + const last = parsed[parsed.length - 1]; + const info = { + parent: parsed.length > 1 ? internalGetPathValue(obj, parsed, parsed.length - 1) : obj, + name: last.p || last.i, + value: internalGetPathValue(obj, parsed) + }; + info.exists = hasProperty(info.parent, info.name); + return info; +} +__name(getPathInfo, "getPathInfo"); + +// lib/chai/assertion.js +var Assertion = class _Assertion { + static { + __name(this, "Assertion"); + } + /** @type {{}} */ + __flags = {}; + /** + * Creates object for chaining. + * `Assertion` objects contain metadata in the form of flags. Three flags can + * be assigned during instantiation by passing arguments to this constructor: + * + * - `object`: This flag contains the target of the assertion. For example, in + * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will + * contain `numKittens` so that the `equal` assertion can reference it when + * needed. + * + * - `message`: This flag contains an optional custom error message to be + * prepended to the error message that's generated by the assertion when it + * fails. + * + * - `ssfi`: This flag stands for "start stack function indicator". It + * contains a function reference that serves as the starting point for + * removing frames from the stack trace of the error that's created by the + * assertion when it fails. The goal is to provide a cleaner stack trace to + * end users by removing Chai's internal functions. Note that it only works + * in environments that support `Error.captureStackTrace`, and only when + * `Chai.config.includeStack` hasn't been set to `false`. + * + * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag + * should retain its current value, even as assertions are chained off of + * this object. This is usually set to `true` when creating a new assertion + * from within another assertion. It's also temporarily set to `true` before + * an overwritten assertion gets called by the overwriting assertion. + * + * - `eql`: This flag contains the deepEqual function to be used by the assertion. + * + * @param {unknown} obj target of the assertion + * @param {string} [msg] (optional) custom error message + * @param {Function} [ssfi] (optional) starting point for removing stack frames + * @param {boolean} [lockSsfi] (optional) whether or not the ssfi flag is locked + */ + constructor(obj, msg, ssfi, lockSsfi) { + flag(this, "ssfi", ssfi || _Assertion); + flag(this, "lockSsfi", lockSsfi); + flag(this, "object", obj); + flag(this, "message", msg); + flag(this, "eql", config.deepEqual || deep_eql_default); + return proxify(this); + } + /** @returns {boolean} */ + static get includeStack() { + console.warn( + "Assertion.includeStack is deprecated, use chai.config.includeStack instead." + ); + return config.includeStack; + } + /** @param {boolean} value */ + static set includeStack(value) { + console.warn( + "Assertion.includeStack is deprecated, use chai.config.includeStack instead." + ); + config.includeStack = value; + } + /** @returns {boolean} */ + static get showDiff() { + console.warn( + "Assertion.showDiff is deprecated, use chai.config.showDiff instead." + ); + return config.showDiff; + } + /** @param {boolean} value */ + static set showDiff(value) { + console.warn( + "Assertion.showDiff is deprecated, use chai.config.showDiff instead." + ); + config.showDiff = value; + } + /** + * @param {string} name + * @param {Function} fn + */ + static addProperty(name, fn) { + addProperty(this.prototype, name, fn); + } + /** + * @param {string} name + * @param {Function} fn + */ + static addMethod(name, fn) { + addMethod(this.prototype, name, fn); + } + /** + * @param {string} name + * @param {Function} fn + * @param {Function} chainingBehavior + */ + static addChainableMethod(name, fn, chainingBehavior) { + addChainableMethod(this.prototype, name, fn, chainingBehavior); + } + /** + * @param {string} name + * @param {Function} fn + */ + static overwriteProperty(name, fn) { + overwriteProperty(this.prototype, name, fn); + } + /** + * @param {string} name + * @param {Function} fn + */ + static overwriteMethod(name, fn) { + overwriteMethod(this.prototype, name, fn); + } + /** + * @param {string} name + * @param {Function} fn + * @param {Function} chainingBehavior + */ + static overwriteChainableMethod(name, fn, chainingBehavior) { + overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + } + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {unknown} _expr to be tested + * @param {string | Function} msg or function that returns message to display if expression fails + * @param {string | Function} _negateMsg or function that returns negatedMessage to display if negated expression fails + * @param {unknown} expected value (remember to check for negation) + * @param {unknown} _actual (optional) will default to `this.obj` + * @param {boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @returns {void} + */ + assert(_expr, msg, _negateMsg, expected, _actual, showDiff) { + const ok = test(this, arguments); + if (false !== showDiff) showDiff = true; + if (void 0 === expected && void 0 === _actual) showDiff = false; + if (true !== config.showDiff) showDiff = false; + if (!ok) { + msg = getMessage2(this, arguments); + const actual = getActual(this, arguments); + const assertionErrorObjectProperties = { + actual, + expected, + showDiff + }; + const operator = getOperator(this, arguments); + if (operator) { + assertionErrorObjectProperties.operator = operator; + } + throw new AssertionError( + msg, + assertionErrorObjectProperties, + // @ts-expect-error Not sure what to do about these types yet + config.includeStack ? this.assert : flag(this, "ssfi") + ); + } + } + /** + * Quick reference to stored `actual` value for plugin developers. + * + * @returns {unknown} + */ + get _obj() { + return flag(this, "object"); + } + /** + * Quick reference to stored `actual` value for plugin developers. + * + * @param {unknown} val + */ + set _obj(val) { + flag(this, "object", val); + } +}; + +// lib/chai/utils/isProxyEnabled.js +function isProxyEnabled() { + return config.useProxy && typeof Proxy !== "undefined" && typeof Reflect !== "undefined"; +} +__name(isProxyEnabled, "isProxyEnabled"); + +// lib/chai/utils/addProperty.js +function addProperty(ctx, name, getter) { + getter = getter === void 0 ? function() { + } : getter; + Object.defineProperty(ctx, name, { + get: /* @__PURE__ */ __name(function propertyGetter() { + if (!isProxyEnabled() && !flag(this, "lockSsfi")) { + flag(this, "ssfi", propertyGetter); + } + let result = getter.call(this); + if (result !== void 0) return result; + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, "propertyGetter"), + configurable: true + }); +} +__name(addProperty, "addProperty"); + +// lib/chai/utils/addLengthGuard.js +var fnLengthDesc = Object.getOwnPropertyDescriptor(function() { +}, "length"); +function addLengthGuard(fn, assertionName, isChainable) { + if (!fnLengthDesc.configurable) return fn; + Object.defineProperty(fn, "length", { + get: /* @__PURE__ */ __name(function() { + if (isChainable) { + throw Error( + "Invalid Chai property: " + assertionName + '.length. Due to a compatibility issue, "length" cannot directly follow "' + assertionName + '". Use "' + assertionName + '.lengthOf" instead.' + ); + } + throw Error( + "Invalid Chai property: " + assertionName + '.length. See docs for proper usage of "' + assertionName + '".' + ); + }, "get") + }); + return fn; +} +__name(addLengthGuard, "addLengthGuard"); + +// lib/chai/utils/getProperties.js +function getProperties(object) { + let result = Object.getOwnPropertyNames(object); + function addProperty2(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + __name(addProperty2, "addProperty"); + let proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty2); + proto = Object.getPrototypeOf(proto); + } + return result; +} +__name(getProperties, "getProperties"); + +// lib/chai/utils/proxify.js +var builtins = ["__flags", "__methods", "_obj", "assert"]; +function proxify(obj, nonChainableMethodName) { + if (!isProxyEnabled()) return obj; + return new Proxy(obj, { + get: /* @__PURE__ */ __name(function proxyGetter(target, property) { + if (typeof property === "string" && config.proxyExcludedKeys.indexOf(property) === -1 && !Reflect.has(target, property)) { + if (nonChainableMethodName) { + throw Error( + "Invalid Chai property: " + nonChainableMethodName + "." + property + '. See docs for proper usage of "' + nonChainableMethodName + '".' + ); + } + let suggestion = null; + let suggestionDistance = 4; + getProperties(target).forEach(function(prop) { + if ( + // we actually mean to check `Object.prototype` here + // eslint-disable-next-line no-prototype-builtins + !Object.prototype.hasOwnProperty(prop) && builtins.indexOf(prop) === -1 + ) { + let dist = stringDistanceCapped(property, prop, suggestionDistance); + if (dist < suggestionDistance) { + suggestion = prop; + suggestionDistance = dist; + } + } + }); + if (suggestion !== null) { + throw Error( + "Invalid Chai property: " + property + '. Did you mean "' + suggestion + '"?' + ); + } else { + throw Error("Invalid Chai property: " + property); + } + } + if (builtins.indexOf(property) === -1 && !flag(target, "lockSsfi")) { + flag(target, "ssfi", proxyGetter); + } + return Reflect.get(target, property); + }, "proxyGetter") + }); +} +__name(proxify, "proxify"); +function stringDistanceCapped(strA, strB, cap) { + if (Math.abs(strA.length - strB.length) >= cap) { + return cap; + } + let memo = []; + for (let i = 0; i <= strA.length; i++) { + memo[i] = Array(strB.length + 1).fill(0); + memo[i][0] = i; + } + for (let j = 0; j < strB.length; j++) { + memo[0][j] = j; + } + for (let i = 1; i <= strA.length; i++) { + let ch = strA.charCodeAt(i - 1); + for (let j = 1; j <= strB.length; j++) { + if (Math.abs(i - j) >= cap) { + memo[i][j] = cap; + continue; + } + memo[i][j] = Math.min( + memo[i - 1][j] + 1, + memo[i][j - 1] + 1, + memo[i - 1][j - 1] + (ch === strB.charCodeAt(j - 1) ? 0 : 1) + ); + } + } + return memo[strA.length][strB.length]; +} +__name(stringDistanceCapped, "stringDistanceCapped"); + +// lib/chai/utils/addMethod.js +function addMethod(ctx, name, method) { + let methodWrapper = /* @__PURE__ */ __name(function() { + if (!flag(this, "lockSsfi")) { + flag(this, "ssfi", methodWrapper); + } + let result = method.apply(this, arguments); + if (result !== void 0) return result; + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, "methodWrapper"); + addLengthGuard(methodWrapper, name, false); + ctx[name] = proxify(methodWrapper, name); +} +__name(addMethod, "addMethod"); + +// lib/chai/utils/overwriteProperty.js +function overwriteProperty(ctx, name, getter) { + let _get = Object.getOwnPropertyDescriptor(ctx, name), _super = /* @__PURE__ */ __name(function() { + }, "_super"); + if (_get && "function" === typeof _get.get) _super = _get.get; + Object.defineProperty(ctx, name, { + get: /* @__PURE__ */ __name(function overwritingPropertyGetter() { + if (!isProxyEnabled() && !flag(this, "lockSsfi")) { + flag(this, "ssfi", overwritingPropertyGetter); + } + let origLockSsfi = flag(this, "lockSsfi"); + flag(this, "lockSsfi", true); + let result = getter(_super).call(this); + flag(this, "lockSsfi", origLockSsfi); + if (result !== void 0) { + return result; + } + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, "overwritingPropertyGetter"), + configurable: true + }); +} +__name(overwriteProperty, "overwriteProperty"); + +// lib/chai/utils/overwriteMethod.js +function overwriteMethod(ctx, name, method) { + let _method = ctx[name], _super = /* @__PURE__ */ __name(function() { + throw new Error(name + " is not a function"); + }, "_super"); + if (_method && "function" === typeof _method) _super = _method; + let overwritingMethodWrapper = /* @__PURE__ */ __name(function() { + if (!flag(this, "lockSsfi")) { + flag(this, "ssfi", overwritingMethodWrapper); + } + let origLockSsfi = flag(this, "lockSsfi"); + flag(this, "lockSsfi", true); + let result = method(_super).apply(this, arguments); + flag(this, "lockSsfi", origLockSsfi); + if (result !== void 0) { + return result; + } + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, "overwritingMethodWrapper"); + addLengthGuard(overwritingMethodWrapper, name, false); + ctx[name] = proxify(overwritingMethodWrapper, name); +} +__name(overwriteMethod, "overwriteMethod"); + +// lib/chai/utils/addChainableMethod.js +var canSetPrototype = typeof Object.setPrototypeOf === "function"; +var testFn = /* @__PURE__ */ __name(function() { +}, "testFn"); +var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { + let propDesc = Object.getOwnPropertyDescriptor(testFn, name); + if (typeof propDesc !== "object") return true; + return !propDesc.configurable; +}); +var call = Function.prototype.call; +var apply = Function.prototype.apply; +function addChainableMethod(ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== "function") { + chainingBehavior = /* @__PURE__ */ __name(function() { + }, "chainingBehavior"); + } + let chainableBehavior = { + method, + chainingBehavior + }; + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + Object.defineProperty(ctx, name, { + get: /* @__PURE__ */ __name(function chainableMethodGetter() { + chainableBehavior.chainingBehavior.call(this); + let chainableMethodWrapper = /* @__PURE__ */ __name(function() { + if (!flag(this, "lockSsfi")) { + flag(this, "ssfi", chainableMethodWrapper); + } + let result = chainableBehavior.method.apply(this, arguments); + if (result !== void 0) { + return result; + } + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, "chainableMethodWrapper"); + addLengthGuard(chainableMethodWrapper, name, true); + if (canSetPrototype) { + let prototype = Object.create(this); + prototype.call = call; + prototype.apply = apply; + Object.setPrototypeOf(chainableMethodWrapper, prototype); + } else { + let asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function(asserterName) { + if (excludeNames.indexOf(asserterName) !== -1) { + return; + } + let pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(chainableMethodWrapper, asserterName, pd); + }); + } + transferFlags(this, chainableMethodWrapper); + return proxify(chainableMethodWrapper); + }, "chainableMethodGetter"), + configurable: true + }); +} +__name(addChainableMethod, "addChainableMethod"); + +// lib/chai/utils/overwriteChainableMethod.js +function overwriteChainableMethod(ctx, name, method, chainingBehavior) { + let chainableBehavior = ctx.__methods[name]; + let _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = /* @__PURE__ */ __name(function overwritingChainableMethodGetter() { + let result = chainingBehavior(_chainingBehavior).call(this); + if (result !== void 0) { + return result; + } + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, "overwritingChainableMethodGetter"); + let _method = chainableBehavior.method; + chainableBehavior.method = /* @__PURE__ */ __name(function overwritingChainableMethodWrapper() { + let result = method(_method).apply(this, arguments); + if (result !== void 0) { + return result; + } + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, "overwritingChainableMethodWrapper"); +} +__name(overwriteChainableMethod, "overwriteChainableMethod"); + +// lib/chai/utils/compareByInspect.js +function compareByInspect(a, b) { + return inspect2(a) < inspect2(b) ? -1 : 1; +} +__name(compareByInspect, "compareByInspect"); + +// lib/chai/utils/getOwnEnumerablePropertySymbols.js +function getOwnEnumerablePropertySymbols(obj) { + if (typeof Object.getOwnPropertySymbols !== "function") return []; + return Object.getOwnPropertySymbols(obj).filter(function(sym) { + return Object.getOwnPropertyDescriptor(obj, sym).enumerable; + }); +} +__name(getOwnEnumerablePropertySymbols, "getOwnEnumerablePropertySymbols"); + +// lib/chai/utils/getOwnEnumerableProperties.js +function getOwnEnumerableProperties(obj) { + return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); +} +__name(getOwnEnumerableProperties, "getOwnEnumerableProperties"); + +// lib/chai/utils/isNaN.js +var isNaN2 = Number.isNaN; + +// lib/chai/utils/getOperator.js +function isObjectType(obj) { + let objectType = type(obj); + let objectTypes = ["Array", "Object", "Function"]; + return objectTypes.indexOf(objectType) !== -1; +} +__name(isObjectType, "isObjectType"); +function getOperator(obj, args) { + let operator = flag(obj, "operator"); + let negate = flag(obj, "negate"); + let expected = args[3]; + let msg = negate ? args[2] : args[1]; + if (operator) { + return operator; + } + if (typeof msg === "function") msg = msg(); + msg = msg || ""; + if (!msg) { + return void 0; + } + if (/\shave\s/.test(msg)) { + return void 0; + } + let isObject = isObjectType(expected); + if (/\snot\s/.test(msg)) { + return isObject ? "notDeepStrictEqual" : "notStrictEqual"; + } + return isObject ? "deepStrictEqual" : "strictEqual"; +} +__name(getOperator, "getOperator"); + +// lib/chai/utils/index.js +function getName(fn) { + return fn.name; +} +__name(getName, "getName"); +function isRegExp2(obj) { + return Object.prototype.toString.call(obj) === "[object RegExp]"; +} +__name(isRegExp2, "isRegExp"); +function isNumeric(obj) { + return ["Number", "BigInt"].includes(type(obj)); +} +__name(isNumeric, "isNumeric"); + +// lib/chai/core/assertions.js +var { flag: flag2 } = utils_exports; +[ + "to", + "be", + "been", + "is", + "and", + "has", + "have", + "with", + "that", + "which", + "at", + "of", + "same", + "but", + "does", + "still", + "also" +].forEach(function(chain) { + Assertion.addProperty(chain); +}); +Assertion.addProperty("not", function() { + flag2(this, "negate", true); +}); +Assertion.addProperty("deep", function() { + flag2(this, "deep", true); +}); +Assertion.addProperty("nested", function() { + flag2(this, "nested", true); +}); +Assertion.addProperty("own", function() { + flag2(this, "own", true); +}); +Assertion.addProperty("ordered", function() { + flag2(this, "ordered", true); +}); +Assertion.addProperty("any", function() { + flag2(this, "any", true); + flag2(this, "all", false); +}); +Assertion.addProperty("all", function() { + flag2(this, "all", true); + flag2(this, "any", false); +}); +var functionTypes = { + function: [ + "function", + "asyncfunction", + "generatorfunction", + "asyncgeneratorfunction" + ], + asyncfunction: ["asyncfunction", "asyncgeneratorfunction"], + generatorfunction: ["generatorfunction", "asyncgeneratorfunction"], + asyncgeneratorfunction: ["asyncgeneratorfunction"] +}; +function an(type3, msg) { + if (msg) flag2(this, "message", msg); + type3 = type3.toLowerCase(); + let obj = flag2(this, "object"), article = ~["a", "e", "i", "o", "u"].indexOf(type3.charAt(0)) ? "an " : "a "; + const detectedType = type(obj).toLowerCase(); + if (functionTypes["function"].includes(type3)) { + this.assert( + functionTypes[type3].includes(detectedType), + "expected #{this} to be " + article + type3, + "expected #{this} not to be " + article + type3 + ); + } else { + this.assert( + type3 === detectedType, + "expected #{this} to be " + article + type3, + "expected #{this} not to be " + article + type3 + ); + } +} +__name(an, "an"); +Assertion.addChainableMethod("an", an); +Assertion.addChainableMethod("a", an); +function SameValueZero(a, b) { + return isNaN2(a) && isNaN2(b) || a === b; +} +__name(SameValueZero, "SameValueZero"); +function includeChainingBehavior() { + flag2(this, "contains", true); +} +__name(includeChainingBehavior, "includeChainingBehavior"); +function include(val, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), objType = type(obj).toLowerCase(), flagMsg = flag2(this, "message"), negate = flag2(this, "negate"), ssfi = flag2(this, "ssfi"), isDeep = flag2(this, "deep"), descriptor = isDeep ? "deep " : "", isEql = isDeep ? flag2(this, "eql") : SameValueZero; + flagMsg = flagMsg ? flagMsg + ": " : ""; + let included = false; + switch (objType) { + case "string": + included = obj.indexOf(val) !== -1; + break; + case "weakset": + if (isDeep) { + throw new AssertionError( + flagMsg + "unable to use .deep.include with WeakSet", + void 0, + ssfi + ); + } + included = obj.has(val); + break; + case "map": + obj.forEach(function(item) { + included = included || isEql(item, val); + }); + break; + case "set": + if (isDeep) { + obj.forEach(function(item) { + included = included || isEql(item, val); + }); + } else { + included = obj.has(val); + } + break; + case "array": + if (isDeep) { + included = obj.some(function(item) { + return isEql(item, val); + }); + } else { + included = obj.indexOf(val) !== -1; + } + break; + default: { + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + "the given combination of arguments (" + objType + " and " + type(val).toLowerCase() + ") is invalid for this assertion. You can use an array, a map, an object, a set, a string, or a weakset instead of a " + type(val).toLowerCase(), + void 0, + ssfi + ); + } + let props = Object.keys(val); + let firstErr = null; + let numErrs = 0; + props.forEach(function(prop) { + let propAssertion = new Assertion(obj); + transferFlags(this, propAssertion, true); + flag2(propAssertion, "lockSsfi", true); + if (!negate || props.length === 1) { + propAssertion.property(prop, val[prop]); + return; + } + try { + propAssertion.property(prop, val[prop]); + } catch (err) { + if (!check_error_exports.compatibleConstructor(err, AssertionError)) { + throw err; + } + if (firstErr === null) firstErr = err; + numErrs++; + } + }, this); + if (negate && props.length > 1 && numErrs === props.length) { + throw firstErr; + } + return; + } + } + this.assert( + included, + "expected #{this} to " + descriptor + "include " + inspect2(val), + "expected #{this} to not " + descriptor + "include " + inspect2(val) + ); +} +__name(include, "include"); +Assertion.addChainableMethod("include", include, includeChainingBehavior); +Assertion.addChainableMethod("contain", include, includeChainingBehavior); +Assertion.addChainableMethod("contains", include, includeChainingBehavior); +Assertion.addChainableMethod("includes", include, includeChainingBehavior); +Assertion.addProperty("ok", function() { + this.assert( + flag2(this, "object"), + "expected #{this} to be truthy", + "expected #{this} to be falsy" + ); +}); +Assertion.addProperty("true", function() { + this.assert( + true === flag2(this, "object"), + "expected #{this} to be true", + "expected #{this} to be false", + flag2(this, "negate") ? false : true + ); +}); +Assertion.addProperty("numeric", function() { + const object = flag2(this, "object"); + this.assert( + ["Number", "BigInt"].includes(type(object)), + "expected #{this} to be numeric", + "expected #{this} to not be numeric", + flag2(this, "negate") ? false : true + ); +}); +Assertion.addProperty("callable", function() { + const val = flag2(this, "object"); + const ssfi = flag2(this, "ssfi"); + const message = flag2(this, "message"); + const msg = message ? `${message}: ` : ""; + const negate = flag2(this, "negate"); + const assertionMessage = negate ? `${msg}expected ${inspect2(val)} not to be a callable function` : `${msg}expected ${inspect2(val)} to be a callable function`; + const isCallable = [ + "Function", + "AsyncFunction", + "GeneratorFunction", + "AsyncGeneratorFunction" + ].includes(type(val)); + if (isCallable && negate || !isCallable && !negate) { + throw new AssertionError(assertionMessage, void 0, ssfi); + } +}); +Assertion.addProperty("false", function() { + this.assert( + false === flag2(this, "object"), + "expected #{this} to be false", + "expected #{this} to be true", + flag2(this, "negate") ? true : false + ); +}); +Assertion.addProperty("null", function() { + this.assert( + null === flag2(this, "object"), + "expected #{this} to be null", + "expected #{this} not to be null" + ); +}); +Assertion.addProperty("undefined", function() { + this.assert( + void 0 === flag2(this, "object"), + "expected #{this} to be undefined", + "expected #{this} not to be undefined" + ); +}); +Assertion.addProperty("NaN", function() { + this.assert( + isNaN2(flag2(this, "object")), + "expected #{this} to be NaN", + "expected #{this} not to be NaN" + ); +}); +function assertExist() { + let val = flag2(this, "object"); + this.assert( + val !== null && val !== void 0, + "expected #{this} to exist", + "expected #{this} to not exist" + ); +} +__name(assertExist, "assertExist"); +Assertion.addProperty("exist", assertExist); +Assertion.addProperty("exists", assertExist); +Assertion.addProperty("empty", function() { + let val = flag2(this, "object"), ssfi = flag2(this, "ssfi"), flagMsg = flag2(this, "message"), itemsCount; + flagMsg = flagMsg ? flagMsg + ": " : ""; + switch (type(val).toLowerCase()) { + case "array": + case "string": + itemsCount = val.length; + break; + case "map": + case "set": + itemsCount = val.size; + break; + case "weakmap": + case "weakset": + throw new AssertionError( + flagMsg + ".empty was passed a weak collection", + void 0, + ssfi + ); + case "function": { + const msg = flagMsg + ".empty was passed a function " + getName(val); + throw new AssertionError(msg.trim(), void 0, ssfi); + } + default: + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + ".empty was passed non-string primitive " + inspect2(val), + void 0, + ssfi + ); + } + itemsCount = Object.keys(val).length; + } + this.assert( + 0 === itemsCount, + "expected #{this} to be empty", + "expected #{this} not to be empty" + ); +}); +function checkArguments() { + let obj = flag2(this, "object"), type3 = type(obj); + this.assert( + "Arguments" === type3, + "expected #{this} to be arguments but got " + type3, + "expected #{this} to not be arguments" + ); +} +__name(checkArguments, "checkArguments"); +Assertion.addProperty("arguments", checkArguments); +Assertion.addProperty("Arguments", checkArguments); +function assertEqual(val, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"); + if (flag2(this, "deep")) { + let prevLockSsfi = flag2(this, "lockSsfi"); + flag2(this, "lockSsfi", true); + this.eql(val); + flag2(this, "lockSsfi", prevLockSsfi); + } else { + this.assert( + val === obj, + "expected #{this} to equal #{exp}", + "expected #{this} to not equal #{exp}", + val, + this._obj, + true + ); + } +} +__name(assertEqual, "assertEqual"); +Assertion.addMethod("equal", assertEqual); +Assertion.addMethod("equals", assertEqual); +Assertion.addMethod("eq", assertEqual); +function assertEql(obj, msg) { + if (msg) flag2(this, "message", msg); + let eql = flag2(this, "eql"); + this.assert( + eql(obj, flag2(this, "object")), + "expected #{this} to deeply equal #{exp}", + "expected #{this} to not deeply equal #{exp}", + obj, + this._obj, + true + ); +} +__name(assertEql, "assertEql"); +Assertion.addMethod("eql", assertEql); +Assertion.addMethod("eqls", assertEql); +function assertAbove(n, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), doLength = flag2(this, "doLength"), flagMsg = flag2(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag2(this, "ssfi"), objType = type(obj).toLowerCase(), nType = type(n).toLowerCase(); + if (doLength && objType !== "map" && objType !== "set") { + new Assertion(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && objType === "date" && nType !== "date") { + throw new AssertionError( + msgPrefix + "the argument to above must be a date", + void 0, + ssfi + ); + } else if (!isNumeric(n) && (doLength || isNumeric(obj))) { + throw new AssertionError( + msgPrefix + "the argument to above must be a number", + void 0, + ssfi + ); + } else if (!doLength && objType !== "date" && !isNumeric(obj)) { + let printObj = objType === "string" ? "'" + obj + "'" : obj; + throw new AssertionError( + msgPrefix + "expected " + printObj + " to be a number or a date", + void 0, + ssfi + ); + } + if (doLength) { + let descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount > n, + "expected #{this} to have a " + descriptor + " above #{exp} but got #{act}", + "expected #{this} to not have a " + descriptor + " above #{exp}", + n, + itemsCount + ); + } else { + this.assert( + obj > n, + "expected #{this} to be above #{exp}", + "expected #{this} to be at most #{exp}", + n + ); + } +} +__name(assertAbove, "assertAbove"); +Assertion.addMethod("above", assertAbove); +Assertion.addMethod("gt", assertAbove); +Assertion.addMethod("greaterThan", assertAbove); +function assertLeast(n, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), doLength = flag2(this, "doLength"), flagMsg = flag2(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag2(this, "ssfi"), objType = type(obj).toLowerCase(), nType = type(n).toLowerCase(), errorMessage, shouldThrow = true; + if (doLength && objType !== "map" && objType !== "set") { + new Assertion(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && objType === "date" && nType !== "date") { + errorMessage = msgPrefix + "the argument to least must be a date"; + } else if (!isNumeric(n) && (doLength || isNumeric(obj))) { + errorMessage = msgPrefix + "the argument to least must be a number"; + } else if (!doLength && objType !== "date" && !isNumeric(obj)) { + let printObj = objType === "string" ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; + } else { + shouldThrow = false; + } + if (shouldThrow) { + throw new AssertionError(errorMessage, void 0, ssfi); + } + if (doLength) { + let descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= n, + "expected #{this} to have a " + descriptor + " at least #{exp} but got #{act}", + "expected #{this} to have a " + descriptor + " below #{exp}", + n, + itemsCount + ); + } else { + this.assert( + obj >= n, + "expected #{this} to be at least #{exp}", + "expected #{this} to be below #{exp}", + n + ); + } +} +__name(assertLeast, "assertLeast"); +Assertion.addMethod("least", assertLeast); +Assertion.addMethod("gte", assertLeast); +Assertion.addMethod("greaterThanOrEqual", assertLeast); +function assertBelow(n, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), doLength = flag2(this, "doLength"), flagMsg = flag2(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag2(this, "ssfi"), objType = type(obj).toLowerCase(), nType = type(n).toLowerCase(), errorMessage, shouldThrow = true; + if (doLength && objType !== "map" && objType !== "set") { + new Assertion(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && objType === "date" && nType !== "date") { + errorMessage = msgPrefix + "the argument to below must be a date"; + } else if (!isNumeric(n) && (doLength || isNumeric(obj))) { + errorMessage = msgPrefix + "the argument to below must be a number"; + } else if (!doLength && objType !== "date" && !isNumeric(obj)) { + let printObj = objType === "string" ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; + } else { + shouldThrow = false; + } + if (shouldThrow) { + throw new AssertionError(errorMessage, void 0, ssfi); + } + if (doLength) { + let descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount < n, + "expected #{this} to have a " + descriptor + " below #{exp} but got #{act}", + "expected #{this} to not have a " + descriptor + " below #{exp}", + n, + itemsCount + ); + } else { + this.assert( + obj < n, + "expected #{this} to be below #{exp}", + "expected #{this} to be at least #{exp}", + n + ); + } +} +__name(assertBelow, "assertBelow"); +Assertion.addMethod("below", assertBelow); +Assertion.addMethod("lt", assertBelow); +Assertion.addMethod("lessThan", assertBelow); +function assertMost(n, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), doLength = flag2(this, "doLength"), flagMsg = flag2(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag2(this, "ssfi"), objType = type(obj).toLowerCase(), nType = type(n).toLowerCase(), errorMessage, shouldThrow = true; + if (doLength && objType !== "map" && objType !== "set") { + new Assertion(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && objType === "date" && nType !== "date") { + errorMessage = msgPrefix + "the argument to most must be a date"; + } else if (!isNumeric(n) && (doLength || isNumeric(obj))) { + errorMessage = msgPrefix + "the argument to most must be a number"; + } else if (!doLength && objType !== "date" && !isNumeric(obj)) { + let printObj = objType === "string" ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; + } else { + shouldThrow = false; + } + if (shouldThrow) { + throw new AssertionError(errorMessage, void 0, ssfi); + } + if (doLength) { + let descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount <= n, + "expected #{this} to have a " + descriptor + " at most #{exp} but got #{act}", + "expected #{this} to have a " + descriptor + " above #{exp}", + n, + itemsCount + ); + } else { + this.assert( + obj <= n, + "expected #{this} to be at most #{exp}", + "expected #{this} to be above #{exp}", + n + ); + } +} +__name(assertMost, "assertMost"); +Assertion.addMethod("most", assertMost); +Assertion.addMethod("lte", assertMost); +Assertion.addMethod("lessThanOrEqual", assertMost); +Assertion.addMethod("within", function(start, finish, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), doLength = flag2(this, "doLength"), flagMsg = flag2(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag2(this, "ssfi"), objType = type(obj).toLowerCase(), startType = type(start).toLowerCase(), finishType = type(finish).toLowerCase(), errorMessage, shouldThrow = true, range = startType === "date" && finishType === "date" ? start.toISOString() + ".." + finish.toISOString() : start + ".." + finish; + if (doLength && objType !== "map" && objType !== "set") { + new Assertion(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && objType === "date" && (startType !== "date" || finishType !== "date")) { + errorMessage = msgPrefix + "the arguments to within must be dates"; + } else if ((!isNumeric(start) || !isNumeric(finish)) && (doLength || isNumeric(obj))) { + errorMessage = msgPrefix + "the arguments to within must be numbers"; + } else if (!doLength && objType !== "date" && !isNumeric(obj)) { + let printObj = objType === "string" ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; + } else { + shouldThrow = false; + } + if (shouldThrow) { + throw new AssertionError(errorMessage, void 0, ssfi); + } + if (doLength) { + let descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= start && itemsCount <= finish, + "expected #{this} to have a " + descriptor + " within " + range, + "expected #{this} to not have a " + descriptor + " within " + range + ); + } else { + this.assert( + obj >= start && obj <= finish, + "expected #{this} to be within " + range, + "expected #{this} to not be within " + range + ); + } +}); +function assertInstanceOf(constructor, msg) { + if (msg) flag2(this, "message", msg); + let target = flag2(this, "object"); + let ssfi = flag2(this, "ssfi"); + let flagMsg = flag2(this, "message"); + let isInstanceOf; + try { + isInstanceOf = target instanceof constructor; + } catch (err) { + if (err instanceof TypeError) { + flagMsg = flagMsg ? flagMsg + ": " : ""; + throw new AssertionError( + flagMsg + "The instanceof assertion needs a constructor but " + type(constructor) + " was given.", + void 0, + ssfi + ); + } + throw err; + } + let name = getName(constructor); + if (name == null) { + name = "an unnamed constructor"; + } + this.assert( + isInstanceOf, + "expected #{this} to be an instance of " + name, + "expected #{this} to not be an instance of " + name + ); +} +__name(assertInstanceOf, "assertInstanceOf"); +Assertion.addMethod("instanceof", assertInstanceOf); +Assertion.addMethod("instanceOf", assertInstanceOf); +function assertProperty(name, val, msg) { + if (msg) flag2(this, "message", msg); + let isNested = flag2(this, "nested"), isOwn = flag2(this, "own"), flagMsg = flag2(this, "message"), obj = flag2(this, "object"), ssfi = flag2(this, "ssfi"), nameType = typeof name; + flagMsg = flagMsg ? flagMsg + ": " : ""; + if (isNested) { + if (nameType !== "string") { + throw new AssertionError( + flagMsg + "the argument to property must be a string when using nested syntax", + void 0, + ssfi + ); + } + } else { + if (nameType !== "string" && nameType !== "number" && nameType !== "symbol") { + throw new AssertionError( + flagMsg + "the argument to property must be a string, number, or symbol", + void 0, + ssfi + ); + } + } + if (isNested && isOwn) { + throw new AssertionError( + flagMsg + 'The "nested" and "own" flags cannot be combined.', + void 0, + ssfi + ); + } + if (obj === null || obj === void 0) { + throw new AssertionError( + flagMsg + "Target cannot be null or undefined.", + void 0, + ssfi + ); + } + let isDeep = flag2(this, "deep"), negate = flag2(this, "negate"), pathInfo = isNested ? getPathInfo(obj, name) : null, value = isNested ? pathInfo.value : obj[name], isEql = isDeep ? flag2(this, "eql") : (val1, val2) => val1 === val2; + let descriptor = ""; + if (isDeep) descriptor += "deep "; + if (isOwn) descriptor += "own "; + if (isNested) descriptor += "nested "; + descriptor += "property "; + let hasProperty2; + if (isOwn) hasProperty2 = Object.prototype.hasOwnProperty.call(obj, name); + else if (isNested) hasProperty2 = pathInfo.exists; + else hasProperty2 = hasProperty(obj, name); + if (!negate || arguments.length === 1) { + this.assert( + hasProperty2, + "expected #{this} to have " + descriptor + inspect2(name), + "expected #{this} to not have " + descriptor + inspect2(name) + ); + } + if (arguments.length > 1) { + this.assert( + hasProperty2 && isEql(val, value), + "expected #{this} to have " + descriptor + inspect2(name) + " of #{exp}, but got #{act}", + "expected #{this} to not have " + descriptor + inspect2(name) + " of #{act}", + val, + value + ); + } + flag2(this, "object", value); +} +__name(assertProperty, "assertProperty"); +Assertion.addMethod("property", assertProperty); +function assertOwnProperty(_name, _value, _msg) { + flag2(this, "own", true); + assertProperty.apply(this, arguments); +} +__name(assertOwnProperty, "assertOwnProperty"); +Assertion.addMethod("ownProperty", assertOwnProperty); +Assertion.addMethod("haveOwnProperty", assertOwnProperty); +function assertOwnPropertyDescriptor(name, descriptor, msg) { + if (typeof descriptor === "string") { + msg = descriptor; + descriptor = null; + } + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"); + let actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + let eql = flag2(this, "eql"); + if (actualDescriptor && descriptor) { + this.assert( + eql(descriptor, actualDescriptor), + "expected the own property descriptor for " + inspect2(name) + " on #{this} to match " + inspect2(descriptor) + ", got " + inspect2(actualDescriptor), + "expected the own property descriptor for " + inspect2(name) + " on #{this} to not match " + inspect2(descriptor), + descriptor, + actualDescriptor, + true + ); + } else { + this.assert( + actualDescriptor, + "expected #{this} to have an own property descriptor for " + inspect2(name), + "expected #{this} to not have an own property descriptor for " + inspect2(name) + ); + } + flag2(this, "object", actualDescriptor); +} +__name(assertOwnPropertyDescriptor, "assertOwnPropertyDescriptor"); +Assertion.addMethod("ownPropertyDescriptor", assertOwnPropertyDescriptor); +Assertion.addMethod("haveOwnPropertyDescriptor", assertOwnPropertyDescriptor); +function assertLengthChain() { + flag2(this, "doLength", true); +} +__name(assertLengthChain, "assertLengthChain"); +function assertLength(n, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), objType = type(obj).toLowerCase(), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"), descriptor = "length", itemsCount; + switch (objType) { + case "map": + case "set": + descriptor = "size"; + itemsCount = obj.size; + break; + default: + new Assertion(obj, flagMsg, ssfi, true).to.have.property("length"); + itemsCount = obj.length; + } + this.assert( + itemsCount == n, + "expected #{this} to have a " + descriptor + " of #{exp} but got #{act}", + "expected #{this} to not have a " + descriptor + " of #{act}", + n, + itemsCount + ); +} +__name(assertLength, "assertLength"); +Assertion.addChainableMethod("length", assertLength, assertLengthChain); +Assertion.addChainableMethod("lengthOf", assertLength, assertLengthChain); +function assertMatch(re, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"); + this.assert( + re.exec(obj), + "expected #{this} to match " + re, + "expected #{this} not to match " + re + ); +} +__name(assertMatch, "assertMatch"); +Assertion.addMethod("match", assertMatch); +Assertion.addMethod("matches", assertMatch); +Assertion.addMethod("string", function(str, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"); + new Assertion(obj, flagMsg, ssfi, true).is.a("string"); + this.assert( + ~obj.indexOf(str), + "expected #{this} to contain " + inspect2(str), + "expected #{this} to not contain " + inspect2(str) + ); +}); +function assertKeys(keys) { + let obj = flag2(this, "object"), objType = type(obj), keysType = type(keys), ssfi = flag2(this, "ssfi"), isDeep = flag2(this, "deep"), str, deepStr = "", actual, ok = true, flagMsg = flag2(this, "message"); + flagMsg = flagMsg ? flagMsg + ": " : ""; + let mixedArgsMsg = flagMsg + "when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments"; + if (objType === "Map" || objType === "Set") { + deepStr = isDeep ? "deeply " : ""; + actual = []; + obj.forEach(function(val, key) { + actual.push(key); + }); + if (keysType !== "Array") { + keys = Array.prototype.slice.call(arguments); + } + } else { + actual = getOwnEnumerableProperties(obj); + switch (keysType) { + case "Array": + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, void 0, ssfi); + } + break; + case "Object": + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, void 0, ssfi); + } + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + keys = keys.map(function(val) { + return typeof val === "symbol" ? val : String(val); + }); + } + if (!keys.length) { + throw new AssertionError(flagMsg + "keys required", void 0, ssfi); + } + let len = keys.length, any = flag2(this, "any"), all = flag2(this, "all"), expected = keys, isEql = isDeep ? flag2(this, "eql") : (val1, val2) => val1 === val2; + if (!any && !all) { + all = true; + } + if (any) { + ok = expected.some(function(expectedKey) { + return actual.some(function(actualKey) { + return isEql(expectedKey, actualKey); + }); + }); + } + if (all) { + ok = expected.every(function(expectedKey) { + return actual.some(function(actualKey) { + return isEql(expectedKey, actualKey); + }); + }); + if (!flag2(this, "contains")) { + ok = ok && keys.length == actual.length; + } + } + if (len > 1) { + keys = keys.map(function(key) { + return inspect2(key); + }); + let last = keys.pop(); + if (all) { + str = keys.join(", ") + ", and " + last; + } + if (any) { + str = keys.join(", ") + ", or " + last; + } + } else { + str = inspect2(keys[0]); + } + str = (len > 1 ? "keys " : "key ") + str; + str = (flag2(this, "contains") ? "contain " : "have ") + str; + this.assert( + ok, + "expected #{this} to " + deepStr + str, + "expected #{this} to not " + deepStr + str, + expected.slice(0).sort(compareByInspect), + actual.sort(compareByInspect), + true + ); +} +__name(assertKeys, "assertKeys"); +Assertion.addMethod("keys", assertKeys); +Assertion.addMethod("key", assertKeys); +function assertThrows(errorLike, errMsgMatcher, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), ssfi = flag2(this, "ssfi"), flagMsg = flag2(this, "message"), negate = flag2(this, "negate") || false; + new Assertion(obj, flagMsg, ssfi, true).is.a("function"); + if (isRegExp2(errorLike) || typeof errorLike === "string") { + errMsgMatcher = errorLike; + errorLike = null; + } + let caughtErr; + let errorWasThrown = false; + try { + obj(); + } catch (err) { + errorWasThrown = true; + caughtErr = err; + } + let everyArgIsUndefined = errorLike === void 0 && errMsgMatcher === void 0; + let everyArgIsDefined = Boolean(errorLike && errMsgMatcher); + let errorLikeFail = false; + let errMsgMatcherFail = false; + if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { + let errorLikeString = "an error"; + if (errorLike instanceof Error) { + errorLikeString = "#{exp}"; + } else if (errorLike) { + errorLikeString = check_error_exports.getConstructorName(errorLike); + } + let actual = caughtErr; + if (caughtErr instanceof Error) { + actual = caughtErr.toString(); + } else if (typeof caughtErr === "string") { + actual = caughtErr; + } else if (caughtErr && (typeof caughtErr === "object" || typeof caughtErr === "function")) { + try { + actual = check_error_exports.getConstructorName(caughtErr); + } catch (_err) { + } + } + this.assert( + errorWasThrown, + "expected #{this} to throw " + errorLikeString, + "expected #{this} to not throw an error but #{act} was thrown", + errorLike && errorLike.toString(), + actual + ); + } + if (errorLike && caughtErr) { + if (errorLike instanceof Error) { + let isCompatibleInstance = check_error_exports.compatibleInstance( + caughtErr, + errorLike + ); + if (isCompatibleInstance === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate, + "expected #{this} to throw #{exp} but #{act} was thrown", + "expected #{this} to not throw #{exp}" + (caughtErr && !negate ? " but #{act} was thrown" : ""), + errorLike.toString(), + caughtErr.toString() + ); + } + } + } + let isCompatibleConstructor = check_error_exports.compatibleConstructor( + caughtErr, + errorLike + ); + if (isCompatibleConstructor === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate, + "expected #{this} to throw #{exp} but #{act} was thrown", + "expected #{this} to not throw #{exp}" + (caughtErr ? " but #{act} was thrown" : ""), + errorLike instanceof Error ? errorLike.toString() : errorLike && check_error_exports.getConstructorName(errorLike), + caughtErr instanceof Error ? caughtErr.toString() : caughtErr && check_error_exports.getConstructorName(caughtErr) + ); + } + } + } + if (caughtErr && errMsgMatcher !== void 0 && errMsgMatcher !== null) { + let placeholder = "including"; + if (isRegExp2(errMsgMatcher)) { + placeholder = "matching"; + } + let isCompatibleMessage = check_error_exports.compatibleMessage( + caughtErr, + errMsgMatcher + ); + if (isCompatibleMessage === negate) { + if (everyArgIsDefined && negate) { + errMsgMatcherFail = true; + } else { + this.assert( + negate, + "expected #{this} to throw error " + placeholder + " #{exp} but got #{act}", + "expected #{this} to throw error not " + placeholder + " #{exp}", + errMsgMatcher, + check_error_exports.getMessage(caughtErr) + ); + } + } + } + if (errorLikeFail && errMsgMatcherFail) { + this.assert( + negate, + "expected #{this} to throw #{exp} but #{act} was thrown", + "expected #{this} to not throw #{exp}" + (caughtErr ? " but #{act} was thrown" : ""), + errorLike instanceof Error ? errorLike.toString() : errorLike && check_error_exports.getConstructorName(errorLike), + caughtErr instanceof Error ? caughtErr.toString() : caughtErr && check_error_exports.getConstructorName(caughtErr) + ); + } + flag2(this, "object", caughtErr); +} +__name(assertThrows, "assertThrows"); +Assertion.addMethod("throw", assertThrows); +Assertion.addMethod("throws", assertThrows); +Assertion.addMethod("Throw", assertThrows); +function respondTo(method, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), itself = flag2(this, "itself"), context = "function" === typeof obj && !itself ? obj.prototype[method] : obj[method]; + this.assert( + "function" === typeof context, + "expected #{this} to respond to " + inspect2(method), + "expected #{this} to not respond to " + inspect2(method) + ); +} +__name(respondTo, "respondTo"); +Assertion.addMethod("respondTo", respondTo); +Assertion.addMethod("respondsTo", respondTo); +Assertion.addProperty("itself", function() { + flag2(this, "itself", true); +}); +function satisfy(matcher, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"); + let result = matcher(obj); + this.assert( + result, + "expected #{this} to satisfy " + objDisplay(matcher), + "expected #{this} to not satisfy" + objDisplay(matcher), + flag2(this, "negate") ? false : true, + result + ); +} +__name(satisfy, "satisfy"); +Assertion.addMethod("satisfy", satisfy); +Assertion.addMethod("satisfies", satisfy); +function closeTo(expected, delta, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"); + new Assertion(obj, flagMsg, ssfi, true).is.numeric; + let message = "A `delta` value is required for `closeTo`"; + if (delta == void 0) { + throw new AssertionError( + flagMsg ? `${flagMsg}: ${message}` : message, + void 0, + ssfi + ); + } + new Assertion(delta, flagMsg, ssfi, true).is.numeric; + message = "A `expected` value is required for `closeTo`"; + if (expected == void 0) { + throw new AssertionError( + flagMsg ? `${flagMsg}: ${message}` : message, + void 0, + ssfi + ); + } + new Assertion(expected, flagMsg, ssfi, true).is.numeric; + const abs = /* @__PURE__ */ __name((x) => x < 0n ? -x : x, "abs"); + const strip = /* @__PURE__ */ __name((number) => parseFloat(parseFloat(number).toPrecision(12)), "strip"); + this.assert( + strip(abs(obj - expected)) <= delta, + "expected #{this} to be close to " + expected + " +/- " + delta, + "expected #{this} not to be close to " + expected + " +/- " + delta + ); +} +__name(closeTo, "closeTo"); +Assertion.addMethod("closeTo", closeTo); +Assertion.addMethod("approximately", closeTo); +function isSubsetOf(_subset, _superset, cmp, contains, ordered) { + let superset = Array.from(_superset); + let subset = Array.from(_subset); + if (!contains) { + if (subset.length !== superset.length) return false; + superset = superset.slice(); + } + return subset.every(function(elem, idx) { + if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; + if (!cmp) { + let matchIdx = superset.indexOf(elem); + if (matchIdx === -1) return false; + if (!contains) superset.splice(matchIdx, 1); + return true; + } + return superset.some(function(elem2, matchIdx) { + if (!cmp(elem, elem2)) return false; + if (!contains) superset.splice(matchIdx, 1); + return true; + }); + }); +} +__name(isSubsetOf, "isSubsetOf"); +Assertion.addMethod("members", function(subset, msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"); + new Assertion(obj, flagMsg, ssfi, true).to.be.iterable; + new Assertion(subset, flagMsg, ssfi, true).to.be.iterable; + let contains = flag2(this, "contains"); + let ordered = flag2(this, "ordered"); + let subject, failMsg, failNegateMsg; + if (contains) { + subject = ordered ? "an ordered superset" : "a superset"; + failMsg = "expected #{this} to be " + subject + " of #{exp}"; + failNegateMsg = "expected #{this} to not be " + subject + " of #{exp}"; + } else { + subject = ordered ? "ordered members" : "members"; + failMsg = "expected #{this} to have the same " + subject + " as #{exp}"; + failNegateMsg = "expected #{this} to not have the same " + subject + " as #{exp}"; + } + let cmp = flag2(this, "deep") ? flag2(this, "eql") : void 0; + this.assert( + isSubsetOf(subset, obj, cmp, contains, ordered), + failMsg, + failNegateMsg, + subset, + obj, + true + ); +}); +Assertion.addProperty("iterable", function(msg) { + if (msg) flag2(this, "message", msg); + let obj = flag2(this, "object"); + this.assert( + obj != void 0 && obj[Symbol.iterator], + "expected #{this} to be an iterable", + "expected #{this} to not be an iterable", + obj + ); +}); +function oneOf(list, msg) { + if (msg) flag2(this, "message", msg); + let expected = flag2(this, "object"), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"), contains = flag2(this, "contains"), isDeep = flag2(this, "deep"), eql = flag2(this, "eql"); + new Assertion(list, flagMsg, ssfi, true).to.be.an("array"); + if (contains) { + this.assert( + list.some(function(possibility) { + return expected.indexOf(possibility) > -1; + }), + "expected #{this} to contain one of #{exp}", + "expected #{this} to not contain one of #{exp}", + list, + expected + ); + } else { + if (isDeep) { + this.assert( + list.some(function(possibility) { + return eql(expected, possibility); + }), + "expected #{this} to deeply equal one of #{exp}", + "expected #{this} to deeply equal one of #{exp}", + list, + expected + ); + } else { + this.assert( + list.indexOf(expected) > -1, + "expected #{this} to be one of #{exp}", + "expected #{this} to not be one of #{exp}", + list, + expected + ); + } + } +} +__name(oneOf, "oneOf"); +Assertion.addMethod("oneOf", oneOf); +function assertChanges(subject, prop, msg) { + if (msg) flag2(this, "message", msg); + let fn = flag2(this, "object"), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"); + new Assertion(fn, flagMsg, ssfi, true).is.a("function"); + let initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a("function"); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + fn(); + let final = prop === void 0 || prop === null ? subject() : subject[prop]; + let msgObj = prop === void 0 || prop === null ? initial : "." + prop; + flag2(this, "deltaMsgObj", msgObj); + flag2(this, "initialDeltaValue", initial); + flag2(this, "finalDeltaValue", final); + flag2(this, "deltaBehavior", "change"); + flag2(this, "realDelta", final !== initial); + this.assert( + initial !== final, + "expected " + msgObj + " to change", + "expected " + msgObj + " to not change" + ); +} +__name(assertChanges, "assertChanges"); +Assertion.addMethod("change", assertChanges); +Assertion.addMethod("changes", assertChanges); +function assertIncreases(subject, prop, msg) { + if (msg) flag2(this, "message", msg); + let fn = flag2(this, "object"), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"); + new Assertion(fn, flagMsg, ssfi, true).is.a("function"); + let initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a("function"); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + new Assertion(initial, flagMsg, ssfi, true).is.a("number"); + fn(); + let final = prop === void 0 || prop === null ? subject() : subject[prop]; + let msgObj = prop === void 0 || prop === null ? initial : "." + prop; + flag2(this, "deltaMsgObj", msgObj); + flag2(this, "initialDeltaValue", initial); + flag2(this, "finalDeltaValue", final); + flag2(this, "deltaBehavior", "increase"); + flag2(this, "realDelta", final - initial); + this.assert( + final - initial > 0, + "expected " + msgObj + " to increase", + "expected " + msgObj + " to not increase" + ); +} +__name(assertIncreases, "assertIncreases"); +Assertion.addMethod("increase", assertIncreases); +Assertion.addMethod("increases", assertIncreases); +function assertDecreases(subject, prop, msg) { + if (msg) flag2(this, "message", msg); + let fn = flag2(this, "object"), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"); + new Assertion(fn, flagMsg, ssfi, true).is.a("function"); + let initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a("function"); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + new Assertion(initial, flagMsg, ssfi, true).is.a("number"); + fn(); + let final = prop === void 0 || prop === null ? subject() : subject[prop]; + let msgObj = prop === void 0 || prop === null ? initial : "." + prop; + flag2(this, "deltaMsgObj", msgObj); + flag2(this, "initialDeltaValue", initial); + flag2(this, "finalDeltaValue", final); + flag2(this, "deltaBehavior", "decrease"); + flag2(this, "realDelta", initial - final); + this.assert( + final - initial < 0, + "expected " + msgObj + " to decrease", + "expected " + msgObj + " to not decrease" + ); +} +__name(assertDecreases, "assertDecreases"); +Assertion.addMethod("decrease", assertDecreases); +Assertion.addMethod("decreases", assertDecreases); +function assertDelta(delta, msg) { + if (msg) flag2(this, "message", msg); + let msgObj = flag2(this, "deltaMsgObj"); + let initial = flag2(this, "initialDeltaValue"); + let final = flag2(this, "finalDeltaValue"); + let behavior = flag2(this, "deltaBehavior"); + let realDelta = flag2(this, "realDelta"); + let expression; + if (behavior === "change") { + expression = Math.abs(final - initial) === Math.abs(delta); + } else { + expression = realDelta === Math.abs(delta); + } + this.assert( + expression, + "expected " + msgObj + " to " + behavior + " by " + delta, + "expected " + msgObj + " to not " + behavior + " by " + delta + ); +} +__name(assertDelta, "assertDelta"); +Assertion.addMethod("by", assertDelta); +Assertion.addProperty("extensible", function() { + let obj = flag2(this, "object"); + let isExtensible = obj === Object(obj) && Object.isExtensible(obj); + this.assert( + isExtensible, + "expected #{this} to be extensible", + "expected #{this} to not be extensible" + ); +}); +Assertion.addProperty("sealed", function() { + let obj = flag2(this, "object"); + let isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; + this.assert( + isSealed, + "expected #{this} to be sealed", + "expected #{this} to not be sealed" + ); +}); +Assertion.addProperty("frozen", function() { + let obj = flag2(this, "object"); + let isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; + this.assert( + isFrozen, + "expected #{this} to be frozen", + "expected #{this} to not be frozen" + ); +}); +Assertion.addProperty("finite", function(_msg) { + let obj = flag2(this, "object"); + this.assert( + typeof obj === "number" && isFinite(obj), + "expected #{this} to be a finite number", + "expected #{this} to not be a finite number" + ); +}); +function compareSubset(expected, actual) { + if (expected === actual) { + return true; + } + if (typeof actual !== typeof expected) { + return false; + } + if (typeof expected !== "object" || expected === null) { + return expected === actual; + } + if (!actual) { + return false; + } + if (Array.isArray(expected)) { + if (!Array.isArray(actual)) { + return false; + } + return expected.every(function(exp) { + return actual.some(function(act) { + return compareSubset(exp, act); + }); + }); + } + if (expected instanceof Date) { + if (actual instanceof Date) { + return expected.getTime() === actual.getTime(); + } else { + return false; + } + } + return Object.keys(expected).every(function(key) { + let expectedValue = expected[key]; + let actualValue = actual[key]; + if (typeof expectedValue === "object" && expectedValue !== null && actualValue !== null) { + return compareSubset(expectedValue, actualValue); + } + if (typeof expectedValue === "function") { + return expectedValue(actualValue); + } + return actualValue === expectedValue; + }); +} +__name(compareSubset, "compareSubset"); +Assertion.addMethod("containSubset", function(expected) { + const actual = flag(this, "object"); + const showDiff = config.showDiff; + this.assert( + compareSubset(expected, actual), + "expected #{act} to contain subset #{exp}", + "expected #{act} to not contain subset #{exp}", + expected, + actual, + showDiff + ); +}); + +// lib/chai/interface/expect.js +function expect(val, message) { + return new Assertion(val, message); +} +__name(expect, "expect"); +expect.fail = function(actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = void 0; + } + message = message || "expect.fail()"; + throw new AssertionError( + message, + { + actual, + expected, + operator + }, + expect.fail + ); +}; + +// lib/chai/interface/should.js +var should_exports = {}; +__export(should_exports, { + Should: () => Should, + should: () => should +}); +function loadShould() { + function shouldGetter() { + if (this instanceof String || this instanceof Number || this instanceof Boolean || typeof Symbol === "function" && this instanceof Symbol || typeof BigInt === "function" && this instanceof BigInt) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + __name(shouldGetter, "shouldGetter"); + function shouldSetter(value) { + Object.defineProperty(this, "should", { + value, + enumerable: true, + configurable: true, + writable: true + }); + } + __name(shouldSetter, "shouldSetter"); + Object.defineProperty(Object.prototype, "should", { + set: shouldSetter, + get: shouldGetter, + configurable: true + }); + let should2 = {}; + should2.fail = function(actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = void 0; + } + message = message || "should.fail()"; + throw new AssertionError( + message, + { + actual, + expected, + operator + }, + should2.fail + ); + }; + should2.equal = function(actual, expected, message) { + new Assertion(actual, message).to.equal(expected); + }; + should2.Throw = function(fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + should2.exist = function(val, msg) { + new Assertion(val, msg).to.exist; + }; + should2.not = {}; + should2.not.equal = function(actual, expected, msg) { + new Assertion(actual, msg).to.not.equal(expected); + }; + should2.not.Throw = function(fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + should2.not.exist = function(val, msg) { + new Assertion(val, msg).to.not.exist; + }; + should2["throw"] = should2["Throw"]; + should2.not["throw"] = should2.not["Throw"]; + return should2; +} +__name(loadShould, "loadShould"); +var should = loadShould; +var Should = loadShould; + +// lib/chai/interface/assert.js +function assert(express, errmsg) { + let test2 = new Assertion(null, null, assert, true); + test2.assert(express, errmsg, "[ negation message unavailable ]"); +} +__name(assert, "assert"); +assert.fail = function(actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = void 0; + } + message = message || "assert.fail()"; + throw new AssertionError( + message, + { + actual, + expected, + operator + }, + assert.fail + ); +}; +assert.isOk = function(val, msg) { + new Assertion(val, msg, assert.isOk, true).is.ok; +}; +assert.isNotOk = function(val, msg) { + new Assertion(val, msg, assert.isNotOk, true).is.not.ok; +}; +assert.equal = function(act, exp, msg) { + let test2 = new Assertion(act, msg, assert.equal, true); + test2.assert( + exp == flag(test2, "object"), + "expected #{this} to equal #{exp}", + "expected #{this} to not equal #{act}", + exp, + act, + true + ); +}; +assert.notEqual = function(act, exp, msg) { + let test2 = new Assertion(act, msg, assert.notEqual, true); + test2.assert( + exp != flag(test2, "object"), + "expected #{this} to not equal #{exp}", + "expected #{this} to equal #{act}", + exp, + act, + true + ); +}; +assert.strictEqual = function(act, exp, msg) { + new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); +}; +assert.notStrictEqual = function(act, exp, msg) { + new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); +}; +assert.deepEqual = assert.deepStrictEqual = function(act, exp, msg) { + new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); +}; +assert.notDeepEqual = function(act, exp, msg) { + new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); +}; +assert.isAbove = function(val, abv, msg) { + new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); +}; +assert.isAtLeast = function(val, atlst, msg) { + new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); +}; +assert.isBelow = function(val, blw, msg) { + new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); +}; +assert.isAtMost = function(val, atmst, msg) { + new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); +}; +assert.isTrue = function(val, msg) { + new Assertion(val, msg, assert.isTrue, true).is["true"]; +}; +assert.isNotTrue = function(val, msg) { + new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); +}; +assert.isFalse = function(val, msg) { + new Assertion(val, msg, assert.isFalse, true).is["false"]; +}; +assert.isNotFalse = function(val, msg) { + new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); +}; +assert.isNull = function(val, msg) { + new Assertion(val, msg, assert.isNull, true).to.equal(null); +}; +assert.isNotNull = function(val, msg) { + new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); +}; +assert.isNaN = function(val, msg) { + new Assertion(val, msg, assert.isNaN, true).to.be.NaN; +}; +assert.isNotNaN = function(value, message) { + new Assertion(value, message, assert.isNotNaN, true).not.to.be.NaN; +}; +assert.exists = function(val, msg) { + new Assertion(val, msg, assert.exists, true).to.exist; +}; +assert.notExists = function(val, msg) { + new Assertion(val, msg, assert.notExists, true).to.not.exist; +}; +assert.isUndefined = function(val, msg) { + new Assertion(val, msg, assert.isUndefined, true).to.equal(void 0); +}; +assert.isDefined = function(val, msg) { + new Assertion(val, msg, assert.isDefined, true).to.not.equal(void 0); +}; +assert.isCallable = function(value, message) { + new Assertion(value, message, assert.isCallable, true).is.callable; +}; +assert.isNotCallable = function(value, message) { + new Assertion(value, message, assert.isNotCallable, true).is.not.callable; +}; +assert.isObject = function(val, msg) { + new Assertion(val, msg, assert.isObject, true).to.be.a("object"); +}; +assert.isNotObject = function(val, msg) { + new Assertion(val, msg, assert.isNotObject, true).to.not.be.a("object"); +}; +assert.isArray = function(val, msg) { + new Assertion(val, msg, assert.isArray, true).to.be.an("array"); +}; +assert.isNotArray = function(val, msg) { + new Assertion(val, msg, assert.isNotArray, true).to.not.be.an("array"); +}; +assert.isString = function(val, msg) { + new Assertion(val, msg, assert.isString, true).to.be.a("string"); +}; +assert.isNotString = function(val, msg) { + new Assertion(val, msg, assert.isNotString, true).to.not.be.a("string"); +}; +assert.isNumber = function(val, msg) { + new Assertion(val, msg, assert.isNumber, true).to.be.a("number"); +}; +assert.isNotNumber = function(val, msg) { + new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a("number"); +}; +assert.isNumeric = function(val, msg) { + new Assertion(val, msg, assert.isNumeric, true).is.numeric; +}; +assert.isNotNumeric = function(val, msg) { + new Assertion(val, msg, assert.isNotNumeric, true).is.not.numeric; +}; +assert.isFinite = function(val, msg) { + new Assertion(val, msg, assert.isFinite, true).to.be.finite; +}; +assert.isBoolean = function(val, msg) { + new Assertion(val, msg, assert.isBoolean, true).to.be.a("boolean"); +}; +assert.isNotBoolean = function(val, msg) { + new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a("boolean"); +}; +assert.typeOf = function(val, type3, msg) { + new Assertion(val, msg, assert.typeOf, true).to.be.a(type3); +}; +assert.notTypeOf = function(value, type3, message) { + new Assertion(value, message, assert.notTypeOf, true).to.not.be.a(type3); +}; +assert.instanceOf = function(val, type3, msg) { + new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type3); +}; +assert.notInstanceOf = function(val, type3, msg) { + new Assertion(val, msg, assert.notInstanceOf, true).to.not.be.instanceOf( + type3 + ); +}; +assert.include = function(exp, inc, msg) { + new Assertion(exp, msg, assert.include, true).include(inc); +}; +assert.notInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude, true).not.include(inc); +}; +assert.deepInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); +}; +assert.notDeepInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); +}; +assert.nestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); +}; +assert.notNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notNestedInclude, true).not.nested.include( + inc + ); +}; +assert.deepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepNestedInclude, true).deep.nested.include( + inc + ); +}; +assert.notDeepNestedInclude = function(exp, inc, msg) { + new Assertion( + exp, + msg, + assert.notDeepNestedInclude, + true + ).not.deep.nested.include(inc); +}; +assert.ownInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); +}; +assert.notOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); +}; +assert.deepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepOwnInclude, true).deep.own.include(inc); +}; +assert.notDeepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepOwnInclude, true).not.deep.own.include( + inc + ); +}; +assert.match = function(exp, re, msg) { + new Assertion(exp, msg, assert.match, true).to.match(re); +}; +assert.notMatch = function(exp, re, msg) { + new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); +}; +assert.property = function(obj, prop, msg) { + new Assertion(obj, msg, assert.property, true).to.have.property(prop); +}; +assert.notProperty = function(obj, prop, msg) { + new Assertion(obj, msg, assert.notProperty, true).to.not.have.property(prop); +}; +assert.propertyVal = function(obj, prop, val, msg) { + new Assertion(obj, msg, assert.propertyVal, true).to.have.property(prop, val); +}; +assert.notPropertyVal = function(obj, prop, val, msg) { + new Assertion(obj, msg, assert.notPropertyVal, true).to.not.have.property( + prop, + val + ); +}; +assert.deepPropertyVal = function(obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepPropertyVal, true).to.have.deep.property( + prop, + val + ); +}; +assert.notDeepPropertyVal = function(obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.notDeepPropertyVal, + true + ).to.not.have.deep.property(prop, val); +}; +assert.ownProperty = function(obj, prop, msg) { + new Assertion(obj, msg, assert.ownProperty, true).to.have.own.property(prop); +}; +assert.notOwnProperty = function(obj, prop, msg) { + new Assertion(obj, msg, assert.notOwnProperty, true).to.not.have.own.property( + prop + ); +}; +assert.ownPropertyVal = function(obj, prop, value, msg) { + new Assertion(obj, msg, assert.ownPropertyVal, true).to.have.own.property( + prop, + value + ); +}; +assert.notOwnPropertyVal = function(obj, prop, value, msg) { + new Assertion( + obj, + msg, + assert.notOwnPropertyVal, + true + ).to.not.have.own.property(prop, value); +}; +assert.deepOwnPropertyVal = function(obj, prop, value, msg) { + new Assertion( + obj, + msg, + assert.deepOwnPropertyVal, + true + ).to.have.deep.own.property(prop, value); +}; +assert.notDeepOwnPropertyVal = function(obj, prop, value, msg) { + new Assertion( + obj, + msg, + assert.notDeepOwnPropertyVal, + true + ).to.not.have.deep.own.property(prop, value); +}; +assert.nestedProperty = function(obj, prop, msg) { + new Assertion(obj, msg, assert.nestedProperty, true).to.have.nested.property( + prop + ); +}; +assert.notNestedProperty = function(obj, prop, msg) { + new Assertion( + obj, + msg, + assert.notNestedProperty, + true + ).to.not.have.nested.property(prop); +}; +assert.nestedPropertyVal = function(obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.nestedPropertyVal, + true + ).to.have.nested.property(prop, val); +}; +assert.notNestedPropertyVal = function(obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.notNestedPropertyVal, + true + ).to.not.have.nested.property(prop, val); +}; +assert.deepNestedPropertyVal = function(obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.deepNestedPropertyVal, + true + ).to.have.deep.nested.property(prop, val); +}; +assert.notDeepNestedPropertyVal = function(obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.notDeepNestedPropertyVal, + true + ).to.not.have.deep.nested.property(prop, val); +}; +assert.lengthOf = function(exp, len, msg) { + new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); +}; +assert.hasAnyKeys = function(obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); +}; +assert.hasAllKeys = function(obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); +}; +assert.containsAllKeys = function(obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllKeys, true).to.contain.all.keys( + keys + ); +}; +assert.doesNotHaveAnyKeys = function(obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true).to.not.have.any.keys( + keys + ); +}; +assert.doesNotHaveAllKeys = function(obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllKeys, true).to.not.have.all.keys( + keys + ); +}; +assert.hasAnyDeepKeys = function(obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyDeepKeys, true).to.have.any.deep.keys( + keys + ); +}; +assert.hasAllDeepKeys = function(obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllDeepKeys, true).to.have.all.deep.keys( + keys + ); +}; +assert.containsAllDeepKeys = function(obj, keys, msg) { + new Assertion( + obj, + msg, + assert.containsAllDeepKeys, + true + ).to.contain.all.deep.keys(keys); +}; +assert.doesNotHaveAnyDeepKeys = function(obj, keys, msg) { + new Assertion( + obj, + msg, + assert.doesNotHaveAnyDeepKeys, + true + ).to.not.have.any.deep.keys(keys); +}; +assert.doesNotHaveAllDeepKeys = function(obj, keys, msg) { + new Assertion( + obj, + msg, + assert.doesNotHaveAllDeepKeys, + true + ).to.not.have.all.deep.keys(keys); +}; +assert.throws = function(fn, errorLike, errMsgMatcher, msg) { + if ("string" === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + let assertErr = new Assertion(fn, msg, assert.throws, true).to.throw( + errorLike, + errMsgMatcher + ); + return flag(assertErr, "object"); +}; +assert.doesNotThrow = function(fn, errorLike, errMsgMatcher, message) { + if ("string" === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + new Assertion(fn, message, assert.doesNotThrow, true).to.not.throw( + errorLike, + errMsgMatcher + ); +}; +assert.operator = function(val, operator, val2, msg) { + let ok; + switch (operator) { + case "==": + ok = val == val2; + break; + case "===": + ok = val === val2; + break; + case ">": + ok = val > val2; + break; + case ">=": + ok = val >= val2; + break; + case "<": + ok = val < val2; + break; + case "<=": + ok = val <= val2; + break; + case "!=": + ok = val != val2; + break; + case "!==": + ok = val !== val2; + break; + default: + msg = msg ? msg + ": " : msg; + throw new AssertionError( + msg + 'Invalid operator "' + operator + '"', + void 0, + assert.operator + ); + } + let test2 = new Assertion(ok, msg, assert.operator, true); + test2.assert( + true === flag(test2, "object"), + "expected " + inspect2(val) + " to be " + operator + " " + inspect2(val2), + "expected " + inspect2(val) + " to not be " + operator + " " + inspect2(val2) + ); +}; +assert.closeTo = function(act, exp, delta, msg) { + new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); +}; +assert.approximately = function(act, exp, delta, msg) { + new Assertion(act, msg, assert.approximately, true).to.be.approximately( + exp, + delta + ); +}; +assert.sameMembers = function(set1, set2, msg) { + new Assertion(set1, msg, assert.sameMembers, true).to.have.same.members(set2); +}; +assert.notSameMembers = function(set1, set2, msg) { + new Assertion( + set1, + msg, + assert.notSameMembers, + true + ).to.not.have.same.members(set2); +}; +assert.sameDeepMembers = function(set1, set2, msg) { + new Assertion( + set1, + msg, + assert.sameDeepMembers, + true + ).to.have.same.deep.members(set2); +}; +assert.notSameDeepMembers = function(set1, set2, msg) { + new Assertion( + set1, + msg, + assert.notSameDeepMembers, + true + ).to.not.have.same.deep.members(set2); +}; +assert.sameOrderedMembers = function(set1, set2, msg) { + new Assertion( + set1, + msg, + assert.sameOrderedMembers, + true + ).to.have.same.ordered.members(set2); +}; +assert.notSameOrderedMembers = function(set1, set2, msg) { + new Assertion( + set1, + msg, + assert.notSameOrderedMembers, + true + ).to.not.have.same.ordered.members(set2); +}; +assert.sameDeepOrderedMembers = function(set1, set2, msg) { + new Assertion( + set1, + msg, + assert.sameDeepOrderedMembers, + true + ).to.have.same.deep.ordered.members(set2); +}; +assert.notSameDeepOrderedMembers = function(set1, set2, msg) { + new Assertion( + set1, + msg, + assert.notSameDeepOrderedMembers, + true + ).to.not.have.same.deep.ordered.members(set2); +}; +assert.includeMembers = function(superset, subset, msg) { + new Assertion(superset, msg, assert.includeMembers, true).to.include.members( + subset + ); +}; +assert.notIncludeMembers = function(superset, subset, msg) { + new Assertion( + superset, + msg, + assert.notIncludeMembers, + true + ).to.not.include.members(subset); +}; +assert.includeDeepMembers = function(superset, subset, msg) { + new Assertion( + superset, + msg, + assert.includeDeepMembers, + true + ).to.include.deep.members(subset); +}; +assert.notIncludeDeepMembers = function(superset, subset, msg) { + new Assertion( + superset, + msg, + assert.notIncludeDeepMembers, + true + ).to.not.include.deep.members(subset); +}; +assert.includeOrderedMembers = function(superset, subset, msg) { + new Assertion( + superset, + msg, + assert.includeOrderedMembers, + true + ).to.include.ordered.members(subset); +}; +assert.notIncludeOrderedMembers = function(superset, subset, msg) { + new Assertion( + superset, + msg, + assert.notIncludeOrderedMembers, + true + ).to.not.include.ordered.members(subset); +}; +assert.includeDeepOrderedMembers = function(superset, subset, msg) { + new Assertion( + superset, + msg, + assert.includeDeepOrderedMembers, + true + ).to.include.deep.ordered.members(subset); +}; +assert.notIncludeDeepOrderedMembers = function(superset, subset, msg) { + new Assertion( + superset, + msg, + assert.notIncludeDeepOrderedMembers, + true + ).to.not.include.deep.ordered.members(subset); +}; +assert.oneOf = function(inList, list, msg) { + new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); +}; +assert.isIterable = function(obj, msg) { + if (obj == void 0 || !obj[Symbol.iterator]) { + msg = msg ? `${msg} expected ${inspect2(obj)} to be an iterable` : `expected ${inspect2(obj)} to be an iterable`; + throw new AssertionError(msg, void 0, assert.isIterable); + } +}; +assert.changes = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); +}; +assert.changesBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion(fn, msg, assert.changesBy, true).to.change(obj, prop).by(delta); +}; +assert.doesNotChange = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion(fn, msg, assert.doesNotChange, true).to.not.change( + obj, + prop + ); +}; +assert.changesButNotBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion(fn, msg, assert.changesButNotBy, true).to.change(obj, prop).but.not.by(delta); +}; +assert.increases = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion(fn, msg, assert.increases, true).to.increase(obj, prop); +}; +assert.increasesBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion(fn, msg, assert.increasesBy, true).to.increase(obj, prop).by(delta); +}; +assert.doesNotIncrease = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion(fn, msg, assert.doesNotIncrease, true).to.not.increase( + obj, + prop + ); +}; +assert.increasesButNotBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion(fn, msg, assert.increasesButNotBy, true).to.increase(obj, prop).but.not.by(delta); +}; +assert.decreases = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion(fn, msg, assert.decreases, true).to.decrease(obj, prop); +}; +assert.decreasesBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion(fn, msg, assert.decreasesBy, true).to.decrease(obj, prop).by(delta); +}; +assert.doesNotDecrease = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion(fn, msg, assert.doesNotDecrease, true).to.not.decrease( + obj, + prop + ); +}; +assert.doesNotDecreaseBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + return new Assertion(fn, msg, assert.doesNotDecreaseBy, true).to.not.decrease(obj, prop).by(delta); +}; +assert.decreasesButNotBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion(fn, msg, assert.decreasesButNotBy, true).to.decrease(obj, prop).but.not.by(delta); +}; +assert.ifError = function(val) { + if (val) { + throw val; + } +}; +assert.isExtensible = function(obj, msg) { + new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; +}; +assert.isNotExtensible = function(obj, msg) { + new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; +}; +assert.isSealed = function(obj, msg) { + new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; +}; +assert.isNotSealed = function(obj, msg) { + new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; +}; +assert.isFrozen = function(obj, msg) { + new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; +}; +assert.isNotFrozen = function(obj, msg) { + new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; +}; +assert.isEmpty = function(val, msg) { + new Assertion(val, msg, assert.isEmpty, true).to.be.empty; +}; +assert.isNotEmpty = function(val, msg) { + new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; +}; +assert.containsSubset = function(val, exp, msg) { + new Assertion(val, msg).to.containSubset(exp); +}; +assert.doesNotContainSubset = function(val, exp, msg) { + new Assertion(val, msg).to.not.containSubset(exp); +}; +var aliases = [ + ["isOk", "ok"], + ["isNotOk", "notOk"], + ["throws", "throw"], + ["throws", "Throw"], + ["isExtensible", "extensible"], + ["isNotExtensible", "notExtensible"], + ["isSealed", "sealed"], + ["isNotSealed", "notSealed"], + ["isFrozen", "frozen"], + ["isNotFrozen", "notFrozen"], + ["isEmpty", "empty"], + ["isNotEmpty", "notEmpty"], + ["isCallable", "isFunction"], + ["isNotCallable", "isNotFunction"], + ["containsSubset", "containSubset"] +]; +for (const [name, as] of aliases) { + assert[as] = assert[name]; +} + +// lib/chai.js +var used = []; +function use(fn) { + const exports = { + use, + AssertionError, + util: utils_exports, + config, + expect, + assert, + Assertion, + ...should_exports + }; + if (!~used.indexOf(fn)) { + fn(exports, utils_exports); + used.push(fn); + } + return exports; +} +__name(use, "use"); +export { + Assertion, + AssertionError, + Should, + assert, + config, + expect, + should, + use, + utils_exports as util +}; +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - isProxyEnabled helper + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - addLengthGuard utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - proxify utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ +/*! + * Chai - compareByInspect utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ +/*! + * Chai - getOwnEnumerablePropertySymbols utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ +/*! + * Chai - getOwnEnumerableProperties utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ +/*! + * Chai - isNaN utility + * Copyright(c) 2012-2015 Sakthipriyan Vairamani + * MIT Licensed + */ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ +/*! Bundled license information: + +deep-eql/index.js: + (*! + * deep-eql + * Copyright(c) 2013 Jake Luer + * MIT Licensed + *) + (*! + * Check to see if the MemoizeMap has recorded a result of the two operands + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @returns {Boolean|null} result + *) + (*! + * Set the result of the equality into the MemoizeMap + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @param {Boolean} result + *) + (*! + * Primary Export + *) + (*! + * The main logic of the `deepEqual` function. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match + *) + (*! + * Compare two Regular Expressions for equality. + * + * @param {RegExp} leftHandOperand + * @param {RegExp} rightHandOperand + * @return {Boolean} result + *) + (*! + * Compare two Sets/Maps for equality. Faster than other equality functions. + * + * @param {Set} leftHandOperand + * @param {Set} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Simple equality for generator objects such as those returned by generator functions. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Determine if the given object has an @@iterator function. + * + * @param {Object} target + * @return {Boolean} `true` if the object has an @@iterator function. + *) + (*! + * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. + * This will consume the iterator - which could have side effects depending on the @@iterator implementation. + * + * @param {Object} target + * @returns {Array} an array of entries from the @@iterator function + *) + (*! + * Gets all entries from a Generator. This will consume the generator - which could have side effects. + * + * @param {Generator} target + * @returns {Array} an array of entries from the Generator. + *) + (*! + * Gets all own and inherited enumerable keys from a target. + * + * @param {Object} target + * @returns {Array} an array of own and inherited enumerable keys from the target. + *) + (*! + * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of + * each key. If any value of the given key is not equal, the function will return false (early). + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` + * for each enumerable key in the object. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Returns true if the argument is a primitive. + * + * This intentionally returns true for all objects that can be compared by reference, + * including functions and symbols. + * + * @param {Mixed} value + * @return {Boolean} result + *) +*/ diff --git a/node_modules/chai/lib/chai.js b/node_modules/chai/lib/chai.js new file mode 100644 index 0000000000..19186896f9 --- /dev/null +++ b/node_modules/chai/lib/chai.js @@ -0,0 +1,66 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +import * as util from './chai/utils/index.js'; +import {AssertionError} from 'assertion-error'; +import {config} from './chai/config.js'; +import './chai/core/assertions.js'; +import {expect} from './chai/interface/expect.js'; +import {Assertion} from './chai/assertion.js'; +import * as should from './chai/interface/should.js'; +import {assert} from './chai/interface/assert.js'; + +const used = []; + +// Assertion Error +export {AssertionError}; + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai. + * + * @param {Function} fn + * @returns {this} for chaining + * @public + */ +export function use(fn) { + const exports = { + use, + AssertionError, + util, + config, + expect, + assert, + Assertion, + ...should + }; + + if (!~used.indexOf(fn)) { + fn(exports, util); + used.push(fn); + } + + return exports; +} + +// Utility Functions +export {util}; + +// Configuration +export {config}; + +// Primary `Assertion` prototype +export * from './chai/assertion.js'; + +// Expect interface +export * from './chai/interface/expect.js'; + +// Should interface +export * from './chai/interface/should.js'; + +// Assert interface +export * from './chai/interface/assert.js'; diff --git a/node_modules/chai/lib/chai/assertion.js b/node_modules/chai/lib/chai/assertion.js new file mode 100644 index 0000000000..95209fbe7f --- /dev/null +++ b/node_modules/chai/lib/chai/assertion.js @@ -0,0 +1,204 @@ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +import {config} from './config.js'; +import {AssertionError} from 'assertion-error'; +import * as util from './utils/index.js'; + +export class Assertion { + /** @type {{}} */ + __flags = {}; + + /** + * Creates object for chaining. + * `Assertion` objects contain metadata in the form of flags. Three flags can + * be assigned during instantiation by passing arguments to this constructor: + * + * - `object`: This flag contains the target of the assertion. For example, in + * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will + * contain `numKittens` so that the `equal` assertion can reference it when + * needed. + * + * - `message`: This flag contains an optional custom error message to be + * prepended to the error message that's generated by the assertion when it + * fails. + * + * - `ssfi`: This flag stands for "start stack function indicator". It + * contains a function reference that serves as the starting point for + * removing frames from the stack trace of the error that's created by the + * assertion when it fails. The goal is to provide a cleaner stack trace to + * end users by removing Chai's internal functions. Note that it only works + * in environments that support `Error.captureStackTrace`, and only when + * `Chai.config.includeStack` hasn't been set to `false`. + * + * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag + * should retain its current value, even as assertions are chained off of + * this object. This is usually set to `true` when creating a new assertion + * from within another assertion. It's also temporarily set to `true` before + * an overwritten assertion gets called by the overwriting assertion. + * + * - `eql`: This flag contains the deepEqual function to be used by the assertion. + * + * @param {unknown} obj target of the assertion + * @param {string} [msg] (optional) custom error message + * @param {Function} [ssfi] (optional) starting point for removing stack frames + * @param {boolean} [lockSsfi] (optional) whether or not the ssfi flag is locked + */ + constructor(obj, msg, ssfi, lockSsfi) { + util.flag(this, 'ssfi', ssfi || Assertion); + util.flag(this, 'lockSsfi', lockSsfi); + util.flag(this, 'object', obj); + util.flag(this, 'message', msg); + util.flag(this, 'eql', config.deepEqual || util.eql); + + return util.proxify(this); + } + + /** @returns {boolean} */ + static get includeStack() { + console.warn( + 'Assertion.includeStack is deprecated, use chai.config.includeStack instead.' + ); + return config.includeStack; + } + + /** @param {boolean} value */ + static set includeStack(value) { + console.warn( + 'Assertion.includeStack is deprecated, use chai.config.includeStack instead.' + ); + config.includeStack = value; + } + + /** @returns {boolean} */ + static get showDiff() { + console.warn( + 'Assertion.showDiff is deprecated, use chai.config.showDiff instead.' + ); + return config.showDiff; + } + + /** @param {boolean} value */ + static set showDiff(value) { + console.warn( + 'Assertion.showDiff is deprecated, use chai.config.showDiff instead.' + ); + config.showDiff = value; + } + + /** + * @param {string} name + * @param {Function} fn + */ + static addProperty(name, fn) { + util.addProperty(this.prototype, name, fn); + } + + /** + * @param {string} name + * @param {Function} fn + */ + static addMethod(name, fn) { + util.addMethod(this.prototype, name, fn); + } + + /** + * @param {string} name + * @param {Function} fn + * @param {Function} chainingBehavior + */ + static addChainableMethod(name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + } + + /** + * @param {string} name + * @param {Function} fn + */ + static overwriteProperty(name, fn) { + util.overwriteProperty(this.prototype, name, fn); + } + + /** + * @param {string} name + * @param {Function} fn + */ + static overwriteMethod(name, fn) { + util.overwriteMethod(this.prototype, name, fn); + } + + /** + * @param {string} name + * @param {Function} fn + * @param {Function} chainingBehavior + */ + static overwriteChainableMethod(name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + } + + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {unknown} _expr to be tested + * @param {string | Function} msg or function that returns message to display if expression fails + * @param {string | Function} _negateMsg or function that returns negatedMessage to display if negated expression fails + * @param {unknown} expected value (remember to check for negation) + * @param {unknown} _actual (optional) will default to `this.obj` + * @param {boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @returns {void} + */ + assert(_expr, msg, _negateMsg, expected, _actual, showDiff) { + const ok = util.test(this, arguments); + if (false !== showDiff) showDiff = true; + if (undefined === expected && undefined === _actual) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + msg = util.getMessage(this, arguments); + const actual = util.getActual(this, arguments); + /** @type {Record} */ + const assertionErrorObjectProperties = { + actual: actual, + expected: expected, + showDiff: showDiff + }; + + const operator = util.getOperator(this, arguments); + if (operator) { + assertionErrorObjectProperties.operator = operator; + } + + throw new AssertionError( + msg, + assertionErrorObjectProperties, + // @ts-expect-error Not sure what to do about these types yet + config.includeStack ? this.assert : util.flag(this, 'ssfi') + ); + } + } + + /** + * Quick reference to stored `actual` value for plugin developers. + * + * @returns {unknown} + */ + get _obj() { + return util.flag(this, 'object'); + } + + /** + * Quick reference to stored `actual` value for plugin developers. + * + * @param {unknown} val + */ + set _obj(val) { + util.flag(this, 'object', val); + } +} diff --git a/node_modules/chai/lib/chai/config.js b/node_modules/chai/lib/chai/config.js new file mode 100644 index 0000000000..07a1bbee76 --- /dev/null +++ b/node_modules/chai/lib/chai/config.js @@ -0,0 +1,112 @@ +export const config = { + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {boolean} + * @public + */ + includeStack: false, + + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {boolean} + * @public + */ + showDiff: true, + + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {number} + * @public + */ + truncateThreshold: 40, + + /** + * ### config.useProxy + * + * User configurable property, defines if chai will use a Proxy to throw + * an error when a non-existent property is read, which protects users + * from typos when using property-based assertions. + * + * Set it to false if you want to disable this feature. + * + * chai.config.useProxy = false; // disable use of Proxy + * + * This feature is automatically disabled regardless of this config value + * in environments that don't support proxies. + * + * @param {boolean} + * @public + */ + useProxy: true, + + /** + * ### config.proxyExcludedKeys + * + * User configurable property, defines which properties should be ignored + * instead of throwing an error if they do not exist on the assertion. + * This is only applied if the environment Chai is running in supports proxies and + * if the `useProxy` configuration setting is enabled. + * By default, `then` and `inspect` will not throw an error if they do not exist on the + * assertion object because the `.inspect` property is read by `util.inspect` (for example, when + * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. + * + * // By default these keys will not throw an error if they do not exist on the assertion object + * chai.config.proxyExcludedKeys = ['then', 'inspect']; + * + * @param {Array} + * @public + */ + proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON'], + + /** + * ### config.deepEqual + * + * User configurable property, defines which a custom function to use for deepEqual + * comparisons. + * By default, the function used is the one from the `deep-eql` package without custom comparator. + * + * // use a custom comparator + * chai.config.deepEqual = (expected, actual) => { + * return chai.util.eql(expected, actual, { + * comparator: (expected, actual) => { + * // for non number comparison, use the default behavior + * if(typeof expected !== 'number') return null; + * // allow a difference of 10 between compared numbers + * return typeof actual === 'number' && Math.abs(actual - expected) < 10 + * } + * }) + * }; + * + * @param {Function} + * @public + */ + deepEqual: null +}; diff --git a/node_modules/chai/lib/chai/core/assertions.js b/node_modules/chai/lib/chai/core/assertions.js new file mode 100644 index 0000000000..53184fd8cd --- /dev/null +++ b/node_modules/chai/lib/chai/core/assertions.js @@ -0,0 +1,4156 @@ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +import {Assertion} from '../assertion.js'; +import {AssertionError} from 'assertion-error'; +import * as _ from '../utils/index.js'; +import {config} from '../config.js'; + +const {flag} = _; + +/** + * ### Language Chains + * + * The following are provided as chainable getters to improve the readability + * of your assertions. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - which + * - and + * - has + * - have + * - with + * - at + * - of + * - same + * - but + * - does + * - still + * - also + * + * @name language chains + * @namespace BDD + * @public + */ + +[ + 'to', + 'be', + 'been', + 'is', + 'and', + 'has', + 'have', + 'with', + 'that', + 'which', + 'at', + 'of', + 'same', + 'but', + 'does', + 'still', + 'also' +].forEach(function (chain) { + Assertion.addProperty(chain); +}); + +/** + * ### .not + * + * Negates all assertions that follow in the chain. + * + * expect(function () {}).to.not.throw(); + * expect({a: 1}).to.not.have.property('b'); + * expect([1, 2]).to.be.an('array').that.does.not.include(3); + * + * Just because you can negate any assertion with `.not` doesn't mean you + * should. With great power comes great responsibility. It's often best to + * assert that the one expected output was produced, rather than asserting + * that one of countless unexpected outputs wasn't produced. See individual + * assertions for specific guidance. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.equal(1); // Not recommended + * + * @name not + * @namespace BDD + * @public + */ + +Assertion.addProperty('not', function () { + flag(this, 'negate', true); +}); + +/** + * ### .deep + * + * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property` + * assertions that follow in the chain to use deep equality instead of strict + * (`===`) equality. See the `deep-eql` project page for info on the deep + * equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]); + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * @name deep + * @namespace BDD + * @public + */ + +Assertion.addProperty('deep', function () { + flag(this, 'deep', true); +}); + +/** + * ### .nested + * + * Enables dot- and bracket-notation in all `.property` and `.include` + * assertions that follow in the chain. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); + * + * `.nested` cannot be combined with `.own`. + * + * @name nested + * @namespace BDD + * @public + */ + +Assertion.addProperty('nested', function () { + flag(this, 'nested', true); +}); + +/** + * ### .own + * + * Causes all `.property` and `.include` assertions that follow in the chain + * to ignore inherited properties. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.property('b'); + * expect({a: 1}).to.not.have.own.property('b'); + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * `.own` cannot be combined with `.nested`. + * + * @name own + * @namespace BDD + * @public + */ + +Assertion.addProperty('own', function () { + flag(this, 'own', true); +}); + +/** + * ### .ordered + * + * Causes all `.members` assertions that follow in the chain to require that + * members be in the same order. + * + * expect([1, 2]).to.have.ordered.members([1, 2]) + * .but.not.have.ordered.members([2, 1]); + * + * When `.include` and `.ordered` are combined, the ordering begins at the + * start of both arrays. + * + * expect([1, 2, 3]).to.include.ordered.members([1, 2]) + * .but.not.include.ordered.members([2, 3]); + * + * @name ordered + * @namespace BDD + * @public + */ + +Assertion.addProperty('ordered', function () { + flag(this, 'ordered', true); +}); + +/** + * ### .any + * + * Causes all `.keys` assertions that follow in the chain to only require that + * the target have at least one of the given keys. This is the opposite of + * `.all`, which requires that the target have all of the given keys. + * + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name any + * @namespace BDD + * @public + */ + +Assertion.addProperty('any', function () { + flag(this, 'any', true); + flag(this, 'all', false); +}); + +/** + * ### .all + * + * Causes all `.keys` assertions that follow in the chain to require that the + * target have all of the given keys. This is the opposite of `.any`, which + * only requires that the target have at least one of the given keys. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` are + * added earlier in the chain. However, it's often best to add `.all` anyway + * because it improves readability. + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name all + * @namespace BDD + * @public + */ +Assertion.addProperty('all', function () { + flag(this, 'all', true); + flag(this, 'any', false); +}); + +const functionTypes = { + function: [ + 'function', + 'asyncfunction', + 'generatorfunction', + 'asyncgeneratorfunction' + ], + asyncfunction: ['asyncfunction', 'asyncgeneratorfunction'], + generatorfunction: ['generatorfunction', 'asyncgeneratorfunction'], + asyncgeneratorfunction: ['asyncgeneratorfunction'] +}; + +/** + * ### .a(type[, msg]) + * + * Asserts that the target's type is equal to the given string `type`. Types + * are case insensitive. See the utility file `./type-detect.js` for info on the + * type detection algorithm. + * + * expect('foo').to.be.a('string'); + * expect({a: 1}).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * expect(new Error).to.be.an('error'); + * expect(Promise.resolve()).to.be.a('promise'); + * expect(new Float32Array).to.be.a('float32array'); + * expect(Symbol()).to.be.a('symbol'); + * + * `.a` supports objects that have a custom type set via `Symbol.toStringTag`. + * + * var myObj = { + * [Symbol.toStringTag]: 'myCustomType' + * }; + * + * expect(myObj).to.be.a('myCustomType').but.not.an('object'); + * + * It's often best to use `.a` to check a target's type before making more + * assertions on the same target. That way, you avoid unexpected behavior from + * any assertion that does different things based on the target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.a`. However, it's often best to + * assert that the target is the expected type, rather than asserting that it + * isn't one of many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.an('array'); // Not recommended + * + * `.a` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * expect(1).to.be.a('string', 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.a('string'); + * + * `.a` can also be used as a language chain to improve the readability of + * your assertions. + * + * expect({b: 2}).to.have.a.property('b'); + * + * The alias `.an` can be used interchangeably with `.a`. + * + * @name a + * @alias an + * @param {string} type + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function an(type, msg) { + if (msg) flag(this, 'message', msg); + type = type.toLowerCase(); + let obj = flag(this, 'object'), + article = ~['a', 'e', 'i', 'o', 'u'].indexOf(type.charAt(0)) ? 'an ' : 'a '; + + const detectedType = _.type(obj).toLowerCase(); + + if (functionTypes['function'].includes(type)) { + this.assert( + functionTypes[type].includes(detectedType), + 'expected #{this} to be ' + article + type, + 'expected #{this} not to be ' + article + type + ); + } else { + this.assert( + type === detectedType, + 'expected #{this} to be ' + article + type, + 'expected #{this} not to be ' + article + type + ); + } +} + +Assertion.addChainableMethod('an', an); +Assertion.addChainableMethod('a', an); + +/** + * @param {unknown} a + * @param {unknown} b + * @returns {boolean} + */ +function SameValueZero(a, b) { + return (_.isNaN(a) && _.isNaN(b)) || a === b; +} + +/** */ +function includeChainingBehavior() { + flag(this, 'contains', true); +} + +/** + * ### .include(val[, msg]) + * + * When the target is a string, `.include` asserts that the given string `val` + * is a substring of the target. + * + * expect('foobar').to.include('foo'); + * + * When the target is an array, `.include` asserts that the given `val` is a + * member of the target. + * + * expect([1, 2, 3]).to.include(2); + * + * When the target is an object, `.include` asserts that the given object + * `val`'s properties are a subset of the target's properties. + * + * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2}); + * + * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a + * member of the target. SameValueZero equality algorithm is used. + * + * expect(new Set([1, 2])).to.include(2); + * + * When the target is a Map, `.include` asserts that the given `val` is one of + * the values of the target. SameValueZero equality algorithm is used. + * + * expect(new Map([['a', 1], ['b', 2]])).to.include(2); + * + * Because `.include` does different things based on the target's type, it's + * important to check the target's type before using `.include`. See the `.a` + * doc for info on testing a target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * + * By default, strict (`===`) equality is used to compare array members and + * object properties. Add `.deep` earlier in the chain to use deep equality + * instead (WeakSet targets are not supported). See the `deep-eql` project + * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * By default, all of the target's properties are searched when working with + * objects. This includes properties that are inherited and/or non-enumerable. + * Add `.own` earlier in the chain to exclude the target's inherited + * properties from the search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * Note that a target object is always only searched for `val`'s own + * enumerable properties. + * + * `.deep` and `.own` can be combined. + * + * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2}); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.include`. + * + * expect('foobar').to.not.include('taco'); + * expect([1, 2, 3]).to.not.include(4); + * + * However, it's dangerous to negate `.include` when the target is an object. + * The problem is that it creates uncertain expectations by asserting that the + * target object doesn't have all of `val`'s key/value pairs but may or may + * not have some of them. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target object isn't even expected to have `val`'s keys, it's + * often best to assert exactly that. + * + * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended + * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended + * + * When the target object is expected to have `val`'s keys, it's often best to + * assert that each of the properties has its expected value, rather than + * asserting that each property doesn't have one of many unexpected values. + * + * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended + * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended + * + * `.include` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.include(4, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.include(4); + * + * `.include` can also be used as a language chain, causing all `.members` and + * `.keys` assertions that follow in the chain to require the target to be a + * superset of the expected set, rather than an identical set. Note that + * `.members` ignores duplicates in the subset when `.include` is added. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * Note that adding `.any` earlier in the chain causes the `.keys` assertion + * to ignore `.include`. + * + * // Both assertions are identical + * expect({a: 1}).to.include.any.keys('a', 'b'); + * expect({a: 1}).to.have.any.keys('a', 'b'); + * + * The aliases `.includes`, `.contain`, and `.contains` can be used + * interchangeably with `.include`. + * + * @name include + * @alias contain + * @alias includes + * @alias contains + * @param {unknown} val + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function include(val, msg) { + if (msg) flag(this, 'message', msg); + + let obj = flag(this, 'object'), + objType = _.type(obj).toLowerCase(), + flagMsg = flag(this, 'message'), + negate = flag(this, 'negate'), + ssfi = flag(this, 'ssfi'), + isDeep = flag(this, 'deep'), + descriptor = isDeep ? 'deep ' : '', + isEql = isDeep ? flag(this, 'eql') : SameValueZero; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + let included = false; + + switch (objType) { + case 'string': + included = obj.indexOf(val) !== -1; + break; + + case 'weakset': + if (isDeep) { + throw new AssertionError( + flagMsg + 'unable to use .deep.include with WeakSet', + undefined, + ssfi + ); + } + + included = obj.has(val); + break; + + case 'map': + obj.forEach(function (item) { + included = included || isEql(item, val); + }); + break; + + case 'set': + if (isDeep) { + obj.forEach(function (item) { + included = included || isEql(item, val); + }); + } else { + included = obj.has(val); + } + break; + + case 'array': + if (isDeep) { + included = obj.some(function (item) { + return isEql(item, val); + }); + } else { + included = obj.indexOf(val) !== -1; + } + break; + + default: { + // This block is for asserting a subset of properties in an object. + // `_.expectTypes` isn't used here because `.include` should work with + // objects with a custom `@@toStringTag`. + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + + 'the given combination of arguments (' + + objType + + ' and ' + + _.type(val).toLowerCase() + + ')' + + ' is invalid for this assertion. ' + + 'You can use an array, a map, an object, a set, a string, ' + + 'or a weakset instead of a ' + + _.type(val).toLowerCase(), + undefined, + ssfi + ); + } + + let props = Object.keys(val); + let firstErr = null; + let numErrs = 0; + + props.forEach(function (prop) { + let propAssertion = new Assertion(obj); + _.transferFlags(this, propAssertion, true); + flag(propAssertion, 'lockSsfi', true); + + if (!negate || props.length === 1) { + propAssertion.property(prop, val[prop]); + return; + } + + try { + propAssertion.property(prop, val[prop]); + } catch (err) { + if (!_.checkError.compatibleConstructor(err, AssertionError)) { + throw err; + } + if (firstErr === null) firstErr = err; + numErrs++; + } + }, this); + + // When validating .not.include with multiple properties, we only want + // to throw an assertion error if all of the properties are included, + // in which case we throw the first property assertion error that we + // encountered. + if (negate && props.length > 1 && numErrs === props.length) { + throw firstErr; + } + return; + } + } + + // Assert inclusion in collection or substring in a string. + this.assert( + included, + 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val), + 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val) + ); +} + +Assertion.addChainableMethod('include', include, includeChainingBehavior); +Assertion.addChainableMethod('contain', include, includeChainingBehavior); +Assertion.addChainableMethod('contains', include, includeChainingBehavior); +Assertion.addChainableMethod('includes', include, includeChainingBehavior); + +/** + * ### .ok + * + * Asserts that the target is a truthy value (considered `true` in boolean context). + * However, it's often best to assert that the target is strictly (`===`) or + * deeply equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.ok; // Not recommended + * + * expect(true).to.be.true; // Recommended + * expect(true).to.be.ok; // Not recommended + * + * Add `.not` earlier in the chain to negate `.ok`. + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.not.be.ok; // Not recommended + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.ok; // Not recommended + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.be.ok; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.be.ok; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.ok; + * + * @name ok + * @namespace BDD + * @public + */ +Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object'), + 'expected #{this} to be truthy', + 'expected #{this} to be falsy' + ); +}); + +/** + * ### .true + * + * Asserts that the target is strictly (`===`) equal to `true`. + * + * expect(true).to.be.true; + * + * Add `.not` earlier in the chain to negate `.true`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `true`. + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.true; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.true; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.true; + * + * @name true + * @namespace BDD + * @public + */ +Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object'), + 'expected #{this} to be true', + 'expected #{this} to be false', + flag(this, 'negate') ? false : true + ); +}); + +Assertion.addProperty('numeric', function () { + const object = flag(this, 'object'); + + this.assert( + ['Number', 'BigInt'].includes(_.type(object)), + 'expected #{this} to be numeric', + 'expected #{this} to not be numeric', + flag(this, 'negate') ? false : true + ); +}); + +/** + * ### .callable + * + * Asserts that the target a callable function. + * + * expect(console.log).to.be.callable; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect('not a function', 'nooo why fail??').to.be.callable; + * + * @name callable + * @namespace BDD + * @public + */ +Assertion.addProperty('callable', function () { + const val = flag(this, 'object'); + const ssfi = flag(this, 'ssfi'); + const message = flag(this, 'message'); + const msg = message ? `${message}: ` : ''; + const negate = flag(this, 'negate'); + + const assertionMessage = negate + ? `${msg}expected ${_.inspect(val)} not to be a callable function` + : `${msg}expected ${_.inspect(val)} to be a callable function`; + + const isCallable = [ + 'Function', + 'AsyncFunction', + 'GeneratorFunction', + 'AsyncGeneratorFunction' + ].includes(_.type(val)); + + if ((isCallable && negate) || (!isCallable && !negate)) { + throw new AssertionError(assertionMessage, undefined, ssfi); + } +}); + +/** + * ### .false + * + * Asserts that the target is strictly (`===`) equal to `false`. + * + * expect(false).to.be.false; + * + * Add `.not` earlier in the chain to negate `.false`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `false`. + * + * expect(true).to.be.true; // Recommended + * expect(true).to.not.be.false; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.false; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(true, 'nooo why fail??').to.be.false; + * + * @name false + * @namespace BDD + * @public + */ +Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object'), + 'expected #{this} to be false', + 'expected #{this} to be true', + flag(this, 'negate') ? true : false + ); +}); + +/** + * ### .null + * + * Asserts that the target is strictly (`===`) equal to `null`. + * + * expect(null).to.be.null; + * + * Add `.not` earlier in the chain to negate `.null`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `null`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.null; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.null; + * + * @name null + * @namespace BDD + * @public + */ +Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object'), + 'expected #{this} to be null', + 'expected #{this} not to be null' + ); +}); + +/** + * ### .undefined + * + * Asserts that the target is strictly (`===`) equal to `undefined`. + * + * expect(undefined).to.be.undefined; + * + * Add `.not` earlier in the chain to negate `.undefined`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `undefined`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.undefined; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.undefined; + * + * @name undefined + * @namespace BDD + * @public + */ +Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object'), + 'expected #{this} to be undefined', + 'expected #{this} not to be undefined' + ); +}); + +/** + * ### .NaN + * + * Asserts that the target is exactly `NaN`. + * + * expect(NaN).to.be.NaN; + * + * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `NaN`. + * + * expect('foo').to.equal('foo'); // Recommended + * expect('foo').to.not.be.NaN; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.NaN; + * + * @name NaN + * @namespace BDD + * @public + */ +Assertion.addProperty('NaN', function () { + this.assert( + _.isNaN(flag(this, 'object')), + 'expected #{this} to be NaN', + 'expected #{this} not to be NaN' + ); +}); + +/** + * ### .exist + * + * Asserts that the target is not strictly (`===`) equal to either `null` or + * `undefined`. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.exist; // Not recommended + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.exist; // Not recommended + * + * Add `.not` earlier in the chain to negate `.exist`. + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.exist; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.exist; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(null, 'nooo why fail??').to.exist; + * + * The alias `.exists` can be used interchangeably with `.exist`. + * + * @name exist + * @alias exists + * @namespace BDD + * @public + */ +function assertExist() { + let val = flag(this, 'object'); + this.assert( + val !== null && val !== undefined, + 'expected #{this} to exist', + 'expected #{this} to not exist' + ); +} + +Assertion.addProperty('exist', assertExist); +Assertion.addProperty('exists', assertExist); + +/** + * ### .empty + * + * When the target is a string or array, `.empty` asserts that the target's + * `length` property is strictly (`===`) equal to `0`. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * + * When the target is a map or set, `.empty` asserts that the target's `size` + * property is strictly equal to `0`. + * + * expect(new Set()).to.be.empty; + * expect(new Map()).to.be.empty; + * + * When the target is a non-function object, `.empty` asserts that the target + * doesn't have any own enumerable properties. Properties with Symbol-based + * keys are excluded from the count. + * + * expect({}).to.be.empty; + * + * Because `.empty` does different things based on the target's type, it's + * important to check the target's type before using `.empty`. See the `.a` + * doc for info on testing a target's type. + * + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.empty`. However, it's often + * best to assert that the target contains its expected number of values, + * rather than asserting that it's not empty. + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.not.be.empty; // Not recommended + * + * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended + * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended + * + * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended + * expect({a: 1}).to.not.be.empty; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect([1, 2, 3], 'nooo why fail??').to.be.empty; + * + * @name empty + * @namespace BDD + * @public + */ +Assertion.addProperty('empty', function () { + let val = flag(this, 'object'), + ssfi = flag(this, 'ssfi'), + flagMsg = flag(this, 'message'), + itemsCount; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + switch (_.type(val).toLowerCase()) { + case 'array': + case 'string': + itemsCount = val.length; + break; + case 'map': + case 'set': + itemsCount = val.size; + break; + case 'weakmap': + case 'weakset': + throw new AssertionError( + flagMsg + '.empty was passed a weak collection', + undefined, + ssfi + ); + case 'function': { + const msg = flagMsg + '.empty was passed a function ' + _.getName(val); + throw new AssertionError(msg.trim(), undefined, ssfi); + } + default: + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + '.empty was passed non-string primitive ' + _.inspect(val), + undefined, + ssfi + ); + } + itemsCount = Object.keys(val).length; + } + + this.assert( + 0 === itemsCount, + 'expected #{this} to be empty', + 'expected #{this} not to be empty' + ); +}); + +/** + * ### .arguments + * + * Asserts that the target is an `arguments` object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * test(); + * + * Add `.not` earlier in the chain to negate `.arguments`. However, it's often + * best to assert which type the target is expected to be, rather than + * asserting that it’s not an `arguments` object. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.arguments; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({}, 'nooo why fail??').to.be.arguments; + * + * The alias `.Arguments` can be used interchangeably with `.arguments`. + * + * @name arguments + * @alias Arguments + * @namespace BDD + * @public + */ +function checkArguments() { + let obj = flag(this, 'object'), + type = _.type(obj); + this.assert( + 'Arguments' === type, + 'expected #{this} to be arguments but got ' + type, + 'expected #{this} to not be arguments' + ); +} + +Assertion.addProperty('arguments', checkArguments); +Assertion.addProperty('Arguments', checkArguments); + +/** + * ### .equal(val[, msg]) + * + * Asserts that the target is strictly (`===`) equal to the given `val`. + * + * expect(1).to.equal(1); + * expect('foo').to.equal('foo'); + * + * Add `.deep` earlier in the chain to use deep equality instead. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) equals `[1, 2]` + * expect([1, 2]).to.deep.equal([1, 2]); + * expect([1, 2]).to.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.equal`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to one of countless unexpected values. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.equal(2); // Not recommended + * + * `.equal` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.equal(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.equal(2); + * + * The aliases `.equals` and `eq` can be used interchangeably with `.equal`. + * + * @name equal + * @alias equals + * @alias eq + * @param {unknown} val + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertEqual(val, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'); + if (flag(this, 'deep')) { + let prevLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + this.eql(val); + flag(this, 'lockSsfi', prevLockSsfi); + } else { + this.assert( + val === obj, + 'expected #{this} to equal #{exp}', + 'expected #{this} to not equal #{exp}', + val, + this._obj, + true + ); + } +} + +Assertion.addMethod('equal', assertEqual); +Assertion.addMethod('equals', assertEqual); +Assertion.addMethod('eq', assertEqual); + +/** + * ### .eql(obj[, msg]) + * + * Asserts that the target is deeply equal to the given `obj`. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object is deeply (but not strictly) equal to {a: 1} + * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); + * + * // Target array is deeply (but not strictly) equal to [1, 2] + * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.eql`. However, it's often best + * to assert that the target is deeply equal to its expected value, rather + * than not deeply equal to one of countless unexpected values. + * + * expect({a: 1}).to.eql({a: 1}); // Recommended + * expect({a: 1}).to.not.eql({b: 2}); // Not recommended + * + * `.eql` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.eql({b: 2}); + * + * The alias `.eqls` can be used interchangeably with `.eql`. + * + * The `.deep.equal` assertion is almost identical to `.eql` but with one + * difference: `.deep.equal` causes deep equality comparisons to also be used + * for any other assertions that follow in the chain. + * + * @name eql + * @alias eqls + * @param {unknown} obj + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertEql(obj, msg) { + if (msg) flag(this, 'message', msg); + let eql = flag(this, 'eql'); + this.assert( + eql(obj, flag(this, 'object')), + 'expected #{this} to deeply equal #{exp}', + 'expected #{this} to not deeply equal #{exp}', + obj, + this._obj, + true + ); +} + +Assertion.addMethod('eql', assertEql); +Assertion.addMethod('eqls', assertEql); + +/** + * ### .above(n[, msg]) + * + * Asserts that the target is a number or a date greater than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.above(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.above(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.above`. + * + * expect(2).to.equal(2); // Recommended + * expect(1).to.not.be.above(2); // Not recommended + * + * `.above` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.above(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.above(2); + * + * The aliases `.gt` and `.greaterThan` can be used interchangeably with + * `.above`. + * + * @name above + * @alias gt + * @alias greaterThan + * @param {number} n + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertAbove(n, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + doLength = flag(this, 'doLength'), + flagMsg = flag(this, 'message'), + msgPrefix = flagMsg ? flagMsg + ': ' : '', + ssfi = flag(this, 'ssfi'), + objType = _.type(obj).toLowerCase(), + nType = _.type(n).toLowerCase(); + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && objType === 'date' && nType !== 'date') { + throw new AssertionError( + msgPrefix + 'the argument to above must be a date', + undefined, + ssfi + ); + } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) { + throw new AssertionError( + msgPrefix + 'the argument to above must be a number', + undefined, + ssfi + ); + } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { + let printObj = objType === 'string' ? "'" + obj + "'" : obj; + throw new AssertionError( + msgPrefix + 'expected ' + printObj + ' to be a number or a date', + undefined, + ssfi + ); + } + + if (doLength) { + let descriptor = 'length', + itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount > n, + 'expected #{this} to have a ' + + descriptor + + ' above #{exp} but got #{act}', + 'expected #{this} to not have a ' + descriptor + ' above #{exp}', + n, + itemsCount + ); + } else { + this.assert( + obj > n, + 'expected #{this} to be above #{exp}', + 'expected #{this} to be at most #{exp}', + n + ); + } +} + +Assertion.addMethod('above', assertAbove); +Assertion.addMethod('gt', assertAbove); +Assertion.addMethod('greaterThan', assertAbove); + +/** + * ### .least(n[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `n` respectively. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.at.least(1); // Not recommended + * expect(2).to.be.at.least(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.least(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.least`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.at.least(2); // Not recommended + * + * `.least` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.at.least(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.at.least(2); + * + * The aliases `.gte` and `.greaterThanOrEqual` can be used interchangeably with + * `.least`. + * + * @name least + * @alias gte + * @alias greaterThanOrEqual + * @param {unknown} n + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertLeast(n, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + doLength = flag(this, 'doLength'), + flagMsg = flag(this, 'message'), + msgPrefix = flagMsg ? flagMsg + ': ' : '', + ssfi = flag(this, 'ssfi'), + objType = _.type(obj).toLowerCase(), + nType = _.type(n).toLowerCase(), + errorMessage, + shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && objType === 'date' && nType !== 'date') { + errorMessage = msgPrefix + 'the argument to least must be a date'; + } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) { + errorMessage = msgPrefix + 'the argument to least must be a number'; + } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { + let printObj = objType === 'string' ? "'" + obj + "'" : obj; + errorMessage = + msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + let descriptor = 'length', + itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= n, + 'expected #{this} to have a ' + + descriptor + + ' at least #{exp} but got #{act}', + 'expected #{this} to have a ' + descriptor + ' below #{exp}', + n, + itemsCount + ); + } else { + this.assert( + obj >= n, + 'expected #{this} to be at least #{exp}', + 'expected #{this} to be below #{exp}', + n + ); + } +} + +Assertion.addMethod('least', assertLeast); +Assertion.addMethod('gte', assertLeast); +Assertion.addMethod('greaterThanOrEqual', assertLeast); + +/** + * ### .below(n[, msg]) + * + * Asserts that the target is a number or a date less than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.below(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is less than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.below(4); // Not recommended + * + * expect([1, 2, 3]).to.have.length(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.below`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.below(1); // Not recommended + * + * `.below` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.below(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.below(1); + * + * The aliases `.lt` and `.lessThan` can be used interchangeably with + * `.below`. + * + * @name below + * @alias lt + * @alias lessThan + * @param {unknown} n + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertBelow(n, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + doLength = flag(this, 'doLength'), + flagMsg = flag(this, 'message'), + msgPrefix = flagMsg ? flagMsg + ': ' : '', + ssfi = flag(this, 'ssfi'), + objType = _.type(obj).toLowerCase(), + nType = _.type(n).toLowerCase(), + errorMessage, + shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && objType === 'date' && nType !== 'date') { + errorMessage = msgPrefix + 'the argument to below must be a date'; + } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) { + errorMessage = msgPrefix + 'the argument to below must be a number'; + } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { + let printObj = objType === 'string' ? "'" + obj + "'" : obj; + errorMessage = + msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + let descriptor = 'length', + itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount < n, + 'expected #{this} to have a ' + + descriptor + + ' below #{exp} but got #{act}', + 'expected #{this} to not have a ' + descriptor + ' below #{exp}', + n, + itemsCount + ); + } else { + this.assert( + obj < n, + 'expected #{this} to be below #{exp}', + 'expected #{this} to be at least #{exp}', + n + ); + } +} + +Assertion.addMethod('below', assertBelow); +Assertion.addMethod('lt', assertBelow); +Assertion.addMethod('lessThan', assertBelow); + +/** + * ### .most(n[, msg]) + * + * Asserts that the target is a number or a date less than or equal to the given number + * or date `n` respectively. However, it's often best to assert that the target is equal to its + * expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.at.most(2); // Not recommended + * expect(1).to.be.at.most(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is less than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.most(4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.most`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.at.most(1); // Not recommended + * + * `.most` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.at.most(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.at.most(1); + * + * The aliases `.lte` and `.lessThanOrEqual` can be used interchangeably with + * `.most`. + * + * @name most + * @alias lte + * @alias lessThanOrEqual + * @param {unknown} n + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertMost(n, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + doLength = flag(this, 'doLength'), + flagMsg = flag(this, 'message'), + msgPrefix = flagMsg ? flagMsg + ': ' : '', + ssfi = flag(this, 'ssfi'), + objType = _.type(obj).toLowerCase(), + nType = _.type(n).toLowerCase(), + errorMessage, + shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && objType === 'date' && nType !== 'date') { + errorMessage = msgPrefix + 'the argument to most must be a date'; + } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) { + errorMessage = msgPrefix + 'the argument to most must be a number'; + } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { + let printObj = objType === 'string' ? "'" + obj + "'" : obj; + errorMessage = + msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + let descriptor = 'length', + itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount <= n, + 'expected #{this} to have a ' + + descriptor + + ' at most #{exp} but got #{act}', + 'expected #{this} to have a ' + descriptor + ' above #{exp}', + n, + itemsCount + ); + } else { + this.assert( + obj <= n, + 'expected #{this} to be at most #{exp}', + 'expected #{this} to be above #{exp}', + n + ); + } +} + +Assertion.addMethod('most', assertMost); +Assertion.addMethod('lte', assertMost); +Assertion.addMethod('lessThanOrEqual', assertMost); + +/** + * ### .within(start, finish[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `start`, and less than or equal to the given number or date `finish` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.within(1, 3); // Not recommended + * expect(2).to.be.within(2, 3); // Not recommended + * expect(2).to.be.within(1, 2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than or equal to the given number `start`, and less + * than or equal to the given number `finish`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.within`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.within(2, 4); // Not recommended + * + * `.within` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(4).to.be.within(1, 3, 'nooo why fail??'); + * expect(4, 'nooo why fail??').to.be.within(1, 3); + * + * @name within + * @param {unknown} start lower bound inclusive + * @param {unknown} finish upper bound inclusive + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +Assertion.addMethod('within', function (start, finish, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + doLength = flag(this, 'doLength'), + flagMsg = flag(this, 'message'), + msgPrefix = flagMsg ? flagMsg + ': ' : '', + ssfi = flag(this, 'ssfi'), + objType = _.type(obj).toLowerCase(), + startType = _.type(start).toLowerCase(), + finishType = _.type(finish).toLowerCase(), + errorMessage, + shouldThrow = true, + range = + startType === 'date' && finishType === 'date' + ? start.toISOString() + '..' + finish.toISOString() + : start + '..' + finish; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if ( + !doLength && + objType === 'date' && + (startType !== 'date' || finishType !== 'date') + ) { + errorMessage = msgPrefix + 'the arguments to within must be dates'; + } else if ( + (!_.isNumeric(start) || !_.isNumeric(finish)) && + (doLength || _.isNumeric(obj)) + ) { + errorMessage = msgPrefix + 'the arguments to within must be numbers'; + } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { + let printObj = objType === 'string' ? "'" + obj + "'" : obj; + errorMessage = + msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + let descriptor = 'length', + itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= start && itemsCount <= finish, + 'expected #{this} to have a ' + descriptor + ' within ' + range, + 'expected #{this} to not have a ' + descriptor + ' within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish, + 'expected #{this} to be within ' + range, + 'expected #{this} to not be within ' + range + ); + } +}); + +/** + * ### .instanceof(constructor[, msg]) + * + * Asserts that the target is an instance of the given `constructor`. + * + * function Cat () { } + * + * expect(new Cat()).to.be.an.instanceof(Cat); + * expect([1, 2]).to.be.an.instanceof(Array); + * + * Add `.not` earlier in the chain to negate `.instanceof`. + * + * expect({a: 1}).to.not.be.an.instanceof(Array); + * + * `.instanceof` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.be.an.instanceof(Array, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.an.instanceof(Array); + * + * Due to limitations in ES5, `.instanceof` may not always work as expected + * when using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing built-in object such as + * `Array`, `Error`, and `Map`. See your transpiler's docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * The alias `.instanceOf` can be used interchangeably with `.instanceof`. + * + * @name instanceof + * @param {unknown} constructor + * @param {string} msg _optional_ + * @alias instanceOf + * @namespace BDD + * @public + */ +function assertInstanceOf(constructor, msg) { + if (msg) flag(this, 'message', msg); + + let target = flag(this, 'object'); + let ssfi = flag(this, 'ssfi'); + let flagMsg = flag(this, 'message'); + let isInstanceOf; + + try { + isInstanceOf = target instanceof constructor; + } catch (err) { + if (err instanceof TypeError) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + + 'The instanceof assertion needs a constructor but ' + + _.type(constructor) + + ' was given.', + undefined, + ssfi + ); + } + throw err; + } + + let name = _.getName(constructor); + if (name == null) { + name = 'an unnamed constructor'; + } + + this.assert( + isInstanceOf, + 'expected #{this} to be an instance of ' + name, + 'expected #{this} to not be an instance of ' + name + ); +} + +Assertion.addMethod('instanceof', assertInstanceOf); +Assertion.addMethod('instanceOf', assertInstanceOf); + +/** + * ### .property(name[, val[, msg]]) + * + * Asserts that the target has a property with the given key `name`. + * + * expect({a: 1}).to.have.property('a'); + * + * When `val` is provided, `.property` also asserts that the property's value + * is equal to the given `val`. + * + * expect({a: 1}).to.have.property('a', 1); + * + * By default, strict (`===`) equality is used. Add `.deep` earlier in the + * chain to use deep equality instead. See the `deep-eql` project page for + * info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * The target's enumerable and non-enumerable properties are always included + * in the search. By default, both own and inherited properties are included. + * Add `.own` earlier in the chain to exclude inherited properties from the + * search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.own.property('a', 1); + * expect({a: 1}).to.have.property('b'); + * expect({a: 1}).to.not.have.own.property('b'); + * + * `.deep` and `.own` can be combined. + * + * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y'); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}) + * .to.have.deep.nested.property('a.b[0]', {c: 3}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.property`. + * + * expect({a: 1}).to.not.have.property('b'); + * + * However, it's dangerous to negate `.property` when providing `val`. The + * problem is that it creates uncertain expectations by asserting that the + * target either doesn't have a property with the given key `name`, or that it + * does have a property with the given key `name` but its value isn't equal to + * the given `val`. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target isn't expected to have a property with the given key + * `name`, it's often best to assert exactly that. + * + * expect({b: 2}).to.not.have.property('a'); // Recommended + * expect({b: 2}).to.not.have.property('a', 1); // Not recommended + * + * When the target is expected to have a property with the given key `name`, + * it's often best to assert that the property has its expected value, rather + * than asserting that it doesn't have one of many unexpected values. + * + * expect({a: 3}).to.have.property('a', 3); // Recommended + * expect({a: 3}).to.not.have.property('a', 1); // Not recommended + * + * `.property` changes the target of any assertions that follow in the chain + * to be the value of the property from the original target object. + * + * expect({a: 1}).to.have.property('a').that.is.a('number'); + * + * `.property` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing `val`, only use the + * second form. + * + * // Recommended + * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2); + * expect({a: 1}, 'nooo why fail??').to.have.property('b'); + * + * // Not recommended + * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `val`. Instead, + * it's asserting that the target object has a `b` property that's equal to + * `undefined`. + * + * The assertions `.ownProperty` and `.haveOwnProperty` can be used + * interchangeably with `.own.property`. + * + * @name property + * @param {string} name + * @param {unknown} val (optional) + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertProperty(name, val, msg) { + if (msg) flag(this, 'message', msg); + + let isNested = flag(this, 'nested'), + isOwn = flag(this, 'own'), + flagMsg = flag(this, 'message'), + obj = flag(this, 'object'), + ssfi = flag(this, 'ssfi'), + nameType = typeof name; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + if (isNested) { + if (nameType !== 'string') { + throw new AssertionError( + flagMsg + + 'the argument to property must be a string when using nested syntax', + undefined, + ssfi + ); + } + } else { + if ( + nameType !== 'string' && + nameType !== 'number' && + nameType !== 'symbol' + ) { + throw new AssertionError( + flagMsg + + 'the argument to property must be a string, number, or symbol', + undefined, + ssfi + ); + } + } + + if (isNested && isOwn) { + throw new AssertionError( + flagMsg + 'The "nested" and "own" flags cannot be combined.', + undefined, + ssfi + ); + } + + if (obj === null || obj === undefined) { + throw new AssertionError( + flagMsg + 'Target cannot be null or undefined.', + undefined, + ssfi + ); + } + + let isDeep = flag(this, 'deep'), + negate = flag(this, 'negate'), + pathInfo = isNested ? _.getPathInfo(obj, name) : null, + value = isNested ? pathInfo.value : obj[name], + isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2; + + let descriptor = ''; + if (isDeep) descriptor += 'deep '; + if (isOwn) descriptor += 'own '; + if (isNested) descriptor += 'nested '; + descriptor += 'property '; + + let hasProperty; + if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name); + else if (isNested) hasProperty = pathInfo.exists; + else hasProperty = _.hasProperty(obj, name); + + // When performing a negated assertion for both name and val, merely having + // a property with the given name isn't enough to cause the assertion to + // fail. It must both have a property with the given name, and the value of + // that property must equal the given val. Therefore, skip this assertion in + // favor of the next. + if (!negate || arguments.length === 1) { + this.assert( + hasProperty, + 'expected #{this} to have ' + descriptor + _.inspect(name), + 'expected #{this} to not have ' + descriptor + _.inspect(name) + ); + } + + if (arguments.length > 1) { + this.assert( + hasProperty && isEql(val, value), + 'expected #{this} to have ' + + descriptor + + _.inspect(name) + + ' of #{exp}, but got #{act}', + 'expected #{this} to not have ' + + descriptor + + _.inspect(name) + + ' of #{act}', + val, + value + ); + } + + flag(this, 'object', value); +} + +Assertion.addMethod('property', assertProperty); + +/** + * @param {unknown} _name + * @param {unknown} _value + * @param {string} _msg + */ +function assertOwnProperty(_name, _value, _msg) { + flag(this, 'own', true); + assertProperty.apply(this, arguments); +} + +Assertion.addMethod('ownProperty', assertOwnProperty); +Assertion.addMethod('haveOwnProperty', assertOwnProperty); + +/** + * ### .ownPropertyDescriptor(name[, descriptor[, msg]]) + * + * Asserts that the target has its own property descriptor with the given key + * `name`. Enumerable and non-enumerable properties are included in the + * search. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a'); + * + * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that + * the property's descriptor is deeply equal to the given `descriptor`. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`. + * + * expect({a: 1}).to.not.have.ownPropertyDescriptor('b'); + * + * However, it's dangerous to negate `.ownPropertyDescriptor` when providing + * a `descriptor`. The problem is that it creates uncertain expectations by + * asserting that the target either doesn't have a property descriptor with + * the given key `name`, or that it does have a property descriptor with the + * given key `name` but it’s not deeply equal to the given `descriptor`. It's + * often best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to have a property descriptor with the given + * key `name`, it's often best to assert exactly that. + * + * // Recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a'); + * + * // Not recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * When the target is expected to have a property descriptor with the given + * key `name`, it's often best to assert that the property has its expected + * descriptor, rather than asserting that it doesn't have one of many + * unexpected descriptors. + * + * // Recommended + * expect({a: 3}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 3, + * }); + * + * // Not recommended + * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * `.ownPropertyDescriptor` changes the target of any assertions that follow + * in the chain to be the value of the property descriptor from the original + * target object. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a') + * .that.has.property('enumerable', true); + * + * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a + * custom error message to show when the assertion fails. The message can also + * be given as the second argument to `expect`. When not providing + * `descriptor`, only use the second form. + * + * // Recommended + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }, 'nooo why fail??'); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b'); + * + * // Not recommended + * expect({a: 1}) + * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `descriptor`. + * Instead, it's asserting that the target object has a `b` property + * descriptor that's deeply equal to `undefined`. + * + * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with + * `.ownPropertyDescriptor`. + * + * @name ownPropertyDescriptor + * @alias haveOwnPropertyDescriptor + * @param {string} name + * @param {object} descriptor _optional_ + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertOwnPropertyDescriptor(name, descriptor, msg) { + if (typeof descriptor === 'string') { + msg = descriptor; + descriptor = null; + } + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'); + let actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + let eql = flag(this, 'eql'); + if (actualDescriptor && descriptor) { + this.assert( + eql(descriptor, actualDescriptor), + 'expected the own property descriptor for ' + + _.inspect(name) + + ' on #{this} to match ' + + _.inspect(descriptor) + + ', got ' + + _.inspect(actualDescriptor), + 'expected the own property descriptor for ' + + _.inspect(name) + + ' on #{this} to not match ' + + _.inspect(descriptor), + descriptor, + actualDescriptor, + true + ); + } else { + this.assert( + actualDescriptor, + 'expected #{this} to have an own property descriptor for ' + + _.inspect(name), + 'expected #{this} to not have an own property descriptor for ' + + _.inspect(name) + ); + } + flag(this, 'object', actualDescriptor); +} + +Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); +Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); + +/** */ +function assertLengthChain() { + flag(this, 'doLength', true); +} + +/** + * ### .lengthOf(n[, msg]) + * + * Asserts that the target's `length` or `size` is equal to the given number + * `n`. + * + * expect([1, 2, 3]).to.have.lengthOf(3); + * expect('foo').to.have.lengthOf(3); + * expect(new Set([1, 2, 3])).to.have.lengthOf(3); + * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3); + * + * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often + * best to assert that the target's `length` property is equal to its expected + * value, rather than not equal to one of many unexpected values. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.not.have.lengthOf(4); // Not recommended + * + * `.lengthOf` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2); + * + * `.lengthOf` can also be used as a language chain, causing all `.above`, + * `.below`, `.least`, `.most`, and `.within` assertions that follow in the + * chain to use the target's `length` property as the target. However, it's + * often best to assert that the target's `length` property is equal to its + * expected length, rather than asserting that its `length` property falls + * within some range of values. + * + * // Recommended + * expect([1, 2, 3]).to.have.lengthOf(3); + * + * // Not recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); + * expect([1, 2, 3]).to.have.lengthOf.below(4); + * expect([1, 2, 3]).to.have.lengthOf.at.least(3); + * expect([1, 2, 3]).to.have.lengthOf.at.most(3); + * expect([1, 2, 3]).to.have.lengthOf.within(2,4); + * + * Due to a compatibility issue, the alias `.length` can't be chained directly + * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used + * interchangeably with `.lengthOf` in every situation. It's recommended to + * always use `.lengthOf` instead of `.length`. + * + * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error + * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected + * + * @name lengthOf + * @alias length + * @param {number} n + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertLength(n, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + objType = _.type(obj).toLowerCase(), + flagMsg = flag(this, 'message'), + ssfi = flag(this, 'ssfi'), + descriptor = 'length', + itemsCount; + + switch (objType) { + case 'map': + case 'set': + descriptor = 'size'; + itemsCount = obj.size; + break; + default: + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + itemsCount = obj.length; + } + + this.assert( + itemsCount == n, + 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}', + 'expected #{this} to not have a ' + descriptor + ' of #{act}', + n, + itemsCount + ); +} + +Assertion.addChainableMethod('length', assertLength, assertLengthChain); +Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain); + +/** + * ### .match(re[, msg]) + * + * Asserts that the target matches the given regular expression `re`. + * + * expect('foobar').to.match(/^foo/); + * + * Add `.not` earlier in the chain to negate `.match`. + * + * expect('foobar').to.not.match(/taco/); + * + * `.match` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect('foobar').to.match(/taco/, 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.match(/taco/); + * + * The alias `.matches` can be used interchangeably with `.match`. + * + * @name match + * @alias matches + * @param {RegExp} re + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertMatch(re, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'); + this.assert( + re.exec(obj), + 'expected #{this} to match ' + re, + 'expected #{this} not to match ' + re + ); +} + +Assertion.addMethod('match', assertMatch); +Assertion.addMethod('matches', assertMatch); + +/** + * ### .string(str[, msg]) + * + * Asserts that the target string contains the given substring `str`. + * + * expect('foobar').to.have.string('bar'); + * + * Add `.not` earlier in the chain to negate `.string`. + * + * expect('foobar').to.not.have.string('taco'); + * + * `.string` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect('foobar').to.have.string('taco', 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.have.string('taco'); + * + * @name string + * @param {string} str + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +Assertion.addMethod('string', function (str, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + flagMsg = flag(this, 'message'), + ssfi = flag(this, 'ssfi'); + new Assertion(obj, flagMsg, ssfi, true).is.a('string'); + + this.assert( + ~obj.indexOf(str), + 'expected #{this} to contain ' + _.inspect(str), + 'expected #{this} to not contain ' + _.inspect(str) + ); +}); + +/** + * ### .keys(key1[, key2[, ...]]) + * + * Asserts that the target object, array, map, or set has the given keys. Only + * the target's own inherited properties are included in the search. + * + * When the target is an object or array, keys can be provided as one or more + * string arguments, a single array argument, or a single object argument. In + * the latter case, only the keys in the given object matter; the values are + * ignored. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * expect(['x', 'y']).to.have.all.keys(0, 1); + * + * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']); + * expect(['x', 'y']).to.have.all.keys([0, 1]); + * + * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5 + * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5 + * + * When the target is a map or set, each key must be provided as a separate + * argument. + * + * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b'); + * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b'); + * + * Because `.keys` does different things based on the target's type, it's + * important to check the target's type before using `.keys`. See the `.a` doc + * for info on testing a target's type. + * + * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b'); + * + * By default, strict (`===`) equality is used to compare keys of maps and + * sets. Add `.deep` earlier in the chain to use deep equality instead. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]); + * + * By default, the target must have all of the given keys and no more. Add + * `.any` earlier in the chain to only require that the target have at least + * one of the given keys. Also, add `.not` earlier in the chain to negate + * `.keys`. It's often best to add `.any` when negating `.keys`, and to use + * `.all` when asserting `.keys` without negation. + * + * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts + * exactly what's expected of the output, whereas `.not.all.keys` creates + * uncertain expectations. + * + * // Recommended; asserts that target doesn't have any of the given keys + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * // Not recommended; asserts that target doesn't have all of the given + * // keys but may or may not have some of them + * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd'); + * + * When asserting `.keys` without negation, `.all` is preferred because + * `.all.keys` asserts exactly what's expected of the output, whereas + * `.any.keys` creates uncertain expectations. + * + * // Recommended; asserts that target has all the given keys + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * // Not recommended; asserts that target has at least one of the given + * // keys but may or may not have more of them + * expect({a: 1, b: 2}).to.have.any.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` appear + * earlier in the chain. However, it's often best to add `.all` anyway because + * it improves readability. + * + * // Both assertions are identical + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended + * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended + * + * Add `.include` earlier in the chain to require that the target's keys be a + * superset of the expected keys, rather than identical sets. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * However, if `.any` and `.include` are combined, only the `.any` takes + * effect. The `.include` is ignored in this case. + * + * // Both assertions are identical + * expect({a: 1}).to.have.any.keys('a', 'b'); + * expect({a: 1}).to.include.any.keys('a', 'b'); + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.have.key('b'); + * + * The alias `.key` can be used interchangeably with `.keys`. + * + * @name keys + * @alias key + * @param {...string | Array | object} keys + * @namespace BDD + * @public + */ +function assertKeys(keys) { + let obj = flag(this, 'object'), + objType = _.type(obj), + keysType = _.type(keys), + ssfi = flag(this, 'ssfi'), + isDeep = flag(this, 'deep'), + str, + deepStr = '', + actual, + ok = true, + flagMsg = flag(this, 'message'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + let mixedArgsMsg = + flagMsg + + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments'; + + if (objType === 'Map' || objType === 'Set') { + deepStr = isDeep ? 'deeply ' : ''; + actual = []; + + // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach. + obj.forEach(function (val, key) { + actual.push(key); + }); + + if (keysType !== 'Array') { + keys = Array.prototype.slice.call(arguments); + } + } else { + actual = _.getOwnEnumerableProperties(obj); + + switch (keysType) { + case 'Array': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + break; + case 'Object': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + + // Only stringify non-Symbols because Symbols would become "Symbol()" + keys = keys.map(function (val) { + return typeof val === 'symbol' ? val : String(val); + }); + } + + if (!keys.length) { + throw new AssertionError(flagMsg + 'keys required', undefined, ssfi); + } + + let len = keys.length, + any = flag(this, 'any'), + all = flag(this, 'all'), + expected = keys, + isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2; + + if (!any && !all) { + all = true; + } + + // Has any + if (any) { + ok = expected.some(function (expectedKey) { + return actual.some(function (actualKey) { + return isEql(expectedKey, actualKey); + }); + }); + } + + // Has all + if (all) { + ok = expected.every(function (expectedKey) { + return actual.some(function (actualKey) { + return isEql(expectedKey, actualKey); + }); + }); + + if (!flag(this, 'contains')) { + ok = ok && keys.length == actual.length; + } + } + + // Key string + if (len > 1) { + keys = keys.map(function (key) { + return _.inspect(key); + }); + let last = keys.pop(); + if (all) { + str = keys.join(', ') + ', and ' + last; + } + if (any) { + str = keys.join(', ') + ', or ' + last; + } + } else { + str = _.inspect(keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + + // Assertion + this.assert( + ok, + 'expected #{this} to ' + deepStr + str, + 'expected #{this} to not ' + deepStr + str, + expected.slice(0).sort(_.compareByInspect), + actual.sort(_.compareByInspect), + true + ); +} + +Assertion.addMethod('keys', assertKeys); +Assertion.addMethod('key', assertKeys); + +/** + * ### .throw([errorLike], [errMsgMatcher], [msg]) + * + * When no arguments are provided, `.throw` invokes the target function and + * asserts that an error is thrown. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * expect(badFn).to.throw(); + * + * When one argument is provided, and it's an error constructor, `.throw` + * invokes the target function and asserts that an error is thrown that's an + * instance of that error constructor. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * expect(badFn).to.throw(TypeError); + * + * When one argument is provided, and it's an error instance, `.throw` invokes + * the target function and asserts that an error is thrown that's strictly + * (`===`) equal to that error instance. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(err); + * + * When one argument is provided, and it's a string, `.throw` invokes the + * target function and asserts that an error is thrown with a message that + * contains that string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * expect(badFn).to.throw('salmon'); + * + * When one argument is provided, and it's a regular expression, `.throw` + * invokes the target function and asserts that an error is thrown with a + * message that matches that regular expression. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * expect(badFn).to.throw(/salmon/); + * + * When two arguments are provided, and the first is an error instance or + * constructor, and the second is a string or regular expression, `.throw` + * invokes the function and asserts that an error is thrown that fulfills both + * conditions as described above. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); + * expect(badFn).to.throw(TypeError, /salmon/); + * expect(badFn).to.throw(err, 'salmon'); + * expect(badFn).to.throw(err, /salmon/); + * + * Add `.not` earlier in the chain to negate `.throw`. + * + * var goodFn = function () {}; + * expect(goodFn).to.not.throw(); + * + * However, it's dangerous to negate `.throw` when providing any arguments. + * The problem is that it creates uncertain expectations by asserting that the + * target either doesn't throw an error, or that it throws an error but of a + * different type than the given type, or that it throws an error of the given + * type but with a message that doesn't include the given string. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to throw an error, it's often best to assert + * exactly that. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); // Recommended + * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * When the target is expected to throw an error, it's often best to assert + * that the error is of its expected type, and has a message that includes an + * expected string, rather than asserting that it doesn't have one of many + * unexpected types, and doesn't have a message that includes some string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended + * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * `.throw` changes the target of any assertions that follow in the chain to + * be the error object that's thrown. + * + * var err = new TypeError('Illegal salmon!'); + * err.code = 42; + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError).with.property('code', 42); + * + * `.throw` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. When not providing two arguments, always use + * the second form. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??'); + * expect(goodFn, 'nooo why fail??').to.throw(); + * + * Due to limitations in ES5, `.throw` may not always work as expected when + * using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing the built-in `Error` object and + * then passing the subclassed constructor to `.throw`. See your transpiler's + * docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * Beware of some common mistakes when using the `throw` assertion. One common + * mistake is to accidentally invoke the function yourself instead of letting + * the `throw` assertion invoke the function for you. For example, when + * testing if a function named `fn` throws, provide `fn` instead of `fn()` as + * the target for the assertion. + * + * expect(fn).to.throw(); // Good! Tests `fn` as desired + * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn` + * + * If you need to assert that your function `fn` throws when passed certain + * arguments, then wrap a call to `fn` inside of another function. + * + * expect(function () { fn(42); }).to.throw(); // Function expression + * expect(() => fn(42)).to.throw(); // ES6 arrow function + * + * Another common mistake is to provide an object method (or any stand-alone + * function that relies on `this`) as the target of the assertion. Doing so is + * problematic because the `this` context will be lost when the function is + * invoked by `.throw`; there's no way for it to know what `this` is supposed + * to be. There are two ways around this problem. One solution is to wrap the + * method or function call inside of another function. Another solution is to + * use `bind`. + * + * expect(function () { cat.meow(); }).to.throw(); // Function expression + * expect(() => cat.meow()).to.throw(); // ES6 arrow function + * expect(cat.meow.bind(cat)).to.throw(); // Bind + * + * Finally, it's worth mentioning that it's a best practice in JavaScript to + * only throw `Error` and derivatives of `Error` such as `ReferenceError`, + * `TypeError`, and user-defined objects that extend `Error`. No other type of + * value will generate a stack trace when initialized. With that said, the + * `throw` assertion does technically support any type of value being thrown, + * not just `Error` and its derivatives. + * + * The aliases `.throws` and `.Throw` can be used interchangeably with + * `.throw`. + * + * @name throw + * @alias throws + * @alias Throw + * @param {Error} errorLike + * @param {string | RegExp} errMsgMatcher error message + * @param {string} msg _optional_ + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @returns {void} error for chaining (null if no error) + * @namespace BDD + * @public + */ +function assertThrows(errorLike, errMsgMatcher, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + ssfi = flag(this, 'ssfi'), + flagMsg = flag(this, 'message'), + negate = flag(this, 'negate') || false; + new Assertion(obj, flagMsg, ssfi, true).is.a('function'); + + if (_.isRegExp(errorLike) || typeof errorLike === 'string') { + errMsgMatcher = errorLike; + errorLike = null; + } + + let caughtErr; + let errorWasThrown = false; + try { + obj(); + } catch (err) { + errorWasThrown = true; + caughtErr = err; + } + + // If we have the negate flag enabled and at least one valid argument it means we do expect an error + // but we want it to match a given set of criteria + let everyArgIsUndefined = + errorLike === undefined && errMsgMatcher === undefined; + + // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible + // See Issue #551 and PR #683@GitHub + let everyArgIsDefined = Boolean(errorLike && errMsgMatcher); + let errorLikeFail = false; + let errMsgMatcherFail = false; + + // Checking if error was thrown + if (everyArgIsUndefined || (!everyArgIsUndefined && !negate)) { + // We need this to display results correctly according to their types + let errorLikeString = 'an error'; + if (errorLike instanceof Error) { + errorLikeString = '#{exp}'; + } else if (errorLike) { + errorLikeString = _.checkError.getConstructorName(errorLike); + } + + let actual = caughtErr; + if (caughtErr instanceof Error) { + actual = caughtErr.toString(); + } else if (typeof caughtErr === 'string') { + actual = caughtErr; + } else if ( + caughtErr && + (typeof caughtErr === 'object' || typeof caughtErr === 'function') + ) { + try { + actual = _.checkError.getConstructorName(caughtErr); + } catch (_err) { + // somehow wasn't a constructor, maybe we got a function thrown + // or similar + } + } + + this.assert( + errorWasThrown, + 'expected #{this} to throw ' + errorLikeString, + 'expected #{this} to not throw an error but #{act} was thrown', + errorLike && errorLike.toString(), + actual + ); + } + + if (errorLike && caughtErr) { + // We should compare instances only if `errorLike` is an instance of `Error` + if (errorLike instanceof Error) { + let isCompatibleInstance = _.checkError.compatibleInstance( + caughtErr, + errorLike + ); + + if (isCompatibleInstance === negate) { + // These checks were created to ensure we won't fail too soon when we've got both args and a negate + // See Issue #551 and PR #683@GitHub + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate, + 'expected #{this} to throw #{exp} but #{act} was thrown', + 'expected #{this} to not throw #{exp}' + + (caughtErr && !negate ? ' but #{act} was thrown' : ''), + errorLike.toString(), + caughtErr.toString() + ); + } + } + } + + let isCompatibleConstructor = _.checkError.compatibleConstructor( + caughtErr, + errorLike + ); + if (isCompatibleConstructor === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate, + 'expected #{this} to throw #{exp} but #{act} was thrown', + 'expected #{this} to not throw #{exp}' + + (caughtErr ? ' but #{act} was thrown' : ''), + errorLike instanceof Error + ? errorLike.toString() + : errorLike && _.checkError.getConstructorName(errorLike), + caughtErr instanceof Error + ? caughtErr.toString() + : caughtErr && _.checkError.getConstructorName(caughtErr) + ); + } + } + } + + if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) { + // Here we check compatible messages + let placeholder = 'including'; + if (_.isRegExp(errMsgMatcher)) { + placeholder = 'matching'; + } + + let isCompatibleMessage = _.checkError.compatibleMessage( + caughtErr, + errMsgMatcher + ); + if (isCompatibleMessage === negate) { + if (everyArgIsDefined && negate) { + errMsgMatcherFail = true; + } else { + this.assert( + negate, + 'expected #{this} to throw error ' + + placeholder + + ' #{exp} but got #{act}', + 'expected #{this} to throw error not ' + placeholder + ' #{exp}', + errMsgMatcher, + _.checkError.getMessage(caughtErr) + ); + } + } + } + + // If both assertions failed and both should've matched we throw an error + if (errorLikeFail && errMsgMatcherFail) { + this.assert( + negate, + 'expected #{this} to throw #{exp} but #{act} was thrown', + 'expected #{this} to not throw #{exp}' + + (caughtErr ? ' but #{act} was thrown' : ''), + errorLike instanceof Error + ? errorLike.toString() + : errorLike && _.checkError.getConstructorName(errorLike), + caughtErr instanceof Error + ? caughtErr.toString() + : caughtErr && _.checkError.getConstructorName(caughtErr) + ); + } + + flag(this, 'object', caughtErr); +} + +Assertion.addMethod('throw', assertThrows); +Assertion.addMethod('throws', assertThrows); +Assertion.addMethod('Throw', assertThrows); + +/** + * ### .respondTo(method[, msg]) + * + * When the target is a non-function object, `.respondTo` asserts that the + * target has a method with the given name `method`. The method can be own or + * inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.respondTo('meow'); + * + * When the target is a function, `.respondTo` asserts that the target's + * `prototype` property has a method with the given name `method`. Again, the + * method can be own or inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(Cat).to.respondTo('meow'); + * + * Add `.itself` earlier in the chain to force `.respondTo` to treat the + * target as a non-function object, even if it's a function. Thus, it asserts + * that the target has a method with the given name `method`, rather than + * asserting that the target's `prototype` property has a method with the + * given name `method`. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * When not adding `.itself`, it's important to check the target's type before + * using `.respondTo`. See the `.a` doc for info on checking a target's type. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.be.an('object').that.respondsTo('meow'); + * + * Add `.not` earlier in the chain to negate `.respondTo`. + * + * function Dog () {} + * Dog.prototype.bark = function () {}; + * + * expect(new Dog()).to.not.respondTo('meow'); + * + * `.respondTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect({}).to.respondTo('meow', 'nooo why fail??'); + * expect({}, 'nooo why fail??').to.respondTo('meow'); + * + * The alias `.respondsTo` can be used interchangeably with `.respondTo`. + * + * @name respondTo + * @alias respondsTo + * @param {string} method + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function respondTo(method, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + itself = flag(this, 'itself'), + context = + 'function' === typeof obj && !itself + ? obj.prototype[method] + : obj[method]; + + this.assert( + 'function' === typeof context, + 'expected #{this} to respond to ' + _.inspect(method), + 'expected #{this} to not respond to ' + _.inspect(method) + ); +} + +Assertion.addMethod('respondTo', respondTo); +Assertion.addMethod('respondsTo', respondTo); + +/** + * ### .itself + * + * Forces all `.respondTo` assertions that follow in the chain to behave as if + * the target is a non-function object, even if it's a function. Thus, it + * causes `.respondTo` to assert that the target has a method with the given + * name, rather than asserting that the target's `prototype` property has a + * method with the given name. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * @name itself + * @namespace BDD + * @public + */ +Assertion.addProperty('itself', function () { + flag(this, 'itself', true); +}); + +/** + * ### .satisfy(matcher[, msg]) + * + * Invokes the given `matcher` function with the target being passed as the + * first argument, and asserts that the value returned is truthy. + * + * expect(1).to.satisfy(function(num) { + * return num > 0; + * }); + * + * Add `.not` earlier in the chain to negate `.satisfy`. + * + * expect(1).to.not.satisfy(function(num) { + * return num > 2; + * }); + * + * `.satisfy` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.satisfy(function(num) { + * return num > 2; + * }, 'nooo why fail??'); + * + * expect(1, 'nooo why fail??').to.satisfy(function(num) { + * return num > 2; + * }); + * + * The alias `.satisfies` can be used interchangeably with `.satisfy`. + * + * @name satisfy + * @alias satisfies + * @param {Function} matcher + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function satisfy(matcher, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'); + let result = matcher(obj); + this.assert( + result, + 'expected #{this} to satisfy ' + _.objDisplay(matcher), + 'expected #{this} to not satisfy' + _.objDisplay(matcher), + flag(this, 'negate') ? false : true, + result + ); +} + +Assertion.addMethod('satisfy', satisfy); +Assertion.addMethod('satisfies', satisfy); + +/** + * ### .closeTo(expected, delta[, msg]) + * + * Asserts that the target is a number that's within a given +/- `delta` range + * of the given number `expected`. However, it's often best to assert that the + * target is equal to its expected value. + * + * // Recommended + * expect(1.5).to.equal(1.5); + * + * // Not recommended + * expect(1.5).to.be.closeTo(1, 0.5); + * expect(1.5).to.be.closeTo(2, 0.5); + * expect(1.5).to.be.closeTo(1, 1); + * + * Add `.not` earlier in the chain to negate `.closeTo`. + * + * expect(1.5).to.equal(1.5); // Recommended + * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended + * + * `.closeTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??'); + * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1); + * + * The alias `.approximately` can be used interchangeably with `.closeTo`. + * + * @name closeTo + * @alias approximately + * @param {number} expected + * @param {number} delta + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function closeTo(expected, delta, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + flagMsg = flag(this, 'message'), + ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).is.numeric; + let message = 'A `delta` value is required for `closeTo`'; + if (delta == undefined) { + throw new AssertionError( + flagMsg ? `${flagMsg}: ${message}` : message, + undefined, + ssfi + ); + } + new Assertion(delta, flagMsg, ssfi, true).is.numeric; + message = 'A `expected` value is required for `closeTo`'; + if (expected == undefined) { + throw new AssertionError( + flagMsg ? `${flagMsg}: ${message}` : message, + undefined, + ssfi + ); + } + new Assertion(expected, flagMsg, ssfi, true).is.numeric; + + const abs = (x) => (x < 0n ? -x : x); + + // Used to round floating point number precision arithmetics + // See: https://stackoverflow.com/a/3644302 + const strip = (number) => parseFloat(parseFloat(number).toPrecision(12)); + + this.assert( + strip(abs(obj - expected)) <= delta, + 'expected #{this} to be close to ' + expected + ' +/- ' + delta, + 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); +} + +Assertion.addMethod('closeTo', closeTo); +Assertion.addMethod('approximately', closeTo); + +/** + * @param {unknown} _subset + * @param {unknown} _superset + * @param {unknown} cmp + * @param {unknown} contains + * @param {unknown} ordered + * @returns {boolean} + */ +function isSubsetOf(_subset, _superset, cmp, contains, ordered) { + let superset = Array.from(_superset); + let subset = Array.from(_subset); + if (!contains) { + if (subset.length !== superset.length) return false; + superset = superset.slice(); + } + + return subset.every(function (elem, idx) { + if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; + + if (!cmp) { + let matchIdx = superset.indexOf(elem); + if (matchIdx === -1) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + } + + return superset.some(function (elem2, matchIdx) { + if (!cmp(elem, elem2)) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + }); + }); +} + +/** + * ### .members(set[, msg]) + * + * Asserts that the target array has the same members as the given array + * `set`. + * + * expect([1, 2, 3]).to.have.members([2, 1, 3]); + * expect([1, 2, 2]).to.have.members([2, 1, 2]); + * + * By default, members are compared using strict (`===`) equality. Add `.deep` + * earlier in the chain to use deep equality instead. See the `deep-eql` + * project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * By default, order doesn't matter. Add `.ordered` earlier in the chain to + * require that members appear in the same order. + * + * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); + * expect([1, 2, 3]).to.have.members([2, 1, 3]) + * .but.not.ordered.members([2, 1, 3]); + * + * By default, both arrays must be the same size. Add `.include` earlier in + * the chain to require that the target's members be a superset of the + * expected members. Note that duplicates are ignored in the subset when + * `.include` is added. + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * `.deep`, `.ordered`, and `.include` can all be combined. However, if + * `.include` and `.ordered` are combined, the ordering begins at the start of + * both arrays. + * + * expect([{a: 1}, {b: 2}, {c: 3}]) + * .to.include.deep.ordered.members([{a: 1}, {b: 2}]) + * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]); + * + * Add `.not` earlier in the chain to negate `.members`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the target array doesn't have all of the same members as + * the given array `set` but may or may not have some of them. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended + * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended + * + * `.members` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??'); + * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]); + * + * @name members + * @param {Array} set + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +Assertion.addMethod('members', function (subset, msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'), + flagMsg = flag(this, 'message'), + ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).to.be.iterable; + new Assertion(subset, flagMsg, ssfi, true).to.be.iterable; + + let contains = flag(this, 'contains'); + let ordered = flag(this, 'ordered'); + + let subject, failMsg, failNegateMsg; + + if (contains) { + subject = ordered ? 'an ordered superset' : 'a superset'; + failMsg = 'expected #{this} to be ' + subject + ' of #{exp}'; + failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}'; + } else { + subject = ordered ? 'ordered members' : 'members'; + failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}'; + failNegateMsg = + 'expected #{this} to not have the same ' + subject + ' as #{exp}'; + } + + let cmp = flag(this, 'deep') ? flag(this, 'eql') : undefined; + + this.assert( + isSubsetOf(subset, obj, cmp, contains, ordered), + failMsg, + failNegateMsg, + subset, + obj, + true + ); +}); + +/** + * ### .iterable + * + * Asserts that the target is an iterable, which means that it has a iterator. + * + * expect([1, 2]).to.be.iterable; + * expect("foobar").to.be.iterable; + * + * Add `.not` earlier in the chain to negate `.iterable`. + * + * expect(1).to.not.be.iterable; + * expect(true).to.not.be.iterable; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(1, 'nooo why fail??').to.be.iterable; + * + * @name iterable + * @namespace BDD + * @public + */ +Assertion.addProperty('iterable', function (msg) { + if (msg) flag(this, 'message', msg); + let obj = flag(this, 'object'); + + this.assert( + obj != undefined && obj[Symbol.iterator], + 'expected #{this} to be an iterable', + 'expected #{this} to not be an iterable', + obj + ); +}); + +/** + * ### .oneOf(list[, msg]) + * + * Asserts that the target is a member of the given array `list`. However, + * it's often best to assert that the target is equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended + * + * Comparisons are performed using strict (`===`) equality. + * + * Add `.not` earlier in the chain to negate `.oneOf`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended + * + * It can also be chained with `.contain` or `.include`, which will work with + * both arrays and strings: + * + * expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy']) + * expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy']) + * expect([1,2,3]).to.contain.oneOf([3,4,5]) + * expect([1,2,3]).to.not.contain.oneOf([4,5,6]) + * + * `.oneOf` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]); + * + * @name oneOf + * @param {Array<*>} list + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function oneOf(list, msg) { + if (msg) flag(this, 'message', msg); + let expected = flag(this, 'object'), + flagMsg = flag(this, 'message'), + ssfi = flag(this, 'ssfi'), + contains = flag(this, 'contains'), + isDeep = flag(this, 'deep'), + eql = flag(this, 'eql'); + new Assertion(list, flagMsg, ssfi, true).to.be.an('array'); + + if (contains) { + this.assert( + list.some(function (possibility) { + return expected.indexOf(possibility) > -1; + }), + 'expected #{this} to contain one of #{exp}', + 'expected #{this} to not contain one of #{exp}', + list, + expected + ); + } else { + if (isDeep) { + this.assert( + list.some(function (possibility) { + return eql(expected, possibility); + }), + 'expected #{this} to deeply equal one of #{exp}', + 'expected #{this} to deeply equal one of #{exp}', + list, + expected + ); + } else { + this.assert( + list.indexOf(expected) > -1, + 'expected #{this} to be one of #{exp}', + 'expected #{this} to not be one of #{exp}', + list, + expected + ); + } + } +} + +Assertion.addMethod('oneOf', oneOf); + +/** + * ### .change(subject[, prop[, msg]]) + * + * When one argument is provided, `.change` asserts that the given function + * `subject` returns a different value when it's invoked before the target + * function compared to when it's invoked afterward. However, it's often best + * to assert that `subject` is equal to its expected value. + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * // Recommended + * expect(getDots()).to.equal(''); + * addDot(); + * expect(getDots()).to.equal('.'); + * + * // Not recommended + * expect(addDot).to.change(getDots); + * + * When two arguments are provided, `.change` asserts that the value of the + * given object `subject`'s `prop` property is different before invoking the + * target function compared to afterward. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * // Recommended + * expect(myObj).to.have.property('dots', ''); + * addDot(); + * expect(myObj).to.have.property('dots', '.'); + * + * // Not recommended + * expect(addDot).to.change(myObj, 'dots'); + * + * Strict (`===`) equality is used to compare before and after values. + * + * Add `.not` earlier in the chain to negate `.change`. + * + * var dots = '' + * , noop = function () {} + * , getDots = function () { return dots; }; + * + * expect(noop).to.not.change(getDots); + * + * var myObj = {dots: ''} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'dots'); + * + * `.change` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??'); + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * expect(addDot, 'nooo why fail??').to.not.change(getDots); + * + * `.change` also causes all `.by` assertions that follow in the chain to + * assert how much a numeric subject was increased or decreased by. However, + * it's dangerous to use `.change.by`. The problem is that it creates + * uncertain expectations by asserting that the subject either increases by + * the given delta, or that it decreases by the given delta. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * The alias `.changes` can be used interchangeably with `.change`. + * + * @name change + * @alias changes + * @param {string} subject + * @param {string} prop name _optional_ + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertChanges(subject, prop, msg) { + if (msg) flag(this, 'message', msg); + let fn = flag(this, 'object'), + flagMsg = flag(this, 'message'), + ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + let initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + fn(); + + let final = prop === undefined || prop === null ? subject() : subject[prop]; + let msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + // This gets flagged because of the .by(delta) assertion + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'change'); + flag(this, 'realDelta', final !== initial); + + this.assert( + initial !== final, + 'expected ' + msgObj + ' to change', + 'expected ' + msgObj + ' to not change' + ); +} + +Assertion.addMethod('change', assertChanges); +Assertion.addMethod('changes', assertChanges); + +/** + * ### .increase(subject[, prop[, msg]]) + * + * When one argument is provided, `.increase` asserts that the given function + * `subject` returns a greater number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.increase` also + * causes all `.by` assertions that follow in the chain to assert how much + * greater of a number is returned. It's often best to assert that the return + * value increased by the expected amount, rather than asserting it increased + * by any amount. + * + * var val = 1 + * , addTwo = function () { val += 2; } + * , getVal = function () { return val; }; + * + * expect(addTwo).to.increase(getVal).by(2); // Recommended + * expect(addTwo).to.increase(getVal); // Not recommended + * + * When two arguments are provided, `.increase` asserts that the value of the + * given object `subject`'s `prop` property is greater after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.increase(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.increase`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either decreases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to decrease, it's often best to assert that it + * decreased by the expected amount. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.increase(myObj, 'val'); // Not recommended + * + * `.increase` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.increase(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.increase(getVal); + * + * The alias `.increases` can be used interchangeably with `.increase`. + * + * @name increase + * @alias increases + * @param {string | Function} subject + * @param {string} prop name _optional_ + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertIncreases(subject, prop, msg) { + if (msg) flag(this, 'message', msg); + let fn = flag(this, 'object'), + flagMsg = flag(this, 'message'), + ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + let initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + let final = prop === undefined || prop === null ? subject() : subject[prop]; + let msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'increase'); + flag(this, 'realDelta', final - initial); + + this.assert( + final - initial > 0, + 'expected ' + msgObj + ' to increase', + 'expected ' + msgObj + ' to not increase' + ); +} + +Assertion.addMethod('increase', assertIncreases); +Assertion.addMethod('increases', assertIncreases); + +/** + * ### .decrease(subject[, prop[, msg]]) + * + * When one argument is provided, `.decrease` asserts that the given function + * `subject` returns a lesser number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.decrease` also + * causes all `.by` assertions that follow in the chain to assert how much + * lesser of a number is returned. It's often best to assert that the return + * value decreased by the expected amount, rather than asserting it decreased + * by any amount. + * + * var val = 1 + * , subtractTwo = function () { val -= 2; } + * , getVal = function () { return val; }; + * + * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended + * expect(subtractTwo).to.decrease(getVal); // Not recommended + * + * When two arguments are provided, `.decrease` asserts that the value of the + * given object `subject`'s `prop` property is lesser after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.decrease`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either increases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to increase, it's often best to assert that it + * increased by the expected amount. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended + * + * `.decrease` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.decrease(getVal); + * + * The alias `.decreases` can be used interchangeably with `.decrease`. + * + * @name decrease + * @alias decreases + * @param {string | Function} subject + * @param {string} prop name _optional_ + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertDecreases(subject, prop, msg) { + if (msg) flag(this, 'message', msg); + let fn = flag(this, 'object'), + flagMsg = flag(this, 'message'), + ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + let initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + let final = prop === undefined || prop === null ? subject() : subject[prop]; + let msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'decrease'); + flag(this, 'realDelta', initial - final); + + this.assert( + final - initial < 0, + 'expected ' + msgObj + ' to decrease', + 'expected ' + msgObj + ' to not decrease' + ); +} + +Assertion.addMethod('decrease', assertDecreases); +Assertion.addMethod('decreases', assertDecreases); + +/** + * ### .by(delta[, msg]) + * + * When following an `.increase` assertion in the chain, `.by` asserts that + * the subject of the `.increase` assertion increased by the given `delta`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * When following a `.decrease` assertion in the chain, `.by` asserts that the + * subject of the `.decrease` assertion decreased by the given `delta`. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); + * + * When following a `.change` assertion in the chain, `.by` asserts that the + * subject of the `.change` assertion either increased or decreased by the + * given `delta`. However, it's dangerous to use `.change.by`. The problem is + * that it creates uncertain expectations. It's often best to identify the + * exact output that's expected, and then write an assertion that only accepts + * that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.by`. However, it's often best + * to assert that the subject changed by its expected delta, rather than + * asserting that it didn't change by one of countless unexpected deltas. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * // Recommended + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * // Not recommended + * expect(addTwo).to.increase(myObj, 'val').but.not.by(3); + * + * `.by` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??'); + * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3); + * + * @name by + * @param {number} delta + * @param {string} msg _optional_ + * @namespace BDD + * @public + */ +function assertDelta(delta, msg) { + if (msg) flag(this, 'message', msg); + + let msgObj = flag(this, 'deltaMsgObj'); + let initial = flag(this, 'initialDeltaValue'); + let final = flag(this, 'finalDeltaValue'); + let behavior = flag(this, 'deltaBehavior'); + let realDelta = flag(this, 'realDelta'); + + let expression; + if (behavior === 'change') { + expression = Math.abs(final - initial) === Math.abs(delta); + } else { + expression = realDelta === Math.abs(delta); + } + + this.assert( + expression, + 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta, + 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta + ); +} + +Assertion.addMethod('by', assertDelta); + +/** + * ### .extensible + * + * Asserts that the target is extensible, which means that new properties can + * be added to it. Primitives are never extensible. + * + * expect({a: 1}).to.be.extensible; + * + * Add `.not` earlier in the chain to negate `.extensible`. + * + * var nonExtensibleObject = Object.preventExtensions({}) + * , sealedObject = Object.seal({}) + * , frozenObject = Object.freeze({}); + * + * expect(nonExtensibleObject).to.not.be.extensible; + * expect(sealedObject).to.not.be.extensible; + * expect(frozenObject).to.not.be.extensible; + * expect(1).to.not.be.extensible; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(1, 'nooo why fail??').to.be.extensible; + * + * @name extensible + * @namespace BDD + * @public + */ +Assertion.addProperty('extensible', function () { + let obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + // The following provides ES6 behavior for ES5 environments. + + let isExtensible = obj === Object(obj) && Object.isExtensible(obj); + + this.assert( + isExtensible, + 'expected #{this} to be extensible', + 'expected #{this} to not be extensible' + ); +}); + +/** + * ### .sealed + * + * Asserts that the target is sealed, which means that new properties can't be + * added to it, and its existing properties can't be reconfigured or deleted. + * However, it's possible that its existing properties can still be reassigned + * to different values. Primitives are always sealed. + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect(sealedObject).to.be.sealed; + * expect(frozenObject).to.be.sealed; + * expect(1).to.be.sealed; + * + * Add `.not` earlier in the chain to negate `.sealed`. + * + * expect({a: 1}).to.not.be.sealed; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.sealed; + * + * @name sealed + * @namespace BDD + * @public + */ +Assertion.addProperty('sealed', function () { + let obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + // The following provides ES6 behavior for ES5 environments. + + let isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; + + this.assert( + isSealed, + 'expected #{this} to be sealed', + 'expected #{this} to not be sealed' + ); +}); + +/** + * ### .frozen + * + * Asserts that the target is frozen, which means that new properties can't be + * added to it, and its existing properties can't be reassigned to different + * values, reconfigured, or deleted. Primitives are always frozen. + * + * var frozenObject = Object.freeze({}); + * + * expect(frozenObject).to.be.frozen; + * expect(1).to.be.frozen; + * + * Add `.not` earlier in the chain to negate `.frozen`. + * + * expect({a: 1}).to.not.be.frozen; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.frozen; + * + * @name frozen + * @namespace BDD + * @public + */ +Assertion.addProperty('frozen', function () { + let obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + // The following provides ES6 behavior for ES5 environments. + + let isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; + + this.assert( + isFrozen, + 'expected #{this} to be frozen', + 'expected #{this} to not be frozen' + ); +}); + +/** + * ### .finite + * + * Asserts that the target is a number, and isn't `NaN` or positive/negative + * `Infinity`. + * + * expect(1).to.be.finite; + * + * Add `.not` earlier in the chain to negate `.finite`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either isn't a number, or that it's `NaN`, or + * that it's positive `Infinity`, or that it's negative `Infinity`. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to be a number, it's often best to assert + * that it's the expected type, rather than asserting that it isn't one of + * many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.finite; // Not recommended + * + * When the target is expected to be `NaN`, it's often best to assert exactly + * that. + * + * expect(NaN).to.be.NaN; // Recommended + * expect(NaN).to.not.be.finite; // Not recommended + * + * When the target is expected to be positive infinity, it's often best to + * assert exactly that. + * + * expect(Infinity).to.equal(Infinity); // Recommended + * expect(Infinity).to.not.be.finite; // Not recommended + * + * When the target is expected to be negative infinity, it's often best to + * assert exactly that. + * + * expect(-Infinity).to.equal(-Infinity); // Recommended + * expect(-Infinity).to.not.be.finite; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect('foo', 'nooo why fail??').to.be.finite; + * + * @name finite + * @namespace BDD + * @public + */ +Assertion.addProperty('finite', function (_msg) { + let obj = flag(this, 'object'); + + this.assert( + typeof obj === 'number' && isFinite(obj), + 'expected #{this} to be a finite number', + 'expected #{this} to not be a finite number' + ); +}); + +/** + * A subset-aware compare function + * + * @param {unknown} expected + * @param {unknown} actual + * @returns {boolean} + */ +function compareSubset(expected, actual) { + if (expected === actual) { + return true; + } + if (typeof actual !== typeof expected) { + return false; + } + if (typeof expected !== 'object' || expected === null) { + return expected === actual; + } + if (!actual) { + return false; + } + + if (Array.isArray(expected)) { + if (!Array.isArray(actual)) { + return false; + } + return expected.every(function (exp) { + return actual.some(function (act) { + return compareSubset(exp, act); + }); + }); + } + + if (expected instanceof Date) { + if (actual instanceof Date) { + return expected.getTime() === actual.getTime(); + } else { + return false; + } + } + + return Object.keys(expected).every(function (key) { + let expectedValue = expected[key]; + let actualValue = actual[key]; + if ( + typeof expectedValue === 'object' && + expectedValue !== null && + actualValue !== null + ) { + return compareSubset(expectedValue, actualValue); + } + if (typeof expectedValue === 'function') { + return expectedValue(actualValue); + } + return actualValue === expectedValue; + }); +} + +/** + * ### .containSubset + * + * Asserts that the target primitive/object/array structure deeply contains all provided fields + * at the same key/depth as the provided structure. + * + * When comparing arrays, the target must contain the subset of at least one of each object/value in the subset array. + * Order does not matter. + * + * expect({name: {first: "John", last: "Smith"}}).to.containSubset({name: {first: "John"}}); + * + * Add `.not` earlier in the chain to negate the assertion. This will cause the assertion to fail + * only if the target DOES contains the provided data at the expected keys/depths. + * + * @name containSubset + * @namespace BDD + * @public + */ +Assertion.addMethod('containSubset', function (expected) { + const actual = _.flag(this, 'object'); + const showDiff = config.showDiff; + + this.assert( + compareSubset(expected, actual), + 'expected #{act} to contain subset #{exp}', + 'expected #{act} to not contain subset #{exp}', + expected, + actual, + showDiff + ); +}); diff --git a/node_modules/chai/lib/chai/interface/assert.js b/node_modules/chai/lib/chai/interface/assert.js new file mode 100644 index 0000000000..9172121679 --- /dev/null +++ b/node_modules/chai/lib/chai/interface/assert.js @@ -0,0 +1,3228 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +import * as chai from '../../chai.js'; +import {Assertion} from '../assertion.js'; +import {flag, inspect} from '../utils/index.js'; +import {AssertionError} from 'assertion-error'; + +/** + * ### assert(expression, message) + * + * Write your own test expressions. + * + * assert('foo' !== 'bar', 'foo is not bar'); + * assert(Array.isArray([]), 'empty arrays are arrays'); + * + * @param {unknown} express - expression to test for truthiness + * @param {string} errmsg - message to display on error + * @name assert + * @namespace Assert + * @public + */ +export function assert(express, errmsg) { + let test = new Assertion(null, null, chai.assert, true); + test.assert(express, errmsg, '[ negation message unavailable ]'); +} + +/** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. Node.js `assert` module-compatible. + * + * assert.fail(); + * assert.fail("custom error message"); + * assert.fail(1, 2); + * assert.fail(1, 2, "custom error message"); + * assert.fail(1, 2, "custom error message", ">"); + * assert.fail(1, 2, undefined, ">"); + * + * @name fail + * @param {unknown} actual + * @param {unknown} expected + * @param {string} message + * @param {string} operator + * @namespace Assert + * @public + */ +assert.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + // Comply with Node's fail([message]) interface + + message = actual; + actual = undefined; + } + + message = message || 'assert.fail()'; + throw new AssertionError( + message, + { + actual: actual, + expected: expected, + operator: operator + }, + assert.fail + ); +}; + +/** + * ### .isOk(object, [message]) + * + * Asserts that `object` is truthy. + * + * assert.isOk('everything', 'everything is ok'); + * assert.isOk(false, 'this will fail'); + * + * @name isOk + * @alias ok + * @param {unknown} val object to test + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isOk = function (val, msg) { + new Assertion(val, msg, assert.isOk, true).is.ok; +}; + +/** + * ### .isNotOk(object, [message]) + * + * Asserts that `object` is falsy. + * + * assert.isNotOk('everything', 'this will fail'); + * assert.isNotOk(false, 'this will pass'); + * + * @name isNotOk + * @alias notOk + * @param {unknown} val object to test + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotOk = function (val, msg) { + new Assertion(val, msg, assert.isNotOk, true).is.not.ok; +}; + +/** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * assert.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {unknown} act + * @param {unknown} exp + * @param {string} msg + * @namespace Assert + * @public + */ +assert.equal = function (act, exp, msg) { + let test = new Assertion(act, msg, assert.equal, true); + + test.assert( + exp == flag(test, 'object'), + 'expected #{this} to equal #{exp}', + 'expected #{this} to not equal #{act}', + exp, + act, + true + ); +}; + +/** + * ### .notEqual(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * assert.notEqual(3, 4, 'these numbers are not equal'); + * + * @name notEqual + * @param {unknown} act + * @param {unknown} exp + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notEqual = function (act, exp, msg) { + let test = new Assertion(act, msg, assert.notEqual, true); + + test.assert( + exp != flag(test, 'object'), + 'expected #{this} to not equal #{exp}', + 'expected #{this} to equal #{act}', + exp, + act, + true + ); +}; + +/** + * ### .strictEqual(actual, expected, [message]) + * + * Asserts strict equality (`===`) of `actual` and `expected`. + * + * assert.strictEqual(true, true, 'these booleans are strictly equal'); + * + * @name strictEqual + * @param {unknown} act + * @param {unknown} exp + * @param {string} msg + * @namespace Assert + * @public + */ +assert.strictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); +}; + +/** + * ### .notStrictEqual(actual, expected, [message]) + * + * Asserts strict inequality (`!==`) of `actual` and `expected`. + * + * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); + * + * @name notStrictEqual + * @param {unknown} act + * @param {unknown} exp + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); +}; + +/** + * ### .deepEqual(actual, expected, [message]) + * + * Asserts that `actual` is deeply equal to `expected`. + * + * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); + * + * @name deepEqual + * @param {unknown} act + * @param {unknown} exp + * @param {string} msg + * @alias deepStrictEqual + * @namespace Assert + * @public + */ +assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); +}; + +/** + * ### .notDeepEqual(actual, expected, [message]) + * + * Assert that `actual` is not deeply equal to `expected`. + * + * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); + * + * @name notDeepEqual + * @param {unknown} act + * @param {unknown} exp + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notDeepEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); +}; + +/** + * ### .isAbove(valueToCheck, valueToBeAbove, [message]) + * + * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`. + * + * assert.isAbove(5, 2, '5 is strictly greater than 2'); + * + * @name isAbove + * @param {unknown} val + * @param {unknown} abv + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isAbove = function (val, abv, msg) { + new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); +}; + +/** + * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) + * + * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`. + * + * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); + * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); + * + * @name isAtLeast + * @param {unknown} val + * @param {unknown} atlst + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isAtLeast = function (val, atlst, msg) { + new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); +}; + +/** + * ### .isBelow(valueToCheck, valueToBeBelow, [message]) + * + * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`. + * + * assert.isBelow(3, 6, '3 is strictly less than 6'); + * + * @name isBelow + * @param {unknown} val + * @param {unknown} blw + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isBelow = function (val, blw, msg) { + new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); +}; + +/** + * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) + * + * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`. + * + * assert.isAtMost(3, 6, '3 is less than or equal to 6'); + * assert.isAtMost(4, 4, '4 is less than or equal to 4'); + * + * @name isAtMost + * @param {unknown} val + * @param {unknown} atmst + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isAtMost = function (val, atmst, msg) { + new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); +}; + +/** + * ### .isTrue(value, [message]) + * + * Asserts that `value` is true. + * + * var teaServed = true; + * assert.isTrue(teaServed, 'the tea has been served'); + * + * @name isTrue + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isTrue = function (val, msg) { + new Assertion(val, msg, assert.isTrue, true).is['true']; +}; + +/** + * ### .isNotTrue(value, [message]) + * + * Asserts that `value` is not true. + * + * var tea = 'tasty chai'; + * assert.isNotTrue(tea, 'great, time for tea!'); + * + * @name isNotTrue + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotTrue = function (val, msg) { + new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); +}; + +/** + * ### .isFalse(value, [message]) + * + * Asserts that `value` is false. + * + * var teaServed = false; + * assert.isFalse(teaServed, 'no tea yet? hmm...'); + * + * @name isFalse + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isFalse = function (val, msg) { + new Assertion(val, msg, assert.isFalse, true).is['false']; +}; + +/** + * ### .isNotFalse(value, [message]) + * + * Asserts that `value` is not false. + * + * var tea = 'tasty chai'; + * assert.isNotFalse(tea, 'great, time for tea!'); + * + * @name isNotFalse + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotFalse = function (val, msg) { + new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); +}; + +/** + * ### .isNull(value, [message]) + * + * Asserts that `value` is null. + * + * assert.isNull(err, 'there was no error'); + * + * @name isNull + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNull = function (val, msg) { + new Assertion(val, msg, assert.isNull, true).to.equal(null); +}; + +/** + * ### .isNotNull(value, [message]) + * + * Asserts that `value` is not null. + * + * var tea = 'tasty chai'; + * assert.isNotNull(tea, 'great, time for tea!'); + * + * @name isNotNull + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotNull = function (val, msg) { + new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); +}; + +/** + * ### .isNaN + * + * Asserts that value is NaN. + * + * assert.isNaN(NaN, 'NaN is NaN'); + * + * @name isNaN + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNaN = function (val, msg) { + new Assertion(val, msg, assert.isNaN, true).to.be.NaN; +}; + +/** + * ### .isNotNaN + * + * Asserts that value is not NaN. + * + * assert.isNotNaN(4, '4 is not NaN'); + * + * @name isNotNaN + * @param {unknown} value + * @param {string} message + * @namespace Assert + * @public + */ +assert.isNotNaN = function (value, message) { + new Assertion(value, message, assert.isNotNaN, true).not.to.be.NaN; +}; + +/** + * ### .exists + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * assert.exists(foo, 'foo is neither `null` nor `undefined`'); + * + * @name exists + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.exists = function (val, msg) { + new Assertion(val, msg, assert.exists, true).to.exist; +}; + +/** + * ### .notExists + * + * Asserts that the target is either `null` or `undefined`. + * + * var bar = null + * , baz; + * + * assert.notExists(bar); + * assert.notExists(baz, 'baz is either null or undefined'); + * + * @name notExists + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notExists = function (val, msg) { + new Assertion(val, msg, assert.notExists, true).to.not.exist; +}; + +/** + * ### .isUndefined(value, [message]) + * + * Asserts that `value` is `undefined`. + * + * var tea; + * assert.isUndefined(tea, 'no tea defined'); + * + * @name isUndefined + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isUndefined = function (val, msg) { + new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined); +}; + +/** + * ### .isDefined(value, [message]) + * + * Asserts that `value` is not `undefined`. + * + * var tea = 'cup of chai'; + * assert.isDefined(tea, 'tea has been defined'); + * + * @name isDefined + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isDefined = function (val, msg) { + new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined); +}; + +/** + * ### .isCallable(value, [message]) + * + * Asserts that `value` is a callable function. + * + * function serveTea() { return 'cup of tea'; }; + * assert.isCallable(serveTea, 'great, we can have tea now'); + * + * @name isCallable + * @param {unknown} value + * @param {string} message + * @namespace Assert + * @public + */ +assert.isCallable = function (value, message) { + new Assertion(value, message, assert.isCallable, true).is.callable; +}; + +/** + * ### .isNotCallable(value, [message]) + * + * Asserts that `value` is _not_ a callable function. + * + * var serveTea = [ 'heat', 'pour', 'sip' ]; + * assert.isNotCallable(serveTea, 'great, we have listed the steps'); + * + * @name isNotCallable + * @param {unknown} value + * @param {string} message + * @namespace Assert + * @public + */ +assert.isNotCallable = function (value, message) { + new Assertion(value, message, assert.isNotCallable, true).is.not.callable; +}; + +/** + * ### .isObject(value, [message]) + * + * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). + * _The assertion does not match subclassed objects._ + * + * var selection = { name: 'Chai', serve: 'with spices' }; + * assert.isObject(selection, 'tea selection is an object'); + * + * @name isObject + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isObject = function (val, msg) { + new Assertion(val, msg, assert.isObject, true).to.be.a('object'); +}; + +/** + * ### .isNotObject(value, [message]) + * + * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). + * + * var selection = 'chai' + * assert.isNotObject(selection, 'tea selection is not an object'); + * assert.isNotObject(null, 'null is not an object'); + * + * @name isNotObject + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotObject = function (val, msg) { + new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object'); +}; + +/** + * ### .isArray(value, [message]) + * + * Asserts that `value` is an array. + * + * var menu = [ 'green', 'chai', 'oolong' ]; + * assert.isArray(menu, 'what kind of tea do we want?'); + * + * @name isArray + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isArray = function (val, msg) { + new Assertion(val, msg, assert.isArray, true).to.be.an('array'); +}; + +/** + * ### .isNotArray(value, [message]) + * + * Asserts that `value` is _not_ an array. + * + * var menu = 'green|chai|oolong'; + * assert.isNotArray(menu, 'what kind of tea do we want?'); + * + * @name isNotArray + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotArray = function (val, msg) { + new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array'); +}; + +/** + * ### .isString(value, [message]) + * + * Asserts that `value` is a string. + * + * var teaOrder = 'chai'; + * assert.isString(teaOrder, 'order placed'); + * + * @name isString + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isString = function (val, msg) { + new Assertion(val, msg, assert.isString, true).to.be.a('string'); +}; + +/** + * ### .isNotString(value, [message]) + * + * Asserts that `value` is _not_ a string. + * + * var teaOrder = 4; + * assert.isNotString(teaOrder, 'order placed'); + * + * @name isNotString + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotString = function (val, msg) { + new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string'); +}; + +/** + * ### .isNumber(value, [message]) + * + * Asserts that `value` is a number. + * + * var cups = 2; + * assert.isNumber(cups, 'how many cups'); + * + * @name isNumber + * @param {number} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNumber = function (val, msg) { + new Assertion(val, msg, assert.isNumber, true).to.be.a('number'); +}; + +/** + * ### .isNotNumber(value, [message]) + * + * Asserts that `value` is _not_ a number. + * + * var cups = '2 cups please'; + * assert.isNotNumber(cups, 'how many cups'); + * + * @name isNotNumber + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotNumber = function (val, msg) { + new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number'); +}; + +/** + * ### .isNumeric(value, [message]) + * + * Asserts that `value` is a number or BigInt. + * + * var cups = 2; + * assert.isNumeric(cups, 'how many cups'); + * + * var cups = 10n; + * assert.isNumeric(cups, 'how many cups'); + * + * @name isNumeric + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNumeric = function (val, msg) { + new Assertion(val, msg, assert.isNumeric, true).is.numeric; +}; + +/** + * ### .isNotNumeric(value, [message]) + * + * Asserts that `value` is _not_ a number or BigInt. + * + * var cups = '2 cups please'; + * assert.isNotNumeric(cups, 'how many cups'); + * + * @name isNotNumeric + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotNumeric = function (val, msg) { + new Assertion(val, msg, assert.isNotNumeric, true).is.not.numeric; +}; + +/** + * ### .isFinite(value, [message]) + * + * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. + * + * var cups = 2; + * assert.isFinite(cups, 'how many cups'); + * assert.isFinite(NaN); // throws + * + * @name isFinite + * @param {number} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isFinite = function (val, msg) { + new Assertion(val, msg, assert.isFinite, true).to.be.finite; +}; + +/** + * ### .isBoolean(value, [message]) + * + * Asserts that `value` is a boolean. + * + * var teaReady = true + * , teaServed = false; + * + * assert.isBoolean(teaReady, 'is the tea ready'); + * assert.isBoolean(teaServed, 'has tea been served'); + * + * @name isBoolean + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isBoolean = function (val, msg) { + new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean'); +}; + +/** + * ### .isNotBoolean(value, [message]) + * + * Asserts that `value` is _not_ a boolean. + * + * var teaReady = 'yep' + * , teaServed = 'nope'; + * + * assert.isNotBoolean(teaReady, 'is the tea ready'); + * assert.isNotBoolean(teaServed, 'has tea been served'); + * + * @name isNotBoolean + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.isNotBoolean = function (val, msg) { + new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean'); +}; + +/** + * ### .typeOf(value, name, [message]) + * + * Asserts that `value`'s type is `name`, as determined by + * `Object.prototype.toString`. + * + * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); + * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); + * assert.typeOf('tea', 'string', 'we have a string'); + * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); + * assert.typeOf(null, 'null', 'we have a null'); + * assert.typeOf(undefined, 'undefined', 'we have an undefined'); + * + * @name typeOf + * @param {unknown} val + * @param {string} type + * @param {string} msg + * @namespace Assert + * @public + */ +assert.typeOf = function (val, type, msg) { + new Assertion(val, msg, assert.typeOf, true).to.be.a(type); +}; + +/** + * ### .notTypeOf(value, name, [message]) + * + * Asserts that `value`'s type is _not_ `name`, as determined by + * `Object.prototype.toString`. + * + * assert.notTypeOf('tea', 'number', 'strings are not numbers'); + * + * @name notTypeOf + * @param {unknown} value + * @param {string} type + * @param {string} message + * @namespace Assert + * @public + */ +assert.notTypeOf = function (value, type, message) { + new Assertion(value, message, assert.notTypeOf, true).to.not.be.a(type); +}; + +/** + * ### .instanceOf(object, constructor, [message]) + * + * Asserts that `value` is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new Tea('chai'); + * + * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); + * + * @name instanceOf + * @param {object} val + * @param {object} type + * @param {string} msg + * @namespace Assert + * @public + */ +assert.instanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type); +}; + +/** + * ### .notInstanceOf(object, constructor, [message]) + * + * Asserts `value` is not an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new String('chai'); + * + * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); + * + * @name notInstanceOf + * @param {object} val + * @param {object} type + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notInstanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.notInstanceOf, true).to.not.be.instanceOf( + type + ); +}; + +/** + * ### .include(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.include([1,2,3], 2, 'array contains value'); + * assert.include('foobar', 'foo', 'string contains substring'); + * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property'); + * + * Strict equality (===) is used. When asserting the inclusion of a value in + * an array, the array is searched for an element that's strictly equal to the + * given value. When asserting a subset of properties in an object, the object + * is searched for the given property keys, checking that each one is present + * and strictly equal to the given property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.include([obj1, obj2], obj1); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1}); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); + * + * @name include + * @param {Array | string} exp + * @param {unknown} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.include = function (exp, inc, msg) { + new Assertion(exp, msg, assert.include, true).include(inc); +}; + +/** + * ### .notInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.notInclude([1,2,3], 4, "array doesn't contain value"); + * assert.notInclude('foobar', 'baz', "string doesn't contain substring"); + * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property'); + * + * Strict equality (===) is used. When asserting the absence of a value in an + * array, the array is searched to confirm the absence of an element that's + * strictly equal to the given value. When asserting a subset of properties in + * an object, the object is searched to confirm that at least one of the given + * property keys is either not present or not strictly equal to the given + * property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notInclude([obj1, obj2], {a: 1}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); + * + * @name notInclude + * @param {Array | string} exp + * @param {unknown} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude, true).not.include(inc); +}; + +/** + * ### .deepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.deepInclude([obj1, obj2], {a: 1}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); + * + * @name deepInclude + * @param {Array | string} exp + * @param {unknown} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.deepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); +}; + +/** + * ### .notDeepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notDeepInclude([obj1, obj2], {a: 9}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); + * + * @name notDeepInclude + * @param {Array | string} exp + * @param {unknown} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notDeepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); +}; + +/** + * ### .nestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'}); + * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'}); + * + * @name nestedInclude + * @param {object} exp + * @param {object} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.nestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); +}; + +/** + * ### .notNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'}); + * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'}); + * + * @name notNestedInclude + * @param {object} exp + * @param {object} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notNestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notNestedInclude, true).not.nested.include( + inc + ); +}; + +/** + * ### .deepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); + * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); + * + * @name deepNestedInclude + * @param {object} exp + * @param {object} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.deepNestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.deepNestedInclude, true).deep.nested.include( + inc + ); +}; + +/** + * ### .notDeepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}}) + * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); + * + * @name notDeepNestedInclude + * @param {object} exp + * @param {object} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notDeepNestedInclude = function (exp, inc, msg) { + new Assertion( + exp, + msg, + assert.notDeepNestedInclude, + true + ).not.deep.nested.include(inc); +}; + +/** + * ### .ownInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties. + * + * assert.ownInclude({ a: 1 }, { a: 1 }); + * + * @name ownInclude + * @param {object} exp + * @param {object} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.ownInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); +}; + +/** + * ### .notOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties. + * + * Object.prototype.b = 2; + * assert.notOwnInclude({ a: 1 }, { b: 2 }); + * + * @name notOwnInclude + * @param {object} exp + * @param {object} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notOwnInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); +}; + +/** + * ### .deepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); + * + * @name deepOwnInclude + * @param {object} exp + * @param {object} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.deepOwnInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.deepOwnInclude, true).deep.own.include(inc); +}; + +/** + * ### .notDeepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); + * + * @name notDeepOwnInclude + * @param {object} exp + * @param {object} inc + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notDeepOwnInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepOwnInclude, true).not.deep.own.include( + inc + ); +}; + +/** + * ### .match(value, regexp, [message]) + * + * Asserts that `value` matches the regular expression `regexp`. + * + * assert.match('foobar', /^foo/, 'regexp matches'); + * + * @name match + * @param {unknown} exp + * @param {RegExp} re + * @param {string} msg + * @namespace Assert + * @public + */ +assert.match = function (exp, re, msg) { + new Assertion(exp, msg, assert.match, true).to.match(re); +}; + +/** + * ### .notMatch(value, regexp, [message]) + * + * Asserts that `value` does not match the regular expression `regexp`. + * + * assert.notMatch('foobar', /^foo/, 'regexp does not match'); + * + * @name notMatch + * @param {unknown} exp + * @param {RegExp} re + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notMatch = function (exp, re, msg) { + new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); +}; + +/** + * ### .property(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`. + * + * assert.property({ tea: { green: 'matcha' }}, 'tea'); + * assert.property({ tea: { green: 'matcha' }}, 'toString'); + * + * @name property + * @param {object} obj + * @param {string} prop + * @param {string} msg + * @namespace Assert + * @public + */ +assert.property = function (obj, prop, msg) { + new Assertion(obj, msg, assert.property, true).to.have.property(prop); +}; + +/** + * ### .notProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property`. + * + * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); + * + * @name notProperty + * @param {object} obj + * @param {string} prop + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notProperty, true).to.not.have.property(prop); +}; + +/** + * ### .propertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a strict equality check + * (===). + * + * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); + * + * @name propertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.propertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.propertyVal, true).to.have.property(prop, val); +}; + +/** + * ### .notPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a strict equality check + * (===). + * + * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad'); + * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good'); + * + * @name notPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notPropertyVal, true).to.not.have.property( + prop, + val + ); +}; + +/** + * ### .deepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a deep equality check. + * + * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.deepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepPropertyVal, true).to.have.deep.property( + prop, + val + ); +}; + +/** + * ### .notDeepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a deep equality check. + * + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * + * @name notDeepPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notDeepPropertyVal = function (obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.notDeepPropertyVal, + true + ).to.not.have.deep.property(prop, val); +}; + +/** + * ### .ownProperty(object, property, [message]) + * + * Asserts that `object` has a direct property named by `property`. Inherited + * properties aren't checked. + * + * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea'); + * + * @name ownProperty + * @param {object} obj + * @param {string} prop + * @param {string} msg + * @public + */ +assert.ownProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.ownProperty, true).to.have.own.property(prop); +}; + +/** + * ### .notOwnProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct property named by + * `property`. Inherited properties aren't checked. + * + * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee'); + * assert.notOwnProperty({}, 'toString'); + * + * @name notOwnProperty + * @param {object} obj + * @param {string} prop + * @param {string} msg + * @public + */ +assert.notOwnProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notOwnProperty, true).to.not.have.own.property( + prop + ); +}; + +/** + * ### .ownPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a strict equality check (===). + * Inherited properties aren't checked. + * + * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good'); + * + * @name ownPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} value + * @param {string} msg + * @public + */ +assert.ownPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.ownPropertyVal, true).to.have.own.property( + prop, + value + ); +}; + +/** + * ### .notOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a strict equality check + * (===). Inherited properties aren't checked. + * + * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse'); + * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notOwnPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} value + * @param {string} msg + * @public + */ +assert.notOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion( + obj, + msg, + assert.notOwnPropertyVal, + true + ).to.not.have.own.property(prop, value); +}; + +/** + * ### .deepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a deep equality check. Inherited + * properties aren't checked. + * + * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepOwnPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} value + * @param {string} msg + * @public + */ +assert.deepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion( + obj, + msg, + assert.deepOwnPropertyVal, + true + ).to.have.deep.own.property(prop, value); +}; + +/** + * ### .notDeepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a deep equality check. + * Inherited properties aren't checked. + * + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notDeepOwnPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} value + * @param {string} msg + * @public + */ +assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion( + obj, + msg, + assert.notDeepOwnPropertyVal, + true + ).to.not.have.deep.own.property(prop, value); +}; + +/** + * ### .nestedProperty(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`, which can be a string using dot- and bracket-notation for + * nested reference. + * + * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green'); + * + * @name nestedProperty + * @param {object} obj + * @param {string} prop + * @param {string} msg + * @namespace Assert + * @public + */ +assert.nestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.nestedProperty, true).to.have.nested.property( + prop + ); +}; + +/** + * ### .notNestedProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`, which + * can be a string using dot- and bracket-notation for nested reference. The + * property cannot exist on the object nor anywhere in its prototype chain. + * + * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); + * + * @name notNestedProperty + * @param {object} obj + * @param {string} prop + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notNestedProperty = function (obj, prop, msg) { + new Assertion( + obj, + msg, + assert.notNestedProperty, + true + ).to.not.have.nested.property(prop); +}; + +/** + * ### .nestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a strict equality check (===). + * + * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); + * + * @name nestedPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.nestedPropertyVal = function (obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.nestedPropertyVal, + true + ).to.have.nested.property(prop, val); +}; + +/** + * ### .notNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a strict equality check (===). + * + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha'); + * + * @name notNestedPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.notNestedPropertyVal, + true + ).to.not.have.nested.property(prop, val); +}; + +/** + * ### .deepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with a value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a deep equality check. + * + * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' }); + * + * @name deepNestedPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.deepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.deepNestedPropertyVal, + true + ).to.have.deep.nested.property(prop, val); +}; + +/** + * ### .notDeepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a deep equality check. + * + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }); + * + * @name notDeepNestedPropertyVal + * @param {object} obj + * @param {string} prop + * @param {unknown} val + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion( + obj, + msg, + assert.notDeepNestedPropertyVal, + true + ).to.not.have.deep.nested.property(prop, val); +}; + +/** + * ### .lengthOf(object, length, [message]) + * + * Asserts that `object` has a `length` or `size` with the expected value. + * + * assert.lengthOf([1,2,3], 3, 'array has length of 3'); + * assert.lengthOf('foobar', 6, 'string has length of 6'); + * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3'); + * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3'); + * + * @name lengthOf + * @param {unknown} exp + * @param {number} len + * @param {string} msg + * @namespace Assert + * @public + */ +assert.lengthOf = function (exp, len, msg) { + new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); +}; + +/** + * ### .hasAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); + * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAnyKeys + * @param {unknown} obj + * @param {Array | object} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.hasAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); +}; + +/** + * ### .hasAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]); + * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAllKeys + * @param {unknown} obj + * @param {string[]} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.hasAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); +}; + +/** + * ### .containsAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all of the `keys` provided but may have more keys not listed. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337}); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337}); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}]); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); + * + * @name containsAllKeys + * @param {unknown} obj + * @param {string[]} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.containsAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllKeys, true).to.contain.all.keys( + keys + ); +}; + +/** + * ### .doesNotHaveAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{one: 'two'}, 'example']); + * + * @name doesNotHaveAnyKeys + * @param {unknown} obj + * @param {string[]} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.doesNotHaveAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true).to.not.have.any.keys( + keys + ); +}; + +/** + * ### .doesNotHaveAllKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{one: 'two'}, 'example']); + * + * @name doesNotHaveAllKeys + * @param {unknown} obj + * @param {string[]} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.doesNotHaveAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllKeys, true).to.not.have.all.keys( + keys + ); +}; + +/** + * ### .hasAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name hasAnyDeepKeys + * @param {unknown} obj + * @param {Array | object} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.hasAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyDeepKeys, true).to.have.any.deep.keys( + keys + ); +}; + +/** + * ### .hasAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'}); + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'}); + * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name hasAllDeepKeys + * @param {unknown} obj + * @param {Array | object} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.hasAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllDeepKeys, true).to.have.all.deep.keys( + keys + ); +}; + +/** + * ### .containsAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name containsAllDeepKeys + * @param {unknown} obj + * @param {Array | object} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.containsAllDeepKeys = function (obj, keys, msg) { + new Assertion( + obj, + msg, + assert.containsAllDeepKeys, + true + ).to.contain.all.deep.keys(keys); +}; + +/** + * ### .doesNotHaveAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAnyDeepKeys + * @param {unknown} obj + * @param {Array | object} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) { + new Assertion( + obj, + msg, + assert.doesNotHaveAnyDeepKeys, + true + ).to.not.have.any.deep.keys(keys); +}; + +/** + * ### .doesNotHaveAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAllDeepKeys + * @param {unknown} obj + * @param {Array | object} keys + * @param {string} msg + * @namespace Assert + * @public + */ +assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) { + new Assertion( + obj, + msg, + assert.doesNotHaveAllDeepKeys, + true + ).to.not.have.all.deep.keys(keys); +}; + +/** + * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a + * message matching `errMsgMatcher`. + * + * assert.throws(fn, 'Error thrown must have this msg'); + * assert.throws(fn, /Error thrown must have a msg that matches this/); + * assert.throws(fn, ReferenceError); + * assert.throws(fn, errorInstance); + * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg'); + * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg'); + * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/); + * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/); + * + * @name throws + * @alias throw + * @alias Throw + * @param {Function} fn + * @param {Error} errorLike + * @param {RegExp | string} errMsgMatcher + * @param {string} msg + * @returns {unknown} + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @public + */ +assert.throws = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + let assertErr = new Assertion(fn, msg, assert.throws, true).to.throw( + errorLike, + errMsgMatcher + ); + return flag(assertErr, 'object'); +}; + +/** + * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a + * message matching `errMsgMatcher`. + * + * assert.doesNotThrow(fn, 'Any Error thrown must not have this message'); + * assert.doesNotThrow(fn, /Any Error thrown must not match this/); + * assert.doesNotThrow(fn, Error); + * assert.doesNotThrow(fn, errorInstance); + * assert.doesNotThrow(fn, Error, 'Error must not have this message'); + * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message'); + * assert.doesNotThrow(fn, Error, /Error must not match this/); + * assert.doesNotThrow(fn, errorInstance, /Error must not match this/); + * + * @name doesNotThrow + * @param {Function} fn + * @param {Error} errorLike + * @param {RegExp | string} errMsgMatcher + * @param {string} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @public + */ +assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, message) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + new Assertion(fn, message, assert.doesNotThrow, true).to.not.throw( + errorLike, + errMsgMatcher + ); +}; + +/** + * ### .operator(val1, operator, val2, [message]) + * + * Compares two values using `operator`. + * + * assert.operator(1, '<', 2, 'everything is ok'); + * assert.operator(1, '>', 2, 'this will fail'); + * + * @name operator + * @param {unknown} val + * @param {string} operator + * @param {unknown} val2 + * @param {string} msg + * @namespace Assert + * @public + */ +assert.operator = function (val, operator, val2, msg) { + let ok; + switch (operator) { + case '==': + ok = val == val2; + break; + case '===': + ok = val === val2; + break; + case '>': + ok = val > val2; + break; + case '>=': + ok = val >= val2; + break; + case '<': + ok = val < val2; + break; + case '<=': + ok = val <= val2; + break; + case '!=': + ok = val != val2; + break; + case '!==': + ok = val !== val2; + break; + default: + msg = msg ? msg + ': ' : msg; + throw new AssertionError( + msg + 'Invalid operator "' + operator + '"', + undefined, + assert.operator + ); + } + let test = new Assertion(ok, msg, assert.operator, true); + test.assert( + true === flag(test, 'object'), + 'expected ' + inspect(val) + ' to be ' + operator + ' ' + inspect(val2), + 'expected ' + inspect(val) + ' to not be ' + operator + ' ' + inspect(val2) + ); +}; + +/** + * ### .closeTo(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); + * + * @name closeTo + * @param {number} act + * @param {number} exp + * @param {number} delta + * @param {string} msg + * @namespace Assert + * @public + */ +assert.closeTo = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); +}; + +/** + * ### .approximately(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.approximately(1.5, 1, 0.5, 'numbers are close'); + * + * @name approximately + * @param {number} act + * @param {number} exp + * @param {number} delta + * @param {string} msg + * @namespace Assert + * @public + */ +assert.approximately = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.approximately, true).to.be.approximately( + exp, + delta + ); +}; + +/** + * ### .sameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * strict equality check (===). + * + * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + * + * @name sameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {string} msg + * @namespace Assert + * @public + */ +assert.sameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameMembers, true).to.have.same.members(set2); +}; + +/** + * ### .notSameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a strict equality check (===). + * + * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members'); + * + * @name notSameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notSameMembers = function (set1, set2, msg) { + new Assertion( + set1, + msg, + assert.notSameMembers, + true + ).to.not.have.same.members(set2); +}; + +/** + * ### .sameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * deep equality check. + * + * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members'); + * + * @name sameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {string} msg + * @namespace Assert + * @public + */ +assert.sameDeepMembers = function (set1, set2, msg) { + new Assertion( + set1, + msg, + assert.sameDeepMembers, + true + ).to.have.same.deep.members(set2); +}; + +/** + * ### .notSameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a deep equality check. + * + * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members'); + * + * @name notSameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notSameDeepMembers = function (set1, set2, msg) { + new Assertion( + set1, + msg, + assert.notSameDeepMembers, + true + ).to.not.have.same.deep.members(set2); +}; + +/** + * ### .sameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a strict equality check (===). + * + * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members'); + * + * @name sameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {string} msg + * @namespace Assert + * @public + */ +assert.sameOrderedMembers = function (set1, set2, msg) { + new Assertion( + set1, + msg, + assert.sameOrderedMembers, + true + ).to.have.same.ordered.members(set2); +}; + +/** + * ### .notSameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a strict equality check (===). + * + * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members'); + * + * @name notSameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notSameOrderedMembers = function (set1, set2, msg) { + new Assertion( + set1, + msg, + assert.notSameOrderedMembers, + true + ).to.not.have.same.ordered.members(set2); +}; + +/** + * ### .sameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a deep equality check. + * + * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members'); + * + * @name sameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {string} msg + * @namespace Assert + * @public + */ +assert.sameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion( + set1, + msg, + assert.sameDeepOrderedMembers, + true + ).to.have.same.deep.ordered.members(set2); +}; + +/** + * ### .notSameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a deep equality check. + * + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members'); + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members'); + * + * @name notSameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notSameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion( + set1, + msg, + assert.notSameDeepOrderedMembers, + true + ).to.not.have.same.deep.ordered.members(set2); +}; + +/** + * ### .includeMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members'); + * + * @name includeMembers + * @param {Array} superset + * @param {Array} subset + * @param {string} msg + * @namespace Assert + * @public + */ +assert.includeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeMembers, true).to.include.members( + subset + ); +}; + +/** + * ### .notIncludeMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members'); + * + * @name notIncludeMembers + * @param {Array} superset + * @param {Array} subset + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notIncludeMembers = function (superset, subset, msg) { + new Assertion( + superset, + msg, + assert.notIncludeMembers, + true + ).to.not.include.members(subset); +}; + +/** + * ### .includeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a deep + * equality check. Duplicates are ignored. + * + * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members'); + * + * @name includeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {string} msg + * @namespace Assert + * @public + */ +assert.includeDeepMembers = function (superset, subset, msg) { + new Assertion( + superset, + msg, + assert.includeDeepMembers, + true + ).to.include.deep.members(subset); +}; + +/** + * ### .notIncludeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * deep equality check. Duplicates are ignored. + * + * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); + * + * @name notIncludeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notIncludeDeepMembers = function (superset, subset, msg) { + new Assertion( + superset, + msg, + assert.notIncludeDeepMembers, + true + ).to.not.include.deep.members(subset); +}; + +/** + * ### .includeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members'); + * + * @name includeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {string} msg + * @namespace Assert + * @public + */ +assert.includeOrderedMembers = function (superset, subset, msg) { + new Assertion( + superset, + msg, + assert.includeOrderedMembers, + true + ).to.include.ordered.members(subset); +}; + +/** + * ### .notIncludeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members'); + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members'); + * + * @name notIncludeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notIncludeOrderedMembers = function (superset, subset, msg) { + new Assertion( + superset, + msg, + assert.notIncludeOrderedMembers, + true + ).to.not.include.ordered.members(subset); +}; + +/** + * ### .includeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members'); + * + * @name includeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {string} msg + * @namespace Assert + * @public + */ +assert.includeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion( + superset, + msg, + assert.includeDeepOrderedMembers, + true + ).to.include.deep.ordered.members(subset); +}; + +/** + * ### .notIncludeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members'); + * + * @name notIncludeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {string} msg + * @namespace Assert + * @public + */ +assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion( + superset, + msg, + assert.notIncludeDeepOrderedMembers, + true + ).to.not.include.deep.ordered.members(subset); +}; + +/** + * ### .oneOf(inList, list, [message]) + * + * Asserts that non-object, non-array value `inList` appears in the flat array `list`. + * + * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); + * + * @name oneOf + * @param {*} inList + * @param {Array<*>} list + * @param {string} msg + * @namespace Assert + * @public + */ +assert.oneOf = function (inList, list, msg) { + new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); +}; + +/** + * ### isIterable(obj, [message]) + * + * Asserts that the target is an iterable, which means that it has a iterator + * with the exception of `String.` + * + * assert.isIterable([1, 2]); + * + * @param {unknown} obj + * @param {string} [msg] + * @namespace Assert + * @public + */ +assert.isIterable = function (obj, msg) { + if (obj == undefined || !obj[Symbol.iterator]) { + msg = msg + ? `${msg} expected ${inspect(obj)} to be an iterable` + : `expected ${inspect(obj)} to be an iterable`; + + throw new AssertionError(msg, undefined, assert.isIterable); + } +}; + +/** + * ### .changes(function, object, property, [message]) + * + * Asserts that a function changes the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 22 }; + * assert.changes(fn, obj, 'val'); + * + * @name changes + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.changes = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); +}; + +/** + * ### .changesBy(function, object, property, delta, [message]) + * + * Asserts that a function changes the value of a property by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 2 }; + * assert.changesBy(fn, obj, 'val', 2); + * + * @name changesBy + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @param {number} delta msg change amount (delta) + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.changesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesBy, true).to.change(obj, prop).by(delta); +}; + +/** + * ### .doesNotChange(function, object, property, [message]) + * + * Asserts that a function does not change the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { console.log('foo'); }; + * assert.doesNotChange(fn, obj, 'val'); + * + * @name doesNotChange + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @param {string} msg _optional_ + * @returns {unknown} + * @namespace Assert + * @public + */ +assert.doesNotChange = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotChange, true).to.not.change( + obj, + prop + ); +}; + +/** + * ### .changesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.changesButNotBy(fn, obj, 'val', 5); + * + * @name changesButNotBy + * @param {Function} fn - modifier function + * @param {object} obj - object or getter function + * @param {string} prop - property name _optional_ + * @param {number} delta - change amount (delta) + * @param {string} msg - message _optional_ + * @namespace Assert + * @public + */ +assert.changesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesButNotBy, true).to + .change(obj, prop) + .but.not.by(delta); +}; + +/** + * ### .increases(function, object, property, [message]) + * + * Asserts that a function increases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 13 }; + * assert.increases(fn, obj, 'val'); + * + * @public + * @namespace Assert + * @name increases + * @param {Function} fn - modifier function + * @param {object} obj - object or getter function + * @param {string} prop - property name _optional_ + * @param {string} msg - message _optional_ + * @returns {unknown} + */ +assert.increases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.increases, true).to.increase(obj, prop); +}; + +/** + * ### .increasesBy(function, object, property, delta, [message]) + * + * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.increasesBy(fn, obj, 'val', 10); + * + * @public + * @name increasesBy + * @namespace Assert + * @param {Function} fn - modifier function + * @param {object} obj - object or getter function + * @param {string} prop - property name _optional_ + * @param {number} delta - change amount (delta) + * @param {string} msg - message _optional_ + */ +assert.increasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesBy, true).to + .increase(obj, prop) + .by(delta); +}; + +/** + * ### .doesNotIncrease(function, object, property, [message]) + * + * Asserts that a function does not increase a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 8 }; + * assert.doesNotIncrease(fn, obj, 'val'); + * + * @name doesNotIncrease + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @returns {Assertion} + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.doesNotIncrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotIncrease, true).to.not.increase( + obj, + prop + ); +}; + +/** + * ### .increasesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.increasesButNotBy(fn, obj, 'val', 10); + * + * @name increasesButNotBy + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @param {number} delta change amount (delta) + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.increasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesButNotBy, true).to + .increase(obj, prop) + .but.not.by(delta); +}; + +/** + * ### .decreases(function, object, property, [message]) + * + * Asserts that a function decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreases(fn, obj, 'val'); + * + * @name decreases + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @returns {Assertion} + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.decreases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.decreases, true).to.decrease(obj, prop); +}; + +/** + * ### .decreasesBy(function, object, property, delta, [message]) + * + * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val -= 5 }; + * assert.decreasesBy(fn, obj, 'val', 5); + * + * @name decreasesBy + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @param {number} delta change amount (delta) + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.decreasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesBy, true).to + .decrease(obj, prop) + .by(delta); +}; + +/** + * ### .doesNotDecrease(function, object, property, [message]) + * + * Asserts that a function does not decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.doesNotDecrease(fn, obj, 'val'); + * + * @name doesNotDecrease + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @returns {Assertion} + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.doesNotDecrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecrease, true).to.not.decrease( + obj, + prop + ); +}; + +/** + * ### .doesNotDecreaseBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.doesNotDecreaseBy(fn, obj, 'val', 1); + * + * @name doesNotDecreaseBy + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @param {number} delta change amount (delta) + * @returns {Assertion} + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecreaseBy, true).to.not + .decrease(obj, prop) + .by(delta); +}; + +/** + * ### .decreasesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreasesButNotBy(fn, obj, 'val', 1); + * + * @name decreasesButNotBy + * @param {Function} fn modifier function + * @param {object} obj object or getter function + * @param {string} prop property name _optional_ + * @param {number} delta change amount (delta) + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + let tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesButNotBy, true).to + .decrease(obj, prop) + .but.not.by(delta); +}; + +/** + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {object} val + * @namespace Assert + * @public + */ +assert.ifError = function (val) { + if (val) { + throw val; + } +}; + +/** + * ### .isExtensible(object) + * + * Asserts that `object` is extensible (can have new properties added to it). + * + * assert.isExtensible({}); + * + * @name isExtensible + * @alias extensible + * @param {object} obj + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.isExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; +}; + +/** + * ### .isNotExtensible(object) + * + * Asserts that `object` is _not_ extensible. + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * assert.isNotExtensible(nonExtensibleObject); + * assert.isNotExtensible(sealedObject); + * assert.isNotExtensible(frozenObject); + * + * @name isNotExtensible + * @alias notExtensible + * @param {object} obj + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.isNotExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; +}; + +/** + * ### .isSealed(object) + * + * Asserts that `object` is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.seal({}); + * + * assert.isSealed(sealedObject); + * assert.isSealed(frozenObject); + * + * @name isSealed + * @alias sealed + * @param {object} obj + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.isSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; +}; + +/** + * ### .isNotSealed(object) + * + * Asserts that `object` is _not_ sealed. + * + * assert.isNotSealed({}); + * + * @name isNotSealed + * @alias notSealed + * @param {object} obj + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.isNotSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; +}; + +/** + * ### .isFrozen(object) + * + * Asserts that `object` is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * assert.frozen(frozenObject); + * + * @name isFrozen + * @alias frozen + * @param {object} obj + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.isFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; +}; + +/** + * ### .isNotFrozen(object) + * + * Asserts that `object` is _not_ frozen. + * + * assert.isNotFrozen({}); + * + * @name isNotFrozen + * @alias notFrozen + * @param {object} obj + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.isNotFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; +}; + +/** + * ### .isEmpty(target) + * + * Asserts that the target does not contain any values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isEmpty([]); + * assert.isEmpty(''); + * assert.isEmpty(new Map); + * assert.isEmpty({}); + * + * @name isEmpty + * @alias empty + * @param {object | Array | string | Map | Set} val + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.isEmpty = function (val, msg) { + new Assertion(val, msg, assert.isEmpty, true).to.be.empty; +}; + +/** + * ### .isNotEmpty(target) + * + * Asserts that the target contains values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isNotEmpty([1, 2]); + * assert.isNotEmpty('34'); + * assert.isNotEmpty(new Set([5, 6])); + * assert.isNotEmpty({ key: 7 }); + * + * @name isNotEmpty + * @alias notEmpty + * @param {object | Array | string | Map | Set} val + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.isNotEmpty = function (val, msg) { + new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; +}; + +/** + * ### .containsSubset(target, subset) + * + * Asserts that the target primitive/object/array structure deeply contains all provided fields + * at the same key/depth as the provided structure. + * + * When comparing arrays, the target must contain the subset of at least one of each object/value in the subset array. + * Order does not matter. + * + * assert.containsSubset( + * [{name: {first: "John", last: "Smith"}}, {name: {first: "Jane", last: "Doe"}}], + * [{name: {first: "Jane"}}] + * ); + * + * @name containsSubset + * @alias containSubset + * @param {unknown} val + * @param {unknown} exp + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.containsSubset = function (val, exp, msg) { + new Assertion(val, msg).to.containSubset(exp); +}; + +/** + * ### .doesNotContainSubset(target, subset) + * + * The negation of assert.containsSubset. + * + * @name doesNotContainSubset + * @param {unknown} val + * @param {unknown} exp + * @param {string} msg _optional_ + * @namespace Assert + * @public + */ +assert.doesNotContainSubset = function (val, exp, msg) { + new Assertion(val, msg).to.not.containSubset(exp); +}; + +/** + * Aliases. + * + * @param {unknown} name + * @param {unknown} as + * @returns {unknown} + */ +const aliases = [ + ['isOk', 'ok'], + ['isNotOk', 'notOk'], + ['throws', 'throw'], + ['throws', 'Throw'], + ['isExtensible', 'extensible'], + ['isNotExtensible', 'notExtensible'], + ['isSealed', 'sealed'], + ['isNotSealed', 'notSealed'], + ['isFrozen', 'frozen'], + ['isNotFrozen', 'notFrozen'], + ['isEmpty', 'empty'], + ['isNotEmpty', 'notEmpty'], + ['isCallable', 'isFunction'], + ['isNotCallable', 'isNotFunction'], + ['containsSubset', 'containSubset'] +]; +for (const [name, as] of aliases) { + assert[as] = assert[name]; +} diff --git a/node_modules/chai/lib/chai/interface/expect.js b/node_modules/chai/lib/chai/interface/expect.js new file mode 100644 index 0000000000..3709897fed --- /dev/null +++ b/node_modules/chai/lib/chai/interface/expect.js @@ -0,0 +1,59 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +import * as chai from '../../chai.js'; +import {Assertion} from '../assertion.js'; +import {AssertionError} from 'assertion-error'; + +/** + * @param {unknown} val + * @param {string} message + * @returns {Assertion} + */ +function expect(val, message) { + return new Assertion(val, message); +} + +export {expect}; + +/** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * expect.fail(); + * expect.fail("custom error message"); + * expect.fail(1, 2); + * expect.fail(1, 2, "custom error message"); + * expect.fail(1, 2, "custom error message", ">"); + * expect.fail(1, 2, undefined, ">"); + * + * @name fail + * @param {unknown} actual + * @param {unknown} expected + * @param {string} message + * @param {string} operator + * @namespace expect + * @public + */ +expect.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = undefined; + } + + message = message || 'expect.fail()'; + throw new AssertionError( + message, + { + actual: actual, + expected: expected, + operator: operator + }, + chai.expect.fail + ); +}; diff --git a/node_modules/chai/lib/chai/interface/should.js b/node_modules/chai/lib/chai/interface/should.js new file mode 100644 index 0000000000..bed3e49aaf --- /dev/null +++ b/node_modules/chai/lib/chai/interface/should.js @@ -0,0 +1,227 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +import {Assertion} from '../assertion.js'; +import {AssertionError} from 'assertion-error'; + +/** + * @returns {void} + */ +function loadShould() { + // explicitly define this method as function as to have it's name to include as `ssfi` + /** + * @returns {Assertion} + */ + function shouldGetter() { + if ( + this instanceof String || + this instanceof Number || + this instanceof Boolean || + (typeof Symbol === 'function' && this instanceof Symbol) || + (typeof BigInt === 'function' && this instanceof BigInt) + ) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + /** + * @param {unknown} value + */ + function shouldSetter(value) { + // See https://github.com/chaijs/chai/issues/86: this makes + // `whatever.should = someValue` actually set `someValue`, which is + // especially useful for `global.should = require('chai').should()`. + // + // Note that we have to use [[DefineProperty]] instead of [[Put]] + // since otherwise we would trigger this very setter! + Object.defineProperty(this, 'should', { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } + // modify Object.prototype to have `should` + Object.defineProperty(Object.prototype, 'should', { + set: shouldSetter, + get: shouldGetter, + configurable: true + }); + + let should = {}; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * should.fail(); + * should.fail("custom error message"); + * should.fail(1, 2); + * should.fail(1, 2, "custom error message"); + * should.fail(1, 2, "custom error message", ">"); + * should.fail(1, 2, undefined, ">"); + * + * @name fail + * @param {unknown} actual + * @param {unknown} expected + * @param {string} message + * @param {string} operator + * @namespace BDD + * @public + */ + should.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = undefined; + } + + message = message || 'should.fail()'; + throw new AssertionError( + message, + { + actual: actual, + expected: expected, + operator: operator + }, + should.fail + ); + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * should.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {unknown} actual + * @param {unknown} expected + * @param {string} message + * @namespace Should + * @public + */ + should.equal = function (actual, expected, message) { + new Assertion(actual, message).to.equal(expected); + }; + + /** + * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * should.throw(fn, 'function throws a reference error'); + * should.throw(fn, /function throws a reference error/); + * should.throw(fn, ReferenceError); + * should.throw(fn, ReferenceError, 'function throws a reference error'); + * should.throw(fn, ReferenceError, /function throws a reference error/); + * + * @name throw + * @alias Throw + * @param {Function} fn + * @param {Error} errt + * @param {RegExp} errs + * @param {string} msg + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @public + */ + should.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * should.exist(foo, 'foo exists'); + * + * @param {unknown} val + * @param {string} msg + * @name exist + * @namespace Should + * @public + */ + should.exist = function (val, msg) { + new Assertion(val, msg).to.exist; + }; + + // negation + should.not = {}; + + /** + * ### .not.equal(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * should.not.equal(3, 4, 'these numbers are not equal'); + * + * @name not.equal + * @param {unknown} actual + * @param {unknown} expected + * @param {string} msg + * @namespace Should + * @public + */ + should.not.equal = function (actual, expected, msg) { + new Assertion(actual, msg).to.not.equal(expected); + }; + + /** + * ### .throw(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * should.not.throw(fn, Error, 'function does not throw'); + * + * @name not.throw + * @alias not.Throw + * @param {Function} fn + * @param {Error} errt + * @param {RegExp} errs + * @param {string} msg + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @public + */ + should.not.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + + /** + * ### .not.exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var bar = null; + * should.not.exist(bar, 'bar does not exist'); + * + * @namespace Should + * @name not.exist + * @param {unknown} val + * @param {string} msg + * @public + */ + should.not.exist = function (val, msg) { + new Assertion(val, msg).to.not.exist; + }; + + should['throw'] = should['Throw']; + should.not['throw'] = should.not['Throw']; + + return should; +} + +export const should = loadShould; +export const Should = loadShould; diff --git a/node_modules/chai/lib/chai/utils/addChainableMethod.js b/node_modules/chai/lib/chai/utils/addChainableMethod.js new file mode 100644 index 0000000000..629a183f90 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addChainableMethod.js @@ -0,0 +1,146 @@ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {Assertion} from '../assertion.js'; +import {addLengthGuard} from './addLengthGuard.js'; +import {flag} from './flag.js'; +import {proxify} from './proxify.js'; +import {transferFlags} from './transferFlags.js'; + +/** + * Module variables + */ + +// Check whether `Object.setPrototypeOf` is supported +let canSetPrototype = typeof Object.setPrototypeOf === 'function'; + +// Without `Object.setPrototypeOf` support, this module will need to add properties to a function. +// However, some of functions' own props are not configurable and should be skipped. +let testFn = function () {}; +let excludeNames = Object.getOwnPropertyNames(testFn).filter(function (name) { + let propDesc = Object.getOwnPropertyDescriptor(testFn, name); + + // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties, + // but then returns `undefined` as the property descriptor for `callee`. As a + // workaround, we perform an otherwise unnecessary type-check for `propDesc`, + // and then filter it out if it's not an object as it should be. + if (typeof propDesc !== 'object') return true; + + return !propDesc.configurable; +}); + +// Cache `Function` properties +let call = Function.prototype.call, + apply = Function.prototype.apply; + +/** + * ### .addChainableMethod(ctx, name, method, chainingBehavior) + * + * Adds a method to an object, such that the method can also be chained. + * + * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); + * + * The result can then be used as both a method assertion, executing both `method` and + * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. + * + * expect(fooStr).to.be.foo('bar'); + * expect(fooStr).to.be.foo.equal('foo'); + * + * @param {object} ctx object to which the method is added + * @param {string} name of method to add + * @param {Function} method function to be used for `name`, when called + * @param {Function} chainingBehavior function to be called every time the property is accessed + * @namespace Utils + * @name addChainableMethod + * @public + */ +export function addChainableMethod(ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== 'function') { + chainingBehavior = function () {}; + } + + let chainableBehavior = { + method: method, + chainingBehavior: chainingBehavior + }; + + // save the methods so we can overwrite them later, if we need to. + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + + Object.defineProperty(ctx, name, { + get: function chainableMethodGetter() { + chainableBehavior.chainingBehavior.call(this); + + let chainableMethodWrapper = function () { + // Setting the `ssfi` flag to `chainableMethodWrapper` causes this + // function to be the starting point for removing implementation + // frames from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then this assertion is being + // invoked from inside of another assertion. In this case, the `ssfi` + // flag has already been set by the outer assertion. + // + // Note that overwriting a chainable method merely replaces the saved + // methods in `ctx.__methods` instead of completely replacing the + // overwritten assertion. Therefore, an overwriting assertion won't + // set the `ssfi` or `lockSsfi` flags. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', chainableMethodWrapper); + } + + let result = chainableBehavior.method.apply(this, arguments); + if (result !== undefined) { + return result; + } + + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(chainableMethodWrapper, name, true); + + // Use `Object.setPrototypeOf` if available + if (canSetPrototype) { + // Inherit all properties from the object by replacing the `Function` prototype + let prototype = Object.create(this); + // Restore the `call` and `apply` methods from `Function` + prototype.call = call; + prototype.apply = apply; + Object.setPrototypeOf(chainableMethodWrapper, prototype); + } + // Otherwise, redefine all properties (slow!) + else { + let asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function (asserterName) { + if (excludeNames.indexOf(asserterName) !== -1) { + return; + } + + let pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(chainableMethodWrapper, asserterName, pd); + }); + } + + transferFlags(this, chainableMethodWrapper); + return proxify(chainableMethodWrapper); + }, + configurable: true + }); +} diff --git a/node_modules/chai/lib/chai/utils/addLengthGuard.js b/node_modules/chai/lib/chai/utils/addLengthGuard.js new file mode 100644 index 0000000000..d08aad6125 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addLengthGuard.js @@ -0,0 +1,73 @@ +const fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); + +/*! + * Chai - addLengthGuard utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .addLengthGuard(fn, assertionName, isChainable) + * + * Define `length` as a getter on the given uninvoked method assertion. The + * getter acts as a guard against chaining `length` directly off of an uninvoked + * method assertion, which is a problem because it references `function`'s + * built-in `length` property instead of Chai's `length` assertion. When the + * getter catches the user making this mistake, it throws an error with a + * helpful message. + * + * There are two ways in which this mistake can be made. The first way is by + * chaining the `length` assertion directly off of an uninvoked chainable + * method. In this case, Chai suggests that the user use `lengthOf` instead. The + * second way is by chaining the `length` assertion directly off of an uninvoked + * non-chainable method. Non-chainable methods must be invoked prior to + * chaining. In this case, Chai suggests that the user consult the docs for the + * given assertion. + * + * If the `length` property of functions is unconfigurable, then return `fn` + * without modification. + * + * Note that in ES6, the function's `length` property is configurable, so once + * support for legacy environments is dropped, Chai's `length` property can + * replace the built-in function's `length` property, and this length guard will + * no longer be necessary. In the mean time, maintaining consistency across all + * environments is the priority. + * + * @param {Function} fn + * @param {string} assertionName + * @param {boolean} isChainable + * @returns {unknown} + * @namespace Utils + * @name addLengthGuard + */ +export function addLengthGuard(fn, assertionName, isChainable) { + if (!fnLengthDesc.configurable) return fn; + + Object.defineProperty(fn, 'length', { + get: function () { + if (isChainable) { + throw Error( + 'Invalid Chai property: ' + + assertionName + + '.length. Due' + + ' to a compatibility issue, "length" cannot directly follow "' + + assertionName + + '". Use "' + + assertionName + + '.lengthOf" instead.' + ); + } + + throw Error( + 'Invalid Chai property: ' + + assertionName + + '.length. See' + + ' docs for proper usage of "' + + assertionName + + '".' + ); + } + }); + + return fn; +} diff --git a/node_modules/chai/lib/chai/utils/addMethod.js b/node_modules/chai/lib/chai/utils/addMethod.js new file mode 100644 index 0000000000..89092926f0 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addMethod.js @@ -0,0 +1,66 @@ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {addLengthGuard} from './addLengthGuard.js'; +import {flag} from './flag.js'; +import {proxify} from './proxify.js'; +import {transferFlags} from './transferFlags.js'; +import {Assertion} from '../assertion.js'; + +/** + * ### .addMethod(ctx, name, method) + * + * Adds a method to the prototype of an object. + * + * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(fooStr).to.be.foo('bar'); + * + * @param {object} ctx object to which the method is added + * @param {string} name of method to add + * @param {Function} method function to be used for name + * @namespace Utils + * @name addMethod + * @public + */ +export function addMethod(ctx, name, method) { + let methodWrapper = function () { + // Setting the `ssfi` flag to `methodWrapper` causes this function to be the + // starting point for removing implementation frames from the stack trace of + // a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', methodWrapper); + } + + let result = method.apply(this, arguments); + if (result !== undefined) return result; + + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(methodWrapper, name, false); + ctx[name] = proxify(methodWrapper, name); +} diff --git a/node_modules/chai/lib/chai/utils/addProperty.js b/node_modules/chai/lib/chai/utils/addProperty.js new file mode 100644 index 0000000000..a9ac3f5778 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addProperty.js @@ -0,0 +1,70 @@ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {Assertion} from '../assertion.js'; +import {flag} from './flag.js'; +import {isProxyEnabled} from './isProxyEnabled.js'; +import {transferFlags} from './transferFlags.js'; + +/** + * ### .addProperty(ctx, name, getter) + * + * Adds a property to the prototype of an object. + * + * utils.addProperty(chai.Assertion.prototype, 'foo', function () { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.instanceof(Foo); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.foo; + * + * @param {object} ctx object to which the property is added + * @param {string} name of property to add + * @param {Function} getter function to be used for name + * @namespace Utils + * @name addProperty + * @public + */ +export function addProperty(ctx, name, getter) { + getter = getter === undefined ? function () {} : getter; + + Object.defineProperty(ctx, name, { + get: function propertyGetter() { + // Setting the `ssfi` flag to `propertyGetter` causes this function to + // be the starting point for removing implementation frames from the + // stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', propertyGetter); + } + + let result = getter.call(this); + if (result !== undefined) return result; + + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, + configurable: true + }); +} diff --git a/node_modules/chai/lib/chai/utils/compareByInspect.js b/node_modules/chai/lib/chai/utils/compareByInspect.js new file mode 100644 index 0000000000..5ab27a2065 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/compareByInspect.js @@ -0,0 +1,26 @@ +/*! + * Chai - compareByInspect utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +import {inspect} from './inspect.js'; + +/** + * ### .compareByInspect(mixed, mixed) + * + * To be used as a compareFunction with Array.prototype.sort. Compares elements + * using inspect instead of default behavior of using toString so that Symbols + * and objects with irregular/missing toString can still be sorted without a + * TypeError. + * + * @param {unknown} a first element to compare + * @param {unknown} b second element to compare + * @returns {number} -1 if 'a' should come before 'b'; otherwise 1 + * @name compareByInspect + * @namespace Utils + * @public + */ +export function compareByInspect(a, b) { + return inspect(a) < inspect(b) ? -1 : 1; +} diff --git a/node_modules/chai/lib/chai/utils/expectTypes.js b/node_modules/chai/lib/chai/utils/expectTypes.js new file mode 100644 index 0000000000..51331d9f34 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/expectTypes.js @@ -0,0 +1,58 @@ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {AssertionError} from 'assertion-error'; +import {flag} from './flag.js'; +import {type} from './type-detect.js'; + +/** + * ### .expectTypes(obj, types) + * + * Ensures that the object being tested against is of a valid type. + * + * utils.expectTypes(this, ['array', 'object', 'string']); + * + * @param {unknown} obj constructed Assertion + * @param {Array} types A list of allowed types for this assertion + * @namespace Utils + * @name expectTypes + * @public + */ +export function expectTypes(obj, types) { + let flagMsg = flag(obj, 'message'); + let ssfi = flag(obj, 'ssfi'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + obj = flag(obj, 'object'); + types = types.map(function (t) { + return t.toLowerCase(); + }); + types.sort(); + + // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum' + let str = types + .map(function (t, index) { + let art = ~['a', 'e', 'i', 'o', 'u'].indexOf(t.charAt(0)) ? 'an' : 'a'; + let or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; + return or + art + ' ' + t; + }) + .join(', '); + + let objType = type(obj).toLowerCase(); + + if ( + !types.some(function (expected) { + return objType === expected; + }) + ) { + throw new AssertionError( + flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given', + undefined, + ssfi + ); + } +} diff --git a/node_modules/chai/lib/chai/utils/flag.js b/node_modules/chai/lib/chai/utils/flag.js new file mode 100644 index 0000000000..84b0293867 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/flag.js @@ -0,0 +1,34 @@ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .flag(object, key, [value]) + * + * Get or set a flag value on an object. If a + * value is provided it will be set, else it will + * return the currently set value or `undefined` if + * the value is not set. + * + * utils.flag(this, 'foo', 'bar'); // setter + * utils.flag(this, 'foo'); // getter, returns `bar` + * + * @template {{__flags?: {[key: PropertyKey]: unknown}}} T + * @param {T} obj object constructed Assertion + * @param {string} key + * @param {unknown} [value] + * @namespace Utils + * @name flag + * @returns {unknown | undefined} + * @private + */ +export function flag(obj, key, value) { + let flags = obj.__flags || (obj.__flags = Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +} diff --git a/node_modules/chai/lib/chai/utils/getActual.js b/node_modules/chai/lib/chai/utils/getActual.js new file mode 100644 index 0000000000..1b4b3aa210 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getActual.js @@ -0,0 +1,20 @@ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getActual(object, [actual]) + * + * Returns the `actual` value for an Assertion. + * + * @param {object} obj object (constructed Assertion) + * @param {unknown} args chai.Assertion.prototype.assert arguments + * @returns {unknown} + * @namespace Utils + * @name getActual + */ +export function getActual(obj, args) { + return args.length > 4 ? args[4] : obj._obj; +} diff --git a/node_modules/chai/lib/chai/utils/getMessage.js b/node_modules/chai/lib/chai/utils/getMessage.js new file mode 100644 index 0000000000..0006b67366 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getMessage.js @@ -0,0 +1,52 @@ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {flag} from './flag.js'; +import {getActual} from './getActual.js'; +import {objDisplay} from './objDisplay.js'; + +/** + * ### .getMessage(object, message, negateMessage) + * + * Construct the error message based on flags + * and template tags. Template tags will return + * a stringified inspection of the object referenced. + * + * Message template tags: + * - `#{this}` current asserted object + * - `#{act}` actual value + * - `#{exp}` expected value + * + * @param {object} obj object (constructed Assertion) + * @param {IArguments} args chai.Assertion.prototype.assert arguments + * @returns {string} + * @namespace Utils + * @name getMessage + * @public + */ +export function getMessage(obj, args) { + let negate = flag(obj, 'negate'); + let val = flag(obj, 'object'); + let expected = args[3]; + let actual = getActual(obj, args); + let msg = negate ? args[2] : args[1]; + let flagMsg = flag(obj, 'message'); + + if (typeof msg === 'function') msg = msg(); + msg = msg || ''; + msg = msg + .replace(/#\{this\}/g, function () { + return objDisplay(val); + }) + .replace(/#\{act\}/g, function () { + return objDisplay(actual); + }) + .replace(/#\{exp\}/g, function () { + return objDisplay(expected); + }); + + return flagMsg ? flagMsg + ': ' + msg : msg; +} diff --git a/node_modules/chai/lib/chai/utils/getOperator.js b/node_modules/chai/lib/chai/utils/getOperator.js new file mode 100644 index 0000000000..1ae854a63c --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getOperator.js @@ -0,0 +1,58 @@ +import {flag} from './flag.js'; +import {type} from './type-detect.js'; + +/** + * @param {unknown} obj + * @returns {boolean} + */ +function isObjectType(obj) { + let objectType = type(obj); + let objectTypes = ['Array', 'Object', 'Function']; + + return objectTypes.indexOf(objectType) !== -1; +} + +/** + * ### .getOperator(message) + * + * Extract the operator from error message. + * Operator defined is based on below link + * https://nodejs.org/api/assert.html#assert_assert. + * + * Returns the `operator` or `undefined` value for an Assertion. + * + * @param {object} obj object (constructed Assertion) + * @param {unknown} args chai.Assertion.prototype.assert arguments + * @returns {unknown} + * @namespace Utils + * @name getOperator + * @public + */ +export function getOperator(obj, args) { + let operator = flag(obj, 'operator'); + let negate = flag(obj, 'negate'); + let expected = args[3]; + let msg = negate ? args[2] : args[1]; + + if (operator) { + return operator; + } + + if (typeof msg === 'function') msg = msg(); + + msg = msg || ''; + if (!msg) { + return undefined; + } + + if (/\shave\s/.test(msg)) { + return undefined; + } + + let isObject = isObjectType(expected); + if (/\snot\s/.test(msg)) { + return isObject ? 'notDeepStrictEqual' : 'notStrictEqual'; + } + + return isObject ? 'deepStrictEqual' : 'strictEqual'; +} diff --git a/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js b/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js new file mode 100644 index 0000000000..9e8e830bf9 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js @@ -0,0 +1,24 @@ +/*! + * Chai - getOwnEnumerableProperties utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +import {getOwnEnumerablePropertySymbols} from './getOwnEnumerablePropertySymbols.js'; + +/** + * ### .getOwnEnumerableProperties(object) + * + * This allows the retrieval of directly-owned enumerable property names and + * symbols of an object. This function is necessary because Object.keys only + * returns enumerable property names, not enumerable property symbols. + * + * @param {object} obj + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerableProperties + * @public + */ +export function getOwnEnumerableProperties(obj) { + return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); +} diff --git a/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js b/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js new file mode 100644 index 0000000000..d8d6d09647 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js @@ -0,0 +1,26 @@ +/*! + * Chai - getOwnEnumerablePropertySymbols utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .getOwnEnumerablePropertySymbols(object) + * + * This allows the retrieval of directly-owned enumerable property symbols of an + * object. This function is necessary because Object.getOwnPropertySymbols + * returns both enumerable and non-enumerable property symbols. + * + * @param {object} obj + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerablePropertySymbols + * @public + */ +export function getOwnEnumerablePropertySymbols(obj) { + if (typeof Object.getOwnPropertySymbols !== 'function') return []; + + return Object.getOwnPropertySymbols(obj).filter(function (sym) { + return Object.getOwnPropertyDescriptor(obj, sym).enumerable; + }); +} diff --git a/node_modules/chai/lib/chai/utils/getProperties.js b/node_modules/chai/lib/chai/utils/getProperties.js new file mode 100644 index 0000000000..03f0c5ee43 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getProperties.js @@ -0,0 +1,38 @@ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getProperties(object) + * + * This allows the retrieval of property names of an object, enumerable or not, + * inherited or not. + * + * @param {object} object + * @returns {Array} + * @namespace Utils + * @name getProperties + * @public + */ +export function getProperties(object) { + let result = Object.getOwnPropertyNames(object); + + /** + * @param {unknown} property + */ + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + + let proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + + return result; +} diff --git a/node_modules/chai/lib/chai/utils/index.js b/node_modules/chai/lib/chai/utils/index.js new file mode 100644 index 0000000000..70d9f4c1e9 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/index.js @@ -0,0 +1,118 @@ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ + +// Dependencies that are used for multiple exports are required here only once +import * as checkError from 'check-error'; + +// test utility +export {test} from './test.js'; + +// type utility +import {type} from './type-detect.js'; +export {type}; + +// expectTypes utility +export {expectTypes} from './expectTypes.js'; + +// message utility +export {getMessage} from './getMessage.js'; + +// actual utility +export {getActual} from './getActual.js'; + +// Inspect util +export {inspect} from './inspect.js'; + +// Object Display util +export {objDisplay} from './objDisplay.js'; + +// Flag utility +export {flag} from './flag.js'; + +// Flag transferring utility +export {transferFlags} from './transferFlags.js'; + +// Deep equal utility +export {default as eql} from 'deep-eql'; + +// Deep path info +export {getPathInfo, hasProperty} from 'pathval'; + +/** + * Function name + * + * @param {Function} fn + * @returns {string} + */ +export function getName(fn) { + return fn.name; +} + +// add Property +export {addProperty} from './addProperty.js'; + +// add Method +export {addMethod} from './addMethod.js'; + +// overwrite Property +export {overwriteProperty} from './overwriteProperty.js'; + +// overwrite Method +export {overwriteMethod} from './overwriteMethod.js'; + +// Add a chainable method +export {addChainableMethod} from './addChainableMethod.js'; + +// Overwrite chainable method +export {overwriteChainableMethod} from './overwriteChainableMethod.js'; + +// Compare by inspect method +export {compareByInspect} from './compareByInspect.js'; + +// Get own enumerable property symbols method +export {getOwnEnumerablePropertySymbols} from './getOwnEnumerablePropertySymbols.js'; + +// Get own enumerable properties method +export {getOwnEnumerableProperties} from './getOwnEnumerableProperties.js'; + +// Checks error against a given set of criteria +export {checkError}; + +// Proxify util +export {proxify} from './proxify.js'; + +// addLengthGuard util +export {addLengthGuard} from './addLengthGuard.js'; + +// isProxyEnabled helper +export {isProxyEnabled} from './isProxyEnabled.js'; + +// isNaN method +export {isNaN} from './isNaN.js'; + +// getOperator method +export {getOperator} from './getOperator.js'; + +/** + * Determines if an object is a `RegExp` + * This is used since `instanceof` will not work in virtual contexts + * + * @param {*} obj Object to test + * @returns {boolean} + */ +export function isRegExp(obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; +} + +/** + * Determines if an object is numeric or not + * + * @param {unknown} obj Object to test + * @returns {boolean} + */ +export function isNumeric(obj) { + return ['Number', 'BigInt'].includes(type(obj)); +} diff --git a/node_modules/chai/lib/chai/utils/inspect.js b/node_modules/chai/lib/chai/utils/inspect.js new file mode 100644 index 0000000000..66403da86b --- /dev/null +++ b/node_modules/chai/lib/chai/utils/inspect.js @@ -0,0 +1,31 @@ +// This is (almost) directly from Node.js utils +// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js + +import {inspect as _inspect} from 'loupe'; +import {config} from '../config.js'; + +/** + * ### .inspect(obj, [showHidden], [depth], [colors]) + * + * Echoes the value of a value. Tries to print the value out + * in the best way possible given the different types. + * + * @param {object} obj The object to print out. + * @param {boolean} showHidden Flag that shows hidden (not enumerable) + * properties of objects. Default is false. + * @param {number} depth Depth in which to descend in object. Default is 2. + * @param {boolean} colors Flag to turn on ANSI escape codes to color the + * output. Default is false (no coloring). + * @returns {string} + * @namespace Utils + * @name inspect + */ +export function inspect(obj, showHidden, depth, colors) { + let options = { + colors: colors, + depth: typeof depth === 'undefined' ? 2 : depth, + showHidden: showHidden, + truncate: config.truncateThreshold ? config.truncateThreshold : Infinity + }; + return _inspect(obj, options); +} diff --git a/node_modules/chai/lib/chai/utils/isNaN.js b/node_modules/chai/lib/chai/utils/isNaN.js new file mode 100644 index 0000000000..413c0a4358 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/isNaN.js @@ -0,0 +1,7 @@ +/*! + * Chai - isNaN utility + * Copyright(c) 2012-2015 Sakthipriyan Vairamani + * MIT Licensed + */ + +export const isNaN = Number.isNaN; diff --git a/node_modules/chai/lib/chai/utils/isProxyEnabled.js b/node_modules/chai/lib/chai/utils/isProxyEnabled.js new file mode 100644 index 0000000000..dd68d4d195 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/isProxyEnabled.js @@ -0,0 +1,26 @@ +import {config} from '../config.js'; + +/*! + * Chai - isProxyEnabled helper + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .isProxyEnabled() + * + * Helper function to check if Chai's proxy protection feature is enabled. If + * proxies are unsupported or disabled via the user's Chai config, then return + * false. Otherwise, return true. + * + * @namespace Utils + * @name isProxyEnabled + * @returns {boolean} + */ +export function isProxyEnabled() { + return ( + config.useProxy && + typeof Proxy !== 'undefined' && + typeof Reflect !== 'undefined' + ); +} diff --git a/node_modules/chai/lib/chai/utils/objDisplay.js b/node_modules/chai/lib/chai/utils/objDisplay.js new file mode 100644 index 0000000000..175b22c682 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/objDisplay.js @@ -0,0 +1,47 @@ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {inspect} from './inspect.js'; +import {config} from '../config.js'; + +/** + * ### .objDisplay(object) + * + * Determines if an object or an array matches + * criteria to be inspected in-line for error + * messages or should be truncated. + * + * @param {unknown} obj javascript object to inspect + * @returns {string} stringified object + * @name objDisplay + * @namespace Utils + * @public + */ +export function objDisplay(obj) { + let str = inspect(obj), + type = Object.prototype.toString.call(obj); + + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type === '[object Function]') { + return !obj.name || obj.name === '' + ? '[Function]' + : '[Function: ' + obj.name + ']'; + } else if (type === '[object Array]') { + return '[ Array(' + obj.length + ') ]'; + } else if (type === '[object Object]') { + let keys = Object.keys(obj), + kstr = + keys.length > 2 + ? keys.splice(0, 2).join(', ') + ', ...' + : keys.join(', '); + return '{ Object (' + kstr + ') }'; + } else { + return str; + } + } else { + return str; + } +} diff --git a/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js b/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js new file mode 100644 index 0000000000..423e00b472 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js @@ -0,0 +1,69 @@ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {Assertion} from '../assertion.js'; +import {transferFlags} from './transferFlags.js'; + +/** + * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior) + * + * Overwrites an already existing chainable method + * and provides access to the previous function or + * property. Must return functions to be used for + * name. + * + * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf', + * function (_super) { + * } + * , function (_super) { + * } + * ); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteChainableMethod('foo', fn, fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.have.lengthOf(3); + * expect(myFoo).to.have.lengthOf.above(3); + * + * @param {object} ctx object whose method / property is to be overwritten + * @param {string} name of method / property to overwrite + * @param {Function} method function that returns a function to be used for name + * @param {Function} chainingBehavior function that returns a function to be used for property + * @namespace Utils + * @name overwriteChainableMethod + * @public + */ +export function overwriteChainableMethod(ctx, name, method, chainingBehavior) { + let chainableBehavior = ctx.__methods[name]; + + let _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = + function overwritingChainableMethodGetter() { + let result = chainingBehavior(_chainingBehavior).call(this); + if (result !== undefined) { + return result; + } + + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + let _method = chainableBehavior.method; + chainableBehavior.method = function overwritingChainableMethodWrapper() { + let result = method(_method).apply(this, arguments); + if (result !== undefined) { + return result; + } + + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; +} diff --git a/node_modules/chai/lib/chai/utils/overwriteMethod.js b/node_modules/chai/lib/chai/utils/overwriteMethod.js new file mode 100644 index 0000000000..62b46592d2 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/overwriteMethod.js @@ -0,0 +1,90 @@ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {Assertion} from '../assertion.js'; +import {addLengthGuard} from './addLengthGuard.js'; +import {flag} from './flag.js'; +import {proxify} from './proxify.js'; +import {transferFlags} from './transferFlags.js'; + +/** + * ### .overwriteMethod(ctx, name, fn) + * + * Overwrites an already existing method and provides + * access to previous function. Must return function + * to be used for name. + * + * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { + * return function (str) { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.value).to.equal(str); + * } else { + * _super.apply(this, arguments); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.equal('bar'); + * + * @param {object} ctx object whose method is to be overwritten + * @param {string} name of method to overwrite + * @param {Function} method function that returns a function to be used for name + * @namespace Utils + * @name overwriteMethod + * @public + */ +export function overwriteMethod(ctx, name, method) { + let _method = ctx[name], + _super = function () { + throw new Error(name + ' is not a function'); + }; + + if (_method && 'function' === typeof _method) _super = _method; + + let overwritingMethodWrapper = function () { + // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this + // function to be the starting point for removing implementation frames from + // the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingMethodWrapper); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion + // from changing the `ssfi` flag. By this point, the `ssfi` flag is already + // set to the correct starting point for this assertion. + let origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + let result = method(_super).apply(this, arguments); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(overwritingMethodWrapper, name, false); + ctx[name] = proxify(overwritingMethodWrapper, name); +} diff --git a/node_modules/chai/lib/chai/utils/overwriteProperty.js b/node_modules/chai/lib/chai/utils/overwriteProperty.js new file mode 100644 index 0000000000..bd886ba64f --- /dev/null +++ b/node_modules/chai/lib/chai/utils/overwriteProperty.js @@ -0,0 +1,89 @@ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {Assertion} from '../assertion.js'; +import {flag} from './flag.js'; +import {isProxyEnabled} from './isProxyEnabled.js'; +import {transferFlags} from './transferFlags.js'; + +/** + * ### .overwriteProperty(ctx, name, fn) + * + * Overwrites an already existing property getter and provides + * access to previous value. Must return function to use as getter. + * + * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { + * return function () { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.name).to.equal('bar'); + * } else { + * _super.call(this); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.ok; + * + * @param {object} ctx object whose property is to be overwritten + * @param {string} name of property to overwrite + * @param {Function} getter function that returns a getter function to be used for name + * @namespace Utils + * @name overwriteProperty + * @public + */ +export function overwriteProperty(ctx, name, getter) { + let _get = Object.getOwnPropertyDescriptor(ctx, name), + _super = function () {}; + + if (_get && 'function' === typeof _get.get) _super = _get.get; + + Object.defineProperty(ctx, name, { + get: function overwritingPropertyGetter() { + // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this + // function to be the starting point for removing implementation frames + // from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingPropertyGetter); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten + // assertion from changing the `ssfi` flag. By this point, the `ssfi` + // flag is already set to the correct starting point for this assertion. + let origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + let result = getter(_super).call(this); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + let newAssertion = new Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, + configurable: true + }); +} diff --git a/node_modules/chai/lib/chai/utils/proxify.js b/node_modules/chai/lib/chai/utils/proxify.js new file mode 100644 index 0000000000..21e40e7c38 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/proxify.js @@ -0,0 +1,158 @@ +import {config} from '../config.js'; +import {flag} from './flag.js'; +import {getProperties} from './getProperties.js'; +import {isProxyEnabled} from './isProxyEnabled.js'; + +/*! + * Chai - proxify utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** @type {PropertyKey[]} */ +const builtins = ['__flags', '__methods', '_obj', 'assert']; + +/** + * ### .proxify(object) + * + * Return a proxy of given object that throws an error when a non-existent + * property is read. By default, the root cause is assumed to be a misspelled + * property, and thus an attempt is made to offer a reasonable suggestion from + * the list of existing properties. However, if a nonChainableMethodName is + * provided, then the root cause is instead a failure to invoke a non-chainable + * method prior to reading the non-existent property. + * + * If proxies are unsupported or disabled via the user's Chai config, then + * return object without modification. + * + * @namespace Utils + * @template {object} T + * @param {T} obj + * @param {string} [nonChainableMethodName] + * @returns {T} + */ +export function proxify(obj, nonChainableMethodName) { + if (!isProxyEnabled()) return obj; + + return new Proxy(obj, { + get: function proxyGetter(target, property) { + // This check is here because we should not throw errors on Symbol properties + // such as `Symbol.toStringTag`. + // The values for which an error should be thrown can be configured using + // the `config.proxyExcludedKeys` setting. + if ( + typeof property === 'string' && + config.proxyExcludedKeys.indexOf(property) === -1 && + !Reflect.has(target, property) + ) { + // Special message for invalid property access of non-chainable methods. + if (nonChainableMethodName) { + throw Error( + 'Invalid Chai property: ' + + nonChainableMethodName + + '.' + + property + + '. See docs for proper usage of "' + + nonChainableMethodName + + '".' + ); + } + + // If the property is reasonably close to an existing Chai property, + // suggest that property to the user. Only suggest properties with a + // distance less than 4. + let suggestion = null; + let suggestionDistance = 4; + getProperties(target).forEach(function (prop) { + if ( + // we actually mean to check `Object.prototype` here + // eslint-disable-next-line no-prototype-builtins + !Object.prototype.hasOwnProperty(prop) && + builtins.indexOf(prop) === -1 + ) { + let dist = stringDistanceCapped(property, prop, suggestionDistance); + if (dist < suggestionDistance) { + suggestion = prop; + suggestionDistance = dist; + } + } + }); + + if (suggestion !== null) { + throw Error( + 'Invalid Chai property: ' + + property + + '. Did you mean "' + + suggestion + + '"?' + ); + } else { + throw Error('Invalid Chai property: ' + property); + } + } + + // Use this proxy getter as the starting point for removing implementation + // frames from the stack trace of a failed assertion. For property + // assertions, this prevents the proxy getter from showing up in the stack + // trace since it's invoked before the property getter. For method and + // chainable method assertions, this flag will end up getting changed to + // the method wrapper, which is good since this frame will no longer be in + // the stack once the method is invoked. Note that Chai builtin assertion + // properties such as `__flags` are skipped since this is only meant to + // capture the starting point of an assertion. This step is also skipped + // if the `lockSsfi` flag is set, thus indicating that this assertion is + // being called from within another assertion. In that case, the `ssfi` + // flag is already set to the outer assertion's starting point. + if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) { + flag(target, 'ssfi', proxyGetter); + } + + return Reflect.get(target, property); + } + }); +} + +/** + * # stringDistanceCapped(strA, strB, cap) + * Return the Levenshtein distance between two strings, but no more than cap. + * + * @param {string} strA + * @param {string} strB + * @param {number} cap + * @returns {number} min(string distance between strA and strB, cap) + * @private + */ +function stringDistanceCapped(strA, strB, cap) { + if (Math.abs(strA.length - strB.length) >= cap) { + return cap; + } + + let memo = []; + // `memo` is a two-dimensional array containing distances. + // memo[i][j] is the distance between strA.slice(0, i) and + // strB.slice(0, j). + for (let i = 0; i <= strA.length; i++) { + memo[i] = Array(strB.length + 1).fill(0); + memo[i][0] = i; + } + for (let j = 0; j < strB.length; j++) { + memo[0][j] = j; + } + + for (let i = 1; i <= strA.length; i++) { + let ch = strA.charCodeAt(i - 1); + for (let j = 1; j <= strB.length; j++) { + if (Math.abs(i - j) >= cap) { + memo[i][j] = cap; + continue; + } + memo[i][j] = Math.min( + memo[i - 1][j] + 1, + memo[i][j - 1] + 1, + memo[i - 1][j - 1] + (ch === strB.charCodeAt(j - 1) ? 0 : 1) + ); + } + } + + return memo[strA.length][strB.length]; +} diff --git a/node_modules/chai/lib/chai/utils/test.js b/node_modules/chai/lib/chai/utils/test.js new file mode 100644 index 0000000000..d5ae9858d6 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/test.js @@ -0,0 +1,24 @@ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +import {flag} from './flag.js'; + +/** + * ### .test(object, expression) + * + * Test an object for expression. + * + * @param {object} obj (constructed Assertion) + * @param {unknown} args + * @returns {unknown} + * @namespace Utils + * @name test + */ +export function test(obj, args) { + let negate = flag(obj, 'negate'), + expr = args[0]; + return negate ? !expr : expr; +} diff --git a/node_modules/chai/lib/chai/utils/transferFlags.js b/node_modules/chai/lib/chai/utils/transferFlags.js new file mode 100644 index 0000000000..01643b31ce --- /dev/null +++ b/node_modules/chai/lib/chai/utils/transferFlags.js @@ -0,0 +1,48 @@ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .transferFlags(assertion, object, includeAll = true) + * + * Transfer all the flags for `assertion` to `object`. If + * `includeAll` is set to `false`, then the base Chai + * assertion flags (namely `object`, `ssfi`, `lockSsfi`, + * and `message`) will not be transferred. + * + * var newAssertion = new Assertion(); + * utils.transferFlags(assertion, newAssertion); + * + * var anotherAssertion = new Assertion(myObj); + * utils.transferFlags(assertion, anotherAssertion, false); + * + * @param {import('../assertion.js').Assertion} assertion the assertion to transfer the flags from + * @param {object} object the object to transfer the flags to; usually a new assertion + * @param {boolean} includeAll + * @namespace Utils + * @name transferFlags + * @private + */ +export function transferFlags(assertion, object, includeAll) { + let flags = assertion.__flags || (assertion.__flags = Object.create(null)); + + if (!object.__flags) { + object.__flags = Object.create(null); + } + + includeAll = arguments.length === 3 ? includeAll : true; + + for (let flag in flags) { + if ( + includeAll || + (flag !== 'object' && + flag !== 'ssfi' && + flag !== 'lockSsfi' && + flag != 'message') + ) { + object.__flags[flag] = flags[flag]; + } + } +} diff --git a/node_modules/chai/lib/chai/utils/type-detect.js b/node_modules/chai/lib/chai/utils/type-detect.js new file mode 100644 index 0000000000..573edf8191 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/type-detect.js @@ -0,0 +1,20 @@ +/** + * @param {unknown} obj + * @returns {string} + */ +export function type(obj) { + if (typeof obj === 'undefined') { + return 'undefined'; + } + + if (obj === null) { + return 'null'; + } + + const stringTag = obj[Symbol.toStringTag]; + if (typeof stringTag === 'string') { + return stringTag; + } + const type = Object.prototype.toString.call(obj).slice(8, -1); + return type; +} diff --git a/node_modules/chai/package.json b/node_modules/chai/package.json new file mode 100644 index 0000000000..872a8dc37c --- /dev/null +++ b/node_modules/chai/package.json @@ -0,0 +1,74 @@ +{ + "author": "Jake Luer ", + "name": "chai", + "type": "module", + "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", + "keywords": [ + "test", + "assertion", + "assert", + "testing", + "chai" + ], + "files": [ + "chai.js", + "index.js", + "lib", + "register-*.js" + ], + "homepage": "http://chaijs.com", + "license": "MIT", + "contributors": [ + "Jake Luer ", + "Domenic Denicola (http://domenicdenicola.com)", + "Veselin Todorov ", + "John Firebaugh " + ], + "version": "5.3.3", + "repository": { + "type": "git", + "url": "https://github.com/chaijs/chai" + }, + "bugs": { + "url": "https://github.com/chaijs/chai/issues" + }, + "main": "./index.js", + "scripts": { + "build": "esbuild --bundle --format=esm --keep-names --outfile=index.js lib/chai.js", + "prebuild": "npm run clean", + "format": "prettier --write lib", + "pretest": "npm run lint", + "test": "npm run test-node && npm run test-chrome", + "test-node": "c8 --99 --check-coverage mocha --require ./test/bootstrap/index.js test/*.js", + "test-chrome": "web-test-runner --playwright", + "lint": "npm run lint:js && npm run lint:format", + "lint:js": "eslint lib/", + "lint:format": "prettier --check lib", + "lint:types": "tsc", + "clean": "rm -rf index.js coverage/" + }, + "engines": { + "node": ">=18" + }, + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "devDependencies": { + "@eslint/js": "^9.17.0", + "@rollup/plugin-commonjs": "^25.0.7", + "@web/dev-server-rollup": "^0.6.1", + "@web/test-runner": "^0.18.0", + "@web/test-runner-playwright": "^0.11.0", + "c8": "^10.1.3", + "esbuild": "^0.25.9", + "eslint": "^8.56.0", + "eslint-plugin-jsdoc": "^48.0.4", + "mocha": "^10.2.0", + "prettier": "^3.4.2", + "typescript": "~5.7.3" + } +} diff --git a/node_modules/chai/register-assert.js b/node_modules/chai/register-assert.js new file mode 100644 index 0000000000..f593717e0b --- /dev/null +++ b/node_modules/chai/register-assert.js @@ -0,0 +1,3 @@ +import {assert} from './index.js'; + +globalThis.assert = assert; diff --git a/node_modules/chai/register-expect.js b/node_modules/chai/register-expect.js new file mode 100644 index 0000000000..2807b89bed --- /dev/null +++ b/node_modules/chai/register-expect.js @@ -0,0 +1,3 @@ +import {expect} from './index.js'; + +globalThis.expect = expect; diff --git a/node_modules/chai/register-should.js b/node_modules/chai/register-should.js new file mode 100644 index 0000000000..1339ee4c47 --- /dev/null +++ b/node_modules/chai/register-should.js @@ -0,0 +1,3 @@ +import {should} from './index.js'; + +globalThis.should = should(); diff --git a/node_modules/check-error/LICENSE b/node_modules/check-error/LICENSE new file mode 100644 index 0000000000..7ea799f0ef --- /dev/null +++ b/node_modules/check-error/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Jake Luer (http://alogicalparadox.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/check-error/README.md b/node_modules/check-error/README.md new file mode 100644 index 0000000000..95c3200023 --- /dev/null +++ b/node_modules/check-error/README.md @@ -0,0 +1,144 @@ +

+ + ChaiJS + +
+ check-error +

+ +

+ Error comparison and information related utility for node and the browser. +

+ +## What is Check-Error? + +Check-Error is a module which you can use to retrieve an Error's information such as its `message` or `constructor` name and also to check whether two Errors are compatible based on their messages, constructors or even instances. + +## Installation + +### Node.js + +`check-error` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install check-error + +### Browsers + +You can also use it within the browser; install via npm and use the `check-error.js` file found within the download. For example: + +```html + +``` + +## Usage + +The primary export of `check-error` is an object which has the following methods: + +* `compatibleInstance(err, errorLike)` - Checks if an error is compatible with another `errorLike` object. If `errorLike` is an error instance we do a strict comparison, otherwise we return `false` by default, because instances of objects can only be compatible if they're both error instances. +* `compatibleConstructor(err, errorLike)` - Checks if an error's constructor is compatible with another `errorLike` object. If `err` has the same constructor as `errorLike` or if `err` is an instance of `errorLike`. +* `compatibleMessage(err, errMatcher)` - Checks if an error message is compatible with an `errMatcher` RegExp or String (we check if the message contains the String). +* `getConstructorName(errorLike)` - Retrieves the name of a constructor, an error's constructor or `errorLike` itself if it's not an error instance or constructor. +* `getMessage(err)` - Retrieves the message of an error or `err` itself if it's a String. If `err` or `err.message` is undefined we return an empty String. + +```js +var checkError = require('check-error'); +``` + +#### .compatibleInstance(err, errorLike) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +var sameInstance = caughtErr; + +checkError.compatibleInstance(caughtErr, sameInstance); // true +checkError.compatibleInstance(caughtErr, new TypeError('Another error')); // false +``` + +#### .compatibleConstructor(err, errorLike) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +checkError.compatibleConstructor(caughtErr, Error); // true +checkError.compatibleConstructor(caughtErr, TypeError); // true +checkError.compatibleConstructor(caughtErr, RangeError); // false +``` + +#### .compatibleMessage(err, errMatcher) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +var sameInstance = caughtErr; + +checkError.compatibleMessage(caughtErr, /TypeError$/); // true +checkError.compatibleMessage(caughtErr, 'I am a'); // true +checkError.compatibleMessage(caughtErr, /unicorn/); // false +checkError.compatibleMessage(caughtErr, 'I do not exist'); // false +``` + +#### .getConstructorName(errorLike) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +var sameInstance = caughtErr; + +checkError.getConstructorName(caughtErr) // 'TypeError' +``` + +#### .getMessage(err) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +var sameInstance = caughtErr; + +checkError.getMessage(caughtErr) // 'I am a TypeError' +``` diff --git a/node_modules/check-error/index.js b/node_modules/check-error/index.js new file mode 100644 index 0000000000..872a7b6c17 --- /dev/null +++ b/node_modules/check-error/index.js @@ -0,0 +1,135 @@ +function isErrorInstance(obj) { + // eslint-disable-next-line prefer-reflect + return obj instanceof Error || Object.prototype.toString.call(obj) === '[object Error]'; +} + +function isRegExp(obj) { + // eslint-disable-next-line prefer-reflect + return Object.prototype.toString.call(obj) === '[object RegExp]'; +} + +/** + * ### .compatibleInstance(thrown, errorLike) + * + * Checks if two instances are compatible (strict equal). + * Returns false if errorLike is not an instance of Error, because instances + * can only be compatible if they're both error instances. + * + * @name compatibleInstance + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleInstance(thrown, errorLike) { + return isErrorInstance(errorLike) && thrown === errorLike; +} + +/** + * ### .compatibleConstructor(thrown, errorLike) + * + * Checks if two constructors are compatible. + * This function can receive either an error constructor or + * an error instance as the `errorLike` argument. + * Constructors are compatible if they're the same or if one is + * an instance of another. + * + * @name compatibleConstructor + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleConstructor(thrown, errorLike) { + if (isErrorInstance(errorLike)) { + // If `errorLike` is an instance of any error we compare their constructors + return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; + } else if ((typeof errorLike === 'object' || typeof errorLike === 'function') && errorLike.prototype) { + // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly + return thrown.constructor === errorLike || thrown instanceof errorLike; + } + + return false; +} + +/** + * ### .compatibleMessage(thrown, errMatcher) + * + * Checks if an error's message is compatible with a matcher (String or RegExp). + * If the message contains the String or passes the RegExp test, + * it is considered compatible. + * + * @name compatibleMessage + * @param {Error} thrown error + * @param {String|RegExp} errMatcher to look for into the message + * @namespace Utils + * @api public + */ + +function compatibleMessage(thrown, errMatcher) { + const comparisonString = typeof thrown === 'string' ? thrown : thrown.message; + if (isRegExp(errMatcher)) { + return errMatcher.test(comparisonString); + } else if (typeof errMatcher === 'string') { + return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers + } + + return false; +} + +/** + * ### .getConstructorName(errorLike) + * + * Gets the constructor name for an Error instance or constructor itself. + * + * @name getConstructorName + * @param {Error|ErrorConstructor} errorLike + * @namespace Utils + * @api public + */ + +function getConstructorName(errorLike) { + let constructorName = errorLike; + if (isErrorInstance(errorLike)) { + constructorName = errorLike.constructor.name; + } else if (typeof errorLike === 'function') { + // If `err` is not an instance of Error it is an error constructor itself or another function. + // If we've got a common function we get its name, otherwise we may need to create a new instance + // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more. + constructorName = errorLike.name; + if (constructorName === '') { + const newConstructorName = (new errorLike().name); // eslint-disable-line new-cap + constructorName = newConstructorName || constructorName; + } + } + + return constructorName; +} + +/** + * ### .getMessage(errorLike) + * + * Gets the error message from an error. + * If `err` is a String itself, we return it. + * If the error has no message, we return an empty string. + * + * @name getMessage + * @param {Error|String} errorLike + * @namespace Utils + * @api public + */ + +function getMessage(errorLike) { + let msg = ''; + if (errorLike && errorLike.message) { + msg = errorLike.message; + } else if (typeof errorLike === 'string') { + msg = errorLike; + } + + return msg; +} + +export { compatibleInstance, compatibleConstructor, compatibleMessage, getMessage, getConstructorName }; diff --git a/node_modules/check-error/package.json b/node_modules/check-error/package.json new file mode 100644 index 0000000000..d2dcbaf1ec --- /dev/null +++ b/node_modules/check-error/package.json @@ -0,0 +1,66 @@ +{ + "version": "2.1.1", + "name": "check-error", + "description": "Error comparison and information related utility for node and the browser", + "keywords": ["check-error", "error", "chai util"], + "license": "MIT", + "author": "Jake Luer (http://alogicalparadox.com)", + "contributors": [ + "David Losert (https://github.com/davelosert)", + "Keith Cirkel (https://github.com/keithamus)", + "Miroslav Bajtoš (https://github.com/bajtos)", + "Lucas Fernandes da Costa (https://github.com/lucasfcosta)" + ], + "files": ["index.js", "check-error.js"], + "type": "module", + "main": "./index.js", + "module": "./index.js", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/chaijs/check-error.git" + }, + "scripts": { + "lint": "eslint --ignore-path .gitignore index.js test/", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "pretest": "npm run lint", + "test": "npm run test:node && npm run test:browser", + "test:browser": "web-test-runner", + "test:node": "mocha" + }, + "config": { + "ghooks": { + "commit-msg": "validate-commit-msg" + } + }, + "eslintConfig": { + "extends": ["strict/es6"], + "env": { + "es6": true + }, + "globals": { + "HTMLElement": false + }, + "rules": { + "complexity": "off", + "max-statements": "off", + "prefer-arrow-callback": "off", + "prefer-reflect": "off" + } + }, + "devDependencies": { + "@web/test-runner": "^0.17.0", + "browserify": "^13.0.0", + "browserify-istanbul": "^1.0.0", + "eslint": "^2.4.0", + "eslint-config-strict": "^8.5.0", + "eslint-plugin-filenames": "^0.2.0", + "ghooks": "^1.0.1", + "mocha": "^9.1.2", + "semantic-release": "^4.3.5", + "simple-assert": "^2.0.0", + "validate-commit-msg": "^2.3.1" + }, + "engines": { + "node": ">= 16" + } +} diff --git a/node_modules/debug/LICENSE b/node_modules/debug/LICENSE new file mode 100644 index 0000000000..1a9820e262 --- /dev/null +++ b/node_modules/debug/LICENSE @@ -0,0 +1,20 @@ +(The MIT License) + +Copyright (c) 2014-2017 TJ Holowaychuk +Copyright (c) 2018-2021 Josh Junon + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the 'Software'), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/node_modules/debug/README.md b/node_modules/debug/README.md new file mode 100644 index 0000000000..9ebdfbf149 --- /dev/null +++ b/node_modules/debug/README.md @@ -0,0 +1,481 @@ +# debug +[![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers) +[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors) + + + +A tiny JavaScript debugging utility modelled after Node.js core's debugging +technique. Works in Node.js and web browsers. + +## Installation + +```bash +$ npm install debug +``` + +## Usage + +`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole. + +Example [_app.js_](./examples/node/app.js): + +```js +var debug = require('debug')('http') + , http = require('http') + , name = 'My App'; + +// fake app + +debug('booting %o', name); + +http.createServer(function(req, res){ + debug(req.method + ' ' + req.url); + res.end('hello\n'); +}).listen(3000, function(){ + debug('listening'); +}); + +// fake worker of some kind + +require('./worker'); +``` + +Example [_worker.js_](./examples/node/worker.js): + +```js +var a = require('debug')('worker:a') + , b = require('debug')('worker:b'); + +function work() { + a('doing lots of uninteresting work'); + setTimeout(work, Math.random() * 1000); +} + +work(); + +function workb() { + b('doing some work'); + setTimeout(workb, Math.random() * 2000); +} + +workb(); +``` + +The `DEBUG` environment variable is then used to enable these based on space or +comma-delimited names. + +Here are some examples: + +screen shot 2017-08-08 at 12 53 04 pm +screen shot 2017-08-08 at 12 53 38 pm +screen shot 2017-08-08 at 12 53 25 pm + +#### Windows command prompt notes + +##### CMD + +On Windows the environment variable is set using the `set` command. + +```cmd +set DEBUG=*,-not_this +``` + +Example: + +```cmd +set DEBUG=* & node app.js +``` + +##### PowerShell (VS Code default) + +PowerShell uses different syntax to set environment variables. + +```cmd +$env:DEBUG = "*,-not_this" +``` + +Example: + +```cmd +$env:DEBUG='app';node app.js +``` + +Then, run the program to be debugged as usual. + +npm script example: +```js + "windowsDebug": "@powershell -Command $env:DEBUG='*';node app.js", +``` + +## Namespace Colors + +Every debug instance has a color generated for it based on its namespace name. +This helps when visually parsing the debug output to identify which debug instance +a debug line belongs to. + +#### Node.js + +In Node.js, colors are enabled when stderr is a TTY. You also _should_ install +the [`supports-color`](https://npmjs.org/supports-color) module alongside debug, +otherwise debug will only use a small handful of basic colors. + + + +#### Web Browser + +Colors are also enabled on "Web Inspectors" that understand the `%c` formatting +option. These are WebKit web inspectors, Firefox ([since version +31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/)) +and the Firebug plugin for Firefox (any version). + + + + +## Millisecond diff + +When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. + + + +When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below: + + + + +## Conventions + +If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output. + +## Wildcards + +The `*` character may be used as a wildcard. Suppose for example your library has +debuggers named "connect:bodyParser", "connect:compress", "connect:session", +instead of listing all three with +`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do +`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. + +You can also exclude specific debuggers by prefixing them with a "-" character. +For example, `DEBUG=*,-connect:*` would include all debuggers except those +starting with "connect:". + +## Environment Variables + +When running through Node.js, you can set a few environment variables that will +change the behavior of the debug logging: + +| Name | Purpose | +|-----------|-------------------------------------------------| +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). | +| `DEBUG_COLORS`| Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + + +__Note:__ The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +## Formatters + +Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. +Below are the officially supported formatters: + +| Formatter | Representation | +|-----------|----------------| +| `%O` | Pretty-print an Object on multiple lines. | +| `%o` | Pretty-print an Object all on a single line. | +| `%s` | String. | +| `%d` | Number (both integer and float). | +| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. | +| `%%` | Single percent sign ('%'). This does not consume an argument. | + + +### Custom formatters + +You can add custom formatters by extending the `debug.formatters` object. +For example, if you wanted to add support for rendering a Buffer as hex with +`%h`, you could do something like: + +```js +const createDebug = require('debug') +createDebug.formatters.h = (v) => { + return v.toString('hex') +} + +// …elsewhere +const debug = createDebug('foo') +debug('this is hex: %h', new Buffer('hello world')) +// foo this is hex: 68656c6c6f20776f726c6421 +0ms +``` + + +## Browser Support + +You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify), +or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest), +if you don't want to build it yourself. + +Debug's enable state is currently persisted by `localStorage`. +Consider the situation shown below where you have `worker:a` and `worker:b`, +and wish to debug both. You can enable this using `localStorage.debug`: + +```js +localStorage.debug = 'worker:*' +``` + +And then refresh the page. + +```js +a = debug('worker:a'); +b = debug('worker:b'); + +setInterval(function(){ + a('doing some work'); +}, 1000); + +setInterval(function(){ + b('doing some work'); +}, 1200); +``` + +In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by `debug` if the "Verbose" log level is _enabled_. + + + +## Output streams + + By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method: + +Example [_stdout.js_](./examples/node/stdout.js): + +```js +var debug = require('debug'); +var error = debug('app:error'); + +// by default stderr is used +error('goes to stderr!'); + +var log = debug('app:log'); +// set this namespace to log via console.log +log.log = console.log.bind(console); // don't forget to bind to console! +log('goes to stdout'); +error('still goes to stderr!'); + +// set all output to go via console.info +// overrides all per-namespace log settings +debug.log = console.info.bind(console); +error('now goes to stdout via console.info'); +log('still goes to stdout, but via console.info now'); +``` + +## Extend +You can simply extend debugger +```js +const log = require('debug')('auth'); + +//creates new debug instance with extended namespace +const logSign = log.extend('sign'); +const logLogin = log.extend('login'); + +log('hello'); // auth hello +logSign('hello'); //auth:sign hello +logLogin('hello'); //auth:login hello +``` + +## Set dynamically + +You can also enable debug dynamically by calling the `enable()` method : + +```js +let debug = require('debug'); + +console.log(1, debug.enabled('test')); + +debug.enable('test'); +console.log(2, debug.enabled('test')); + +debug.disable(); +console.log(3, debug.enabled('test')); + +``` + +print : +``` +1 false +2 true +3 false +``` + +Usage : +`enable(namespaces)` +`namespaces` can include modes separated by a colon and wildcards. + +Note that calling `enable()` completely overrides previously set DEBUG variable : + +``` +$ DEBUG=foo node -e 'var dbg = require("debug"); dbg.enable("bar"); console.log(dbg.enabled("foo"))' +=> false +``` + +`disable()` + +Will disable all namespaces. The functions returns the namespaces currently +enabled (and skipped). This can be useful if you want to disable debugging +temporarily without knowing what was enabled to begin with. + +For example: + +```js +let debug = require('debug'); +debug.enable('foo:*,-foo:bar'); +let namespaces = debug.disable(); +debug.enable(namespaces); +``` + +Note: There is no guarantee that the string will be identical to the initial +enable string, but semantically they will be identical. + +## Checking whether a debug target is enabled + +After you've created a debug instance, you can determine whether or not it is +enabled by checking the `enabled` property: + +```javascript +const debug = require('debug')('http'); + +if (debug.enabled) { + // do stuff... +} +``` + +You can also manually toggle this property to force the debug instance to be +enabled or disabled. + +## Usage in child processes + +Due to the way `debug` detects if the output is a TTY or not, colors are not shown in child processes when `stderr` is piped. A solution is to pass the `DEBUG_COLORS=1` environment variable to the child process. +For example: + +```javascript +worker = fork(WORKER_WRAP_PATH, [workerPath], { + stdio: [ + /* stdin: */ 0, + /* stdout: */ 'pipe', + /* stderr: */ 'pipe', + 'ipc', + ], + env: Object.assign({}, process.env, { + DEBUG_COLORS: 1 // without this settings, colors won't be shown + }), +}); + +worker.stderr.pipe(process.stderr, { end: false }); +``` + + +## Authors + + - TJ Holowaychuk + - Nathan Rajlich + - Andrew Rhyne + - Josh Junon + +## Backers + +Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Sponsors + +Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## License + +(The MIT License) + +Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca> +Copyright (c) 2018-2021 Josh Junon + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/debug/package.json b/node_modules/debug/package.json new file mode 100644 index 0000000000..afc2f8b615 --- /dev/null +++ b/node_modules/debug/package.json @@ -0,0 +1,64 @@ +{ + "name": "debug", + "version": "4.4.1", + "repository": { + "type": "git", + "url": "git://github.com/debug-js/debug.git" + }, + "description": "Lightweight debugging utility for Node.js and the browser", + "keywords": [ + "debug", + "log", + "debugger" + ], + "files": [ + "src", + "LICENSE", + "README.md" + ], + "author": "Josh Junon (https://github.com/qix-)", + "contributors": [ + "TJ Holowaychuk ", + "Nathan Rajlich (http://n8.io)", + "Andrew Rhyne " + ], + "license": "MIT", + "scripts": { + "lint": "xo", + "test": "npm run test:node && npm run test:browser && npm run lint", + "test:node": "mocha test.js test.node.js", + "test:browser": "karma start --single-run", + "test:coverage": "cat ./coverage/lcov.info | coveralls" + }, + "dependencies": { + "ms": "^2.1.3" + }, + "devDependencies": { + "brfs": "^2.0.1", + "browserify": "^16.2.3", + "coveralls": "^3.0.2", + "karma": "^3.1.4", + "karma-browserify": "^6.0.0", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^1.3.0", + "mocha": "^5.2.0", + "mocha-lcov-reporter": "^1.2.0", + "sinon": "^14.0.0", + "xo": "^0.23.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + }, + "main": "./src/index.js", + "browser": "./src/browser.js", + "engines": { + "node": ">=6.0" + }, + "xo": { + "rules": { + "import/extensions": "off" + } + } +} diff --git a/node_modules/debug/src/browser.js b/node_modules/debug/src/browser.js new file mode 100644 index 0000000000..5993451b82 --- /dev/null +++ b/node_modules/debug/src/browser.js @@ -0,0 +1,272 @@ +/* eslint-env browser */ + +/** + * This is the web browser implementation of `debug()`. + */ + +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = localstorage(); +exports.destroy = (() => { + let warned = false; + + return () => { + if (!warned) { + warned = true; + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + }; +})(); + +/** + * Colors. + */ + +exports.colors = [ + '#0000CC', + '#0000FF', + '#0033CC', + '#0033FF', + '#0066CC', + '#0066FF', + '#0099CC', + '#0099FF', + '#00CC00', + '#00CC33', + '#00CC66', + '#00CC99', + '#00CCCC', + '#00CCFF', + '#3300CC', + '#3300FF', + '#3333CC', + '#3333FF', + '#3366CC', + '#3366FF', + '#3399CC', + '#3399FF', + '#33CC00', + '#33CC33', + '#33CC66', + '#33CC99', + '#33CCCC', + '#33CCFF', + '#6600CC', + '#6600FF', + '#6633CC', + '#6633FF', + '#66CC00', + '#66CC33', + '#9900CC', + '#9900FF', + '#9933CC', + '#9933FF', + '#99CC00', + '#99CC33', + '#CC0000', + '#CC0033', + '#CC0066', + '#CC0099', + '#CC00CC', + '#CC00FF', + '#CC3300', + '#CC3333', + '#CC3366', + '#CC3399', + '#CC33CC', + '#CC33FF', + '#CC6600', + '#CC6633', + '#CC9900', + '#CC9933', + '#CCCC00', + '#CCCC33', + '#FF0000', + '#FF0033', + '#FF0066', + '#FF0099', + '#FF00CC', + '#FF00FF', + '#FF3300', + '#FF3333', + '#FF3366', + '#FF3399', + '#FF33CC', + '#FF33FF', + '#FF6600', + '#FF6633', + '#FF9900', + '#FF9933', + '#FFCC00', + '#FFCC33' +]; + +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +// eslint-disable-next-line complexity +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { + return true; + } + + // Internet Explorer and Edge do not support colors. + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + + let m; + + // Is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + // eslint-disable-next-line no-return-assign + return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || + // Is firebug? http://stackoverflow.com/a/398120/376773 + (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || + // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) || + // Double check webkit in userAgent just in case we are in a worker + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); +} + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs(args) { + args[0] = (this.useColors ? '%c' : '') + + this.namespace + + (this.useColors ? ' %c' : ' ') + + args[0] + + (this.useColors ? '%c ' : ' ') + + '+' + module.exports.humanize(this.diff); + + if (!this.useColors) { + return; + } + + const c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); + + // The final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + let index = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, match => { + if (match === '%%') { + return; + } + index++; + if (match === '%c') { + // We only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); +} + +/** + * Invokes `console.debug()` when available. + * No-op when `console.debug` is not a "function". + * If `console.debug` is not available, falls back + * to `console.log`. + * + * @api public + */ +exports.log = console.debug || console.log || (() => {}); + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ +function save(namespaces) { + try { + if (namespaces) { + exports.storage.setItem('debug', namespaces); + } else { + exports.storage.removeItem('debug'); + } + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ +function load() { + let r; + try { + r = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ; + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + + return r; +} + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage() { + try { + // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context + // The Browser also has localStorage in the global context. + return localStorage; + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} + +module.exports = require('./common')(exports); + +const {formatters} = module.exports; + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (error) { + return '[UnexpectedJSONParseError]: ' + error.message; + } +}; diff --git a/node_modules/debug/src/common.js b/node_modules/debug/src/common.js new file mode 100644 index 0000000000..141cb578b7 --- /dev/null +++ b/node_modules/debug/src/common.js @@ -0,0 +1,292 @@ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + */ + +function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = require('ms'); + createDebug.destroy = destroy; + + Object.keys(env).forEach(key => { + createDebug[key] = env[key]; + }); + + /** + * The currently active debug mode names, and names to skip. + */ + + createDebug.names = []; + createDebug.skips = []; + + /** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ + createDebug.formatters = {}; + + /** + * Selects a color for a debug namespace + * @param {String} namespace The namespace string for the debug instance to be colored + * @return {Number|String} An ANSI color code for the given namespace + * @api private + */ + function selectColor(namespace) { + let hash = 0; + + for (let i = 0; i < namespace.length; i++) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } + + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + createDebug.selectColor = selectColor; + + /** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + function createDebug(namespace) { + let prevTime; + let enableOverride = null; + let namespacesCache; + let enabledCache; + + function debug(...args) { + // Disabled? + if (!debug.enabled) { + return; + } + + const self = debug; + + // Set `diff` timestamp + const curr = Number(new Date()); + const ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + args[0] = createDebug.coerce(args[0]); + + if (typeof args[0] !== 'string') { + // Anything else let's inspect with %O + args.unshift('%O'); + } + + // Apply any `formatters` transformations + let index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + // If we encounter an escaped % then don't increase the array index + if (match === '%%') { + return '%'; + } + index++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === 'function') { + const val = args[index]; + match = formatter.call(self, val); + + // Now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // Apply env-specific formatting (colors, etc.) + createDebug.formatArgs.call(self, args); + + const logFn = self.log || createDebug.log; + logFn.apply(self, args); + } + + debug.namespace = namespace; + debug.useColors = createDebug.useColors(); + debug.color = createDebug.selectColor(namespace); + debug.extend = extend; + debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. + + Object.defineProperty(debug, 'enabled', { + enumerable: true, + configurable: false, + get: () => { + if (enableOverride !== null) { + return enableOverride; + } + if (namespacesCache !== createDebug.namespaces) { + namespacesCache = createDebug.namespaces; + enabledCache = createDebug.enabled(namespace); + } + + return enabledCache; + }, + set: v => { + enableOverride = v; + } + }); + + // Env-specific initialization logic for debug instances + if (typeof createDebug.init === 'function') { + createDebug.init(debug); + } + + return debug; + } + + function extend(namespace, delimiter) { + const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + + /** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.namespaces = namespaces; + + createDebug.names = []; + createDebug.skips = []; + + const split = (typeof namespaces === 'string' ? namespaces : '') + .trim() + .replace(/\s+/g, ',') + .split(',') + .filter(Boolean); + + for (const ns of split) { + if (ns[0] === '-') { + createDebug.skips.push(ns.slice(1)); + } else { + createDebug.names.push(ns); + } + } + } + + /** + * Checks if the given string matches a namespace template, honoring + * asterisks as wildcards. + * + * @param {String} search + * @param {String} template + * @return {Boolean} + */ + function matchesTemplate(search, template) { + let searchIndex = 0; + let templateIndex = 0; + let starIndex = -1; + let matchIndex = 0; + + while (searchIndex < search.length) { + if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) { + // Match character or proceed with wildcard + if (template[templateIndex] === '*') { + starIndex = templateIndex; + matchIndex = searchIndex; + templateIndex++; // Skip the '*' + } else { + searchIndex++; + templateIndex++; + } + } else if (starIndex !== -1) { // eslint-disable-line no-negated-condition + // Backtrack to the last '*' and try to match more characters + templateIndex = starIndex + 1; + matchIndex++; + searchIndex = matchIndex; + } else { + return false; // No match + } + } + + // Handle trailing '*' in template + while (templateIndex < template.length && template[templateIndex] === '*') { + templateIndex++; + } + + return templateIndex === template.length; + } + + /** + * Disable debug output. + * + * @return {String} namespaces + * @api public + */ + function disable() { + const namespaces = [ + ...createDebug.names, + ...createDebug.skips.map(namespace => '-' + namespace) + ].join(','); + createDebug.enable(''); + return namespaces; + } + + /** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + function enabled(name) { + for (const skip of createDebug.skips) { + if (matchesTemplate(name, skip)) { + return false; + } + } + + for (const ns of createDebug.names) { + if (matchesTemplate(name, ns)) { + return true; + } + } + + return false; + } + + /** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } + + /** + * XXX DO NOT USE. This is a temporary stub function. + * XXX It WILL be removed in the next major release. + */ + function destroy() { + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + + createDebug.enable(createDebug.load()); + + return createDebug; +} + +module.exports = setup; diff --git a/node_modules/debug/src/index.js b/node_modules/debug/src/index.js new file mode 100644 index 0000000000..bf4c57f259 --- /dev/null +++ b/node_modules/debug/src/index.js @@ -0,0 +1,10 @@ +/** + * Detect Electron renderer / nwjs process, which is node, but we should + * treat as a browser. + */ + +if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { + module.exports = require('./browser.js'); +} else { + module.exports = require('./node.js'); +} diff --git a/node_modules/debug/src/node.js b/node_modules/debug/src/node.js new file mode 100644 index 0000000000..715560a4ca --- /dev/null +++ b/node_modules/debug/src/node.js @@ -0,0 +1,263 @@ +/** + * Module dependencies. + */ + +const tty = require('tty'); +const util = require('util'); + +/** + * This is the Node.js implementation of `debug()`. + */ + +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.destroy = util.deprecate( + () => {}, + 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.' +); + +/** + * Colors. + */ + +exports.colors = [6, 2, 3, 4, 5, 1]; + +try { + // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) + // eslint-disable-next-line import/no-extraneous-dependencies + const supportsColor = require('supports-color'); + + if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { + exports.colors = [ + 20, + 21, + 26, + 27, + 32, + 33, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 56, + 57, + 62, + 63, + 68, + 69, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 92, + 93, + 98, + 99, + 112, + 113, + 128, + 129, + 134, + 135, + 148, + 149, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 178, + 179, + 184, + 185, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 214, + 215, + 220, + 221 + ]; + } +} catch (error) { + // Swallow - we only care if `supports-color` is available; it doesn't have to be. +} + +/** + * Build up the default `inspectOpts` object from the environment variables. + * + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + */ + +exports.inspectOpts = Object.keys(process.env).filter(key => { + return /^debug_/i.test(key); +}).reduce((obj, key) => { + // Camel-case + const prop = key + .substring(6) + .toLowerCase() + .replace(/_([a-z])/g, (_, k) => { + return k.toUpperCase(); + }); + + // Coerce string value into JS value + let val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) { + val = true; + } else if (/^(no|off|false|disabled)$/i.test(val)) { + val = false; + } else if (val === 'null') { + val = null; + } else { + val = Number(val); + } + + obj[prop] = val; + return obj; +}, {}); + +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ + +function useColors() { + return 'colors' in exports.inspectOpts ? + Boolean(exports.inspectOpts.colors) : + tty.isatty(process.stderr.fd); +} + +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ + +function formatArgs(args) { + const {namespace: name, useColors} = this; + + if (useColors) { + const c = this.color; + const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); + const prefix = ` ${colorCode};1m${name} \u001B[0m`; + + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); + } else { + args[0] = getDate() + name + ' ' + args[0]; + } +} + +function getDate() { + if (exports.inspectOpts.hideDate) { + return ''; + } + return new Date().toISOString() + ' '; +} + +/** + * Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr. + */ + +function log(...args) { + return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n'); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ +function save(namespaces) { + if (namespaces) { + process.env.DEBUG = namespaces; + } else { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + return process.env.DEBUG; +} + +/** + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. + */ + +function init(debug) { + debug.inspectOpts = {}; + + const keys = Object.keys(exports.inspectOpts); + for (let i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; + } +} + +module.exports = require('./common')(exports); + +const {formatters} = module.exports; + +/** + * Map %o to `util.inspect()`, all on a single line. + */ + +formatters.o = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts) + .split('\n') + .map(str => str.trim()) + .join(' '); +}; + +/** + * Map %O to `util.inspect()`, allowing multiple lines if needed. + */ + +formatters.O = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); +}; diff --git a/node_modules/deep-eql/LICENSE b/node_modules/deep-eql/LICENSE new file mode 100644 index 0000000000..7ea799f0ef --- /dev/null +++ b/node_modules/deep-eql/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Jake Luer (http://alogicalparadox.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/deep-eql/README.md b/node_modules/deep-eql/README.md new file mode 100644 index 0000000000..f6e1b85cf7 --- /dev/null +++ b/node_modules/deep-eql/README.md @@ -0,0 +1,93 @@ +

+ + deep-eql + +

+ +

+ Improved deep equality testing for node and the browser. +

+ +

+ + build:? + + coverage:? + + dependencies:? + + devDependencies:? + +
+ + Join the Slack chat + + + Join the Gitter chat + +

+ +## What is Deep-Eql? + +Deep Eql is a module which you can use to determine if two objects are "deeply" equal - that is, rather than having referential equality (`a === b`), this module checks an object's keys recursively, until it finds primitives to check for referential equality. For more on equality in JavaScript, read [the comparison operators article on mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators). + +As an example, take the following: + +```js +1 === 1 // These are primitives, they hold the same reference - they are strictly equal +1 == '1' // These are two different primitives, through type coercion they hold the same value - they are loosely equal +{ a: 1 } !== { a: 1 } // These are two different objects, they hold different references and so are not strictly equal - even though they hold the same values inside +{ a: 1 } != { a: 1 } // They have the same type, meaning loose equality performs the same check as strict equality - they are still not equal. + +var deepEql = require("deep-eql"); +deepEql({ a: 1 }, { a: 1 }) === true // deepEql can determine that they share the same keys and those keys share the same values, therefore they are deeply equal! +``` + +## Installation + +### Node.js + +`deep-eql` is available on [npm](http://npmjs.org). + + $ npm install deep-eql + +## Usage + +The primary export of `deep-eql` is function that can be given two objects to compare. It will always return a boolean which can be used to determine if two objects are deeply equal. + +### Rules + +- Strict equality for non-traversable nodes according to [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is): + - `eql(NaN, NaN).should.be.true;` + - `eql(-0, +0).should.be.false;` +- All own and inherited enumerable properties are considered: + - `eql(Object.create({ foo: { a: 1 } }), Object.create({ foo: { a: 1 } })).should.be.true;` + - `eql(Object.create({ foo: { a: 1 } }), Object.create({ foo: { a: 2 } })).should.be.false;` +- When comparing `Error` objects, only `name`, `message`, and `code` properties are considered, regardless of enumerability: + - `eql(Error('foo'), Error('foo')).should.be.true;` + - `eql(Error('foo'), Error('bar')).should.be.false;` + - `eql(Error('foo'), TypeError('foo')).should.be.false;` + - `eql(Object.assign(Error('foo'), { code: 42 }), Object.assign(Error('foo'), { code: 42 })).should.be.true;` + - `eql(Object.assign(Error('foo'), { code: 42 }), Object.assign(Error('foo'), { code: 13 })).should.be.false;` + - `eql(Object.assign(Error('foo'), { otherProp: 42 }), Object.assign(Error('foo'), { otherProp: 13 })).should.be.true;` +- Arguments are not Arrays: + - `eql([], arguments).should.be.false;` + - `eql([], Array.prototype.slice.call(arguments)).should.be.true;` diff --git a/node_modules/deep-eql/index.js b/node_modules/deep-eql/index.js new file mode 100644 index 0000000000..8e5e333dd6 --- /dev/null +++ b/node_modules/deep-eql/index.js @@ -0,0 +1,513 @@ +/* globals Symbol: false, Uint8Array: false, WeakMap: false */ +/*! + * deep-eql + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +function type(obj) { + if (typeof obj === 'undefined') { + return 'undefined'; + } + + if (obj === null) { + return 'null'; + } + + const stringTag = obj[Symbol.toStringTag]; + if (typeof stringTag === 'string') { + return stringTag; + } + const sliceStart = 8; + const sliceEnd = -1; + return Object.prototype.toString.call(obj).slice(sliceStart, sliceEnd); +} + +function FakeMap() { + this._key = 'chai/deep-eql__' + Math.random() + Date.now(); +} + +FakeMap.prototype = { + get: function get(key) { + return key[this._key]; + }, + set: function set(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this._key, { + value: value, + configurable: true, + }); + } + }, +}; + +export var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap; +/*! + * Check to see if the MemoizeMap has recorded a result of the two operands + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @returns {Boolean|null} result +*/ +function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return null; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + var result = leftHandMap.get(rightHandOperand); + if (typeof result === 'boolean') { + return result; + } + } + return null; +} + +/*! + * Set the result of the equality into the MemoizeMap + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @param {Boolean} result +*/ +function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + leftHandMap.set(rightHandOperand, result); + } else { + leftHandMap = new MemoizeMap(); + leftHandMap.set(rightHandOperand, result); + memoizeMap.set(leftHandOperand, leftHandMap); + } +} + +/*! + * Primary Export + */ + +export default deepEqual; + +/** + * Assert deeply nested sameValue equality between two objects of any type. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match + */ +function deepEqual(leftHandOperand, rightHandOperand, options) { + // If we have a comparator, we can't assume anything; so bail to its check first. + if (options && options.comparator) { + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); + } + + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + return simpleResult; + } + + // Deeper comparisons are pushed through to a larger function + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); +} + +/** + * Many comparisons can be canceled out early via simple equality or primitive checks. + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @return {Boolean|null} equal match + */ +function simpleEqual(leftHandOperand, rightHandOperand) { + // Equal references (except for Numbers) can be returned early + if (leftHandOperand === rightHandOperand) { + // Handle +-0 cases + return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; + } + + // handle NaN cases + if ( + leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare + rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare + ) { + return true; + } + + // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers, + // strings, and undefined, can be compared by reference. + if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + // Easy out b/c it would have passed the first equality check + return false; + } + return null; +} + +/*! + * The main logic of the `deepEqual` function. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match +*/ +function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { + options = options || {}; + options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); + var comparator = options && options.comparator; + + // Check if a memoized result exists. + var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); + if (memoizeResultLeft !== null) { + return memoizeResultLeft; + } + var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); + if (memoizeResultRight !== null) { + return memoizeResultRight; + } + + // If a comparator is present, use it. + if (comparator) { + var comparatorResult = comparator(leftHandOperand, rightHandOperand); + // Comparators may return null, in which case we want to go back to default behavior. + if (comparatorResult === false || comparatorResult === true) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); + return comparatorResult; + } + // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide + // what to do, we need to make sure to return the basic tests first before we move on. + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + // Don't memoize this, it takes longer to set/retrieve than to just compare. + return simpleResult; + } + } + + var leftHandType = type(leftHandOperand); + if (leftHandType !== type(rightHandOperand)) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); + return false; + } + + // Temporarily set the operands in the memoize object to prevent blowing the stack + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); + + var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); + return result; +} + +function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { + switch (leftHandType) { + case 'String': + case 'Number': + case 'Boolean': + case 'Date': + // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values + return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); + case 'Promise': + case 'Symbol': + case 'function': + case 'WeakMap': + case 'WeakSet': + return leftHandOperand === rightHandOperand; + case 'Error': + return keysEqual(leftHandOperand, rightHandOperand, [ 'name', 'message', 'code' ], options); + case 'Arguments': + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float32Array': + case 'Float64Array': + case 'Array': + return iterableEqual(leftHandOperand, rightHandOperand, options); + case 'RegExp': + return regexpEqual(leftHandOperand, rightHandOperand); + case 'Generator': + return generatorEqual(leftHandOperand, rightHandOperand, options); + case 'DataView': + return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); + case 'ArrayBuffer': + return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); + case 'Set': + return entriesEqual(leftHandOperand, rightHandOperand, options); + case 'Map': + return entriesEqual(leftHandOperand, rightHandOperand, options); + case 'Temporal.PlainDate': + case 'Temporal.PlainTime': + case 'Temporal.PlainDateTime': + case 'Temporal.Instant': + case 'Temporal.ZonedDateTime': + case 'Temporal.PlainYearMonth': + case 'Temporal.PlainMonthDay': + return leftHandOperand.equals(rightHandOperand); + case 'Temporal.Duration': + return leftHandOperand.total('nanoseconds') === rightHandOperand.total('nanoseconds'); + case 'Temporal.TimeZone': + case 'Temporal.Calendar': + return leftHandOperand.toString() === rightHandOperand.toString(); + default: + return objectEqual(leftHandOperand, rightHandOperand, options); + } +} + +/*! + * Compare two Regular Expressions for equality. + * + * @param {RegExp} leftHandOperand + * @param {RegExp} rightHandOperand + * @return {Boolean} result + */ + +function regexpEqual(leftHandOperand, rightHandOperand) { + return leftHandOperand.toString() === rightHandOperand.toString(); +} + +/*! + * Compare two Sets/Maps for equality. Faster than other equality functions. + * + * @param {Set} leftHandOperand + * @param {Set} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function entriesEqual(leftHandOperand, rightHandOperand, options) { + try { + // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach + if (leftHandOperand.size !== rightHandOperand.size) { + return false; + } + if (leftHandOperand.size === 0) { + return true; + } + } catch (sizeError) { + // things that aren't actual Maps or Sets will throw here + return false; + } + var leftHandItems = []; + var rightHandItems = []; + leftHandOperand.forEach(function gatherEntries(key, value) { + leftHandItems.push([ key, value ]); + }); + rightHandOperand.forEach(function gatherEntries(key, value) { + rightHandItems.push([ key, value ]); + }); + return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); +} + +/*! + * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function iterableEqual(leftHandOperand, rightHandOperand, options) { + var length = leftHandOperand.length; + if (length !== rightHandOperand.length) { + return false; + } + if (length === 0) { + return true; + } + var index = -1; + while (++index < length) { + if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { + return false; + } + } + return true; +} + +/*! + * Simple equality for generator objects such as those returned by generator functions. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function generatorEqual(leftHandOperand, rightHandOperand, options) { + return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); +} + +/*! + * Determine if the given object has an @@iterator function. + * + * @param {Object} target + * @return {Boolean} `true` if the object has an @@iterator function. + */ +function hasIteratorFunction(target) { + return typeof Symbol !== 'undefined' && + typeof target === 'object' && + typeof Symbol.iterator !== 'undefined' && + typeof target[Symbol.iterator] === 'function'; +} + +/*! + * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. + * This will consume the iterator - which could have side effects depending on the @@iterator implementation. + * + * @param {Object} target + * @returns {Array} an array of entries from the @@iterator function + */ +function getIteratorEntries(target) { + if (hasIteratorFunction(target)) { + try { + return getGeneratorEntries(target[Symbol.iterator]()); + } catch (iteratorError) { + return []; + } + } + return []; +} + +/*! + * Gets all entries from a Generator. This will consume the generator - which could have side effects. + * + * @param {Generator} target + * @returns {Array} an array of entries from the Generator. + */ +function getGeneratorEntries(generator) { + var generatorResult = generator.next(); + var accumulator = [ generatorResult.value ]; + while (generatorResult.done === false) { + generatorResult = generator.next(); + accumulator.push(generatorResult.value); + } + return accumulator; +} + +/*! + * Gets all own and inherited enumerable keys from a target. + * + * @param {Object} target + * @returns {Array} an array of own and inherited enumerable keys from the target. + */ +function getEnumerableKeys(target) { + var keys = []; + for (var key in target) { + keys.push(key); + } + return keys; +} + +function getEnumerableSymbols(target) { + var keys = []; + var allKeys = Object.getOwnPropertySymbols(target); + for (var i = 0; i < allKeys.length; i += 1) { + var key = allKeys[i]; + if (Object.getOwnPropertyDescriptor(target, key).enumerable) { + keys.push(key); + } + } + return keys; +} + +/*! + * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of + * each key. If any value of the given key is not equal, the function will return false (early). + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ +function keysEqual(leftHandOperand, rightHandOperand, keys, options) { + var length = keys.length; + if (length === 0) { + return true; + } + for (var i = 0; i < length; i += 1) { + if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { + return false; + } + } + return true; +} + +/*! + * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` + * for each enumerable key in the object. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ +function objectEqual(leftHandOperand, rightHandOperand, options) { + var leftHandKeys = getEnumerableKeys(leftHandOperand); + var rightHandKeys = getEnumerableKeys(rightHandOperand); + var leftHandSymbols = getEnumerableSymbols(leftHandOperand); + var rightHandSymbols = getEnumerableSymbols(rightHandOperand); + leftHandKeys = leftHandKeys.concat(leftHandSymbols); + rightHandKeys = rightHandKeys.concat(rightHandSymbols); + + if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { + if (iterableEqual(mapSymbols(leftHandKeys).sort(), mapSymbols(rightHandKeys).sort()) === false) { + return false; + } + return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); + } + + var leftHandEntries = getIteratorEntries(leftHandOperand); + var rightHandEntries = getIteratorEntries(rightHandOperand); + if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { + leftHandEntries.sort(); + rightHandEntries.sort(); + return iterableEqual(leftHandEntries, rightHandEntries, options); + } + + if (leftHandKeys.length === 0 && + leftHandEntries.length === 0 && + rightHandKeys.length === 0 && + rightHandEntries.length === 0) { + return true; + } + + return false; +} + +/*! + * Returns true if the argument is a primitive. + * + * This intentionally returns true for all objects that can be compared by reference, + * including functions and symbols. + * + * @param {Mixed} value + * @return {Boolean} result + */ +function isPrimitive(value) { + return value === null || typeof value !== 'object'; +} + +function mapSymbols(arr) { + return arr.map(function mapSymbol(entry) { + if (typeof entry === 'symbol') { + return entry.toString(); + } + + return entry; + }); +} diff --git a/node_modules/deep-eql/package.json b/node_modules/deep-eql/package.json new file mode 100644 index 0000000000..c88004316f --- /dev/null +++ b/node_modules/deep-eql/package.json @@ -0,0 +1,73 @@ +{ + "name": "deep-eql", + "version": "5.0.2", + "description": "Improved deep equality testing for Node.js and the browser.", + "keywords": [ + "chai util", + "deep equal", + "object equal", + "testing" + ], + "repository": { + "type": "git", + "url": "git@github.com:chaijs/deep-eql.git" + }, + "license": "MIT", + "author": "Jake Luer ", + "contributors": [ + "Keith Cirkel (https://github.com/keithamus)", + "dougluce (https://github.com/dougluce)", + "Lorenz Leutgeb (https://github.com/flowlo)" + ], + "type": "module", + "main": "./index.js", + "files": [ + "index.js", + "deep-eql.js" + ], + "scripts": { + "bench": "node bench", + "lint": "eslint --ignore-path .gitignore .", + "semantic-release": "semantic-release pre && semantic-release post", + "pretest": "npm run lint", + "test": "npm run test:node && npm run test:browser", + "test:browser": "web-test-runner", + "test:node": "istanbul cover _mocha", + "upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0", + "watch": "web-test-runner --watch" + }, + "eslintConfig": { + "extends": [ + "strict/es5" + ], + "rules": { + "complexity": 0, + "no-underscore-dangle": 0, + "no-use-before-define": 0, + "spaced-comment": 0 + }, + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2015 + } + }, + "devDependencies": { + "@js-temporal/polyfill": "^0.4.3", + "@rollup/plugin-commonjs": "^24.1.0", + "@web/test-runner": "^0.16.1", + "benchmark": "^2.1.0", + "coveralls": "^3.1.1", + "eslint": "^7.32.0", + "eslint-config-strict": "^14.0.1", + "eslint-plugin-filenames": "^1.3.2", + "istanbul": "^0.4.2", + "kewlr": "^0.4.1", + "lcov-result-merger": "^1.0.2", + "lodash.isequal": "^4.4.0", + "mocha": "^9.1.1", + "simple-assert": "^2.0.0" + }, + "engines": { + "node": ">=6" + } +} diff --git a/node_modules/es-module-lexer/LICENSE b/node_modules/es-module-lexer/LICENSE new file mode 100644 index 0000000000..c795a2775f --- /dev/null +++ b/node_modules/es-module-lexer/LICENSE @@ -0,0 +1,10 @@ +MIT License +----------- + +Copyright (C) 2018-2022 Guy Bedford + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/es-module-lexer/README.md b/node_modules/es-module-lexer/README.md new file mode 100644 index 0000000000..310f4ee660 --- /dev/null +++ b/node_modules/es-module-lexer/README.md @@ -0,0 +1,338 @@ +# ES Module Lexer + +[![Build Status][actions-image]][actions-url] + +A JS module syntax lexer used in [es-module-shims](https://github.com/guybedford/es-module-shims). + +Outputs the list of exports and locations of import specifiers, including dynamic import and import meta handling. + +Supports new syntax features including import attributes and source phase imports. + +A very small single JS file (4KiB gzipped) that includes inlined Web Assembly for very fast source analysis of ECMAScript module syntax only. + +For an example of the performance, Angular 1 (720KiB) is fully parsed in 5ms, in comparison to the fastest JS parser, Acorn which takes over 100ms. + +_Comprehensively handles the JS language grammar while remaining small and fast. - ~10ms per MB of JS cold and ~5ms per MB of JS warm, [see benchmarks](#benchmarks) for more info._ + +> [Built with](https://github.com/guybedford/es-module-lexer/blob/main/chompfile.toml) [Chomp](https://chompbuild.com/) + +### Usage + +``` +npm install es-module-lexer +``` + +See [src/lexer.ts](src/lexer.ts) for the type definitions. + +For use in CommonJS: + +```js +const { init, parse } = require('es-module-lexer'); + +(async () => { + // either await init, or call parse asynchronously + // this is necessary for the Web Assembly boot + await init; + + const source = 'export var p = 5'; + const [imports, exports] = parse(source); + + // Returns "p" + source.slice(exports[0].s, exports[0].e); + // Returns "p" + source.slice(exports[0].ls, exports[0].le); +})(); +``` + +An ES module version is also available: + +```js +import { init, parse } from 'es-module-lexer'; + +(async () => { + await init; + + const source = ` + import { name } from 'mod\\u1011'; + import json from './json.json' assert { type: 'json' } + export var p = 5; + export function q () { + + }; + export { x as 'external name' } from 'external'; + + // Comments provided to demonstrate edge cases + import /*comment!*/ ( 'asdf', { assert: { type: 'json' }}); + import /*comment!*/.meta.asdf; + + // Source phase imports: + import source mod from './mod.wasm'; + import.source('./mod.wasm'); + `; + + const [imports, exports] = parse(source, 'optional-sourcename'); + + // Returns "modထ" + imports[0].n + // Returns "mod\u1011" + source.slice(imports[0].s, imports[0].e); + // "s" = start + // "e" = end + + // Returns "import { name } from 'mod'" + source.slice(imports[0].ss, imports[0].se); + // "ss" = statement start + // "se" = statement end + + // Returns "{ type: 'json' }" + source.slice(imports[1].a, imports[1].se); + // "a" = assert, -1 for no assertion + + // Returns "external" + source.slice(imports[2].s, imports[2].e); + + // Returns "p" + source.slice(exports[0].s, exports[0].e); + // Returns "p" + source.slice(exports[0].ls, exports[0].le); + // Returns "q" + source.slice(exports[1].s, exports[1].e); + // Returns "q" + source.slice(exports[1].ls, exports[1].le); + // Returns "'external name'" + source.slice(exports[2].s, exports[2].e); + // Returns -1 + exports[2].ls; + // Returns -1 + exports[2].le; + + // Import type is provided by `t` value + // (1 for static, 2, for dynamic) + // Returns true + imports[2].t == 2; + + // Returns "asdf" (only for string literal dynamic imports) + imports[2].n + // Returns "import /*comment!*/ ( 'asdf', { assert: { type: 'json' } })" + source.slice(imports[3].ss, imports[3].se); + // Returns "'asdf'" + source.slice(imports[3].s, imports[3].e); + // Returns "( 'asdf', { assert: { type: 'json' } })" + source.slice(imports[3].d, imports[3].se); + // Returns "{ assert: { type: 'json' } }" + source.slice(imports[3].a, imports[3].se - 1); + + // For non-string dynamic import expressions: + // - n will be undefined + // - a is currently -1 even if there is an assertion + // - e is currently the character before the closing ) + + // For nested dynamic imports, the se value of the outer import is -1 as end tracking does not + // currently support nested dynamic immports + + // import.meta is indicated by imports[3].d === -2 + // Returns true + imports[4].d === -2; + // Returns "import /*comment!*/.meta" + source.slice(imports[4].s, imports[4].e); + // ss and se are the same for import meta + + // Returns "'./mod.wasm'" + source.slice(imports[5].s, imports[5].e); + + // Import type 4 and 5 for static and dynamic source phase + imports[5].t === 4; + imports[6].t === 5; +})(); +``` + +### CSP asm.js Build + +The default version of the library uses Wasm and (safe) eval usage for performance and a minimal footprint. + +Neither of these represent security escalation possibilities since there are no execution string injection vectors, but that can still violate existing CSP policies for applications. + +For a version that works with CSP eval disabled, use the `es-module-lexer/js` build: + +```js +import { parse } from 'es-module-lexer/js'; +``` + +Instead of Web Assembly, this uses an asm.js build which is almost as fast as the Wasm version ([see benchmarks below](#benchmarks)). + +### Escape Sequences + +To handle escape sequences in specifier strings, the `.n` field of imported specifiers will be provided where possible. + +For dynamic import expressions, this field will be empty if not a valid JS string. + +### Facade Detection + +Facade modules that only use import / export syntax can be detected via the third return value: + +```js +const [,, facade] = parse(` + export * from 'external'; + import * as ns from 'external2'; + export { a as b } from 'external3'; + export { ns }; +`); +facade === true; +``` + +### ESM Detection + +Modules that uses ESM syntaxes can be detected via the fourth return value: + +```js +const [,,, hasModuleSyntax] = parse(` + export {} +`); +hasModuleSyntax === true; +``` + +Dynamic imports are ignored since they can be used in Non-ESM files. + +```js +const [,,, hasModuleSyntax] = parse(` + import('./foo.js') +`); +hasModuleSyntax === false; +``` + +### Environment Support + +Node.js 10+, and [all browsers with Web Assembly support](https://caniuse.com/#feat=wasm). + +### Grammar Support + +* Token state parses all line comments, block comments, strings, template strings, blocks, parens and punctuators. +* Division operator / regex token ambiguity is handled via backtracking checks against punctuator prefixes, including closing brace or paren backtracking. +* Always correctly parses valid JS source, but may parse invalid JS source without errors. + +### Limitations + +The lexing approach is designed to deal with the full language grammar including RegEx / division operator ambiguity through backtracking and paren / brace tracking. + +The only limitation to the reduced parser is that the "exports" list may not correctly gather all export identifiers in the following edge cases: + +```js +// Only "a" is detected as an export, "q" isn't +export var a = 'asdf', q = z; + +// "b" is not detected as an export +export var { a: b } = asdf; +``` + +The above cases are handled gracefully in that the lexer will keep going fine, it will just not properly detect the export names above. + +### Benchmarks + +Benchmarks can be run with `npm run bench`. + +Current results for a high spec machine: + +#### Wasm Build + +``` +Module load time +> 5ms +Cold Run, All Samples +test/samples/*.js (3123 KiB) +> 18ms + +Warm Runs (average of 25 runs) +test/samples/angular.js (739 KiB) +> 3ms +test/samples/angular.min.js (188 KiB) +> 1ms +test/samples/d3.js (508 KiB) +> 3ms +test/samples/d3.min.js (274 KiB) +> 2ms +test/samples/magic-string.js (35 KiB) +> 0ms +test/samples/magic-string.min.js (20 KiB) +> 0ms +test/samples/rollup.js (929 KiB) +> 4.32ms +test/samples/rollup.min.js (429 KiB) +> 2.16ms + +Warm Runs, All Samples (average of 25 runs) +test/samples/*.js (3123 KiB) +> 14.16ms +``` + +#### JS Build (asm.js) + +``` +Module load time +> 2ms +Cold Run, All Samples +test/samples/*.js (3123 KiB) +> 34ms + +Warm Runs (average of 25 runs) +test/samples/angular.js (739 KiB) +> 3ms +test/samples/angular.min.js (188 KiB) +> 1ms +test/samples/d3.js (508 KiB) +> 3ms +test/samples/d3.min.js (274 KiB) +> 2ms +test/samples/magic-string.js (35 KiB) +> 0ms +test/samples/magic-string.min.js (20 KiB) +> 0ms +test/samples/rollup.js (929 KiB) +> 5ms +test/samples/rollup.min.js (429 KiB) +> 3.04ms + +Warm Runs, All Samples (average of 25 runs) +test/samples/*.js (3123 KiB) +> 17.12ms +``` + +### Building + +This project uses [Chomp](https://chompbuild.com) for building. + +With Chomp installed, download the WASI SDK 12.0 from https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-12. + +- [Linux](https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-12/wasi-sdk-12.0-linux.tar.gz) +- [Windows (MinGW)](https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-12/wasi-sdk-12.0-mingw.tar.gz) +- [macOS](https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-12/wasi-sdk-12.0-macos.tar.gz) + +Locate the WASI-SDK as a sibling folder, or customize the path via the `WASI_PATH` environment variable. + +Emscripten emsdk is also assumed to be a sibling folder or via the `EMSDK_PATH` environment variable. + +Example setup: + +``` +git clone https://github.com:guybedford/es-module-lexer +git clone https://github.com/emscripten-core/emsdk +cd emsdk +git checkout 1.40.1-fastcomp +./emsdk install 1.40.1-fastcomp +cd .. +wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-12/wasi-sdk-12.0-linux.tar.gz +gunzip wasi-sdk-12.0-linux.tar.gz +tar -xf wasi-sdk-12.0-linux.tar +mv wasi-sdk-12.0-linux.tar wasi-sdk-12.0 +cargo install chompbuild +cd es-module-lexer +chomp test +``` + +For the `asm.js` build, git clone `emsdk` from is assumed to be a sibling folder as well. + +### License + +MIT + +[actions-image]: https://github.com/guybedford/es-module-lexer/actions/workflows/build.yml/badge.svg +[actions-url]: https://github.com/guybedford/es-module-lexer/actions/workflows/build.yml diff --git a/node_modules/es-module-lexer/dist/lexer.asm.js b/node_modules/es-module-lexer/dist/lexer.asm.js new file mode 100644 index 0000000000..d64300da74 --- /dev/null +++ b/node_modules/es-module-lexer/dist/lexer.asm.js @@ -0,0 +1,2 @@ +/* es-module-lexer 1.7.0 */ +let e,a,r,i=2<<19;const s=1===new Uint8Array(new Uint16Array([1]).buffer)[0]?function(e,a){const r=e.length;let i=0;for(;i>>8}},f="xportmportlassforetaourceeferromsyncunctionssertvoyiedelecontininstantybreareturdebuggeawaithrwhileifcatcfinallels";let t,c,n;export function parse(k,l="@"){t=k,c=l;const u=2*t.length+(2<<18);if(u>i||!e){for(;u>i;)i*=2;a=new ArrayBuffer(i),s(f,new Uint16Array(a,16,114)),e=function(e,a,r){"use asm";var i=new e.Int8Array(r),s=new e.Int16Array(r),f=new e.Int32Array(r),t=new e.Uint8Array(r),c=new e.Uint16Array(r),n=1040;function b(){var e=0,a=0,r=0,t=0,c=0,b=0,u=0;u=n;n=n+10240|0;i[812]=1;i[811]=0;s[403]=0;s[404]=0;f[71]=f[2];i[813]=0;f[70]=0;i[810]=0;f[72]=u+2048;f[73]=u;i[814]=0;e=(f[3]|0)+-2|0;f[74]=e;a=e+(f[68]<<1)|0;f[75]=a;e:while(1){r=e+2|0;f[74]=r;if(e>>>0>=a>>>0){t=18;break}a:do{switch(s[r>>1]|0){case 9:case 10:case 11:case 12:case 13:case 32:break;case 101:{if((((s[404]|0)==0?H(r)|0:0)?(m(e+4|0,16,10)|0)==0:0)?(k(),(i[812]|0)==0):0){t=9;break e}else t=17;break}case 105:{if(H(r)|0?(m(e+4|0,26,10)|0)==0:0){l();t=17}else t=17;break}case 59:{t=17;break}case 47:switch(s[e+4>>1]|0){case 47:{P();break a}case 42:{y(1);break a}default:{t=16;break e}}default:{t=16;break e}}}while(0);if((t|0)==17){t=0;f[71]=f[74]}e=f[74]|0;a=f[75]|0}if((t|0)==9){e=f[74]|0;f[71]=e;t=19}else if((t|0)==16){i[812]=0;f[74]=e;t=19}else if((t|0)==18)if(!(i[810]|0)){e=r;t=19}else e=0;do{if((t|0)==19){e:while(1){a=e+2|0;f[74]=a;if(e>>>0>=(f[75]|0)>>>0){t=92;break}a:do{switch(s[a>>1]|0){case 9:case 10:case 11:case 12:case 13:case 32:break;case 101:{if(((s[404]|0)==0?H(a)|0:0)?(m(e+4|0,16,10)|0)==0:0){k();t=91}else t=91;break}case 105:{if(H(a)|0?(m(e+4|0,26,10)|0)==0:0){l();t=91}else t=91;break}case 99:{if((H(a)|0?(m(e+4|0,36,8)|0)==0:0)?V(s[e+12>>1]|0)|0:0){i[814]=1;t=91}else t=91;break}case 40:{r=f[72]|0;e=s[404]|0;t=e&65535;f[r+(t<<3)>>2]=1;a=f[71]|0;s[404]=e+1<<16>>16;f[r+(t<<3)+4>>2]=a;t=91;break}case 41:{a=s[404]|0;if(!(a<<16>>16)){t=36;break e}r=a+-1<<16>>16;s[404]=r;t=s[403]|0;a=t&65535;if(t<<16>>16!=0?(f[(f[72]|0)+((r&65535)<<3)>>2]|0)==5:0){a=f[(f[73]|0)+(a+-1<<2)>>2]|0;r=a+4|0;if(!(f[r>>2]|0))f[r>>2]=(f[71]|0)+2;f[a+12>>2]=e+4;s[403]=t+-1<<16>>16;t=91}else t=91;break}case 123:{t=f[71]|0;r=f[65]|0;e=t;do{if((s[t>>1]|0)==41&(r|0)!=0?(f[r+4>>2]|0)==(t|0):0){a=f[66]|0;f[65]=a;if(!a){f[61]=0;break}else{f[a+32>>2]=0;break}}}while(0);r=f[72]|0;a=s[404]|0;t=a&65535;f[r+(t<<3)>>2]=(i[814]|0)==0?2:6;s[404]=a+1<<16>>16;f[r+(t<<3)+4>>2]=e;i[814]=0;t=91;break}case 125:{e=s[404]|0;if(!(e<<16>>16)){t=49;break e}r=f[72]|0;t=e+-1<<16>>16;s[404]=t;if((f[r+((t&65535)<<3)>>2]|0)==4){h();t=91}else t=91;break}case 39:{v(39);t=91;break}case 34:{v(34);t=91;break}case 47:switch(s[e+4>>1]|0){case 47:{P();break a}case 42:{y(1);break a}default:{e=f[71]|0;a=s[e>>1]|0;r:do{if(!(U(a)|0))if(a<<16>>16==41){r=s[404]|0;if(!(D(f[(f[72]|0)+((r&65535)<<3)+4>>2]|0)|0))t=65}else t=64;else switch(a<<16>>16){case 46:if(((s[e+-2>>1]|0)+-48&65535)<10){t=64;break r}else break r;case 43:if((s[e+-2>>1]|0)==43){t=64;break r}else break r;case 45:if((s[e+-2>>1]|0)==45){t=64;break r}else break r;default:break r}}while(0);if((t|0)==64){r=s[404]|0;t=65}r:do{if((t|0)==65){t=0;if(r<<16>>16!=0?(c=f[72]|0,b=(r&65535)+-1|0,a<<16>>16==102?(f[c+(b<<3)>>2]|0)==1:0):0){if((s[e+-2>>1]|0)==111?$(f[c+(b<<3)+4>>2]|0,44,3)|0:0)break}else t=69;if((t|0)==69?(0,a<<16>>16==125):0){t=f[72]|0;r=r&65535;if(p(f[t+(r<<3)+4>>2]|0)|0)break;if((f[t+(r<<3)>>2]|0)==6)break}if(!(o(e)|0)){switch(a<<16>>16){case 0:break r;case 47:{if(i[813]|0)break r;break}default:{}}t=f[67]|0;if((t|0?e>>>0>=(f[t>>2]|0)>>>0:0)?e>>>0<=(f[t+4>>2]|0)>>>0:0){g();i[813]=0;t=91;break a}r=f[3]|0;do{if(e>>>0<=r>>>0)break;e=e+-2|0;f[71]=e;a=s[e>>1]|0}while(!(E(a)|0));if(F(a)|0){do{if(e>>>0<=r>>>0)break;e=e+-2|0;f[71]=e}while(F(s[e>>1]|0)|0);if(j(e)|0){g();i[813]=0;t=91;break a}}i[813]=1;t=91;break a}}}while(0);g();i[813]=0;t=91;break a}}case 96:{r=f[72]|0;a=s[404]|0;t=a&65535;f[r+(t<<3)+4>>2]=f[71];s[404]=a+1<<16>>16;f[r+(t<<3)>>2]=3;h();t=91;break}default:t=91}}while(0);if((t|0)==91){t=0;f[71]=f[74]}e=f[74]|0}if((t|0)==36){T();e=0;break}else if((t|0)==49){T();e=0;break}else if((t|0)==92){e=(i[810]|0)==0?(s[403]|s[404])<<16>>16==0:0;break}}}while(0);n=u;return e|0}function k(){var e=0,a=0,r=0,t=0,c=0,n=0,b=0,k=0,l=0,o=0,h=0,d=0,C=0,g=0;k=f[74]|0;l=f[67]|0;g=k+12|0;f[74]=g;r=w(1)|0;e=f[74]|0;if(!((e|0)==(g|0)?!(I(r)|0):0))C=3;e:do{if((C|0)==3){a:do{switch(r<<16>>16){case 123:{f[74]=e+2;e=w(1)|0;a=f[74]|0;while(1){if(W(e)|0){v(e);e=(f[74]|0)+2|0;f[74]=e}else{q(e)|0;e=f[74]|0}w(1)|0;e=A(a,e)|0;if(e<<16>>16==44){f[74]=(f[74]|0)+2;e=w(1)|0}if(e<<16>>16==125){C=15;break}g=a;a=f[74]|0;if((a|0)==(g|0)){C=12;break}if(a>>>0>(f[75]|0)>>>0){C=14;break}}if((C|0)==12){T();break e}else if((C|0)==14){T();break e}else if((C|0)==15){i[811]=1;f[74]=(f[74]|0)+2;break a}break}case 42:{f[74]=e+2;w(1)|0;g=f[74]|0;A(g,g)|0;break}default:{i[812]=0;switch(r<<16>>16){case 100:{k=e+14|0;f[74]=k;switch((w(1)|0)<<16>>16){case 97:{a=f[74]|0;if((m(a+2|0,80,8)|0)==0?(c=a+10|0,F(s[c>>1]|0)|0):0){f[74]=c;w(0)|0;C=22}break}case 102:{C=22;break}case 99:{a=f[74]|0;if(((m(a+2|0,36,8)|0)==0?(t=a+10|0,g=s[t>>1]|0,V(g)|0|g<<16>>16==123):0)?(f[74]=t,n=w(1)|0,n<<16>>16!=123):0){d=n;C=31}break}default:{}}r:do{if((C|0)==22?(b=f[74]|0,(m(b+2|0,88,14)|0)==0):0){r=b+16|0;a=s[r>>1]|0;if(!(V(a)|0))switch(a<<16>>16){case 40:case 42:break;default:break r}f[74]=r;a=w(1)|0;if(a<<16>>16==42){f[74]=(f[74]|0)+2;a=w(1)|0}if(a<<16>>16!=40){d=a;C=31}}}while(0);if((C|0)==31?(o=f[74]|0,q(d)|0,h=f[74]|0,h>>>0>o>>>0):0){O(e,k,o,h);f[74]=(f[74]|0)+-2;break e}O(e,k,0,0);f[74]=e+12;break e}case 97:{f[74]=e+10;w(0)|0;e=f[74]|0;C=35;break}case 102:{C=35;break}case 99:{if((m(e+2|0,36,8)|0)==0?(a=e+10|0,E(s[a>>1]|0)|0):0){f[74]=a;g=w(1)|0;C=f[74]|0;q(g)|0;g=f[74]|0;O(C,g,C,g);f[74]=(f[74]|0)+-2;break e}e=e+4|0;f[74]=e;break}case 108:case 118:break;default:break e}if((C|0)==35){f[74]=e+16;e=w(1)|0;if(e<<16>>16==42){f[74]=(f[74]|0)+2;e=w(1)|0}C=f[74]|0;q(e)|0;g=f[74]|0;O(C,g,C,g);f[74]=(f[74]|0)+-2;break e}f[74]=e+6;i[812]=0;r=w(1)|0;e=f[74]|0;r=(q(r)|0|32)<<16>>16==123;t=f[74]|0;if(r){f[74]=t+2;g=w(1)|0;e=f[74]|0;q(g)|0}r:while(1){a=f[74]|0;if((a|0)==(e|0))break;O(e,a,e,a);a=w(1)|0;if(r)switch(a<<16>>16){case 93:case 125:break e;default:{}}e=f[74]|0;if(a<<16>>16!=44){C=51;break}f[74]=e+2;a=w(1)|0;e=f[74]|0;switch(a<<16>>16){case 91:case 123:{C=51;break r}default:{}}q(a)|0}if((C|0)==51)f[74]=e+-2;if(!r)break e;f[74]=t+-2;break e}}}while(0);g=(w(1)|0)<<16>>16==102;e=f[74]|0;if(g?(m(e+2|0,74,6)|0)==0:0){f[74]=e+8;u(k,w(1)|0,0);e=(l|0)==0?248:l+16|0;while(1){e=f[e>>2]|0;if(!e)break e;f[e+12>>2]=0;f[e+8>>2]=0;e=e+16|0}}f[74]=e+-2}}while(0);return}function l(){var e=0,a=0,r=0,t=0,c=0,n=0,b=0;b=f[74]|0;c=b+12|0;f[74]=c;e=w(1)|0;t=f[74]|0;e:do{if(e<<16>>16!=46){if(!(e<<16>>16==115&t>>>0>c>>>0)){if(!(e<<16>>16==100&t>>>0>(b+10|0)>>>0)){t=0;n=28;break}if(m(t+2|0,66,8)|0){a=t;e=100;t=0;n=59;break}e=t+10|0;if(!(V(s[e>>1]|0)|0)){a=t;e=100;t=0;n=59;break}f[74]=e;e=w(1)|0;if(e<<16>>16==42){e=42;t=2;n=61;break}f[74]=t;t=0;n=28;break}if((m(t+2|0,56,10)|0)==0?(r=t+12|0,V(s[r>>1]|0)|0):0){f[74]=r;e=w(1)|0;a=f[74]|0;if((a|0)!=(r|0)){if(e<<16>>16!=102){t=1;n=28;break}if(m(a+2|0,74,6)|0){e=102;t=1;n=59;break}if(!(E(s[a+8>>1]|0)|0)){e=102;t=1;n=59;break}}f[74]=t;t=0;n=28}else{a=t;e=115;t=0;n=59}}else{f[74]=t+2;switch((w(1)|0)<<16>>16){case 109:{e=f[74]|0;if(m(e+2|0,50,6)|0)break e;a=f[71]|0;if(!(G(a)|0)?(s[a>>1]|0)==46:0)break e;d(b,b,e+8|0,2);break e}case 115:{e=f[74]|0;if(m(e+2|0,56,10)|0)break e;a=f[71]|0;if(!(G(a)|0)?(s[a>>1]|0)==46:0)break e;f[74]=e+12;e=w(1)|0;t=1;n=28;break e}case 100:{e=f[74]|0;if(m(e+2|0,66,8)|0)break e;a=f[71]|0;if(!(G(a)|0)?(s[a>>1]|0)==46:0)break e;f[74]=e+10;e=w(1)|0;t=2;n=28;break e}default:break e}}}while(0);e:do{if((n|0)==28){if(e<<16>>16==40){r=f[72]|0;a=s[404]|0;c=a&65535;f[r+(c<<3)>>2]=5;e=f[74]|0;s[404]=a+1<<16>>16;f[r+(c<<3)+4>>2]=e;if((s[f[71]>>1]|0)==46)break;f[74]=e+2;a=w(1)|0;d(b,f[74]|0,0,e);if(!t)e=f[65]|0;else{e=f[65]|0;f[e+28>>2]=(t|0)==1?5:7}c=f[73]|0;b=s[403]|0;s[403]=b+1<<16>>16;f[c+((b&65535)<<2)>>2]=e;switch(a<<16>>16){case 39:{v(39);break}case 34:{v(34);break}default:{f[74]=(f[74]|0)+-2;break e}}e=(f[74]|0)+2|0;f[74]=e;switch((w(1)|0)<<16>>16){case 44:{f[74]=(f[74]|0)+2;w(1)|0;c=f[65]|0;f[c+4>>2]=e;b=f[74]|0;f[c+16>>2]=b;i[c+24>>0]=1;f[74]=b+-2;break e}case 41:{s[404]=(s[404]|0)+-1<<16>>16;b=f[65]|0;f[b+4>>2]=e;f[b+12>>2]=(f[74]|0)+2;i[b+24>>0]=1;s[403]=(s[403]|0)+-1<<16>>16;break e}default:{f[74]=(f[74]|0)+-2;break e}}}if(!((t|0)==0&e<<16>>16==123)){switch(e<<16>>16){case 42:case 39:case 34:{n=61;break e}default:{}}a=f[74]|0;n=59;break}e=f[74]|0;if(s[404]|0){f[74]=e+-2;break}while(1){if(e>>>0>=(f[75]|0)>>>0)break;e=w(1)|0;if(!(W(e)|0)){if(e<<16>>16==125){n=49;break}}else v(e);e=(f[74]|0)+2|0;f[74]=e}if((n|0)==49)f[74]=(f[74]|0)+2;c=(w(1)|0)<<16>>16==102;e=f[74]|0;if(c?m(e+2|0,74,6)|0:0){T();break}f[74]=e+8;e=w(1)|0;if(W(e)|0){u(b,e,0);break}else{T();break}}}while(0);if((n|0)==59)if((a|0)==(c|0))f[74]=b+10;else n=61;do{if((n|0)==61){if(!((e<<16>>16==42|(t|0)!=2)&(s[404]|0)==0)){f[74]=(f[74]|0)+-2;break}e=f[75]|0;a=f[74]|0;while(1){if(a>>>0>=e>>>0){n=68;break}r=s[a>>1]|0;if(W(r)|0){n=66;break}n=a+2|0;f[74]=n;a=n}if((n|0)==66){u(b,r,t);break}else if((n|0)==68){T();break}}}while(0);return}function u(e,a,r){e=e|0;a=a|0;r=r|0;var i=0,t=0;i=(f[74]|0)+2|0;switch(a<<16>>16){case 39:{v(39);t=5;break}case 34:{v(34);t=5;break}default:T()}do{if((t|0)==5){d(e,i,f[74]|0,1);if((r|0)>0)f[(f[65]|0)+28>>2]=(r|0)==1?4:6;f[74]=(f[74]|0)+2;a=w(0)|0;r=a<<16>>16==97;if(r){i=f[74]|0;if(m(i+2|0,102,10)|0)t=13}else{i=f[74]|0;if(!(((a<<16>>16==119?(s[i+2>>1]|0)==105:0)?(s[i+4>>1]|0)==116:0)?(s[i+6>>1]|0)==104:0))t=13}if((t|0)==13){f[74]=i+-2;break}f[74]=i+((r?6:4)<<1);if((w(1)|0)<<16>>16!=123){f[74]=i;break}r=f[74]|0;a=r;e:while(1){f[74]=a+2;a=w(1)|0;switch(a<<16>>16){case 39:{v(39);f[74]=(f[74]|0)+2;a=w(1)|0;break}case 34:{v(34);f[74]=(f[74]|0)+2;a=w(1)|0;break}default:a=q(a)|0}if(a<<16>>16!=58){t=22;break}f[74]=(f[74]|0)+2;switch((w(1)|0)<<16>>16){case 39:{v(39);break}case 34:{v(34);break}default:{t=26;break e}}f[74]=(f[74]|0)+2;switch((w(1)|0)<<16>>16){case 125:{t=31;break e}case 44:break;default:{t=30;break e}}f[74]=(f[74]|0)+2;if((w(1)|0)<<16>>16==125){t=31;break}a=f[74]|0}if((t|0)==22){f[74]=i;break}else if((t|0)==26){f[74]=i;break}else if((t|0)==30){f[74]=i;break}else if((t|0)==31){t=f[65]|0;f[t+16>>2]=r;f[t+12>>2]=(f[74]|0)+2;break}}}while(0);return}function o(e){e=e|0;e:do{switch(s[e>>1]|0){case 100:switch(s[e+-2>>1]|0){case 105:{e=$(e+-4|0,112,2)|0;break e}case 108:{e=$(e+-4|0,116,3)|0;break e}default:{e=0;break e}}case 101:switch(s[e+-2>>1]|0){case 115:switch(s[e+-4>>1]|0){case 108:{e=B(e+-6|0,101)|0;break e}case 97:{e=B(e+-6|0,99)|0;break e}default:{e=0;break e}}case 116:{e=$(e+-4|0,122,4)|0;break e}case 117:{e=$(e+-4|0,130,6)|0;break e}default:{e=0;break e}}case 102:{if((s[e+-2>>1]|0)==111?(s[e+-4>>1]|0)==101:0)switch(s[e+-6>>1]|0){case 99:{e=$(e+-8|0,142,6)|0;break e}case 112:{e=$(e+-8|0,154,2)|0;break e}default:{e=0;break e}}else e=0;break}case 107:{e=$(e+-2|0,158,4)|0;break}case 110:{e=e+-2|0;if(B(e,105)|0)e=1;else e=$(e,166,5)|0;break}case 111:{e=B(e+-2|0,100)|0;break}case 114:{e=$(e+-2|0,176,7)|0;break}case 116:{e=$(e+-2|0,190,4)|0;break}case 119:switch(s[e+-2>>1]|0){case 101:{e=B(e+-4|0,110)|0;break e}case 111:{e=$(e+-4|0,198,3)|0;break e}default:{e=0;break e}}default:e=0}}while(0);return e|0}function h(){var e=0,a=0,r=0,i=0;a=f[75]|0;r=f[74]|0;e:while(1){e=r+2|0;if(r>>>0>=a>>>0){a=10;break}switch(s[e>>1]|0){case 96:{a=7;break e}case 36:{if((s[r+4>>1]|0)==123){a=6;break e}break}case 92:{e=r+4|0;break}default:{}}r=e}if((a|0)==6){e=r+4|0;f[74]=e;a=f[72]|0;i=s[404]|0;r=i&65535;f[a+(r<<3)>>2]=4;s[404]=i+1<<16>>16;f[a+(r<<3)+4>>2]=e}else if((a|0)==7){f[74]=e;r=f[72]|0;i=(s[404]|0)+-1<<16>>16;s[404]=i;if((f[r+((i&65535)<<3)>>2]|0)!=3)T()}else if((a|0)==10){f[74]=e;T()}return}function w(e){e=e|0;var a=0,r=0,i=0;r=f[74]|0;e:do{a=s[r>>1]|0;a:do{if(a<<16>>16!=47)if(e)if(V(a)|0)break;else break e;else if(F(a)|0)break;else break e;else switch(s[r+2>>1]|0){case 47:{P();break a}case 42:{y(e);break a}default:{a=47;break e}}}while(0);i=f[74]|0;r=i+2|0;f[74]=r}while(i>>>0<(f[75]|0)>>>0);return a|0}function d(e,a,r,s){e=e|0;a=a|0;r=r|0;s=s|0;var t=0,c=0;c=f[69]|0;f[69]=c+36;t=f[65]|0;f[((t|0)==0?244:t+32|0)>>2]=c;f[66]=t;f[65]=c;f[c+8>>2]=e;if(2==(s|0)){e=3;t=r}else{t=1==(s|0);e=t?1:2;t=t?r+2|0:0}f[c+12>>2]=t;f[c+28>>2]=e;f[c>>2]=a;f[c+4>>2]=r;f[c+16>>2]=0;f[c+20>>2]=s;a=1==(s|0);i[c+24>>0]=a&1;f[c+32>>2]=0;if(a|2==(s|0))i[811]=1;return}function v(e){e=e|0;var a=0,r=0,i=0,t=0;t=f[75]|0;a=f[74]|0;while(1){i=a+2|0;if(a>>>0>=t>>>0){a=9;break}r=s[i>>1]|0;if(r<<16>>16==e<<16>>16){a=10;break}if(r<<16>>16==92){r=a+4|0;if((s[r>>1]|0)==13){a=a+6|0;a=(s[a>>1]|0)==10?a:r}else a=r}else if(Z(r)|0){a=9;break}else a=i}if((a|0)==9){f[74]=i;T()}else if((a|0)==10)f[74]=i;return}function A(e,a){e=e|0;a=a|0;var r=0,i=0,t=0,c=0;r=f[74]|0;i=s[r>>1]|0;c=(e|0)==(a|0);t=c?0:e;c=c?0:a;if(i<<16>>16==97){f[74]=r+4;r=w(1)|0;e=f[74]|0;if(W(r)|0){v(r);a=(f[74]|0)+2|0;f[74]=a}else{q(r)|0;a=f[74]|0}i=w(1)|0;r=f[74]|0}if((r|0)!=(e|0))O(e,a,t,c);return i|0}function C(){var e=0,a=0,r=0;r=f[75]|0;a=f[74]|0;e:while(1){e=a+2|0;if(a>>>0>=r>>>0){a=6;break}switch(s[e>>1]|0){case 13:case 10:{a=6;break e}case 93:{a=7;break e}case 92:{e=a+4|0;break}default:{}}a=e}if((a|0)==6){f[74]=e;T();e=0}else if((a|0)==7){f[74]=e;e=93}return e|0}function g(){var e=0,a=0,r=0;e:while(1){e=f[74]|0;a=e+2|0;f[74]=a;if(e>>>0>=(f[75]|0)>>>0){r=7;break}switch(s[a>>1]|0){case 13:case 10:{r=7;break e}case 47:break e;case 91:{C()|0;break}case 92:{f[74]=e+4;break}default:{}}}if((r|0)==7)T();return}function p(e){e=e|0;switch(s[e>>1]|0){case 62:{e=(s[e+-2>>1]|0)==61;break}case 41:case 59:{e=1;break}case 104:{e=$(e+-2|0,218,4)|0;break}case 121:{e=$(e+-2|0,226,6)|0;break}case 101:{e=$(e+-2|0,238,3)|0;break}default:e=0}return e|0}function y(e){e=e|0;var a=0,r=0,i=0,t=0,c=0;t=(f[74]|0)+2|0;f[74]=t;r=f[75]|0;while(1){a=t+2|0;if(t>>>0>=r>>>0)break;i=s[a>>1]|0;if(!e?Z(i)|0:0)break;if(i<<16>>16==42?(s[t+4>>1]|0)==47:0){c=8;break}t=a}if((c|0)==8){f[74]=a;a=t+4|0}f[74]=a;return}function m(e,a,r){e=e|0;a=a|0;r=r|0;var s=0,f=0;e:do{if(!r)e=0;else{while(1){s=i[e>>0]|0;f=i[a>>0]|0;if(s<<24>>24!=f<<24>>24)break;r=r+-1|0;if(!r){e=0;break e}else{e=e+1|0;a=a+1|0}}e=(s&255)-(f&255)|0}}while(0);return e|0}function I(e){e=e|0;e:do{switch(e<<16>>16){case 38:case 37:case 33:{e=1;break}default:if((e&-8)<<16>>16==40|(e+-58&65535)<6)e=1;else{switch(e<<16>>16){case 91:case 93:case 94:{e=1;break e}default:{}}e=(e+-123&65535)<4}}}while(0);return e|0}function U(e){e=e|0;e:do{switch(e<<16>>16){case 38:case 37:case 33:break;default:if(!((e+-58&65535)<6|(e+-40&65535)<7&e<<16>>16!=41)){switch(e<<16>>16){case 91:case 94:break e;default:{}}return e<<16>>16!=125&(e+-123&65535)<4|0}}}while(0);return 1}function x(e){e=e|0;var a=0;a=s[e>>1]|0;e:do{if((a+-9&65535)>=5){switch(a<<16>>16){case 160:case 32:{a=1;break e}default:{}}if(I(a)|0)return a<<16>>16!=46|(G(e)|0)|0;else a=0}else a=1}while(0);return a|0}function S(e){e=e|0;var a=0,r=0,i=0,t=0;r=n;n=n+16|0;i=r;f[i>>2]=0;f[68]=e;a=f[3]|0;t=a+(e<<1)|0;e=t+2|0;s[t>>1]=0;f[i>>2]=e;f[69]=e;f[61]=0;f[65]=0;f[63]=0;f[62]=0;f[67]=0;f[64]=0;n=r;return a|0}function O(e,a,r,s){e=e|0;a=a|0;r=r|0;s=s|0;var t=0,c=0;t=f[69]|0;f[69]=t+20;c=f[67]|0;f[((c|0)==0?248:c+16|0)>>2]=t;f[67]=t;f[t>>2]=e;f[t+4>>2]=a;f[t+8>>2]=r;f[t+12>>2]=s;f[t+16>>2]=0;i[811]=1;return}function $(e,a,r){e=e|0;a=a|0;r=r|0;var i=0,s=0;i=e+(0-r<<1)|0;s=i+2|0;e=f[3]|0;if(s>>>0>=e>>>0?(m(s,a,r<<1)|0)==0:0)if((s|0)==(e|0))e=1;else e=x(i)|0;else e=0;return e|0}function j(e){e=e|0;switch(s[e>>1]|0){case 107:{e=$(e+-2|0,158,4)|0;break}case 101:{if((s[e+-2>>1]|0)==117)e=$(e+-4|0,130,6)|0;else e=0;break}default:e=0}return e|0}function B(e,a){e=e|0;a=a|0;var r=0;r=f[3]|0;if(r>>>0<=e>>>0?(s[e>>1]|0)==a<<16>>16:0)if((r|0)==(e|0))r=1;else r=E(s[e+-2>>1]|0)|0;else r=0;return r|0}function E(e){e=e|0;e:do{if((e+-9&65535)<5)e=1;else{switch(e<<16>>16){case 32:case 160:{e=1;break e}default:{}}e=e<<16>>16!=46&(I(e)|0)}}while(0);return e|0}function P(){var e=0,a=0,r=0;e=f[75]|0;r=f[74]|0;e:while(1){a=r+2|0;if(r>>>0>=e>>>0)break;switch(s[a>>1]|0){case 13:case 10:break e;default:r=a}}f[74]=a;return}function q(e){e=e|0;while(1){if(V(e)|0)break;if(I(e)|0)break;e=(f[74]|0)+2|0;f[74]=e;e=s[e>>1]|0;if(!(e<<16>>16)){e=0;break}}return e|0}function z(){var e=0;e=f[(f[63]|0)+20>>2]|0;switch(e|0){case 1:{e=-1;break}case 2:{e=-2;break}default:e=e-(f[3]|0)>>1}return e|0}function D(e){e=e|0;if(!($(e,204,5)|0)?!($(e,44,3)|0):0)e=$(e,214,2)|0;else e=1;return e|0}function F(e){e=e|0;switch(e<<16>>16){case 160:case 32:case 12:case 11:case 9:{e=1;break}default:e=0}return e|0}function G(e){e=e|0;if((s[e>>1]|0)==46?(s[e+-2>>1]|0)==46:0)e=(s[e+-4>>1]|0)==46;else e=0;return e|0}function H(e){e=e|0;if((f[3]|0)==(e|0))e=1;else e=x(e+-2|0)|0;return e|0}function J(){var e=0;e=f[(f[64]|0)+12>>2]|0;if(!e)e=-1;else e=e-(f[3]|0)>>1;return e|0}function K(){var e=0;e=f[(f[63]|0)+12>>2]|0;if(!e)e=-1;else e=e-(f[3]|0)>>1;return e|0}function L(){var e=0;e=f[(f[64]|0)+8>>2]|0;if(!e)e=-1;else e=e-(f[3]|0)>>1;return e|0}function M(){var e=0;e=f[(f[63]|0)+16>>2]|0;if(!e)e=-1;else e=e-(f[3]|0)>>1;return e|0}function N(){var e=0;e=f[(f[63]|0)+4>>2]|0;if(!e)e=-1;else e=e-(f[3]|0)>>1;return e|0}function Q(){var e=0;e=f[63]|0;e=f[((e|0)==0?244:e+32|0)>>2]|0;f[63]=e;return(e|0)!=0|0}function R(){var e=0;e=f[64]|0;e=f[((e|0)==0?248:e+16|0)>>2]|0;f[64]=e;return(e|0)!=0|0}function T(){i[810]=1;f[70]=(f[74]|0)-(f[3]|0)>>1;f[74]=(f[75]|0)+2;return}function V(e){e=e|0;return(e|128)<<16>>16==160|(e+-9&65535)<5|0}function W(e){e=e|0;return e<<16>>16==39|e<<16>>16==34|0}function X(){return(f[(f[63]|0)+8>>2]|0)-(f[3]|0)>>1|0}function Y(){return(f[(f[64]|0)+4>>2]|0)-(f[3]|0)>>1|0}function Z(e){e=e|0;return e<<16>>16==13|e<<16>>16==10|0}function _(){return(f[f[63]>>2]|0)-(f[3]|0)>>1|0}function ee(){return(f[f[64]>>2]|0)-(f[3]|0)>>1|0}function ae(){return t[(f[63]|0)+24>>0]|0|0}function re(e){e=e|0;f[3]=e;return}function ie(){return f[(f[63]|0)+28>>2]|0}function se(){return(i[811]|0)!=0|0}function fe(){return(i[812]|0)!=0|0}function te(){return f[70]|0}function ce(e){e=e|0;n=e+992+15&-16;return 992}return{su:ce,ai:M,e:te,ee:Y,ele:J,els:L,es:ee,f:fe,id:z,ie:N,ip:ae,is:_,it:ie,ms:se,p:b,re:R,ri:Q,sa:S,se:K,ses:re,ss:X}}("undefined"!=typeof self?self:global,{},a),r=e.su(i-(2<<17))}const h=t.length+1;e.ses(r),e.sa(h-1),s(t,new Uint16Array(a,r,h)),e.p()||(n=e.e(),o());const w=[],d=[];for(;e.ri();){const a=e.is(),r=e.ie(),i=e.ai(),s=e.id(),f=e.ss(),c=e.se(),n=e.it();let k;e.ip()&&(k=b(-1===s?a:a+1,t.charCodeAt(-1===s?a-1:a))),w.push({t:n,n:k,s:a,e:r,ss:f,se:c,d:s,a:i})}for(;e.re();){const a=e.es(),r=e.ee(),i=e.els(),s=e.ele(),f=t.charCodeAt(a),c=i>=0?t.charCodeAt(i):-1;d.push({s:a,e:r,ls:i,le:s,n:34===f||39===f?b(a+1,f):t.slice(a,r),ln:i<0?void 0:34===c||39===c?b(i+1,c):t.slice(i,s)})}return[w,d,!!e.f(),!!e.ms()]}function b(e,a){n=e;let r="",i=n;for(;;){n>=t.length&&o();const e=t.charCodeAt(n);if(e===a)break;92===e?(r+=t.slice(i,n),r+=k(),i=n):(8232===e||8233===e||u(e)&&o(),++n)}return r+=t.slice(i,n++),r}function k(){let e=t.charCodeAt(++n);switch(++n,e){case 110:return"\n";case 114:return"\r";case 120:return String.fromCharCode(l(2));case 117:return function(){const e=t.charCodeAt(n);let a;123===e?(++n,a=l(t.indexOf("}",n)-n),++n,a>1114111&&o()):a=l(4);return a<=65535?String.fromCharCode(a):(a-=65536,String.fromCharCode(55296+(a>>10),56320+(1023&a)))}();case 116:return"\t";case 98:return"\b";case 118:return"\v";case 102:return"\f";case 13:10===t.charCodeAt(n)&&++n;case 10:return"";case 56:case 57:o();default:if(e>=48&&e<=55){let a=t.substr(n-1,3).match(/^[0-7]+/)[0],r=parseInt(a,8);return r>255&&(a=a.slice(0,-1),r=parseInt(a,8)),n+=a.length-1,e=t.charCodeAt(n),"0"===a&&56!==e&&57!==e||o(),String.fromCharCode(r)}return u(e)?"":String.fromCharCode(e)}}function l(e){const a=n;let r=0,i=0;for(let a=0;a=97)e=s-97+10;else if(s>=65)e=s-65+10;else{if(!(s>=48&&s<=57))break;e=s-48}if(e>=16)break;i=s,r=16*r+e}else 95!==i&&0!==a||o(),i=s}return 95!==i&&n-a===e||o(),r}function u(e){return 13===e||10===e}function o(){throw Object.assign(Error(`Parse error ${c}:${t.slice(0,n).split("\n").length}:${n-t.lastIndexOf("\n",n-1)}`),{idx:n})} diff --git a/node_modules/es-module-lexer/dist/lexer.cjs b/node_modules/es-module-lexer/dist/lexer.cjs new file mode 100644 index 0000000000..4b0c87b1d5 --- /dev/null +++ b/node_modules/es-module-lexer/dist/lexer.cjs @@ -0,0 +1 @@ +"use strict";var ImportType;exports.initSync=exports.init=exports.ImportType=void 0,exports.parse=parse,exports.ImportType=ImportType,function(A){A[A.Static=1]="Static",A[A.Dynamic=2]="Dynamic",A[A.ImportMeta=3]="ImportMeta",A[A.StaticSourcePhase=4]="StaticSourcePhase",A[A.DynamicSourcePhase=5]="DynamicSourcePhase",A[A.StaticDeferPhase=6]="StaticDeferPhase",A[A.DynamicDeferPhase=7]="DynamicDeferPhase"}(ImportType||(exports.ImportType=ImportType={}));const A=1===new Uint8Array(new Uint16Array([1]).buffer)[0];function parse(E,g="@"){if(!C)return init.then((()=>parse(E)));const I=E.length+1,w=(C.__heap_base.value||C.__heap_base)+4*I-C.memory.buffer.byteLength;w>0&&C.memory.grow(Math.ceil(w/65536));const K=C.sa(I-1);if((A?B:Q)(E,new Uint16Array(C.memory.buffer,K,I)),!C.parse())throw Object.assign(new Error(`Parse error ${g}:${E.slice(0,C.e()).split("\n").length}:${C.e()-E.lastIndexOf("\n",C.e()-1)}`),{idx:C.e()});const o=[],D=[];for(;C.ri();){const A=C.is(),Q=C.ie(),B=C.it(),g=C.ai(),I=C.id(),w=C.ss(),K=C.se();let D;C.ip()&&(D=k(E.slice(-1===I?A-1:A,-1===I?Q+1:Q))),o.push({n:D,t:B,s:A,e:Q,ss:w,se:K,d:I,a:g})}for(;C.re();){const A=C.es(),Q=C.ee(),B=C.els(),g=C.ele(),I=E.slice(A,Q),w=I[0],K=B<0?void 0:E.slice(B,g),o=K?K[0]:"";D.push({s:A,e:Q,ls:B,le:g,n:'"'===w||"'"===w?k(I):I,ln:'"'===o||"'"===o?k(K):K})}function k(A){try{return(0,eval)(A)}catch(A){}}return[o,D,!!C.f(),!!C.ms()]}function Q(A,Q){const C=A.length;let B=0;for(;B>>8}}function B(A,Q){const C=A.length;let B=0;for(;B{return A="AGFzbQEAAAABKwhgAX8Bf2AEf39/fwBgAAF/YAAAYAF/AGADf39/AX9gAn9/AX9gA39/fwADMTAAAQECAgICAgICAgICAgICAgICAgIAAwMDBAQAAAUAAAAAAAMDAwAGAAAABwAGAgUEBQFwAQEBBQMBAAEGDwJ/AUHA8gALfwBBwPIACwd6FQZtZW1vcnkCAAJzYQAAAWUAAwJpcwAEAmllAAUCc3MABgJzZQAHAml0AAgCYWkACQJpZAAKAmlwAAsCZXMADAJlZQANA2VscwAOA2VsZQAPAnJpABACcmUAEQFmABICbXMAEwVwYXJzZQAUC19faGVhcF9iYXNlAwEKzkQwaAEBf0EAIAA2AoAKQQAoAtwJIgEgAEEBdGoiAEEAOwEAQQAgAEECaiIANgKECkEAIAA2AogKQQBBADYC4AlBAEEANgLwCUEAQQA2AugJQQBBADYC5AlBAEEANgL4CUEAQQA2AuwJIAEL0wEBA39BACgC8AkhBEEAQQAoAogKIgU2AvAJQQAgBDYC9AlBACAFQSRqNgKICiAEQSBqQeAJIAQbIAU2AgBBACgC1AkhBEEAKALQCSEGIAUgATYCACAFIAA2AgggBSACIAJBAmpBACAGIANGIgAbIAQgA0YiBBs2AgwgBSADNgIUIAVBADYCECAFIAI2AgQgBUEANgIgIAVBA0EBQQIgABsgBBs2AhwgBUEAKALQCSADRiICOgAYAkACQCACDQBBACgC1AkgA0cNAQtBAEEBOgCMCgsLXgEBf0EAKAL4CSIEQRBqQeQJIAQbQQAoAogKIgQ2AgBBACAENgL4CUEAIARBFGo2AogKQQBBAToAjAogBEEANgIQIAQgAzYCDCAEIAI2AgggBCABNgIEIAQgADYCAAsIAEEAKAKQCgsVAEEAKALoCSgCAEEAKALcCWtBAXULHgEBf0EAKALoCSgCBCIAQQAoAtwJa0EBdUF/IAAbCxUAQQAoAugJKAIIQQAoAtwJa0EBdQseAQF/QQAoAugJKAIMIgBBACgC3AlrQQF1QX8gABsLCwBBACgC6AkoAhwLHgEBf0EAKALoCSgCECIAQQAoAtwJa0EBdUF/IAAbCzsBAX8CQEEAKALoCSgCFCIAQQAoAtAJRw0AQX8PCwJAIABBACgC1AlHDQBBfg8LIABBACgC3AlrQQF1CwsAQQAoAugJLQAYCxUAQQAoAuwJKAIAQQAoAtwJa0EBdQsVAEEAKALsCSgCBEEAKALcCWtBAXULHgEBf0EAKALsCSgCCCIAQQAoAtwJa0EBdUF/IAAbCx4BAX9BACgC7AkoAgwiAEEAKALcCWtBAXVBfyAAGwslAQF/QQBBACgC6AkiAEEgakHgCSAAGygCACIANgLoCSAAQQBHCyUBAX9BAEEAKALsCSIAQRBqQeQJIAAbKAIAIgA2AuwJIABBAEcLCABBAC0AlAoLCABBAC0AjAoL3Q0BBX8jAEGA0ABrIgAkAEEAQQE6AJQKQQBBACgC2Ak2ApwKQQBBACgC3AlBfmoiATYCsApBACABQQAoAoAKQQF0aiICNgK0CkEAQQA6AIwKQQBBADsBlgpBAEEAOwGYCkEAQQA6AKAKQQBBADYCkApBAEEAOgD8CUEAIABBgBBqNgKkCkEAIAA2AqgKQQBBADoArAoCQAJAAkACQANAQQAgAUECaiIDNgKwCiABIAJPDQECQCADLwEAIgJBd2pBBUkNAAJAAkACQAJAAkAgAkGbf2oOBQEICAgCAAsgAkEgRg0EIAJBL0YNAyACQTtGDQIMBwtBAC8BmAoNASADEBVFDQEgAUEEakGCCEEKEC8NARAWQQAtAJQKDQFBAEEAKAKwCiIBNgKcCgwHCyADEBVFDQAgAUEEakGMCEEKEC8NABAXC0EAQQAoArAKNgKcCgwBCwJAIAEvAQQiA0EqRg0AIANBL0cNBBAYDAELQQEQGQtBACgCtAohAkEAKAKwCiEBDAALC0EAIQIgAyEBQQAtAPwJDQIMAQtBACABNgKwCkEAQQA6AJQKCwNAQQAgAUECaiIDNgKwCgJAAkACQAJAAkACQAJAIAFBACgCtApPDQAgAy8BACICQXdqQQVJDQYCQAJAAkACQAJAAkACQAJAAkACQCACQWBqDgoQDwYPDw8PBQECAAsCQAJAAkACQCACQaB/ag4KCxISAxIBEhISAgALIAJBhX9qDgMFEQYJC0EALwGYCg0QIAMQFUUNECABQQRqQYIIQQoQLw0QEBYMEAsgAxAVRQ0PIAFBBGpBjAhBChAvDQ8QFwwPCyADEBVFDQ4gASkABELsgISDsI7AOVINDiABLwEMIgNBd2oiAUEXSw0MQQEgAXRBn4CABHFFDQwMDQtBAEEALwGYCiIBQQFqOwGYCkEAKAKkCiABQQN0aiIBQQE2AgAgAUEAKAKcCjYCBAwNC0EALwGYCiIDRQ0JQQAgA0F/aiIDOwGYCkEALwGWCiICRQ0MQQAoAqQKIANB//8DcUEDdGooAgBBBUcNDAJAIAJBAnRBACgCqApqQXxqKAIAIgMoAgQNACADQQAoApwKQQJqNgIEC0EAIAJBf2o7AZYKIAMgAUEEajYCDAwMCwJAQQAoApwKIgEvAQBBKUcNAEEAKALwCSIDRQ0AIAMoAgQgAUcNAEEAQQAoAvQJIgM2AvAJAkAgA0UNACADQQA2AiAMAQtBAEEANgLgCQtBAEEALwGYCiIDQQFqOwGYCkEAKAKkCiADQQN0aiIDQQZBAkEALQCsChs2AgAgAyABNgIEQQBBADoArAoMCwtBAC8BmAoiAUUNB0EAIAFBf2oiATsBmApBACgCpAogAUH//wNxQQN0aigCAEEERg0EDAoLQScQGgwJC0EiEBoMCAsgAkEvRw0HAkACQCABLwEEIgFBKkYNACABQS9HDQEQGAwKC0EBEBkMCQsCQAJAAkACQEEAKAKcCiIBLwEAIgMQG0UNAAJAAkAgA0FVag4EAAkBAwkLIAFBfmovAQBBK0YNAwwICyABQX5qLwEAQS1GDQIMBwsgA0EpRw0BQQAoAqQKQQAvAZgKIgJBA3RqKAIEEBxFDQIMBgsgAUF+ai8BAEFQakH//wNxQQpPDQULQQAvAZgKIQILAkACQCACQf//A3EiAkUNACADQeYARw0AQQAoAqQKIAJBf2pBA3RqIgQoAgBBAUcNACABQX5qLwEAQe8ARw0BIAQoAgRBlghBAxAdRQ0BDAULIANB/QBHDQBBACgCpAogAkEDdGoiAigCBBAeDQQgAigCAEEGRg0ECyABEB8NAyADRQ0DIANBL0ZBAC0AoApBAEdxDQMCQEEAKAL4CSICRQ0AIAEgAigCAEkNACABIAIoAgRNDQQLIAFBfmohAUEAKALcCSECAkADQCABQQJqIgQgAk0NAUEAIAE2ApwKIAEvAQAhAyABQX5qIgQhASADECBFDQALIARBAmohBAsCQCADQf//A3EQIUUNACAEQX5qIQECQANAIAFBAmoiAyACTQ0BQQAgATYCnAogAS8BACEDIAFBfmoiBCEBIAMQIQ0ACyAEQQJqIQMLIAMQIg0EC0EAQQE6AKAKDAcLQQAoAqQKQQAvAZgKIgFBA3QiA2pBACgCnAo2AgRBACABQQFqOwGYCkEAKAKkCiADakEDNgIACxAjDAULQQAtAPwJQQAvAZYKQQAvAZgKcnJFIQIMBwsQJEEAQQA6AKAKDAMLECVBACECDAULIANBoAFHDQELQQBBAToArAoLQQBBACgCsAo2ApwKC0EAKAKwCiEBDAALCyAAQYDQAGokACACCxoAAkBBACgC3AkgAEcNAEEBDwsgAEF+ahAmC/4KAQZ/QQBBACgCsAoiAEEMaiIBNgKwCkEAKAL4CSECQQEQKSEDAkACQAJAAkACQAJAAkACQAJAQQAoArAKIgQgAUcNACADEChFDQELAkACQAJAAkACQAJAAkAgA0EqRg0AIANB+wBHDQFBACAEQQJqNgKwCkEBECkhA0EAKAKwCiEEA0ACQAJAIANB//8DcSIDQSJGDQAgA0EnRg0AIAMQLBpBACgCsAohAwwBCyADEBpBAEEAKAKwCkECaiIDNgKwCgtBARApGgJAIAQgAxAtIgNBLEcNAEEAQQAoArAKQQJqNgKwCkEBECkhAwsgA0H9AEYNA0EAKAKwCiIFIARGDQ8gBSEEIAVBACgCtApNDQAMDwsLQQAgBEECajYCsApBARApGkEAKAKwCiIDIAMQLRoMAgtBAEEAOgCUCgJAAkACQAJAAkACQCADQZ9/ag4MAgsEAQsDCwsLCwsFAAsgA0H2AEYNBAwKC0EAIARBDmoiAzYCsAoCQAJAAkBBARApQZ9/ag4GABICEhIBEgtBACgCsAoiBSkAAkLzgOSD4I3AMVINESAFLwEKECFFDRFBACAFQQpqNgKwCkEAECkaC0EAKAKwCiIFQQJqQbIIQQ4QLw0QIAUvARAiAkF3aiIBQRdLDQ1BASABdEGfgIAEcUUNDQwOC0EAKAKwCiIFKQACQuyAhIOwjsA5Ug0PIAUvAQoiAkF3aiIBQRdNDQYMCgtBACAEQQpqNgKwCkEAECkaQQAoArAKIQQLQQAgBEEQajYCsAoCQEEBECkiBEEqRw0AQQBBACgCsApBAmo2ArAKQQEQKSEEC0EAKAKwCiEDIAQQLBogA0EAKAKwCiIEIAMgBBACQQBBACgCsApBfmo2ArAKDwsCQCAEKQACQuyAhIOwjsA5Ug0AIAQvAQoQIEUNAEEAIARBCmo2ArAKQQEQKSEEQQAoArAKIQMgBBAsGiADQQAoArAKIgQgAyAEEAJBAEEAKAKwCkF+ajYCsAoPC0EAIARBBGoiBDYCsAoLQQAgBEEGajYCsApBAEEAOgCUCkEBECkhBEEAKAKwCiEDIAQQLCEEQQAoArAKIQIgBEHf/wNxIgFB2wBHDQNBACACQQJqNgKwCkEBECkhBUEAKAKwCiEDQQAhBAwEC0EAQQE6AIwKQQBBACgCsApBAmo2ArAKC0EBECkhBEEAKAKwCiEDAkAgBEHmAEcNACADQQJqQawIQQYQLw0AQQAgA0EIajYCsAogAEEBEClBABArIAJBEGpB5AkgAhshAwNAIAMoAgAiA0UNBSADQgA3AgggA0EQaiEDDAALC0EAIANBfmo2ArAKDAMLQQEgAXRBn4CABHFFDQMMBAtBASEECwNAAkACQCAEDgIAAQELIAVB//8DcRAsGkEBIQQMAQsCQAJAQQAoArAKIgQgA0YNACADIAQgAyAEEAJBARApIQQCQCABQdsARw0AIARBIHJB/QBGDQQLQQAoArAKIQMCQCAEQSxHDQBBACADQQJqNgKwCkEBECkhBUEAKAKwCiEDIAVBIHJB+wBHDQILQQAgA0F+ajYCsAoLIAFB2wBHDQJBACACQX5qNgKwCg8LQQAhBAwACwsPCyACQaABRg0AIAJB+wBHDQQLQQAgBUEKajYCsApBARApIgVB+wBGDQMMAgsCQCACQVhqDgMBAwEACyACQaABRw0CC0EAIAVBEGo2ArAKAkBBARApIgVBKkcNAEEAQQAoArAKQQJqNgKwCkEBECkhBQsgBUEoRg0BC0EAKAKwCiEBIAUQLBpBACgCsAoiBSABTQ0AIAQgAyABIAUQAkEAQQAoArAKQX5qNgKwCg8LIAQgA0EAQQAQAkEAIARBDGo2ArAKDwsQJQuFDAEKf0EAQQAoArAKIgBBDGoiATYCsApBARApIQJBACgCsAohAwJAAkACQAJAAkACQAJAAkAgAkEuRw0AQQAgA0ECajYCsAoCQEEBECkiAkHkAEYNAAJAIAJB8wBGDQAgAkHtAEcNB0EAKAKwCiICQQJqQZwIQQYQLw0HAkBBACgCnAoiAxAqDQAgAy8BAEEuRg0ICyAAIAAgAkEIakEAKALUCRABDwtBACgCsAoiAkECakGiCEEKEC8NBgJAQQAoApwKIgMQKg0AIAMvAQBBLkYNBwtBACEEQQAgAkEMajYCsApBASEFQQUhBkEBECkhAkEAIQdBASEIDAILQQAoArAKIgIpAAJC5YCYg9CMgDlSDQUCQEEAKAKcCiIDECoNACADLwEAQS5GDQYLQQAhBEEAIAJBCmo2ArAKQQIhCEEHIQZBASEHQQEQKSECQQEhBQwBCwJAAkACQAJAIAJB8wBHDQAgAyABTQ0AIANBAmpBoghBChAvDQACQCADLwEMIgRBd2oiB0EXSw0AQQEgB3RBn4CABHENAgsgBEGgAUYNAQtBACEHQQchBkEBIQQgAkHkAEYNAQwCC0EAIQRBACADQQxqIgI2ArAKQQEhBUEBECkhCQJAQQAoArAKIgYgAkYNAEHmACECAkAgCUHmAEYNAEEFIQZBACEHQQEhCCAJIQIMBAtBACEHQQEhCCAGQQJqQawIQQYQLw0EIAYvAQgQIEUNBAtBACEHQQAgAzYCsApBByEGQQEhBEEAIQVBACEIIAkhAgwCCyADIABBCmpNDQBBACEIQeQAIQICQCADKQACQuWAmIPQjIA5Ug0AAkACQCADLwEKIgRBd2oiB0EXSw0AQQEgB3RBn4CABHENAQtBACEIIARBoAFHDQELQQAhBUEAIANBCmo2ArAKQSohAkEBIQdBAiEIQQEQKSIJQSpGDQRBACADNgKwCkEBIQRBACEHQQAhCCAJIQIMAgsgAyEGQQAhBwwCC0EAIQVBACEICwJAIAJBKEcNAEEAKAKkCkEALwGYCiICQQN0aiIDQQAoArAKNgIEQQAgAkEBajsBmAogA0EFNgIAQQAoApwKLwEAQS5GDQRBAEEAKAKwCiIDQQJqNgKwCkEBECkhAiAAQQAoArAKQQAgAxABAkACQCAFDQBBACgC8AkhAQwBC0EAKALwCSIBIAY2AhwLQQBBAC8BlgoiA0EBajsBlgpBACgCqAogA0ECdGogATYCAAJAIAJBIkYNACACQSdGDQBBAEEAKAKwCkF+ajYCsAoPCyACEBpBAEEAKAKwCkECaiICNgKwCgJAAkACQEEBEClBV2oOBAECAgACC0EAQQAoArAKQQJqNgKwCkEBECkaQQAoAvAJIgMgAjYCBCADQQE6ABggA0EAKAKwCiICNgIQQQAgAkF+ajYCsAoPC0EAKALwCSIDIAI2AgQgA0EBOgAYQQBBAC8BmApBf2o7AZgKIANBACgCsApBAmo2AgxBAEEALwGWCkF/ajsBlgoPC0EAQQAoArAKQX5qNgKwCg8LAkAgBEEBcyACQfsAR3INAEEAKAKwCiECQQAvAZgKDQUDQAJAAkACQCACQQAoArQKTw0AQQEQKSICQSJGDQEgAkEnRg0BIAJB/QBHDQJBAEEAKAKwCkECajYCsAoLQQEQKSEDQQAoArAKIQICQCADQeYARw0AIAJBAmpBrAhBBhAvDQcLQQAgAkEIajYCsAoCQEEBECkiAkEiRg0AIAJBJ0cNBwsgACACQQAQKw8LIAIQGgtBAEEAKAKwCkECaiICNgKwCgwACwsCQAJAIAJBWWoOBAMBAQMACyACQSJGDQILQQAoArAKIQYLIAYgAUcNAEEAIABBCmo2ArAKDwsgAkEqRyAHcQ0DQQAvAZgKQf//A3ENA0EAKAKwCiECQQAoArQKIQEDQCACIAFPDQECQAJAIAIvAQAiA0EnRg0AIANBIkcNAQsgACADIAgQKw8LQQAgAkECaiICNgKwCgwACwsQJQsPC0EAIAJBfmo2ArAKDwtBAEEAKAKwCkF+ajYCsAoLRwEDf0EAKAKwCkECaiEAQQAoArQKIQECQANAIAAiAkF+aiABTw0BIAJBAmohACACLwEAQXZqDgQBAAABAAsLQQAgAjYCsAoLmAEBA39BAEEAKAKwCiIBQQJqNgKwCiABQQZqIQFBACgCtAohAgNAAkACQAJAIAFBfGogAk8NACABQX5qLwEAIQMCQAJAIAANACADQSpGDQEgA0F2ag4EAgQEAgQLIANBKkcNAwsgAS8BAEEvRw0CQQAgAUF+ajYCsAoMAQsgAUF+aiEBC0EAIAE2ArAKDwsgAUECaiEBDAALC4gBAQR/QQAoArAKIQFBACgCtAohAgJAAkADQCABIgNBAmohASADIAJPDQEgAS8BACIEIABGDQICQCAEQdwARg0AIARBdmoOBAIBAQIBCyADQQRqIQEgAy8BBEENRw0AIANBBmogASADLwEGQQpGGyEBDAALC0EAIAE2ArAKECUPC0EAIAE2ArAKC2wBAX8CQAJAIABBX2oiAUEFSw0AQQEgAXRBMXENAQsgAEFGakH//wNxQQZJDQAgAEEpRyAAQVhqQf//A3FBB0lxDQACQCAAQaV/ag4EAQAAAQALIABB/QBHIABBhX9qQf//A3FBBElxDwtBAQsuAQF/QQEhAQJAIABBpglBBRAdDQAgAEGWCEEDEB0NACAAQbAJQQIQHSEBCyABC0YBA39BACEDAkAgACACQQF0IgJrIgRBAmoiAEEAKALcCSIFSQ0AIAAgASACEC8NAAJAIAAgBUcNAEEBDwsgBBAmIQMLIAMLgwEBAn9BASEBAkACQAJAAkACQAJAIAAvAQAiAkFFag4EBQQEAQALAkAgAkGbf2oOBAMEBAIACyACQSlGDQQgAkH5AEcNAyAAQX5qQbwJQQYQHQ8LIABBfmovAQBBPUYPCyAAQX5qQbQJQQQQHQ8LIABBfmpByAlBAxAdDwtBACEBCyABC7QDAQJ/QQAhAQJAAkACQAJAAkACQAJAAkACQAJAIAAvAQBBnH9qDhQAAQIJCQkJAwkJBAUJCQYJBwkJCAkLAkACQCAAQX5qLwEAQZd/ag4EAAoKAQoLIABBfGpByghBAhAdDwsgAEF8akHOCEEDEB0PCwJAAkACQCAAQX5qLwEAQY1/ag4DAAECCgsCQCAAQXxqLwEAIgJB4QBGDQAgAkHsAEcNCiAAQXpqQeUAECcPCyAAQXpqQeMAECcPCyAAQXxqQdQIQQQQHQ8LIABBfGpB3AhBBhAdDwsgAEF+ai8BAEHvAEcNBiAAQXxqLwEAQeUARw0GAkAgAEF6ai8BACICQfAARg0AIAJB4wBHDQcgAEF4akHoCEEGEB0PCyAAQXhqQfQIQQIQHQ8LIABBfmpB+AhBBBAdDwtBASEBIABBfmoiAEHpABAnDQQgAEGACUEFEB0PCyAAQX5qQeQAECcPCyAAQX5qQYoJQQcQHQ8LIABBfmpBmAlBBBAdDwsCQCAAQX5qLwEAIgJB7wBGDQAgAkHlAEcNASAAQXxqQe4AECcPCyAAQXxqQaAJQQMQHSEBCyABCzQBAX9BASEBAkAgAEF3akH//wNxQQVJDQAgAEGAAXJBoAFGDQAgAEEuRyAAEChxIQELIAELMAEBfwJAAkAgAEF3aiIBQRdLDQBBASABdEGNgIAEcQ0BCyAAQaABRg0AQQAPC0EBC04BAn9BACEBAkACQCAALwEAIgJB5QBGDQAgAkHrAEcNASAAQX5qQfgIQQQQHQ8LIABBfmovAQBB9QBHDQAgAEF8akHcCEEGEB0hAQsgAQveAQEEf0EAKAKwCiEAQQAoArQKIQECQAJAAkADQCAAIgJBAmohACACIAFPDQECQAJAAkAgAC8BACIDQaR/ag4FAgMDAwEACyADQSRHDQIgAi8BBEH7AEcNAkEAIAJBBGoiADYCsApBAEEALwGYCiICQQFqOwGYCkEAKAKkCiACQQN0aiICQQQ2AgAgAiAANgIEDwtBACAANgKwCkEAQQAvAZgKQX9qIgA7AZgKQQAoAqQKIABB//8DcUEDdGooAgBBA0cNAwwECyACQQRqIQAMAAsLQQAgADYCsAoLECULC3ABAn8CQAJAA0BBAEEAKAKwCiIAQQJqIgE2ArAKIABBACgCtApPDQECQAJAAkAgAS8BACIBQaV/ag4CAQIACwJAIAFBdmoOBAQDAwQACyABQS9HDQIMBAsQLhoMAQtBACAAQQRqNgKwCgwACwsQJQsLNQEBf0EAQQE6APwJQQAoArAKIQBBAEEAKAK0CkECajYCsApBACAAQQAoAtwJa0EBdTYCkAoLQwECf0EBIQECQCAALwEAIgJBd2pB//8DcUEFSQ0AIAJBgAFyQaABRg0AQQAhASACEChFDQAgAkEuRyAAECpyDwsgAQs9AQJ/QQAhAgJAQQAoAtwJIgMgAEsNACAALwEAIAFHDQACQCADIABHDQBBAQ8LIABBfmovAQAQICECCyACC2gBAn9BASEBAkACQCAAQV9qIgJBBUsNAEEBIAJ0QTFxDQELIABB+P8DcUEoRg0AIABBRmpB//8DcUEGSQ0AAkAgAEGlf2oiAkEDSw0AIAJBAUcNAQsgAEGFf2pB//8DcUEESSEBCyABC5wBAQN/QQAoArAKIQECQANAAkACQCABLwEAIgJBL0cNAAJAIAEvAQIiAUEqRg0AIAFBL0cNBBAYDAILIAAQGQwBCwJAAkAgAEUNACACQXdqIgFBF0sNAUEBIAF0QZ+AgARxRQ0BDAILIAIQIUUNAwwBCyACQaABRw0CC0EAQQAoArAKIgNBAmoiATYCsAogA0EAKAK0CkkNAAsLIAILMQEBf0EAIQECQCAALwEAQS5HDQAgAEF+ai8BAEEuRw0AIABBfGovAQBBLkYhAQsgAQumBAEBfwJAIAFBIkYNACABQSdGDQAQJQ8LQQAoArAKIQMgARAaIAAgA0ECakEAKAKwCkEAKALQCRABAkAgAkEBSA0AQQAoAvAJQQRBBiACQQFGGzYCHAtBAEEAKAKwCkECajYCsAoCQAJAAkACQEEAECkiAUHhAEYNACABQfcARg0BQQAoArAKIQEMAgtBACgCsAoiAUECakHACEEKEC8NAUEGIQIMAgtBACgCsAoiAS8BAkHpAEcNACABLwEEQfQARw0AQQQhAiABLwEGQegARg0BC0EAIAFBfmo2ArAKDwtBACABIAJBAXRqNgKwCgJAQQEQKUH7AEYNAEEAIAE2ArAKDwtBACgCsAoiACECA0BBACACQQJqNgKwCgJAAkACQEEBECkiAkEiRg0AIAJBJ0cNAUEnEBpBAEEAKAKwCkECajYCsApBARApIQIMAgtBIhAaQQBBACgCsApBAmo2ArAKQQEQKSECDAELIAIQLCECCwJAIAJBOkYNAEEAIAE2ArAKDwtBAEEAKAKwCkECajYCsAoCQEEBECkiAkEiRg0AIAJBJ0YNAEEAIAE2ArAKDwsgAhAaQQBBACgCsApBAmo2ArAKAkACQEEBECkiAkEsRg0AIAJB/QBGDQFBACABNgKwCg8LQQBBACgCsApBAmo2ArAKQQEQKUH9AEYNAEEAKAKwCiECDAELC0EAKALwCSIBIAA2AhAgAUEAKAKwCkECajYCDAttAQJ/AkACQANAAkAgAEH//wNxIgFBd2oiAkEXSw0AQQEgAnRBn4CABHENAgsgAUGgAUYNASAAIQIgARAoDQJBACECQQBBACgCsAoiAEECajYCsAogAC8BAiIADQAMAgsLIAAhAgsgAkH//wNxC6sBAQR/AkACQEEAKAKwCiICLwEAIgNB4QBGDQAgASEEIAAhBQwBC0EAIAJBBGo2ArAKQQEQKSECQQAoArAKIQUCQAJAIAJBIkYNACACQSdGDQAgAhAsGkEAKAKwCiEEDAELIAIQGkEAQQAoArAKQQJqIgQ2ArAKC0EBECkhA0EAKAKwCiECCwJAIAIgBUYNACAFIARBACAAIAAgAUYiAhtBACABIAIbEAILIAMLcgEEf0EAKAKwCiEAQQAoArQKIQECQAJAA0AgAEECaiECIAAgAU8NAQJAAkAgAi8BACIDQaR/ag4CAQQACyACIQAgA0F2ag4EAgEBAgELIABBBGohAAwACwtBACACNgKwChAlQQAPC0EAIAI2ArAKQd0AC0kBA39BACEDAkAgAkUNAAJAA0AgAC0AACIEIAEtAAAiBUcNASABQQFqIQEgAEEBaiEAIAJBf2oiAg0ADAILCyAEIAVrIQMLIAMLC+wBAgBBgAgLzgEAAHgAcABvAHIAdABtAHAAbwByAHQAZgBvAHIAZQB0AGEAbwB1AHIAYwBlAHIAbwBtAHUAbgBjAHQAaQBvAG4AcwBzAGUAcgB0AHYAbwB5AGkAZQBkAGUAbABlAGMAbwBuAHQAaQBuAGkAbgBzAHQAYQBuAHQAeQBiAHIAZQBhAHIAZQB0AHUAcgBkAGUAYgB1AGcAZwBlAGEAdwBhAGkAdABoAHIAdwBoAGkAbABlAGkAZgBjAGEAdABjAGYAaQBuAGEAbABsAGUAbABzAABB0AkLEAEAAAACAAAAAAQAAEA5AAA=","undefined"!=typeof Buffer?Buffer.from(A,"base64"):Uint8Array.from(atob(A),(A=>A.charCodeAt(0)));var A},init=WebAssembly.compile(E()).then(WebAssembly.instantiate).then((({exports:A})=>{C=A}));exports.init=init;const initSync=()=>{if(C)return;const A=new WebAssembly.Module(E());C=new WebAssembly.Instance(A).exports};exports.initSync=initSync; \ No newline at end of file diff --git a/node_modules/es-module-lexer/dist/lexer.js b/node_modules/es-module-lexer/dist/lexer.js new file mode 100644 index 0000000000..6f9404d45f --- /dev/null +++ b/node_modules/es-module-lexer/dist/lexer.js @@ -0,0 +1,2 @@ +/* es-module-lexer 1.7.0 */ +export var ImportType;!function(A){A[A.Static=1]="Static",A[A.Dynamic=2]="Dynamic",A[A.ImportMeta=3]="ImportMeta",A[A.StaticSourcePhase=4]="StaticSourcePhase",A[A.DynamicSourcePhase=5]="DynamicSourcePhase",A[A.StaticDeferPhase=6]="StaticDeferPhase",A[A.DynamicDeferPhase=7]="DynamicDeferPhase"}(ImportType||(ImportType={}));const A=1===new Uint8Array(new Uint16Array([1]).buffer)[0];export function parse(E,g="@"){if(!C)return init.then((()=>parse(E)));const I=E.length+1,w=(C.__heap_base.value||C.__heap_base)+4*I-C.memory.buffer.byteLength;w>0&&C.memory.grow(Math.ceil(w/65536));const K=C.sa(I-1);if((A?B:Q)(E,new Uint16Array(C.memory.buffer,K,I)),!C.parse())throw Object.assign(new Error(`Parse error ${g}:${E.slice(0,C.e()).split("\n").length}:${C.e()-E.lastIndexOf("\n",C.e()-1)}`),{idx:C.e()});const o=[],D=[];for(;C.ri();){const A=C.is(),Q=C.ie(),B=C.it(),g=C.ai(),I=C.id(),w=C.ss(),K=C.se();let D;C.ip()&&(D=k(E.slice(-1===I?A-1:A,-1===I?Q+1:Q))),o.push({n:D,t:B,s:A,e:Q,ss:w,se:K,d:I,a:g})}for(;C.re();){const A=C.es(),Q=C.ee(),B=C.els(),g=C.ele(),I=E.slice(A,Q),w=I[0],K=B<0?void 0:E.slice(B,g),o=K?K[0]:"";D.push({s:A,e:Q,ls:B,le:g,n:'"'===w||"'"===w?k(I):I,ln:'"'===o||"'"===o?k(K):K})}function k(A){try{return(0,eval)(A)}catch(A){}}return[o,D,!!C.f(),!!C.ms()]}function Q(A,Q){const B=A.length;let C=0;for(;C>>8}}function B(A,Q){const B=A.length;let C=0;for(;C{return A="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GzYCHAtBAEEAKAKwCkECajYCsAoCQAJAAkACQEEAECkiAUHhAEYNACABQfcARg0BQQAoArAKIQEMAgtBACgCsAoiAUECakHACEEKEC8NAUEGIQIMAgtBACgCsAoiAS8BAkHpAEcNACABLwEEQfQARw0AQQQhAiABLwEGQegARg0BC0EAIAFBfmo2ArAKDwtBACABIAJBAXRqNgKwCgJAQQEQKUH7AEYNAEEAIAE2ArAKDwtBACgCsAoiACECA0BBACACQQJqNgKwCgJAAkACQEEBECkiAkEiRg0AIAJBJ0cNAUEnEBpBAEEAKAKwCkECajYCsApBARApIQIMAgtBIhAaQQBBACgCsApBAmo2ArAKQQEQKSECDAELIAIQLCECCwJAIAJBOkYNAEEAIAE2ArAKDwtBAEEAKAKwCkECajYCsAoCQEEBECkiAkEiRg0AIAJBJ0YNAEEAIAE2ArAKDwsgAhAaQQBBACgCsApBAmo2ArAKAkACQEEBECkiAkEsRg0AIAJB/QBGDQFBACABNgKwCg8LQQBBACgCsApBAmo2ArAKQQEQKUH9AEYNAEEAKAKwCiECDAELC0EAKALwCSIBIAA2AhAgAUEAKAKwCkECajYCDAttAQJ/AkACQANAAkAgAEH//wNxIgFBd2oiAkEXSw0AQQEgAnRBn4CABHENAgsgAUGgAUYNASAAIQIgARAoDQJBACECQQBBACgCsAoiAEECajYCsAogAC8BAiIADQAMAgsLIAAhAgsgAkH//wNxC6sBAQR/AkACQEEAKAKwCiICLwEAIgNB4QBGDQAgASEEIAAhBQwBC0EAIAJBBGo2ArAKQQEQKSECQQAoArAKIQUCQAJAIAJBIkYNACACQSdGDQAgAhAsGkEAKAKwCiEEDAELIAIQGkEAQQAoArAKQQJqIgQ2ArAKC0EBECkhA0EAKAKwCiECCwJAIAIgBUYNACAFIARBACAAIAAgAUYiAhtBACABIAIbEAILIAMLcgEEf0EAKAKwCiEAQQAoArQKIQECQAJAA0AgAEECaiECIAAgAU8NAQJAAkAgAi8BACIDQaR/ag4CAQQACyACIQAgA0F2ag4EAgEBAgELIABBBGohAAwACwtBACACNgKwChAlQQAPC0EAIAI2ArAKQd0AC0kBA39BACEDAkAgAkUNAAJAA0AgAC0AACIEIAEtAAAiBUcNASABQQFqIQEgAEEBaiEAIAJBf2oiAg0ADAILCyAEIAVrIQMLIAMLC+wBAgBBgAgLzgEAAHgAcABvAHIAdABtAHAAbwByAHQAZgBvAHIAZQB0AGEAbwB1AHIAYwBlAHIAbwBtAHUAbgBjAHQAaQBvAG4AcwBzAGUAcgB0AHYAbwB5AGkAZQBkAGUAbABlAGMAbwBuAHQAaQBuAGkAbgBzAHQAYQBuAHQAeQBiAHIAZQBhAHIAZQB0AHUAcgBkAGUAYgB1AGcAZwBlAGEAdwBhAGkAdABoAHIAdwBoAGkAbABlAGkAZgBjAGEAdABjAGYAaQBuAGEAbABsAGUAbABzAABB0AkLEAEAAAACAAAAAAQAAEA5AAA=","undefined"!=typeof Buffer?Buffer.from(A,"base64"):Uint8Array.from(atob(A),(A=>A.charCodeAt(0)));var A};export const init=WebAssembly.compile(E()).then(WebAssembly.instantiate).then((({exports:A})=>{C=A}));export const initSync=()=>{if(C)return;const A=new WebAssembly.Module(E());C=new WebAssembly.Instance(A).exports}; \ No newline at end of file diff --git a/node_modules/es-module-lexer/lexer.js b/node_modules/es-module-lexer/lexer.js new file mode 100644 index 0000000000..587fafe06e --- /dev/null +++ b/node_modules/es-module-lexer/lexer.js @@ -0,0 +1,925 @@ +let source, pos, end, + openTokenDepth, + lastTokenPos, + openTokenPosStack, + openClassPosStack, + curDynamicImport, + templateStackDepth, + facade, + lastSlashWasDivision, + nextBraceIsClass, + templateDepth, + templateStack, + imports, + exports, + name; + +function addImport (ss, s, e, d) { + const impt = { ss, se: d === -2 ? e : d === -1 ? e + 1 : 0, s, e, d, a: -1, n: undefined }; + imports.push(impt); + return impt; +} + +function addExport (s, e, ls, le) { + exports.push({ + s, + e, + ls, + le, + n: s[0] === '"' ? readString(s, '"') : s[0] === "'" ? readString(s, "'") : source.slice(s, e), + ln: ls[0] === '"' ? readString(ls, '"') : ls[0] === "'" ? readString(ls, "'") : source.slice(ls, le) + }); +} + +function readName (impt) { + let { d, s } = impt; + if (d !== -1) + s++; + impt.n = readString(s, source.charCodeAt(s - 1)); +} + +// Note: parsing is based on the _assumption_ that the source is already valid +export function parse (_source, _name) { + openTokenDepth = 0; + curDynamicImport = null; + templateDepth = -1; + lastTokenPos = -1; + lastSlashWasDivision = false; + templateStack = Array(1024); + templateStackDepth = 0; + openTokenPosStack = Array(1024); + openClassPosStack = Array(1024); + nextBraceIsClass = false; + facade = true; + name = _name || '@'; + + imports = []; + exports = []; + + source = _source; + pos = -1; + end = source.length - 1; + let ch = 0; + + // start with a pure "module-only" parser + m: while (pos++ < end) { + ch = source.charCodeAt(pos); + + if (ch === 32 || ch < 14 && ch > 8) + continue; + + switch (ch) { + case 101/*e*/: + if (openTokenDepth === 0 && keywordStart(pos) && source.startsWith('xport', pos + 1)) { + tryParseExportStatement(); + // export might have been a non-pure declaration + if (!facade) { + lastTokenPos = pos; + break m; + } + } + break; + case 105/*i*/: + if (keywordStart(pos) && source.startsWith('mport', pos + 1)) + tryParseImportStatement(); + break; + case 59/*;*/: + break; + case 47/*/*/: { + const next_ch = source.charCodeAt(pos + 1); + if (next_ch === 47/*/*/) { + lineComment(); + // dont update lastToken + continue; + } + else if (next_ch === 42/***/) { + blockComment(true); + // dont update lastToken + continue; + } + // fallthrough + } + default: + // as soon as we hit a non-module token, we go to main parser + facade = false; + pos--; + break m; + } + lastTokenPos = pos; + } + + while (pos++ < end) { + ch = source.charCodeAt(pos); + + if (ch === 32 || ch < 14 && ch > 8) + continue; + + switch (ch) { + case 101/*e*/: + if (openTokenDepth === 0 && keywordStart(pos) && source.startsWith('xport', pos + 1)) + tryParseExportStatement(); + break; + case 105/*i*/: + if (keywordStart(pos) && source.startsWith('mport', pos + 1)) + tryParseImportStatement(); + break; + case 99/*c*/: + if (keywordStart(pos) && source.startsWith('lass', pos + 1) && isBrOrWs(source.charCodeAt(pos + 5))) + nextBraceIsClass = true; + break; + case 40/*(*/: + openTokenPosStack[openTokenDepth++] = lastTokenPos; + break; + case 41/*)*/: + if (openTokenDepth === 0) + syntaxError(); + openTokenDepth--; + if (curDynamicImport && curDynamicImport.d === openTokenPosStack[openTokenDepth]) { + if (curDynamicImport.e === 0) + curDynamicImport.e = pos; + curDynamicImport.se = pos; + curDynamicImport = null; + } + break; + case 123/*{*/: + // dynamic import followed by { is not a dynamic import (so remove) + // this is a sneaky way to get around { import () {} } v { import () } + // block / object ambiguity without a parser (assuming source is valid) + if (source.charCodeAt(lastTokenPos) === 41/*)*/ && imports.length && imports[imports.length - 1].e === lastTokenPos) { + imports.pop(); + } + openClassPosStack[openTokenDepth] = nextBraceIsClass; + nextBraceIsClass = false; + openTokenPosStack[openTokenDepth++] = lastTokenPos; + break; + case 125/*}*/: + if (openTokenDepth === 0) + syntaxError(); + if (openTokenDepth-- === templateDepth) { + templateDepth = templateStack[--templateStackDepth]; + templateString(); + } + else { + if (templateDepth !== -1 && openTokenDepth < templateDepth) + syntaxError(); + } + break; + case 39/*'*/: + case 34/*"*/: + stringLiteral(ch); + break; + case 47/*/*/: { + const next_ch = source.charCodeAt(pos + 1); + if (next_ch === 47/*/*/) { + lineComment(); + // dont update lastToken + continue; + } + else if (next_ch === 42/***/) { + blockComment(true); + // dont update lastToken + continue; + } + else { + // Division / regex ambiguity handling based on checking backtrack analysis of: + // - what token came previously (lastToken) + // - if a closing brace or paren, what token came before the corresponding + // opening brace or paren (lastOpenTokenIndex) + const lastToken = source.charCodeAt(lastTokenPos); + const lastExport = exports[exports.length - 1]; + if (isExpressionPunctuator(lastToken) && + !(lastToken === 46/*.*/ && (source.charCodeAt(lastTokenPos - 1) >= 48/*0*/ && source.charCodeAt(lastTokenPos - 1) <= 57/*9*/)) && + !(lastToken === 43/*+*/ && source.charCodeAt(lastTokenPos - 1) === 43/*+*/) && !(lastToken === 45/*-*/ && source.charCodeAt(lastTokenPos - 1) === 45/*-*/) || + lastToken === 41/*)*/ && isParenKeyword(openTokenPosStack[openTokenDepth]) || + lastToken === 125/*}*/ && (isExpressionTerminator(openTokenPosStack[openTokenDepth]) || openClassPosStack[openTokenDepth]) || + lastToken === 47/*/*/ && lastSlashWasDivision || + isExpressionKeyword(lastTokenPos) || + !lastToken) { + regularExpression(); + lastSlashWasDivision = false; + } + else if (lastExport && lastTokenPos >= lastExport.s && lastTokenPos <= lastExport.e) { + // export default /some-regexp/ + regularExpression(); + lastSlashWasDivision = false; + } + else { + lastSlashWasDivision = true; + } + } + break; + } + case 96/*`*/: + templateString(); + break; + } + lastTokenPos = pos; + } + + if (templateDepth !== -1 || openTokenDepth) + syntaxError(); + + return [imports, exports, facade]; +} + +function tryParseImportStatement () { + const startPos = pos; + + pos += 6; + + let ch = commentWhitespace(true); + + switch (ch) { + // dynamic import + case 40/*(*/: + openTokenPosStack[openTokenDepth++] = startPos; + if (source.charCodeAt(lastTokenPos) === 46/*.*/) + return; + // dynamic import indicated by positive d + const impt = addImport(startPos, pos + 1, 0, startPos); + curDynamicImport = impt; + // try parse a string, to record a safe dynamic import string + pos++; + ch = commentWhitespace(true); + if (ch === 39/*'*/ || ch === 34/*"*/) { + stringLiteral(ch); + } + else { + pos--; + return; + } + pos++; + ch = commentWhitespace(true); + if (ch === 44/*,*/) { + impt.e = pos; + pos++; + ch = commentWhitespace(true); + impt.a = pos; + readName(impt); + pos--; + } + else if (ch === 41/*)*/) { + openTokenDepth--; + impt.e = pos; + impt.se = pos; + readName(impt); + } + else { + pos--; + } + return; + // import.meta + case 46/*.*/: + pos++; + ch = commentWhitespace(true); + // import.meta indicated by d === -2 + if (ch === 109/*m*/ && source.startsWith('eta', pos + 1) && source.charCodeAt(lastTokenPos) !== 46/*.*/) + addImport(startPos, startPos, pos + 4, -2); + return; + + default: + // no space after "import" -> not an import keyword + if (pos === startPos + 6) + break; + case 34/*"*/: + case 39/*'*/: + case 123/*{*/: + case 42/***/: + // import statement only permitted at base-level + if (openTokenDepth !== 0) { + pos--; + return; + } + while (pos < end) { + ch = source.charCodeAt(pos); + if (ch === 39/*'*/ || ch === 34/*"*/) { + readImportString(startPos, ch); + return; + } + pos++; + } + syntaxError(); + } +} + +function tryParseExportStatement () { + const sStartPos = pos; + const prevExport = exports.length; + + pos += 6; + + const curPos = pos; + + let ch = commentWhitespace(true); + + if (pos === curPos && !isPunctuator(ch)) + return; + + switch (ch) { + // export default ... + case 100/*d*/: + addExport(pos, pos + 7, -1, -1); + return; + + // export async? function*? name () { + case 97/*a*/: + pos += 5; + commentWhitespace(true); + // fallthrough + case 102/*f*/: + pos += 8; + ch = commentWhitespace(true); + if (ch === 42/***/) { + pos++; + ch = commentWhitespace(true); + } + const startPos = pos; + ch = readToWsOrPunctuator(ch); + addExport(startPos, pos, startPos, pos); + pos--; + return; + + // export class name ... + case 99/*c*/: + if (source.startsWith('lass', pos + 1) && isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos + 5))) { + pos += 5; + ch = commentWhitespace(true); + const startPos = pos; + ch = readToWsOrPunctuator(ch); + addExport(startPos, pos, startPos, pos); + pos--; + return; + } + pos += 2; + // fallthrough + + // export var/let/const name = ...(, name = ...)+ + case 118/*v*/: + case 109/*l*/: + // destructured initializations not currently supported (skipped for { or [) + // also, lexing names after variable equals is skipped (export var p = function () { ... }, q = 5 skips "q") + pos += 2; + facade = false; + do { + pos++; + ch = commentWhitespace(true); + const startPos = pos; + ch = readToWsOrPunctuator(ch); + // dont yet handle [ { destructurings + if (ch === 123/*{*/ || ch === 91/*[*/) { + pos--; + return; + } + if (pos === startPos) + return; + addExport(startPos, pos, startPos, pos); + ch = commentWhitespace(true); + if (ch === 61/*=*/) { + pos--; + return; + } + } while (ch === 44/*,*/); + pos--; + return; + + + // export {...} + case 123/*{*/: + pos++; + ch = commentWhitespace(true); + while (true) { + const startPos = pos; + readToWsOrPunctuator(ch); + const endPos = pos; + commentWhitespace(true); + ch = readExportAs(startPos, endPos); + // , + if (ch === 44/*,*/) { + pos++; + ch = commentWhitespace(true); + } + if (ch === 125/*}*/) + break; + if (pos === startPos) + return syntaxError(); + if (pos > end) + return syntaxError(); + } + pos++; + ch = commentWhitespace(true); + break; + + // export * + // export * as X + case 42/***/: + pos++; + commentWhitespace(true); + ch = readExportAs(pos, pos); + ch = commentWhitespace(true); + break; + } + + // from ... + if (ch === 102/*f*/ && source.startsWith('rom', pos + 1)) { + pos += 4; + readImportString(sStartPos, commentWhitespace(true)); + + // There were no local names. + for (let i = prevExport; i < exports.length; ++i) { + exports[i].ls = exports[i].le = -1; + exports[i].ln = undefined; + } + } + else { + pos--; + } +} + +/* + * Ported from Acorn + * + * MIT License + + * Copyright (C) 2012-2020 by various contributors (see AUTHORS) + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +let acornPos; +function readString (start, quote) { + acornPos = start; + let out = '', chunkStart = acornPos; + for (;;) { + if (acornPos >= source.length) syntaxError(); + const ch = source.charCodeAt(acornPos); + if (ch === quote) break; + if (ch === 92) { // '\' + out += source.slice(chunkStart, acornPos); + out += readEscapedChar(); + chunkStart = acornPos; + } + else if (ch === 0x2028 || ch === 0x2029) { + ++acornPos; + } + else { + if (isBr(ch)) syntaxError(); + ++acornPos; + } + } + out += source.slice(chunkStart, acornPos++); + return out; +} + +// Used to read escaped characters + +function readEscapedChar () { + let ch = source.charCodeAt(++acornPos); + ++acornPos; + switch (ch) { + case 110: return '\n'; // 'n' -> '\n' + case 114: return '\r'; // 'r' -> '\r' + case 120: return String.fromCharCode(readHexChar(2)); // 'x' + case 117: return readCodePointToString(); // 'u' + case 116: return '\t'; // 't' -> '\t' + case 98: return '\b'; // 'b' -> '\b' + case 118: return '\u000b'; // 'v' -> '\u000b' + case 102: return '\f'; // 'f' -> '\f' + case 13: if (source.charCodeAt(acornPos) === 10) ++acornPos; // '\r\n' + case 10: // ' \n' + return ''; + case 56: + case 57: + syntaxError(); + default: + if (ch >= 48 && ch <= 55) { + let octalStr = source.substr(acornPos - 1, 3).match(/^[0-7]+/)[0]; + let octal = parseInt(octalStr, 8); + if (octal > 255) { + octalStr = octalStr.slice(0, -1); + octal = parseInt(octalStr, 8); + } + acornPos += octalStr.length - 1; + ch = source.charCodeAt(acornPos); + if (octalStr !== '0' || ch === 56 || ch === 57) + syntaxError(); + return String.fromCharCode(octal); + } + if (isBr(ch)) { + // Unicode new line characters after \ get removed from output in both + // template literals and strings + return ''; + } + return String.fromCharCode(ch); + } +} + +// Used to read character escape sequences ('\x', '\u', '\U'). + +function readHexChar (len) { + const start = acornPos; + let total = 0, lastCode = 0; + for (let i = 0; i < len; ++i, ++acornPos) { + let code = source.charCodeAt(acornPos), val; + + if (code === 95) { + if (lastCode === 95 || i === 0) syntaxError(); + lastCode = code; + continue; + } + + if (code >= 97) val = code - 97 + 10; // a + else if (code >= 65) val = code - 65 + 10; // A + else if (code >= 48 && code <= 57) val = code - 48; // 0-9 + else break; + if (val >= 16) break; + lastCode = code; + total = total * 16 + val; + } + + if (lastCode === 95 || acornPos - start !== len) syntaxError(); + + return total; +} + +// Read a string value, interpreting backslash-escapes. + +function readCodePointToString () { + const ch = source.charCodeAt(acornPos); + let code; + if (ch === 123) { // '{' + ++acornPos; + code = readHexChar(source.indexOf('}', acornPos) - acornPos); + ++acornPos; + if (code > 0x10FFFF) syntaxError(); + } else { + code = readHexChar(4); + } + // UTF-16 Decoding + if (code <= 0xFFFF) return String.fromCharCode(code); + code -= 0x10000; + return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00); +} + +/* + * + */ + +function readExportAs (startPos, endPos) { + let ch = source.charCodeAt(pos); + let ls = startPos, le = endPos; + if (ch === 97 /*a*/) { + pos += 2; + ch = commentWhitespace(true); + startPos = pos; + readToWsOrPunctuator(ch); + endPos = pos; + ch = commentWhitespace(true); + } + if (pos !== startPos) + addExport(startPos, endPos, ls, le); + return ch; +} + +function readImportString (ss, ch) { + const startPos = pos + 1; + if (ch === 39/*'*/ || ch === 34/*"*/) { + stringLiteral(ch); + } + else { + syntaxError(); + return; + } + const impt = addImport(ss, startPos, pos, -1); + readName(impt); + pos++; + ch = commentWhitespace(false); + if (ch !== 97/*a*/ || !source.startsWith('ssert', pos + 1)) { + pos--; + return; + } + const assertIndex = pos; + + pos += 6; + ch = commentWhitespace(true); + if (ch !== 123/*{*/) { + pos = assertIndex; + return; + } + const assertStart = pos; + do { + pos++; + ch = commentWhitespace(true); + if (ch === 39/*'*/ || ch === 34/*"*/) { + stringLiteral(ch); + pos++; + ch = commentWhitespace(true); + } + else { + ch = readToWsOrPunctuator(ch); + } + if (ch !== 58/*:*/) { + pos = assertIndex; + return; + } + pos++; + ch = commentWhitespace(true); + if (ch === 39/*'*/ || ch === 34/*"*/) { + stringLiteral(ch); + } + else { + pos = assertIndex; + return; + } + pos++; + ch = commentWhitespace(true); + if (ch === 44/*,*/) { + pos++; + ch = commentWhitespace(true); + if (ch === 125/*}*/) + break; + continue; + } + if (ch === 125/*}*/) + break; + pos = assertIndex; + return; + } while (true); + impt.a = assertStart; + impt.se = pos + 1; +} + +function commentWhitespace (br) { + let ch; + do { + ch = source.charCodeAt(pos); + if (ch === 47/*/*/) { + const next_ch = source.charCodeAt(pos + 1); + if (next_ch === 47/*/*/) + lineComment(); + else if (next_ch === 42/***/) + blockComment(br); + else + return ch; + } + else if (br ? !isBrOrWs(ch): !isWsNotBr(ch)) { + return ch; + } + } while (pos++ < end); + return ch; +} + +function templateString () { + while (pos++ < end) { + const ch = source.charCodeAt(pos); + if (ch === 36/*$*/ && source.charCodeAt(pos + 1) === 123/*{*/) { + pos++; + templateStack[templateStackDepth++] = templateDepth; + templateDepth = ++openTokenDepth; + return; + } + if (ch === 96/*`*/) + return; + if (ch === 92/*\*/) + pos++; + } + syntaxError(); +} + +function blockComment (br) { + pos++; + while (pos++ < end) { + const ch = source.charCodeAt(pos); + if (!br && isBr(ch)) + return; + if (ch === 42/***/ && source.charCodeAt(pos + 1) === 47/*/*/) { + pos++; + return; + } + } +} + +function lineComment () { + while (pos++ < end) { + const ch = source.charCodeAt(pos); + if (ch === 10/*\n*/ || ch === 13/*\r*/) + return; + } +} + +function stringLiteral (quote) { + while (pos++ < end) { + let ch = source.charCodeAt(pos); + if (ch === quote) + return; + if (ch === 92/*\*/) { + ch = source.charCodeAt(++pos); + if (ch === 13/*\r*/ && source.charCodeAt(pos + 1) === 10/*\n*/) + pos++; + } + else if (isBr(ch)) + break; + } + syntaxError(); +} + +function regexCharacterClass () { + while (pos++ < end) { + let ch = source.charCodeAt(pos); + if (ch === 93/*]*/) + return ch; + if (ch === 92/*\*/) + pos++; + else if (ch === 10/*\n*/ || ch === 13/*\r*/) + break; + } + syntaxError(); +} + +function regularExpression () { + while (pos++ < end) { + let ch = source.charCodeAt(pos); + if (ch === 47/*/*/) + return; + if (ch === 91/*[*/) + ch = regexCharacterClass(); + else if (ch === 92/*\*/) + pos++; + else if (ch === 10/*\n*/ || ch === 13/*\r*/) + break; + } + syntaxError(); +} + +function readToWsOrPunctuator (ch) { + do { + if (isBrOrWs(ch) || isPunctuator(ch)) + return ch; + } while (ch = source.charCodeAt(++pos)); + return ch; +} + +// Note: non-asii BR and whitespace checks omitted for perf / footprint +// if there is a significant user need this can be reconsidered +function isBr (c) { + return c === 13/*\r*/ || c === 10/*\n*/; +} + +function isWsNotBr (c) { + return c === 9 || c === 11 || c === 12 || c === 32 || c === 160; +} + +function isBrOrWs (c) { + return c > 8 && c < 14 || c === 32 || c === 160; +} + +function isBrOrWsOrPunctuatorNotDot (c) { + return c > 8 && c < 14 || c === 32 || c === 160 || isPunctuator(c) && c !== 46/*.*/; +} + +function keywordStart (pos) { + return pos === 0 || isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos - 1)); +} + +function readPrecedingKeyword (pos, match) { + if (pos < match.length - 1) + return false; + return source.startsWith(match, pos - match.length + 1) && (pos === 0 || isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos - match.length))); +} + +function readPrecedingKeyword1 (pos, ch) { + return source.charCodeAt(pos) === ch && (pos === 0 || isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos - 1))); +} + +// Detects one of case, debugger, delete, do, else, in, instanceof, new, +// return, throw, typeof, void, yield, await +function isExpressionKeyword (pos) { + switch (source.charCodeAt(pos)) { + case 100/*d*/: + switch (source.charCodeAt(pos - 1)) { + case 105/*i*/: + // void + return readPrecedingKeyword(pos - 2, 'vo'); + case 108/*l*/: + // yield + return readPrecedingKeyword(pos - 2, 'yie'); + default: + return false; + } + case 101/*e*/: + switch (source.charCodeAt(pos - 1)) { + case 115/*s*/: + switch (source.charCodeAt(pos - 2)) { + case 108/*l*/: + // else + return readPrecedingKeyword1(pos - 3, 101/*e*/); + case 97/*a*/: + // case + return readPrecedingKeyword1(pos - 3, 99/*c*/); + default: + return false; + } + case 116/*t*/: + // delete + return readPrecedingKeyword(pos - 2, 'dele'); + default: + return false; + } + case 102/*f*/: + if (source.charCodeAt(pos - 1) !== 111/*o*/ || source.charCodeAt(pos - 2) !== 101/*e*/) + return false; + switch (source.charCodeAt(pos - 3)) { + case 99/*c*/: + // instanceof + return readPrecedingKeyword(pos - 4, 'instan'); + case 112/*p*/: + // typeof + return readPrecedingKeyword(pos - 4, 'ty'); + default: + return false; + } + case 110/*n*/: + // in, return + return readPrecedingKeyword1(pos - 1, 105/*i*/) || readPrecedingKeyword(pos - 1, 'retur'); + case 111/*o*/: + // do + return readPrecedingKeyword1(pos - 1, 100/*d*/); + case 114/*r*/: + // debugger + return readPrecedingKeyword(pos - 1, 'debugge'); + case 116/*t*/: + // await + return readPrecedingKeyword(pos - 1, 'awai'); + case 119/*w*/: + switch (source.charCodeAt(pos - 1)) { + case 101/*e*/: + // new + return readPrecedingKeyword1(pos - 2, 110/*n*/); + case 111/*o*/: + // throw + return readPrecedingKeyword(pos - 2, 'thr'); + default: + return false; + } + } + return false; +} + +function isParenKeyword (curPos) { + return source.charCodeAt(curPos) === 101/*e*/ && source.startsWith('whil', curPos - 4) || + source.charCodeAt(curPos) === 114/*r*/ && source.startsWith('fo', curPos - 2) || + source.charCodeAt(curPos - 1) === 105/*i*/ && source.charCodeAt(curPos) === 102/*f*/; +} + +function isPunctuator (ch) { + // 23 possible punctuator endings: !%&()*+,-./:;<=>?[]^{}|~ + return ch === 33/*!*/ || ch === 37/*%*/ || ch === 38/*&*/ || + ch > 39 && ch < 48 || ch > 57 && ch < 64 || + ch === 91/*[*/ || ch === 93/*]*/ || ch === 94/*^*/ || + ch > 122 && ch < 127; +} + +function isExpressionPunctuator (ch) { + // 20 possible expression endings: !%&(*+,-.:;<=>?[^{|~ + return ch === 33/*!*/ || ch === 37/*%*/ || ch === 38/*&*/ || + ch > 39 && ch < 47 && ch !== 41 || ch > 57 && ch < 64 || + ch === 91/*[*/ || ch === 94/*^*/ || ch > 122 && ch < 127 && ch !== 125/*}*/; +} + +function isExpressionTerminator (curPos) { + // detects: + // => ; ) finally catch else + // as all of these followed by a { will indicate a statement brace + switch (source.charCodeAt(curPos)) { + case 62/*>*/: + return source.charCodeAt(curPos - 1) === 61/*=*/; + case 59/*;*/: + case 41/*)*/: + return true; + case 104/*h*/: + return source.startsWith('catc', curPos - 4); + case 121/*y*/: + return source.startsWith('finall', curPos - 6); + case 101/*e*/: + return source.startsWith('els', curPos - 3); + } + return false; +} + +function syntaxError () { + throw Object.assign(new Error(`Parse error ${name}:${source.slice(0, pos).split('\n').length}:${pos - source.lastIndexOf('\n', pos - 1)}`), { idx: pos }); +} \ No newline at end of file diff --git a/node_modules/es-module-lexer/package.json b/node_modules/es-module-lexer/package.json new file mode 100644 index 0000000000..98a3adfc9c --- /dev/null +++ b/node_modules/es-module-lexer/package.json @@ -0,0 +1,57 @@ +{ + "name": "es-module-lexer", + "version": "1.7.0", + "description": "Lexes ES modules returning their import/export metadata", + "main": "dist/lexer.cjs", + "module": "dist/lexer.js", + "types": "types/lexer.d.ts", + "exports": { + ".": { + "types": "./types/lexer.d.ts", + "module": "./dist/lexer.js", + "import": "./dist/lexer.js", + "require": "./dist/lexer.cjs" + }, + "./js": { + "types": "./types/lexer.d.ts", + "default": "./dist/lexer.asm.js" + } + }, + "scripts": { + "build": "npm install -g chomp ; chomp build", + "test": "npm install -g chomp ; chomp test" + }, + "author": "Guy Bedford", + "license": "MIT", + "devDependencies": { + "@babel/cli": "^7.5.5", + "@babel/core": "^7.5.5", + "@babel/plugin-transform-modules-commonjs": "^7.5.0", + "@swc/cli": "^0.1.57", + "@swc/core": "^1.2.224", + "@types/node": "^18.7.1", + "kleur": "^2.0.2", + "mocha": "^5.2.0", + "terser": "^5.19.4", + "typescript": "^4.7.4" + }, + "files": [ + "dist", + "types", + "lexer.js" + ], + "type": "module", + "repository": { + "type": "git", + "url": "git+https://github.com/guybedford/es-module-lexer.git" + }, + "bugs": { + "url": "https://github.com/guybedford/es-module-lexer/issues" + }, + "homepage": "https://github.com/guybedford/es-module-lexer#readme", + "directories": { + "lib": "lib", + "test": "test" + }, + "keywords": [] +} diff --git a/node_modules/es-module-lexer/types/lexer.d.ts b/node_modules/es-module-lexer/types/lexer.d.ts new file mode 100644 index 0000000000..dd15b64d36 --- /dev/null +++ b/node_modules/es-module-lexer/types/lexer.d.ts @@ -0,0 +1,195 @@ +export declare enum ImportType { + /** + * A normal static using any syntax variations + * import .. from 'module' + */ + Static = 1, + /** + * A dynamic import expression `import(specifier)` + * or `import(specifier, opts)` + */ + Dynamic = 2, + /** + * An import.meta expression + */ + ImportMeta = 3, + /** + * A source phase import + * import source x from 'module' + */ + StaticSourcePhase = 4, + /** + * A dynamic source phase import + * import.source('module') + */ + DynamicSourcePhase = 5, + /** + * A defer phase import + * import defer * as x from 'module' + */ + StaticDeferPhase = 6, + /** + * A dynamic defer phase import + * import.defer('module') + */ + DynamicDeferPhase = 7 +} +export interface ImportSpecifier { + /** + * Module name + * + * To handle escape sequences in specifier strings, the .n field of imported specifiers will be provided where possible. + * + * For dynamic import expressions, this field will be empty if not a valid JS string. + * For static import expressions, this field will always be populated. + * + * @example + * const [imports1, exports1] = parse(String.raw`import './\u0061\u0062.js'`); + * imports1[0].n; + * // Returns "./ab.js" + * + * const [imports2, exports2] = parse(`import("./ab.js")`); + * imports2[0].n; + * // Returns "./ab.js" + * + * const [imports3, exports3] = parse(`import("./" + "ab.js")`); + * imports3[0].n; + * // Returns undefined + */ + readonly n: string | undefined; + /** + * Type of import statement + */ + readonly t: ImportType; + /** + * Start of module specifier + * + * @example + * const source = `import { a } from 'asdf'`; + * const [imports, exports] = parse(source); + * source.substring(imports[0].s, imports[0].e); + * // Returns "asdf" + */ + readonly s: number; + /** + * End of module specifier + */ + readonly e: number; + /** + * Start of import statement + * + * @example + * const source = `import { a } from 'asdf'`; + * const [imports, exports] = parse(source); + * source.substring(imports[0].ss, imports[0].se); + * // Returns "import { a } from 'asdf';" + */ + readonly ss: number; + /** + * End of import statement + */ + readonly se: number; + /** + * If this import keyword is a dynamic import, this is the start value. + * If this import keyword is a static import, this is -1. + * If this import keyword is an import.meta expresion, this is -2. + */ + readonly d: number; + /** + * If this import has an import assertion, this is the start value. + * Otherwise this is `-1`. + */ + readonly a: number; +} +export interface ExportSpecifier { + /** + * Exported name + * + * @example + * const source = `export default []`; + * const [imports, exports] = parse(source); + * exports[0].n; + * // Returns "default" + * + * @example + * const source = `export const asdf = 42`; + * const [imports, exports] = parse(source); + * exports[0].n; + * // Returns "asdf" + */ + readonly n: string; + /** + * Local name, or undefined. + * + * @example + * const source = `export default []`; + * const [imports, exports] = parse(source); + * exports[0].ln; + * // Returns undefined + * + * @example + * const asdf = 42; + * const source = `export { asdf as a }`; + * const [imports, exports] = parse(source); + * exports[0].ln; + * // Returns "asdf" + */ + readonly ln: string | undefined; + /** + * Start of exported name + * + * @example + * const source = `export default []`; + * const [imports, exports] = parse(source); + * source.substring(exports[0].s, exports[0].e); + * // Returns "default" + * + * @example + * const source = `export { 42 as asdf }`; + * const [imports, exports] = parse(source); + * source.substring(exports[0].s, exports[0].e); + * // Returns "asdf" + */ + readonly s: number; + /** + * End of exported name + */ + readonly e: number; + /** + * Start of local name, or -1. + * + * @example + * const asdf = 42; + * const source = `export { asdf as a }`; + * const [imports, exports] = parse(source); + * source.substring(exports[0].ls, exports[0].le); + * // Returns "asdf" + */ + readonly ls: number; + /** + * End of local name, or -1. + */ + readonly le: number; +} +export interface ParseError extends Error { + idx: number; +} +/** + * Outputs the list of exports and locations of import specifiers, + * including dynamic import and import meta handling. + * + * @param source Source code to parser + * @param name Optional sourcename + * @returns Tuple contaning imports list and exports list. + */ +export declare function parse(source: string, name?: string): readonly [ + imports: ReadonlyArray, + exports: ReadonlyArray, + facade: boolean, + hasModuleSyntax: boolean +]; +/** + * Wait for init to resolve before calling `parse`. + */ +export declare const init: Promise; +export declare const initSync: () => void; diff --git a/node_modules/esbuild/LICENSE.md b/node_modules/esbuild/LICENSE.md new file mode 100644 index 0000000000..2027e8dcf3 --- /dev/null +++ b/node_modules/esbuild/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Evan Wallace + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/esbuild/README.md b/node_modules/esbuild/README.md new file mode 100644 index 0000000000..93863d1980 --- /dev/null +++ b/node_modules/esbuild/README.md @@ -0,0 +1,3 @@ +# esbuild + +This is a JavaScript bundler and minifier. See https://github.com/evanw/esbuild and the [JavaScript API documentation](https://esbuild.github.io/api/) for details. diff --git a/node_modules/esbuild/bin/esbuild b/node_modules/esbuild/bin/esbuild new file mode 100755 index 0000000000..6a456f3482 Binary files /dev/null and b/node_modules/esbuild/bin/esbuild differ diff --git a/node_modules/esbuild/install.js b/node_modules/esbuild/install.js new file mode 100644 index 0000000000..1019e62435 --- /dev/null +++ b/node_modules/esbuild/install.js @@ -0,0 +1,289 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// lib/npm/node-platform.ts +var fs = require("fs"); +var os = require("os"); +var path = require("path"); +var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH; +var isValidBinaryPath = (x) => !!x && x !== "/usr/bin/esbuild"; +var knownWindowsPackages = { + "win32 arm64 LE": "@esbuild/win32-arm64", + "win32 ia32 LE": "@esbuild/win32-ia32", + "win32 x64 LE": "@esbuild/win32-x64" +}; +var knownUnixlikePackages = { + "aix ppc64 BE": "@esbuild/aix-ppc64", + "android arm64 LE": "@esbuild/android-arm64", + "darwin arm64 LE": "@esbuild/darwin-arm64", + "darwin x64 LE": "@esbuild/darwin-x64", + "freebsd arm64 LE": "@esbuild/freebsd-arm64", + "freebsd x64 LE": "@esbuild/freebsd-x64", + "linux arm LE": "@esbuild/linux-arm", + "linux arm64 LE": "@esbuild/linux-arm64", + "linux ia32 LE": "@esbuild/linux-ia32", + "linux mips64el LE": "@esbuild/linux-mips64el", + "linux ppc64 LE": "@esbuild/linux-ppc64", + "linux riscv64 LE": "@esbuild/linux-riscv64", + "linux s390x BE": "@esbuild/linux-s390x", + "linux x64 LE": "@esbuild/linux-x64", + "linux loong64 LE": "@esbuild/linux-loong64", + "netbsd arm64 LE": "@esbuild/netbsd-arm64", + "netbsd x64 LE": "@esbuild/netbsd-x64", + "openbsd arm64 LE": "@esbuild/openbsd-arm64", + "openbsd x64 LE": "@esbuild/openbsd-x64", + "sunos x64 LE": "@esbuild/sunos-x64" +}; +var knownWebAssemblyFallbackPackages = { + "android arm LE": "@esbuild/android-arm", + "android x64 LE": "@esbuild/android-x64", + "openharmony arm64 LE": "@esbuild/openharmony-arm64" +}; +function pkgAndSubpathForCurrentPlatform() { + let pkg; + let subpath; + let isWASM = false; + let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`; + if (platformKey in knownWindowsPackages) { + pkg = knownWindowsPackages[platformKey]; + subpath = "esbuild.exe"; + } else if (platformKey in knownUnixlikePackages) { + pkg = knownUnixlikePackages[platformKey]; + subpath = "bin/esbuild"; + } else if (platformKey in knownWebAssemblyFallbackPackages) { + pkg = knownWebAssemblyFallbackPackages[platformKey]; + subpath = "bin/esbuild"; + isWASM = true; + } else { + throw new Error(`Unsupported platform: ${platformKey}`); + } + return { pkg, subpath, isWASM }; +} +function downloadedBinPath(pkg, subpath) { + const esbuildLibDir = path.dirname(require.resolve("esbuild")); + return path.join(esbuildLibDir, `downloaded-${pkg.replace("/", "-")}-${path.basename(subpath)}`); +} + +// lib/npm/node-install.ts +var fs2 = require("fs"); +var os2 = require("os"); +var path2 = require("path"); +var zlib = require("zlib"); +var https = require("https"); +var child_process = require("child_process"); +var versionFromPackageJSON = require(path2.join(__dirname, "package.json")).version; +var toPath = path2.join(__dirname, "bin", "esbuild"); +var isToPathJS = true; +function validateBinaryVersion(...command) { + command.push("--version"); + let stdout; + try { + stdout = child_process.execFileSync(command.shift(), command, { + // Without this, this install script strangely crashes with the error + // "EACCES: permission denied, write" but only on Ubuntu Linux when node is + // installed from the Snap Store. This is not a problem when you download + // the official version of node. The problem appears to be that stderr + // (i.e. file descriptor 2) isn't writable? + // + // More info: + // - https://snapcraft.io/ (what the Snap Store is) + // - https://nodejs.org/dist/ (download the official version of node) + // - https://github.com/evanw/esbuild/issues/1711#issuecomment-1027554035 + // + stdio: "pipe" + }).toString().trim(); + } catch (err) { + if (os2.platform() === "darwin" && /_SecTrustEvaluateWithError/.test(err + "")) { + let os3 = "this version of macOS"; + try { + os3 = "macOS " + child_process.execFileSync("sw_vers", ["-productVersion"]).toString().trim(); + } catch { + } + throw new Error(`The "esbuild" package cannot be installed because ${os3} is too outdated. + +The Go compiler (which esbuild relies on) no longer supports ${os3}, +which means the "esbuild" binary executable can't be run. You can either: + + * Update your version of macOS to one that the Go compiler supports + * Use the "esbuild-wasm" package instead of the "esbuild" package + * Build esbuild yourself using an older version of the Go compiler +`); + } + throw err; + } + if (stdout !== versionFromPackageJSON) { + throw new Error(`Expected ${JSON.stringify(versionFromPackageJSON)} but got ${JSON.stringify(stdout)}`); + } +} +function isYarn() { + const { npm_config_user_agent } = process.env; + if (npm_config_user_agent) { + return /\byarn\//.test(npm_config_user_agent); + } + return false; +} +function fetch(url) { + return new Promise((resolve, reject) => { + https.get(url, (res) => { + if ((res.statusCode === 301 || res.statusCode === 302) && res.headers.location) + return fetch(res.headers.location).then(resolve, reject); + if (res.statusCode !== 200) + return reject(new Error(`Server responded with ${res.statusCode}`)); + let chunks = []; + res.on("data", (chunk) => chunks.push(chunk)); + res.on("end", () => resolve(Buffer.concat(chunks))); + }).on("error", reject); + }); +} +function extractFileFromTarGzip(buffer, subpath) { + try { + buffer = zlib.unzipSync(buffer); + } catch (err) { + throw new Error(`Invalid gzip data in archive: ${err && err.message || err}`); + } + let str = (i, n) => String.fromCharCode(...buffer.subarray(i, i + n)).replace(/\0.*$/, ""); + let offset = 0; + subpath = `package/${subpath}`; + while (offset < buffer.length) { + let name = str(offset, 100); + let size = parseInt(str(offset + 124, 12), 8); + offset += 512; + if (!isNaN(size)) { + if (name === subpath) return buffer.subarray(offset, offset + size); + offset += size + 511 & ~511; + } + } + throw new Error(`Could not find ${JSON.stringify(subpath)} in archive`); +} +function installUsingNPM(pkg, subpath, binPath) { + const env = { ...process.env, npm_config_global: void 0 }; + const esbuildLibDir = path2.dirname(require.resolve("esbuild")); + const installDir = path2.join(esbuildLibDir, "npm-install"); + fs2.mkdirSync(installDir); + try { + fs2.writeFileSync(path2.join(installDir, "package.json"), "{}"); + child_process.execSync( + `npm install --loglevel=error --prefer-offline --no-audit --progress=false ${pkg}@${versionFromPackageJSON}`, + { cwd: installDir, stdio: "pipe", env } + ); + const installedBinPath = path2.join(installDir, "node_modules", pkg, subpath); + fs2.renameSync(installedBinPath, binPath); + } finally { + try { + removeRecursive(installDir); + } catch { + } + } +} +function removeRecursive(dir) { + for (const entry of fs2.readdirSync(dir)) { + const entryPath = path2.join(dir, entry); + let stats; + try { + stats = fs2.lstatSync(entryPath); + } catch { + continue; + } + if (stats.isDirectory()) removeRecursive(entryPath); + else fs2.unlinkSync(entryPath); + } + fs2.rmdirSync(dir); +} +function applyManualBinaryPathOverride(overridePath) { + const pathString = JSON.stringify(overridePath); + fs2.writeFileSync(toPath, `#!/usr/bin/env node +require('child_process').execFileSync(${pathString}, process.argv.slice(2), { stdio: 'inherit' }); +`); + const libMain = path2.join(__dirname, "lib", "main.js"); + const code = fs2.readFileSync(libMain, "utf8"); + fs2.writeFileSync(libMain, `var ESBUILD_BINARY_PATH = ${pathString}; +${code}`); +} +function maybeOptimizePackage(binPath) { + const { isWASM } = pkgAndSubpathForCurrentPlatform(); + if (os2.platform() !== "win32" && !isYarn() && !isWASM) { + const tempPath = path2.join(__dirname, "bin-esbuild"); + try { + fs2.linkSync(binPath, tempPath); + fs2.renameSync(tempPath, toPath); + isToPathJS = false; + fs2.unlinkSync(tempPath); + } catch { + } + } +} +async function downloadDirectlyFromNPM(pkg, subpath, binPath) { + const url = `https://registry.npmjs.org/${pkg}/-/${pkg.replace("@esbuild/", "")}-${versionFromPackageJSON}.tgz`; + console.error(`[esbuild] Trying to download ${JSON.stringify(url)}`); + try { + fs2.writeFileSync(binPath, extractFileFromTarGzip(await fetch(url), subpath)); + fs2.chmodSync(binPath, 493); + } catch (e) { + console.error(`[esbuild] Failed to download ${JSON.stringify(url)}: ${e && e.message || e}`); + throw e; + } +} +async function checkAndPreparePackage() { + if (isValidBinaryPath(ESBUILD_BINARY_PATH)) { + if (!fs2.existsSync(ESBUILD_BINARY_PATH)) { + console.warn(`[esbuild] Ignoring bad configuration: ESBUILD_BINARY_PATH=${ESBUILD_BINARY_PATH}`); + } else { + applyManualBinaryPathOverride(ESBUILD_BINARY_PATH); + return; + } + } + const { pkg, subpath } = pkgAndSubpathForCurrentPlatform(); + let binPath; + try { + binPath = require.resolve(`${pkg}/${subpath}`); + } catch (e) { + console.error(`[esbuild] Failed to find package "${pkg}" on the file system + +This can happen if you use the "--no-optional" flag. The "optionalDependencies" +package.json feature is used by esbuild to install the correct binary executable +for your current platform. This install script will now attempt to work around +this. If that fails, you need to remove the "--no-optional" flag to use esbuild. +`); + binPath = downloadedBinPath(pkg, subpath); + try { + console.error(`[esbuild] Trying to install package "${pkg}" using npm`); + installUsingNPM(pkg, subpath, binPath); + } catch (e2) { + console.error(`[esbuild] Failed to install package "${pkg}" using npm: ${e2 && e2.message || e2}`); + try { + await downloadDirectlyFromNPM(pkg, subpath, binPath); + } catch (e3) { + throw new Error(`Failed to install package "${pkg}"`); + } + } + } + maybeOptimizePackage(binPath); +} +checkAndPreparePackage().then(() => { + if (isToPathJS) { + validateBinaryVersion(process.execPath, toPath); + } else { + validateBinaryVersion(toPath); + } +}); diff --git a/node_modules/esbuild/lib/main.d.ts b/node_modules/esbuild/lib/main.d.ts new file mode 100644 index 0000000000..9e69c39f58 --- /dev/null +++ b/node_modules/esbuild/lib/main.d.ts @@ -0,0 +1,716 @@ +export type Platform = 'browser' | 'node' | 'neutral' +export type Format = 'iife' | 'cjs' | 'esm' +export type Loader = 'base64' | 'binary' | 'copy' | 'css' | 'dataurl' | 'default' | 'empty' | 'file' | 'js' | 'json' | 'jsx' | 'local-css' | 'text' | 'ts' | 'tsx' +export type LogLevel = 'verbose' | 'debug' | 'info' | 'warning' | 'error' | 'silent' +export type Charset = 'ascii' | 'utf8' +export type Drop = 'console' | 'debugger' +export type AbsPaths = 'code' | 'log' | 'metafile' + +interface CommonOptions { + /** Documentation: https://esbuild.github.io/api/#sourcemap */ + sourcemap?: boolean | 'linked' | 'inline' | 'external' | 'both' + /** Documentation: https://esbuild.github.io/api/#legal-comments */ + legalComments?: 'none' | 'inline' | 'eof' | 'linked' | 'external' + /** Documentation: https://esbuild.github.io/api/#source-root */ + sourceRoot?: string + /** Documentation: https://esbuild.github.io/api/#sources-content */ + sourcesContent?: boolean + + /** Documentation: https://esbuild.github.io/api/#format */ + format?: Format + /** Documentation: https://esbuild.github.io/api/#global-name */ + globalName?: string + /** Documentation: https://esbuild.github.io/api/#target */ + target?: string | string[] + /** Documentation: https://esbuild.github.io/api/#supported */ + supported?: Record + /** Documentation: https://esbuild.github.io/api/#platform */ + platform?: Platform + + /** Documentation: https://esbuild.github.io/api/#mangle-props */ + mangleProps?: RegExp + /** Documentation: https://esbuild.github.io/api/#mangle-props */ + reserveProps?: RegExp + /** Documentation: https://esbuild.github.io/api/#mangle-props */ + mangleQuoted?: boolean + /** Documentation: https://esbuild.github.io/api/#mangle-props */ + mangleCache?: Record + /** Documentation: https://esbuild.github.io/api/#drop */ + drop?: Drop[] + /** Documentation: https://esbuild.github.io/api/#drop-labels */ + dropLabels?: string[] + /** Documentation: https://esbuild.github.io/api/#minify */ + minify?: boolean + /** Documentation: https://esbuild.github.io/api/#minify */ + minifyWhitespace?: boolean + /** Documentation: https://esbuild.github.io/api/#minify */ + minifyIdentifiers?: boolean + /** Documentation: https://esbuild.github.io/api/#minify */ + minifySyntax?: boolean + /** Documentation: https://esbuild.github.io/api/#line-limit */ + lineLimit?: number + /** Documentation: https://esbuild.github.io/api/#charset */ + charset?: Charset + /** Documentation: https://esbuild.github.io/api/#tree-shaking */ + treeShaking?: boolean + /** Documentation: https://esbuild.github.io/api/#ignore-annotations */ + ignoreAnnotations?: boolean + + /** Documentation: https://esbuild.github.io/api/#jsx */ + jsx?: 'transform' | 'preserve' | 'automatic' + /** Documentation: https://esbuild.github.io/api/#jsx-factory */ + jsxFactory?: string + /** Documentation: https://esbuild.github.io/api/#jsx-fragment */ + jsxFragment?: string + /** Documentation: https://esbuild.github.io/api/#jsx-import-source */ + jsxImportSource?: string + /** Documentation: https://esbuild.github.io/api/#jsx-development */ + jsxDev?: boolean + /** Documentation: https://esbuild.github.io/api/#jsx-side-effects */ + jsxSideEffects?: boolean + + /** Documentation: https://esbuild.github.io/api/#define */ + define?: { [key: string]: string } + /** Documentation: https://esbuild.github.io/api/#pure */ + pure?: string[] + /** Documentation: https://esbuild.github.io/api/#keep-names */ + keepNames?: boolean + + /** Documentation: https://esbuild.github.io/api/#abs-paths */ + absPaths?: AbsPaths[] + /** Documentation: https://esbuild.github.io/api/#color */ + color?: boolean + /** Documentation: https://esbuild.github.io/api/#log-level */ + logLevel?: LogLevel + /** Documentation: https://esbuild.github.io/api/#log-limit */ + logLimit?: number + /** Documentation: https://esbuild.github.io/api/#log-override */ + logOverride?: Record + + /** Documentation: https://esbuild.github.io/api/#tsconfig-raw */ + tsconfigRaw?: string | TsconfigRaw +} + +export interface TsconfigRaw { + compilerOptions?: { + alwaysStrict?: boolean + baseUrl?: string + experimentalDecorators?: boolean + importsNotUsedAsValues?: 'remove' | 'preserve' | 'error' + jsx?: 'preserve' | 'react-native' | 'react' | 'react-jsx' | 'react-jsxdev' + jsxFactory?: string + jsxFragmentFactory?: string + jsxImportSource?: string + paths?: Record + preserveValueImports?: boolean + strict?: boolean + target?: string + useDefineForClassFields?: boolean + verbatimModuleSyntax?: boolean + } +} + +export interface BuildOptions extends CommonOptions { + /** Documentation: https://esbuild.github.io/api/#bundle */ + bundle?: boolean + /** Documentation: https://esbuild.github.io/api/#splitting */ + splitting?: boolean + /** Documentation: https://esbuild.github.io/api/#preserve-symlinks */ + preserveSymlinks?: boolean + /** Documentation: https://esbuild.github.io/api/#outfile */ + outfile?: string + /** Documentation: https://esbuild.github.io/api/#metafile */ + metafile?: boolean + /** Documentation: https://esbuild.github.io/api/#outdir */ + outdir?: string + /** Documentation: https://esbuild.github.io/api/#outbase */ + outbase?: string + /** Documentation: https://esbuild.github.io/api/#external */ + external?: string[] + /** Documentation: https://esbuild.github.io/api/#packages */ + packages?: 'bundle' | 'external' + /** Documentation: https://esbuild.github.io/api/#alias */ + alias?: Record + /** Documentation: https://esbuild.github.io/api/#loader */ + loader?: { [ext: string]: Loader } + /** Documentation: https://esbuild.github.io/api/#resolve-extensions */ + resolveExtensions?: string[] + /** Documentation: https://esbuild.github.io/api/#main-fields */ + mainFields?: string[] + /** Documentation: https://esbuild.github.io/api/#conditions */ + conditions?: string[] + /** Documentation: https://esbuild.github.io/api/#write */ + write?: boolean + /** Documentation: https://esbuild.github.io/api/#allow-overwrite */ + allowOverwrite?: boolean + /** Documentation: https://esbuild.github.io/api/#tsconfig */ + tsconfig?: string + /** Documentation: https://esbuild.github.io/api/#out-extension */ + outExtension?: { [ext: string]: string } + /** Documentation: https://esbuild.github.io/api/#public-path */ + publicPath?: string + /** Documentation: https://esbuild.github.io/api/#entry-names */ + entryNames?: string + /** Documentation: https://esbuild.github.io/api/#chunk-names */ + chunkNames?: string + /** Documentation: https://esbuild.github.io/api/#asset-names */ + assetNames?: string + /** Documentation: https://esbuild.github.io/api/#inject */ + inject?: string[] + /** Documentation: https://esbuild.github.io/api/#banner */ + banner?: { [type: string]: string } + /** Documentation: https://esbuild.github.io/api/#footer */ + footer?: { [type: string]: string } + /** Documentation: https://esbuild.github.io/api/#entry-points */ + entryPoints?: (string | { in: string, out: string })[] | Record + /** Documentation: https://esbuild.github.io/api/#stdin */ + stdin?: StdinOptions + /** Documentation: https://esbuild.github.io/plugins/ */ + plugins?: Plugin[] + /** Documentation: https://esbuild.github.io/api/#working-directory */ + absWorkingDir?: string + /** Documentation: https://esbuild.github.io/api/#node-paths */ + nodePaths?: string[]; // The "NODE_PATH" variable from Node.js +} + +export interface StdinOptions { + contents: string | Uint8Array + resolveDir?: string + sourcefile?: string + loader?: Loader +} + +export interface Message { + id: string + pluginName: string + text: string + location: Location | null + notes: Note[] + + /** + * Optional user-specified data that is passed through unmodified. You can + * use this to stash the original error, for example. + */ + detail: any +} + +export interface Note { + text: string + location: Location | null +} + +export interface Location { + file: string + namespace: string + /** 1-based */ + line: number + /** 0-based, in bytes */ + column: number + /** in bytes */ + length: number + lineText: string + suggestion: string +} + +export interface OutputFile { + path: string + contents: Uint8Array + hash: string + /** "contents" as text (changes automatically with "contents") */ + readonly text: string +} + +export interface BuildResult { + errors: Message[] + warnings: Message[] + /** Only when "write: false" */ + outputFiles: OutputFile[] | (ProvidedOptions['write'] extends false ? never : undefined) + /** Only when "metafile: true" */ + metafile: Metafile | (ProvidedOptions['metafile'] extends true ? never : undefined) + /** Only when "mangleCache" is present */ + mangleCache: Record | (ProvidedOptions['mangleCache'] extends Object ? never : undefined) +} + +export interface BuildFailure extends Error { + errors: Message[] + warnings: Message[] +} + +/** Documentation: https://esbuild.github.io/api/#serve-arguments */ +export interface ServeOptions { + port?: number + host?: string + servedir?: string + keyfile?: string + certfile?: string + fallback?: string + cors?: CORSOptions + onRequest?: (args: ServeOnRequestArgs) => void +} + +/** Documentation: https://esbuild.github.io/api/#cors */ +export interface CORSOptions { + origin?: string | string[] +} + +export interface ServeOnRequestArgs { + remoteAddress: string + method: string + path: string + status: number + /** The time to generate the response, not to send it */ + timeInMS: number +} + +/** Documentation: https://esbuild.github.io/api/#serve-return-values */ +export interface ServeResult { + port: number + hosts: string[] +} + +export interface TransformOptions extends CommonOptions { + /** Documentation: https://esbuild.github.io/api/#sourcefile */ + sourcefile?: string + /** Documentation: https://esbuild.github.io/api/#loader */ + loader?: Loader + /** Documentation: https://esbuild.github.io/api/#banner */ + banner?: string + /** Documentation: https://esbuild.github.io/api/#footer */ + footer?: string +} + +export interface TransformResult { + code: string + map: string + warnings: Message[] + /** Only when "mangleCache" is present */ + mangleCache: Record | (ProvidedOptions['mangleCache'] extends Object ? never : undefined) + /** Only when "legalComments" is "external" */ + legalComments: string | (ProvidedOptions['legalComments'] extends 'external' ? never : undefined) +} + +export interface TransformFailure extends Error { + errors: Message[] + warnings: Message[] +} + +export interface Plugin { + name: string + setup: (build: PluginBuild) => (void | Promise) +} + +export interface PluginBuild { + /** Documentation: https://esbuild.github.io/plugins/#build-options */ + initialOptions: BuildOptions + + /** Documentation: https://esbuild.github.io/plugins/#resolve */ + resolve(path: string, options?: ResolveOptions): Promise + + /** Documentation: https://esbuild.github.io/plugins/#on-start */ + onStart(callback: () => + (OnStartResult | null | void | Promise)): void + + /** Documentation: https://esbuild.github.io/plugins/#on-end */ + onEnd(callback: (result: BuildResult) => + (OnEndResult | null | void | Promise)): void + + /** Documentation: https://esbuild.github.io/plugins/#on-resolve */ + onResolve(options: OnResolveOptions, callback: (args: OnResolveArgs) => + (OnResolveResult | null | undefined | Promise)): void + + /** Documentation: https://esbuild.github.io/plugins/#on-load */ + onLoad(options: OnLoadOptions, callback: (args: OnLoadArgs) => + (OnLoadResult | null | undefined | Promise)): void + + /** Documentation: https://esbuild.github.io/plugins/#on-dispose */ + onDispose(callback: () => void): void + + // This is a full copy of the esbuild library in case you need it + esbuild: { + context: typeof context, + build: typeof build, + buildSync: typeof buildSync, + transform: typeof transform, + transformSync: typeof transformSync, + formatMessages: typeof formatMessages, + formatMessagesSync: typeof formatMessagesSync, + analyzeMetafile: typeof analyzeMetafile, + analyzeMetafileSync: typeof analyzeMetafileSync, + initialize: typeof initialize, + version: typeof version, + } +} + +/** Documentation: https://esbuild.github.io/plugins/#resolve-options */ +export interface ResolveOptions { + pluginName?: string + importer?: string + namespace?: string + resolveDir?: string + kind?: ImportKind + pluginData?: any + with?: Record +} + +/** Documentation: https://esbuild.github.io/plugins/#resolve-results */ +export interface ResolveResult { + errors: Message[] + warnings: Message[] + + path: string + external: boolean + sideEffects: boolean + namespace: string + suffix: string + pluginData: any +} + +export interface OnStartResult { + errors?: PartialMessage[] + warnings?: PartialMessage[] +} + +export interface OnEndResult { + errors?: PartialMessage[] + warnings?: PartialMessage[] +} + +/** Documentation: https://esbuild.github.io/plugins/#on-resolve-options */ +export interface OnResolveOptions { + filter: RegExp + namespace?: string +} + +/** Documentation: https://esbuild.github.io/plugins/#on-resolve-arguments */ +export interface OnResolveArgs { + path: string + importer: string + namespace: string + resolveDir: string + kind: ImportKind + pluginData: any + with: Record +} + +export type ImportKind = + | 'entry-point' + + // JS + | 'import-statement' + | 'require-call' + | 'dynamic-import' + | 'require-resolve' + + // CSS + | 'import-rule' + | 'composes-from' + | 'url-token' + +/** Documentation: https://esbuild.github.io/plugins/#on-resolve-results */ +export interface OnResolveResult { + pluginName?: string + + errors?: PartialMessage[] + warnings?: PartialMessage[] + + path?: string + external?: boolean + sideEffects?: boolean + namespace?: string + suffix?: string + pluginData?: any + + watchFiles?: string[] + watchDirs?: string[] +} + +/** Documentation: https://esbuild.github.io/plugins/#on-load-options */ +export interface OnLoadOptions { + filter: RegExp + namespace?: string +} + +/** Documentation: https://esbuild.github.io/plugins/#on-load-arguments */ +export interface OnLoadArgs { + path: string + namespace: string + suffix: string + pluginData: any + with: Record +} + +/** Documentation: https://esbuild.github.io/plugins/#on-load-results */ +export interface OnLoadResult { + pluginName?: string + + errors?: PartialMessage[] + warnings?: PartialMessage[] + + contents?: string | Uint8Array + resolveDir?: string + loader?: Loader + pluginData?: any + + watchFiles?: string[] + watchDirs?: string[] +} + +export interface PartialMessage { + id?: string + pluginName?: string + text?: string + location?: Partial | null + notes?: PartialNote[] + detail?: any +} + +export interface PartialNote { + text?: string + location?: Partial | null +} + +/** Documentation: https://esbuild.github.io/api/#metafile */ +export interface Metafile { + inputs: { + [path: string]: { + bytes: number + imports: { + path: string + kind: ImportKind + external?: boolean + original?: string + with?: Record + }[] + format?: 'cjs' | 'esm' + with?: Record + } + } + outputs: { + [path: string]: { + bytes: number + inputs: { + [path: string]: { + bytesInOutput: number + } + } + imports: { + path: string + kind: ImportKind | 'file-loader' + external?: boolean + }[] + exports: string[] + entryPoint?: string + cssBundle?: string + } + } +} + +export interface FormatMessagesOptions { + kind: 'error' | 'warning' + color?: boolean + terminalWidth?: number +} + +export interface AnalyzeMetafileOptions { + color?: boolean + verbose?: boolean +} + +/** Documentation: https://esbuild.github.io/api/#watch-arguments */ +export interface WatchOptions { + delay?: number // In milliseconds +} + +export interface BuildContext { + /** Documentation: https://esbuild.github.io/api/#rebuild */ + rebuild(): Promise> + + /** Documentation: https://esbuild.github.io/api/#watch */ + watch(options?: WatchOptions): Promise + + /** Documentation: https://esbuild.github.io/api/#serve */ + serve(options?: ServeOptions): Promise + + cancel(): Promise + dispose(): Promise +} + +// This is a TypeScript type-level function which replaces any keys in "In" +// that aren't in "Out" with "never". We use this to reject properties with +// typos in object literals. See: https://stackoverflow.com/questions/49580725 +type SameShape = In & { [Key in Exclude]: never } + +/** + * This function invokes the "esbuild" command-line tool for you. It returns a + * promise that either resolves with a "BuildResult" object or rejects with a + * "BuildFailure" object. + * + * - Works in node: yes + * - Works in browser: yes + * + * Documentation: https://esbuild.github.io/api/#build + */ +export declare function build(options: SameShape): Promise> + +/** + * This is the advanced long-running form of "build" that supports additional + * features such as watch mode and a local development server. + * + * - Works in node: yes + * - Works in browser: no + * + * Documentation: https://esbuild.github.io/api/#build + */ +export declare function context(options: SameShape): Promise> + +/** + * This function transforms a single JavaScript file. It can be used to minify + * JavaScript, convert TypeScript/JSX to JavaScript, or convert newer JavaScript + * to older JavaScript. It returns a promise that is either resolved with a + * "TransformResult" object or rejected with a "TransformFailure" object. + * + * - Works in node: yes + * - Works in browser: yes + * + * Documentation: https://esbuild.github.io/api/#transform + */ +export declare function transform(input: string | Uint8Array, options?: SameShape): Promise> + +/** + * Converts log messages to formatted message strings suitable for printing in + * the terminal. This allows you to reuse the built-in behavior of esbuild's + * log message formatter. This is a batch-oriented API for efficiency. + * + * - Works in node: yes + * - Works in browser: yes + */ +export declare function formatMessages(messages: PartialMessage[], options: FormatMessagesOptions): Promise + +/** + * Pretty-prints an analysis of the metafile JSON to a string. This is just for + * convenience to be able to match esbuild's pretty-printing exactly. If you want + * to customize it, you can just inspect the data in the metafile yourself. + * + * - Works in node: yes + * - Works in browser: yes + * + * Documentation: https://esbuild.github.io/api/#analyze + */ +export declare function analyzeMetafile(metafile: Metafile | string, options?: AnalyzeMetafileOptions): Promise + +/** + * A synchronous version of "build". + * + * - Works in node: yes + * - Works in browser: no + * + * Documentation: https://esbuild.github.io/api/#build + */ +export declare function buildSync(options: SameShape): BuildResult + +/** + * A synchronous version of "transform". + * + * - Works in node: yes + * - Works in browser: no + * + * Documentation: https://esbuild.github.io/api/#transform + */ +export declare function transformSync(input: string | Uint8Array, options?: SameShape): TransformResult + +/** + * A synchronous version of "formatMessages". + * + * - Works in node: yes + * - Works in browser: no + */ +export declare function formatMessagesSync(messages: PartialMessage[], options: FormatMessagesOptions): string[] + +/** + * A synchronous version of "analyzeMetafile". + * + * - Works in node: yes + * - Works in browser: no + * + * Documentation: https://esbuild.github.io/api/#analyze + */ +export declare function analyzeMetafileSync(metafile: Metafile | string, options?: AnalyzeMetafileOptions): string + +/** + * This configures the browser-based version of esbuild. It is necessary to + * call this first and wait for the returned promise to be resolved before + * making other API calls when using esbuild in the browser. + * + * - Works in node: yes + * - Works in browser: yes ("options" is required) + * + * Documentation: https://esbuild.github.io/api/#browser + */ +export declare function initialize(options: InitializeOptions): Promise + +export interface InitializeOptions { + /** + * The URL of the "esbuild.wasm" file. This must be provided when running + * esbuild in the browser. + */ + wasmURL?: string | URL + + /** + * The result of calling "new WebAssembly.Module(buffer)" where "buffer" + * is a typed array or ArrayBuffer containing the binary code of the + * "esbuild.wasm" file. + * + * You can use this as an alternative to "wasmURL" for environments where it's + * not possible to download the WebAssembly module. + */ + wasmModule?: WebAssembly.Module + + /** + * By default esbuild runs the WebAssembly-based browser API in a web worker + * to avoid blocking the UI thread. This can be disabled by setting "worker" + * to false. + */ + worker?: boolean +} + +export let version: string + +// Call this function to terminate esbuild's child process. The child process +// is not terminated and re-created after each API call because it's more +// efficient to keep it around when there are multiple API calls. +// +// In node this happens automatically before the parent node process exits. So +// you only need to call this if you know you will not make any more esbuild +// API calls and you want to clean up resources. +// +// Unlike node, Deno lacks the necessary APIs to clean up child processes +// automatically. You must manually call stop() in Deno when you're done +// using esbuild or Deno will continue running forever. +// +// Another reason you might want to call this is if you are using esbuild from +// within a Deno test. Deno fails tests that create a child process without +// killing it before the test ends, so you have to call this function (and +// await the returned promise) in every Deno test that uses esbuild. +export declare function stop(): Promise + +// Note: These declarations exist to avoid type errors when you omit "dom" from +// "lib" in your "tsconfig.json" file. TypeScript confusingly declares the +// global "WebAssembly" type in "lib.dom.d.ts" even though it has nothing to do +// with the browser DOM and is present in many non-browser JavaScript runtimes +// (e.g. node and deno). Declaring it here allows esbuild's API to be used in +// these scenarios. +// +// There's an open issue about getting this problem corrected (although these +// declarations will need to remain even if this is fixed for backward +// compatibility with older TypeScript versions): +// +// https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/826 +// +declare global { + namespace WebAssembly { + interface Module { + } + } + interface URL { + } +} diff --git a/node_modules/esbuild/lib/main.js b/node_modules/esbuild/lib/main.js new file mode 100644 index 0000000000..de88f8e315 --- /dev/null +++ b/node_modules/esbuild/lib/main.js @@ -0,0 +1,2242 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// lib/npm/node.ts +var node_exports = {}; +__export(node_exports, { + analyzeMetafile: () => analyzeMetafile, + analyzeMetafileSync: () => analyzeMetafileSync, + build: () => build, + buildSync: () => buildSync, + context: () => context, + default: () => node_default, + formatMessages: () => formatMessages, + formatMessagesSync: () => formatMessagesSync, + initialize: () => initialize, + stop: () => stop, + transform: () => transform, + transformSync: () => transformSync, + version: () => version +}); +module.exports = __toCommonJS(node_exports); + +// lib/shared/stdio_protocol.ts +function encodePacket(packet) { + let visit = (value) => { + if (value === null) { + bb.write8(0); + } else if (typeof value === "boolean") { + bb.write8(1); + bb.write8(+value); + } else if (typeof value === "number") { + bb.write8(2); + bb.write32(value | 0); + } else if (typeof value === "string") { + bb.write8(3); + bb.write(encodeUTF8(value)); + } else if (value instanceof Uint8Array) { + bb.write8(4); + bb.write(value); + } else if (value instanceof Array) { + bb.write8(5); + bb.write32(value.length); + for (let item of value) { + visit(item); + } + } else { + let keys = Object.keys(value); + bb.write8(6); + bb.write32(keys.length); + for (let key of keys) { + bb.write(encodeUTF8(key)); + visit(value[key]); + } + } + }; + let bb = new ByteBuffer(); + bb.write32(0); + bb.write32(packet.id << 1 | +!packet.isRequest); + visit(packet.value); + writeUInt32LE(bb.buf, bb.len - 4, 0); + return bb.buf.subarray(0, bb.len); +} +function decodePacket(bytes) { + let visit = () => { + switch (bb.read8()) { + case 0: + return null; + case 1: + return !!bb.read8(); + case 2: + return bb.read32(); + case 3: + return decodeUTF8(bb.read()); + case 4: + return bb.read(); + case 5: { + let count = bb.read32(); + let value2 = []; + for (let i = 0; i < count; i++) { + value2.push(visit()); + } + return value2; + } + case 6: { + let count = bb.read32(); + let value2 = {}; + for (let i = 0; i < count; i++) { + value2[decodeUTF8(bb.read())] = visit(); + } + return value2; + } + default: + throw new Error("Invalid packet"); + } + }; + let bb = new ByteBuffer(bytes); + let id = bb.read32(); + let isRequest = (id & 1) === 0; + id >>>= 1; + let value = visit(); + if (bb.ptr !== bytes.length) { + throw new Error("Invalid packet"); + } + return { id, isRequest, value }; +} +var ByteBuffer = class { + constructor(buf = new Uint8Array(1024)) { + this.buf = buf; + this.len = 0; + this.ptr = 0; + } + _write(delta) { + if (this.len + delta > this.buf.length) { + let clone = new Uint8Array((this.len + delta) * 2); + clone.set(this.buf); + this.buf = clone; + } + this.len += delta; + return this.len - delta; + } + write8(value) { + let offset = this._write(1); + this.buf[offset] = value; + } + write32(value) { + let offset = this._write(4); + writeUInt32LE(this.buf, value, offset); + } + write(bytes) { + let offset = this._write(4 + bytes.length); + writeUInt32LE(this.buf, bytes.length, offset); + this.buf.set(bytes, offset + 4); + } + _read(delta) { + if (this.ptr + delta > this.buf.length) { + throw new Error("Invalid packet"); + } + this.ptr += delta; + return this.ptr - delta; + } + read8() { + return this.buf[this._read(1)]; + } + read32() { + return readUInt32LE(this.buf, this._read(4)); + } + read() { + let length = this.read32(); + let bytes = new Uint8Array(length); + let ptr = this._read(bytes.length); + bytes.set(this.buf.subarray(ptr, ptr + length)); + return bytes; + } +}; +var encodeUTF8; +var decodeUTF8; +var encodeInvariant; +if (typeof TextEncoder !== "undefined" && typeof TextDecoder !== "undefined") { + let encoder = new TextEncoder(); + let decoder = new TextDecoder(); + encodeUTF8 = (text) => encoder.encode(text); + decodeUTF8 = (bytes) => decoder.decode(bytes); + encodeInvariant = 'new TextEncoder().encode("")'; +} else if (typeof Buffer !== "undefined") { + encodeUTF8 = (text) => Buffer.from(text); + decodeUTF8 = (bytes) => { + let { buffer, byteOffset, byteLength } = bytes; + return Buffer.from(buffer, byteOffset, byteLength).toString(); + }; + encodeInvariant = 'Buffer.from("")'; +} else { + throw new Error("No UTF-8 codec found"); +} +if (!(encodeUTF8("") instanceof Uint8Array)) + throw new Error(`Invariant violation: "${encodeInvariant} instanceof Uint8Array" is incorrectly false + +This indicates that your JavaScript environment is broken. You cannot use +esbuild in this environment because esbuild relies on this invariant. This +is not a problem with esbuild. You need to fix your environment instead. +`); +function readUInt32LE(buffer, offset) { + return buffer[offset++] | buffer[offset++] << 8 | buffer[offset++] << 16 | buffer[offset++] << 24; +} +function writeUInt32LE(buffer, value, offset) { + buffer[offset++] = value; + buffer[offset++] = value >> 8; + buffer[offset++] = value >> 16; + buffer[offset++] = value >> 24; +} + +// lib/shared/common.ts +var quote = JSON.stringify; +var buildLogLevelDefault = "warning"; +var transformLogLevelDefault = "silent"; +function validateAndJoinStringArray(values, what) { + const toJoin = []; + for (const value of values) { + validateStringValue(value, what); + if (value.indexOf(",") >= 0) throw new Error(`Invalid ${what}: ${value}`); + toJoin.push(value); + } + return toJoin.join(","); +} +var canBeAnything = () => null; +var mustBeBoolean = (value) => typeof value === "boolean" ? null : "a boolean"; +var mustBeString = (value) => typeof value === "string" ? null : "a string"; +var mustBeRegExp = (value) => value instanceof RegExp ? null : "a RegExp object"; +var mustBeInteger = (value) => typeof value === "number" && value === (value | 0) ? null : "an integer"; +var mustBeValidPortNumber = (value) => typeof value === "number" && value === (value | 0) && value >= 0 && value <= 65535 ? null : "a valid port number"; +var mustBeFunction = (value) => typeof value === "function" ? null : "a function"; +var mustBeArray = (value) => Array.isArray(value) ? null : "an array"; +var mustBeArrayOfStrings = (value) => Array.isArray(value) && value.every((x) => typeof x === "string") ? null : "an array of strings"; +var mustBeObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? null : "an object"; +var mustBeEntryPoints = (value) => typeof value === "object" && value !== null ? null : "an array or an object"; +var mustBeWebAssemblyModule = (value) => value instanceof WebAssembly.Module ? null : "a WebAssembly.Module"; +var mustBeObjectOrNull = (value) => typeof value === "object" && !Array.isArray(value) ? null : "an object or null"; +var mustBeStringOrBoolean = (value) => typeof value === "string" || typeof value === "boolean" ? null : "a string or a boolean"; +var mustBeStringOrObject = (value) => typeof value === "string" || typeof value === "object" && value !== null && !Array.isArray(value) ? null : "a string or an object"; +var mustBeStringOrArrayOfStrings = (value) => typeof value === "string" || Array.isArray(value) && value.every((x) => typeof x === "string") ? null : "a string or an array of strings"; +var mustBeStringOrUint8Array = (value) => typeof value === "string" || value instanceof Uint8Array ? null : "a string or a Uint8Array"; +var mustBeStringOrURL = (value) => typeof value === "string" || value instanceof URL ? null : "a string or a URL"; +function getFlag(object, keys, key, mustBeFn) { + let value = object[key]; + keys[key + ""] = true; + if (value === void 0) return void 0; + let mustBe = mustBeFn(value); + if (mustBe !== null) throw new Error(`${quote(key)} must be ${mustBe}`); + return value; +} +function checkForInvalidFlags(object, keys, where) { + for (let key in object) { + if (!(key in keys)) { + throw new Error(`Invalid option ${where}: ${quote(key)}`); + } + } +} +function validateInitializeOptions(options) { + let keys = /* @__PURE__ */ Object.create(null); + let wasmURL = getFlag(options, keys, "wasmURL", mustBeStringOrURL); + let wasmModule = getFlag(options, keys, "wasmModule", mustBeWebAssemblyModule); + let worker = getFlag(options, keys, "worker", mustBeBoolean); + checkForInvalidFlags(options, keys, "in initialize() call"); + return { + wasmURL, + wasmModule, + worker + }; +} +function validateMangleCache(mangleCache) { + let validated; + if (mangleCache !== void 0) { + validated = /* @__PURE__ */ Object.create(null); + for (let key in mangleCache) { + let value = mangleCache[key]; + if (typeof value === "string" || value === false) { + validated[key] = value; + } else { + throw new Error(`Expected ${quote(key)} in mangle cache to map to either a string or false`); + } + } + } + return validated; +} +function pushLogFlags(flags, options, keys, isTTY2, logLevelDefault) { + let color = getFlag(options, keys, "color", mustBeBoolean); + let logLevel = getFlag(options, keys, "logLevel", mustBeString); + let logLimit = getFlag(options, keys, "logLimit", mustBeInteger); + if (color !== void 0) flags.push(`--color=${color}`); + else if (isTTY2) flags.push(`--color=true`); + flags.push(`--log-level=${logLevel || logLevelDefault}`); + flags.push(`--log-limit=${logLimit || 0}`); +} +function validateStringValue(value, what, key) { + if (typeof value !== "string") { + throw new Error(`Expected value for ${what}${key !== void 0 ? " " + quote(key) : ""} to be a string, got ${typeof value} instead`); + } + return value; +} +function pushCommonFlags(flags, options, keys) { + let legalComments = getFlag(options, keys, "legalComments", mustBeString); + let sourceRoot = getFlag(options, keys, "sourceRoot", mustBeString); + let sourcesContent = getFlag(options, keys, "sourcesContent", mustBeBoolean); + let target = getFlag(options, keys, "target", mustBeStringOrArrayOfStrings); + let format = getFlag(options, keys, "format", mustBeString); + let globalName = getFlag(options, keys, "globalName", mustBeString); + let mangleProps = getFlag(options, keys, "mangleProps", mustBeRegExp); + let reserveProps = getFlag(options, keys, "reserveProps", mustBeRegExp); + let mangleQuoted = getFlag(options, keys, "mangleQuoted", mustBeBoolean); + let minify = getFlag(options, keys, "minify", mustBeBoolean); + let minifySyntax = getFlag(options, keys, "minifySyntax", mustBeBoolean); + let minifyWhitespace = getFlag(options, keys, "minifyWhitespace", mustBeBoolean); + let minifyIdentifiers = getFlag(options, keys, "minifyIdentifiers", mustBeBoolean); + let lineLimit = getFlag(options, keys, "lineLimit", mustBeInteger); + let drop = getFlag(options, keys, "drop", mustBeArrayOfStrings); + let dropLabels = getFlag(options, keys, "dropLabels", mustBeArrayOfStrings); + let charset = getFlag(options, keys, "charset", mustBeString); + let treeShaking = getFlag(options, keys, "treeShaking", mustBeBoolean); + let ignoreAnnotations = getFlag(options, keys, "ignoreAnnotations", mustBeBoolean); + let jsx = getFlag(options, keys, "jsx", mustBeString); + let jsxFactory = getFlag(options, keys, "jsxFactory", mustBeString); + let jsxFragment = getFlag(options, keys, "jsxFragment", mustBeString); + let jsxImportSource = getFlag(options, keys, "jsxImportSource", mustBeString); + let jsxDev = getFlag(options, keys, "jsxDev", mustBeBoolean); + let jsxSideEffects = getFlag(options, keys, "jsxSideEffects", mustBeBoolean); + let define = getFlag(options, keys, "define", mustBeObject); + let logOverride = getFlag(options, keys, "logOverride", mustBeObject); + let supported = getFlag(options, keys, "supported", mustBeObject); + let pure = getFlag(options, keys, "pure", mustBeArrayOfStrings); + let keepNames = getFlag(options, keys, "keepNames", mustBeBoolean); + let platform = getFlag(options, keys, "platform", mustBeString); + let tsconfigRaw = getFlag(options, keys, "tsconfigRaw", mustBeStringOrObject); + let absPaths = getFlag(options, keys, "absPaths", mustBeArrayOfStrings); + if (legalComments) flags.push(`--legal-comments=${legalComments}`); + if (sourceRoot !== void 0) flags.push(`--source-root=${sourceRoot}`); + if (sourcesContent !== void 0) flags.push(`--sources-content=${sourcesContent}`); + if (target) flags.push(`--target=${validateAndJoinStringArray(Array.isArray(target) ? target : [target], "target")}`); + if (format) flags.push(`--format=${format}`); + if (globalName) flags.push(`--global-name=${globalName}`); + if (platform) flags.push(`--platform=${platform}`); + if (tsconfigRaw) flags.push(`--tsconfig-raw=${typeof tsconfigRaw === "string" ? tsconfigRaw : JSON.stringify(tsconfigRaw)}`); + if (minify) flags.push("--minify"); + if (minifySyntax) flags.push("--minify-syntax"); + if (minifyWhitespace) flags.push("--minify-whitespace"); + if (minifyIdentifiers) flags.push("--minify-identifiers"); + if (lineLimit) flags.push(`--line-limit=${lineLimit}`); + if (charset) flags.push(`--charset=${charset}`); + if (treeShaking !== void 0) flags.push(`--tree-shaking=${treeShaking}`); + if (ignoreAnnotations) flags.push(`--ignore-annotations`); + if (drop) for (let what of drop) flags.push(`--drop:${validateStringValue(what, "drop")}`); + if (dropLabels) flags.push(`--drop-labels=${validateAndJoinStringArray(dropLabels, "drop label")}`); + if (absPaths) flags.push(`--abs-paths=${validateAndJoinStringArray(absPaths, "abs paths")}`); + if (mangleProps) flags.push(`--mangle-props=${jsRegExpToGoRegExp(mangleProps)}`); + if (reserveProps) flags.push(`--reserve-props=${jsRegExpToGoRegExp(reserveProps)}`); + if (mangleQuoted !== void 0) flags.push(`--mangle-quoted=${mangleQuoted}`); + if (jsx) flags.push(`--jsx=${jsx}`); + if (jsxFactory) flags.push(`--jsx-factory=${jsxFactory}`); + if (jsxFragment) flags.push(`--jsx-fragment=${jsxFragment}`); + if (jsxImportSource) flags.push(`--jsx-import-source=${jsxImportSource}`); + if (jsxDev) flags.push(`--jsx-dev`); + if (jsxSideEffects) flags.push(`--jsx-side-effects`); + if (define) { + for (let key in define) { + if (key.indexOf("=") >= 0) throw new Error(`Invalid define: ${key}`); + flags.push(`--define:${key}=${validateStringValue(define[key], "define", key)}`); + } + } + if (logOverride) { + for (let key in logOverride) { + if (key.indexOf("=") >= 0) throw new Error(`Invalid log override: ${key}`); + flags.push(`--log-override:${key}=${validateStringValue(logOverride[key], "log override", key)}`); + } + } + if (supported) { + for (let key in supported) { + if (key.indexOf("=") >= 0) throw new Error(`Invalid supported: ${key}`); + const value = supported[key]; + if (typeof value !== "boolean") throw new Error(`Expected value for supported ${quote(key)} to be a boolean, got ${typeof value} instead`); + flags.push(`--supported:${key}=${value}`); + } + } + if (pure) for (let fn of pure) flags.push(`--pure:${validateStringValue(fn, "pure")}`); + if (keepNames) flags.push(`--keep-names`); +} +function flagsForBuildOptions(callName, options, isTTY2, logLevelDefault, writeDefault) { + var _a2; + let flags = []; + let entries = []; + let keys = /* @__PURE__ */ Object.create(null); + let stdinContents = null; + let stdinResolveDir = null; + pushLogFlags(flags, options, keys, isTTY2, logLevelDefault); + pushCommonFlags(flags, options, keys); + let sourcemap = getFlag(options, keys, "sourcemap", mustBeStringOrBoolean); + let bundle = getFlag(options, keys, "bundle", mustBeBoolean); + let splitting = getFlag(options, keys, "splitting", mustBeBoolean); + let preserveSymlinks = getFlag(options, keys, "preserveSymlinks", mustBeBoolean); + let metafile = getFlag(options, keys, "metafile", mustBeBoolean); + let outfile = getFlag(options, keys, "outfile", mustBeString); + let outdir = getFlag(options, keys, "outdir", mustBeString); + let outbase = getFlag(options, keys, "outbase", mustBeString); + let tsconfig = getFlag(options, keys, "tsconfig", mustBeString); + let resolveExtensions = getFlag(options, keys, "resolveExtensions", mustBeArrayOfStrings); + let nodePathsInput = getFlag(options, keys, "nodePaths", mustBeArrayOfStrings); + let mainFields = getFlag(options, keys, "mainFields", mustBeArrayOfStrings); + let conditions = getFlag(options, keys, "conditions", mustBeArrayOfStrings); + let external = getFlag(options, keys, "external", mustBeArrayOfStrings); + let packages = getFlag(options, keys, "packages", mustBeString); + let alias = getFlag(options, keys, "alias", mustBeObject); + let loader = getFlag(options, keys, "loader", mustBeObject); + let outExtension = getFlag(options, keys, "outExtension", mustBeObject); + let publicPath = getFlag(options, keys, "publicPath", mustBeString); + let entryNames = getFlag(options, keys, "entryNames", mustBeString); + let chunkNames = getFlag(options, keys, "chunkNames", mustBeString); + let assetNames = getFlag(options, keys, "assetNames", mustBeString); + let inject = getFlag(options, keys, "inject", mustBeArrayOfStrings); + let banner = getFlag(options, keys, "banner", mustBeObject); + let footer = getFlag(options, keys, "footer", mustBeObject); + let entryPoints = getFlag(options, keys, "entryPoints", mustBeEntryPoints); + let absWorkingDir = getFlag(options, keys, "absWorkingDir", mustBeString); + let stdin = getFlag(options, keys, "stdin", mustBeObject); + let write = (_a2 = getFlag(options, keys, "write", mustBeBoolean)) != null ? _a2 : writeDefault; + let allowOverwrite = getFlag(options, keys, "allowOverwrite", mustBeBoolean); + let mangleCache = getFlag(options, keys, "mangleCache", mustBeObject); + keys.plugins = true; + checkForInvalidFlags(options, keys, `in ${callName}() call`); + if (sourcemap) flags.push(`--sourcemap${sourcemap === true ? "" : `=${sourcemap}`}`); + if (bundle) flags.push("--bundle"); + if (allowOverwrite) flags.push("--allow-overwrite"); + if (splitting) flags.push("--splitting"); + if (preserveSymlinks) flags.push("--preserve-symlinks"); + if (metafile) flags.push(`--metafile`); + if (outfile) flags.push(`--outfile=${outfile}`); + if (outdir) flags.push(`--outdir=${outdir}`); + if (outbase) flags.push(`--outbase=${outbase}`); + if (tsconfig) flags.push(`--tsconfig=${tsconfig}`); + if (packages) flags.push(`--packages=${packages}`); + if (resolveExtensions) flags.push(`--resolve-extensions=${validateAndJoinStringArray(resolveExtensions, "resolve extension")}`); + if (publicPath) flags.push(`--public-path=${publicPath}`); + if (entryNames) flags.push(`--entry-names=${entryNames}`); + if (chunkNames) flags.push(`--chunk-names=${chunkNames}`); + if (assetNames) flags.push(`--asset-names=${assetNames}`); + if (mainFields) flags.push(`--main-fields=${validateAndJoinStringArray(mainFields, "main field")}`); + if (conditions) flags.push(`--conditions=${validateAndJoinStringArray(conditions, "condition")}`); + if (external) for (let name of external) flags.push(`--external:${validateStringValue(name, "external")}`); + if (alias) { + for (let old in alias) { + if (old.indexOf("=") >= 0) throw new Error(`Invalid package name in alias: ${old}`); + flags.push(`--alias:${old}=${validateStringValue(alias[old], "alias", old)}`); + } + } + if (banner) { + for (let type in banner) { + if (type.indexOf("=") >= 0) throw new Error(`Invalid banner file type: ${type}`); + flags.push(`--banner:${type}=${validateStringValue(banner[type], "banner", type)}`); + } + } + if (footer) { + for (let type in footer) { + if (type.indexOf("=") >= 0) throw new Error(`Invalid footer file type: ${type}`); + flags.push(`--footer:${type}=${validateStringValue(footer[type], "footer", type)}`); + } + } + if (inject) for (let path3 of inject) flags.push(`--inject:${validateStringValue(path3, "inject")}`); + if (loader) { + for (let ext in loader) { + if (ext.indexOf("=") >= 0) throw new Error(`Invalid loader extension: ${ext}`); + flags.push(`--loader:${ext}=${validateStringValue(loader[ext], "loader", ext)}`); + } + } + if (outExtension) { + for (let ext in outExtension) { + if (ext.indexOf("=") >= 0) throw new Error(`Invalid out extension: ${ext}`); + flags.push(`--out-extension:${ext}=${validateStringValue(outExtension[ext], "out extension", ext)}`); + } + } + if (entryPoints) { + if (Array.isArray(entryPoints)) { + for (let i = 0, n = entryPoints.length; i < n; i++) { + let entryPoint = entryPoints[i]; + if (typeof entryPoint === "object" && entryPoint !== null) { + let entryPointKeys = /* @__PURE__ */ Object.create(null); + let input = getFlag(entryPoint, entryPointKeys, "in", mustBeString); + let output = getFlag(entryPoint, entryPointKeys, "out", mustBeString); + checkForInvalidFlags(entryPoint, entryPointKeys, "in entry point at index " + i); + if (input === void 0) throw new Error('Missing property "in" for entry point at index ' + i); + if (output === void 0) throw new Error('Missing property "out" for entry point at index ' + i); + entries.push([output, input]); + } else { + entries.push(["", validateStringValue(entryPoint, "entry point at index " + i)]); + } + } + } else { + for (let key in entryPoints) { + entries.push([key, validateStringValue(entryPoints[key], "entry point", key)]); + } + } + } + if (stdin) { + let stdinKeys = /* @__PURE__ */ Object.create(null); + let contents = getFlag(stdin, stdinKeys, "contents", mustBeStringOrUint8Array); + let resolveDir = getFlag(stdin, stdinKeys, "resolveDir", mustBeString); + let sourcefile = getFlag(stdin, stdinKeys, "sourcefile", mustBeString); + let loader2 = getFlag(stdin, stdinKeys, "loader", mustBeString); + checkForInvalidFlags(stdin, stdinKeys, 'in "stdin" object'); + if (sourcefile) flags.push(`--sourcefile=${sourcefile}`); + if (loader2) flags.push(`--loader=${loader2}`); + if (resolveDir) stdinResolveDir = resolveDir; + if (typeof contents === "string") stdinContents = encodeUTF8(contents); + else if (contents instanceof Uint8Array) stdinContents = contents; + } + let nodePaths = []; + if (nodePathsInput) { + for (let value of nodePathsInput) { + value += ""; + nodePaths.push(value); + } + } + return { + entries, + flags, + write, + stdinContents, + stdinResolveDir, + absWorkingDir, + nodePaths, + mangleCache: validateMangleCache(mangleCache) + }; +} +function flagsForTransformOptions(callName, options, isTTY2, logLevelDefault) { + let flags = []; + let keys = /* @__PURE__ */ Object.create(null); + pushLogFlags(flags, options, keys, isTTY2, logLevelDefault); + pushCommonFlags(flags, options, keys); + let sourcemap = getFlag(options, keys, "sourcemap", mustBeStringOrBoolean); + let sourcefile = getFlag(options, keys, "sourcefile", mustBeString); + let loader = getFlag(options, keys, "loader", mustBeString); + let banner = getFlag(options, keys, "banner", mustBeString); + let footer = getFlag(options, keys, "footer", mustBeString); + let mangleCache = getFlag(options, keys, "mangleCache", mustBeObject); + checkForInvalidFlags(options, keys, `in ${callName}() call`); + if (sourcemap) flags.push(`--sourcemap=${sourcemap === true ? "external" : sourcemap}`); + if (sourcefile) flags.push(`--sourcefile=${sourcefile}`); + if (loader) flags.push(`--loader=${loader}`); + if (banner) flags.push(`--banner=${banner}`); + if (footer) flags.push(`--footer=${footer}`); + return { + flags, + mangleCache: validateMangleCache(mangleCache) + }; +} +function createChannel(streamIn) { + const requestCallbacksByKey = {}; + const closeData = { didClose: false, reason: "" }; + let responseCallbacks = {}; + let nextRequestID = 0; + let nextBuildKey = 0; + let stdout = new Uint8Array(16 * 1024); + let stdoutUsed = 0; + let readFromStdout = (chunk) => { + let limit = stdoutUsed + chunk.length; + if (limit > stdout.length) { + let swap = new Uint8Array(limit * 2); + swap.set(stdout); + stdout = swap; + } + stdout.set(chunk, stdoutUsed); + stdoutUsed += chunk.length; + let offset = 0; + while (offset + 4 <= stdoutUsed) { + let length = readUInt32LE(stdout, offset); + if (offset + 4 + length > stdoutUsed) { + break; + } + offset += 4; + handleIncomingPacket(stdout.subarray(offset, offset + length)); + offset += length; + } + if (offset > 0) { + stdout.copyWithin(0, offset, stdoutUsed); + stdoutUsed -= offset; + } + }; + let afterClose = (error) => { + closeData.didClose = true; + if (error) closeData.reason = ": " + (error.message || error); + const text = "The service was stopped" + closeData.reason; + for (let id in responseCallbacks) { + responseCallbacks[id](text, null); + } + responseCallbacks = {}; + }; + let sendRequest = (refs, value, callback) => { + if (closeData.didClose) return callback("The service is no longer running" + closeData.reason, null); + let id = nextRequestID++; + responseCallbacks[id] = (error, response) => { + try { + callback(error, response); + } finally { + if (refs) refs.unref(); + } + }; + if (refs) refs.ref(); + streamIn.writeToStdin(encodePacket({ id, isRequest: true, value })); + }; + let sendResponse = (id, value) => { + if (closeData.didClose) throw new Error("The service is no longer running" + closeData.reason); + streamIn.writeToStdin(encodePacket({ id, isRequest: false, value })); + }; + let handleRequest = async (id, request) => { + try { + if (request.command === "ping") { + sendResponse(id, {}); + return; + } + if (typeof request.key === "number") { + const requestCallbacks = requestCallbacksByKey[request.key]; + if (!requestCallbacks) { + return; + } + const callback = requestCallbacks[request.command]; + if (callback) { + await callback(id, request); + return; + } + } + throw new Error(`Invalid command: ` + request.command); + } catch (e) { + const errors = [extractErrorMessageV8(e, streamIn, null, void 0, "")]; + try { + sendResponse(id, { errors }); + } catch { + } + } + }; + let isFirstPacket = true; + let handleIncomingPacket = (bytes) => { + if (isFirstPacket) { + isFirstPacket = false; + let binaryVersion = String.fromCharCode(...bytes); + if (binaryVersion !== "0.25.9") { + throw new Error(`Cannot start service: Host version "${"0.25.9"}" does not match binary version ${quote(binaryVersion)}`); + } + return; + } + let packet = decodePacket(bytes); + if (packet.isRequest) { + handleRequest(packet.id, packet.value); + } else { + let callback = responseCallbacks[packet.id]; + delete responseCallbacks[packet.id]; + if (packet.value.error) callback(packet.value.error, {}); + else callback(null, packet.value); + } + }; + let buildOrContext = ({ callName, refs, options, isTTY: isTTY2, defaultWD: defaultWD2, callback }) => { + let refCount = 0; + const buildKey = nextBuildKey++; + const requestCallbacks = {}; + const buildRefs = { + ref() { + if (++refCount === 1) { + if (refs) refs.ref(); + } + }, + unref() { + if (--refCount === 0) { + delete requestCallbacksByKey[buildKey]; + if (refs) refs.unref(); + } + } + }; + requestCallbacksByKey[buildKey] = requestCallbacks; + buildRefs.ref(); + buildOrContextImpl( + callName, + buildKey, + sendRequest, + sendResponse, + buildRefs, + streamIn, + requestCallbacks, + options, + isTTY2, + defaultWD2, + (err, res) => { + try { + callback(err, res); + } finally { + buildRefs.unref(); + } + } + ); + }; + let transform2 = ({ callName, refs, input, options, isTTY: isTTY2, fs: fs3, callback }) => { + const details = createObjectStash(); + let start = (inputPath) => { + try { + if (typeof input !== "string" && !(input instanceof Uint8Array)) + throw new Error('The input to "transform" must be a string or a Uint8Array'); + let { + flags, + mangleCache + } = flagsForTransformOptions(callName, options, isTTY2, transformLogLevelDefault); + let request = { + command: "transform", + flags, + inputFS: inputPath !== null, + input: inputPath !== null ? encodeUTF8(inputPath) : typeof input === "string" ? encodeUTF8(input) : input + }; + if (mangleCache) request.mangleCache = mangleCache; + sendRequest(refs, request, (error, response) => { + if (error) return callback(new Error(error), null); + let errors = replaceDetailsInMessages(response.errors, details); + let warnings = replaceDetailsInMessages(response.warnings, details); + let outstanding = 1; + let next = () => { + if (--outstanding === 0) { + let result = { + warnings, + code: response.code, + map: response.map, + mangleCache: void 0, + legalComments: void 0 + }; + if ("legalComments" in response) result.legalComments = response == null ? void 0 : response.legalComments; + if (response.mangleCache) result.mangleCache = response == null ? void 0 : response.mangleCache; + callback(null, result); + } + }; + if (errors.length > 0) return callback(failureErrorWithLog("Transform failed", errors, warnings), null); + if (response.codeFS) { + outstanding++; + fs3.readFile(response.code, (err, contents) => { + if (err !== null) { + callback(err, null); + } else { + response.code = contents; + next(); + } + }); + } + if (response.mapFS) { + outstanding++; + fs3.readFile(response.map, (err, contents) => { + if (err !== null) { + callback(err, null); + } else { + response.map = contents; + next(); + } + }); + } + next(); + }); + } catch (e) { + let flags = []; + try { + pushLogFlags(flags, options, {}, isTTY2, transformLogLevelDefault); + } catch { + } + const error = extractErrorMessageV8(e, streamIn, details, void 0, ""); + sendRequest(refs, { command: "error", flags, error }, () => { + error.detail = details.load(error.detail); + callback(failureErrorWithLog("Transform failed", [error], []), null); + }); + } + }; + if ((typeof input === "string" || input instanceof Uint8Array) && input.length > 1024 * 1024) { + let next = start; + start = () => fs3.writeFile(input, next); + } + start(null); + }; + let formatMessages2 = ({ callName, refs, messages, options, callback }) => { + if (!options) throw new Error(`Missing second argument in ${callName}() call`); + let keys = {}; + let kind = getFlag(options, keys, "kind", mustBeString); + let color = getFlag(options, keys, "color", mustBeBoolean); + let terminalWidth = getFlag(options, keys, "terminalWidth", mustBeInteger); + checkForInvalidFlags(options, keys, `in ${callName}() call`); + if (kind === void 0) throw new Error(`Missing "kind" in ${callName}() call`); + if (kind !== "error" && kind !== "warning") throw new Error(`Expected "kind" to be "error" or "warning" in ${callName}() call`); + let request = { + command: "format-msgs", + messages: sanitizeMessages(messages, "messages", null, "", terminalWidth), + isWarning: kind === "warning" + }; + if (color !== void 0) request.color = color; + if (terminalWidth !== void 0) request.terminalWidth = terminalWidth; + sendRequest(refs, request, (error, response) => { + if (error) return callback(new Error(error), null); + callback(null, response.messages); + }); + }; + let analyzeMetafile2 = ({ callName, refs, metafile, options, callback }) => { + if (options === void 0) options = {}; + let keys = {}; + let color = getFlag(options, keys, "color", mustBeBoolean); + let verbose = getFlag(options, keys, "verbose", mustBeBoolean); + checkForInvalidFlags(options, keys, `in ${callName}() call`); + let request = { + command: "analyze-metafile", + metafile + }; + if (color !== void 0) request.color = color; + if (verbose !== void 0) request.verbose = verbose; + sendRequest(refs, request, (error, response) => { + if (error) return callback(new Error(error), null); + callback(null, response.result); + }); + }; + return { + readFromStdout, + afterClose, + service: { + buildOrContext, + transform: transform2, + formatMessages: formatMessages2, + analyzeMetafile: analyzeMetafile2 + } + }; +} +function buildOrContextImpl(callName, buildKey, sendRequest, sendResponse, refs, streamIn, requestCallbacks, options, isTTY2, defaultWD2, callback) { + const details = createObjectStash(); + const isContext = callName === "context"; + const handleError = (e, pluginName) => { + const flags = []; + try { + pushLogFlags(flags, options, {}, isTTY2, buildLogLevelDefault); + } catch { + } + const message = extractErrorMessageV8(e, streamIn, details, void 0, pluginName); + sendRequest(refs, { command: "error", flags, error: message }, () => { + message.detail = details.load(message.detail); + callback(failureErrorWithLog(isContext ? "Context failed" : "Build failed", [message], []), null); + }); + }; + let plugins; + if (typeof options === "object") { + const value = options.plugins; + if (value !== void 0) { + if (!Array.isArray(value)) return handleError(new Error(`"plugins" must be an array`), ""); + plugins = value; + } + } + if (plugins && plugins.length > 0) { + if (streamIn.isSync) return handleError(new Error("Cannot use plugins in synchronous API calls"), ""); + handlePlugins( + buildKey, + sendRequest, + sendResponse, + refs, + streamIn, + requestCallbacks, + options, + plugins, + details + ).then( + (result) => { + if (!result.ok) return handleError(result.error, result.pluginName); + try { + buildOrContextContinue(result.requestPlugins, result.runOnEndCallbacks, result.scheduleOnDisposeCallbacks); + } catch (e) { + handleError(e, ""); + } + }, + (e) => handleError(e, "") + ); + return; + } + try { + buildOrContextContinue(null, (result, done) => done([], []), () => { + }); + } catch (e) { + handleError(e, ""); + } + function buildOrContextContinue(requestPlugins, runOnEndCallbacks, scheduleOnDisposeCallbacks) { + const writeDefault = streamIn.hasFS; + const { + entries, + flags, + write, + stdinContents, + stdinResolveDir, + absWorkingDir, + nodePaths, + mangleCache + } = flagsForBuildOptions(callName, options, isTTY2, buildLogLevelDefault, writeDefault); + if (write && !streamIn.hasFS) throw new Error(`The "write" option is unavailable in this environment`); + const request = { + command: "build", + key: buildKey, + entries, + flags, + write, + stdinContents, + stdinResolveDir, + absWorkingDir: absWorkingDir || defaultWD2, + nodePaths, + context: isContext + }; + if (requestPlugins) request.plugins = requestPlugins; + if (mangleCache) request.mangleCache = mangleCache; + const buildResponseToResult = (response, callback2) => { + const result = { + errors: replaceDetailsInMessages(response.errors, details), + warnings: replaceDetailsInMessages(response.warnings, details), + outputFiles: void 0, + metafile: void 0, + mangleCache: void 0 + }; + const originalErrors = result.errors.slice(); + const originalWarnings = result.warnings.slice(); + if (response.outputFiles) result.outputFiles = response.outputFiles.map(convertOutputFiles); + if (response.metafile) result.metafile = JSON.parse(response.metafile); + if (response.mangleCache) result.mangleCache = response.mangleCache; + if (response.writeToStdout !== void 0) console.log(decodeUTF8(response.writeToStdout).replace(/\n$/, "")); + runOnEndCallbacks(result, (onEndErrors, onEndWarnings) => { + if (originalErrors.length > 0 || onEndErrors.length > 0) { + const error = failureErrorWithLog("Build failed", originalErrors.concat(onEndErrors), originalWarnings.concat(onEndWarnings)); + return callback2(error, null, onEndErrors, onEndWarnings); + } + callback2(null, result, onEndErrors, onEndWarnings); + }); + }; + let latestResultPromise; + let provideLatestResult; + if (isContext) + requestCallbacks["on-end"] = (id, request2) => new Promise((resolve) => { + buildResponseToResult(request2, (err, result, onEndErrors, onEndWarnings) => { + const response = { + errors: onEndErrors, + warnings: onEndWarnings + }; + if (provideLatestResult) provideLatestResult(err, result); + latestResultPromise = void 0; + provideLatestResult = void 0; + sendResponse(id, response); + resolve(); + }); + }); + sendRequest(refs, request, (error, response) => { + if (error) return callback(new Error(error), null); + if (!isContext) { + return buildResponseToResult(response, (err, res) => { + scheduleOnDisposeCallbacks(); + return callback(err, res); + }); + } + if (response.errors.length > 0) { + return callback(failureErrorWithLog("Context failed", response.errors, response.warnings), null); + } + let didDispose = false; + const result = { + rebuild: () => { + if (!latestResultPromise) latestResultPromise = new Promise((resolve, reject) => { + let settlePromise; + provideLatestResult = (err, result2) => { + if (!settlePromise) settlePromise = () => err ? reject(err) : resolve(result2); + }; + const triggerAnotherBuild = () => { + const request2 = { + command: "rebuild", + key: buildKey + }; + sendRequest(refs, request2, (error2, response2) => { + if (error2) { + reject(new Error(error2)); + } else if (settlePromise) { + settlePromise(); + } else { + triggerAnotherBuild(); + } + }); + }; + triggerAnotherBuild(); + }); + return latestResultPromise; + }, + watch: (options2 = {}) => new Promise((resolve, reject) => { + if (!streamIn.hasFS) throw new Error(`Cannot use the "watch" API in this environment`); + const keys = {}; + const delay = getFlag(options2, keys, "delay", mustBeInteger); + checkForInvalidFlags(options2, keys, `in watch() call`); + const request2 = { + command: "watch", + key: buildKey + }; + if (delay) request2.delay = delay; + sendRequest(refs, request2, (error2) => { + if (error2) reject(new Error(error2)); + else resolve(void 0); + }); + }), + serve: (options2 = {}) => new Promise((resolve, reject) => { + if (!streamIn.hasFS) throw new Error(`Cannot use the "serve" API in this environment`); + const keys = {}; + const port = getFlag(options2, keys, "port", mustBeValidPortNumber); + const host = getFlag(options2, keys, "host", mustBeString); + const servedir = getFlag(options2, keys, "servedir", mustBeString); + const keyfile = getFlag(options2, keys, "keyfile", mustBeString); + const certfile = getFlag(options2, keys, "certfile", mustBeString); + const fallback = getFlag(options2, keys, "fallback", mustBeString); + const cors = getFlag(options2, keys, "cors", mustBeObject); + const onRequest = getFlag(options2, keys, "onRequest", mustBeFunction); + checkForInvalidFlags(options2, keys, `in serve() call`); + const request2 = { + command: "serve", + key: buildKey, + onRequest: !!onRequest + }; + if (port !== void 0) request2.port = port; + if (host !== void 0) request2.host = host; + if (servedir !== void 0) request2.servedir = servedir; + if (keyfile !== void 0) request2.keyfile = keyfile; + if (certfile !== void 0) request2.certfile = certfile; + if (fallback !== void 0) request2.fallback = fallback; + if (cors) { + const corsKeys = {}; + const origin = getFlag(cors, corsKeys, "origin", mustBeStringOrArrayOfStrings); + checkForInvalidFlags(cors, corsKeys, `on "cors" object`); + if (Array.isArray(origin)) request2.corsOrigin = origin; + else if (origin !== void 0) request2.corsOrigin = [origin]; + } + sendRequest(refs, request2, (error2, response2) => { + if (error2) return reject(new Error(error2)); + if (onRequest) { + requestCallbacks["serve-request"] = (id, request3) => { + onRequest(request3.args); + sendResponse(id, {}); + }; + } + resolve(response2); + }); + }), + cancel: () => new Promise((resolve) => { + if (didDispose) return resolve(); + const request2 = { + command: "cancel", + key: buildKey + }; + sendRequest(refs, request2, () => { + resolve(); + }); + }), + dispose: () => new Promise((resolve) => { + if (didDispose) return resolve(); + didDispose = true; + const request2 = { + command: "dispose", + key: buildKey + }; + sendRequest(refs, request2, () => { + resolve(); + scheduleOnDisposeCallbacks(); + refs.unref(); + }); + }) + }; + refs.ref(); + callback(null, result); + }); + } +} +var handlePlugins = async (buildKey, sendRequest, sendResponse, refs, streamIn, requestCallbacks, initialOptions, plugins, details) => { + let onStartCallbacks = []; + let onEndCallbacks = []; + let onResolveCallbacks = {}; + let onLoadCallbacks = {}; + let onDisposeCallbacks = []; + let nextCallbackID = 0; + let i = 0; + let requestPlugins = []; + let isSetupDone = false; + plugins = [...plugins]; + for (let item of plugins) { + let keys = {}; + if (typeof item !== "object") throw new Error(`Plugin at index ${i} must be an object`); + const name = getFlag(item, keys, "name", mustBeString); + if (typeof name !== "string" || name === "") throw new Error(`Plugin at index ${i} is missing a name`); + try { + let setup = getFlag(item, keys, "setup", mustBeFunction); + if (typeof setup !== "function") throw new Error(`Plugin is missing a setup function`); + checkForInvalidFlags(item, keys, `on plugin ${quote(name)}`); + let plugin = { + name, + onStart: false, + onEnd: false, + onResolve: [], + onLoad: [] + }; + i++; + let resolve = (path3, options = {}) => { + if (!isSetupDone) throw new Error('Cannot call "resolve" before plugin setup has completed'); + if (typeof path3 !== "string") throw new Error(`The path to resolve must be a string`); + let keys2 = /* @__PURE__ */ Object.create(null); + let pluginName = getFlag(options, keys2, "pluginName", mustBeString); + let importer = getFlag(options, keys2, "importer", mustBeString); + let namespace = getFlag(options, keys2, "namespace", mustBeString); + let resolveDir = getFlag(options, keys2, "resolveDir", mustBeString); + let kind = getFlag(options, keys2, "kind", mustBeString); + let pluginData = getFlag(options, keys2, "pluginData", canBeAnything); + let importAttributes = getFlag(options, keys2, "with", mustBeObject); + checkForInvalidFlags(options, keys2, "in resolve() call"); + return new Promise((resolve2, reject) => { + const request = { + command: "resolve", + path: path3, + key: buildKey, + pluginName: name + }; + if (pluginName != null) request.pluginName = pluginName; + if (importer != null) request.importer = importer; + if (namespace != null) request.namespace = namespace; + if (resolveDir != null) request.resolveDir = resolveDir; + if (kind != null) request.kind = kind; + else throw new Error(`Must specify "kind" when calling "resolve"`); + if (pluginData != null) request.pluginData = details.store(pluginData); + if (importAttributes != null) request.with = sanitizeStringMap(importAttributes, "with"); + sendRequest(refs, request, (error, response) => { + if (error !== null) reject(new Error(error)); + else resolve2({ + errors: replaceDetailsInMessages(response.errors, details), + warnings: replaceDetailsInMessages(response.warnings, details), + path: response.path, + external: response.external, + sideEffects: response.sideEffects, + namespace: response.namespace, + suffix: response.suffix, + pluginData: details.load(response.pluginData) + }); + }); + }); + }; + let promise = setup({ + initialOptions, + resolve, + onStart(callback) { + let registeredText = `This error came from the "onStart" callback registered here:`; + let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onStart"); + onStartCallbacks.push({ name, callback, note: registeredNote }); + plugin.onStart = true; + }, + onEnd(callback) { + let registeredText = `This error came from the "onEnd" callback registered here:`; + let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onEnd"); + onEndCallbacks.push({ name, callback, note: registeredNote }); + plugin.onEnd = true; + }, + onResolve(options, callback) { + let registeredText = `This error came from the "onResolve" callback registered here:`; + let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onResolve"); + let keys2 = {}; + let filter = getFlag(options, keys2, "filter", mustBeRegExp); + let namespace = getFlag(options, keys2, "namespace", mustBeString); + checkForInvalidFlags(options, keys2, `in onResolve() call for plugin ${quote(name)}`); + if (filter == null) throw new Error(`onResolve() call is missing a filter`); + let id = nextCallbackID++; + onResolveCallbacks[id] = { name, callback, note: registeredNote }; + plugin.onResolve.push({ id, filter: jsRegExpToGoRegExp(filter), namespace: namespace || "" }); + }, + onLoad(options, callback) { + let registeredText = `This error came from the "onLoad" callback registered here:`; + let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onLoad"); + let keys2 = {}; + let filter = getFlag(options, keys2, "filter", mustBeRegExp); + let namespace = getFlag(options, keys2, "namespace", mustBeString); + checkForInvalidFlags(options, keys2, `in onLoad() call for plugin ${quote(name)}`); + if (filter == null) throw new Error(`onLoad() call is missing a filter`); + let id = nextCallbackID++; + onLoadCallbacks[id] = { name, callback, note: registeredNote }; + plugin.onLoad.push({ id, filter: jsRegExpToGoRegExp(filter), namespace: namespace || "" }); + }, + onDispose(callback) { + onDisposeCallbacks.push(callback); + }, + esbuild: streamIn.esbuild + }); + if (promise) await promise; + requestPlugins.push(plugin); + } catch (e) { + return { ok: false, error: e, pluginName: name }; + } + } + requestCallbacks["on-start"] = async (id, request) => { + details.clear(); + let response = { errors: [], warnings: [] }; + await Promise.all(onStartCallbacks.map(async ({ name, callback, note }) => { + try { + let result = await callback(); + if (result != null) { + if (typeof result !== "object") throw new Error(`Expected onStart() callback in plugin ${quote(name)} to return an object`); + let keys = {}; + let errors = getFlag(result, keys, "errors", mustBeArray); + let warnings = getFlag(result, keys, "warnings", mustBeArray); + checkForInvalidFlags(result, keys, `from onStart() callback in plugin ${quote(name)}`); + if (errors != null) response.errors.push(...sanitizeMessages(errors, "errors", details, name, void 0)); + if (warnings != null) response.warnings.push(...sanitizeMessages(warnings, "warnings", details, name, void 0)); + } + } catch (e) { + response.errors.push(extractErrorMessageV8(e, streamIn, details, note && note(), name)); + } + })); + sendResponse(id, response); + }; + requestCallbacks["on-resolve"] = async (id, request) => { + let response = {}, name = "", callback, note; + for (let id2 of request.ids) { + try { + ({ name, callback, note } = onResolveCallbacks[id2]); + let result = await callback({ + path: request.path, + importer: request.importer, + namespace: request.namespace, + resolveDir: request.resolveDir, + kind: request.kind, + pluginData: details.load(request.pluginData), + with: request.with + }); + if (result != null) { + if (typeof result !== "object") throw new Error(`Expected onResolve() callback in plugin ${quote(name)} to return an object`); + let keys = {}; + let pluginName = getFlag(result, keys, "pluginName", mustBeString); + let path3 = getFlag(result, keys, "path", mustBeString); + let namespace = getFlag(result, keys, "namespace", mustBeString); + let suffix = getFlag(result, keys, "suffix", mustBeString); + let external = getFlag(result, keys, "external", mustBeBoolean); + let sideEffects = getFlag(result, keys, "sideEffects", mustBeBoolean); + let pluginData = getFlag(result, keys, "pluginData", canBeAnything); + let errors = getFlag(result, keys, "errors", mustBeArray); + let warnings = getFlag(result, keys, "warnings", mustBeArray); + let watchFiles = getFlag(result, keys, "watchFiles", mustBeArrayOfStrings); + let watchDirs = getFlag(result, keys, "watchDirs", mustBeArrayOfStrings); + checkForInvalidFlags(result, keys, `from onResolve() callback in plugin ${quote(name)}`); + response.id = id2; + if (pluginName != null) response.pluginName = pluginName; + if (path3 != null) response.path = path3; + if (namespace != null) response.namespace = namespace; + if (suffix != null) response.suffix = suffix; + if (external != null) response.external = external; + if (sideEffects != null) response.sideEffects = sideEffects; + if (pluginData != null) response.pluginData = details.store(pluginData); + if (errors != null) response.errors = sanitizeMessages(errors, "errors", details, name, void 0); + if (warnings != null) response.warnings = sanitizeMessages(warnings, "warnings", details, name, void 0); + if (watchFiles != null) response.watchFiles = sanitizeStringArray(watchFiles, "watchFiles"); + if (watchDirs != null) response.watchDirs = sanitizeStringArray(watchDirs, "watchDirs"); + break; + } + } catch (e) { + response = { id: id2, errors: [extractErrorMessageV8(e, streamIn, details, note && note(), name)] }; + break; + } + } + sendResponse(id, response); + }; + requestCallbacks["on-load"] = async (id, request) => { + let response = {}, name = "", callback, note; + for (let id2 of request.ids) { + try { + ({ name, callback, note } = onLoadCallbacks[id2]); + let result = await callback({ + path: request.path, + namespace: request.namespace, + suffix: request.suffix, + pluginData: details.load(request.pluginData), + with: request.with + }); + if (result != null) { + if (typeof result !== "object") throw new Error(`Expected onLoad() callback in plugin ${quote(name)} to return an object`); + let keys = {}; + let pluginName = getFlag(result, keys, "pluginName", mustBeString); + let contents = getFlag(result, keys, "contents", mustBeStringOrUint8Array); + let resolveDir = getFlag(result, keys, "resolveDir", mustBeString); + let pluginData = getFlag(result, keys, "pluginData", canBeAnything); + let loader = getFlag(result, keys, "loader", mustBeString); + let errors = getFlag(result, keys, "errors", mustBeArray); + let warnings = getFlag(result, keys, "warnings", mustBeArray); + let watchFiles = getFlag(result, keys, "watchFiles", mustBeArrayOfStrings); + let watchDirs = getFlag(result, keys, "watchDirs", mustBeArrayOfStrings); + checkForInvalidFlags(result, keys, `from onLoad() callback in plugin ${quote(name)}`); + response.id = id2; + if (pluginName != null) response.pluginName = pluginName; + if (contents instanceof Uint8Array) response.contents = contents; + else if (contents != null) response.contents = encodeUTF8(contents); + if (resolveDir != null) response.resolveDir = resolveDir; + if (pluginData != null) response.pluginData = details.store(pluginData); + if (loader != null) response.loader = loader; + if (errors != null) response.errors = sanitizeMessages(errors, "errors", details, name, void 0); + if (warnings != null) response.warnings = sanitizeMessages(warnings, "warnings", details, name, void 0); + if (watchFiles != null) response.watchFiles = sanitizeStringArray(watchFiles, "watchFiles"); + if (watchDirs != null) response.watchDirs = sanitizeStringArray(watchDirs, "watchDirs"); + break; + } + } catch (e) { + response = { id: id2, errors: [extractErrorMessageV8(e, streamIn, details, note && note(), name)] }; + break; + } + } + sendResponse(id, response); + }; + let runOnEndCallbacks = (result, done) => done([], []); + if (onEndCallbacks.length > 0) { + runOnEndCallbacks = (result, done) => { + (async () => { + const onEndErrors = []; + const onEndWarnings = []; + for (const { name, callback, note } of onEndCallbacks) { + let newErrors; + let newWarnings; + try { + const value = await callback(result); + if (value != null) { + if (typeof value !== "object") throw new Error(`Expected onEnd() callback in plugin ${quote(name)} to return an object`); + let keys = {}; + let errors = getFlag(value, keys, "errors", mustBeArray); + let warnings = getFlag(value, keys, "warnings", mustBeArray); + checkForInvalidFlags(value, keys, `from onEnd() callback in plugin ${quote(name)}`); + if (errors != null) newErrors = sanitizeMessages(errors, "errors", details, name, void 0); + if (warnings != null) newWarnings = sanitizeMessages(warnings, "warnings", details, name, void 0); + } + } catch (e) { + newErrors = [extractErrorMessageV8(e, streamIn, details, note && note(), name)]; + } + if (newErrors) { + onEndErrors.push(...newErrors); + try { + result.errors.push(...newErrors); + } catch { + } + } + if (newWarnings) { + onEndWarnings.push(...newWarnings); + try { + result.warnings.push(...newWarnings); + } catch { + } + } + } + done(onEndErrors, onEndWarnings); + })(); + }; + } + let scheduleOnDisposeCallbacks = () => { + for (const cb of onDisposeCallbacks) { + setTimeout(() => cb(), 0); + } + }; + isSetupDone = true; + return { + ok: true, + requestPlugins, + runOnEndCallbacks, + scheduleOnDisposeCallbacks + }; +}; +function createObjectStash() { + const map = /* @__PURE__ */ new Map(); + let nextID = 0; + return { + clear() { + map.clear(); + }, + load(id) { + return map.get(id); + }, + store(value) { + if (value === void 0) return -1; + const id = nextID++; + map.set(id, value); + return id; + } + }; +} +function extractCallerV8(e, streamIn, ident) { + let note; + let tried = false; + return () => { + if (tried) return note; + tried = true; + try { + let lines = (e.stack + "").split("\n"); + lines.splice(1, 1); + let location = parseStackLinesV8(streamIn, lines, ident); + if (location) { + note = { text: e.message, location }; + return note; + } + } catch { + } + }; +} +function extractErrorMessageV8(e, streamIn, stash, note, pluginName) { + let text = "Internal error"; + let location = null; + try { + text = (e && e.message || e) + ""; + } catch { + } + try { + location = parseStackLinesV8(streamIn, (e.stack + "").split("\n"), ""); + } catch { + } + return { id: "", pluginName, text, location, notes: note ? [note] : [], detail: stash ? stash.store(e) : -1 }; +} +function parseStackLinesV8(streamIn, lines, ident) { + let at = " at "; + if (streamIn.readFileSync && !lines[0].startsWith(at) && lines[1].startsWith(at)) { + for (let i = 1; i < lines.length; i++) { + let line = lines[i]; + if (!line.startsWith(at)) continue; + line = line.slice(at.length); + while (true) { + let match = /^(?:new |async )?\S+ \((.*)\)$/.exec(line); + if (match) { + line = match[1]; + continue; + } + match = /^eval at \S+ \((.*)\)(?:, \S+:\d+:\d+)?$/.exec(line); + if (match) { + line = match[1]; + continue; + } + match = /^(\S+):(\d+):(\d+)$/.exec(line); + if (match) { + let contents; + try { + contents = streamIn.readFileSync(match[1], "utf8"); + } catch { + break; + } + let lineText = contents.split(/\r\n|\r|\n|\u2028|\u2029/)[+match[2] - 1] || ""; + let column = +match[3] - 1; + let length = lineText.slice(column, column + ident.length) === ident ? ident.length : 0; + return { + file: match[1], + namespace: "file", + line: +match[2], + column: encodeUTF8(lineText.slice(0, column)).length, + length: encodeUTF8(lineText.slice(column, column + length)).length, + lineText: lineText + "\n" + lines.slice(1).join("\n"), + suggestion: "" + }; + } + break; + } + } + } + return null; +} +function failureErrorWithLog(text, errors, warnings) { + let limit = 5; + text += errors.length < 1 ? "" : ` with ${errors.length} error${errors.length < 2 ? "" : "s"}:` + errors.slice(0, limit + 1).map((e, i) => { + if (i === limit) return "\n..."; + if (!e.location) return ` +error: ${e.text}`; + let { file, line, column } = e.location; + let pluginText = e.pluginName ? `[plugin: ${e.pluginName}] ` : ""; + return ` +${file}:${line}:${column}: ERROR: ${pluginText}${e.text}`; + }).join(""); + let error = new Error(text); + for (const [key, value] of [["errors", errors], ["warnings", warnings]]) { + Object.defineProperty(error, key, { + configurable: true, + enumerable: true, + get: () => value, + set: (value2) => Object.defineProperty(error, key, { + configurable: true, + enumerable: true, + value: value2 + }) + }); + } + return error; +} +function replaceDetailsInMessages(messages, stash) { + for (const message of messages) { + message.detail = stash.load(message.detail); + } + return messages; +} +function sanitizeLocation(location, where, terminalWidth) { + if (location == null) return null; + let keys = {}; + let file = getFlag(location, keys, "file", mustBeString); + let namespace = getFlag(location, keys, "namespace", mustBeString); + let line = getFlag(location, keys, "line", mustBeInteger); + let column = getFlag(location, keys, "column", mustBeInteger); + let length = getFlag(location, keys, "length", mustBeInteger); + let lineText = getFlag(location, keys, "lineText", mustBeString); + let suggestion = getFlag(location, keys, "suggestion", mustBeString); + checkForInvalidFlags(location, keys, where); + if (lineText) { + const relevantASCII = lineText.slice( + 0, + (column && column > 0 ? column : 0) + (length && length > 0 ? length : 0) + (terminalWidth && terminalWidth > 0 ? terminalWidth : 80) + ); + if (!/[\x7F-\uFFFF]/.test(relevantASCII) && !/\n/.test(lineText)) { + lineText = relevantASCII; + } + } + return { + file: file || "", + namespace: namespace || "", + line: line || 0, + column: column || 0, + length: length || 0, + lineText: lineText || "", + suggestion: suggestion || "" + }; +} +function sanitizeMessages(messages, property, stash, fallbackPluginName, terminalWidth) { + let messagesClone = []; + let index = 0; + for (const message of messages) { + let keys = {}; + let id = getFlag(message, keys, "id", mustBeString); + let pluginName = getFlag(message, keys, "pluginName", mustBeString); + let text = getFlag(message, keys, "text", mustBeString); + let location = getFlag(message, keys, "location", mustBeObjectOrNull); + let notes = getFlag(message, keys, "notes", mustBeArray); + let detail = getFlag(message, keys, "detail", canBeAnything); + let where = `in element ${index} of "${property}"`; + checkForInvalidFlags(message, keys, where); + let notesClone = []; + if (notes) { + for (const note of notes) { + let noteKeys = {}; + let noteText = getFlag(note, noteKeys, "text", mustBeString); + let noteLocation = getFlag(note, noteKeys, "location", mustBeObjectOrNull); + checkForInvalidFlags(note, noteKeys, where); + notesClone.push({ + text: noteText || "", + location: sanitizeLocation(noteLocation, where, terminalWidth) + }); + } + } + messagesClone.push({ + id: id || "", + pluginName: pluginName || fallbackPluginName, + text: text || "", + location: sanitizeLocation(location, where, terminalWidth), + notes: notesClone, + detail: stash ? stash.store(detail) : -1 + }); + index++; + } + return messagesClone; +} +function sanitizeStringArray(values, property) { + const result = []; + for (const value of values) { + if (typeof value !== "string") throw new Error(`${quote(property)} must be an array of strings`); + result.push(value); + } + return result; +} +function sanitizeStringMap(map, property) { + const result = /* @__PURE__ */ Object.create(null); + for (const key in map) { + const value = map[key]; + if (typeof value !== "string") throw new Error(`key ${quote(key)} in object ${quote(property)} must be a string`); + result[key] = value; + } + return result; +} +function convertOutputFiles({ path: path3, contents, hash }) { + let text = null; + return { + path: path3, + contents, + hash, + get text() { + const binary = this.contents; + if (text === null || binary !== contents) { + contents = binary; + text = decodeUTF8(binary); + } + return text; + } + }; +} +function jsRegExpToGoRegExp(regexp) { + let result = regexp.source; + if (regexp.flags) result = `(?${regexp.flags})${result}`; + return result; +} + +// lib/npm/node-platform.ts +var fs = require("fs"); +var os = require("os"); +var path = require("path"); +var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH; +var isValidBinaryPath = (x) => !!x && x !== "/usr/bin/esbuild"; +var packageDarwin_arm64 = "@esbuild/darwin-arm64"; +var packageDarwin_x64 = "@esbuild/darwin-x64"; +var knownWindowsPackages = { + "win32 arm64 LE": "@esbuild/win32-arm64", + "win32 ia32 LE": "@esbuild/win32-ia32", + "win32 x64 LE": "@esbuild/win32-x64" +}; +var knownUnixlikePackages = { + "aix ppc64 BE": "@esbuild/aix-ppc64", + "android arm64 LE": "@esbuild/android-arm64", + "darwin arm64 LE": "@esbuild/darwin-arm64", + "darwin x64 LE": "@esbuild/darwin-x64", + "freebsd arm64 LE": "@esbuild/freebsd-arm64", + "freebsd x64 LE": "@esbuild/freebsd-x64", + "linux arm LE": "@esbuild/linux-arm", + "linux arm64 LE": "@esbuild/linux-arm64", + "linux ia32 LE": "@esbuild/linux-ia32", + "linux mips64el LE": "@esbuild/linux-mips64el", + "linux ppc64 LE": "@esbuild/linux-ppc64", + "linux riscv64 LE": "@esbuild/linux-riscv64", + "linux s390x BE": "@esbuild/linux-s390x", + "linux x64 LE": "@esbuild/linux-x64", + "linux loong64 LE": "@esbuild/linux-loong64", + "netbsd arm64 LE": "@esbuild/netbsd-arm64", + "netbsd x64 LE": "@esbuild/netbsd-x64", + "openbsd arm64 LE": "@esbuild/openbsd-arm64", + "openbsd x64 LE": "@esbuild/openbsd-x64", + "sunos x64 LE": "@esbuild/sunos-x64" +}; +var knownWebAssemblyFallbackPackages = { + "android arm LE": "@esbuild/android-arm", + "android x64 LE": "@esbuild/android-x64", + "openharmony arm64 LE": "@esbuild/openharmony-arm64" +}; +function pkgAndSubpathForCurrentPlatform() { + let pkg; + let subpath; + let isWASM = false; + let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`; + if (platformKey in knownWindowsPackages) { + pkg = knownWindowsPackages[platformKey]; + subpath = "esbuild.exe"; + } else if (platformKey in knownUnixlikePackages) { + pkg = knownUnixlikePackages[platformKey]; + subpath = "bin/esbuild"; + } else if (platformKey in knownWebAssemblyFallbackPackages) { + pkg = knownWebAssemblyFallbackPackages[platformKey]; + subpath = "bin/esbuild"; + isWASM = true; + } else { + throw new Error(`Unsupported platform: ${platformKey}`); + } + return { pkg, subpath, isWASM }; +} +function pkgForSomeOtherPlatform() { + const libMainJS = require.resolve("esbuild"); + const nodeModulesDirectory = path.dirname(path.dirname(path.dirname(libMainJS))); + if (path.basename(nodeModulesDirectory) === "node_modules") { + for (const unixKey in knownUnixlikePackages) { + try { + const pkg = knownUnixlikePackages[unixKey]; + if (fs.existsSync(path.join(nodeModulesDirectory, pkg))) return pkg; + } catch { + } + } + for (const windowsKey in knownWindowsPackages) { + try { + const pkg = knownWindowsPackages[windowsKey]; + if (fs.existsSync(path.join(nodeModulesDirectory, pkg))) return pkg; + } catch { + } + } + } + return null; +} +function downloadedBinPath(pkg, subpath) { + const esbuildLibDir = path.dirname(require.resolve("esbuild")); + return path.join(esbuildLibDir, `downloaded-${pkg.replace("/", "-")}-${path.basename(subpath)}`); +} +function generateBinPath() { + if (isValidBinaryPath(ESBUILD_BINARY_PATH)) { + if (!fs.existsSync(ESBUILD_BINARY_PATH)) { + console.warn(`[esbuild] Ignoring bad configuration: ESBUILD_BINARY_PATH=${ESBUILD_BINARY_PATH}`); + } else { + return { binPath: ESBUILD_BINARY_PATH, isWASM: false }; + } + } + const { pkg, subpath, isWASM } = pkgAndSubpathForCurrentPlatform(); + let binPath; + try { + binPath = require.resolve(`${pkg}/${subpath}`); + } catch (e) { + binPath = downloadedBinPath(pkg, subpath); + if (!fs.existsSync(binPath)) { + try { + require.resolve(pkg); + } catch { + const otherPkg = pkgForSomeOtherPlatform(); + if (otherPkg) { + let suggestions = ` +Specifically the "${otherPkg}" package is present but this platform +needs the "${pkg}" package instead. People often get into this +situation by installing esbuild on Windows or macOS and copying "node_modules" +into a Docker image that runs Linux, or by copying "node_modules" between +Windows and WSL environments. + +If you are installing with npm, you can try not copying the "node_modules" +directory when you copy the files over, and running "npm ci" or "npm install" +on the destination platform after the copy. Or you could consider using yarn +instead of npm which has built-in support for installing a package on multiple +platforms simultaneously. + +If you are installing with yarn, you can try listing both this platform and the +other platform in your ".yarnrc.yml" file using the "supportedArchitectures" +feature: https://yarnpkg.com/configuration/yarnrc/#supportedArchitectures +Keep in mind that this means multiple copies of esbuild will be present. +`; + if (pkg === packageDarwin_x64 && otherPkg === packageDarwin_arm64 || pkg === packageDarwin_arm64 && otherPkg === packageDarwin_x64) { + suggestions = ` +Specifically the "${otherPkg}" package is present but this platform +needs the "${pkg}" package instead. People often get into this +situation by installing esbuild with npm running inside of Rosetta 2 and then +trying to use it with node running outside of Rosetta 2, or vice versa (Rosetta +2 is Apple's on-the-fly x86_64-to-arm64 translation service). + +If you are installing with npm, you can try ensuring that both npm and node are +not running under Rosetta 2 and then reinstalling esbuild. This likely involves +changing how you installed npm and/or node. For example, installing node with +the universal installer here should work: https://nodejs.org/en/download/. Or +you could consider using yarn instead of npm which has built-in support for +installing a package on multiple platforms simultaneously. + +If you are installing with yarn, you can try listing both "arm64" and "x64" +in your ".yarnrc.yml" file using the "supportedArchitectures" feature: +https://yarnpkg.com/configuration/yarnrc/#supportedArchitectures +Keep in mind that this means multiple copies of esbuild will be present. +`; + } + throw new Error(` +You installed esbuild for another platform than the one you're currently using. +This won't work because esbuild is written with native code and needs to +install a platform-specific binary executable. +${suggestions} +Another alternative is to use the "esbuild-wasm" package instead, which works +the same way on all platforms. But it comes with a heavy performance cost and +can sometimes be 10x slower than the "esbuild" package, so you may also not +want to do that. +`); + } + throw new Error(`The package "${pkg}" could not be found, and is needed by esbuild. + +If you are installing esbuild with npm, make sure that you don't specify the +"--no-optional" or "--omit=optional" flags. The "optionalDependencies" feature +of "package.json" is used by esbuild to install the correct binary executable +for your current platform.`); + } + throw e; + } + } + if (/\.zip\//.test(binPath)) { + let pnpapi; + try { + pnpapi = require("pnpapi"); + } catch (e) { + } + if (pnpapi) { + const root = pnpapi.getPackageInformation(pnpapi.topLevel).packageLocation; + const binTargetPath = path.join( + root, + "node_modules", + ".cache", + "esbuild", + `pnpapi-${pkg.replace("/", "-")}-${"0.25.9"}-${path.basename(subpath)}` + ); + if (!fs.existsSync(binTargetPath)) { + fs.mkdirSync(path.dirname(binTargetPath), { recursive: true }); + fs.copyFileSync(binPath, binTargetPath); + fs.chmodSync(binTargetPath, 493); + } + return { binPath: binTargetPath, isWASM }; + } + } + return { binPath, isWASM }; +} + +// lib/npm/node.ts +var child_process = require("child_process"); +var crypto = require("crypto"); +var path2 = require("path"); +var fs2 = require("fs"); +var os2 = require("os"); +var tty = require("tty"); +var worker_threads; +if (process.env.ESBUILD_WORKER_THREADS !== "0") { + try { + worker_threads = require("worker_threads"); + } catch { + } + let [major, minor] = process.versions.node.split("."); + if ( + // { + if ((!ESBUILD_BINARY_PATH || false) && (path2.basename(__filename) !== "main.js" || path2.basename(__dirname) !== "lib")) { + throw new Error( + `The esbuild JavaScript API cannot be bundled. Please mark the "esbuild" package as external so it's not included in the bundle. + +More information: The file containing the code for esbuild's JavaScript API (${__filename}) does not appear to be inside the esbuild package on the file system, which usually means that the esbuild package was bundled into another file. This is problematic because the API needs to run a binary executable inside the esbuild package which is located using a relative path from the API code to the executable. If the esbuild package is bundled, the relative path will be incorrect and the executable won't be found.` + ); + } + if (false) { + return ["node", [path2.join(__dirname, "..", "bin", "esbuild")]]; + } else { + const { binPath, isWASM } = generateBinPath(); + if (isWASM) { + return ["node", [binPath]]; + } else { + return [binPath, []]; + } + } +}; +var isTTY = () => tty.isatty(2); +var fsSync = { + readFile(tempFile, callback) { + try { + let contents = fs2.readFileSync(tempFile, "utf8"); + try { + fs2.unlinkSync(tempFile); + } catch { + } + callback(null, contents); + } catch (err) { + callback(err, null); + } + }, + writeFile(contents, callback) { + try { + let tempFile = randomFileName(); + fs2.writeFileSync(tempFile, contents); + callback(tempFile); + } catch { + callback(null); + } + } +}; +var fsAsync = { + readFile(tempFile, callback) { + try { + fs2.readFile(tempFile, "utf8", (err, contents) => { + try { + fs2.unlink(tempFile, () => callback(err, contents)); + } catch { + callback(err, contents); + } + }); + } catch (err) { + callback(err, null); + } + }, + writeFile(contents, callback) { + try { + let tempFile = randomFileName(); + fs2.writeFile(tempFile, contents, (err) => err !== null ? callback(null) : callback(tempFile)); + } catch { + callback(null); + } + } +}; +var version = "0.25.9"; +var build = (options) => ensureServiceIsRunning().build(options); +var context = (buildOptions) => ensureServiceIsRunning().context(buildOptions); +var transform = (input, options) => ensureServiceIsRunning().transform(input, options); +var formatMessages = (messages, options) => ensureServiceIsRunning().formatMessages(messages, options); +var analyzeMetafile = (messages, options) => ensureServiceIsRunning().analyzeMetafile(messages, options); +var buildSync = (options) => { + if (worker_threads && !isInternalWorkerThread) { + if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads); + return workerThreadService.buildSync(options); + } + let result; + runServiceSync((service) => service.buildOrContext({ + callName: "buildSync", + refs: null, + options, + isTTY: isTTY(), + defaultWD, + callback: (err, res) => { + if (err) throw err; + result = res; + } + })); + return result; +}; +var transformSync = (input, options) => { + if (worker_threads && !isInternalWorkerThread) { + if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads); + return workerThreadService.transformSync(input, options); + } + let result; + runServiceSync((service) => service.transform({ + callName: "transformSync", + refs: null, + input, + options: options || {}, + isTTY: isTTY(), + fs: fsSync, + callback: (err, res) => { + if (err) throw err; + result = res; + } + })); + return result; +}; +var formatMessagesSync = (messages, options) => { + if (worker_threads && !isInternalWorkerThread) { + if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads); + return workerThreadService.formatMessagesSync(messages, options); + } + let result; + runServiceSync((service) => service.formatMessages({ + callName: "formatMessagesSync", + refs: null, + messages, + options, + callback: (err, res) => { + if (err) throw err; + result = res; + } + })); + return result; +}; +var analyzeMetafileSync = (metafile, options) => { + if (worker_threads && !isInternalWorkerThread) { + if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads); + return workerThreadService.analyzeMetafileSync(metafile, options); + } + let result; + runServiceSync((service) => service.analyzeMetafile({ + callName: "analyzeMetafileSync", + refs: null, + metafile: typeof metafile === "string" ? metafile : JSON.stringify(metafile), + options, + callback: (err, res) => { + if (err) throw err; + result = res; + } + })); + return result; +}; +var stop = () => { + if (stopService) stopService(); + if (workerThreadService) workerThreadService.stop(); + return Promise.resolve(); +}; +var initializeWasCalled = false; +var initialize = (options) => { + options = validateInitializeOptions(options || {}); + if (options.wasmURL) throw new Error(`The "wasmURL" option only works in the browser`); + if (options.wasmModule) throw new Error(`The "wasmModule" option only works in the browser`); + if (options.worker) throw new Error(`The "worker" option only works in the browser`); + if (initializeWasCalled) throw new Error('Cannot call "initialize" more than once'); + ensureServiceIsRunning(); + initializeWasCalled = true; + return Promise.resolve(); +}; +var defaultWD = process.cwd(); +var longLivedService; +var stopService; +var ensureServiceIsRunning = () => { + if (longLivedService) return longLivedService; + let [command, args] = esbuildCommandAndArgs(); + let child = child_process.spawn(command, args.concat(`--service=${"0.25.9"}`, "--ping"), { + windowsHide: true, + stdio: ["pipe", "pipe", "inherit"], + cwd: defaultWD + }); + let { readFromStdout, afterClose, service } = createChannel({ + writeToStdin(bytes) { + child.stdin.write(bytes, (err) => { + if (err) afterClose(err); + }); + }, + readFileSync: fs2.readFileSync, + isSync: false, + hasFS: true, + esbuild: node_exports + }); + child.stdin.on("error", afterClose); + child.on("error", afterClose); + const stdin = child.stdin; + const stdout = child.stdout; + stdout.on("data", readFromStdout); + stdout.on("end", afterClose); + stopService = () => { + stdin.destroy(); + stdout.destroy(); + child.kill(); + initializeWasCalled = false; + longLivedService = void 0; + stopService = void 0; + }; + let refCount = 0; + child.unref(); + if (stdin.unref) { + stdin.unref(); + } + if (stdout.unref) { + stdout.unref(); + } + const refs = { + ref() { + if (++refCount === 1) child.ref(); + }, + unref() { + if (--refCount === 0) child.unref(); + } + }; + longLivedService = { + build: (options) => new Promise((resolve, reject) => { + service.buildOrContext({ + callName: "build", + refs, + options, + isTTY: isTTY(), + defaultWD, + callback: (err, res) => err ? reject(err) : resolve(res) + }); + }), + context: (options) => new Promise((resolve, reject) => service.buildOrContext({ + callName: "context", + refs, + options, + isTTY: isTTY(), + defaultWD, + callback: (err, res) => err ? reject(err) : resolve(res) + })), + transform: (input, options) => new Promise((resolve, reject) => service.transform({ + callName: "transform", + refs, + input, + options: options || {}, + isTTY: isTTY(), + fs: fsAsync, + callback: (err, res) => err ? reject(err) : resolve(res) + })), + formatMessages: (messages, options) => new Promise((resolve, reject) => service.formatMessages({ + callName: "formatMessages", + refs, + messages, + options, + callback: (err, res) => err ? reject(err) : resolve(res) + })), + analyzeMetafile: (metafile, options) => new Promise((resolve, reject) => service.analyzeMetafile({ + callName: "analyzeMetafile", + refs, + metafile: typeof metafile === "string" ? metafile : JSON.stringify(metafile), + options, + callback: (err, res) => err ? reject(err) : resolve(res) + })) + }; + return longLivedService; +}; +var runServiceSync = (callback) => { + let [command, args] = esbuildCommandAndArgs(); + let stdin = new Uint8Array(); + let { readFromStdout, afterClose, service } = createChannel({ + writeToStdin(bytes) { + if (stdin.length !== 0) throw new Error("Must run at most one command"); + stdin = bytes; + }, + isSync: true, + hasFS: true, + esbuild: node_exports + }); + callback(service); + let stdout = child_process.execFileSync(command, args.concat(`--service=${"0.25.9"}`), { + cwd: defaultWD, + windowsHide: true, + input: stdin, + // We don't know how large the output could be. If it's too large, the + // command will fail with ENOBUFS. Reserve 16mb for now since that feels + // like it should be enough. Also allow overriding this with an environment + // variable. + maxBuffer: +process.env.ESBUILD_MAX_BUFFER || 16 * 1024 * 1024 + }); + readFromStdout(stdout); + afterClose(null); +}; +var randomFileName = () => { + return path2.join(os2.tmpdir(), `esbuild-${crypto.randomBytes(32).toString("hex")}`); +}; +var workerThreadService = null; +var startWorkerThreadService = (worker_threads2) => { + let { port1: mainPort, port2: workerPort } = new worker_threads2.MessageChannel(); + let worker = new worker_threads2.Worker(__filename, { + workerData: { workerPort, defaultWD, esbuildVersion: "0.25.9" }, + transferList: [workerPort], + // From node's documentation: https://nodejs.org/api/worker_threads.html + // + // Take care when launching worker threads from preload scripts (scripts loaded + // and run using the `-r` command line flag). Unless the `execArgv` option is + // explicitly set, new Worker threads automatically inherit the command line flags + // from the running process and will preload the same preload scripts as the main + // thread. If the preload script unconditionally launches a worker thread, every + // thread spawned will spawn another until the application crashes. + // + execArgv: [] + }); + let nextID = 0; + let fakeBuildError = (text) => { + let error = new Error(`Build failed with 1 error: +error: ${text}`); + let errors = [{ id: "", pluginName: "", text, location: null, notes: [], detail: void 0 }]; + error.errors = errors; + error.warnings = []; + return error; + }; + let validateBuildSyncOptions = (options) => { + if (!options) return; + let plugins = options.plugins; + if (plugins && plugins.length > 0) throw fakeBuildError(`Cannot use plugins in synchronous API calls`); + }; + let applyProperties = (object, properties) => { + for (let key in properties) { + object[key] = properties[key]; + } + }; + let runCallSync = (command, args) => { + let id = nextID++; + let sharedBuffer = new SharedArrayBuffer(8); + let sharedBufferView = new Int32Array(sharedBuffer); + let msg = { sharedBuffer, id, command, args }; + worker.postMessage(msg); + let status = Atomics.wait(sharedBufferView, 0, 0); + if (status !== "ok" && status !== "not-equal") throw new Error("Internal error: Atomics.wait() failed: " + status); + let { message: { id: id2, resolve, reject, properties } } = worker_threads2.receiveMessageOnPort(mainPort); + if (id !== id2) throw new Error(`Internal error: Expected id ${id} but got id ${id2}`); + if (reject) { + applyProperties(reject, properties); + throw reject; + } + return resolve; + }; + worker.unref(); + return { + buildSync(options) { + validateBuildSyncOptions(options); + return runCallSync("build", [options]); + }, + transformSync(input, options) { + return runCallSync("transform", [input, options]); + }, + formatMessagesSync(messages, options) { + return runCallSync("formatMessages", [messages, options]); + }, + analyzeMetafileSync(metafile, options) { + return runCallSync("analyzeMetafile", [metafile, options]); + }, + stop() { + worker.terminate(); + workerThreadService = null; + } + }; +}; +var startSyncServiceWorker = () => { + let workerPort = worker_threads.workerData.workerPort; + let parentPort = worker_threads.parentPort; + let extractProperties = (object) => { + let properties = {}; + if (object && typeof object === "object") { + for (let key in object) { + properties[key] = object[key]; + } + } + return properties; + }; + try { + let service = ensureServiceIsRunning(); + defaultWD = worker_threads.workerData.defaultWD; + parentPort.on("message", (msg) => { + (async () => { + let { sharedBuffer, id, command, args } = msg; + let sharedBufferView = new Int32Array(sharedBuffer); + try { + switch (command) { + case "build": + workerPort.postMessage({ id, resolve: await service.build(args[0]) }); + break; + case "transform": + workerPort.postMessage({ id, resolve: await service.transform(args[0], args[1]) }); + break; + case "formatMessages": + workerPort.postMessage({ id, resolve: await service.formatMessages(args[0], args[1]) }); + break; + case "analyzeMetafile": + workerPort.postMessage({ id, resolve: await service.analyzeMetafile(args[0], args[1]) }); + break; + default: + throw new Error(`Invalid command: ${command}`); + } + } catch (reject) { + workerPort.postMessage({ id, reject, properties: extractProperties(reject) }); + } + Atomics.add(sharedBufferView, 0, 1); + Atomics.notify(sharedBufferView, 0, Infinity); + })(); + }); + } catch (reject) { + parentPort.on("message", (msg) => { + let { sharedBuffer, id } = msg; + let sharedBufferView = new Int32Array(sharedBuffer); + workerPort.postMessage({ id, reject, properties: extractProperties(reject) }); + Atomics.add(sharedBufferView, 0, 1); + Atomics.notify(sharedBufferView, 0, Infinity); + }); + } +}; +if (isInternalWorkerThread) { + startSyncServiceWorker(); +} +var node_default = node_exports; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + analyzeMetafile, + analyzeMetafileSync, + build, + buildSync, + context, + formatMessages, + formatMessagesSync, + initialize, + stop, + transform, + transformSync, + version +}); diff --git a/node_modules/esbuild/package.json b/node_modules/esbuild/package.json new file mode 100644 index 0000000000..43c34ad2ab --- /dev/null +++ b/node_modules/esbuild/package.json @@ -0,0 +1,49 @@ +{ + "name": "esbuild", + "version": "0.25.9", + "description": "An extremely fast JavaScript and CSS bundler and minifier.", + "repository": { + "type": "git", + "url": "git+https://github.com/evanw/esbuild.git" + }, + "scripts": { + "postinstall": "node install.js" + }, + "main": "lib/main.js", + "types": "lib/main.d.ts", + "engines": { + "node": ">=18" + }, + "bin": { + "esbuild": "bin/esbuild" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" + }, + "license": "MIT" +} diff --git a/node_modules/estree-walker/LICENSE b/node_modules/estree-walker/LICENSE new file mode 100644 index 0000000000..63b62098ee --- /dev/null +++ b/node_modules/estree-walker/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2015-20 [these people](https://github.com/Rich-Harris/estree-walker/graphs/contributors) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/estree-walker/README.md b/node_modules/estree-walker/README.md new file mode 100644 index 0000000000..d739d1bf18 --- /dev/null +++ b/node_modules/estree-walker/README.md @@ -0,0 +1,48 @@ +# estree-walker + +Simple utility for walking an [ESTree](https://github.com/estree/estree)-compliant AST, such as one generated by [acorn](https://github.com/marijnh/acorn). + + +## Installation + +```bash +npm i estree-walker +``` + + +## Usage + +```js +var walk = require('estree-walker').walk; +var acorn = require('acorn'); + +ast = acorn.parse(sourceCode, options); // https://github.com/acornjs/acorn + +walk(ast, { + enter(node, parent, prop, index) { + // some code happens + }, + leave(node, parent, prop, index) { + // some code happens + } +}); +``` + +Inside the `enter` function, calling `this.skip()` will prevent the node's children being walked, or the `leave` function (which is optional) being called. + +Call `this.replace(new_node)` in either `enter` or `leave` to replace the current node with a new one. + +Call `this.remove()` in either `enter` or `leave` to remove the current node. + +## Why not use estraverse? + +The ESTree spec is evolving to accommodate ES6/7. I've had a couple of experiences where [estraverse](https://github.com/estools/estraverse) was unable to handle an AST generated by recent versions of acorn, because it hard-codes visitor keys. + +estree-walker, by contrast, simply enumerates a node's properties to find child nodes (and child lists of nodes), and is therefore resistant to spec changes. It's also much smaller. (The performance, if you're wondering, is basically identical.) + +None of which should be taken as criticism of estraverse, which has more features and has been battle-tested in many more situations, and for which I'm very grateful. + + +## License + +MIT diff --git a/node_modules/estree-walker/package.json b/node_modules/estree-walker/package.json new file mode 100644 index 0000000000..c9f54edd9f --- /dev/null +++ b/node_modules/estree-walker/package.json @@ -0,0 +1,38 @@ +{ + "name": "estree-walker", + "description": "Traverse an ESTree-compliant AST", + "version": "3.0.3", + "private": false, + "author": "Rich Harris", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/Rich-Harris/estree-walker" + }, + "type": "module", + "module": "./src/index.js", + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./types/index.d.ts", + "import": "./src/index.js" + } + }, + "types": "types/index.d.ts", + "scripts": { + "prepublishOnly": "tsc && npm test", + "test": "uvu test" + }, + "dependencies": { + "@types/estree": "^1.0.0" + }, + "devDependencies": { + "typescript": "^4.9.0", + "uvu": "^0.5.1" + }, + "files": [ + "src", + "types", + "README.md" + ] +} diff --git a/node_modules/estree-walker/src/async.js b/node_modules/estree-walker/src/async.js new file mode 100644 index 0000000000..f068c713c4 --- /dev/null +++ b/node_modules/estree-walker/src/async.js @@ -0,0 +1,152 @@ +import { WalkerBase } from './walker.js'; + +/** + * @typedef { import('estree').Node} Node + * @typedef { import('./walker.js').WalkerContext} WalkerContext + * @typedef {( + * this: WalkerContext, + * node: Node, + * parent: Node | null, + * key: string | number | symbol | null | undefined, + * index: number | null | undefined + * ) => Promise} AsyncHandler + */ + +export class AsyncWalker extends WalkerBase { + /** + * + * @param {AsyncHandler} [enter] + * @param {AsyncHandler} [leave] + */ + constructor(enter, leave) { + super(); + + /** @type {boolean} */ + this.should_skip = false; + + /** @type {boolean} */ + this.should_remove = false; + + /** @type {Node | null} */ + this.replacement = null; + + /** @type {WalkerContext} */ + this.context = { + skip: () => (this.should_skip = true), + remove: () => (this.should_remove = true), + replace: (node) => (this.replacement = node) + }; + + /** @type {AsyncHandler | undefined} */ + this.enter = enter; + + /** @type {AsyncHandler | undefined} */ + this.leave = leave; + } + + /** + * @template {Node} Parent + * @param {Node} node + * @param {Parent | null} parent + * @param {keyof Parent} [prop] + * @param {number | null} [index] + * @returns {Promise} + */ + async visit(node, parent, prop, index) { + if (node) { + if (this.enter) { + const _should_skip = this.should_skip; + const _should_remove = this.should_remove; + const _replacement = this.replacement; + this.should_skip = false; + this.should_remove = false; + this.replacement = null; + + await this.enter.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const skipped = this.should_skip; + const removed = this.should_remove; + + this.should_skip = _should_skip; + this.should_remove = _should_remove; + this.replacement = _replacement; + + if (skipped) return node; + if (removed) return null; + } + + /** @type {keyof Node} */ + let key; + + for (key in node) { + /** @type {unknown} */ + const value = node[key]; + + if (value && typeof value === 'object') { + if (Array.isArray(value)) { + const nodes = /** @type {Array} */ (value); + for (let i = 0; i < nodes.length; i += 1) { + const item = nodes[i]; + if (isNode(item)) { + if (!(await this.visit(item, node, key, i))) { + // removed + i--; + } + } + } + } else if (isNode(value)) { + await this.visit(value, node, key, null); + } + } + } + + if (this.leave) { + const _replacement = this.replacement; + const _should_remove = this.should_remove; + this.replacement = null; + this.should_remove = false; + + await this.leave.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const removed = this.should_remove; + + this.replacement = _replacement; + this.should_remove = _should_remove; + + if (removed) return null; + } + } + + return node; + } +} + +/** + * Ducktype a node. + * + * @param {unknown} value + * @returns {value is Node} + */ +function isNode(value) { + return ( + value !== null && typeof value === 'object' && 'type' in value && typeof value.type === 'string' + ); +} diff --git a/node_modules/estree-walker/src/index.js b/node_modules/estree-walker/src/index.js new file mode 100644 index 0000000000..933ea4f28d --- /dev/null +++ b/node_modules/estree-walker/src/index.js @@ -0,0 +1,34 @@ +import { SyncWalker } from './sync.js'; +import { AsyncWalker } from './async.js'; + +/** + * @typedef {import('estree').Node} Node + * @typedef {import('./sync.js').SyncHandler} SyncHandler + * @typedef {import('./async.js').AsyncHandler} AsyncHandler + */ + +/** + * @param {Node} ast + * @param {{ + * enter?: SyncHandler + * leave?: SyncHandler + * }} walker + * @returns {Node | null} + */ +export function walk(ast, { enter, leave }) { + const instance = new SyncWalker(enter, leave); + return instance.visit(ast, null); +} + +/** + * @param {Node} ast + * @param {{ + * enter?: AsyncHandler + * leave?: AsyncHandler + * }} walker + * @returns {Promise} + */ +export async function asyncWalk(ast, { enter, leave }) { + const instance = new AsyncWalker(enter, leave); + return await instance.visit(ast, null); +} diff --git a/node_modules/estree-walker/src/sync.js b/node_modules/estree-walker/src/sync.js new file mode 100644 index 0000000000..171fb360a7 --- /dev/null +++ b/node_modules/estree-walker/src/sync.js @@ -0,0 +1,152 @@ +import { WalkerBase } from './walker.js'; + +/** + * @typedef { import('estree').Node} Node + * @typedef { import('./walker.js').WalkerContext} WalkerContext + * @typedef {( + * this: WalkerContext, + * node: Node, + * parent: Node | null, + * key: string | number | symbol | null | undefined, + * index: number | null | undefined + * ) => void} SyncHandler + */ + +export class SyncWalker extends WalkerBase { + /** + * + * @param {SyncHandler} [enter] + * @param {SyncHandler} [leave] + */ + constructor(enter, leave) { + super(); + + /** @type {boolean} */ + this.should_skip = false; + + /** @type {boolean} */ + this.should_remove = false; + + /** @type {Node | null} */ + this.replacement = null; + + /** @type {WalkerContext} */ + this.context = { + skip: () => (this.should_skip = true), + remove: () => (this.should_remove = true), + replace: (node) => (this.replacement = node) + }; + + /** @type {SyncHandler | undefined} */ + this.enter = enter; + + /** @type {SyncHandler | undefined} */ + this.leave = leave; + } + + /** + * @template {Node} Parent + * @param {Node} node + * @param {Parent | null} parent + * @param {keyof Parent} [prop] + * @param {number | null} [index] + * @returns {Node | null} + */ + visit(node, parent, prop, index) { + if (node) { + if (this.enter) { + const _should_skip = this.should_skip; + const _should_remove = this.should_remove; + const _replacement = this.replacement; + this.should_skip = false; + this.should_remove = false; + this.replacement = null; + + this.enter.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const skipped = this.should_skip; + const removed = this.should_remove; + + this.should_skip = _should_skip; + this.should_remove = _should_remove; + this.replacement = _replacement; + + if (skipped) return node; + if (removed) return null; + } + + /** @type {keyof Node} */ + let key; + + for (key in node) { + /** @type {unknown} */ + const value = node[key]; + + if (value && typeof value === 'object') { + if (Array.isArray(value)) { + const nodes = /** @type {Array} */ (value); + for (let i = 0; i < nodes.length; i += 1) { + const item = nodes[i]; + if (isNode(item)) { + if (!this.visit(item, node, key, i)) { + // removed + i--; + } + } + } + } else if (isNode(value)) { + this.visit(value, node, key, null); + } + } + } + + if (this.leave) { + const _replacement = this.replacement; + const _should_remove = this.should_remove; + this.replacement = null; + this.should_remove = false; + + this.leave.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const removed = this.should_remove; + + this.replacement = _replacement; + this.should_remove = _should_remove; + + if (removed) return null; + } + } + + return node; + } +} + +/** + * Ducktype a node. + * + * @param {unknown} value + * @returns {value is Node} + */ +function isNode(value) { + return ( + value !== null && typeof value === 'object' && 'type' in value && typeof value.type === 'string' + ); +} diff --git a/node_modules/estree-walker/src/walker.js b/node_modules/estree-walker/src/walker.js new file mode 100644 index 0000000000..6dc6bd7bbe --- /dev/null +++ b/node_modules/estree-walker/src/walker.js @@ -0,0 +1,61 @@ +/** + * @typedef { import('estree').Node} Node + * @typedef {{ + * skip: () => void; + * remove: () => void; + * replace: (node: Node) => void; + * }} WalkerContext + */ + +export class WalkerBase { + constructor() { + /** @type {boolean} */ + this.should_skip = false; + + /** @type {boolean} */ + this.should_remove = false; + + /** @type {Node | null} */ + this.replacement = null; + + /** @type {WalkerContext} */ + this.context = { + skip: () => (this.should_skip = true), + remove: () => (this.should_remove = true), + replace: (node) => (this.replacement = node) + }; + } + + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + * @param {Node} node + */ + replace(parent, prop, index, node) { + if (parent && prop) { + if (index != null) { + /** @type {Array} */ (parent[prop])[index] = node; + } else { + /** @type {Node} */ (parent[prop]) = node; + } + } + } + + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + */ + remove(parent, prop, index) { + if (parent && prop) { + if (index !== null && index !== undefined) { + /** @type {Array} */ (parent[prop]).splice(index, 1); + } else { + delete parent[prop]; + } + } + } +} diff --git a/node_modules/estree-walker/types/async.d.ts b/node_modules/estree-walker/types/async.d.ts new file mode 100644 index 0000000000..db0825aa7b --- /dev/null +++ b/node_modules/estree-walker/types/async.d.ts @@ -0,0 +1,36 @@ +/** + * @typedef { import('estree').Node} Node + * @typedef { import('./walker.js').WalkerContext} WalkerContext + * @typedef {( + * this: WalkerContext, + * node: Node, + * parent: Node | null, + * key: string | number | symbol | null | undefined, + * index: number | null | undefined + * ) => Promise} AsyncHandler + */ +export class AsyncWalker extends WalkerBase { + /** + * + * @param {AsyncHandler} [enter] + * @param {AsyncHandler} [leave] + */ + constructor(enter?: AsyncHandler | undefined, leave?: AsyncHandler | undefined); + /** @type {AsyncHandler | undefined} */ + enter: AsyncHandler | undefined; + /** @type {AsyncHandler | undefined} */ + leave: AsyncHandler | undefined; + /** + * @template {Node} Parent + * @param {Node} node + * @param {Parent | null} parent + * @param {keyof Parent} [prop] + * @param {number | null} [index] + * @returns {Promise} + */ + visit(node: Node, parent: Parent | null, prop?: keyof Parent | undefined, index?: number | null | undefined): Promise; +} +export type Node = import('estree').Node; +export type WalkerContext = import('./walker.js').WalkerContext; +export type AsyncHandler = (this: WalkerContext, node: Node, parent: Node | null, key: string | number | symbol | null | undefined, index: number | null | undefined) => Promise; +import { WalkerBase } from "./walker.js"; diff --git a/node_modules/estree-walker/types/index.d.ts b/node_modules/estree-walker/types/index.d.ts new file mode 100644 index 0000000000..c25afed98b --- /dev/null +++ b/node_modules/estree-walker/types/index.d.ts @@ -0,0 +1,32 @@ +/** + * @typedef {import('estree').Node} Node + * @typedef {import('./sync.js').SyncHandler} SyncHandler + * @typedef {import('./async.js').AsyncHandler} AsyncHandler + */ +/** + * @param {Node} ast + * @param {{ + * enter?: SyncHandler + * leave?: SyncHandler + * }} walker + * @returns {Node | null} + */ +export function walk(ast: Node, { enter, leave }: { + enter?: SyncHandler; + leave?: SyncHandler; +}): Node | null; +/** + * @param {Node} ast + * @param {{ + * enter?: AsyncHandler + * leave?: AsyncHandler + * }} walker + * @returns {Promise} + */ +export function asyncWalk(ast: Node, { enter, leave }: { + enter?: AsyncHandler; + leave?: AsyncHandler; +}): Promise; +export type Node = import('estree').Node; +export type SyncHandler = import('./sync.js').SyncHandler; +export type AsyncHandler = import('./async.js').AsyncHandler; diff --git a/node_modules/estree-walker/types/sync.d.ts b/node_modules/estree-walker/types/sync.d.ts new file mode 100644 index 0000000000..3612b7ff42 --- /dev/null +++ b/node_modules/estree-walker/types/sync.d.ts @@ -0,0 +1,36 @@ +/** + * @typedef { import('estree').Node} Node + * @typedef { import('./walker.js').WalkerContext} WalkerContext + * @typedef {( + * this: WalkerContext, + * node: Node, + * parent: Node | null, + * key: string | number | symbol | null | undefined, + * index: number | null | undefined + * ) => void} SyncHandler + */ +export class SyncWalker extends WalkerBase { + /** + * + * @param {SyncHandler} [enter] + * @param {SyncHandler} [leave] + */ + constructor(enter?: SyncHandler | undefined, leave?: SyncHandler | undefined); + /** @type {SyncHandler | undefined} */ + enter: SyncHandler | undefined; + /** @type {SyncHandler | undefined} */ + leave: SyncHandler | undefined; + /** + * @template {Node} Parent + * @param {Node} node + * @param {Parent | null} parent + * @param {keyof Parent} [prop] + * @param {number | null} [index] + * @returns {Node | null} + */ + visit(node: Node, parent: Parent | null, prop?: keyof Parent | undefined, index?: number | null | undefined): Node | null; +} +export type Node = import('estree').Node; +export type WalkerContext = import('./walker.js').WalkerContext; +export type SyncHandler = (this: WalkerContext, node: Node, parent: Node | null, key: string | number | symbol | null | undefined, index: number | null | undefined) => void; +import { WalkerBase } from "./walker.js"; diff --git a/node_modules/estree-walker/types/walker.d.ts b/node_modules/estree-walker/types/walker.d.ts new file mode 100644 index 0000000000..a3fa29c193 --- /dev/null +++ b/node_modules/estree-walker/types/walker.d.ts @@ -0,0 +1,39 @@ +/** + * @typedef { import('estree').Node} Node + * @typedef {{ + * skip: () => void; + * remove: () => void; + * replace: (node: Node) => void; + * }} WalkerContext + */ +export class WalkerBase { + /** @type {boolean} */ + should_skip: boolean; + /** @type {boolean} */ + should_remove: boolean; + /** @type {Node | null} */ + replacement: Node | null; + /** @type {WalkerContext} */ + context: WalkerContext; + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + * @param {Node} node + */ + replace(parent: Parent | null | undefined, prop: keyof Parent | null | undefined, index: number | null | undefined, node: Node): void; + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + */ + remove(parent: Parent_1 | null | undefined, prop: keyof Parent_1 | null | undefined, index: number | null | undefined): void; +} +export type Node = import('estree').Node; +export type WalkerContext = { + skip: () => void; + remove: () => void; + replace: (node: Node) => void; +}; diff --git a/node_modules/expect-type/LICENSE b/node_modules/expect-type/LICENSE new file mode 100644 index 0000000000..deede247d2 --- /dev/null +++ b/node_modules/expect-type/LICENSE @@ -0,0 +1,191 @@ + Copyright 2024 Misha Kaletsky + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/node_modules/expect-type/README.md b/node_modules/expect-type/README.md new file mode 100644 index 0000000000..f9a1752bf1 --- /dev/null +++ b/node_modules/expect-type/README.md @@ -0,0 +1,925 @@ +# expect-type + +[![CI](https://github.com/mmkal/expect-type/actions/workflows/ci.yml/badge.svg)](https://github.com/mmkal/expect-type/actions/workflows/ci.yml) +![npm](https://img.shields.io/npm/dt/expect-type) +[![X (formerly Twitter) Follow](https://img.shields.io/twitter/follow/mmkal)](https://x.com/mmkalmmkal) + +Compile-time tests for types. Useful to make sure types don't regress into being overly permissive as changes go in over time. + +Similar to `expect`, but with type-awareness. Gives you access to several type-matchers that let you make assertions about the form of a reference or generic type parameter. + +```ts +import {expectTypeOf} from 'expect-type' +import {foo, bar} from '../foo' + +// make sure `foo` has type {a: number} +expectTypeOf(foo).toEqualTypeOf<{a: number}>() + +// make sure `bar` is a function taking a string: +expectTypeOf(bar).parameter(0).toBeString() +expectTypeOf(bar).returns.not.toBeAny() +``` + +It can be used in your existing test files (and is actually [built in to vitest](https://vitest.dev/guide/testing-types)). Or it can be used in any other type-checked file you'd like - it's built into existing tooling with no dependencies. No extra build step, cli tool, IDE extension, or lint plugin is needed. Just import the function and start writing tests. Failures will be at compile time - they'll appear in your IDE and when you run `tsc`. + +See below for lots more examples. + +## Contents + +- [Contents](#contents) +- [Installation and usage](#installation-and-usage) +- [Documentation](#documentation) + - [Features](#features) + - [Why is my assertion failing?](#why-is-my-assertion-failing) + - [Why is `.toMatchTypeOf` deprecated?](#why-is-tomatchtypeof-deprecated) + - [Internal type helpers](#internal-type-helpers) + - [Error messages](#error-messages) + - [Concrete "expected" objects vs type arguments](#concrete-expected-objects-vs-type-arguments) + - [Overloaded functions](#overloaded-functions) + - [Within test frameworks](#within-test-frameworks) + - [Vitest](#vitest) + - [Jest & `eslint-plugin-jest`](#jest--eslint-plugin-jest) + - [Limitations](#limitations) +- [Similar projects](#similar-projects) + - [Comparison](#comparison) +- [TypeScript backwards-compatibility](#typescript-backwards-compatibility) +- [Contributing](#contributing) + - [Documentation of limitations through tests](#documentation-of-limitations-through-tests) + + +## Installation and usage + +```cli +npm install expect-type --save-dev +``` + +```typescript +import {expectTypeOf} from 'expect-type' +``` + +## Documentation + +The `expectTypeOf` method takes a single argument or a generic type parameter. Neither it nor the functions chained off its return value have any meaningful runtime behaviour. The assertions you write will be _compile-time_ errors if they don't hold true. + +### Features + + +Check an object's type with `.toEqualTypeOf`: + +```typescript +expectTypeOf({a: 1}).toEqualTypeOf<{a: number}>() +``` + +`.toEqualTypeOf` can check that two concrete objects have equivalent types (note: when these assertions _fail_, the error messages can be less informative vs the generic type argument syntax above - see [error messages docs](#error-messages)): + +```typescript +expectTypeOf({a: 1}).toEqualTypeOf({a: 1}) +``` + +`.toEqualTypeOf` succeeds for objects with different values, but the same type: + +```typescript +expectTypeOf({a: 1}).toEqualTypeOf({a: 2}) +``` + +`.toEqualTypeOf` fails on excess properties: + +```typescript +// @ts-expect-error +expectTypeOf({a: 1, b: 1}).toEqualTypeOf<{a: number}>() +``` + +To allow for extra properties on an object type, use `.toMatchObjectType`. This is a strict check, but only on the subset of keys that are in the expected type: + +```typescript +expectTypeOf({a: 1, b: 1}).toMatchObjectType<{a: number}>() +``` + +`.toMatchObjectType` can check partial matches on deeply nested objects: + +```typescript +const user = { + email: 'a@b.com', + name: 'John Doe', + address: {street: '123 2nd St', city: 'New York', zip: '10001', state: 'NY', country: 'USA'}, +} + +expectTypeOf(user).toMatchObjectType<{name: string; address: {city: string}}>() +``` + +To check that a type extends another type, use `.toExtend`: + +```typescript +expectTypeOf('some string').toExtend() +// @ts-expect-error +expectTypeOf({a: 1}).toExtend<{b: number}>() +``` + +`.toExtend` can be used with object types, but `.toMatchObjectType` is usually a better choice when dealing with objects, since it's stricter: + +```typescript +expectTypeOf({a: 1, b: 2}).toExtend<{a: number}>() // avoid this +expectTypeOf({a: 1, b: 2}).toMatchObjectType<{a: number}>() // prefer this +``` + +`.toEqualTypeOf`, `.toMatchObjectType`, and `.toExtend` all fail on missing properties: + +```typescript +// @ts-expect-error +expectTypeOf({a: 1}).toEqualTypeOf<{a: number; b: number}>() +// @ts-expect-error +expectTypeOf({a: 1}).toMatchObjectType<{a: number; b: number}>() +// @ts-expect-error +expectTypeOf({a: 1}).toExtend<{a: number; b: number}>() +``` + +Another example of the difference between `.toExtend`, `.toMatchObjectType`, and `.toEqualTypeOf`. `.toExtend` can be used for "is-a" relationships: + +```typescript +type Fruit = {type: 'Fruit'; edible: boolean} +type Apple = {type: 'Fruit'; name: 'Apple'; edible: true} + +expectTypeOf().toExtend() + +// @ts-expect-error - the `editable` property isn't an exact match. In `Apple`, it's `true`, which extends `boolean`, but they're not identical. +expectTypeOf().toMatchObjectType() + +// @ts-expect-error - Apple is not an identical type to Fruit, it's a subtype +expectTypeOf().toEqualTypeOf() + +// @ts-expect-error - Apple is a Fruit, but not vice versa +expectTypeOf().toExtend() +``` + +Assertions can be inverted with `.not`: + +```typescript +expectTypeOf({a: 1}).not.toExtend<{b: 1}>() +expectTypeOf({a: 1}).not.toMatchObjectType<{b: 1}>() +``` + +`.not` can be easier than relying on `// @ts-expect-error`: + +```typescript +type Fruit = {type: 'Fruit'; edible: boolean} +type Apple = {type: 'Fruit'; name: 'Apple'; edible: true} + +expectTypeOf().toExtend() + +expectTypeOf().not.toExtend() +expectTypeOf().not.toEqualTypeOf() +``` + +Catch any/unknown/never types: + +```typescript +expectTypeOf().toBeUnknown() +expectTypeOf().toBeAny() +expectTypeOf().toBeNever() + +// @ts-expect-error +expectTypeOf().toBeNumber() +``` + +`.toEqualTypeOf` distinguishes between deeply-nested `any` and `unknown` properties: + +```typescript +expectTypeOf<{deeply: {nested: any}}>().not.toEqualTypeOf<{deeply: {nested: unknown}}>() +``` + +You can test for basic JavaScript types: + +```typescript +expectTypeOf(() => 1).toBeFunction() +expectTypeOf({}).toBeObject() +expectTypeOf([]).toBeArray() +expectTypeOf('').toBeString() +expectTypeOf(1).toBeNumber() +expectTypeOf(true).toBeBoolean() +expectTypeOf(() => {}).returns.toBeVoid() +expectTypeOf(Promise.resolve(123)).resolves.toBeNumber() +expectTypeOf(Symbol(1)).toBeSymbol() +expectTypeOf(1n).toBeBigInt() +``` + +`.toBe...` methods allow for types that extend the expected type: + +```typescript +expectTypeOf().toBeNumber() +expectTypeOf<1>().toBeNumber() + +expectTypeOf().toBeArray() +expectTypeOf().toBeArray() + +expectTypeOf().toBeString() +expectTypeOf<'foo'>().toBeString() + +expectTypeOf().toBeBoolean() +expectTypeOf().toBeBoolean() + +expectTypeOf().toBeBigInt() +expectTypeOf<0n>().toBeBigInt() +``` + +`.toBe...` methods protect against `any`: + +```typescript +const goodIntParser = (s: string) => Number.parseInt(s, 10) +const badIntParser = (s: string) => JSON.parse(s) // uh-oh - works at runtime if the input is a number, but return 'any' + +expectTypeOf(goodIntParser).returns.toBeNumber() +// @ts-expect-error - if you write a test like this, `.toBeNumber()` will let you know your implementation returns `any`. +expectTypeOf(badIntParser).returns.toBeNumber() +``` + +Nullable types: + +```typescript +expectTypeOf(undefined).toBeUndefined() +expectTypeOf(undefined).toBeNullable() +expectTypeOf(undefined).not.toBeNull() + +expectTypeOf(null).toBeNull() +expectTypeOf(null).toBeNullable() +expectTypeOf(null).not.toBeUndefined() + +expectTypeOf<1 | undefined>().toBeNullable() +expectTypeOf<1 | null>().toBeNullable() +expectTypeOf<1 | undefined | null>().toBeNullable() +``` + +More `.not` examples: + +```typescript +expectTypeOf(1).not.toBeUnknown() +expectTypeOf(1).not.toBeAny() +expectTypeOf(1).not.toBeNever() +expectTypeOf(1).not.toBeNull() +expectTypeOf(1).not.toBeUndefined() +expectTypeOf(1).not.toBeNullable() +expectTypeOf(1).not.toBeBigInt() +``` + +Detect assignability of unioned types: + +```typescript +expectTypeOf().toExtend() +expectTypeOf().not.toExtend() +``` + +Use `.extract` and `.exclude` to narrow down complex union types: + +```typescript +type ResponsiveProp = T | T[] | {xs?: T; sm?: T; md?: T} +const getResponsiveProp = (_props: T): ResponsiveProp => ({}) +type CSSProperties = {margin?: string; padding?: string} + +const cssProperties: CSSProperties = {margin: '1px', padding: '2px'} + +expectTypeOf(getResponsiveProp(cssProperties)) + .exclude() + .exclude<{xs?: unknown}>() + .toEqualTypeOf() + +expectTypeOf(getResponsiveProp(cssProperties)) + .extract() + .toEqualTypeOf() + +expectTypeOf(getResponsiveProp(cssProperties)) + .extract<{xs?: any}>() + .toEqualTypeOf<{xs?: CSSProperties; sm?: CSSProperties; md?: CSSProperties}>() + +expectTypeOf>().exclude().toHaveProperty('sm') +expectTypeOf>().exclude().not.toHaveProperty('xxl') +``` + +`.extract` and `.exclude` return never if no types remain after exclusion: + +```typescript +type Person = {name: string; age: number} +type Customer = Person & {customerId: string} +type Employee = Person & {employeeId: string} + +expectTypeOf().extract<{foo: string}>().toBeNever() +expectTypeOf().exclude<{name: string}>().toBeNever() +``` + +Use `.pick` to pick a set of properties from an object: + +```typescript +type Person = {name: string; age: number} + +expectTypeOf().pick<'name'>().toEqualTypeOf<{name: string}>() +``` + +Use `.omit` to remove a set of properties from an object: + +```typescript +type Person = {name: string; age: number} + +expectTypeOf().omit<'name'>().toEqualTypeOf<{age: number}>() +``` + +Make assertions about object properties: + +```typescript +const obj = {a: 1, b: ''} + +// check that properties exist (or don't) with `.toHaveProperty` +expectTypeOf(obj).toHaveProperty('a') +expectTypeOf(obj).not.toHaveProperty('c') + +// check types of properties +expectTypeOf(obj).toHaveProperty('a').toBeNumber() +expectTypeOf(obj).toHaveProperty('b').toBeString() +expectTypeOf(obj).toHaveProperty('a').not.toBeString() +``` + +`.toEqualTypeOf` can be used to distinguish between functions: + +```typescript +type NoParam = () => void +type HasParam = (s: string) => void + +expectTypeOf().not.toEqualTypeOf() +``` + +But often it's preferable to use `.parameters` or `.returns` for more specific function assertions: + +```typescript +type NoParam = () => void +type HasParam = (s: string) => void + +expectTypeOf().parameters.toEqualTypeOf<[]>() +expectTypeOf().returns.toBeVoid() + +expectTypeOf().parameters.toEqualTypeOf<[string]>() +expectTypeOf().returns.toBeVoid() +``` + +Up to ten overloads will produce union types for `.parameters` and `.returns`: + +```typescript +type Factorize = { + (input: number): number[] + (input: bigint): bigint[] +} + +expectTypeOf().parameters.not.toEqualTypeOf<[number]>() +expectTypeOf().parameters.toEqualTypeOf<[number] | [bigint]>() +expectTypeOf().returns.toEqualTypeOf() + +expectTypeOf().parameter(0).toEqualTypeOf() +``` + +Note that these aren't exactly like TypeScript's built-in Parameters<...> and ReturnType<...>: + +The TypeScript builtins simply choose a single overload (see the [Overloaded functions](#overloaded-functions) section for more information) + +```typescript +type Factorize = { + (input: number): number[] + (input: bigint): bigint[] +} + +// overload using `number` is ignored! +expectTypeOf>().toEqualTypeOf<[bigint]>() +expectTypeOf>().toEqualTypeOf() +``` + +More examples of ways to work with functions - parameters using `.parameter(n)` or `.parameters`, and return values using `.returns`: + +```typescript +const f = (a: number) => [a, a] + +expectTypeOf(f).toBeFunction() + +expectTypeOf(f).toBeCallableWith(1) +expectTypeOf(f).not.toBeAny() +expectTypeOf(f).returns.not.toBeAny() +expectTypeOf(f).returns.toEqualTypeOf([1, 2]) +expectTypeOf(f).returns.toEqualTypeOf([1, 2, 3]) +expectTypeOf(f).parameter(0).not.toEqualTypeOf('1') +expectTypeOf(f).parameter(0).toEqualTypeOf(1) +expectTypeOf(1).parameter(0).toBeNever() + +const twoArgFunc = (a: number, b: string) => ({a, b}) + +expectTypeOf(twoArgFunc).parameters.toEqualTypeOf<[number, string]>() +``` + +`.toBeCallableWith` allows for overloads. You can also use it to narrow down the return type for given input parameters.: + +```typescript +type Factorize = { + (input: number): number[] + (input: bigint): bigint[] +} + +expectTypeOf().toBeCallableWith(6) +expectTypeOf().toBeCallableWith(6n) +``` + +`.toBeCallableWith` returns a type that can be used to narrow down the return type for given input parameters.: + +```typescript +type Factorize = { + (input: number): number[] + (input: bigint): bigint[] +} +expectTypeOf().toBeCallableWith(6).returns.toEqualTypeOf() +expectTypeOf().toBeCallableWith(6n).returns.toEqualTypeOf() +``` + +`.toBeCallableWith` can be used to narrow down the parameters of a function: + +```typescript +type Delete = { + (path: string): void + (paths: string[], options?: {force: boolean}): void +} + +expectTypeOf().toBeCallableWith('abc').parameters.toEqualTypeOf<[string]>() +expectTypeOf() + .toBeCallableWith(['abc', 'def'], {force: true}) + .parameters.toEqualTypeOf<[string[], {force: boolean}?]>() + +expectTypeOf().toBeCallableWith('abc').parameter(0).toBeString() +expectTypeOf().toBeCallableWith('abc').parameter(1).toBeUndefined() + +expectTypeOf() + .toBeCallableWith(['abc', 'def', 'ghi']) + .parameter(0) + .toEqualTypeOf() + +expectTypeOf() + .toBeCallableWith(['abc', 'def', 'ghi']) + .parameter(1) + .toEqualTypeOf<{force: boolean} | undefined>() +``` + +You can't use `.toBeCallableWith` with `.not` - you need to use ts-expect-error:: + +```typescript +const f = (a: number) => [a, a] + +// @ts-expect-error +expectTypeOf(f).toBeCallableWith('foo') +``` + +Use `.map` to transform types: + +This can be useful for generic functions or complex types which you can't access via `.toBeCallableWith`, `.toHaveProperty` etc. The callback function isn't called at runtime, which can make this a useful way to get complex inferred types without worrying about running code. + +```typescript +const capitalize = (input: S) => + (input.slice(0, 1).toUpperCase() + input.slice(1)) as Capitalize + +expectTypeOf(capitalize) + .map(fn => fn('hello world')) + .toEqualTypeOf<'Hello world'>() +``` + +You can also check type guards & type assertions: + +```typescript +const assertNumber = (v: any): asserts v is number => { + if (typeof v !== 'number') { + throw new TypeError('Nope !') + } +} + +expectTypeOf(assertNumber).asserts.toBeNumber() + +const isString = (v: any): v is string => typeof v === 'string' + +expectTypeOf(isString).guards.toBeString() + +const isBigInt = (value: any): value is bigint => typeof value === 'bigint' + +expectTypeOf(isBigInt).guards.toBeBigInt() +``` + +Assert on constructor parameters: + +```typescript +expectTypeOf(Date).toBeConstructibleWith('1970') +expectTypeOf(Date).toBeConstructibleWith(0) +expectTypeOf(Date).toBeConstructibleWith(new Date()) +expectTypeOf(Date).toBeConstructibleWith() + +expectTypeOf(Date).constructorParameters.toEqualTypeOf< + | [] + | [value: string | number] + | [value: string | number | Date] + | [ + year: number, + monthIndex: number, + date?: number | undefined, + hours?: number | undefined, + minutes?: number | undefined, + seconds?: number | undefined, + ms?: number | undefined, + ] +>() +``` + +Constructor overloads: + +```typescript +class DBConnection { + constructor() + constructor(connectionString: string) + constructor(options: {host: string; port: number}) + constructor(..._: unknown[]) {} +} + +expectTypeOf(DBConnection).toBeConstructibleWith() +expectTypeOf(DBConnection).toBeConstructibleWith('localhost') +expectTypeOf(DBConnection).toBeConstructibleWith({host: 'localhost', port: 1234}) +// @ts-expect-error - as when calling `new DBConnection(...)` you can't actually use the `(...args: unknown[])` overlaod, it's purely for the implementation. +expectTypeOf(DBConnection).toBeConstructibleWith(1, 2) +``` + +Check function `this` parameters: + +```typescript +function greet(this: {name: string}, message: string) { + return `Hello ${this.name}, here's your message: ${message}` +} + +expectTypeOf(greet).thisParameter.toEqualTypeOf<{name: string}>() +``` + +Distinguish between functions with different `this` parameters: + +```typescript +function greetFormal(this: {title: string; name: string}, message: string) { + return `Dear ${this.title} ${this.name}, here's your message: ${message}` +} + +function greetCasual(this: {name: string}, message: string) { + return `Hi ${this.name}, here's your message: ${message}` +} + +expectTypeOf(greetFormal).not.toEqualTypeOf(greetCasual) +``` + +Class instance types: + +```typescript +expectTypeOf(Date).instance.toHaveProperty('toISOString') +``` + +Promise resolution types can be checked with `.resolves`: + +```typescript +const asyncFunc = async () => 123 + +expectTypeOf(asyncFunc).returns.resolves.toBeNumber() +``` + +Array items can be checked with `.items`: + +```typescript +expectTypeOf([1, 2, 3]).items.toBeNumber() +expectTypeOf([1, 2, 3]).items.not.toBeString() +``` + +You can also compare arrays directly: + +```typescript +expectTypeOf().not.toEqualTypeOf() +``` + +Check that functions never return: + +```typescript +const thrower = () => { + throw new Error('oh no') +} + +expectTypeOf(thrower).returns.toBeNever() +``` + +Generics can be used rather than references: + +```typescript +expectTypeOf<{a: string}>().not.toEqualTypeOf<{a: number}>() +``` + +Distinguish between missing/null/optional properties: + +```typescript +expectTypeOf<{a?: number}>().not.toEqualTypeOf<{}>() +expectTypeOf<{a?: number}>().not.toEqualTypeOf<{a: number}>() +expectTypeOf<{a?: number}>().not.toEqualTypeOf<{a: number | undefined}>() +expectTypeOf<{a?: number | null}>().not.toEqualTypeOf<{a: number | null}>() +expectTypeOf<{a: {b?: number}}>().not.toEqualTypeOf<{a: {}}>() +``` + +Detect the difference between regular and `readonly` properties: + +```typescript +type A1 = {readonly a: string; b: string} +type E1 = {a: string; b: string} + +expectTypeOf().toExtend() +expectTypeOf().not.toEqualTypeOf() + +type A2 = {a: string; b: {readonly c: string}} +type E2 = {a: string; b: {c: string}} + +expectTypeOf().toExtend() +expectTypeOf().not.toEqualTypeOf() +``` + +Distinguish between classes with different constructors: + +```typescript +class A { + value: number + constructor(a: 1) { + this.value = a + } +} +class B { + value: number + constructor(b: 2) { + this.value = b + } +} + +expectTypeOf().not.toEqualTypeOf() + +class C { + value: number + constructor(c: 1) { + this.value = c + } +} + +expectTypeOf().toEqualTypeOf() +``` + +Known limitation: Intersection types can cause issues with `toEqualTypeOf`: + +```typescript +// @ts-expect-error the following line doesn't compile, even though the types are arguably the same. +// See https://github.com/mmkal/expect-type/pull/21 +expectTypeOf<{a: 1} & {b: 2}>().toEqualTypeOf<{a: 1; b: 2}>() +``` + +To workaround for simple cases, you can use a mapped type: + +```typescript +type Simplify = {[K in keyof T]: T[K]} + +expectTypeOf>().toEqualTypeOf<{a: 1; b: 2}>() +``` + +But this won't work if the nesting is deeper in the type. For these situations, you can use the `.branded` helper. Note that this comes at a performance cost, and can cause the compiler to 'give up' if used with excessively deep types, so use sparingly. This helper is under `.branded` because it deeply transforms the Actual and Expected types into a pseudo-AST: + +```typescript +// @ts-expect-error +expectTypeOf<{a: {b: 1} & {c: 1}}>().toEqualTypeOf<{a: {b: 1; c: 1}}>() + +expectTypeOf<{a: {b: 1} & {c: 1}}>().branded.toEqualTypeOf<{a: {b: 1; c: 1}}>() +``` + +Be careful with `.branded` for very deep or complex types, though. If possible you should find a way to simplify your test to avoid needing to use it: + +```typescript +// This *should* result in an error, but the "branding" mechanism produces too large a type and TypeScript just gives up! https://github.com/microsoft/TypeScript/issues/50670 +expectTypeOf<() => () => () => () => 1>().branded.toEqualTypeOf<() => () => () => () => 2>() + +// @ts-expect-error the non-branded implementation catches the error as expected. +expectTypeOf<() => () => () => () => 1>().toEqualTypeOf<() => () => () => () => 2>() +``` + +So, if you have an extremely deep type that ALSO has an intersection in it, you're out of luck and this library won't be able to test your type properly: + +```typescript +// @ts-expect-error this fails, but it should succeed. +expectTypeOf<() => () => () => () => {a: 1} & {b: 2}>().toEqualTypeOf< + () => () => () => () => {a: 1; b: 2} +>() + +// this succeeds, but it should fail. +expectTypeOf<() => () => () => () => {a: 1} & {b: 2}>().branded.toEqualTypeOf< + () => () => () => () => {a: 1; c: 2} +>() +``` + +Another limitation: passing `this` references to `expectTypeOf` results in errors.: + +```typescript +class B { + b = 'b' + + foo() { + // @ts-expect-error + expectTypeOf(this).toEqualTypeOf(this) + } +} + +// Instead of the above, try something like this: +expectTypeOf(B).instance.toEqualTypeOf<{b: string; foo: () => void}>() +``` + + +Overloads limitation for TypeScript <5.3: Due to a [TypeScript bug fixed in 5.3](https://github.com/microsoft/TypeScript/issues/28867), overloaded functions which include an overload resembling `(...args: unknown[]) => unknown` will exclude `unknown[]` from `.parameters` and exclude `unknown` from `.returns`: + +```typescript +type Factorize = { + (...args: unknown[]): unknown + (input: number): number[] + (input: bigint): bigint[] +} + +expectTypeOf().parameters.toEqualTypeOf<[number] | [bigint]>() +expectTypeOf().returns.toEqualTypeOf() +``` + +This overload, however, allows any input and returns an unknown output anyway, so it's not very useful. If you are worried about this for some reason, you'll have to update TypeScript to 5.3+. + +### Why is my assertion failing? + +For complex types, an assertion might fail when it should if the `Actual` type contains a deeply-nested intersection type but the `Expected` doesn't. In these cases you can use `.branded` as described above: + +```typescript +// @ts-expect-error this unfortunately fails - a TypeScript limitation prevents making this pass without a big perf hit +expectTypeOf<{a: {b: 1} & {c: 1}}>().toEqualTypeOf<{a: {b: 1; c: 1}}>() + +expectTypeOf<{a: {b: 1} & {c: 1}}>().branded.toEqualTypeOf<{a: {b: 1; c: 1}}>() +``` + +### Why is `.toMatchTypeOf` deprecated? + +The `.toMatchTypeOf` method is deprecated in favour of `.toMatchObjectType` (when strictly checking against an object type with a subset of keys), or `.toExtend` (when checking for "is-a" relationships). There are no foreseeable plans to remove `.toMatchTypeOf`, but there's no reason to continue using it - `.toMatchObjectType` is stricter, and `.toExtend` is identical. + +### Internal type helpers + +🚧 This library also exports some helper types for performing boolean operations on types, checking extension/equality in various ways, branding types, and checking for various special types like `never`, `any`, `unknown`. Use at your own risk! Nothing is stopping you from using these beyond this warning: + +>All internal types that are not documented here are _not_ part of the supported API surface, and may be renamed, modified, or removed, without warning or documentation in release notes. + +For a dedicated internal type library, feel free to look at the [source code](./src/index.ts) for inspiration - or better, use a library like [type-fest](https://npmjs.com/package/type-fest). + +### Error messages + +When types don't match, `.toEqualTypeOf` and `.toMatchTypeOf` use a special helper type to produce error messages that are as actionable as possible. But there's a bit of a nuance to understanding them. Since the assertions are written "fluently", the failure should be on the "expected" type, not the "actual" type (`expect().toEqualTypeOf()`). This means that type errors can be a little confusing - so this library produces a `MismatchInfo` type to try to make explicit what the expectation is. For example: + +```ts +expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() +``` + +Is an assertion that will fail, since `{a: 1}` has type `{a: number}` and not `{a: string}`. The error message in this case will read something like this: + +``` +test/test.ts:999:999 - error TS2344: Type '{ a: string; }' does not satisfy the constraint '{ a: \\"Expected: string, Actual: number\\"; }'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type '\\"Expected: string, Actual: number\\"'. + +999 expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() +``` + +Note that the type constraint reported is a human-readable messaging specifying both the "expected" and "actual" types. Rather than taking the sentence `Types of property 'a' are incompatible // Type 'string' is not assignable to type "Expected: string, Actual: number"` literally - just look at the property name (`'a'`) and the message: `Expected: string, Actual: number`. This will tell you what's wrong, in most cases. Extremely complex types will, of course, be more effort to debug, and may require some experimentation. Please [raise an issue](https://github.com/mmkal/expect-type) if the error messages are misleading. + +The `toBe...` methods (like `toBeString`, `toBeNumber`, `toBeVoid`, etc.) fail by resolving to a non-callable type when the `Actual` type under test doesn't match up. For example, the failure for an assertion like `expectTypeOf(1).toBeString()` will look something like this: + +``` +test/test.ts:999:999 - error TS2349: This expression is not callable. + Type 'ExpectString' has no call signatures. + +999 expectTypeOf(1).toBeString() + ~~~~~~~~~~ +``` + +The `This expression is not callable` part isn't all that helpful - the meaningful error is the next line, `Type 'ExpectString has no call signatures`. This essentially means you passed a number but asserted it should be a string. + +If TypeScript added support for ["throw" types](https://github.com/microsoft/TypeScript/pull/40468) these error messages could be improved. Until then they will take a certain amount of squinting. + +#### Concrete "expected" objects vs type arguments + +Error messages for an assertion like this: + +```ts +expectTypeOf({a: 1}).toEqualTypeOf({a: ''}) +``` + +Will be less helpful than for an assertion like this: + +```ts +expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() +``` + +This is because the TypeScript compiler needs to infer the type argument for the `.toEqualTypeOf({a: ''})` style and this library can only mark it as a failure by comparing it against a generic `Mismatch` type. So, where possible, use a type argument rather than a concrete type for `.toEqualTypeOf` and `toMatchTypeOf`. If it's much more convenient to compare two concrete types, you can use `typeof`: + +```ts +const one = valueFromFunctionOne({some: {complex: inputs}}) +const two = valueFromFunctionTwo({some: {other: inputs}}) + +expectTypeOf(one).toEqualTypeof() +``` + +### Overloaded functions + +Due to a TypeScript [design limitation](https://github.com/microsoft/TypeScript/issues/32164#issuecomment-506810756), the native TypeScript `Parameters<...>` and `ReturnType<...>` helpers only return types from one variant of an overloaded function. This limitation doesn't apply to expect-type, since it is not used to author TypeScript code, only to assert on existing types. So, we use a workaround for this TypeScript behaviour to assert on _all_ overloads as a union (actually, not necessarily _all_ - we cap out at 10 overloads). + +### Within test frameworks + +### Vitest + +`expectTypeOf` is built in to [vitest](https://vitest.dev/guide/testing-types), so you can import `expectTypeOf` from the vitest library directly if you prefer. Note that there is no set release cadence, at time of writing, so vitest may not always be using the very latest version. + +```ts +import {expectTypeOf} from 'vitest' +import {mount} from './mount.js' + +test('my types work properly', () => { + expectTypeOf(mount).toBeFunction() + expectTypeOf(mount).parameter(0).toEqualTypeOf<{name: string}>() + + expectTypeOf(mount({name: 42})).toBeString() +}) +``` + +#### Jest & `eslint-plugin-jest` + +If you're using Jest along with `eslint-plugin-jest`, and you put assertions inside `test(...)` definitions, you may get warnings from the [`jest/expect-expect`](https://github.com/jest-community/eslint-plugin-jest/blob/master/docs/rules/expect-expect.md) rule, complaining that "Test has no assertions" for tests that only use `expectTypeOf()`. + +To remove this warning, configure the ESLint rule to consider `expectTypeOf` as an assertion: + +```json +"rules": { + // ... + "jest/expect-expect": [ + "warn", + { + "assertFunctionNames": [ + "expect", "expectTypeOf" + ] + } + ], + // ... +} +``` + +### Limitations + +A summary of some of the limitations of this library. Some of these are documented more fully elsewhere. + +1. Intersection types can result in failures when the expected and actual types are not identically defined, even when they are effectively identical. See [Why is my assertion failing](#why-is-my-assertion-failing) for details. TL;DR: use `.brand` in these cases - and accept the performance hit that it comes with. +1. `toBeCallableWith` will likely fail if you try to use it with a generic function or an overload. See [this issue](https://github.com/mmkal/expect-type/issues/50) for an example and how to work around it. +1. (For now) overloaded functions might trip up the `.parameter` and `.parameters` helpers. This matches how the built-in TypeScript helper `Parameters<...>` works. This may be improved in the future though ([see related issue](https://github.com/mmkal/expect-type/issues/30)). +1. `expectTypeOf(this).toEqualTypeOf(this)` inside class methods does not work. + +## Similar projects + +Other projects with similar goals: + +- [`tsd`](https://github.com/SamVerschueren/tsd) is a CLI that runs the TypeScript type checker over assertions +- [`ts-expect`](https://github.com/TypeStrong/ts-expect) exports several generic helper types to perform type assertions +- [`dtslint`](https://github.com/Microsoft/dtslint) does type checks via comment directives and tslint +- [`type-plus`](https://github.com/unional/type-plus) comes with various type and runtime TypeScript assertions +- [`static-type-assert`](https://github.com/ksxnodemodules/static-type-assert) type assertion functions + +### Comparison + +The key differences in this project are: + +- a fluent, jest-inspired API, making the difference between `actual` and `expected` clear. This is helpful with complex types and assertions. +- inverting assertions intuitively and easily via `expectTypeOf(...).not` +- checks generics properly and strictly ([tsd doesn't](https://github.com/SamVerschueren/tsd/issues/142)) +- first-class support for: + - `any` (as well as `unknown` and `never`) (see issues outstanding at time of writing in tsd for [never](https://github.com/SamVerschueren/tsd/issues/78) and [any](https://github.com/SamVerschueren/tsd/issues/82)). + - This can be especially useful in combination with `not`, to protect against functions returning too-permissive types. For example, `const parseFile = (filename: string) => JSON.parse(readFileSync(filename).toString())` returns `any`, which could lead to errors. After giving it a proper return-type, you can add a test for this with `expect(parseFile).returns.not.toBeAny()` + - object properties + - function parameters + - function return values + - constructor parameters + - class instances + - array item values + - nullable types +- assertions on types "matching" rather than exact type equality, for "is-a" relationships e.g. `expectTypeOf(square).toExtend()` +- built into existing tooling. No extra build step, cli tool, IDE extension, or lint plugin is needed. Just import the function and start writing tests. Failures will be at compile time - they'll appear in your IDE and when you run `tsc`. +- small implementation with no dependencies. [Take a look!](./src/index.ts) (tsd, for comparison, is [2.6MB](https://bundlephobia.com/result?p=tsd@0.13.1) because it ships a patched version of TypeScript). + +## TypeScript backwards-compatibility + +There is a CI job called `test-types` that checks whether the tests still pass with certain older TypeScript versions. To check the supported TypeScript versions, [refer to the job definition](./.github/workflows/ci.yml). + +## Contributing + +In most cases, it's worth checking existing issues or creating one to discuss a new feature or a bug fix before opening a pull request. + +Once you're ready to make a pull request: clone the repo, and install pnpm if you don't have it already with `npm install --global pnpm`. Lockfiles for `npm` and `yarn` are gitignored. + +If you're adding a feature, you should write a self-contained usage example in the form of a test, in [test/usage.test.ts](./test/usage.test.ts). This file is used to populate the bulk of this readme using [eslint-plugin-codegen](https://npmjs.com/package/eslint-plugin-codegen), and to generate an ["errors" test file](./test/errors.test.ts), which captures the error messages that are emitted for failing assertions by the TypeScript compiler. So, the test name should be written as a human-readable sentence explaining the usage example. Have a look at the existing tests for an idea of the style. + +After adding the tests, run `npm run lint -- --fix` to update the readme, and `npm test -- --updateSnapshot` to update the errors test. The generated documentation and tests should be pushed to the same branch as the source code, and submitted as a pull request. CI will test that the docs and tests are up to date if you forget to run these commands. + +### Documentation of limitations through tests + +Limitations of the library are documented through tests in `usage.test.ts`. This means that if a future TypeScript version (or library version) fixes the limitation, the test will start failing, and it will be automatically removed from the documentation once it no longer applies. diff --git a/node_modules/expect-type/SECURITY.md b/node_modules/expect-type/SECURITY.md new file mode 100644 index 0000000000..3f988a6f4f --- /dev/null +++ b/node_modules/expect-type/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +Version 1.0.0 will be supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 1.x.x | :white_check_mark: | +| < 1.0 | :x: | + +## Reporting a Vulnerability + +To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. diff --git a/node_modules/expect-type/dist/branding.d.ts b/node_modules/expect-type/dist/branding.d.ts new file mode 100644 index 0000000000..b59cccd159 --- /dev/null +++ b/node_modules/expect-type/dist/branding.d.ts @@ -0,0 +1,61 @@ +import type { ConstructorOverloadParameters, NumOverloads, OverloadsInfoUnion } from './overloads'; +import type { IsNever, IsAny, IsUnknown, ReadonlyKeys, RequiredKeys, OptionalKeys, MutuallyExtends, UnionToTuple } from './utils'; +/** + * Represents a deeply branded type. + * + * Recursively walk a type and replace it with a branded type related to the + * original. This is useful for equality-checking stricter than + * `A extends B ? B extends A ? true : false : false`, because it detects the + * difference between a few edge-case types that vanilla TypeScript + * doesn't by default: + * - `any` vs `unknown` + * - `{ readonly a: string }` vs `{ a: string }` + * - `{ a?: string }` vs `{ a: string | undefined }` + * + * __Note__: not very performant for complex types - this should only be used + * when you know you need it. If doing an equality check, it's almost always + * better to use {@linkcode StrictEqualUsingTSInternalIdenticalToOperator}. + */ +export type DeepBrand = IsNever extends true ? { + type: 'never'; +} : IsAny extends true ? { + type: 'any'; +} : IsUnknown extends true ? { + type: 'unknown'; +} : T extends string | number | boolean | symbol | bigint | null | undefined | void ? { + type: 'primitive'; + value: T; +} : T extends new (...args: any[]) => any ? { + type: 'constructor'; + params: ConstructorOverloadParameters; + instance: DeepBrand any>>>; +} : T extends (...args: infer P) => infer R ? NumOverloads extends 1 ? { + type: 'function'; + params: DeepBrand

; + return: DeepBrand; + this: DeepBrand>; + props: DeepBrand>; +} : UnionToTuple> extends infer OverloadsTuple ? { + type: 'overloads'; + overloads: { + [K in keyof OverloadsTuple]: DeepBrand; + }; +} : never : T extends any[] ? { + type: 'array'; + items: { + [K in keyof T]: T[K]; + }; +} : { + type: 'object'; + properties: { + [K in keyof T]: DeepBrand; + }; + readonly: ReadonlyKeys; + required: RequiredKeys; + optional: OptionalKeys; + constructorParams: DeepBrand>; +}; +/** + * Checks if two types are strictly equal using branding. + */ +export type StrictEqualUsingBranding = MutuallyExtends, DeepBrand>; diff --git a/node_modules/expect-type/dist/branding.js b/node_modules/expect-type/dist/branding.js new file mode 100644 index 0000000000..c8ad2e549b --- /dev/null +++ b/node_modules/expect-type/dist/branding.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/expect-type/dist/index.d.ts b/node_modules/expect-type/dist/index.d.ts new file mode 100644 index 0000000000..4098988f1a --- /dev/null +++ b/node_modules/expect-type/dist/index.d.ts @@ -0,0 +1,897 @@ +import type { StrictEqualUsingBranding } from './branding'; +import type { ExpectAny, ExpectArray, ExpectBigInt, ExpectBoolean, ExpectFunction, ExpectNever, ExpectNull, ExpectNullable, ExpectNumber, ExpectObject, ExpectString, ExpectSymbol, ExpectUndefined, ExpectUnknown, ExpectVoid, MismatchInfo, Scolder } from './messages'; +import type { ConstructorOverloadParameters, OverloadParameters, OverloadReturnTypes, OverloadsNarrowedByParameters } from './overloads'; +import type { AValue, DeepPickMatchingProps, Extends, IsUnion, MismatchArgs, Not, StrictEqualUsingTSInternalIdenticalToOperator } from './utils'; +export * from './branding'; +export * from './messages'; +export * from './overloads'; +export * from './utils'; +/** + * Represents the positive assertion methods available for type checking in the + * {@linkcode expectTypeOf()} utility. + */ +export interface PositiveExpectTypeOf extends BaseExpectTypeOf { + /** + * Similar to jest's `expect(...).toMatchObject(...)` but for types. + * Deeply "picks" the properties of the actual type based on the expected type, then performs a strict check to make sure the types match `Expected`. + * + * **Note**: optional properties on the {@linkcode Expected | expected type} are not allowed to be missing on the {@linkcode Actual | actual type}. + * + * @example + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchObjectType<{ a: number }>() + * + * expectTypeOf({ a: 1, b: 1 }).not.toMatchObjectType<{ a: number; c?: number }>() + * ``` + * + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + toMatchObjectType: extends true ? 'toMatchObject does not support union types' : Not>> extends true ? 'toMatchObject only supports object types' : StrictEqualUsingTSInternalIdenticalToOperator, Expected> extends true ? unknown : MismatchInfo, Expected>>(...MISMATCH: MismatchArgs, Expected>, true>) => true; + /** + * Check if your type extends the expected type + * + * A less strict version of {@linkcode toEqualTypeOf | .toEqualTypeOf()} that allows for extra properties. + * This is roughly equivalent to an `extends` constraint in a function type argument. + * + * @example + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toExtend<{ a: number }>() + * + * expectTypeOf({ a: 1 }).not.toExtend<{ b: number }>() + * ``` + * + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + toExtend: extends true ? unknown : MismatchInfo>(...MISMATCH: MismatchArgs, true>) => true; + toEqualTypeOf: { + /** + * Uses TypeScript's internal technique to check for type "identicalness". + * + * It will check if the types are fully equal to each other. + * It will not fail if two objects have different values, but the same type. + * It will fail however if an object is missing a property. + * + * **_Unexpected failure_**? For a more permissive but less performant + * check that accommodates for equivalent intersection types, + * use {@linkcode branded | .branded.toEqualTypeOf()}. + * @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}. + * + * @example + * Using generic type argument syntax + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: number }>() + * + * expectTypeOf({ a: 1, b: 1 }).not.toEqualTypeOf<{ a: number }>() + * ``` + * + * @example + * Using inferred type syntax by passing a value + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 1 }) + * + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 2 }) + * ``` + * + * @param value - The value to compare against the expected type. + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + extends true ? unknown : MismatchInfo>(value: Expected & AValue, // reason for `& AValue`: make sure this is only the selected overload when the end-user passes a value for an inferred typearg. The `Mismatch` type does match `AValue`. + ...MISMATCH: MismatchArgs, true>): true; + /** + * Uses TypeScript's internal technique to check for type "identicalness". + * + * It will check if the types are fully equal to each other. + * It will not fail if two objects have different values, but the same type. + * It will fail however if an object is missing a property. + * + * **_Unexpected failure_**? For a more permissive but less performant + * check that accommodates for equivalent intersection types, + * use {@linkcode branded | .branded.toEqualTypeOf()}. + * @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}. + * + * @example + * Using generic type argument syntax + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: number }>() + * + * expectTypeOf({ a: 1, b: 1 }).not.toEqualTypeOf<{ a: number }>() + * ``` + * + * @example + * Using inferred type syntax by passing a value + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 1 }) + * + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 2 }) + * ``` + * + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + extends true ? unknown : MismatchInfo>(...MISMATCH: MismatchArgs, true>): true; + }; + /** + * @deprecated Since v1.2.0 - Use either {@linkcode toMatchObjectType} or {@linkcode toExtend} instead + * + * - Use {@linkcode toMatchObjectType} to perform a strict check on a subset of your type's keys + * - Use {@linkcode toExtend} to check if your type extends the expected type + */ + toMatchTypeOf: { + /** + * @deprecated Since v1.2.0 - Use either {@linkcode toMatchObjectType} or {@linkcode toExtend} instead + * + * - Use {@linkcode toMatchObjectType} to perform a strict check on a subset of your type's keys + * - Use {@linkcode toExtend} to check if your type extends the expected type + * + * A less strict version of {@linkcode toEqualTypeOf | .toEqualTypeOf()} + * that allows for extra properties. + * This is roughly equivalent to an `extends` constraint + * in a function type argument. + * + * @example + * Using generic type argument syntax + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf<{ a: number }>() + * ``` + * + * @example + * Using inferred type syntax by passing a value + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf({ a: 2 }) + * ``` + * + * @param value - The value to compare against the expected type. + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + extends true ? unknown : MismatchInfo>(value: Expected & AValue, // reason for `& AValue`: make sure this is only the selected overload when the end-user passes a value for an inferred typearg. The `Mismatch` type does match `AValue`. + ...MISMATCH: MismatchArgs, true>): true; + /** + * @deprecated Since v1.2.0 - Use either {@linkcode toMatchObjectType} or {@linkcode toExtend} instead + * + * - Use {@linkcode toMatchObjectType} to perform a strict check on a subset of your type's keys + * - Use {@linkcode toExtend} to check if your type extends the expected type + * + * A less strict version of {@linkcode toEqualTypeOf | .toEqualTypeOf()} + * that allows for extra properties. + * This is roughly equivalent to an `extends` constraint + * in a function type argument. + * + * @example + * Using generic type argument syntax + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf<{ a: number }>() + * ``` + * + * @example + * Using inferred type syntax by passing a value + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf({ a: 2 }) + * ``` + * + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + extends true ? unknown : MismatchInfo>(...MISMATCH: MismatchArgs, true>): true; + }; + /** + * Checks whether an object has a given property. + * + * @example + * check that properties exist + * ```ts + * const obj = { a: 1, b: '' } + * + * expectTypeOf(obj).toHaveProperty('a') + * + * expectTypeOf(obj).not.toHaveProperty('c') + * ``` + * + * @param key - The property key to check for. + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + toHaveProperty: (key: KeyType, ...MISMATCH: MismatchArgs, true>) => KeyType extends keyof Actual ? PositiveExpectTypeOf : true; + /** + * Inverts the result of the following assertions. + * + * @example + * ```ts + * expectTypeOf({ a: 1 }).not.toMatchTypeOf({ b: 1 }) + * ``` + */ + not: NegativeExpectTypeOf; + /** + * Intersection types can cause issues with + * {@linkcode toEqualTypeOf | .toEqualTypeOf()}: + * ```ts + * // ❌ The following line doesn't compile, even though the types are arguably the same. + * expectTypeOf<{ a: 1 } & { b: 2 }>().toEqualTypeOf<{ a: 1; b: 2 }>() + * ``` + * This helper works around this problem by using + * a more permissive but less performant check. + * + * __Note__: This comes at a performance cost, and can cause the compiler + * to 'give up' if used with excessively deep types, so use sparingly. + * + * @see {@link https://github.com/mmkal/expect-type/pull/21 | Reference} + */ + branded: { + /** + * Uses TypeScript's internal technique to check for type "identicalness". + * + * It will check if the types are fully equal to each other. + * It will not fail if two objects have different values, but the same type. + * It will fail however if an object is missing a property. + * + * **_Unexpected failure_**? For a more permissive but less performant + * check that accommodates for equivalent intersection types, + * use {@linkcode PositiveExpectTypeOf.branded | .branded.toEqualTypeOf()}. + * @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}. + * + * @example + * Using generic type argument syntax + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: number }>() + * + * expectTypeOf({ a: 1, b: 1 }).not.toEqualTypeOf<{ a: number }>() + * ``` + * + * @example + * Using inferred type syntax by passing a value + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 1 }) + * + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 2 }) + * ``` + * + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + toEqualTypeOf: extends true ? unknown : MismatchInfo>(...MISMATCH: MismatchArgs, true>) => true; + }; +} +/** + * Represents the negative expectation type for the {@linkcode Actual} type. + */ +export interface NegativeExpectTypeOf extends BaseExpectTypeOf { + /** + * Similar to jest's `expect(...).toMatchObject(...)` but for types. + * Deeply "picks" the properties of the actual type based on the expected type, then performs a strict check to make sure the types match `Expected`. + * + * **Note**: optional properties on the {@linkcode Expected | expected type} are not allowed to be missing on the {@linkcode Actual | actual type}. + * + * @example + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchObjectType<{ a: number }>() + * + * expectTypeOf({ a: 1, b: 1 }).not.toMatchObjectType<{ a: number; c?: number }>() + * ``` + * + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + toMatchObjectType: (...MISMATCH: MismatchArgs, Expected>, false>) => true; + /** + * Check if your type extends the expected type + * + * A less strict version of {@linkcode PositiveExpectTypeOf.toEqualTypeOf | .toEqualTypeOf()} that allows for extra properties. + * This is roughly equivalent to an `extends` constraint in a function type argument. + * + * @example + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toExtend<{ a: number }>()] + * + * expectTypeOf({ a: 1 }).not.toExtend<{ b: number }>() + * ``` + * + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + toExtend(...MISMATCH: MismatchArgs, false>): true; + toEqualTypeOf: { + /** + * Uses TypeScript's internal technique to check for type "identicalness". + * + * It will check if the types are fully equal to each other. + * It will not fail if two objects have different values, but the same type. + * It will fail however if an object is missing a property. + * + * **_Unexpected failure_**? For a more permissive but less performant + * check that accommodates for equivalent intersection types, + * use {@linkcode PositiveExpectTypeOf.branded | .branded.toEqualTypeOf()}. + * @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}. + * + * @example + * Using generic type argument syntax + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: number }>() + * + * expectTypeOf({ a: 1, b: 1 }).not.toEqualTypeOf<{ a: number }>() + * ``` + * + * @example + * Using inferred type syntax by passing a value + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 1 }) + * + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 2 }) + * ``` + * + * @param value - The value to compare against the expected type. + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + (value: Expected & AValue, ...MISMATCH: MismatchArgs, false>): true; + /** + * Uses TypeScript's internal technique to check for type "identicalness". + * + * It will check if the types are fully equal to each other. + * It will not fail if two objects have different values, but the same type. + * It will fail however if an object is missing a property. + * + * **_Unexpected failure_**? For a more permissive but less performant + * check that accommodates for equivalent intersection types, + * use {@linkcode PositiveExpectTypeOf.branded | .branded.toEqualTypeOf()}. + * @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}. + * + * @example + * Using generic type argument syntax + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: number }>() + * + * expectTypeOf({ a: 1, b: 1 }).not.toEqualTypeOf<{ a: number }>() + * ``` + * + * @example + * Using inferred type syntax by passing a value + * ```ts + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 1 }) + * + * expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 2 }) + * ``` + * + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + (...MISMATCH: MismatchArgs, false>): true; + }; + /** + * @deprecated Since v1.2.0 - Use either {@linkcode toMatchObjectType} or {@linkcode toExtend} instead + * + * - Use {@linkcode toMatchObjectType} to perform a strict check on a subset of your type's keys + * - Use {@linkcode toExtend} to check if your type extends the expected type + */ + toMatchTypeOf: { + /** + * @deprecated Since v1.2.0 - Use either {@linkcode toMatchObjectType} or {@linkcode toExtend} instead + * + * - Use {@linkcode toMatchObjectType} to perform a strict check on a subset of your type's keys + * - Use {@linkcode toExtend} to check if your type extends the expected type + * + * A less strict version of + * {@linkcode PositiveExpectTypeOf.toEqualTypeOf | .toEqualTypeOf()} + * that allows for extra properties. + * This is roughly equivalent to an `extends` constraint + * in a function type argument. + * + * @example + * Using generic type argument syntax + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf<{ a: number }>() + * ``` + * + * @example + * Using inferred type syntax by passing a value + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf({ a: 2 }) + * ``` + * + * @param value - The value to compare against the expected type. + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + (value: Expected & AValue, // reason for `& AValue`: make sure this is only the selected overload when the end-user passes a value for an inferred typearg. The `Mismatch` type does match `AValue`. + ...MISMATCH: MismatchArgs, false>): true; + /** + * @deprecated Since v1.2.0 - Use either {@linkcode toMatchObjectType} or {@linkcode toExtend} instead + * + * - Use {@linkcode toMatchObjectType} to perform a strict check on a subset of your type's keys + * - Use {@linkcode toExtend} to check if your type extends the expected type + * + * A less strict version of + * {@linkcode PositiveExpectTypeOf.toEqualTypeOf | .toEqualTypeOf()} + * that allows for extra properties. + * This is roughly equivalent to an `extends` constraint + * in a function type argument. + * + * @example + * Using generic type argument syntax + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf<{ a: number }>() + * ``` + * + * @example + * Using inferred type syntax by passing a value + * ```ts + * expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf({ a: 2 }) + * ``` + * + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + (...MISMATCH: MismatchArgs, false>): true; + }; + /** + * Checks whether an object has a given property. + * + * @example + * check that properties exist + * ```ts + * const obj = { a: 1, b: '' } + * + * expectTypeOf(obj).toHaveProperty('a') + * + * expectTypeOf(obj).not.toHaveProperty('c') + * ``` + * + * @param key - The property key to check for. + * @param MISMATCH - The mismatch arguments. + * @returns `true`. + */ + toHaveProperty: (key: KeyType, ...MISMATCH: MismatchArgs, false>) => true; +} +/** + * Represents a conditional type that selects either + * {@linkcode PositiveExpectTypeOf} or {@linkcode NegativeExpectTypeOf} based + * on the value of the `positive` property in the {@linkcode Options} type. + */ +export type ExpectTypeOf = Options['positive'] extends true ? PositiveExpectTypeOf : NegativeExpectTypeOf; +/** + * Represents the base interface for the + * {@linkcode expectTypeOf()} function. + * Provides a set of assertion methods to perform type checks on a value. + */ +export interface BaseExpectTypeOf { + /** + * Checks whether the type of the value is `any`. + */ + toBeAny: Scolder, Options>; + /** + * Checks whether the type of the value is `unknown`. + */ + toBeUnknown: Scolder, Options>; + /** + * Checks whether the type of the value is `never`. + */ + toBeNever: Scolder, Options>; + /** + * Checks whether the type of the value is `function`. + */ + toBeFunction: Scolder, Options>; + /** + * Checks whether the type of the value is `object`. + */ + toBeObject: Scolder, Options>; + /** + * Checks whether the type of the value is an {@linkcode Array}. + */ + toBeArray: Scolder, Options>; + /** + * Checks whether the type of the value is `number`. + */ + toBeNumber: Scolder, Options>; + /** + * Checks whether the type of the value is `string`. + */ + toBeString: Scolder, Options>; + /** + * Checks whether the type of the value is `boolean`. + */ + toBeBoolean: Scolder, Options>; + /** + * Checks whether the type of the value is `void`. + */ + toBeVoid: Scolder, Options>; + /** + * Checks whether the type of the value is `symbol`. + */ + toBeSymbol: Scolder, Options>; + /** + * Checks whether the type of the value is `null`. + */ + toBeNull: Scolder, Options>; + /** + * Checks whether the type of the value is `undefined`. + */ + toBeUndefined: Scolder, Options>; + /** + * Checks whether the type of the value is `null` or `undefined`. + */ + toBeNullable: Scolder, Options>; + /** + * Transform that type of the value via a callback. + * + * @param fn - A callback that transforms the input value. Note that this function is not actually called - it's only used for type inference. + * @returns A new type which can be used for further assertions. + */ + map: (fn: (value: Actual) => T) => ExpectTypeOf; + /** + * Checks whether the type of the value is **`bigint`**. + * + * @example + * #### Distinguish between **`number`** and **`bigint`** + * + * ```ts + * import { expectTypeOf } from 'expect-type' + * + * const aVeryBigInteger = 10n ** 100n + * + * expectTypeOf(aVeryBigInteger).not.toBeNumber() + * + * expectTypeOf(aVeryBigInteger).toBeBigInt() + * ``` + * + * @since 1.1.0 + */ + toBeBigInt: Scolder, Options>; + /** + * Checks whether a function is callable with the given parameters. + * + * __Note__: You cannot negate this assertion with + * {@linkcode PositiveExpectTypeOf.not | .not}, you need to use + * `ts-expect-error` instead. + * + * @example + * ```ts + * const f = (a: number) => [a, a] + * + * expectTypeOf(f).toBeCallableWith(1) + * ``` + * + * __Known Limitation__: This assertion will likely fail if you try to use it + * with a generic function or an overload. + * @see {@link https://github.com/mmkal/expect-type/issues/50 | This issue} for an example and a workaround. + * + * @param args - The arguments to check for callability. + * @returns `true`. + */ + toBeCallableWith: Options['positive'] extends true ? >(...args: Args) => ExpectTypeOf, Options> : never; + /** + * Checks whether a class is constructible with the given parameters. + * + * @example + * ```ts + * expectTypeOf(Date).toBeConstructibleWith('1970') + * + * expectTypeOf(Date).toBeConstructibleWith(0) + * + * expectTypeOf(Date).toBeConstructibleWith(new Date()) + * + * expectTypeOf(Date).toBeConstructibleWith() + * ``` + * + * @param args - The arguments to check for constructibility. + * @returns `true`. + */ + toBeConstructibleWith: Options['positive'] extends true ? >(...args: Args) => true : never; + /** + * Equivalent to the {@linkcode Extract} utility type. + * Helps narrow down complex union types. + * + * @example + * ```ts + * type ResponsiveProp = T | T[] | { xs?: T; sm?: T; md?: T } + * + * interface CSSProperties { + * margin?: string + * padding?: string + * } + * + * function getResponsiveProp(_props: T): ResponsiveProp { + * return {} + * } + * + * const cssProperties: CSSProperties = { margin: '1px', padding: '2px' } + * + * expectTypeOf(getResponsiveProp(cssProperties)) + * .extract<{ xs?: any }>() // extracts the last type from a union + * .toEqualTypeOf<{ + * xs?: CSSProperties + * sm?: CSSProperties + * md?: CSSProperties + * }>() + * + * expectTypeOf(getResponsiveProp(cssProperties)) + * .extract() // extracts an array from a union + * .toEqualTypeOf() + * ``` + * + * __Note__: If no type is found in the union, it will return `never`. + * + * @param v - The type to extract from the union. + * @returns The type after extracting the type from the union. + */ + extract: (v?: V) => ExpectTypeOf, Options>; + /** + * Equivalent to the {@linkcode Exclude} utility type. + * Removes types from a union. + * + * @example + * ```ts + * type ResponsiveProp = T | T[] | { xs?: T; sm?: T; md?: T } + * + * interface CSSProperties { + * margin?: string + * padding?: string + * } + * + * function getResponsiveProp(_props: T): ResponsiveProp { + * return {} + * } + * + * const cssProperties: CSSProperties = { margin: '1px', padding: '2px' } + * + * expectTypeOf(getResponsiveProp(cssProperties)) + * .exclude() + * .exclude<{ xs?: unknown }>() // or just `.exclude()` + * .toEqualTypeOf() + * ``` + */ + exclude: (v?: V) => ExpectTypeOf, Options>; + /** + * Equivalent to the {@linkcode Pick} utility type. + * Helps select a subset of properties from an object type. + * + * @example + * ```ts + * interface Person { + * name: string + * age: number + * } + * + * expectTypeOf() + * .pick<'name'>() + * .toEqualTypeOf<{ name: string }>() + * ``` + * + * @param keyToPick - The property key to pick. + * @returns The type after picking the property. + */ + pick: (keyToPick?: KeyToPick) => ExpectTypeOf, Options>; + /** + * Equivalent to the {@linkcode Omit} utility type. + * Helps remove a subset of properties from an object type. + * + * @example + * ```ts + * interface Person { + * name: string + * age: number + * } + * + * expectTypeOf().omit<'name'>().toEqualTypeOf<{ age: number }>() + * ``` + * + * @param keyToOmit - The property key to omit. + * @returns The type after omitting the property. + */ + omit: )>(keyToOmit?: KeyToOmit) => ExpectTypeOf, Options>; + /** + * Extracts a certain function argument with `.parameter(number)` call to + * perform other assertions on it. + * + * @example + * ```ts + * function foo(a: number, b: string) { + * return [a, b] + * } + * + * expectTypeOf(foo).parameter(0).toBeNumber() + * + * expectTypeOf(foo).parameter(1).toBeString() + * ``` + * + * @param index - The index of the parameter to extract. + * @returns The extracted parameter type. + */ + parameter: (index: Index) => ExpectTypeOf[Index], Options>; + /** + * Equivalent to the {@linkcode Parameters} utility type. + * Extracts function parameters to perform assertions on its value. + * Parameters are returned as an array. + * + * @example + * ```ts + * function noParam() {} + * + * function hasParam(s: string) {} + * + * expectTypeOf(noParam).parameters.toEqualTypeOf<[]>() + * + * expectTypeOf(hasParam).parameters.toEqualTypeOf<[string]>() + * ``` + */ + parameters: ExpectTypeOf, Options>; + /** + * Equivalent to the {@linkcode ConstructorParameters} utility type. + * Extracts constructor parameters as an array of values and + * perform assertions on them with this method. + * + * For overloaded constructors it will return a union of all possible parameter-tuples. + * + * @example + * ```ts + * expectTypeOf(Date).constructorParameters.toEqualTypeOf< + * [] | [string | number | Date] + * >() + * ``` + */ + constructorParameters: ExpectTypeOf, Options>; + /** + * Equivalent to the {@linkcode ThisParameterType} utility type. + * Extracts the `this` parameter of a function to + * perform assertions on its value. + * + * @example + * ```ts + * function greet(this: { name: string }, message: string) { + * return `Hello ${this.name}, here's your message: ${message}` + * } + * + * expectTypeOf(greet).thisParameter.toEqualTypeOf<{ name: string }>() + * ``` + */ + thisParameter: ExpectTypeOf, Options>; + /** + * Equivalent to the {@linkcode InstanceType} utility type. + * Extracts the instance type of a class to perform assertions on. + * + * @example + * ```ts + * expectTypeOf(Date).instance.toHaveProperty('toISOString') + * ``` + */ + instance: Actual extends new (...args: any[]) => infer I ? ExpectTypeOf : never; + /** + * Equivalent to the {@linkcode ReturnType} utility type. + * Extracts the return type of a function. + * + * @example + * ```ts + * expectTypeOf(() => {}).returns.toBeVoid() + * + * expectTypeOf((a: number) => [a, a]).returns.toEqualTypeOf([1, 2]) + * ``` + */ + returns: Actual extends Function ? ExpectTypeOf, Options> : never; + /** + * Extracts resolved value of a Promise, + * so you can perform other assertions on it. + * + * @example + * ```ts + * async function asyncFunc() { + * return 123 + * } + * + * expectTypeOf(asyncFunc).returns.resolves.toBeNumber() + * + * expectTypeOf(Promise.resolve('string')).resolves.toBeString() + * ``` + * + * Type Equivalent: + * ```ts + * type Resolves = PromiseType extends PromiseLike + * ? ResolvedType + * : never + * ``` + */ + resolves: Actual extends PromiseLike ? ExpectTypeOf : never; + /** + * Extracts array item type to perform assertions on. + * + * @example + * ```ts + * expectTypeOf([1, 2, 3]).items.toEqualTypeOf() + * + * expectTypeOf([1, 2, 3]).items.not.toEqualTypeOf() + * ``` + * + * __Type Equivalent__: + * ```ts + * type Items = ArrayType extends ArrayLike + * ? ItemType + * : never + * ``` + */ + items: Actual extends ArrayLike ? ExpectTypeOf : never; + /** + * Extracts the type guarded by a function to perform assertions on. + * + * @example + * ```ts + * function isString(v: any): v is string { + * return typeof v === 'string' + * } + * + * expectTypeOf(isString).guards.toBeString() + * ``` + */ + guards: Actual extends (v: any, ...args: any[]) => v is infer T ? ExpectTypeOf : never; + /** + * Extracts the type asserted by a function to perform assertions on. + * + * @example + * ```ts + * function assertNumber(v: any): asserts v is number { + * if (typeof v !== 'number') + * throw new TypeError('Nope !') + * } + * + * expectTypeOf(assertNumber).asserts.toBeNumber() + * ``` + */ + asserts: Actual extends (v: any, ...args: any[]) => asserts v is infer T ? unknown extends T ? never : ExpectTypeOf : never; +} +/** + * Represents a function that allows asserting the expected type of a value. + */ +export type _ExpectTypeOf = { + /** + * Asserts the expected type of a value. + * + * @param actual - The actual value being asserted. + * @returns An object representing the expected type assertion. + */ + (actual: Actual): ExpectTypeOf; + /** + * Asserts the expected type of a value without providing an actual value. + * + * @returns An object representing the expected type assertion. + */ + (): ExpectTypeOf; +}; +/** + * Similar to Jest's `expect`, but with type-awareness. + * Gives you access to a number of type-matchers that let you make assertions about the + * form of a reference or generic type parameter. + * + * @example + * ```ts + * import { foo, bar } from '../foo' + * import { expectTypeOf } from 'expect-type' + * + * test('foo types', () => { + * // make sure `foo` has type { a: number } + * expectTypeOf(foo).toMatchTypeOf({ a: 1 }) + * expectTypeOf(foo).toHaveProperty('a').toBeNumber() + * + * // make sure `bar` is a function taking a string: + * expectTypeOf(bar).parameter(0).toBeString() + * expectTypeOf(bar).returns.not.toBeAny() + * }) + * ``` + * + * @description + * See the [full docs](https://npmjs.com/package/expect-type#documentation) for lots more examples. + */ +export declare const expectTypeOf: _ExpectTypeOf; diff --git a/node_modules/expect-type/dist/index.js b/node_modules/expect-type/dist/index.js new file mode 100644 index 0000000000..55e299ec50 --- /dev/null +++ b/node_modules/expect-type/dist/index.js @@ -0,0 +1,96 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.expectTypeOf = void 0; +__exportStar(require("./branding"), exports); // backcompat, consider removing in next major version +__exportStar(require("./messages"), exports); // backcompat, consider removing in next major version +__exportStar(require("./overloads"), exports); +__exportStar(require("./utils"), exports); // backcompat, consider removing in next major version +const fn = () => true; +/** + * Similar to Jest's `expect`, but with type-awareness. + * Gives you access to a number of type-matchers that let you make assertions about the + * form of a reference or generic type parameter. + * + * @example + * ```ts + * import { foo, bar } from '../foo' + * import { expectTypeOf } from 'expect-type' + * + * test('foo types', () => { + * // make sure `foo` has type { a: number } + * expectTypeOf(foo).toMatchTypeOf({ a: 1 }) + * expectTypeOf(foo).toHaveProperty('a').toBeNumber() + * + * // make sure `bar` is a function taking a string: + * expectTypeOf(bar).parameter(0).toBeString() + * expectTypeOf(bar).returns.not.toBeAny() + * }) + * ``` + * + * @description + * See the [full docs](https://npmjs.com/package/expect-type#documentation) for lots more examples. + */ +const expectTypeOf = (_actual) => { + const nonFunctionProperties = [ + 'parameters', + 'returns', + 'resolves', + 'not', + 'items', + 'constructorParameters', + 'thisParameter', + 'instance', + 'guards', + 'asserts', + 'branded', + ]; + const obj = { + /* eslint-disable @typescript-eslint/no-unsafe-assignment */ + toBeAny: fn, + toBeUnknown: fn, + toBeNever: fn, + toBeFunction: fn, + toBeObject: fn, + toBeArray: fn, + toBeString: fn, + toBeNumber: fn, + toBeBoolean: fn, + toBeVoid: fn, + toBeSymbol: fn, + toBeNull: fn, + toBeUndefined: fn, + toBeNullable: fn, + toBeBigInt: fn, + toMatchTypeOf: fn, + toEqualTypeOf: fn, + toBeConstructibleWith: fn, + toMatchObjectType: fn, + toExtend: fn, + map: exports.expectTypeOf, + toBeCallableWith: exports.expectTypeOf, + extract: exports.expectTypeOf, + exclude: exports.expectTypeOf, + pick: exports.expectTypeOf, + omit: exports.expectTypeOf, + toHaveProperty: exports.expectTypeOf, + parameter: exports.expectTypeOf, + }; + const getterProperties = nonFunctionProperties; + getterProperties.forEach((prop) => Object.defineProperty(obj, prop, { get: () => (0, exports.expectTypeOf)({}) })); + return obj; +}; +exports.expectTypeOf = expectTypeOf; diff --git a/node_modules/expect-type/dist/messages.d.ts b/node_modules/expect-type/dist/messages.d.ts new file mode 100644 index 0000000000..20527b7bd7 --- /dev/null +++ b/node_modules/expect-type/dist/messages.d.ts @@ -0,0 +1,155 @@ +import type { StrictEqualUsingBranding } from './branding'; +import type { And, Extends, ExtendsExcludingAnyOrNever, IsAny, IsNever, IsUnknown, Not, UsefulKeys } from './utils'; +/** + * Determines the printable type representation for a given type. + */ +export type PrintType = IsUnknown extends true ? 'unknown' : IsNever extends true ? 'never' : IsAny extends true ? never : boolean extends T ? 'boolean' : T extends boolean ? `literal boolean: ${T}` : string extends T ? 'string' : T extends string ? `literal string: ${T}` : number extends T ? 'number' : T extends number ? `literal number: ${T}` : bigint extends T ? 'bigint' : T extends bigint ? `literal bigint: ${T}` : T extends null ? 'null' : T extends undefined ? 'undefined' : T extends (...args: any[]) => any ? 'function' : '...'; +/** + * Helper for showing end-user a hint why their type assertion is failing. + * This swaps "leaf" types with a literal message about what the actual and + * expected types are. Needs to check for `Not>` because + * otherwise `LeafTypeOf` returns `never`, which extends everything 🤔 + */ +export type MismatchInfo = And<[Extends, '...'>, Not>]> extends true ? And<[Extends, Extends]> extends true ? Array[number], Extract[number]>> : { + [K in UsefulKeys | UsefulKeys]: MismatchInfo; +} : StrictEqualUsingBranding extends true ? Actual : `Expected: ${PrintType}, Actual: ${PrintType>}`; +/** + * @internal + */ +declare const inverted: unique symbol; +/** + * @internal + */ +type Inverted = { + [inverted]: T; +}; +/** + * @internal + */ +declare const expectNull: unique symbol; +export type ExpectNull = { + [expectNull]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * @internal + */ +declare const expectUndefined: unique symbol; +export type ExpectUndefined = { + [expectUndefined]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * @internal + */ +declare const expectNumber: unique symbol; +export type ExpectNumber = { + [expectNumber]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * @internal + */ +declare const expectString: unique symbol; +export type ExpectString = { + [expectString]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * @internal + */ +declare const expectBoolean: unique symbol; +export type ExpectBoolean = { + [expectBoolean]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * @internal + */ +declare const expectVoid: unique symbol; +export type ExpectVoid = { + [expectVoid]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * @internal + */ +declare const expectFunction: unique symbol; +export type ExpectFunction = { + [expectFunction]: T; + result: ExtendsExcludingAnyOrNever any>; +}; +/** + * @internal + */ +declare const expectObject: unique symbol; +export type ExpectObject = { + [expectObject]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * @internal + */ +declare const expectArray: unique symbol; +export type ExpectArray = { + [expectArray]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * @internal + */ +declare const expectSymbol: unique symbol; +export type ExpectSymbol = { + [expectSymbol]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * @internal + */ +declare const expectAny: unique symbol; +export type ExpectAny = { + [expectAny]: T; + result: IsAny; +}; +/** + * @internal + */ +declare const expectUnknown: unique symbol; +export type ExpectUnknown = { + [expectUnknown]: T; + result: IsUnknown; +}; +/** + * @internal + */ +declare const expectNever: unique symbol; +export type ExpectNever = { + [expectNever]: T; + result: IsNever; +}; +/** + * @internal + */ +declare const expectNullable: unique symbol; +export type ExpectNullable = { + [expectNullable]: T; + result: Not>>; +}; +/** + * @internal + */ +declare const expectBigInt: unique symbol; +export type ExpectBigInt = { + [expectBigInt]: T; + result: ExtendsExcludingAnyOrNever; +}; +/** + * Checks if the result of an expecter matches the specified options, and + * resolves to a fairly readable error message if not. + */ +export type Scolder = Expecter['result'] extends Options['positive'] ? () => true : Options['positive'] extends true ? Expecter : Inverted; +export {}; diff --git a/node_modules/expect-type/dist/messages.js b/node_modules/expect-type/dist/messages.js new file mode 100644 index 0000000000..ff4e0ae9d1 --- /dev/null +++ b/node_modules/expect-type/dist/messages.js @@ -0,0 +1,66 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * @internal + */ +const inverted = Symbol('inverted'); +/** + * @internal + */ +const expectNull = Symbol('expectNull'); +/** + * @internal + */ +const expectUndefined = Symbol('expectUndefined'); +/** + * @internal + */ +const expectNumber = Symbol('expectNumber'); +/** + * @internal + */ +const expectString = Symbol('expectString'); +/** + * @internal + */ +const expectBoolean = Symbol('expectBoolean'); +/** + * @internal + */ +const expectVoid = Symbol('expectVoid'); +/** + * @internal + */ +const expectFunction = Symbol('expectFunction'); +/** + * @internal + */ +const expectObject = Symbol('expectObject'); +/** + * @internal + */ +const expectArray = Symbol('expectArray'); +/** + * @internal + */ +const expectSymbol = Symbol('expectSymbol'); +/** + * @internal + */ +const expectAny = Symbol('expectAny'); +/** + * @internal + */ +const expectUnknown = Symbol('expectUnknown'); +/** + * @internal + */ +const expectNever = Symbol('expectNever'); +/** + * @internal + */ +const expectNullable = Symbol('expectNullable'); +/** + * @internal + */ +const expectBigInt = Symbol('expectBigInt'); diff --git a/node_modules/expect-type/dist/overloads.d.ts b/node_modules/expect-type/dist/overloads.d.ts new file mode 100644 index 0000000000..ab0e22ed8f --- /dev/null +++ b/node_modules/expect-type/dist/overloads.d.ts @@ -0,0 +1,288 @@ +import type { StrictEqualUsingTSInternalIdenticalToOperator, IsNever, UnionToIntersection, UnionToTuple } from './utils'; +/** + * The simple(ish) way to get overload info from a function + * {@linkcode FunctionType}. Recent versions of TypeScript will match any + * function against a generic 10-overload type, filling in slots with + * duplicates of the function. So, we can just match against a single type + * and get all the overloads. + * + * For older versions of TypeScript, we'll need to painstakingly do + * ten separate matches. + */ +export type TSPost53OverloadsInfoUnion = FunctionType extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; + (...args: infer A3): infer R3; + (...args: infer A4): infer R4; + (...args: infer A5): infer R5; + (...args: infer A6): infer R6; + (...args: infer A7): infer R7; + (...args: infer A8): infer R8; + (...args: infer A9): infer R9; + (...args: infer A10): infer R10; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) | ((...p: A3) => R3) | ((...p: A4) => R4) | ((...p: A5) => R5) | ((...p: A6) => R6) | ((...p: A7) => R7) | ((...p: A8) => R8) | ((...p: A9) => R9) | ((...p: A10) => R10) : never; +/** + * A function with `unknown` parameters and return type. + */ +export type UnknownFunction = (...args: unknown[]) => unknown; +/** + * `true` iff {@linkcode FunctionType} is + * equivalent to `(...args: unknown[]) => unknown`, + * which is what an overload variant looks like for a non-existent overload. + * This is useful because older versions of TypeScript end up with + * 9 "useless" overloads and one real one for parameterless/generic functions. + * + * @see {@link https://github.com/microsoft/TypeScript/issues/28867 | Related} + */ +export type IsUselessOverloadInfo = StrictEqualUsingTSInternalIdenticalToOperator; +/** + * Old versions of TypeScript can sometimes seem to refuse to separate out + * union members unless you put them each in a pointless tuple and add an + * extra `infer X` expression. There may be a better way to work around this + * problem, but since it's not a problem in newer versions of TypeScript, + * it's not a priority right now. + */ +export type Tuplify = Union extends infer X ? [X] : never; +/** + * For older versions of TypeScript, we need two separate workarounds + * to get overload info. First, we need need to use + * {@linkcode DecreasingOverloadsInfoUnion} to get the overload info for + * functions with 1-10 overloads. Then, we need to filter out the + * "useless" overloads that are present in older versions of TypeScript, + * for parameterless functions. To do this we use + * {@linkcode IsUselessOverloadInfo} to remove useless overloads. + * + * @see {@link https://github.com/microsoft/TypeScript/issues/28867 | Related} + */ +export type TSPre53OverloadsInfoUnion = Tuplify> extends infer Tup ? Tup extends [infer Fn] ? IsUselessOverloadInfo extends true ? never : Fn : never : never; +/** + * For versions of TypeScript below 5.3, we need to check for 10 overloads, + * then 9, then 8, etc., to get a union of the overload variants. + */ +export type DecreasingOverloadsInfoUnion = F extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; + (...args: infer A3): infer R3; + (...args: infer A4): infer R4; + (...args: infer A5): infer R5; + (...args: infer A6): infer R6; + (...args: infer A7): infer R7; + (...args: infer A8): infer R8; + (...args: infer A9): infer R9; + (...args: infer A10): infer R10; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) | ((...p: A3) => R3) | ((...p: A4) => R4) | ((...p: A5) => R5) | ((...p: A6) => R6) | ((...p: A7) => R7) | ((...p: A8) => R8) | ((...p: A9) => R9) | ((...p: A10) => R10) : F extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; + (...args: infer A3): infer R3; + (...args: infer A4): infer R4; + (...args: infer A5): infer R5; + (...args: infer A6): infer R6; + (...args: infer A7): infer R7; + (...args: infer A8): infer R8; + (...args: infer A9): infer R9; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) | ((...p: A3) => R3) | ((...p: A4) => R4) | ((...p: A5) => R5) | ((...p: A6) => R6) | ((...p: A7) => R7) | ((...p: A8) => R8) | ((...p: A9) => R9) : F extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; + (...args: infer A3): infer R3; + (...args: infer A4): infer R4; + (...args: infer A5): infer R5; + (...args: infer A6): infer R6; + (...args: infer A7): infer R7; + (...args: infer A8): infer R8; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) | ((...p: A3) => R3) | ((...p: A4) => R4) | ((...p: A5) => R5) | ((...p: A6) => R6) | ((...p: A7) => R7) | ((...p: A8) => R8) : F extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; + (...args: infer A3): infer R3; + (...args: infer A4): infer R4; + (...args: infer A5): infer R5; + (...args: infer A6): infer R6; + (...args: infer A7): infer R7; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) | ((...p: A3) => R3) | ((...p: A4) => R4) | ((...p: A5) => R5) | ((...p: A6) => R6) | ((...p: A7) => R7) : F extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; + (...args: infer A3): infer R3; + (...args: infer A4): infer R4; + (...args: infer A5): infer R5; + (...args: infer A6): infer R6; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) | ((...p: A3) => R3) | ((...p: A4) => R4) | ((...p: A5) => R5) | ((...p: A6) => R6) : F extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; + (...args: infer A3): infer R3; + (...args: infer A4): infer R4; + (...args: infer A5): infer R5; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) | ((...p: A3) => R3) | ((...p: A4) => R4) | ((...p: A5) => R5) : F extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; + (...args: infer A3): infer R3; + (...args: infer A4): infer R4; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) | ((...p: A3) => R3) | ((...p: A4) => R4) : F extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; + (...args: infer A3): infer R3; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) | ((...p: A3) => R3) : F extends { + (...args: infer A1): infer R1; + (...args: infer A2): infer R2; +} ? ((...p: A1) => R1) | ((...p: A2) => R2) : F extends (...args: infer A1) => infer R1 ? ((...p: A1) => R1) : never; +/** + * Get a union of overload variants for a function {@linkcode FunctionType}. + * Does a check for whether we can do the one-shot + * 10-overload matcher (which works for ts\>5.3), and if not, + * falls back to the more complicated utility. + */ +export type OverloadsInfoUnion = IsNever 2>> extends true ? TSPre53OverloadsInfoUnion : TSPost53OverloadsInfoUnion; +/** + * Allows inferring any function using the `infer` keyword. + */ +export type InferFunctionType any> = FunctionType; +/** + * A union type of the parameters allowed for any + * overload of function {@linkcode FunctionType}. + */ +export type OverloadParameters = OverloadsInfoUnion extends InferFunctionType ? Parameters : never; +/** + * A union type of the return types for any overload of + * function {@linkcode FunctionType}. + */ +export type OverloadReturnTypes = OverloadsInfoUnion extends InferFunctionType ? ReturnType : never; +/** + * Takes an overload variants {@linkcode Union}, + * produced from {@linkcode OverloadsInfoUnion} and rejects + * the ones incompatible with parameters {@linkcode Args}. + */ +export type SelectOverloadsInfo = Union extends InferFunctionType ? (Args extends Parameters ? Fn : never) : never; +/** + * Creates a new overload (an intersection type) from an existing one, + * which only includes variant(s) which can accept + * {@linkcode Args} as parameters. + */ +export type OverloadsNarrowedByParameters> = UnionToIntersection, Args>>; +/** + * The simple(ish) way to get overload info from a constructor + * {@linkcode ConstructorType}. Recent versions of TypeScript will match any + * constructor against a generic 10-overload type, filling in slots with + * duplicates of the constructor. So, we can just match against a single type + * and get all the overloads. + * + * For older versions of TypeScript, + * we'll need to painstakingly do ten separate matches. + */ +export type TSPost53ConstructorOverloadsInfoUnion = ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; + new (...args: infer A3): infer R3; + new (...args: infer A4): infer R4; + new (...args: infer A5): infer R5; + new (...args: infer A6): infer R6; + new (...args: infer A7): infer R7; + new (...args: infer A8): infer R8; + new (...args: infer A9): infer R9; + new (...args: infer A10): infer R10; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) | (new (...p: A3) => R3) | (new (...p: A4) => R4) | (new (...p: A5) => R5) | (new (...p: A6) => R6) | (new (...p: A7) => R7) | (new (...p: A8) => R8) | (new (...p: A9) => R9) | (new (...p: A10) => R10) : never; +/** + * A constructor function with `unknown` parameters and return type. + */ +export type UnknownConstructor = new (...args: unknown[]) => unknown; +/** + * Same as {@linkcode IsUselessOverloadInfo}, but for constructors. + */ +export type IsUselessConstructorOverloadInfo = StrictEqualUsingTSInternalIdenticalToOperator; +/** + * For older versions of TypeScript, we need two separate workarounds to + * get constructor overload info. First, we need need to use + * {@linkcode DecreasingConstructorOverloadsInfoUnion} to get the overload + * info for constructors with 1-10 overloads. Then, we need to filter out the + * "useless" overloads that are present in older versions of TypeScript, + * for parameterless constructors. To do this we use + * {@linkcode IsUselessConstructorOverloadInfo} to remove useless overloads. + * + * @see {@link https://github.com/microsoft/TypeScript/issues/28867 | Related} + */ +export type TSPre53ConstructorOverloadsInfoUnion = Tuplify> extends infer Tup ? Tup extends [infer Ctor] ? IsUselessConstructorOverloadInfo extends true ? never : Ctor : never : never; +/** + * For versions of TypeScript below 5.3, we need to check for 10 overloads, + * then 9, then 8, etc., to get a union of the overload variants. + */ +export type DecreasingConstructorOverloadsInfoUnion = ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; + new (...args: infer A3): infer R3; + new (...args: infer A4): infer R4; + new (...args: infer A5): infer R5; + new (...args: infer A6): infer R6; + new (...args: infer A7): infer R7; + new (...args: infer A8): infer R8; + new (...args: infer A9): infer R9; + new (...args: infer A10): infer R10; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) | (new (...p: A3) => R3) | (new (...p: A4) => R4) | (new (...p: A5) => R5) | (new (...p: A6) => R6) | (new (...p: A7) => R7) | (new (...p: A8) => R8) | (new (...p: A9) => R9) | (new (...p: A10) => R10) : ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; + new (...args: infer A3): infer R3; + new (...args: infer A4): infer R4; + new (...args: infer A5): infer R5; + new (...args: infer A6): infer R6; + new (...args: infer A7): infer R7; + new (...args: infer A8): infer R8; + new (...args: infer A9): infer R9; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) | (new (...p: A3) => R3) | (new (...p: A4) => R4) | (new (...p: A5) => R5) | (new (...p: A6) => R6) | (new (...p: A7) => R7) | (new (...p: A8) => R8) | (new (...p: A9) => R9) : ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; + new (...args: infer A3): infer R3; + new (...args: infer A4): infer R4; + new (...args: infer A5): infer R5; + new (...args: infer A6): infer R6; + new (...args: infer A7): infer R7; + new (...args: infer A8): infer R8; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) | (new (...p: A3) => R3) | (new (...p: A4) => R4) | (new (...p: A5) => R5) | (new (...p: A6) => R6) | (new (...p: A7) => R7) | (new (...p: A8) => R8) : ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; + new (...args: infer A3): infer R3; + new (...args: infer A4): infer R4; + new (...args: infer A5): infer R5; + new (...args: infer A6): infer R6; + new (...args: infer A7): infer R7; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) | (new (...p: A3) => R3) | (new (...p: A4) => R4) | (new (...p: A5) => R5) | (new (...p: A6) => R6) | (new (...p: A7) => R7) : ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; + new (...args: infer A3): infer R3; + new (...args: infer A4): infer R4; + new (...args: infer A5): infer R5; + new (...args: infer A6): infer R6; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) | (new (...p: A3) => R3) | (new (...p: A4) => R4) | (new (...p: A5) => R5) | (new (...p: A6) => R6) : ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; + new (...args: infer A3): infer R3; + new (...args: infer A4): infer R4; + new (...args: infer A5): infer R5; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) | (new (...p: A3) => R3) | (new (...p: A4) => R4) | (new (...p: A5) => R5) : ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; + new (...args: infer A3): infer R3; + new (...args: infer A4): infer R4; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) | (new (...p: A3) => R3) | (new (...p: A4) => R4) : ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; + new (...args: infer A3): infer R3; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) | (new (...p: A3) => R3) : ConstructorType extends { + new (...args: infer A1): infer R1; + new (...args: infer A2): infer R2; +} ? (new (...p: A1) => R1) | (new (...p: A2) => R2) : ConstructorType extends new (...args: infer A1) => infer R1 ? (new (...p: A1) => R1) : never; +/** + * Get a union of overload variants for a constructor + * {@linkcode ConstructorType}. Does a check for whether we can do the + * one-shot 10-overload matcher (which works for ts\>5.3), and if not, + * falls back to the more complicated utility. + */ +export type ConstructorOverloadsUnion = IsNever any>> extends true ? TSPre53ConstructorOverloadsInfoUnion : TSPost53ConstructorOverloadsInfoUnion; +/** + * Allows inferring any constructor using the `infer` keyword. + */ +export type InferConstructor any> = ConstructorType; +/** + * A union type of the parameters allowed for any overload + * of constructor {@linkcode ConstructorType}. + */ +export type ConstructorOverloadParameters = ConstructorOverloadsUnion extends InferConstructor ? ConstructorParameters : never; +/** + * Calculates the number of overloads for a given function type. + */ +export type NumOverloads = UnionToTuple>['length']; diff --git a/node_modules/expect-type/dist/overloads.js b/node_modules/expect-type/dist/overloads.js new file mode 100644 index 0000000000..c8ad2e549b --- /dev/null +++ b/node_modules/expect-type/dist/overloads.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/expect-type/dist/utils.d.ts b/node_modules/expect-type/dist/utils.d.ts new file mode 100644 index 0000000000..255624b433 --- /dev/null +++ b/node_modules/expect-type/dist/utils.d.ts @@ -0,0 +1,197 @@ +/** + * Negates a boolean type. + */ +export type Not = T extends true ? false : true; +/** + * Returns `true` if at least one of the types in the + * {@linkcode Types} array is `true`, otherwise returns `false`. + */ +export type Or = Types[number] extends false ? false : true; +/** + * Checks if all the boolean types in the {@linkcode Types} array are `true`. + */ +export type And = Types[number] extends true ? true : false; +/** + * Represents an equality type that returns {@linkcode Right} if + * {@linkcode Left} is `true`, + * otherwise returns the negation of {@linkcode Right}. + */ +export type Eq = Left extends true ? Right : Not; +/** + * Represents the exclusive OR operation on a tuple of boolean types. + * Returns `true` if exactly one of the boolean types is `true`, + * otherwise returns `false`. + */ +export type Xor = Not>; +/** + * @internal + */ +declare const secret: unique symbol; +/** + * @internal + */ +type Secret = typeof secret; +/** + * Checks if the given type is `never`. + */ +export type IsNever = [T] extends [never] ? true : false; +/** + * Checks if the given type is `any`. + */ +export type IsAny = [T] extends [Secret] ? Not> : false; +/** + * Determines if the given type is `unknown`. + */ +export type IsUnknown = [unknown] extends [T] ? Not> : false; +/** + * Determines if a type is either `never` or `any`. + */ +export type IsNeverOrAny = Or<[IsNever, IsAny]>; +/** + * Subjective "useful" keys from a type. For objects it's just `keyof` but for + * tuples/arrays it's the number keys. + * + * @example + * ```ts + * UsefulKeys<{ a: 1; b: 2 }> // 'a' | 'b' + * + * UsefulKeys<['a', 'b']> // '0' | '1' + * + * UsefulKeys // number + * ``` + */ +export type UsefulKeys = T extends any[] ? { + [K in keyof T]: K; +}[number] : keyof T; +/** + * Extracts the keys from a type that are required (not optional). + */ +export type RequiredKeys = Extract<{ + [K in keyof T]-?: {} extends Pick ? never : K; +}[keyof T], keyof T>; +/** + * Gets the keys of an object type that are optional. + */ +export type OptionalKeys = Exclude>; +/** + * Extracts the keys from a type that are not `readonly`. + */ +export type ReadonlyKeys = Extract<{ + [K in keyof T]-?: ReadonlyEquivalent<{ + [_K in K]: T[K]; + }, { + -readonly [_K in K]: T[K]; + }> extends true ? never : K; +}[keyof T], keyof T>; +/** + * Determines if two types, are equivalent in a `readonly` manner. + * + * @internal + */ +type ReadonlyEquivalent = Extends<(() => T extends X ? true : false), (() => T extends Y ? true : false)>; +/** + * Checks if one type extends another. Note: this is not quite the same as `Left extends Right` because: + * 1. If either type is `never`, the result is `true` iff the other type is also `never`. + * 2. Types are wrapped in a 1-tuple so that union types are not distributed - instead we consider `string | number` to _not_ extend `number`. If we used `Left extends Right` directly you would get `Extends` => `false | true` => `boolean`. + */ +export type Extends = IsNever extends true ? IsNever : [Left] extends [Right] ? true : false; +/** + * Checks if the {@linkcode Left} type extends the {@linkcode Right} type, + * excluding `any` or `never`. + */ +export type ExtendsExcludingAnyOrNever = IsAny extends true ? IsAny : Extends; +/** + * Checks if two types are strictly equal using + * the TypeScript internal identical-to operator. + * + * @see {@link https://github.com/microsoft/TypeScript/issues/55188#issuecomment-1656328122 | much history} + */ +export type StrictEqualUsingTSInternalIdenticalToOperator = (() => T extends (L & T) | T ? true : false) extends () => T extends (R & T) | T ? true : false ? IsNever extends IsNever ? true : false : false; +/** + * Checks that {@linkcode Left} and {@linkcode Right} extend each other. + * Not quite the same as an equality check since `any` can make it resolve + * to `true`. So should only be used when {@linkcode Left} and + * {@linkcode Right} are known to avoid `any`. + */ +export type MutuallyExtends = And<[Extends, Extends]>; +/** + * @internal + */ +declare const mismatch: unique symbol; +/** + * @internal + */ +type Mismatch = { + [mismatch]: 'mismatch'; +}; +/** + * A type which should match anything passed as a value but *doesn't* + * match {@linkcode Mismatch}. It helps TypeScript select the right overload + * for {@linkcode PositiveExpectTypeOf.toEqualTypeOf | .toEqualTypeOf()} and + * {@linkcode PositiveExpectTypeOf.toMatchTypeOf | .toMatchTypeOf()}. + * + * @internal + */ +declare const avalue: unique symbol; +/** + * Represents a value that can be of various types. + */ +export type AValue = { + [avalue]?: undefined; +} | string | number | boolean | symbol | bigint | null | undefined | void; +/** + * Represents the type of mismatched arguments between + * the actual result and the expected result. + * + * If {@linkcode ActualResult} and {@linkcode ExpectedResult} are equivalent, + * the type resolves to an empty tuple `[]`, indicating no mismatch. + * If they are not equivalent, it resolves to a tuple containing the element + * {@linkcode Mismatch}, signifying a discrepancy between + * the expected and actual results. + */ +export type MismatchArgs = Eq extends true ? [] : [Mismatch]; +/** + * Represents the options for the {@linkcode ExpectTypeOf} function. + */ +export interface ExpectTypeOfOptions { + positive: boolean; + branded: boolean; +} +/** + * Convert a union to an intersection. + * `A | B | C` -\> `A & B & C` + */ +export type UnionToIntersection = (Union extends any ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : never; +/** + * Get the last element of a union. + * First, converts to a union of `() => T` functions, + * then uses {@linkcode UnionToIntersection} to get the last one. + */ +export type LastOf = UnionToIntersection Union : never> extends () => infer R ? R : never; +/** + * Intermediate type for {@linkcode UnionToTuple} which pushes the + * "last" union member to the end of a tuple, and recursively prepends + * the remainder of the union. + */ +export type TuplifyUnion> = IsNever extends true ? [] : [...TuplifyUnion>, LastElement]; +/** + * Convert a union like `1 | 2 | 3` to a tuple like `[1, 2, 3]`. + */ +export type UnionToTuple = TuplifyUnion; +export type IsTuple = Or<[Extends, Extends]>; +export type IsUnion = Not['length'], 1>>; +/** + * A recursive version of `Pick` that selects properties from the left type that are present in the right type. + * The "leaf" types from `Left` are used - only the keys of `Right` are considered. + * + * @example + * ```ts + * const user = {email: 'a@b.com', name: 'John Doe', address: {street: '123 2nd St', city: 'New York', zip: '10001', state: 'NY', country: 'USA'}} + * + * type Result = DeepPickMatchingProps // {name: string, address: {city: string}} + * ``` + */ +export type DeepPickMatchingProps = Left extends Record ? Pick<{ + [K in keyof Left]: K extends keyof Right ? DeepPickMatchingProps : never; +}, Extract> : Left; +export {}; diff --git a/node_modules/expect-type/dist/utils.js b/node_modules/expect-type/dist/utils.js new file mode 100644 index 0000000000..43407cf45b --- /dev/null +++ b/node_modules/expect-type/dist/utils.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * @internal + */ +const secret = Symbol('secret'); +/** + * @internal + */ +const mismatch = Symbol('mismatch'); +/** + * A type which should match anything passed as a value but *doesn't* + * match {@linkcode Mismatch}. It helps TypeScript select the right overload + * for {@linkcode PositiveExpectTypeOf.toEqualTypeOf | .toEqualTypeOf()} and + * {@linkcode PositiveExpectTypeOf.toMatchTypeOf | .toMatchTypeOf()}. + * + * @internal + */ +const avalue = Symbol('avalue'); diff --git a/node_modules/expect-type/package.json b/node_modules/expect-type/package.json new file mode 100644 index 0000000000..fe1714507c --- /dev/null +++ b/node_modules/expect-type/package.json @@ -0,0 +1,50 @@ +{ + "name": "expect-type", + "version": "1.2.2", + "engines": { + "node": ">=12.0.0" + }, + "keywords": [ + "typescript", + "type-check", + "assert", + "types", + "typings", + "test", + "testing" + ], + "homepage": "https://github.com/mmkal/expect-type#readme", + "repository": { + "type": "git", + "url": "https://github.com/mmkal/expect-type.git" + }, + "license": "Apache-2.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist", + "*.md" + ], + "devDependencies": { + "@arethetypeswrong/cli": "0.17.3", + "@types/node": "^22.0.0", + "@typescript/native-preview": "7.0.0-dev.20250527.1", + "@vitest/ui": "^3.0.0", + "eslint": "^8.57.0", + "eslint-plugin-mmkal": "0.9.0", + "np": "^10.2.0", + "pkg-pr-new": "0.0.39", + "strip-ansi": "7.1.0", + "ts-morph": "23.0.0", + "typescript": "5.8.3", + "vitest": "^3.0.0" + }, + "scripts": { + "eslint": "eslint --max-warnings 0", + "lint": "tsc && pnpm eslint .", + "type-check": "tsc", + "build": "tsc -p tsconfig.lib.json", + "arethetypeswrong": "attw --pack", + "test": "vitest run" + } +} \ No newline at end of file diff --git a/node_modules/fdir/LICENSE b/node_modules/fdir/LICENSE new file mode 100644 index 0000000000..bb7fdee44c --- /dev/null +++ b/node_modules/fdir/LICENSE @@ -0,0 +1,7 @@ +Copyright 2023 Abdullah Atta + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/fdir/README.md b/node_modules/fdir/README.md new file mode 100644 index 0000000000..5c70530fa0 --- /dev/null +++ b/node_modules/fdir/README.md @@ -0,0 +1,91 @@ +

+ + +

The Fastest Directory Crawler & Globber for NodeJS

+

+ + + + + + + + +

+

+ +⚡ **The Fastest:** Nothing similar (in the NodeJS world) beats `fdir` in speed. It can easily crawl a directory containing **1 million files in < 1 second.** + +💡 **Stupidly Easy:** `fdir` uses expressive Builder pattern to build the crawler increasing code readability. + +🤖 **Zero Dependencies\*:** `fdir` only uses NodeJS `fs` & `path` modules. + +🕺 **Astonishingly Small:** < 2KB in size gzipped & minified. + +🖮 **Hackable:** Extending `fdir` is extremely simple now that the new Builder API is here. Feel free to experiment around. + +_\* `picomatch` must be installed manually by the user to support globbing._ + +## 🚄 Quickstart + +### Installation + +You can install using `npm`: + +```sh +$ npm i fdir +``` + +or Yarn: + +```sh +$ yarn add fdir +``` + +### Usage + +```ts +import { fdir } from "fdir"; + +// create the builder +const api = new fdir().withFullPaths().crawl("path/to/dir"); + +// get all files in a directory synchronously +const files = api.sync(); + +// or asynchronously +api.withPromise().then((files) => { + // do something with the result here. +}); +``` + +## Documentation: + +Documentation for all methods is available [here](/documentation.md). + +## 📊 Benchmarks: + +Please check the benchmark against the latest version [here](/BENCHMARKS.md). + +## 🙏Used by: + +`fdir` is downloaded over 200k+ times a week by projects around the world. Here's a list of some notable projects using `fdir` in production: + +> Note: if you think your project should be here, feel free to open an issue. Notable is anything with a considerable amount of GitHub stars. + +1. [rollup/plugins](https://github.com/rollup/plugins) +2. [SuperchupuDev/tinyglobby](https://github.com/SuperchupuDev/tinyglobby) +3. [pulumi/pulumi](https://github.com/pulumi/pulumi) +4. [dotenvx/dotenvx](https://github.com/dotenvx/dotenvx) +5. [mdn/yari](https://github.com/mdn/yari) +6. [streetwriters/notesnook](https://github.com/streetwriters/notesnook) +7. [imba/imba](https://github.com/imba/imba) +8. [moroshko/react-scanner](https://github.com/moroshko/react-scanner) +9. [netlify/build](https://github.com/netlify/build) +10. [yassinedoghri/astro-i18next](https://github.com/yassinedoghri/astro-i18next) +11. [selfrefactor/rambda](https://github.com/selfrefactor/rambda) +12. [whyboris/Video-Hub-App](https://github.com/whyboris/Video-Hub-App) + +## 🦮 LICENSE + +Copyright © 2024 Abdullah Atta under MIT. [Read full text here.](https://github.com/thecodrr/fdir/raw/master/LICENSE) diff --git a/node_modules/fdir/dist/index.cjs b/node_modules/fdir/dist/index.cjs new file mode 100644 index 0000000000..4868ffba35 --- /dev/null +++ b/node_modules/fdir/dist/index.cjs @@ -0,0 +1,588 @@ +//#region rolldown:runtime +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { + key = keys[i]; + if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { + get: ((k) => from[k]).bind(null, key), + enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable + }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { + value: mod, + enumerable: true +}) : target, mod)); + +//#endregion +const path = __toESM(require("path")); +const fs = __toESM(require("fs")); + +//#region src/utils.ts +function cleanPath(path$1) { + let normalized = (0, path.normalize)(path$1); + if (normalized.length > 1 && normalized[normalized.length - 1] === path.sep) normalized = normalized.substring(0, normalized.length - 1); + return normalized; +} +const SLASHES_REGEX = /[\\/]/g; +function convertSlashes(path$1, separator) { + return path$1.replace(SLASHES_REGEX, separator); +} +const WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i; +function isRootDirectory(path$1) { + return path$1 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path$1); +} +function normalizePath(path$1, options) { + const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options; + const pathNeedsCleaning = process.platform === "win32" && path$1.includes("/") || path$1.startsWith("."); + if (resolvePaths) path$1 = (0, path.resolve)(path$1); + if (normalizePath$1 || pathNeedsCleaning) path$1 = cleanPath(path$1); + if (path$1 === ".") return ""; + const needsSeperator = path$1[path$1.length - 1] !== pathSeparator; + return convertSlashes(needsSeperator ? path$1 + pathSeparator : path$1, pathSeparator); +} + +//#endregion +//#region src/api/functions/join-path.ts +function joinPathWithBasePath(filename, directoryPath) { + return directoryPath + filename; +} +function joinPathWithRelativePath(root, options) { + return function(filename, directoryPath) { + const sameRoot = directoryPath.startsWith(root); + if (sameRoot) return directoryPath.slice(root.length) + filename; + else return convertSlashes((0, path.relative)(root, directoryPath), options.pathSeparator) + options.pathSeparator + filename; + }; +} +function joinPath(filename) { + return filename; +} +function joinDirectoryPath(filename, directoryPath, separator) { + return directoryPath + filename + separator; +} +function build$7(root, options) { + const { relativePaths, includeBasePath } = options; + return relativePaths && root ? joinPathWithRelativePath(root, options) : includeBasePath ? joinPathWithBasePath : joinPath; +} + +//#endregion +//#region src/api/functions/push-directory.ts +function pushDirectoryWithRelativePath(root) { + return function(directoryPath, paths) { + paths.push(directoryPath.substring(root.length) || "."); + }; +} +function pushDirectoryFilterWithRelativePath(root) { + return function(directoryPath, paths, filters) { + const relativePath = directoryPath.substring(root.length) || "."; + if (filters.every((filter) => filter(relativePath, true))) paths.push(relativePath); + }; +} +const pushDirectory = (directoryPath, paths) => { + paths.push(directoryPath || "."); +}; +const pushDirectoryFilter = (directoryPath, paths, filters) => { + const path$1 = directoryPath || "."; + if (filters.every((filter) => filter(path$1, true))) paths.push(path$1); +}; +const empty$2 = () => {}; +function build$6(root, options) { + const { includeDirs, filters, relativePaths } = options; + if (!includeDirs) return empty$2; + if (relativePaths) return filters && filters.length ? pushDirectoryFilterWithRelativePath(root) : pushDirectoryWithRelativePath(root); + return filters && filters.length ? pushDirectoryFilter : pushDirectory; +} + +//#endregion +//#region src/api/functions/push-file.ts +const pushFileFilterAndCount = (filename, _paths, counts, filters) => { + if (filters.every((filter) => filter(filename, false))) counts.files++; +}; +const pushFileFilter = (filename, paths, _counts, filters) => { + if (filters.every((filter) => filter(filename, false))) paths.push(filename); +}; +const pushFileCount = (_filename, _paths, counts, _filters) => { + counts.files++; +}; +const pushFile = (filename, paths) => { + paths.push(filename); +}; +const empty$1 = () => {}; +function build$5(options) { + const { excludeFiles, filters, onlyCounts } = options; + if (excludeFiles) return empty$1; + if (filters && filters.length) return onlyCounts ? pushFileFilterAndCount : pushFileFilter; + else if (onlyCounts) return pushFileCount; + else return pushFile; +} + +//#endregion +//#region src/api/functions/get-array.ts +const getArray = (paths) => { + return paths; +}; +const getArrayGroup = () => { + return [""].slice(0, 0); +}; +function build$4(options) { + return options.group ? getArrayGroup : getArray; +} + +//#endregion +//#region src/api/functions/group-files.ts +const groupFiles = (groups, directory, files) => { + groups.push({ + directory, + files, + dir: directory + }); +}; +const empty = () => {}; +function build$3(options) { + return options.group ? groupFiles : empty; +} + +//#endregion +//#region src/api/functions/resolve-symlink.ts +const resolveSymlinksAsync = function(path$1, state, callback$1) { + const { queue, fs: fs$1, options: { suppressErrors } } = state; + queue.enqueue(); + fs$1.realpath(path$1, (error, resolvedPath) => { + if (error) return queue.dequeue(suppressErrors ? null : error, state); + fs$1.stat(resolvedPath, (error$1, stat) => { + if (error$1) return queue.dequeue(suppressErrors ? null : error$1, state); + if (stat.isDirectory() && isRecursive(path$1, resolvedPath, state)) return queue.dequeue(null, state); + callback$1(stat, resolvedPath); + queue.dequeue(null, state); + }); + }); +}; +const resolveSymlinks = function(path$1, state, callback$1) { + const { queue, fs: fs$1, options: { suppressErrors } } = state; + queue.enqueue(); + try { + const resolvedPath = fs$1.realpathSync(path$1); + const stat = fs$1.statSync(resolvedPath); + if (stat.isDirectory() && isRecursive(path$1, resolvedPath, state)) return; + callback$1(stat, resolvedPath); + } catch (e) { + if (!suppressErrors) throw e; + } +}; +function build$2(options, isSynchronous) { + if (!options.resolveSymlinks || options.excludeSymlinks) return null; + return isSynchronous ? resolveSymlinks : resolveSymlinksAsync; +} +function isRecursive(path$1, resolved, state) { + if (state.options.useRealPaths) return isRecursiveUsingRealPaths(resolved, state); + let parent = (0, path.dirname)(path$1); + let depth = 1; + while (parent !== state.root && depth < 2) { + const resolvedPath = state.symlinks.get(parent); + const isSameRoot = !!resolvedPath && (resolvedPath === resolved || resolvedPath.startsWith(resolved) || resolved.startsWith(resolvedPath)); + if (isSameRoot) depth++; + else parent = (0, path.dirname)(parent); + } + state.symlinks.set(path$1, resolved); + return depth > 1; +} +function isRecursiveUsingRealPaths(resolved, state) { + return state.visited.includes(resolved + state.options.pathSeparator); +} + +//#endregion +//#region src/api/functions/invoke-callback.ts +const onlyCountsSync = (state) => { + return state.counts; +}; +const groupsSync = (state) => { + return state.groups; +}; +const defaultSync = (state) => { + return state.paths; +}; +const limitFilesSync = (state) => { + return state.paths.slice(0, state.options.maxFiles); +}; +const onlyCountsAsync = (state, error, callback$1) => { + report(error, callback$1, state.counts, state.options.suppressErrors); + return null; +}; +const defaultAsync = (state, error, callback$1) => { + report(error, callback$1, state.paths, state.options.suppressErrors); + return null; +}; +const limitFilesAsync = (state, error, callback$1) => { + report(error, callback$1, state.paths.slice(0, state.options.maxFiles), state.options.suppressErrors); + return null; +}; +const groupsAsync = (state, error, callback$1) => { + report(error, callback$1, state.groups, state.options.suppressErrors); + return null; +}; +function report(error, callback$1, output, suppressErrors) { + if (error && !suppressErrors) callback$1(error, output); + else callback$1(null, output); +} +function build$1(options, isSynchronous) { + const { onlyCounts, group, maxFiles } = options; + if (onlyCounts) return isSynchronous ? onlyCountsSync : onlyCountsAsync; + else if (group) return isSynchronous ? groupsSync : groupsAsync; + else if (maxFiles) return isSynchronous ? limitFilesSync : limitFilesAsync; + else return isSynchronous ? defaultSync : defaultAsync; +} + +//#endregion +//#region src/api/functions/walk-directory.ts +const readdirOpts = { withFileTypes: true }; +const walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => { + state.queue.enqueue(); + if (currentDepth < 0) return state.queue.dequeue(null, state); + const { fs: fs$1 } = state; + state.visited.push(crawlPath); + state.counts.directories++; + fs$1.readdir(crawlPath || ".", readdirOpts, (error, entries = []) => { + callback$1(entries, directoryPath, currentDepth); + state.queue.dequeue(state.options.suppressErrors ? null : error, state); + }); +}; +const walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => { + const { fs: fs$1 } = state; + if (currentDepth < 0) return; + state.visited.push(crawlPath); + state.counts.directories++; + let entries = []; + try { + entries = fs$1.readdirSync(crawlPath || ".", readdirOpts); + } catch (e) { + if (!state.options.suppressErrors) throw e; + } + callback$1(entries, directoryPath, currentDepth); +}; +function build(isSynchronous) { + return isSynchronous ? walkSync : walkAsync; +} + +//#endregion +//#region src/api/queue.ts +/** +* This is a custom stateless queue to track concurrent async fs calls. +* It increments a counter whenever a call is queued and decrements it +* as soon as it completes. When the counter hits 0, it calls onQueueEmpty. +*/ +var Queue = class { + count = 0; + constructor(onQueueEmpty) { + this.onQueueEmpty = onQueueEmpty; + } + enqueue() { + this.count++; + return this.count; + } + dequeue(error, output) { + if (this.onQueueEmpty && (--this.count <= 0 || error)) { + this.onQueueEmpty(error, output); + if (error) { + output.controller.abort(); + this.onQueueEmpty = void 0; + } + } + } +}; + +//#endregion +//#region src/api/counter.ts +var Counter = class { + _files = 0; + _directories = 0; + set files(num) { + this._files = num; + } + get files() { + return this._files; + } + set directories(num) { + this._directories = num; + } + get directories() { + return this._directories; + } + /** + * @deprecated use `directories` instead + */ + /* c8 ignore next 3 */ + get dirs() { + return this._directories; + } +}; + +//#endregion +//#region src/api/aborter.ts +/** +* AbortController is not supported on Node 14 so we use this until we can drop +* support for Node 14. +*/ +var Aborter = class { + aborted = false; + abort() { + this.aborted = true; + } +}; + +//#endregion +//#region src/api/walker.ts +var Walker = class { + root; + isSynchronous; + state; + joinPath; + pushDirectory; + pushFile; + getArray; + groupFiles; + resolveSymlink; + walkDirectory; + callbackInvoker; + constructor(root, options, callback$1) { + this.isSynchronous = !callback$1; + this.callbackInvoker = build$1(options, this.isSynchronous); + this.root = normalizePath(root, options); + this.state = { + root: isRootDirectory(this.root) ? this.root : this.root.slice(0, -1), + paths: [""].slice(0, 0), + groups: [], + counts: new Counter(), + options, + queue: new Queue((error, state) => this.callbackInvoker(state, error, callback$1)), + symlinks: /* @__PURE__ */ new Map(), + visited: [""].slice(0, 0), + controller: new Aborter(), + fs: options.fs || fs + }; + this.joinPath = build$7(this.root, options); + this.pushDirectory = build$6(this.root, options); + this.pushFile = build$5(options); + this.getArray = build$4(options); + this.groupFiles = build$3(options); + this.resolveSymlink = build$2(options, this.isSynchronous); + this.walkDirectory = build(this.isSynchronous); + } + start() { + this.pushDirectory(this.root, this.state.paths, this.state.options.filters); + this.walkDirectory(this.state, this.root, this.root, this.state.options.maxDepth, this.walk); + return this.isSynchronous ? this.callbackInvoker(this.state, null) : null; + } + walk = (entries, directoryPath, depth) => { + const { paths, options: { filters, resolveSymlinks: resolveSymlinks$1, excludeSymlinks, exclude, maxFiles, signal, useRealPaths, pathSeparator }, controller } = this.state; + if (controller.aborted || signal && signal.aborted || maxFiles && paths.length > maxFiles) return; + const files = this.getArray(this.state.paths); + for (let i = 0; i < entries.length; ++i) { + const entry = entries[i]; + if (entry.isFile() || entry.isSymbolicLink() && !resolveSymlinks$1 && !excludeSymlinks) { + const filename = this.joinPath(entry.name, directoryPath); + this.pushFile(filename, files, this.state.counts, filters); + } else if (entry.isDirectory()) { + let path$1 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator); + if (exclude && exclude(entry.name, path$1)) continue; + this.pushDirectory(path$1, paths, filters); + this.walkDirectory(this.state, path$1, path$1, depth - 1, this.walk); + } else if (this.resolveSymlink && entry.isSymbolicLink()) { + let path$1 = joinPathWithBasePath(entry.name, directoryPath); + this.resolveSymlink(path$1, this.state, (stat, resolvedPath) => { + if (stat.isDirectory()) { + resolvedPath = normalizePath(resolvedPath, this.state.options); + if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path$1 + pathSeparator)) return; + this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path$1 + pathSeparator, depth - 1, this.walk); + } else { + resolvedPath = useRealPaths ? resolvedPath : path$1; + const filename = (0, path.basename)(resolvedPath); + const directoryPath$1 = normalizePath((0, path.dirname)(resolvedPath), this.state.options); + resolvedPath = this.joinPath(filename, directoryPath$1); + this.pushFile(resolvedPath, files, this.state.counts, filters); + } + }); + } + } + this.groupFiles(this.state.groups, directoryPath, files); + }; +}; + +//#endregion +//#region src/api/async.ts +function promise(root, options) { + return new Promise((resolve$1, reject) => { + callback(root, options, (err, output) => { + if (err) return reject(err); + resolve$1(output); + }); + }); +} +function callback(root, options, callback$1) { + let walker = new Walker(root, options, callback$1); + walker.start(); +} + +//#endregion +//#region src/api/sync.ts +function sync(root, options) { + const walker = new Walker(root, options); + return walker.start(); +} + +//#endregion +//#region src/builder/api-builder.ts +var APIBuilder = class { + constructor(root, options) { + this.root = root; + this.options = options; + } + withPromise() { + return promise(this.root, this.options); + } + withCallback(cb) { + callback(this.root, this.options, cb); + } + sync() { + return sync(this.root, this.options); + } +}; + +//#endregion +//#region src/builder/index.ts +let pm = null; +/* c8 ignore next 6 */ +try { + require.resolve("picomatch"); + pm = require("picomatch"); +} catch {} +var Builder = class { + globCache = {}; + options = { + maxDepth: Infinity, + suppressErrors: true, + pathSeparator: path.sep, + filters: [] + }; + globFunction; + constructor(options) { + this.options = { + ...this.options, + ...options + }; + this.globFunction = this.options.globFunction; + } + group() { + this.options.group = true; + return this; + } + withPathSeparator(separator) { + this.options.pathSeparator = separator; + return this; + } + withBasePath() { + this.options.includeBasePath = true; + return this; + } + withRelativePaths() { + this.options.relativePaths = true; + return this; + } + withDirs() { + this.options.includeDirs = true; + return this; + } + withMaxDepth(depth) { + this.options.maxDepth = depth; + return this; + } + withMaxFiles(limit) { + this.options.maxFiles = limit; + return this; + } + withFullPaths() { + this.options.resolvePaths = true; + this.options.includeBasePath = true; + return this; + } + withErrors() { + this.options.suppressErrors = false; + return this; + } + withSymlinks({ resolvePaths = true } = {}) { + this.options.resolveSymlinks = true; + this.options.useRealPaths = resolvePaths; + return this.withFullPaths(); + } + withAbortSignal(signal) { + this.options.signal = signal; + return this; + } + normalize() { + this.options.normalizePath = true; + return this; + } + filter(predicate) { + this.options.filters.push(predicate); + return this; + } + onlyDirs() { + this.options.excludeFiles = true; + this.options.includeDirs = true; + return this; + } + exclude(predicate) { + this.options.exclude = predicate; + return this; + } + onlyCounts() { + this.options.onlyCounts = true; + return this; + } + crawl(root) { + return new APIBuilder(root || ".", this.options); + } + withGlobFunction(fn) { + this.globFunction = fn; + return this; + } + /** + * @deprecated Pass options using the constructor instead: + * ```ts + * new fdir(options).crawl("/path/to/root"); + * ``` + * This method will be removed in v7.0 + */ + /* c8 ignore next 4 */ + crawlWithOptions(root, options) { + this.options = { + ...this.options, + ...options + }; + return new APIBuilder(root || ".", this.options); + } + glob(...patterns) { + if (this.globFunction) return this.globWithOptions(patterns); + return this.globWithOptions(patterns, ...[{ dot: true }]); + } + globWithOptions(patterns, ...options) { + const globFn = this.globFunction || pm; + /* c8 ignore next 5 */ + if (!globFn) throw new Error("Please specify a glob function to use glob matching."); + var isMatch = this.globCache[patterns.join("\0")]; + if (!isMatch) { + isMatch = globFn(patterns, ...options); + this.globCache[patterns.join("\0")] = isMatch; + } + this.options.filters.push((path$1) => isMatch(path$1)); + return this; + } +}; + +//#endregion +exports.fdir = Builder; \ No newline at end of file diff --git a/node_modules/fdir/dist/index.d.cts b/node_modules/fdir/dist/index.d.cts new file mode 100644 index 0000000000..f448ef5d9b --- /dev/null +++ b/node_modules/fdir/dist/index.d.cts @@ -0,0 +1,155 @@ +/// +import * as nativeFs from "fs"; +import picomatch from "picomatch"; + +//#region src/api/aborter.d.ts +/** + * AbortController is not supported on Node 14 so we use this until we can drop + * support for Node 14. + */ +declare class Aborter { + aborted: boolean; + abort(): void; +} +//#endregion +//#region src/api/queue.d.ts +type OnQueueEmptyCallback = (error: Error | null, output: WalkerState) => void; +/** + * This is a custom stateless queue to track concurrent async fs calls. + * It increments a counter whenever a call is queued and decrements it + * as soon as it completes. When the counter hits 0, it calls onQueueEmpty. + */ +declare class Queue { + private onQueueEmpty?; + count: number; + constructor(onQueueEmpty?: OnQueueEmptyCallback | undefined); + enqueue(): number; + dequeue(error: Error | null, output: WalkerState): void; +} +//#endregion +//#region src/types.d.ts +type Counts = { + files: number; + directories: number; + /** + * @deprecated use `directories` instead. Will be removed in v7.0. + */ + dirs: number; +}; +type Group = { + directory: string; + files: string[]; + /** + * @deprecated use `directory` instead. Will be removed in v7.0. + */ + dir: string; +}; +type GroupOutput = Group[]; +type OnlyCountsOutput = Counts; +type PathsOutput = string[]; +type Output = OnlyCountsOutput | PathsOutput | GroupOutput; +type FSLike = { + readdir: typeof nativeFs.readdir; + readdirSync: typeof nativeFs.readdirSync; + realpath: typeof nativeFs.realpath; + realpathSync: typeof nativeFs.realpathSync; + stat: typeof nativeFs.stat; + statSync: typeof nativeFs.statSync; +}; +type WalkerState = { + root: string; + paths: string[]; + groups: Group[]; + counts: Counts; + options: Options; + queue: Queue; + controller: Aborter; + fs: FSLike; + symlinks: Map; + visited: string[]; +}; +type ResultCallback = (error: Error | null, output: TOutput) => void; +type FilterPredicate = (path: string, isDirectory: boolean) => boolean; +type ExcludePredicate = (dirName: string, dirPath: string) => boolean; +type PathSeparator = "/" | "\\"; +type Options = { + includeBasePath?: boolean; + includeDirs?: boolean; + normalizePath?: boolean; + maxDepth: number; + maxFiles?: number; + resolvePaths?: boolean; + suppressErrors: boolean; + group?: boolean; + onlyCounts?: boolean; + filters: FilterPredicate[]; + resolveSymlinks?: boolean; + useRealPaths?: boolean; + excludeFiles?: boolean; + excludeSymlinks?: boolean; + exclude?: ExcludePredicate; + relativePaths?: boolean; + pathSeparator: PathSeparator; + signal?: AbortSignal; + globFunction?: TGlobFunction; + fs?: FSLike; +}; +type GlobMatcher = (test: string) => boolean; +type GlobFunction = (glob: string | string[], ...params: unknown[]) => GlobMatcher; +type GlobParams = T extends ((globs: string | string[], ...params: infer TParams extends unknown[]) => GlobMatcher) ? TParams : []; +//#endregion +//#region src/builder/api-builder.d.ts +declare class APIBuilder { + private readonly root; + private readonly options; + constructor(root: string, options: Options); + withPromise(): Promise; + withCallback(cb: ResultCallback): void; + sync(): TReturnType; +} +//#endregion +//#region src/builder/index.d.ts +declare class Builder { + private readonly globCache; + private options; + private globFunction?; + constructor(options?: Partial>); + group(): Builder; + withPathSeparator(separator: "/" | "\\"): this; + withBasePath(): this; + withRelativePaths(): this; + withDirs(): this; + withMaxDepth(depth: number): this; + withMaxFiles(limit: number): this; + withFullPaths(): this; + withErrors(): this; + withSymlinks({ + resolvePaths + }?: { + resolvePaths?: boolean | undefined; + }): this; + withAbortSignal(signal: AbortSignal): this; + normalize(): this; + filter(predicate: FilterPredicate): this; + onlyDirs(): this; + exclude(predicate: ExcludePredicate): this; + onlyCounts(): Builder; + crawl(root?: string): APIBuilder; + withGlobFunction(fn: TFunc): Builder; + /** + * @deprecated Pass options using the constructor instead: + * ```ts + * new fdir(options).crawl("/path/to/root"); + * ``` + * This method will be removed in v7.0 + */ + crawlWithOptions(root: string, options: Partial>): APIBuilder; + glob(...patterns: string[]): Builder; + globWithOptions(patterns: string[]): Builder; + globWithOptions(patterns: string[], ...options: GlobParams): Builder; +} +//#endregion +//#region src/index.d.ts +type Fdir = typeof Builder; +//#endregion +export { Counts, ExcludePredicate, FSLike, Fdir, FilterPredicate, GlobFunction, GlobMatcher, GlobParams, Group, GroupOutput, OnlyCountsOutput, Options, Output, PathSeparator, PathsOutput, ResultCallback, WalkerState, Builder as fdir }; \ No newline at end of file diff --git a/node_modules/fdir/dist/index.d.mts b/node_modules/fdir/dist/index.d.mts new file mode 100644 index 0000000000..f448ef5d9b --- /dev/null +++ b/node_modules/fdir/dist/index.d.mts @@ -0,0 +1,155 @@ +/// +import * as nativeFs from "fs"; +import picomatch from "picomatch"; + +//#region src/api/aborter.d.ts +/** + * AbortController is not supported on Node 14 so we use this until we can drop + * support for Node 14. + */ +declare class Aborter { + aborted: boolean; + abort(): void; +} +//#endregion +//#region src/api/queue.d.ts +type OnQueueEmptyCallback = (error: Error | null, output: WalkerState) => void; +/** + * This is a custom stateless queue to track concurrent async fs calls. + * It increments a counter whenever a call is queued and decrements it + * as soon as it completes. When the counter hits 0, it calls onQueueEmpty. + */ +declare class Queue { + private onQueueEmpty?; + count: number; + constructor(onQueueEmpty?: OnQueueEmptyCallback | undefined); + enqueue(): number; + dequeue(error: Error | null, output: WalkerState): void; +} +//#endregion +//#region src/types.d.ts +type Counts = { + files: number; + directories: number; + /** + * @deprecated use `directories` instead. Will be removed in v7.0. + */ + dirs: number; +}; +type Group = { + directory: string; + files: string[]; + /** + * @deprecated use `directory` instead. Will be removed in v7.0. + */ + dir: string; +}; +type GroupOutput = Group[]; +type OnlyCountsOutput = Counts; +type PathsOutput = string[]; +type Output = OnlyCountsOutput | PathsOutput | GroupOutput; +type FSLike = { + readdir: typeof nativeFs.readdir; + readdirSync: typeof nativeFs.readdirSync; + realpath: typeof nativeFs.realpath; + realpathSync: typeof nativeFs.realpathSync; + stat: typeof nativeFs.stat; + statSync: typeof nativeFs.statSync; +}; +type WalkerState = { + root: string; + paths: string[]; + groups: Group[]; + counts: Counts; + options: Options; + queue: Queue; + controller: Aborter; + fs: FSLike; + symlinks: Map; + visited: string[]; +}; +type ResultCallback = (error: Error | null, output: TOutput) => void; +type FilterPredicate = (path: string, isDirectory: boolean) => boolean; +type ExcludePredicate = (dirName: string, dirPath: string) => boolean; +type PathSeparator = "/" | "\\"; +type Options = { + includeBasePath?: boolean; + includeDirs?: boolean; + normalizePath?: boolean; + maxDepth: number; + maxFiles?: number; + resolvePaths?: boolean; + suppressErrors: boolean; + group?: boolean; + onlyCounts?: boolean; + filters: FilterPredicate[]; + resolveSymlinks?: boolean; + useRealPaths?: boolean; + excludeFiles?: boolean; + excludeSymlinks?: boolean; + exclude?: ExcludePredicate; + relativePaths?: boolean; + pathSeparator: PathSeparator; + signal?: AbortSignal; + globFunction?: TGlobFunction; + fs?: FSLike; +}; +type GlobMatcher = (test: string) => boolean; +type GlobFunction = (glob: string | string[], ...params: unknown[]) => GlobMatcher; +type GlobParams = T extends ((globs: string | string[], ...params: infer TParams extends unknown[]) => GlobMatcher) ? TParams : []; +//#endregion +//#region src/builder/api-builder.d.ts +declare class APIBuilder { + private readonly root; + private readonly options; + constructor(root: string, options: Options); + withPromise(): Promise; + withCallback(cb: ResultCallback): void; + sync(): TReturnType; +} +//#endregion +//#region src/builder/index.d.ts +declare class Builder { + private readonly globCache; + private options; + private globFunction?; + constructor(options?: Partial>); + group(): Builder; + withPathSeparator(separator: "/" | "\\"): this; + withBasePath(): this; + withRelativePaths(): this; + withDirs(): this; + withMaxDepth(depth: number): this; + withMaxFiles(limit: number): this; + withFullPaths(): this; + withErrors(): this; + withSymlinks({ + resolvePaths + }?: { + resolvePaths?: boolean | undefined; + }): this; + withAbortSignal(signal: AbortSignal): this; + normalize(): this; + filter(predicate: FilterPredicate): this; + onlyDirs(): this; + exclude(predicate: ExcludePredicate): this; + onlyCounts(): Builder; + crawl(root?: string): APIBuilder; + withGlobFunction(fn: TFunc): Builder; + /** + * @deprecated Pass options using the constructor instead: + * ```ts + * new fdir(options).crawl("/path/to/root"); + * ``` + * This method will be removed in v7.0 + */ + crawlWithOptions(root: string, options: Partial>): APIBuilder; + glob(...patterns: string[]): Builder; + globWithOptions(patterns: string[]): Builder; + globWithOptions(patterns: string[], ...options: GlobParams): Builder; +} +//#endregion +//#region src/index.d.ts +type Fdir = typeof Builder; +//#endregion +export { Counts, ExcludePredicate, FSLike, Fdir, FilterPredicate, GlobFunction, GlobMatcher, GlobParams, Group, GroupOutput, OnlyCountsOutput, Options, Output, PathSeparator, PathsOutput, ResultCallback, WalkerState, Builder as fdir }; \ No newline at end of file diff --git a/node_modules/fdir/dist/index.mjs b/node_modules/fdir/dist/index.mjs new file mode 100644 index 0000000000..5c37e092b5 --- /dev/null +++ b/node_modules/fdir/dist/index.mjs @@ -0,0 +1,570 @@ +import { createRequire } from "module"; +import { basename, dirname, normalize, relative, resolve, sep } from "path"; +import * as nativeFs from "fs"; + +//#region rolldown:runtime +var __require = /* @__PURE__ */ createRequire(import.meta.url); + +//#endregion +//#region src/utils.ts +function cleanPath(path) { + let normalized = normalize(path); + if (normalized.length > 1 && normalized[normalized.length - 1] === sep) normalized = normalized.substring(0, normalized.length - 1); + return normalized; +} +const SLASHES_REGEX = /[\\/]/g; +function convertSlashes(path, separator) { + return path.replace(SLASHES_REGEX, separator); +} +const WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i; +function isRootDirectory(path) { + return path === "/" || WINDOWS_ROOT_DIR_REGEX.test(path); +} +function normalizePath(path, options) { + const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options; + const pathNeedsCleaning = process.platform === "win32" && path.includes("/") || path.startsWith("."); + if (resolvePaths) path = resolve(path); + if (normalizePath$1 || pathNeedsCleaning) path = cleanPath(path); + if (path === ".") return ""; + const needsSeperator = path[path.length - 1] !== pathSeparator; + return convertSlashes(needsSeperator ? path + pathSeparator : path, pathSeparator); +} + +//#endregion +//#region src/api/functions/join-path.ts +function joinPathWithBasePath(filename, directoryPath) { + return directoryPath + filename; +} +function joinPathWithRelativePath(root, options) { + return function(filename, directoryPath) { + const sameRoot = directoryPath.startsWith(root); + if (sameRoot) return directoryPath.slice(root.length) + filename; + else return convertSlashes(relative(root, directoryPath), options.pathSeparator) + options.pathSeparator + filename; + }; +} +function joinPath(filename) { + return filename; +} +function joinDirectoryPath(filename, directoryPath, separator) { + return directoryPath + filename + separator; +} +function build$7(root, options) { + const { relativePaths, includeBasePath } = options; + return relativePaths && root ? joinPathWithRelativePath(root, options) : includeBasePath ? joinPathWithBasePath : joinPath; +} + +//#endregion +//#region src/api/functions/push-directory.ts +function pushDirectoryWithRelativePath(root) { + return function(directoryPath, paths) { + paths.push(directoryPath.substring(root.length) || "."); + }; +} +function pushDirectoryFilterWithRelativePath(root) { + return function(directoryPath, paths, filters) { + const relativePath = directoryPath.substring(root.length) || "."; + if (filters.every((filter) => filter(relativePath, true))) paths.push(relativePath); + }; +} +const pushDirectory = (directoryPath, paths) => { + paths.push(directoryPath || "."); +}; +const pushDirectoryFilter = (directoryPath, paths, filters) => { + const path = directoryPath || "."; + if (filters.every((filter) => filter(path, true))) paths.push(path); +}; +const empty$2 = () => {}; +function build$6(root, options) { + const { includeDirs, filters, relativePaths } = options; + if (!includeDirs) return empty$2; + if (relativePaths) return filters && filters.length ? pushDirectoryFilterWithRelativePath(root) : pushDirectoryWithRelativePath(root); + return filters && filters.length ? pushDirectoryFilter : pushDirectory; +} + +//#endregion +//#region src/api/functions/push-file.ts +const pushFileFilterAndCount = (filename, _paths, counts, filters) => { + if (filters.every((filter) => filter(filename, false))) counts.files++; +}; +const pushFileFilter = (filename, paths, _counts, filters) => { + if (filters.every((filter) => filter(filename, false))) paths.push(filename); +}; +const pushFileCount = (_filename, _paths, counts, _filters) => { + counts.files++; +}; +const pushFile = (filename, paths) => { + paths.push(filename); +}; +const empty$1 = () => {}; +function build$5(options) { + const { excludeFiles, filters, onlyCounts } = options; + if (excludeFiles) return empty$1; + if (filters && filters.length) return onlyCounts ? pushFileFilterAndCount : pushFileFilter; + else if (onlyCounts) return pushFileCount; + else return pushFile; +} + +//#endregion +//#region src/api/functions/get-array.ts +const getArray = (paths) => { + return paths; +}; +const getArrayGroup = () => { + return [""].slice(0, 0); +}; +function build$4(options) { + return options.group ? getArrayGroup : getArray; +} + +//#endregion +//#region src/api/functions/group-files.ts +const groupFiles = (groups, directory, files) => { + groups.push({ + directory, + files, + dir: directory + }); +}; +const empty = () => {}; +function build$3(options) { + return options.group ? groupFiles : empty; +} + +//#endregion +//#region src/api/functions/resolve-symlink.ts +const resolveSymlinksAsync = function(path, state, callback$1) { + const { queue, fs, options: { suppressErrors } } = state; + queue.enqueue(); + fs.realpath(path, (error, resolvedPath) => { + if (error) return queue.dequeue(suppressErrors ? null : error, state); + fs.stat(resolvedPath, (error$1, stat) => { + if (error$1) return queue.dequeue(suppressErrors ? null : error$1, state); + if (stat.isDirectory() && isRecursive(path, resolvedPath, state)) return queue.dequeue(null, state); + callback$1(stat, resolvedPath); + queue.dequeue(null, state); + }); + }); +}; +const resolveSymlinks = function(path, state, callback$1) { + const { queue, fs, options: { suppressErrors } } = state; + queue.enqueue(); + try { + const resolvedPath = fs.realpathSync(path); + const stat = fs.statSync(resolvedPath); + if (stat.isDirectory() && isRecursive(path, resolvedPath, state)) return; + callback$1(stat, resolvedPath); + } catch (e) { + if (!suppressErrors) throw e; + } +}; +function build$2(options, isSynchronous) { + if (!options.resolveSymlinks || options.excludeSymlinks) return null; + return isSynchronous ? resolveSymlinks : resolveSymlinksAsync; +} +function isRecursive(path, resolved, state) { + if (state.options.useRealPaths) return isRecursiveUsingRealPaths(resolved, state); + let parent = dirname(path); + let depth = 1; + while (parent !== state.root && depth < 2) { + const resolvedPath = state.symlinks.get(parent); + const isSameRoot = !!resolvedPath && (resolvedPath === resolved || resolvedPath.startsWith(resolved) || resolved.startsWith(resolvedPath)); + if (isSameRoot) depth++; + else parent = dirname(parent); + } + state.symlinks.set(path, resolved); + return depth > 1; +} +function isRecursiveUsingRealPaths(resolved, state) { + return state.visited.includes(resolved + state.options.pathSeparator); +} + +//#endregion +//#region src/api/functions/invoke-callback.ts +const onlyCountsSync = (state) => { + return state.counts; +}; +const groupsSync = (state) => { + return state.groups; +}; +const defaultSync = (state) => { + return state.paths; +}; +const limitFilesSync = (state) => { + return state.paths.slice(0, state.options.maxFiles); +}; +const onlyCountsAsync = (state, error, callback$1) => { + report(error, callback$1, state.counts, state.options.suppressErrors); + return null; +}; +const defaultAsync = (state, error, callback$1) => { + report(error, callback$1, state.paths, state.options.suppressErrors); + return null; +}; +const limitFilesAsync = (state, error, callback$1) => { + report(error, callback$1, state.paths.slice(0, state.options.maxFiles), state.options.suppressErrors); + return null; +}; +const groupsAsync = (state, error, callback$1) => { + report(error, callback$1, state.groups, state.options.suppressErrors); + return null; +}; +function report(error, callback$1, output, suppressErrors) { + if (error && !suppressErrors) callback$1(error, output); + else callback$1(null, output); +} +function build$1(options, isSynchronous) { + const { onlyCounts, group, maxFiles } = options; + if (onlyCounts) return isSynchronous ? onlyCountsSync : onlyCountsAsync; + else if (group) return isSynchronous ? groupsSync : groupsAsync; + else if (maxFiles) return isSynchronous ? limitFilesSync : limitFilesAsync; + else return isSynchronous ? defaultSync : defaultAsync; +} + +//#endregion +//#region src/api/functions/walk-directory.ts +const readdirOpts = { withFileTypes: true }; +const walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => { + state.queue.enqueue(); + if (currentDepth < 0) return state.queue.dequeue(null, state); + const { fs } = state; + state.visited.push(crawlPath); + state.counts.directories++; + fs.readdir(crawlPath || ".", readdirOpts, (error, entries = []) => { + callback$1(entries, directoryPath, currentDepth); + state.queue.dequeue(state.options.suppressErrors ? null : error, state); + }); +}; +const walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => { + const { fs } = state; + if (currentDepth < 0) return; + state.visited.push(crawlPath); + state.counts.directories++; + let entries = []; + try { + entries = fs.readdirSync(crawlPath || ".", readdirOpts); + } catch (e) { + if (!state.options.suppressErrors) throw e; + } + callback$1(entries, directoryPath, currentDepth); +}; +function build(isSynchronous) { + return isSynchronous ? walkSync : walkAsync; +} + +//#endregion +//#region src/api/queue.ts +/** +* This is a custom stateless queue to track concurrent async fs calls. +* It increments a counter whenever a call is queued and decrements it +* as soon as it completes. When the counter hits 0, it calls onQueueEmpty. +*/ +var Queue = class { + count = 0; + constructor(onQueueEmpty) { + this.onQueueEmpty = onQueueEmpty; + } + enqueue() { + this.count++; + return this.count; + } + dequeue(error, output) { + if (this.onQueueEmpty && (--this.count <= 0 || error)) { + this.onQueueEmpty(error, output); + if (error) { + output.controller.abort(); + this.onQueueEmpty = void 0; + } + } + } +}; + +//#endregion +//#region src/api/counter.ts +var Counter = class { + _files = 0; + _directories = 0; + set files(num) { + this._files = num; + } + get files() { + return this._files; + } + set directories(num) { + this._directories = num; + } + get directories() { + return this._directories; + } + /** + * @deprecated use `directories` instead + */ + /* c8 ignore next 3 */ + get dirs() { + return this._directories; + } +}; + +//#endregion +//#region src/api/aborter.ts +/** +* AbortController is not supported on Node 14 so we use this until we can drop +* support for Node 14. +*/ +var Aborter = class { + aborted = false; + abort() { + this.aborted = true; + } +}; + +//#endregion +//#region src/api/walker.ts +var Walker = class { + root; + isSynchronous; + state; + joinPath; + pushDirectory; + pushFile; + getArray; + groupFiles; + resolveSymlink; + walkDirectory; + callbackInvoker; + constructor(root, options, callback$1) { + this.isSynchronous = !callback$1; + this.callbackInvoker = build$1(options, this.isSynchronous); + this.root = normalizePath(root, options); + this.state = { + root: isRootDirectory(this.root) ? this.root : this.root.slice(0, -1), + paths: [""].slice(0, 0), + groups: [], + counts: new Counter(), + options, + queue: new Queue((error, state) => this.callbackInvoker(state, error, callback$1)), + symlinks: /* @__PURE__ */ new Map(), + visited: [""].slice(0, 0), + controller: new Aborter(), + fs: options.fs || nativeFs + }; + this.joinPath = build$7(this.root, options); + this.pushDirectory = build$6(this.root, options); + this.pushFile = build$5(options); + this.getArray = build$4(options); + this.groupFiles = build$3(options); + this.resolveSymlink = build$2(options, this.isSynchronous); + this.walkDirectory = build(this.isSynchronous); + } + start() { + this.pushDirectory(this.root, this.state.paths, this.state.options.filters); + this.walkDirectory(this.state, this.root, this.root, this.state.options.maxDepth, this.walk); + return this.isSynchronous ? this.callbackInvoker(this.state, null) : null; + } + walk = (entries, directoryPath, depth) => { + const { paths, options: { filters, resolveSymlinks: resolveSymlinks$1, excludeSymlinks, exclude, maxFiles, signal, useRealPaths, pathSeparator }, controller } = this.state; + if (controller.aborted || signal && signal.aborted || maxFiles && paths.length > maxFiles) return; + const files = this.getArray(this.state.paths); + for (let i = 0; i < entries.length; ++i) { + const entry = entries[i]; + if (entry.isFile() || entry.isSymbolicLink() && !resolveSymlinks$1 && !excludeSymlinks) { + const filename = this.joinPath(entry.name, directoryPath); + this.pushFile(filename, files, this.state.counts, filters); + } else if (entry.isDirectory()) { + let path = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator); + if (exclude && exclude(entry.name, path)) continue; + this.pushDirectory(path, paths, filters); + this.walkDirectory(this.state, path, path, depth - 1, this.walk); + } else if (this.resolveSymlink && entry.isSymbolicLink()) { + let path = joinPathWithBasePath(entry.name, directoryPath); + this.resolveSymlink(path, this.state, (stat, resolvedPath) => { + if (stat.isDirectory()) { + resolvedPath = normalizePath(resolvedPath, this.state.options); + if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path + pathSeparator)) return; + this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path + pathSeparator, depth - 1, this.walk); + } else { + resolvedPath = useRealPaths ? resolvedPath : path; + const filename = basename(resolvedPath); + const directoryPath$1 = normalizePath(dirname(resolvedPath), this.state.options); + resolvedPath = this.joinPath(filename, directoryPath$1); + this.pushFile(resolvedPath, files, this.state.counts, filters); + } + }); + } + } + this.groupFiles(this.state.groups, directoryPath, files); + }; +}; + +//#endregion +//#region src/api/async.ts +function promise(root, options) { + return new Promise((resolve$1, reject) => { + callback(root, options, (err, output) => { + if (err) return reject(err); + resolve$1(output); + }); + }); +} +function callback(root, options, callback$1) { + let walker = new Walker(root, options, callback$1); + walker.start(); +} + +//#endregion +//#region src/api/sync.ts +function sync(root, options) { + const walker = new Walker(root, options); + return walker.start(); +} + +//#endregion +//#region src/builder/api-builder.ts +var APIBuilder = class { + constructor(root, options) { + this.root = root; + this.options = options; + } + withPromise() { + return promise(this.root, this.options); + } + withCallback(cb) { + callback(this.root, this.options, cb); + } + sync() { + return sync(this.root, this.options); + } +}; + +//#endregion +//#region src/builder/index.ts +let pm = null; +/* c8 ignore next 6 */ +try { + __require.resolve("picomatch"); + pm = __require("picomatch"); +} catch {} +var Builder = class { + globCache = {}; + options = { + maxDepth: Infinity, + suppressErrors: true, + pathSeparator: sep, + filters: [] + }; + globFunction; + constructor(options) { + this.options = { + ...this.options, + ...options + }; + this.globFunction = this.options.globFunction; + } + group() { + this.options.group = true; + return this; + } + withPathSeparator(separator) { + this.options.pathSeparator = separator; + return this; + } + withBasePath() { + this.options.includeBasePath = true; + return this; + } + withRelativePaths() { + this.options.relativePaths = true; + return this; + } + withDirs() { + this.options.includeDirs = true; + return this; + } + withMaxDepth(depth) { + this.options.maxDepth = depth; + return this; + } + withMaxFiles(limit) { + this.options.maxFiles = limit; + return this; + } + withFullPaths() { + this.options.resolvePaths = true; + this.options.includeBasePath = true; + return this; + } + withErrors() { + this.options.suppressErrors = false; + return this; + } + withSymlinks({ resolvePaths = true } = {}) { + this.options.resolveSymlinks = true; + this.options.useRealPaths = resolvePaths; + return this.withFullPaths(); + } + withAbortSignal(signal) { + this.options.signal = signal; + return this; + } + normalize() { + this.options.normalizePath = true; + return this; + } + filter(predicate) { + this.options.filters.push(predicate); + return this; + } + onlyDirs() { + this.options.excludeFiles = true; + this.options.includeDirs = true; + return this; + } + exclude(predicate) { + this.options.exclude = predicate; + return this; + } + onlyCounts() { + this.options.onlyCounts = true; + return this; + } + crawl(root) { + return new APIBuilder(root || ".", this.options); + } + withGlobFunction(fn) { + this.globFunction = fn; + return this; + } + /** + * @deprecated Pass options using the constructor instead: + * ```ts + * new fdir(options).crawl("/path/to/root"); + * ``` + * This method will be removed in v7.0 + */ + /* c8 ignore next 4 */ + crawlWithOptions(root, options) { + this.options = { + ...this.options, + ...options + }; + return new APIBuilder(root || ".", this.options); + } + glob(...patterns) { + if (this.globFunction) return this.globWithOptions(patterns); + return this.globWithOptions(patterns, ...[{ dot: true }]); + } + globWithOptions(patterns, ...options) { + const globFn = this.globFunction || pm; + /* c8 ignore next 5 */ + if (!globFn) throw new Error("Please specify a glob function to use glob matching."); + var isMatch = this.globCache[patterns.join("\0")]; + if (!isMatch) { + isMatch = globFn(patterns, ...options); + this.globCache[patterns.join("\0")] = isMatch; + } + this.options.filters.push((path) => isMatch(path)); + return this; + } +}; + +//#endregion +export { Builder as fdir }; \ No newline at end of file diff --git a/node_modules/fdir/package.json b/node_modules/fdir/package.json new file mode 100644 index 0000000000..e229dff815 --- /dev/null +++ b/node_modules/fdir/package.json @@ -0,0 +1,103 @@ +{ + "name": "fdir", + "version": "6.5.0", + "description": "The fastest directory crawler & globbing alternative to glob, fast-glob, & tiny-glob. Crawls 1m files in < 1s", + "main": "./dist/index.cjs", + "types": "./dist/index.d.cts", + "type": "module", + "scripts": { + "prepublishOnly": "npm run test && npm run build", + "build": "tsdown", + "format": "prettier --write src __tests__ benchmarks", + "test": "vitest run __tests__/", + "test:coverage": "vitest run --coverage __tests__/", + "test:watch": "vitest __tests__/", + "bench": "ts-node benchmarks/benchmark.js", + "bench:glob": "ts-node benchmarks/glob-benchmark.ts", + "bench:fdir": "ts-node benchmarks/fdir-benchmark.ts", + "release": "./scripts/release.sh" + }, + "engines": { + "node": ">=12.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/thecodrr/fdir.git" + }, + "keywords": [ + "util", + "os", + "sys", + "fs", + "walk", + "crawler", + "directory", + "files", + "io", + "tiny-glob", + "glob", + "fast-glob", + "speed", + "javascript", + "nodejs" + ], + "author": "thecodrr ", + "license": "MIT", + "bugs": { + "url": "https://github.com/thecodrr/fdir/issues" + }, + "homepage": "https://github.com/thecodrr/fdir#readme", + "devDependencies": { + "@types/glob": "^8.1.0", + "@types/mock-fs": "^4.13.4", + "@types/node": "^20.9.4", + "@types/picomatch": "^4.0.0", + "@types/tap": "^15.0.11", + "@vitest/coverage-v8": "^0.34.6", + "all-files-in-tree": "^1.1.2", + "benny": "^3.7.1", + "csv-to-markdown-table": "^1.3.1", + "expect": "^29.7.0", + "fast-glob": "^3.3.2", + "fdir1": "npm:fdir@1.2.0", + "fdir2": "npm:fdir@2.1.0", + "fdir3": "npm:fdir@3.4.2", + "fdir4": "npm:fdir@4.1.0", + "fdir5": "npm:fdir@5.0.0", + "fs-readdir-recursive": "^1.1.0", + "get-all-files": "^4.1.0", + "glob": "^10.3.10", + "klaw-sync": "^6.0.0", + "mock-fs": "^5.2.0", + "picomatch": "^4.0.2", + "prettier": "^3.5.3", + "recur-readdir": "0.0.1", + "recursive-files": "^1.0.2", + "recursive-fs": "^2.1.0", + "recursive-readdir": "^2.2.3", + "rrdir": "^12.1.0", + "systeminformation": "^5.21.17", + "tiny-glob": "^0.2.9", + "ts-node": "^10.9.1", + "tsdown": "^0.12.5", + "typescript": "^5.3.2", + "vitest": "^0.34.6", + "walk-sync": "^3.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + }, + "module": "./dist/index.mjs", + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + }, + "./package.json": "./package.json" + } +} diff --git a/node_modules/js-tokens/LICENSE b/node_modules/js-tokens/LICENSE new file mode 100644 index 0000000000..f07e1ac1eb --- /dev/null +++ b/node_modules/js-tokens/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Simon Lydell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/js-tokens/README.md b/node_modules/js-tokens/README.md new file mode 100644 index 0000000000..ee52150ef8 --- /dev/null +++ b/node_modules/js-tokens/README.md @@ -0,0 +1,14 @@ +# js-tokens + +The tiny, regex powered, lenient, _almost_ spec-compliant JavaScript tokenizer that never fails. + +```js +const jsTokens = require("js-tokens"); + +const jsString = 'JSON.stringify({k:3.14**2}, null /*replacer*/, "\\t")'; + +Array.from(jsTokens(jsString), (token) => token.value).join("|"); +// JSON|.|stringify|(|{|k|:|3.14|**|2|}|,| |null| |/*replacer*/|,| |"\t"|) +``` + +**[➡️ Full readme](https://github.com/lydell/js-tokens/)** \ No newline at end of file diff --git a/node_modules/js-tokens/index.d.ts b/node_modules/js-tokens/index.d.ts new file mode 100644 index 0000000000..d67cac0883 --- /dev/null +++ b/node_modules/js-tokens/index.d.ts @@ -0,0 +1,37 @@ +export declare type Token = + | { type: "StringLiteral"; value: string; closed: boolean } + | { type: "NoSubstitutionTemplate"; value: string; closed: boolean } + | { type: "TemplateHead"; value: string } + | { type: "TemplateMiddle"; value: string } + | { type: "TemplateTail"; value: string; closed: boolean } + | { type: "RegularExpressionLiteral"; value: string; closed: boolean } + | { type: "MultiLineComment"; value: string; closed: boolean } + | { type: "SingleLineComment"; value: string } + | { type: "HashbangComment"; value: string } + | { type: "IdentifierName"; value: string } + | { type: "PrivateIdentifier"; value: string } + | { type: "NumericLiteral"; value: string } + | { type: "Punctuator"; value: string } + | { type: "WhiteSpace"; value: string } + | { type: "LineTerminatorSequence"; value: string } + | { type: "Invalid"; value: string }; + +export declare type JSXToken = + | { type: "JSXString"; value: string; closed: boolean } + | { type: "JSXText"; value: string } + | { type: "JSXIdentifier"; value: string } + | { type: "JSXPunctuator"; value: string } + | { type: "JSXInvalid"; value: string }; + +declare function jsTokens( + input: string, + options: { jsx: true }, +): Iterable; + +declare function jsTokens( + input: string, + options?: { jsx?: boolean }, +): Iterable; + +// @ts-expect-error TypeScript complains about _both_ exporting types _and_ using `export =` but it seems to work fine in practice. +export = jsTokens; diff --git a/node_modules/js-tokens/index.js b/node_modules/js-tokens/index.js new file mode 100644 index 0000000000..1afeff97ef --- /dev/null +++ b/node_modules/js-tokens/index.js @@ -0,0 +1,396 @@ +// Copyright 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Simon Lydell +// License: MIT. +var HashbangComment, Identifier, JSXIdentifier, JSXPunctuator, JSXString, JSXText, KeywordsWithExpressionAfter, KeywordsWithNoLineTerminatorAfter, LineTerminatorSequence, MultiLineComment, Newline, NumericLiteral, Punctuator, RegularExpressionLiteral, SingleLineComment, StringLiteral, Template, TokensNotPrecedingObjectLiteral, TokensPrecedingExpression, WhiteSpace, jsTokens; +RegularExpressionLiteral = /\/(?![*\/])(?:\[(?:[^\]\\\n\r\u2028\u2029]+|\\.)*\]?|[^\/[\\\n\r\u2028\u2029]+|\\.)*(\/[$_\u200C\u200D\p{ID_Continue}]*|\\)?/yu; +Punctuator = /--|\+\+|=>|\.{3}|\??\.(?!\d)|(?:&&|\|\||\?\?|[+\-%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2}|\/(?![\/*]))=?|[?~,:;[\](){}]/y; +Identifier = /(\x23?)(?=[$_\p{ID_Start}\\])(?:[$_\u200C\u200D\p{ID_Continue}]+|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+/yu; +StringLiteral = /(['"])(?:[^'"\\\n\r]+|(?!\1)['"]|\\(?:\r\n|[^]))*(\1)?/y; +NumericLiteral = /(?:0[xX][\da-fA-F](?:_?[\da-fA-F])*|0[oO][0-7](?:_?[0-7])*|0[bB][01](?:_?[01])*)n?|0n|[1-9](?:_?\d)*n|(?:(?:0(?!\d)|0\d*[89]\d*|[1-9](?:_?\d)*)(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?|0[0-7]+/y; +Template = /[`}](?:[^`\\$]+|\\[^]|\$(?!\{))*(`|\$\{)?/y; +WhiteSpace = /[\t\v\f\ufeff\p{Zs}]+/yu; +LineTerminatorSequence = /\r?\n|[\r\u2028\u2029]/y; +MultiLineComment = /\/\*(?:[^*]+|\*(?!\/))*(\*\/)?/y; +SingleLineComment = /\/\/.*/y; +HashbangComment = /^#!.*/; +JSXPunctuator = /[<>.:={}]|\/(?![\/*])/y; +JSXIdentifier = /[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}-]*/yu; +JSXString = /(['"])(?:[^'"]+|(?!\1)['"])*(\1)?/y; +JSXText = /[^<>{}]+/y; +TokensPrecedingExpression = /^(?:[\/+-]|\.{3}|\?(?:InterpolationIn(?:JSX|Template)|NoLineTerminatorHere|NonExpressionParenEnd|UnaryIncDec))?$|[{}([,;<>=*%&|^!~?:]$/; +TokensNotPrecedingObjectLiteral = /^(?:=>|[;\]){}]|else|\?(?:NoLineTerminatorHere|NonExpressionParenEnd))?$/; +KeywordsWithExpressionAfter = /^(?:await|case|default|delete|do|else|instanceof|new|return|throw|typeof|void|yield)$/; +KeywordsWithNoLineTerminatorAfter = /^(?:return|throw|yield)$/; +Newline = RegExp(LineTerminatorSequence.source); +module.exports = jsTokens = function*(input, {jsx = false} = {}) { + var braces, firstCodePoint, isExpression, lastIndex, lastSignificantToken, length, match, mode, nextLastIndex, nextLastSignificantToken, parenNesting, postfixIncDec, punctuator, stack; + ({length} = input); + lastIndex = 0; + lastSignificantToken = ""; + stack = [ + {tag: "JS"} + ]; + braces = []; + parenNesting = 0; + postfixIncDec = false; + if (match = HashbangComment.exec(input)) { + yield ({ + type: "HashbangComment", + value: match[0] + }); + lastIndex = match[0].length; + } + while (lastIndex < length) { + mode = stack[stack.length - 1]; + switch (mode.tag) { + case "JS": + case "JSNonExpressionParen": + case "InterpolationInTemplate": + case "InterpolationInJSX": + if (input[lastIndex] === "/" && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + RegularExpressionLiteral.lastIndex = lastIndex; + if (match = RegularExpressionLiteral.exec(input)) { + lastIndex = RegularExpressionLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "RegularExpressionLiteral", + value: match[0], + closed: match[1] !== void 0 && match[1] !== "\\" + }); + continue; + } + } + Punctuator.lastIndex = lastIndex; + if (match = Punctuator.exec(input)) { + punctuator = match[0]; + nextLastIndex = Punctuator.lastIndex; + nextLastSignificantToken = punctuator; + switch (punctuator) { + case "(": + if (lastSignificantToken === "?NonExpressionParenKeyword") { + stack.push({ + tag: "JSNonExpressionParen", + nesting: parenNesting + }); + } + parenNesting++; + postfixIncDec = false; + break; + case ")": + parenNesting--; + postfixIncDec = true; + if (mode.tag === "JSNonExpressionParen" && parenNesting === mode.nesting) { + stack.pop(); + nextLastSignificantToken = "?NonExpressionParenEnd"; + postfixIncDec = false; + } + break; + case "{": + Punctuator.lastIndex = 0; + isExpression = !TokensNotPrecedingObjectLiteral.test(lastSignificantToken) && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken)); + braces.push(isExpression); + postfixIncDec = false; + break; + case "}": + switch (mode.tag) { + case "InterpolationInTemplate": + if (braces.length === mode.nesting) { + Template.lastIndex = lastIndex; + match = Template.exec(input); + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + postfixIncDec = false; + yield ({ + type: "TemplateMiddle", + value: match[0] + }); + } else { + stack.pop(); + postfixIncDec = true; + yield ({ + type: "TemplateTail", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "InterpolationInJSX": + if (braces.length === mode.nesting) { + stack.pop(); + lastIndex += 1; + lastSignificantToken = "}"; + yield ({ + type: "JSXPunctuator", + value: "}" + }); + continue; + } + } + postfixIncDec = braces.pop(); + nextLastSignificantToken = postfixIncDec ? "?ExpressionBraceEnd" : "}"; + break; + case "]": + postfixIncDec = true; + break; + case "++": + case "--": + nextLastSignificantToken = postfixIncDec ? "?PostfixIncDec" : "?UnaryIncDec"; + break; + case "<": + if (jsx && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + stack.push({tag: "JSXTag"}); + lastIndex += 1; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: punctuator + }); + continue; + } + postfixIncDec = false; + break; + default: + postfixIncDec = false; + } + lastIndex = nextLastIndex; + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "Punctuator", + value: punctuator + }); + continue; + } + Identifier.lastIndex = lastIndex; + if (match = Identifier.exec(input)) { + lastIndex = Identifier.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "for": + case "if": + case "while": + case "with": + if (lastSignificantToken !== "." && lastSignificantToken !== "?.") { + nextLastSignificantToken = "?NonExpressionParenKeyword"; + } + } + lastSignificantToken = nextLastSignificantToken; + postfixIncDec = !KeywordsWithExpressionAfter.test(match[0]); + yield ({ + type: match[1] === "#" ? "PrivateIdentifier" : "IdentifierName", + value: match[0] + }); + continue; + } + StringLiteral.lastIndex = lastIndex; + if (match = StringLiteral.exec(input)) { + lastIndex = StringLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "StringLiteral", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + NumericLiteral.lastIndex = lastIndex; + if (match = NumericLiteral.exec(input)) { + lastIndex = NumericLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "NumericLiteral", + value: match[0] + }); + continue; + } + Template.lastIndex = lastIndex; + if (match = Template.exec(input)) { + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + stack.push({ + tag: "InterpolationInTemplate", + nesting: braces.length + }); + postfixIncDec = false; + yield ({ + type: "TemplateHead", + value: match[0] + }); + } else { + postfixIncDec = true; + yield ({ + type: "NoSubstitutionTemplate", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "JSXTag": + case "JSXTagEnd": + JSXPunctuator.lastIndex = lastIndex; + if (match = JSXPunctuator.exec(input)) { + lastIndex = JSXPunctuator.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "<": + stack.push({tag: "JSXTag"}); + break; + case ">": + stack.pop(); + if (lastSignificantToken === "/" || mode.tag === "JSXTagEnd") { + nextLastSignificantToken = "?JSX"; + postfixIncDec = true; + } else { + stack.push({tag: "JSXChildren"}); + } + break; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + nextLastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + break; + case "/": + if (lastSignificantToken === "<") { + stack.pop(); + if (stack[stack.length - 1].tag === "JSXChildren") { + stack.pop(); + } + stack.push({tag: "JSXTagEnd"}); + } + } + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "JSXPunctuator", + value: match[0] + }); + continue; + } + JSXIdentifier.lastIndex = lastIndex; + if (match = JSXIdentifier.exec(input)) { + lastIndex = JSXIdentifier.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXIdentifier", + value: match[0] + }); + continue; + } + JSXString.lastIndex = lastIndex; + if (match = JSXString.exec(input)) { + lastIndex = JSXString.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXString", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + break; + case "JSXChildren": + JSXText.lastIndex = lastIndex; + if (match = JSXText.exec(input)) { + lastIndex = JSXText.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXText", + value: match[0] + }); + continue; + } + switch (input[lastIndex]) { + case "<": + stack.push({tag: "JSXTag"}); + lastIndex++; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: "<" + }); + continue; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + lastIndex++; + lastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + yield ({ + type: "JSXPunctuator", + value: "{" + }); + continue; + } + } + WhiteSpace.lastIndex = lastIndex; + if (match = WhiteSpace.exec(input)) { + lastIndex = WhiteSpace.lastIndex; + yield ({ + type: "WhiteSpace", + value: match[0] + }); + continue; + } + LineTerminatorSequence.lastIndex = lastIndex; + if (match = LineTerminatorSequence.exec(input)) { + lastIndex = LineTerminatorSequence.lastIndex; + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + yield ({ + type: "LineTerminatorSequence", + value: match[0] + }); + continue; + } + MultiLineComment.lastIndex = lastIndex; + if (match = MultiLineComment.exec(input)) { + lastIndex = MultiLineComment.lastIndex; + if (Newline.test(match[0])) { + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + } + yield ({ + type: "MultiLineComment", + value: match[0], + closed: match[1] !== void 0 + }); + continue; + } + SingleLineComment.lastIndex = lastIndex; + if (match = SingleLineComment.exec(input)) { + lastIndex = SingleLineComment.lastIndex; + postfixIncDec = false; + yield ({ + type: "SingleLineComment", + value: match[0] + }); + continue; + } + firstCodePoint = String.fromCodePoint(input.codePointAt(lastIndex)); + lastIndex += firstCodePoint.length; + lastSignificantToken = firstCodePoint; + postfixIncDec = false; + yield ({ + type: mode.tag.startsWith("JSX") ? "JSXInvalid" : "Invalid", + value: firstCodePoint + }); + } + return void 0; +}; diff --git a/node_modules/js-tokens/package.json b/node_modules/js-tokens/package.json new file mode 100644 index 0000000000..b868c1c365 --- /dev/null +++ b/node_modules/js-tokens/package.json @@ -0,0 +1,22 @@ +{ + "name": "js-tokens", + "version": "9.0.1", + "author": "Simon Lydell", + "license": "MIT", + "description": "Tiny JavaScript tokenizer.", + "repository": "lydell/js-tokens", + "type": "commonjs", + "exports": "./index.js", + "keywords": [ + "JavaScript", + "js", + "ECMAScript", + "es", + "token", + "tokens", + "tokenize", + "tokenizer", + "regex", + "regexp" + ] +} diff --git a/node_modules/loupe/LICENSE b/node_modules/loupe/LICENSE new file mode 100644 index 0000000000..b0c8a5aaa4 --- /dev/null +++ b/node_modules/loupe/LICENSE @@ -0,0 +1,9 @@ +(The MIT License) + +Copyright (c) 2011-2013 Jake Luer jake@alogicalparadox.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/loupe/README.md b/node_modules/loupe/README.md new file mode 100644 index 0000000000..44f61d38d9 --- /dev/null +++ b/node_modules/loupe/README.md @@ -0,0 +1,63 @@ +![npm](https://img.shields.io/npm/v/loupe?logo=npm) +![Build](https://github.com/chaijs/loupe/workflows/Build/badge.svg?branch=master) +![Codecov branch](https://img.shields.io/codecov/c/github/chaijs/loupe/master?logo=codecov) + +# What is loupe? + +Loupe turns the object you give it into a string. It's similar to Node.js' `util.inspect()` function, but it works cross platform, in most modern browsers as well as Node. + +## Installation + +### Node.js + +`loupe` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install loupe + +### Browsers + +You can also use it within the browser; install via npm and use the `loupe.js` file found within the download. For example: + +```html + +``` + +## Usage + +``` js +const { inspect } = require('loupe'); +``` + +```js +inspect({ foo: 'bar' }); // => "{ foo: 'bar' }" +inspect(1); // => '1' +inspect('foo'); // => "'foo'" +inspect([ 1, 2, 3 ]); // => '[ 1, 2, 3 ]' +inspect(/Test/g); // => '/Test/g' + +// ... +``` + +## Tests + +```bash +$ npm test +``` + +Coverage: + +```bash +$ npm run upload-coverage +``` + +## License + +(The MIT License) + +Copyright (c) 2011-2013 Jake Luer jake@alogicalparadox.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/loupe/lib/arguments.d.ts b/node_modules/loupe/lib/arguments.d.ts new file mode 100644 index 0000000000..fb0b814b7a --- /dev/null +++ b/node_modules/loupe/lib/arguments.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectArguments(args: IArguments, options: Options): string; +//# sourceMappingURL=arguments.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/arguments.d.ts.map b/node_modules/loupe/lib/arguments.d.ts.map new file mode 100644 index 0000000000..15c46687a2 --- /dev/null +++ b/node_modules/loupe/lib/arguments.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"arguments.d.ts","sourceRoot":"","sources":["../src/arguments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAInF"} \ No newline at end of file diff --git a/node_modules/loupe/lib/arguments.js b/node_modules/loupe/lib/arguments.js new file mode 100644 index 0000000000..b5df404d15 --- /dev/null +++ b/node_modules/loupe/lib/arguments.js @@ -0,0 +1,7 @@ +import { inspectList } from './helpers.js'; +export default function inspectArguments(args, options) { + if (args.length === 0) + return 'Arguments[]'; + options.truncate -= 13; + return `Arguments[ ${inspectList(args, options)} ]`; +} diff --git a/node_modules/loupe/lib/array.d.ts b/node_modules/loupe/lib/array.d.ts new file mode 100644 index 0000000000..7b4043ed46 --- /dev/null +++ b/node_modules/loupe/lib/array.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectArray(array: ArrayLike, options: Options): string; +//# sourceMappingURL=array.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/array.d.ts.map b/node_modules/loupe/lib/array.d.ts.map new file mode 100644 index 0000000000..dfd4d499a1 --- /dev/null +++ b/node_modules/loupe/lib/array.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../src/array.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,YAAY,CAAA;AAElD,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,UAiB/E"} \ No newline at end of file diff --git a/node_modules/loupe/lib/array.js b/node_modules/loupe/lib/array.js new file mode 100644 index 0000000000..78f6c9631a --- /dev/null +++ b/node_modules/loupe/lib/array.js @@ -0,0 +1,16 @@ +import { inspectList, inspectProperty } from './helpers.js'; +export default function inspectArray(array, options) { + // Object.keys will always output the Array indices first, so we can slice by + // `array.length` to get non-index properties + const nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) + return '[]'; + options.truncate -= 4; + const listContents = inspectList(array, options); + options.truncate -= listContents.length; + let propertyContents = ''; + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map(key => [key, array[key]]), options, inspectProperty); + } + return `[ ${listContents}${propertyContents ? `, ${propertyContents}` : ''} ]`; +} diff --git a/node_modules/loupe/lib/bigint.d.ts b/node_modules/loupe/lib/bigint.d.ts new file mode 100644 index 0000000000..ad1d630378 --- /dev/null +++ b/node_modules/loupe/lib/bigint.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectBigInt(number: bigint, options: Options): string; +//# sourceMappingURL=bigint.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/bigint.d.ts.map b/node_modules/loupe/lib/bigint.d.ts.map new file mode 100644 index 0000000000..2af38e7db4 --- /dev/null +++ b/node_modules/loupe/lib/bigint.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"bigint.d.ts","sourceRoot":"","sources":["../src/bigint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,UAIrE"} \ No newline at end of file diff --git a/node_modules/loupe/lib/bigint.js b/node_modules/loupe/lib/bigint.js new file mode 100644 index 0000000000..808ab0ff00 --- /dev/null +++ b/node_modules/loupe/lib/bigint.js @@ -0,0 +1,7 @@ +import { truncate, truncator } from './helpers.js'; +export default function inspectBigInt(number, options) { + let nums = truncate(number.toString(), options.truncate - 1); + if (nums !== truncator) + nums += 'n'; + return options.stylize(nums, 'bigint'); +} diff --git a/node_modules/loupe/lib/class.d.ts b/node_modules/loupe/lib/class.d.ts new file mode 100644 index 0000000000..affd642478 --- /dev/null +++ b/node_modules/loupe/lib/class.d.ts @@ -0,0 +1,5 @@ +import type { Options } from './types.js'; +export default function inspectClass(value: { + new (...args: any[]): unknown; +}, options: Options): string; +//# sourceMappingURL=class.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/class.d.ts.map b/node_modules/loupe/lib/class.d.ts.map new file mode 100644 index 0000000000..a1324cc33a --- /dev/null +++ b/node_modules/loupe/lib/class.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"class.d.ts","sourceRoot":"","sources":["../src/class.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAIzC,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,KAAK,EAAE;IAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAA;CAAE,EAAE,OAAO,EAAE,OAAO,UAY9F"} \ No newline at end of file diff --git a/node_modules/loupe/lib/class.js b/node_modules/loupe/lib/class.js new file mode 100644 index 0000000000..a5f9332b41 --- /dev/null +++ b/node_modules/loupe/lib/class.js @@ -0,0 +1,15 @@ +import inspectObject from './object.js'; +const toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag ? Symbol.toStringTag : false; +export default function inspectClass(value, options) { + let name = ''; + if (toStringTag && toStringTag in value) { + name = value[toStringTag]; + } + name = name || value.constructor.name; + // Babel transforms anonymous classes to the name `_class` + if (!name || name === '_class') { + name = ''; + } + options.truncate -= name.length; + return `${name}${inspectObject(value, options)}`; +} diff --git a/node_modules/loupe/lib/date.d.ts b/node_modules/loupe/lib/date.d.ts new file mode 100644 index 0000000000..cdc51b7a1c --- /dev/null +++ b/node_modules/loupe/lib/date.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectDate(dateObject: Date, options: Options): string; +//# sourceMappingURL=date.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/date.d.ts.map b/node_modules/loupe/lib/date.d.ts.map new file mode 100644 index 0000000000..a551da7fc3 --- /dev/null +++ b/node_modules/loupe/lib/date.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../src/date.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,UAWrE"} \ No newline at end of file diff --git a/node_modules/loupe/lib/date.js b/node_modules/loupe/lib/date.js new file mode 100644 index 0000000000..09a645aae1 --- /dev/null +++ b/node_modules/loupe/lib/date.js @@ -0,0 +1,11 @@ +import { truncate } from './helpers.js'; +export default function inspectDate(dateObject, options) { + const stringRepresentation = dateObject.toJSON(); + if (stringRepresentation === null) { + return 'Invalid Date'; + } + const split = stringRepresentation.split('T'); + const date = split[0]; + // If we need to - truncate the time portion, but never the date + return options.stylize(`${date}T${truncate(split[1], options.truncate - date.length - 1)}`, 'date'); +} diff --git a/node_modules/loupe/lib/error.d.ts b/node_modules/loupe/lib/error.d.ts new file mode 100644 index 0000000000..adb2a0d10b --- /dev/null +++ b/node_modules/loupe/lib/error.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectObject(error: Error, options: Options): string; +//# sourceMappingURL=error.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/error.d.ts.map b/node_modules/loupe/lib/error.d.ts.map new file mode 100644 index 0000000000..90a35db1c6 --- /dev/null +++ b/node_modules/loupe/lib/error.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,YAAY,CAAA;AAgBlD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,UAuBnE"} \ No newline at end of file diff --git a/node_modules/loupe/lib/error.js b/node_modules/loupe/lib/error.js new file mode 100644 index 0000000000..ab8f996b54 --- /dev/null +++ b/node_modules/loupe/lib/error.js @@ -0,0 +1,35 @@ +import { inspectList, inspectProperty, truncate } from './helpers.js'; +const errorKeys = [ + 'stack', + 'line', + 'column', + 'name', + 'message', + 'fileName', + 'lineNumber', + 'columnNumber', + 'number', + 'description', + 'cause', +]; +export default function inspectObject(error, options) { + const properties = Object.getOwnPropertyNames(error).filter(key => errorKeys.indexOf(key) === -1); + const name = error.name; + options.truncate -= name.length; + let message = ''; + if (typeof error.message === 'string') { + message = truncate(error.message, options.truncate); + } + else { + properties.unshift('message'); + } + message = message ? `: ${message}` : ''; + options.truncate -= message.length + 5; + options.seen = options.seen || []; + if (options.seen.includes(error)) { + return '[Circular]'; + } + options.seen.push(error); + const propertyContents = inspectList(properties.map(key => [key, error[key]]), options, inspectProperty); + return `${name}${message}${propertyContents ? ` { ${propertyContents} }` : ''}`; +} diff --git a/node_modules/loupe/lib/function.d.ts b/node_modules/loupe/lib/function.d.ts new file mode 100644 index 0000000000..98458696c5 --- /dev/null +++ b/node_modules/loupe/lib/function.d.ts @@ -0,0 +1,7 @@ +import type { Options } from './types.js'; +type ToStringable = Function & { + [Symbol.toStringTag]: string; +}; +export default function inspectFunction(func: ToStringable, options: Options): string; +export {}; +//# sourceMappingURL=function.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/function.d.ts.map b/node_modules/loupe/lib/function.d.ts.map new file mode 100644 index 0000000000..ccc44e2ad7 --- /dev/null +++ b/node_modules/loupe/lib/function.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../src/function.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,KAAK,YAAY,GAAG,QAAQ,GAAG;IAAC,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC;AAE9D,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,UAQ3E"} \ No newline at end of file diff --git a/node_modules/loupe/lib/function.js b/node_modules/loupe/lib/function.js new file mode 100644 index 0000000000..4459d5b108 --- /dev/null +++ b/node_modules/loupe/lib/function.js @@ -0,0 +1,9 @@ +import { truncate } from './helpers.js'; +export default function inspectFunction(func, options) { + const functionType = func[Symbol.toStringTag] || 'Function'; + const name = func.name; + if (!name) { + return options.stylize(`[${functionType}]`, 'special'); + } + return options.stylize(`[${functionType} ${truncate(name, options.truncate - 11)}]`, 'special'); +} diff --git a/node_modules/loupe/lib/helpers.d.ts b/node_modules/loupe/lib/helpers.d.ts new file mode 100644 index 0000000000..ae1b8dd3b5 --- /dev/null +++ b/node_modules/loupe/lib/helpers.d.ts @@ -0,0 +1,7 @@ +import type { Inspect, Options } from './types.js'; +export declare const truncator = "\u2026"; +export declare function normaliseOptions({ showHidden, depth, colors, customInspect, showProxy, maxArrayLength, breakLength, seen, truncate, stylize, }: Partial | undefined, inspect: Inspect): Options; +export declare function truncate(string: string | number, length: number, tail?: typeof truncator): string; +export declare function inspectList(list: ArrayLike, options: Options, inspectItem?: Inspect, separator?: string): string; +export declare function inspectProperty([key, value]: [unknown, unknown], options: Options): string; +//# sourceMappingURL=helpers.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/helpers.d.ts.map b/node_modules/loupe/lib/helpers.d.ts.map new file mode 100644 index 0000000000..18c13c9475 --- /dev/null +++ b/node_modules/loupe/lib/helpers.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AA+ClD,eAAO,MAAM,SAAS,WAAM,CAAA;AAa5B,wBAAgB,gBAAgB,CAC9B,EACE,UAAkB,EAClB,KAAS,EACT,MAAc,EACd,aAAoB,EACpB,SAAiB,EACjB,cAAyB,EACzB,WAAsB,EACtB,IAAS,EAET,QAAmB,EACnB,OAAgB,GACjB,EAAE,OAAO,CAAC,OAAO,CAAC,YAAK,EACxB,OAAO,EAAE,OAAO,GACf,OAAO,CAkBT;AAMD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,OAAO,SAAqB,UAenG;AAGD,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,EACxB,OAAO,EAAE,OAAO,EAChB,WAAW,CAAC,EAAE,OAAO,EACrB,SAAS,SAAO,GACf,MAAM,CAsDR;AAYD,wBAAgB,eAAe,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAU1F"} \ No newline at end of file diff --git a/node_modules/loupe/lib/helpers.js b/node_modules/loupe/lib/helpers.js new file mode 100644 index 0000000000..0ca92ba876 --- /dev/null +++ b/node_modules/loupe/lib/helpers.js @@ -0,0 +1,159 @@ +const ansiColors = { + bold: ['1', '22'], + dim: ['2', '22'], + italic: ['3', '23'], + underline: ['4', '24'], + // 5 & 6 are blinking + inverse: ['7', '27'], + hidden: ['8', '28'], + strike: ['9', '29'], + // 10-20 are fonts + // 21-29 are resets for 1-9 + black: ['30', '39'], + red: ['31', '39'], + green: ['32', '39'], + yellow: ['33', '39'], + blue: ['34', '39'], + magenta: ['35', '39'], + cyan: ['36', '39'], + white: ['37', '39'], + brightblack: ['30;1', '39'], + brightred: ['31;1', '39'], + brightgreen: ['32;1', '39'], + brightyellow: ['33;1', '39'], + brightblue: ['34;1', '39'], + brightmagenta: ['35;1', '39'], + brightcyan: ['36;1', '39'], + brightwhite: ['37;1', '39'], + grey: ['90', '39'], +}; +const styles = { + special: 'cyan', + number: 'yellow', + bigint: 'yellow', + boolean: 'yellow', + undefined: 'grey', + null: 'bold', + string: 'green', + symbol: 'green', + date: 'magenta', + regexp: 'red', +}; +export const truncator = '…'; +function colorise(value, styleType) { + const color = ansiColors[styles[styleType]] || ansiColors[styleType] || ''; + if (!color) { + return String(value); + } + return `\u001b[${color[0]}m${String(value)}\u001b[${color[1]}m`; +} +export function normaliseOptions({ showHidden = false, depth = 2, colors = false, customInspect = true, showProxy = false, maxArrayLength = Infinity, breakLength = Infinity, seen = [], +// eslint-disable-next-line no-shadow +truncate = Infinity, stylize = String, } = {}, inspect) { + const options = { + showHidden: Boolean(showHidden), + depth: Number(depth), + colors: Boolean(colors), + customInspect: Boolean(customInspect), + showProxy: Boolean(showProxy), + maxArrayLength: Number(maxArrayLength), + breakLength: Number(breakLength), + truncate: Number(truncate), + seen, + inspect, + stylize, + }; + if (options.colors) { + options.stylize = colorise; + } + return options; +} +function isHighSurrogate(char) { + return char >= '\ud800' && char <= '\udbff'; +} +export function truncate(string, length, tail = truncator) { + string = String(string); + const tailLength = tail.length; + const stringLength = string.length; + if (tailLength > length && stringLength > tailLength) { + return tail; + } + if (stringLength > length && stringLength > tailLength) { + let end = length - tailLength; + if (end > 0 && isHighSurrogate(string[end - 1])) { + end = end - 1; + } + return `${string.slice(0, end)}${tail}`; + } + return string; +} +// eslint-disable-next-line complexity +export function inspectList(list, options, inspectItem, separator = ', ') { + inspectItem = inspectItem || options.inspect; + const size = list.length; + if (size === 0) + return ''; + const originalLength = options.truncate; + let output = ''; + let peek = ''; + let truncated = ''; + for (let i = 0; i < size; i += 1) { + const last = i + 1 === list.length; + const secondToLast = i + 2 === list.length; + truncated = `${truncator}(${list.length - i})`; + const value = list[i]; + // If there is more than one remaining we need to account for a separator of `, ` + options.truncate = originalLength - output.length - (last ? 0 : separator.length); + const string = peek || inspectItem(value, options) + (last ? '' : separator); + const nextLength = output.length + string.length; + const truncatedLength = nextLength + truncated.length; + // If this is the last element, and adding it would + // take us over length, but adding the truncator wouldn't - then break now + if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) { + break; + } + // If this isn't the last or second to last element to scan, + // but the string is already over length then break here + if (!last && !secondToLast && truncatedLength > originalLength) { + break; + } + // Peek at the next string to determine if we should + // break early before adding this item to the output + peek = last ? '' : inspectItem(list[i + 1], options) + (secondToLast ? '' : separator); + // If we have one element left, but this element and + // the next takes over length, the break early + if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) { + break; + } + output += string; + // If the next element takes us to length - + // but there are more after that, then we should truncate now + if (!last && !secondToLast && nextLength + peek.length >= originalLength) { + truncated = `${truncator}(${list.length - i - 1})`; + break; + } + truncated = ''; + } + return `${output}${truncated}`; +} +function quoteComplexKey(key) { + if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) { + return key; + } + return JSON.stringify(key) + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); +} +export function inspectProperty([key, value], options) { + options.truncate -= 2; + if (typeof key === 'string') { + key = quoteComplexKey(key); + } + else if (typeof key !== 'number') { + key = `[${options.inspect(key, options)}]`; + } + options.truncate -= key.length; + value = options.inspect(value, options); + return `${key}: ${value}`; +} diff --git a/node_modules/loupe/lib/html.d.ts b/node_modules/loupe/lib/html.d.ts new file mode 100644 index 0000000000..7788be3aba --- /dev/null +++ b/node_modules/loupe/lib/html.d.ts @@ -0,0 +1,6 @@ +import type { Options } from './types.js'; +export declare function inspectAttribute([key, value]: [unknown, unknown], options: Options): string; +export declare function inspectNodeCollection(collection: ArrayLike, options: Options): string; +export declare function inspectNode(node: Node, options: Options): string; +export default function inspectHTML(element: Element, options: Options): string; +//# sourceMappingURL=html.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/html.d.ts.map b/node_modules/loupe/lib/html.d.ts.map new file mode 100644 index 0000000000..e6df6e1734 --- /dev/null +++ b/node_modules/loupe/lib/html.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,YAAY,CAAA;AAElD,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,UAMlF;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAE3F;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAShE;AAGD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAwB9E"} \ No newline at end of file diff --git a/node_modules/loupe/lib/html.js b/node_modules/loupe/lib/html.js new file mode 100644 index 0000000000..85b0a62e24 --- /dev/null +++ b/node_modules/loupe/lib/html.js @@ -0,0 +1,42 @@ +import { inspectList, truncator } from './helpers.js'; +export function inspectAttribute([key, value], options) { + options.truncate -= 3; + if (!value) { + return `${options.stylize(String(key), 'yellow')}`; + } + return `${options.stylize(String(key), 'yellow')}=${options.stylize(`"${value}"`, 'string')}`; +} +export function inspectNodeCollection(collection, options) { + return inspectList(collection, options, inspectNode, '\n'); +} +export function inspectNode(node, options) { + switch (node.nodeType) { + case 1: + return inspectHTML(node, options); + case 3: + return options.inspect(node.data, options); + default: + return options.inspect(node, options); + } +} +// @ts-ignore (Deno doesn't have Element) +export default function inspectHTML(element, options) { + const properties = element.getAttributeNames(); + const name = element.tagName.toLowerCase(); + const head = options.stylize(`<${name}`, 'special'); + const headClose = options.stylize(`>`, 'special'); + const tail = options.stylize(``, 'special'); + options.truncate -= name.length * 2 + 5; + let propertyContents = ''; + if (properties.length > 0) { + propertyContents += ' '; + propertyContents += inspectList(properties.map((key) => [key, element.getAttribute(key)]), options, inspectAttribute, ' '); + } + options.truncate -= propertyContents.length; + const truncate = options.truncate; + let children = inspectNodeCollection(element.children, options); + if (children && children.length > truncate) { + children = `${truncator}(${element.children.length})`; + } + return `${head}${propertyContents}${headClose}${children}${tail}`; +} diff --git a/node_modules/loupe/lib/index.d.ts b/node_modules/loupe/lib/index.d.ts new file mode 100644 index 0000000000..bdf2f16c4f --- /dev/null +++ b/node_modules/loupe/lib/index.d.ts @@ -0,0 +1,7 @@ +import type { Inspect, Options } from './types.js'; +export declare function inspect(value: unknown, opts?: Partial): string; +export declare function registerConstructor(constructor: Function, inspector: Inspect): boolean; +export declare function registerStringTag(stringTag: string, inspector: Inspect): boolean; +export declare const custom: string | symbol; +export default inspect; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/index.d.ts.map b/node_modules/loupe/lib/index.d.ts.map new file mode 100644 index 0000000000..f48f33dac6 --- /dev/null +++ b/node_modules/loupe/lib/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AA2FlD,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,OAAO,CAAC,OAAO,CAAM,GAAG,MAAM,CAmD3E;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,WAM5E;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,WAMtE;AAED,eAAO,MAAM,MAAM,iBAAc,CAAA;AAEjC,eAAe,OAAO,CAAA"} \ No newline at end of file diff --git a/node_modules/loupe/lib/index.js b/node_modules/loupe/lib/index.js new file mode 100644 index 0000000000..0259276571 --- /dev/null +++ b/node_modules/loupe/lib/index.js @@ -0,0 +1,152 @@ +/* ! + * loupe + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ +import inspectArray from './array.js'; +import inspectTypedArray from './typedarray.js'; +import inspectDate from './date.js'; +import inspectFunction from './function.js'; +import inspectMap from './map.js'; +import inspectNumber from './number.js'; +import inspectBigInt from './bigint.js'; +import inspectRegExp from './regexp.js'; +import inspectSet from './set.js'; +import inspectString from './string.js'; +import inspectSymbol from './symbol.js'; +import inspectPromise from './promise.js'; +import inspectClass from './class.js'; +import inspectObject from './object.js'; +import inspectArguments from './arguments.js'; +import inspectError from './error.js'; +import inspectHTMLElement, { inspectNodeCollection } from './html.js'; +import { normaliseOptions } from './helpers.js'; +const symbolsSupported = typeof Symbol === 'function' && typeof Symbol.for === 'function'; +const chaiInspect = symbolsSupported ? Symbol.for('chai/inspect') : '@@chai/inspect'; +const nodeInspect = Symbol.for('nodejs.util.inspect.custom'); +const constructorMap = new WeakMap(); +const stringTagMap = {}; +const baseTypesMap = { + undefined: (value, options) => options.stylize('undefined', 'undefined'), + null: (value, options) => options.stylize('null', 'null'), + boolean: (value, options) => options.stylize(String(value), 'boolean'), + Boolean: (value, options) => options.stylize(String(value), 'boolean'), + number: inspectNumber, + Number: inspectNumber, + bigint: inspectBigInt, + BigInt: inspectBigInt, + string: inspectString, + String: inspectString, + function: inspectFunction, + Function: inspectFunction, + symbol: inspectSymbol, + // A Symbol polyfill will return `Symbol` not `symbol` from typedetect + Symbol: inspectSymbol, + Array: inspectArray, + Date: inspectDate, + Map: inspectMap, + Set: inspectSet, + RegExp: inspectRegExp, + Promise: inspectPromise, + // WeakSet, WeakMap are totally opaque to us + WeakSet: (value, options) => options.stylize('WeakSet{…}', 'special'), + WeakMap: (value, options) => options.stylize('WeakMap{…}', 'special'), + Arguments: inspectArguments, + Int8Array: inspectTypedArray, + Uint8Array: inspectTypedArray, + Uint8ClampedArray: inspectTypedArray, + Int16Array: inspectTypedArray, + Uint16Array: inspectTypedArray, + Int32Array: inspectTypedArray, + Uint32Array: inspectTypedArray, + Float32Array: inspectTypedArray, + Float64Array: inspectTypedArray, + Generator: () => '', + DataView: () => '', + ArrayBuffer: () => '', + Error: inspectError, + HTMLCollection: inspectNodeCollection, + NodeList: inspectNodeCollection, +}; +// eslint-disable-next-line complexity +const inspectCustom = (value, options, type, inspectFn) => { + if (chaiInspect in value && typeof value[chaiInspect] === 'function') { + return value[chaiInspect](options); + } + if (nodeInspect in value && typeof value[nodeInspect] === 'function') { + return value[nodeInspect](options.depth, options, inspectFn); + } + if ('inspect' in value && typeof value.inspect === 'function') { + return value.inspect(options.depth, options); + } + if ('constructor' in value && constructorMap.has(value.constructor)) { + return constructorMap.get(value.constructor)(value, options); + } + if (stringTagMap[type]) { + return stringTagMap[type](value, options); + } + return ''; +}; +const toString = Object.prototype.toString; +// eslint-disable-next-line complexity +export function inspect(value, opts = {}) { + const options = normaliseOptions(opts, inspect); + const { customInspect } = options; + let type = value === null ? 'null' : typeof value; + if (type === 'object') { + type = toString.call(value).slice(8, -1); + } + // If it is a base value that we already support, then use Loupe's inspector + if (type in baseTypesMap) { + return baseTypesMap[type](value, options); + } + // If `options.customInspect` is set to true then try to use the custom inspector + if (customInspect && value) { + const output = inspectCustom(value, options, type, inspect); + if (output) { + if (typeof output === 'string') + return output; + return inspect(output, options); + } + } + const proto = value ? Object.getPrototypeOf(value) : false; + // If it's a plain Object then use Loupe's inspector + if (proto === Object.prototype || proto === null) { + return inspectObject(value, options); + } + // Specifically account for HTMLElements + // @ts-ignore + if (value && typeof HTMLElement === 'function' && value instanceof HTMLElement) { + return inspectHTMLElement(value, options); + } + if ('constructor' in value) { + // If it is a class, inspect it like an object but add the constructor name + if (value.constructor !== Object) { + return inspectClass(value, options); + } + // If it is an object with an anonymous prototype, display it as an object. + return inspectObject(value, options); + } + // last chance to check if it's an object + if (value === Object(value)) { + return inspectObject(value, options); + } + // We have run out of options! Just stringify the value + return options.stylize(String(value), type); +} +export function registerConstructor(constructor, inspector) { + if (constructorMap.has(constructor)) { + return false; + } + constructorMap.set(constructor, inspector); + return true; +} +export function registerStringTag(stringTag, inspector) { + if (stringTag in stringTagMap) { + return false; + } + stringTagMap[stringTag] = inspector; + return true; +} +export const custom = chaiInspect; +export default inspect; diff --git a/node_modules/loupe/lib/map.d.ts b/node_modules/loupe/lib/map.d.ts new file mode 100644 index 0000000000..6ed57064ca --- /dev/null +++ b/node_modules/loupe/lib/map.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectMap(map: Map, options: Options): string; +//# sourceMappingURL=map.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/map.d.ts.map b/node_modules/loupe/lib/map.d.ts.map new file mode 100644 index 0000000000..39f453b533 --- /dev/null +++ b/node_modules/loupe/lib/map.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,YAAY,CAAA;AAmBlD,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAIvF"} \ No newline at end of file diff --git a/node_modules/loupe/lib/map.js b/node_modules/loupe/lib/map.js new file mode 100644 index 0000000000..ab60dc0cb8 --- /dev/null +++ b/node_modules/loupe/lib/map.js @@ -0,0 +1,22 @@ +import { inspectList } from './helpers.js'; +function inspectMapEntry([key, value], options) { + options.truncate -= 4; + key = options.inspect(key, options); + options.truncate -= key.length; + value = options.inspect(value, options); + return `${key} => ${value}`; +} +// IE11 doesn't support `map.entries()` +function mapToEntries(map) { + const entries = []; + map.forEach((value, key) => { + entries.push([key, value]); + }); + return entries; +} +export default function inspectMap(map, options) { + if (map.size === 0) + return 'Map{}'; + options.truncate -= 7; + return `Map{ ${inspectList(mapToEntries(map), options, inspectMapEntry)} }`; +} diff --git a/node_modules/loupe/lib/number.d.ts b/node_modules/loupe/lib/number.d.ts new file mode 100644 index 0000000000..231ccceb7c --- /dev/null +++ b/node_modules/loupe/lib/number.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectNumber(number: number, options: Options): string; +//# sourceMappingURL=number.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/number.d.ts.map b/node_modules/loupe/lib/number.d.ts.map new file mode 100644 index 0000000000..31131ddc58 --- /dev/null +++ b/node_modules/loupe/lib/number.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"number.d.ts","sourceRoot":"","sources":["../src/number.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAGzC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAc9E"} \ No newline at end of file diff --git a/node_modules/loupe/lib/number.js b/node_modules/loupe/lib/number.js new file mode 100644 index 0000000000..85442f04e3 --- /dev/null +++ b/node_modules/loupe/lib/number.js @@ -0,0 +1,17 @@ +import { truncate } from './helpers.js'; +const isNaN = Number.isNaN || (i => i !== i); // eslint-disable-line no-self-compare +export default function inspectNumber(number, options) { + if (isNaN(number)) { + return options.stylize('NaN', 'number'); + } + if (number === Infinity) { + return options.stylize('Infinity', 'number'); + } + if (number === -Infinity) { + return options.stylize('-Infinity', 'number'); + } + if (number === 0) { + return options.stylize(1 / number === Infinity ? '+0' : '-0', 'number'); + } + return options.stylize(truncate(String(number), options.truncate), 'number'); +} diff --git a/node_modules/loupe/lib/object.d.ts b/node_modules/loupe/lib/object.d.ts new file mode 100644 index 0000000000..11ac7edcdd --- /dev/null +++ b/node_modules/loupe/lib/object.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectObject(object: object, options: Options): string; +//# sourceMappingURL=object.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/object.d.ts.map b/node_modules/loupe/lib/object.d.ts.map new file mode 100644 index 0000000000..a3cf52f08d --- /dev/null +++ b/node_modules/loupe/lib/object.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,YAAY,CAAA;AAElD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CA4B9E"} \ No newline at end of file diff --git a/node_modules/loupe/lib/object.js b/node_modules/loupe/lib/object.js new file mode 100644 index 0000000000..e39eb45d1d --- /dev/null +++ b/node_modules/loupe/lib/object.js @@ -0,0 +1,22 @@ +import { inspectList, inspectProperty } from './helpers.js'; +export default function inspectObject(object, options) { + const properties = Object.getOwnPropertyNames(object); + const symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : []; + if (properties.length === 0 && symbols.length === 0) { + return '{}'; + } + options.truncate -= 4; + options.seen = options.seen || []; + if (options.seen.includes(object)) { + return '[Circular]'; + } + options.seen.push(object); + const propertyContents = inspectList(properties.map(key => [key, object[key]]), options, inspectProperty); + const symbolContents = inspectList(symbols.map(key => [key, object[key]]), options, inspectProperty); + options.seen.pop(); + let sep = ''; + if (propertyContents && symbolContents) { + sep = ', '; + } + return `{ ${propertyContents}${sep}${symbolContents} }`; +} diff --git a/node_modules/loupe/lib/promise.d.ts b/node_modules/loupe/lib/promise.d.ts new file mode 100644 index 0000000000..3d62fc9052 --- /dev/null +++ b/node_modules/loupe/lib/promise.d.ts @@ -0,0 +1,5 @@ +import type { Options } from './types.js'; +type GetPromiseValue = (value: Promise, options: Options) => string; +declare const getPromiseValue: GetPromiseValue; +export default getPromiseValue; +//# sourceMappingURL=promise.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/promise.d.ts.map b/node_modules/loupe/lib/promise.d.ts.map new file mode 100644 index 0000000000..58baf42729 --- /dev/null +++ b/node_modules/loupe/lib/promise.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,KAAK,eAAe,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,KAAK,MAAM,CAAA;AAC5E,QAAA,MAAM,eAAe,EAAE,eAAoC,CAAA;AAC3D,eAAe,eAAe,CAAA"} \ No newline at end of file diff --git a/node_modules/loupe/lib/promise.js b/node_modules/loupe/lib/promise.js new file mode 100644 index 0000000000..8fb9d3a90e --- /dev/null +++ b/node_modules/loupe/lib/promise.js @@ -0,0 +1,2 @@ +const getPromiseValue = () => 'Promise{…}'; +export default getPromiseValue; diff --git a/node_modules/loupe/lib/regexp.d.ts b/node_modules/loupe/lib/regexp.d.ts new file mode 100644 index 0000000000..ec77ec9336 --- /dev/null +++ b/node_modules/loupe/lib/regexp.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectRegExp(value: RegExp, options: Options): string; +//# sourceMappingURL=regexp.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/regexp.d.ts.map b/node_modules/loupe/lib/regexp.d.ts.map new file mode 100644 index 0000000000..7d8295eeda --- /dev/null +++ b/node_modules/loupe/lib/regexp.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"regexp.d.ts","sourceRoot":"","sources":["../src/regexp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAK7E"} \ No newline at end of file diff --git a/node_modules/loupe/lib/regexp.js b/node_modules/loupe/lib/regexp.js new file mode 100644 index 0000000000..0a35f49f9f --- /dev/null +++ b/node_modules/loupe/lib/regexp.js @@ -0,0 +1,7 @@ +import { truncate } from './helpers.js'; +export default function inspectRegExp(value, options) { + const flags = value.toString().split('/')[2]; + const sourceLength = options.truncate - (2 + flags.length); + const source = value.source; + return options.stylize(`/${truncate(source, sourceLength)}/${flags}`, 'regexp'); +} diff --git a/node_modules/loupe/lib/set.d.ts b/node_modules/loupe/lib/set.d.ts new file mode 100644 index 0000000000..280de62ea5 --- /dev/null +++ b/node_modules/loupe/lib/set.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectSet(set: Set, options: Options): string; +//# sourceMappingURL=set.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/set.d.ts.map b/node_modules/loupe/lib/set.d.ts.map new file mode 100644 index 0000000000..1436d03d74 --- /dev/null +++ b/node_modules/loupe/lib/set.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../src/set.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAWzC,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAI9E"} \ No newline at end of file diff --git a/node_modules/loupe/lib/set.js b/node_modules/loupe/lib/set.js new file mode 100644 index 0000000000..51b81adda9 --- /dev/null +++ b/node_modules/loupe/lib/set.js @@ -0,0 +1,15 @@ +import { inspectList } from './helpers.js'; +// IE11 doesn't support `Array.from(set)` +function arrayFromSet(set) { + const values = []; + set.forEach(value => { + values.push(value); + }); + return values; +} +export default function inspectSet(set, options) { + if (set.size === 0) + return 'Set{}'; + options.truncate -= 7; + return `Set{ ${inspectList(arrayFromSet(set), options)} }`; +} diff --git a/node_modules/loupe/lib/string.d.ts b/node_modules/loupe/lib/string.d.ts new file mode 100644 index 0000000000..7e178fb0a7 --- /dev/null +++ b/node_modules/loupe/lib/string.d.ts @@ -0,0 +1,3 @@ +import type { Options } from './types.js'; +export default function inspectString(string: string, options: Options): string; +//# sourceMappingURL=string.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/string.d.ts.map b/node_modules/loupe/lib/string.d.ts.map new file mode 100644 index 0000000000..0471e49d18 --- /dev/null +++ b/node_modules/loupe/lib/string.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../src/string.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AA2BzC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAK9E"} \ No newline at end of file diff --git a/node_modules/loupe/lib/string.js b/node_modules/loupe/lib/string.js new file mode 100644 index 0000000000..49c966580a --- /dev/null +++ b/node_modules/loupe/lib/string.js @@ -0,0 +1,24 @@ +import { truncate } from './helpers.js'; +const stringEscapeChars = new RegExp("['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5" + + '\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]', 'g'); +const escapeCharacters = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + "'": "\\'", + '\\': '\\\\', +}; +const hex = 16; +const unicodeLength = 4; +function escape(char) { + return (escapeCharacters[char] || + `\\u${`0000${char.charCodeAt(0).toString(hex)}`.slice(-unicodeLength)}`); +} +export default function inspectString(string, options) { + if (stringEscapeChars.test(string)) { + string = string.replace(stringEscapeChars, escape); + } + return options.stylize(`'${truncate(string, options.truncate - 2)}'`, 'string'); +} diff --git a/node_modules/loupe/lib/symbol.d.ts b/node_modules/loupe/lib/symbol.d.ts new file mode 100644 index 0000000000..81015e73a1 --- /dev/null +++ b/node_modules/loupe/lib/symbol.d.ts @@ -0,0 +1,2 @@ +export default function inspectSymbol(value: Symbol): string; +//# sourceMappingURL=symbol.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/symbol.d.ts.map b/node_modules/loupe/lib/symbol.d.ts.map new file mode 100644 index 0000000000..45786f134c --- /dev/null +++ b/node_modules/loupe/lib/symbol.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"symbol.d.ts","sourceRoot":"","sources":["../src/symbol.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK3D"} \ No newline at end of file diff --git a/node_modules/loupe/lib/symbol.js b/node_modules/loupe/lib/symbol.js new file mode 100644 index 0000000000..ca8dd68edd --- /dev/null +++ b/node_modules/loupe/lib/symbol.js @@ -0,0 +1,6 @@ +export default function inspectSymbol(value) { + if ('description' in Symbol.prototype) { + return value.description ? `Symbol(${value.description})` : 'Symbol()'; + } + return value.toString(); +} diff --git a/node_modules/loupe/lib/typedarray.d.ts b/node_modules/loupe/lib/typedarray.d.ts new file mode 100644 index 0000000000..0bdc4ecf44 --- /dev/null +++ b/node_modules/loupe/lib/typedarray.d.ts @@ -0,0 +1,5 @@ +import type { Options } from './types.js'; +type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; +export default function inspectTypedArray(array: TypedArray, options: Options): string; +export {}; +//# sourceMappingURL=typedarray.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/typedarray.d.ts.map b/node_modules/loupe/lib/typedarray.d.ts.map new file mode 100644 index 0000000000..6d11f73985 --- /dev/null +++ b/node_modules/loupe/lib/typedarray.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"typedarray.d.ts","sourceRoot":"","sources":["../src/typedarray.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,YAAY,CAAA;AAElD,KAAK,UAAU,GACX,SAAS,GACT,UAAU,GACV,iBAAiB,GACjB,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,GACX,YAAY,GACZ,YAAY,CAAA;AAchB,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CA8BrF"} \ No newline at end of file diff --git a/node_modules/loupe/lib/typedarray.js b/node_modules/loupe/lib/typedarray.js new file mode 100644 index 0000000000..e8257f6926 --- /dev/null +++ b/node_modules/loupe/lib/typedarray.js @@ -0,0 +1,38 @@ +import { inspectList, inspectProperty, truncate, truncator } from './helpers.js'; +const getArrayName = (array) => { + // We need to special case Node.js' Buffers, which report to be Uint8Array + // @ts-ignore + if (typeof Buffer === 'function' && array instanceof Buffer) { + return 'Buffer'; + } + if (array[Symbol.toStringTag]) { + return array[Symbol.toStringTag]; + } + return array.constructor.name; +}; +export default function inspectTypedArray(array, options) { + const name = getArrayName(array); + options.truncate -= name.length + 4; + // Object.keys will always output the Array indices first, so we can slice by + // `array.length` to get non-index properties + const nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) + return `${name}[]`; + // As we know TypedArrays only contain Unsigned Integers, we can skip inspecting each one and simply + // stylise the toString() value of them + let output = ''; + for (let i = 0; i < array.length; i++) { + const string = `${options.stylize(truncate(array[i], options.truncate), 'number')}${i === array.length - 1 ? '' : ', '}`; + options.truncate -= string.length; + if (array[i] !== array.length && options.truncate <= 3) { + output += `${truncator}(${array.length - array[i] + 1})`; + break; + } + output += string; + } + let propertyContents = ''; + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map(key => [key, array[key]]), options, inspectProperty); + } + return `${name}[ ${output}${propertyContents ? `, ${propertyContents}` : ''} ]`; +} diff --git a/node_modules/loupe/lib/types.d.ts b/node_modules/loupe/lib/types.d.ts new file mode 100644 index 0000000000..1abae2373b --- /dev/null +++ b/node_modules/loupe/lib/types.d.ts @@ -0,0 +1,15 @@ +export type Inspect = (value: unknown, options: Options) => string; +export interface Options { + showHidden: boolean; + depth: number; + colors: boolean; + customInspect: boolean; + showProxy: boolean; + maxArrayLength: number; + breakLength: number; + truncate: number; + seen: unknown[]; + inspect: Inspect; + stylize: (value: string, styleType: string) => string; +} +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/node_modules/loupe/lib/types.d.ts.map b/node_modules/loupe/lib/types.d.ts.map new file mode 100644 index 0000000000..e0ab591ff3 --- /dev/null +++ b/node_modules/loupe/lib/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,MAAM,CAAA;AAElE,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,aAAa,EAAE,OAAO,CAAA;IACtB,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAA;CACtD"} \ No newline at end of file diff --git a/node_modules/loupe/lib/types.js b/node_modules/loupe/lib/types.js new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/node_modules/loupe/lib/types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/loupe/loupe.js b/node_modules/loupe/loupe.js new file mode 100644 index 0000000000..a90bcbc712 --- /dev/null +++ b/node_modules/loupe/loupe.js @@ -0,0 +1,622 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var index_exports = {}; +__export(index_exports, { + custom: () => custom, + default: () => index_default, + inspect: () => inspect, + registerConstructor: () => registerConstructor, + registerStringTag: () => registerStringTag +}); +module.exports = __toCommonJS(index_exports); + +// src/helpers.ts +var ansiColors = { + bold: ["1", "22"], + dim: ["2", "22"], + italic: ["3", "23"], + underline: ["4", "24"], + // 5 & 6 are blinking + inverse: ["7", "27"], + hidden: ["8", "28"], + strike: ["9", "29"], + // 10-20 are fonts + // 21-29 are resets for 1-9 + black: ["30", "39"], + red: ["31", "39"], + green: ["32", "39"], + yellow: ["33", "39"], + blue: ["34", "39"], + magenta: ["35", "39"], + cyan: ["36", "39"], + white: ["37", "39"], + brightblack: ["30;1", "39"], + brightred: ["31;1", "39"], + brightgreen: ["32;1", "39"], + brightyellow: ["33;1", "39"], + brightblue: ["34;1", "39"], + brightmagenta: ["35;1", "39"], + brightcyan: ["36;1", "39"], + brightwhite: ["37;1", "39"], + grey: ["90", "39"] +}; +var styles = { + special: "cyan", + number: "yellow", + bigint: "yellow", + boolean: "yellow", + undefined: "grey", + null: "bold", + string: "green", + symbol: "green", + date: "magenta", + regexp: "red" +}; +var truncator = "\u2026"; +function colorise(value, styleType) { + const color = ansiColors[styles[styleType]] || ansiColors[styleType] || ""; + if (!color) { + return String(value); + } + return `\x1B[${color[0]}m${String(value)}\x1B[${color[1]}m`; +} +function normaliseOptions({ + showHidden = false, + depth = 2, + colors = false, + customInspect = true, + showProxy = false, + maxArrayLength = Infinity, + breakLength = Infinity, + seen = [], + // eslint-disable-next-line no-shadow + truncate: truncate2 = Infinity, + stylize = String +} = {}, inspect2) { + const options = { + showHidden: Boolean(showHidden), + depth: Number(depth), + colors: Boolean(colors), + customInspect: Boolean(customInspect), + showProxy: Boolean(showProxy), + maxArrayLength: Number(maxArrayLength), + breakLength: Number(breakLength), + truncate: Number(truncate2), + seen, + inspect: inspect2, + stylize + }; + if (options.colors) { + options.stylize = colorise; + } + return options; +} +function isHighSurrogate(char) { + return char >= "\uD800" && char <= "\uDBFF"; +} +function truncate(string, length, tail = truncator) { + string = String(string); + const tailLength = tail.length; + const stringLength = string.length; + if (tailLength > length && stringLength > tailLength) { + return tail; + } + if (stringLength > length && stringLength > tailLength) { + let end = length - tailLength; + if (end > 0 && isHighSurrogate(string[end - 1])) { + end = end - 1; + } + return `${string.slice(0, end)}${tail}`; + } + return string; +} +function inspectList(list, options, inspectItem, separator = ", ") { + inspectItem = inspectItem || options.inspect; + const size = list.length; + if (size === 0) return ""; + const originalLength = options.truncate; + let output = ""; + let peek = ""; + let truncated = ""; + for (let i = 0; i < size; i += 1) { + const last = i + 1 === list.length; + const secondToLast = i + 2 === list.length; + truncated = `${truncator}(${list.length - i})`; + const value = list[i]; + options.truncate = originalLength - output.length - (last ? 0 : separator.length); + const string = peek || inspectItem(value, options) + (last ? "" : separator); + const nextLength = output.length + string.length; + const truncatedLength = nextLength + truncated.length; + if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) { + break; + } + if (!last && !secondToLast && truncatedLength > originalLength) { + break; + } + peek = last ? "" : inspectItem(list[i + 1], options) + (secondToLast ? "" : separator); + if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) { + break; + } + output += string; + if (!last && !secondToLast && nextLength + peek.length >= originalLength) { + truncated = `${truncator}(${list.length - i - 1})`; + break; + } + truncated = ""; + } + return `${output}${truncated}`; +} +function quoteComplexKey(key) { + if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) { + return key; + } + return JSON.stringify(key).replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'"); +} +function inspectProperty([key, value], options) { + options.truncate -= 2; + if (typeof key === "string") { + key = quoteComplexKey(key); + } else if (typeof key !== "number") { + key = `[${options.inspect(key, options)}]`; + } + options.truncate -= key.length; + value = options.inspect(value, options); + return `${key}: ${value}`; +} + +// src/array.ts +function inspectArray(array, options) { + const nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) return "[]"; + options.truncate -= 4; + const listContents = inspectList(array, options); + options.truncate -= listContents.length; + let propertyContents = ""; + if (nonIndexProperties.length) { + propertyContents = inspectList( + nonIndexProperties.map((key) => [key, array[key]]), + options, + inspectProperty + ); + } + return `[ ${listContents}${propertyContents ? `, ${propertyContents}` : ""} ]`; +} + +// src/typedarray.ts +var getArrayName = (array) => { + if (typeof Buffer === "function" && array instanceof Buffer) { + return "Buffer"; + } + if (array[Symbol.toStringTag]) { + return array[Symbol.toStringTag]; + } + return array.constructor.name; +}; +function inspectTypedArray(array, options) { + const name = getArrayName(array); + options.truncate -= name.length + 4; + const nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) return `${name}[]`; + let output = ""; + for (let i = 0; i < array.length; i++) { + const string = `${options.stylize(truncate(array[i], options.truncate), "number")}${i === array.length - 1 ? "" : ", "}`; + options.truncate -= string.length; + if (array[i] !== array.length && options.truncate <= 3) { + output += `${truncator}(${array.length - array[i] + 1})`; + break; + } + output += string; + } + let propertyContents = ""; + if (nonIndexProperties.length) { + propertyContents = inspectList( + nonIndexProperties.map((key) => [key, array[key]]), + options, + inspectProperty + ); + } + return `${name}[ ${output}${propertyContents ? `, ${propertyContents}` : ""} ]`; +} + +// src/date.ts +function inspectDate(dateObject, options) { + const stringRepresentation = dateObject.toJSON(); + if (stringRepresentation === null) { + return "Invalid Date"; + } + const split = stringRepresentation.split("T"); + const date = split[0]; + return options.stylize(`${date}T${truncate(split[1], options.truncate - date.length - 1)}`, "date"); +} + +// src/function.ts +function inspectFunction(func, options) { + const functionType = func[Symbol.toStringTag] || "Function"; + const name = func.name; + if (!name) { + return options.stylize(`[${functionType}]`, "special"); + } + return options.stylize(`[${functionType} ${truncate(name, options.truncate - 11)}]`, "special"); +} + +// src/map.ts +function inspectMapEntry([key, value], options) { + options.truncate -= 4; + key = options.inspect(key, options); + options.truncate -= key.length; + value = options.inspect(value, options); + return `${key} => ${value}`; +} +function mapToEntries(map) { + const entries = []; + map.forEach((value, key) => { + entries.push([key, value]); + }); + return entries; +} +function inspectMap(map, options) { + if (map.size === 0) return "Map{}"; + options.truncate -= 7; + return `Map{ ${inspectList(mapToEntries(map), options, inspectMapEntry)} }`; +} + +// src/number.ts +var isNaN = Number.isNaN || ((i) => i !== i); +function inspectNumber(number, options) { + if (isNaN(number)) { + return options.stylize("NaN", "number"); + } + if (number === Infinity) { + return options.stylize("Infinity", "number"); + } + if (number === -Infinity) { + return options.stylize("-Infinity", "number"); + } + if (number === 0) { + return options.stylize(1 / number === Infinity ? "+0" : "-0", "number"); + } + return options.stylize(truncate(String(number), options.truncate), "number"); +} + +// src/bigint.ts +function inspectBigInt(number, options) { + let nums = truncate(number.toString(), options.truncate - 1); + if (nums !== truncator) nums += "n"; + return options.stylize(nums, "bigint"); +} + +// src/regexp.ts +function inspectRegExp(value, options) { + const flags = value.toString().split("/")[2]; + const sourceLength = options.truncate - (2 + flags.length); + const source = value.source; + return options.stylize(`/${truncate(source, sourceLength)}/${flags}`, "regexp"); +} + +// src/set.ts +function arrayFromSet(set) { + const values = []; + set.forEach((value) => { + values.push(value); + }); + return values; +} +function inspectSet(set, options) { + if (set.size === 0) return "Set{}"; + options.truncate -= 7; + return `Set{ ${inspectList(arrayFromSet(set), options)} }`; +} + +// src/string.ts +var stringEscapeChars = new RegExp( + "['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]", + "g" +); +var escapeCharacters = { + "\b": "\\b", + " ": "\\t", + "\n": "\\n", + "\f": "\\f", + "\r": "\\r", + "'": "\\'", + "\\": "\\\\" +}; +var hex = 16; +var unicodeLength = 4; +function escape(char) { + return escapeCharacters[char] || `\\u${`0000${char.charCodeAt(0).toString(hex)}`.slice(-unicodeLength)}`; +} +function inspectString(string, options) { + if (stringEscapeChars.test(string)) { + string = string.replace(stringEscapeChars, escape); + } + return options.stylize(`'${truncate(string, options.truncate - 2)}'`, "string"); +} + +// src/symbol.ts +function inspectSymbol(value) { + if ("description" in Symbol.prototype) { + return value.description ? `Symbol(${value.description})` : "Symbol()"; + } + return value.toString(); +} + +// src/promise.ts +var getPromiseValue = () => "Promise{\u2026}"; +var promise_default = getPromiseValue; + +// src/object.ts +function inspectObject(object, options) { + const properties = Object.getOwnPropertyNames(object); + const symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : []; + if (properties.length === 0 && symbols.length === 0) { + return "{}"; + } + options.truncate -= 4; + options.seen = options.seen || []; + if (options.seen.includes(object)) { + return "[Circular]"; + } + options.seen.push(object); + const propertyContents = inspectList( + properties.map((key) => [key, object[key]]), + options, + inspectProperty + ); + const symbolContents = inspectList( + symbols.map((key) => [key, object[key]]), + options, + inspectProperty + ); + options.seen.pop(); + let sep = ""; + if (propertyContents && symbolContents) { + sep = ", "; + } + return `{ ${propertyContents}${sep}${symbolContents} }`; +} + +// src/class.ts +var toStringTag = typeof Symbol !== "undefined" && Symbol.toStringTag ? Symbol.toStringTag : false; +function inspectClass(value, options) { + let name = ""; + if (toStringTag && toStringTag in value) { + name = value[toStringTag]; + } + name = name || value.constructor.name; + if (!name || name === "_class") { + name = ""; + } + options.truncate -= name.length; + return `${name}${inspectObject(value, options)}`; +} + +// src/arguments.ts +function inspectArguments(args, options) { + if (args.length === 0) return "Arguments[]"; + options.truncate -= 13; + return `Arguments[ ${inspectList(args, options)} ]`; +} + +// src/error.ts +var errorKeys = [ + "stack", + "line", + "column", + "name", + "message", + "fileName", + "lineNumber", + "columnNumber", + "number", + "description", + "cause" +]; +function inspectObject2(error, options) { + const properties = Object.getOwnPropertyNames(error).filter((key) => errorKeys.indexOf(key) === -1); + const name = error.name; + options.truncate -= name.length; + let message = ""; + if (typeof error.message === "string") { + message = truncate(error.message, options.truncate); + } else { + properties.unshift("message"); + } + message = message ? `: ${message}` : ""; + options.truncate -= message.length + 5; + options.seen = options.seen || []; + if (options.seen.includes(error)) { + return "[Circular]"; + } + options.seen.push(error); + const propertyContents = inspectList( + properties.map((key) => [key, error[key]]), + options, + inspectProperty + ); + return `${name}${message}${propertyContents ? ` { ${propertyContents} }` : ""}`; +} + +// src/html.ts +function inspectAttribute([key, value], options) { + options.truncate -= 3; + if (!value) { + return `${options.stylize(String(key), "yellow")}`; + } + return `${options.stylize(String(key), "yellow")}=${options.stylize(`"${value}"`, "string")}`; +} +function inspectNodeCollection(collection, options) { + return inspectList(collection, options, inspectNode, "\n"); +} +function inspectNode(node, options) { + switch (node.nodeType) { + case 1: + return inspectHTML(node, options); + case 3: + return options.inspect(node.data, options); + default: + return options.inspect(node, options); + } +} +function inspectHTML(element, options) { + const properties = element.getAttributeNames(); + const name = element.tagName.toLowerCase(); + const head = options.stylize(`<${name}`, "special"); + const headClose = options.stylize(`>`, "special"); + const tail = options.stylize(``, "special"); + options.truncate -= name.length * 2 + 5; + let propertyContents = ""; + if (properties.length > 0) { + propertyContents += " "; + propertyContents += inspectList( + properties.map((key) => [key, element.getAttribute(key)]), + options, + inspectAttribute, + " " + ); + } + options.truncate -= propertyContents.length; + const truncate2 = options.truncate; + let children = inspectNodeCollection(element.children, options); + if (children && children.length > truncate2) { + children = `${truncator}(${element.children.length})`; + } + return `${head}${propertyContents}${headClose}${children}${tail}`; +} + +// src/index.ts +var symbolsSupported = typeof Symbol === "function" && typeof Symbol.for === "function"; +var chaiInspect = symbolsSupported ? Symbol.for("chai/inspect") : "@@chai/inspect"; +var nodeInspect = Symbol.for("nodejs.util.inspect.custom"); +var constructorMap = /* @__PURE__ */ new WeakMap(); +var stringTagMap = {}; +var baseTypesMap = { + undefined: (value, options) => options.stylize("undefined", "undefined"), + null: (value, options) => options.stylize("null", "null"), + boolean: (value, options) => options.stylize(String(value), "boolean"), + Boolean: (value, options) => options.stylize(String(value), "boolean"), + number: inspectNumber, + Number: inspectNumber, + bigint: inspectBigInt, + BigInt: inspectBigInt, + string: inspectString, + String: inspectString, + function: inspectFunction, + Function: inspectFunction, + symbol: inspectSymbol, + // A Symbol polyfill will return `Symbol` not `symbol` from typedetect + Symbol: inspectSymbol, + Array: inspectArray, + Date: inspectDate, + Map: inspectMap, + Set: inspectSet, + RegExp: inspectRegExp, + Promise: promise_default, + // WeakSet, WeakMap are totally opaque to us + WeakSet: (value, options) => options.stylize("WeakSet{\u2026}", "special"), + WeakMap: (value, options) => options.stylize("WeakMap{\u2026}", "special"), + Arguments: inspectArguments, + Int8Array: inspectTypedArray, + Uint8Array: inspectTypedArray, + Uint8ClampedArray: inspectTypedArray, + Int16Array: inspectTypedArray, + Uint16Array: inspectTypedArray, + Int32Array: inspectTypedArray, + Uint32Array: inspectTypedArray, + Float32Array: inspectTypedArray, + Float64Array: inspectTypedArray, + Generator: () => "", + DataView: () => "", + ArrayBuffer: () => "", + Error: inspectObject2, + HTMLCollection: inspectNodeCollection, + NodeList: inspectNodeCollection +}; +var inspectCustom = (value, options, type, inspectFn) => { + if (chaiInspect in value && typeof value[chaiInspect] === "function") { + return value[chaiInspect](options); + } + if (nodeInspect in value && typeof value[nodeInspect] === "function") { + return value[nodeInspect](options.depth, options, inspectFn); + } + if ("inspect" in value && typeof value.inspect === "function") { + return value.inspect(options.depth, options); + } + if ("constructor" in value && constructorMap.has(value.constructor)) { + return constructorMap.get(value.constructor)(value, options); + } + if (stringTagMap[type]) { + return stringTagMap[type](value, options); + } + return ""; +}; +var toString = Object.prototype.toString; +function inspect(value, opts = {}) { + const options = normaliseOptions(opts, inspect); + const { customInspect } = options; + let type = value === null ? "null" : typeof value; + if (type === "object") { + type = toString.call(value).slice(8, -1); + } + if (type in baseTypesMap) { + return baseTypesMap[type](value, options); + } + if (customInspect && value) { + const output = inspectCustom(value, options, type, inspect); + if (output) { + if (typeof output === "string") return output; + return inspect(output, options); + } + } + const proto = value ? Object.getPrototypeOf(value) : false; + if (proto === Object.prototype || proto === null) { + return inspectObject(value, options); + } + if (value && typeof HTMLElement === "function" && value instanceof HTMLElement) { + return inspectHTML(value, options); + } + if ("constructor" in value) { + if (value.constructor !== Object) { + return inspectClass(value, options); + } + return inspectObject(value, options); + } + if (value === Object(value)) { + return inspectObject(value, options); + } + return options.stylize(String(value), type); +} +function registerConstructor(constructor, inspector) { + if (constructorMap.has(constructor)) { + return false; + } + constructorMap.set(constructor, inspector); + return true; +} +function registerStringTag(stringTag, inspector) { + if (stringTag in stringTagMap) { + return false; + } + stringTagMap[stringTag] = inspector; + return true; +} +var custom = chaiInspect; +var index_default = inspect; diff --git a/node_modules/loupe/package.json b/node_modules/loupe/package.json new file mode 100644 index 0000000000..de69efdbc4 --- /dev/null +++ b/node_modules/loupe/package.json @@ -0,0 +1,73 @@ +{ + "name": "loupe", + "version": "3.2.1", + "description": "Inspect utility for Node.js and browsers", + "homepage": "https://github.com/chaijs/loupe", + "license": "MIT", + "author": "Veselin Todorov ", + "contributors": [ + "Keith Cirkel (https://github.com/keithamus)" + ], + "type": "module", + "main": "./lib/index.js", + "module": "./lib/index.js", + "browser": { + "./index.js": "./loupe.js", + "util": false + }, + "repository": { + "type": "git", + "url": "https://github.com/chaijs/loupe" + }, + "files": [ + "loupe.js", + "lib/*" + ], + "scripts": { + "bench": "node bench", + "lint": "eslint .", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "test": "npm run test:node && npm run test:browser", + "pretest:browser": "npx playwright install-deps && npx playwright install && npm run build", + "test:browser": "wtr", + "pretest:node": "npm run build", + "test:node": "mocha", + "build": "npm run build:lib && npm run build:esm-bundle && npm run build:cjs-bundle", + "build:lib": "tsc", + "build:esm-bundle": "esbuild --bundle src/index.ts --outfile=loupe.js --format=esm", + "build:cjs-bundle": "esbuild --bundle src/index.ts --outfile=loupe.js --format=cjs", + "upload-coverage": "codecov" + }, + "prettier": { + "printWidth": 120, + "tabWidth": 2, + "useTabs": false, + "semi": false, + "singleQuote": true, + "trailingComma": "es5", + "arrowParens": "avoid", + "bracketSpacing": true + }, + "devDependencies": { + "@web/dev-server-esbuild": "^1.0.3", + "@web/test-runner": "^0.19.0", + "@web/test-runner-playwright": "^0.11.0", + "benchmark": "^2.1.4", + "chai": "^5.0.0-alpha.0", + "codecov": "^3.8.3", + "core-js": "^3.8.3", + "cross-env": "^7.0.3", + "esbuild": "^0.24.2", + "eslint": "^9.19.0", + "eslint-config-prettier": "^10.0.1", + "eslint-config-strict": "^14.0.1", + "eslint-plugin-filenames": "^1.3.2", + "eslint-plugin-prettier": "^5.2.3", + "husky": "^9.1.7", + "mocha": "^11.1.0", + "nyc": "^17.1.0", + "prettier": "^3.0.0", + "simple-assert": "^2.0.0", + "typescript": "^5.0.0-beta" + } +} diff --git a/node_modules/magic-string/LICENSE b/node_modules/magic-string/LICENSE new file mode 100644 index 0000000000..667e8b45e4 --- /dev/null +++ b/node_modules/magic-string/LICENSE @@ -0,0 +1,7 @@ +Copyright 2018 Rich Harris + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/magic-string/README.md b/node_modules/magic-string/README.md new file mode 100644 index 0000000000..b2e9f9a19f --- /dev/null +++ b/node_modules/magic-string/README.md @@ -0,0 +1,324 @@ +# magic-string + + + build status + + + npm version + + + license + + +Suppose you have some source code. You want to make some light modifications to it - replacing a few characters here and there, wrapping it with a header and footer, etc - and ideally you'd like to generate a [source map](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/) at the end of it. You've thought about using something like [recast](https://github.com/benjamn/recast) (which allows you to generate an AST from some JavaScript, manipulate it, and reprint it with a sourcemap without losing your comments and formatting), but it seems like overkill for your needs (or maybe the source code isn't JavaScript). + +Your requirements are, frankly, rather niche. But they're requirements that I also have, and for which I made magic-string. It's a small, fast utility for manipulating strings and generating sourcemaps. + +## Installation + +magic-string works in both node.js and browser environments. For node, install with npm: + +```bash +npm i magic-string +``` + +To use in browser, grab the [magic-string.umd.js](https://unpkg.com/magic-string/dist/magic-string.umd.js) file and add it to your page: + +```html + +``` + +(It also works with various module systems, if you prefer that sort of thing - it has a dependency on [vlq](https://github.com/Rich-Harris/vlq).) + +## Usage + +These examples assume you're in node.js, or something similar: + +```js +import MagicString from 'magic-string'; +import fs from 'fs'; + +const s = new MagicString('problems = 99'); + +s.update(0, 8, 'answer'); +s.toString(); // 'answer = 99' + +s.update(11, 13, '42'); // character indices always refer to the original string +s.toString(); // 'answer = 42' + +s.prepend('var ').append(';'); // most methods are chainable +s.toString(); // 'var answer = 42;' + +const map = s.generateMap({ + source: 'source.js', + file: 'converted.js.map', + includeContent: true, +}); // generates a v3 sourcemap + +fs.writeFileSync('converted.js', s.toString()); +fs.writeFileSync('converted.js.map', map.toString()); +``` + +You can pass an options argument: + +```js +const s = new MagicString(someCode, { + // these options will be used if you later call `bundle.addSource( s )` - see below + filename: 'foo.js', + indentExclusionRanges: [ + /*...*/ + ], + // mark source as ignore in DevTools, see below #Bundling + ignoreList: false, + // adjust the incoming position - see below + offset: 0, +}); +``` + +## Properties + +### s.offset + +Sets the offset property to adjust the incoming position for the following APIs: `slice`, `update`, `overwrite`, `appendLeft`, `prependLeft`, `appendRight`, `prependRight`, `move`, `reset`, and `remove`. + +Example usage: + +```ts +const s = new MagicString('hello world', { offset: 0 }); +s.offset = 6; +s.slice() === 'world'; +``` + +## Methods + +### s.addSourcemapLocation( index ) + +Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is `false` (see below). + +### s.append( content ) + +Appends the specified content to the end of the string. Returns `this`. + +### s.appendLeft( index, content ) + +Appends the specified `content` at the `index` in the original string. If a range _ending_ with `index` is subsequently moved, the insert will be moved with it. Returns `this`. See also `s.prependLeft(...)`. + +### s.appendRight( index, content ) + +Appends the specified `content` at the `index` in the original string. If a range _starting_ with `index` is subsequently moved, the insert will be moved with it. Returns `this`. See also `s.prependRight(...)`. + +### s.clone() + +Does what you'd expect. + +### s.generateDecodedMap( options ) + +Generates a sourcemap object with raw mappings in array form, rather than encoded as a string. See `generateMap` documentation below for options details. Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead. + +### s.generateMap( options ) + +Generates a [version 3 sourcemap](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit). All options are, well, optional: + +- `file` - the filename where you plan to write the sourcemap +- `source` - the filename of the file containing the original source +- `includeContent` - whether to include the original content in the map's `sourcesContent` array +- `hires` - whether the mapping should be high-resolution. Hi-res mappings map every single character, meaning (for example) your devtools will always be able to pinpoint the exact location of function calls and so on. With lo-res mappings, devtools may only be able to identify the correct line - but they're quicker to generate and less bulky. You can also set `"boundary"` to generate a semi-hi-res mappings segmented per word boundary instead of per character, suitable for string semantics that are separated by words. If sourcemap locations have been specified with `s.addSourcemapLocation()`, they will be used here. + +The returned sourcemap has two (non-enumerable) methods attached for convenience: + +- `toString` - returns the equivalent of `JSON.stringify(map)` +- `toUrl` - returns a DataURI containing the sourcemap. Useful for doing this sort of thing: + +```js +code += '\n//# sourceMappingURL=' + map.toUrl(); +``` + +### s.hasChanged() + +Indicates if the string has been changed. + +### s.indent( prefix[, options] ) + +Prefixes each line of the string with `prefix`. If `prefix` is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. Returns `this`. + +The `options` argument can have an `exclude` property, which is an array of `[start, end]` character ranges. These ranges will be excluded from the indentation - useful for (e.g.) multiline strings. + +### s.insertLeft( index, content ) + +**DEPRECATED** since 0.17 – use `s.appendLeft(...)` instead + +### s.insertRight( index, content ) + +**DEPRECATED** since 0.17 – use `s.prependRight(...)` instead + +### s.isEmpty() + +Returns true if the resulting source is empty (disregarding white space). + +### s.locate( index ) + +**DEPRECATED** since 0.10 – see [#30](https://github.com/Rich-Harris/magic-string/pull/30) + +### s.locateOrigin( index ) + +**DEPRECATED** since 0.10 – see [#30](https://github.com/Rich-Harris/magic-string/pull/30) + +### s.move( start, end, index ) + +Moves the characters from `start` and `end` to `index`. Returns `this`. + +### s.overwrite( start, end, content[, options] ) + +Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in that range. The same restrictions as `s.remove()` apply. Returns `this`. + +The fourth argument is optional. It can have a `storeName` property — if `true`, the original name will be stored for later inclusion in a sourcemap's `names` array — and a `contentOnly` property which determines whether only the content is overwritten, or anything that was appended/prepended to the range as well. + +It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content. + +### s.prepend( content ) + +Prepends the string with the specified content. Returns `this`. + +### s.prependLeft ( index, content ) + +Same as `s.appendLeft(...)`, except that the inserted content will go _before_ any previous appends or prepends at `index` + +### s.prependRight ( index, content ) + +Same as `s.appendRight(...)`, except that the inserted content will go _before_ any previous appends or prepends at `index` + +### s.replace( regexpOrString, substitution ) + +String replacement with RegExp or string. When using a RegExp, replacer function is also supported. Returns `this`. + +```ts +import MagicString from 'magic-string'; + +const s = new MagicString(source); + +s.replace('foo', 'bar'); +s.replace(/foo/g, 'bar'); +s.replace(/(\w)(\d+)/g, (_, $1, $2) => $1.toUpperCase() + $2); +``` + +The differences from [`String.replace`](<(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace)>): + +- It will always match against the **original string** +- It mutates the magic string state (use `.clone()` to be immutable) + +### s.replaceAll( regexpOrString, substitution ) + +Same as `s.replace`, but replace all matched strings instead of just one. +If `regexpOrString` is a regex, then it must have the global (`g`) flag set, or a `TypeError` is thrown. Matches the behavior of the builtin [`String.property.replaceAll`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll). Returns `this`. + +### s.remove( start, end ) + +Removes the characters from `start` to `end` (of the original string, **not** the generated string). Removing the same content twice, or making removals that partially overlap, will cause an error. Returns `this`. + +### s.reset( start, end ) + +Resets the characters from `start` to `end` (of the original string, **not** the generated string). +It can be used to restore previously removed characters and discard unwanted changes. + +### s.slice( start, end ) + +Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string. Throws error if the indices are for characters that were already removed. + +### s.snip( start, end ) + +Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed. + +### s.toString() + +Returns the generated string. + +### s.trim([ charType ]) + +Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end. Returns `this`. + +### s.trimStart([ charType ]) + +Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start. Returns `this`. + +### s.trimEnd([ charType ]) + +Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end. Returns `this`. + +### s.trimLines() + +Removes empty lines from the start and end. Returns `this`. + +### s.update( start, end, content[, options] ) + +Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply. Returns `this`. + +The fourth argument is optional. It can have a `storeName` property — if `true`, the original name will be stored for later inclusion in a sourcemap's `names` array — and an `overwrite` property which defaults to `false` and determines whether anything that was appended/prepended to the range will be overwritten along with the original content. + +`s.update(start, end, content)` is equivalent to `s.overwrite(start, end, content, { contentOnly: true })`. + +## Bundling + +To concatenate several sources, use `MagicString.Bundle`: + +```js +const bundle = new MagicString.Bundle(); + +bundle.addSource({ + filename: 'foo.js', + content: new MagicString('var answer = 42;'), +}); + +bundle.addSource({ + filename: 'bar.js', + content: new MagicString('console.log( answer )'), +}); + +// Sources can be marked as ignore-listed, which provides a hint to debuggers +// to not step into this code and also don't show the source files depending +// on user preferences. +bundle.addSource({ + filename: 'some-3rdparty-library.js', + content: new MagicString('function myLib(){}'), + ignoreList: false, // <-- +}); + +// Advanced: a source can include an `indentExclusionRanges` property +// alongside `filename` and `content`. This will be passed to `s.indent()` +// - see documentation above + +bundle + .indent() // optionally, pass an indent string, otherwise it will be guessed + .prepend('(function () {\n') + .append('}());'); + +bundle.toString(); +// (function () { +// var answer = 42; +// console.log( answer ); +// }()); + +// options are as per `s.generateMap()` above +const map = bundle.generateMap({ + file: 'bundle.js', + includeContent: true, + hires: true, +}); +``` + +As an alternative syntax, if you a) don't have `filename` or `indentExclusionRanges` options, or b) passed those in when you used `new MagicString(...)`, you can simply pass the `MagicString` instance itself: + +```js +const bundle = new MagicString.Bundle(); +const source = new MagicString(someCode, { + filename: 'foo.js', +}); + +bundle.addSource(source); +``` + +## License + +MIT diff --git a/node_modules/magic-string/dist/magic-string.cjs.d.ts b/node_modules/magic-string/dist/magic-string.cjs.d.ts new file mode 100644 index 0000000000..76cc537d1c --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.cjs.d.ts @@ -0,0 +1,289 @@ +export interface BundleOptions { + intro?: string; + separator?: string; +} + +export interface SourceMapOptions { + /** + * Whether the mapping should be high-resolution. + * Hi-res mappings map every single character, meaning (for example) your devtools will always + * be able to pinpoint the exact location of function calls and so on. + * With lo-res mappings, devtools may only be able to identify the correct + * line - but they're quicker to generate and less bulky. + * You can also set `"boundary"` to generate a semi-hi-res mappings segmented per word boundary + * instead of per character, suitable for string semantics that are separated by words. + * If sourcemap locations have been specified with s.addSourceMapLocation(), they will be used here. + */ + hires?: boolean | 'boundary'; + /** + * The filename where you plan to write the sourcemap. + */ + file?: string; + /** + * The filename of the file containing the original source. + */ + source?: string; + /** + * Whether to include the original content in the map's sourcesContent array. + */ + includeContent?: boolean; +} + +export type SourceMapSegment = + | [number] + | [number, number, number, number] + | [number, number, number, number, number]; + +export interface DecodedSourceMap { + file: string; + sources: string[]; + sourcesContent?: string[]; + names: string[]; + mappings: SourceMapSegment[][]; + x_google_ignoreList?: number[]; +} + +export class SourceMap { + constructor(properties: DecodedSourceMap); + + version: number; + file: string; + sources: string[]; + sourcesContent?: string[]; + names: string[]; + mappings: string; + x_google_ignoreList?: number[]; + debugId?: string; + + /** + * Returns the equivalent of `JSON.stringify(map)` + */ + toString(): string; + /** + * Returns a DataURI containing the sourcemap. Useful for doing this sort of thing: + * `generateMap(options?: SourceMapOptions): SourceMap;` + */ + toUrl(): string; +} + +export class Bundle { + constructor(options?: BundleOptions); + /** + * Adds the specified source to the bundle, which can either be a `MagicString` object directly, + * or an options object that holds a magic string `content` property and optionally provides + * a `filename` for the source within the bundle, as well as an optional `ignoreList` hint + * (which defaults to `false`). The `filename` is used when constructing the source map for the + * bundle, to identify this `source` in the source map's `sources` field. The `ignoreList` hint + * is used to populate the `x_google_ignoreList` extension field in the source map, which is a + * mechanism for tools to signal to debuggers that certain sources should be ignored by default + * (depending on user preferences). + */ + addSource( + source: MagicString | { filename?: string; content: MagicString; ignoreList?: boolean }, + ): this; + append(str: string, options?: BundleOptions): this; + clone(): this; + generateMap( + options?: SourceMapOptions, + ): Omit & { sourcesContent: Array }; + generateDecodedMap( + options?: SourceMapOptions, + ): Omit & { sourcesContent: Array }; + getIndentString(): string; + indent(indentStr?: string): this; + indentExclusionRanges: ExclusionRange | Array; + prepend(str: string): this; + toString(): string; + trimLines(): this; + trim(charType?: string): this; + trimStart(charType?: string): this; + trimEnd(charType?: string): this; + isEmpty(): boolean; + length(): number; +} + +export type ExclusionRange = [number, number]; + +export interface MagicStringOptions { + filename?: string; + indentExclusionRanges?: ExclusionRange | Array; + offset?: number; +} + +export interface IndentOptions { + exclude?: ExclusionRange | Array; + indentStart?: boolean; +} + +export interface OverwriteOptions { + storeName?: boolean; + contentOnly?: boolean; +} + +export interface UpdateOptions { + storeName?: boolean; + overwrite?: boolean; +} + +export default class MagicString { + constructor(str: string, options?: MagicStringOptions); + /** + * Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is false. + */ + addSourcemapLocation(char: number): void; + /** + * Appends the specified content to the end of the string. + */ + append(content: string): this; + /** + * Appends the specified content at the index in the original string. + * If a range *ending* with index is subsequently moved, the insert will be moved with it. + * See also `s.prependLeft(...)`. + */ + appendLeft(index: number, content: string): this; + /** + * Appends the specified content at the index in the original string. + * If a range *starting* with index is subsequently moved, the insert will be moved with it. + * See also `s.prependRight(...)`. + */ + appendRight(index: number, content: string): this; + /** + * Does what you'd expect. + */ + clone(): this; + /** + * Generates a version 3 sourcemap. + */ + generateMap(options?: SourceMapOptions): SourceMap; + /** + * Generates a sourcemap object with raw mappings in array form, rather than encoded as a string. + * Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead. + */ + generateDecodedMap(options?: SourceMapOptions): DecodedSourceMap; + getIndentString(): string; + + /** + * Prefixes each line of the string with prefix. + * If prefix is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. + */ + indent(options?: IndentOptions): this; + /** + * Prefixes each line of the string with prefix. + * If prefix is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. + * + * The options argument can have an exclude property, which is an array of [start, end] character ranges. + * These ranges will be excluded from the indentation - useful for (e.g.) multiline strings. + */ + indent(indentStr?: string, options?: IndentOptions): this; + indentExclusionRanges: ExclusionRange | Array; + + /** + * Moves the characters from `start` and `end` to `index`. + */ + move(start: number, end: number, index: number): this; + /** + * Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in + * that range. The same restrictions as `s.remove()` apply. + * + * The fourth argument is optional. It can have a storeName property — if true, the original name will be stored + * for later inclusion in a sourcemap's names array — and a contentOnly property which determines whether only + * the content is overwritten, or anything that was appended/prepended to the range as well. + * + * It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content. + */ + overwrite( + start: number, + end: number, + content: string, + options?: boolean | OverwriteOptions, + ): this; + /** + * Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply. + * + * The fourth argument is optional. It can have a storeName property — if true, the original name will be stored + * for later inclusion in a sourcemap's names array — and an overwrite property which determines whether only + * the content is overwritten, or anything that was appended/prepended to the range as well. + */ + update(start: number, end: number, content: string, options?: boolean | UpdateOptions): this; + /** + * Prepends the string with the specified content. + */ + prepend(content: string): this; + /** + * Same as `s.appendLeft(...)`, except that the inserted content will go *before* any previous appends or prepends at index + */ + prependLeft(index: number, content: string): this; + /** + * Same as `s.appendRight(...)`, except that the inserted content will go *before* any previous appends or prepends at `index` + */ + prependRight(index: number, content: string): this; + /** + * Removes the characters from `start` to `end` (of the original string, **not** the generated string). + * Removing the same content twice, or making removals that partially overlap, will cause an error. + */ + remove(start: number, end: number): this; + /** + * Reset the modified characters from `start` to `end` (of the original string, **not** the generated string). + */ + reset(start: number, end: number): this; + /** + * Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string. + * Throws error if the indices are for characters that were already removed. + */ + slice(start: number, end: number): string; + /** + * Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed. + */ + snip(start: number, end: number): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end. + */ + trim(charType?: string): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start. + */ + trimStart(charType?: string): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end. + */ + trimEnd(charType?: string): this; + /** + * Removes empty lines from the start and end. + */ + trimLines(): this; + /** + * String replacement with RegExp or string. + */ + replace( + regex: RegExp | string, + replacement: string | ((substring: string, ...args: any[]) => string), + ): this; + /** + * Same as `s.replace`, but replace all matched strings instead of just one. + */ + replaceAll( + regex: RegExp | string, + replacement: string | ((substring: string, ...args: any[]) => string), + ): this; + + lastChar(): string; + lastLine(): string; + /** + * Returns true if the resulting source is empty (disregarding white space). + */ + isEmpty(): boolean; + length(): number; + + /** + * Indicates if the string has been changed. + */ + hasChanged(): boolean; + + original: string; + /** + * Returns the generated string. + */ + toString(): string; + + offset: number; +} diff --git a/node_modules/magic-string/dist/magic-string.cjs.js b/node_modules/magic-string/dist/magic-string.cjs.js new file mode 100644 index 0000000000..74ed915a85 --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.cjs.js @@ -0,0 +1,1581 @@ +'use strict'; + +var sourcemapCodec = require('@jridgewell/sourcemap-codec'); + +class BitSet { + constructor(arg) { + this.bits = arg instanceof BitSet ? arg.bits.slice() : []; + } + + add(n) { + this.bits[n >> 5] |= 1 << (n & 31); + } + + has(n) { + return !!(this.bits[n >> 5] & (1 << (n & 31))); + } +} + +class Chunk { + constructor(start, end, content) { + this.start = start; + this.end = end; + this.original = content; + + this.intro = ''; + this.outro = ''; + + this.content = content; + this.storeName = false; + this.edited = false; + + { + this.previous = null; + this.next = null; + } + } + + appendLeft(content) { + this.outro += content; + } + + appendRight(content) { + this.intro = this.intro + content; + } + + clone() { + const chunk = new Chunk(this.start, this.end, this.original); + + chunk.intro = this.intro; + chunk.outro = this.outro; + chunk.content = this.content; + chunk.storeName = this.storeName; + chunk.edited = this.edited; + + return chunk; + } + + contains(index) { + return this.start < index && index < this.end; + } + + eachNext(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.next; + } + } + + eachPrevious(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.previous; + } + } + + edit(content, storeName, contentOnly) { + this.content = content; + if (!contentOnly) { + this.intro = ''; + this.outro = ''; + } + this.storeName = storeName; + + this.edited = true; + + return this; + } + + prependLeft(content) { + this.outro = content + this.outro; + } + + prependRight(content) { + this.intro = content + this.intro; + } + + reset() { + this.intro = ''; + this.outro = ''; + if (this.edited) { + this.content = this.original; + this.storeName = false; + this.edited = false; + } + } + + split(index) { + const sliceIndex = index - this.start; + + const originalBefore = this.original.slice(0, sliceIndex); + const originalAfter = this.original.slice(sliceIndex); + + this.original = originalBefore; + + const newChunk = new Chunk(index, this.end, originalAfter); + newChunk.outro = this.outro; + this.outro = ''; + + this.end = index; + + if (this.edited) { + // after split we should save the edit content record into the correct chunk + // to make sure sourcemap correct + // For example: + // ' test'.trim() + // split -> ' ' + 'test' + // ✔️ edit -> '' + 'test' + // ✖️ edit -> 'test' + '' + // TODO is this block necessary?... + newChunk.edit('', false); + this.content = ''; + } else { + this.content = originalBefore; + } + + newChunk.next = this.next; + if (newChunk.next) newChunk.next.previous = newChunk; + newChunk.previous = this; + this.next = newChunk; + + return newChunk; + } + + toString() { + return this.intro + this.content + this.outro; + } + + trimEnd(rx) { + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + this.split(this.start + trimmed.length).edit('', undefined, true); + if (this.edited) { + // save the change, if it has been edited + this.edit(trimmed, this.storeName, true); + } + } + return true; + } else { + this.edit('', undefined, true); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + } + } + + trimStart(rx) { + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + const newChunk = this.split(this.end - trimmed.length); + if (this.edited) { + // save the change, if it has been edited + newChunk.edit(trimmed, this.storeName, true); + } + this.edit('', undefined, true); + } + return true; + } else { + this.edit('', undefined, true); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + } + } +} + +function getBtoa() { + if (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') { + return (str) => globalThis.btoa(unescape(encodeURIComponent(str))); + } else if (typeof Buffer === 'function') { + return (str) => Buffer.from(str, 'utf-8').toString('base64'); + } else { + return () => { + throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.'); + }; + } +} + +const btoa = /*#__PURE__*/ getBtoa(); + +class SourceMap { + constructor(properties) { + this.version = 3; + this.file = properties.file; + this.sources = properties.sources; + this.sourcesContent = properties.sourcesContent; + this.names = properties.names; + this.mappings = sourcemapCodec.encode(properties.mappings); + if (typeof properties.x_google_ignoreList !== 'undefined') { + this.x_google_ignoreList = properties.x_google_ignoreList; + } + if (typeof properties.debugId !== 'undefined') { + this.debugId = properties.debugId; + } + } + + toString() { + return JSON.stringify(this); + } + + toUrl() { + return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString()); + } +} + +function guessIndent(code) { + const lines = code.split('\n'); + + const tabbed = lines.filter((line) => /^\t+/.test(line)); + const spaced = lines.filter((line) => /^ {2,}/.test(line)); + + if (tabbed.length === 0 && spaced.length === 0) { + return null; + } + + // More lines tabbed than spaced? Assume tabs, and + // default to tabs in the case of a tie (or nothing + // to go on) + if (tabbed.length >= spaced.length) { + return '\t'; + } + + // Otherwise, we need to guess the multiple + const min = spaced.reduce((previous, current) => { + const numSpaces = /^ +/.exec(current)[0].length; + return Math.min(numSpaces, previous); + }, Infinity); + + return new Array(min + 1).join(' '); +} + +function getRelativePath(from, to) { + const fromParts = from.split(/[/\\]/); + const toParts = to.split(/[/\\]/); + + fromParts.pop(); // get dirname + + while (fromParts[0] === toParts[0]) { + fromParts.shift(); + toParts.shift(); + } + + if (fromParts.length) { + let i = fromParts.length; + while (i--) fromParts[i] = '..'; + } + + return fromParts.concat(toParts).join('/'); +} + +const toString = Object.prototype.toString; + +function isObject(thing) { + return toString.call(thing) === '[object Object]'; +} + +function getLocator(source) { + const originalLines = source.split('\n'); + const lineOffsets = []; + + for (let i = 0, pos = 0; i < originalLines.length; i++) { + lineOffsets.push(pos); + pos += originalLines[i].length + 1; + } + + return function locate(index) { + let i = 0; + let j = lineOffsets.length; + while (i < j) { + const m = (i + j) >> 1; + if (index < lineOffsets[m]) { + j = m; + } else { + i = m + 1; + } + } + const line = i - 1; + const column = index - lineOffsets[line]; + return { line, column }; + }; +} + +const wordRegex = /\w/; + +class Mappings { + constructor(hires) { + this.hires = hires; + this.generatedCodeLine = 0; + this.generatedCodeColumn = 0; + this.raw = []; + this.rawSegments = this.raw[this.generatedCodeLine] = []; + this.pending = null; + } + + addEdit(sourceIndex, content, loc, nameIndex) { + if (content.length) { + const contentLengthMinusOne = content.length - 1; + let contentLineEnd = content.indexOf('\n', 0); + let previousContentLineEnd = -1; + // Loop through each line in the content and add a segment, but stop if the last line is empty, + // else code afterwards would fill one line too many + while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + + previousContentLineEnd = contentLineEnd; + contentLineEnd = content.indexOf('\n', contentLineEnd + 1); + } + + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.advance(content.slice(previousContentLineEnd + 1)); + } else if (this.pending) { + this.rawSegments.push(this.pending); + this.advance(content); + } + + this.pending = null; + } + + addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) { + let originalCharIndex = chunk.start; + let first = true; + // when iterating each char, check if it's in a word boundary + let charInHiresBoundary = false; + + while (originalCharIndex < chunk.end) { + if (original[originalCharIndex] === '\n') { + loc.line += 1; + loc.column = 0; + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + first = true; + charInHiresBoundary = false; + } else { + if (this.hires || first || sourcemapLocations.has(originalCharIndex)) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + + if (this.hires === 'boundary') { + // in hires "boundary", group segments per word boundary than per char + if (wordRegex.test(original[originalCharIndex])) { + // for first char in the boundary found, start the boundary by pushing a segment + if (!charInHiresBoundary) { + this.rawSegments.push(segment); + charInHiresBoundary = true; + } + } else { + // for non-word char, end the boundary by pushing a segment + this.rawSegments.push(segment); + charInHiresBoundary = false; + } + } else { + this.rawSegments.push(segment); + } + } + + loc.column += 1; + this.generatedCodeColumn += 1; + first = false; + } + + originalCharIndex += 1; + } + + this.pending = null; + } + + advance(str) { + if (!str) return; + + const lines = str.split('\n'); + + if (lines.length > 1) { + for (let i = 0; i < lines.length - 1; i++) { + this.generatedCodeLine++; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + } + this.generatedCodeColumn = 0; + } + + this.generatedCodeColumn += lines[lines.length - 1].length; + } +} + +const n = '\n'; + +const warned = { + insertLeft: false, + insertRight: false, + storeName: false, +}; + +class MagicString { + constructor(string, options = {}) { + const chunk = new Chunk(0, string.length, string); + + Object.defineProperties(this, { + original: { writable: true, value: string }, + outro: { writable: true, value: '' }, + intro: { writable: true, value: '' }, + firstChunk: { writable: true, value: chunk }, + lastChunk: { writable: true, value: chunk }, + lastSearchedChunk: { writable: true, value: chunk }, + byStart: { writable: true, value: {} }, + byEnd: { writable: true, value: {} }, + filename: { writable: true, value: options.filename }, + indentExclusionRanges: { writable: true, value: options.indentExclusionRanges }, + sourcemapLocations: { writable: true, value: new BitSet() }, + storedNames: { writable: true, value: {} }, + indentStr: { writable: true, value: undefined }, + ignoreList: { writable: true, value: options.ignoreList }, + offset: { writable: true, value: options.offset || 0 }, + }); + + this.byStart[0] = chunk; + this.byEnd[string.length] = chunk; + } + + addSourcemapLocation(char) { + this.sourcemapLocations.add(char); + } + + append(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.outro += content; + return this; + } + + appendLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.appendLeft(content); + } else { + this.intro += content; + } + return this; + } + + appendRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.appendRight(content); + } else { + this.outro += content; + } + return this; + } + + clone() { + const cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset }); + + let originalChunk = this.firstChunk; + let clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone()); + + while (originalChunk) { + cloned.byStart[clonedChunk.start] = clonedChunk; + cloned.byEnd[clonedChunk.end] = clonedChunk; + + const nextOriginalChunk = originalChunk.next; + const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone(); + + if (nextClonedChunk) { + clonedChunk.next = nextClonedChunk; + nextClonedChunk.previous = clonedChunk; + + clonedChunk = nextClonedChunk; + } + + originalChunk = nextOriginalChunk; + } + + cloned.lastChunk = clonedChunk; + + if (this.indentExclusionRanges) { + cloned.indentExclusionRanges = this.indentExclusionRanges.slice(); + } + + cloned.sourcemapLocations = new BitSet(this.sourcemapLocations); + + cloned.intro = this.intro; + cloned.outro = this.outro; + + return cloned; + } + + generateDecodedMap(options) { + options = options || {}; + + const sourceIndex = 0; + const names = Object.keys(this.storedNames); + const mappings = new Mappings(options.hires); + + const locate = getLocator(this.original); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: [ + options.source ? getRelativePath(options.file || '', options.source) : options.file || '', + ], + sourcesContent: options.includeContent ? [this.original] : undefined, + names, + mappings: mappings.raw, + x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + _ensureindentStr() { + if (this.indentStr === undefined) { + this.indentStr = guessIndent(this.original); + } + } + + _getRawIndentString() { + this._ensureindentStr(); + return this.indentStr; + } + + getIndentString() { + this._ensureindentStr(); + return this.indentStr === null ? '\t' : this.indentStr; + } + + indent(indentStr, options) { + const pattern = /^[^\r\n]/gm; + + if (isObject(indentStr)) { + options = indentStr; + indentStr = undefined; + } + + if (indentStr === undefined) { + this._ensureindentStr(); + indentStr = this.indentStr || '\t'; + } + + if (indentStr === '') return this; // noop + + options = options || {}; + + // Process exclusion ranges + const isExcluded = {}; + + if (options.exclude) { + const exclusions = + typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude; + exclusions.forEach((exclusion) => { + for (let i = exclusion[0]; i < exclusion[1]; i += 1) { + isExcluded[i] = true; + } + }); + } + + let shouldIndentNextCharacter = options.indentStart !== false; + const replacer = (match) => { + if (shouldIndentNextCharacter) return `${indentStr}${match}`; + shouldIndentNextCharacter = true; + return match; + }; + + this.intro = this.intro.replace(pattern, replacer); + + let charIndex = 0; + let chunk = this.firstChunk; + + while (chunk) { + const end = chunk.end; + + if (chunk.edited) { + if (!isExcluded[charIndex]) { + chunk.content = chunk.content.replace(pattern, replacer); + + if (chunk.content.length) { + shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n'; + } + } + } else { + charIndex = chunk.start; + + while (charIndex < end) { + if (!isExcluded[charIndex]) { + const char = this.original[charIndex]; + + if (char === '\n') { + shouldIndentNextCharacter = true; + } else if (char !== '\r' && shouldIndentNextCharacter) { + shouldIndentNextCharacter = false; + + if (charIndex === chunk.start) { + chunk.prependRight(indentStr); + } else { + this._splitChunk(chunk, charIndex); + chunk = chunk.next; + chunk.prependRight(indentStr); + } + } + } + + charIndex += 1; + } + } + + charIndex = chunk.end; + chunk = chunk.next; + } + + this.outro = this.outro.replace(pattern, replacer); + + return this; + } + + insert() { + throw new Error( + 'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)', + ); + } + + insertLeft(index, content) { + if (!warned.insertLeft) { + console.warn( + 'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead', + ); + warned.insertLeft = true; + } + + return this.appendLeft(index, content); + } + + insertRight(index, content) { + if (!warned.insertRight) { + console.warn( + 'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead', + ); + warned.insertRight = true; + } + + return this.prependRight(index, content); + } + + move(start, end, index) { + start = start + this.offset; + end = end + this.offset; + index = index + this.offset; + + if (index >= start && index <= end) throw new Error('Cannot move a selection inside itself'); + + this._split(start); + this._split(end); + this._split(index); + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + const oldLeft = first.previous; + const oldRight = last.next; + + const newRight = this.byStart[index]; + if (!newRight && last === this.lastChunk) return this; + const newLeft = newRight ? newRight.previous : this.lastChunk; + + if (oldLeft) oldLeft.next = oldRight; + if (oldRight) oldRight.previous = oldLeft; + + if (newLeft) newLeft.next = first; + if (newRight) newRight.previous = last; + + if (!first.previous) this.firstChunk = last.next; + if (!last.next) { + this.lastChunk = first.previous; + this.lastChunk.next = null; + } + + first.previous = newLeft; + last.next = newRight || null; + + if (!newLeft) this.firstChunk = first; + if (!newRight) this.lastChunk = last; + return this; + } + + overwrite(start, end, content, options) { + options = options || {}; + return this.update(start, end, content, { ...options, overwrite: !options.contentOnly }); + } + + update(start, end, content, options) { + start = start + this.offset; + end = end + this.offset; + + if (typeof content !== 'string') throw new TypeError('replacement content must be a string'); + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (end > this.original.length) throw new Error('end is out of bounds'); + if (start === end) + throw new Error( + 'Cannot overwrite a zero-length range – use appendLeft or prependRight instead', + ); + + this._split(start); + this._split(end); + + if (options === true) { + if (!warned.storeName) { + console.warn( + 'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string', + ); + warned.storeName = true; + } + + options = { storeName: true }; + } + const storeName = options !== undefined ? options.storeName : false; + const overwrite = options !== undefined ? options.overwrite : false; + + if (storeName) { + const original = this.original.slice(start, end); + Object.defineProperty(this.storedNames, original, { + writable: true, + value: true, + enumerable: true, + }); + } + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + if (first) { + let chunk = first; + while (chunk !== last) { + if (chunk.next !== this.byStart[chunk.end]) { + throw new Error('Cannot overwrite across a split point'); + } + chunk = chunk.next; + chunk.edit('', false); + } + + first.edit(content, storeName, !overwrite); + } else { + // must be inserting at the end + const newChunk = new Chunk(start, end, '').edit(content, storeName); + + // TODO last chunk in the array may not be the last chunk, if it's moved... + last.next = newChunk; + newChunk.previous = last; + } + return this; + } + + prepend(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.intro = content + this.intro; + return this; + } + + prependLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.prependLeft(content); + } else { + this.intro = content + this.intro; + } + return this; + } + + prependRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.prependRight(content); + } else { + this.outro = content + this.outro; + } + return this; + } + + remove(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.intro = ''; + chunk.outro = ''; + chunk.edit(''); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + reset(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.reset(); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + lastChar() { + if (this.outro.length) return this.outro[this.outro.length - 1]; + let chunk = this.lastChunk; + do { + if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1]; + if (chunk.content.length) return chunk.content[chunk.content.length - 1]; + if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1]; + } while ((chunk = chunk.previous)); + if (this.intro.length) return this.intro[this.intro.length - 1]; + return ''; + } + + lastLine() { + let lineIndex = this.outro.lastIndexOf(n); + if (lineIndex !== -1) return this.outro.substr(lineIndex + 1); + let lineStr = this.outro; + let chunk = this.lastChunk; + do { + if (chunk.outro.length > 0) { + lineIndex = chunk.outro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.outro + lineStr; + } + + if (chunk.content.length > 0) { + lineIndex = chunk.content.lastIndexOf(n); + if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr; + lineStr = chunk.content + lineStr; + } + + if (chunk.intro.length > 0) { + lineIndex = chunk.intro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.intro + lineStr; + } + } while ((chunk = chunk.previous)); + lineIndex = this.intro.lastIndexOf(n); + if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr; + return this.intro + lineStr; + } + + slice(start = 0, end = this.original.length - this.offset) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + let result = ''; + + // find start chunk + let chunk = this.firstChunk; + while (chunk && (chunk.start > start || chunk.end <= start)) { + // found end chunk before start + if (chunk.start < end && chunk.end >= end) { + return result; + } + + chunk = chunk.next; + } + + if (chunk && chunk.edited && chunk.start !== start) + throw new Error(`Cannot use replaced character ${start} as slice start anchor.`); + + const startChunk = chunk; + while (chunk) { + if (chunk.intro && (startChunk !== chunk || chunk.start === start)) { + result += chunk.intro; + } + + const containsEnd = chunk.start < end && chunk.end >= end; + if (containsEnd && chunk.edited && chunk.end !== end) + throw new Error(`Cannot use replaced character ${end} as slice end anchor.`); + + const sliceStart = startChunk === chunk ? start - chunk.start : 0; + const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length; + + result += chunk.content.slice(sliceStart, sliceEnd); + + if (chunk.outro && (!containsEnd || chunk.end === end)) { + result += chunk.outro; + } + + if (containsEnd) { + break; + } + + chunk = chunk.next; + } + + return result; + } + + // TODO deprecate this? not really very useful + snip(start, end) { + const clone = this.clone(); + clone.remove(0, start); + clone.remove(end, clone.original.length); + + return clone; + } + + _split(index) { + if (this.byStart[index] || this.byEnd[index]) return; + + let chunk = this.lastSearchedChunk; + let previousChunk = chunk; + const searchForward = index > chunk.end; + + while (chunk) { + if (chunk.contains(index)) return this._splitChunk(chunk, index); + + chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start]; + + // Prevent infinite loop (e.g. via empty chunks, where start === end) + if (chunk === previousChunk) return; + + previousChunk = chunk; + } + } + + _splitChunk(chunk, index) { + if (chunk.edited && chunk.content.length) { + // zero-length edited chunks are a special case (overlapping replacements) + const loc = getLocator(this.original)(index); + throw new Error( + `Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`, + ); + } + + const newChunk = chunk.split(index); + + this.byEnd[index] = chunk; + this.byStart[index] = newChunk; + this.byEnd[newChunk.end] = newChunk; + + if (chunk === this.lastChunk) this.lastChunk = newChunk; + + this.lastSearchedChunk = chunk; + return true; + } + + toString() { + let str = this.intro; + + let chunk = this.firstChunk; + while (chunk) { + str += chunk.toString(); + chunk = chunk.next; + } + + return str + this.outro; + } + + isEmpty() { + let chunk = this.firstChunk; + do { + if ( + (chunk.intro.length && chunk.intro.trim()) || + (chunk.content.length && chunk.content.trim()) || + (chunk.outro.length && chunk.outro.trim()) + ) + return false; + } while ((chunk = chunk.next)); + return true; + } + + length() { + let chunk = this.firstChunk; + let length = 0; + do { + length += chunk.intro.length + chunk.content.length + chunk.outro.length; + } while ((chunk = chunk.next)); + return length; + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimEndAborted(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + let chunk = this.lastChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimEnd(rx); + + // if chunk was trimmed, we have a new lastChunk + if (chunk.end !== end) { + if (this.lastChunk === chunk) { + this.lastChunk = chunk.next; + } + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.previous; + } while (chunk); + + return false; + } + + trimEnd(charType) { + this.trimEndAborted(charType); + return this; + } + trimStartAborted(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + let chunk = this.firstChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimStart(rx); + + if (chunk.end !== end) { + // special case... + if (chunk === this.lastChunk) this.lastChunk = chunk.next; + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.next; + } while (chunk); + + return false; + } + + trimStart(charType) { + this.trimStartAborted(charType); + return this; + } + + hasChanged() { + return this.original !== this.toString(); + } + + _replaceRegexp(searchValue, replacement) { + function getReplacement(match, str) { + if (typeof replacement === 'string') { + return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter + if (i === '$') return '$'; + if (i === '&') return match[0]; + const num = +i; + if (num < match.length) return match[+i]; + return `$${i}`; + }); + } else { + return replacement(...match, match.index, str, match.groups); + } + } + function matchAll(re, str) { + let match; + const matches = []; + while ((match = re.exec(str))) { + matches.push(match); + } + return matches; + } + if (searchValue.global) { + const matches = matchAll(searchValue, this.original); + matches.forEach((match) => { + if (match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + }); + } else { + const match = this.original.match(searchValue); + if (match && match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + } + return this; + } + + _replaceString(string, replacement) { + const { original } = this; + const index = original.indexOf(string); + + if (index !== -1) { + this.overwrite(index, index + string.length, replacement); + } + + return this; + } + + replace(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceString(searchValue, replacement); + } + + return this._replaceRegexp(searchValue, replacement); + } + + _replaceAllString(string, replacement) { + const { original } = this; + const stringLength = string.length; + for ( + let index = original.indexOf(string); + index !== -1; + index = original.indexOf(string, index + stringLength) + ) { + const previous = original.slice(index, index + stringLength); + if (previous !== replacement) this.overwrite(index, index + stringLength, replacement); + } + + return this; + } + + replaceAll(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceAllString(searchValue, replacement); + } + + if (!searchValue.global) { + throw new TypeError( + 'MagicString.prototype.replaceAll called with a non-global RegExp argument', + ); + } + + return this._replaceRegexp(searchValue, replacement); + } +} + +const hasOwnProp = Object.prototype.hasOwnProperty; + +class Bundle { + constructor(options = {}) { + this.intro = options.intro || ''; + this.separator = options.separator !== undefined ? options.separator : '\n'; + this.sources = []; + this.uniqueSources = []; + this.uniqueSourceIndexByFilename = {}; + } + + addSource(source) { + if (source instanceof MagicString) { + return this.addSource({ + content: source, + filename: source.filename, + separator: this.separator, + }); + } + + if (!isObject(source) || !source.content) { + throw new Error( + 'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`', + ); + } + + ['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => { + if (!hasOwnProp.call(source, option)) source[option] = source.content[option]; + }); + + if (source.separator === undefined) { + // TODO there's a bunch of this sort of thing, needs cleaning up + source.separator = this.separator; + } + + if (source.filename) { + if (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) { + this.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length; + this.uniqueSources.push({ filename: source.filename, content: source.content.original }); + } else { + const uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]]; + if (source.content.original !== uniqueSource.content) { + throw new Error(`Illegal source: same filename (${source.filename}), different contents`); + } + } + } + + this.sources.push(source); + return this; + } + + append(str, options) { + this.addSource({ + content: new MagicString(str), + separator: (options && options.separator) || '', + }); + + return this; + } + + clone() { + const bundle = new Bundle({ + intro: this.intro, + separator: this.separator, + }); + + this.sources.forEach((source) => { + bundle.addSource({ + filename: source.filename, + content: source.content.clone(), + separator: source.separator, + }); + }); + + return bundle; + } + + generateDecodedMap(options = {}) { + const names = []; + let x_google_ignoreList = undefined; + this.sources.forEach((source) => { + Object.keys(source.content.storedNames).forEach((name) => { + if (!~names.indexOf(name)) names.push(name); + }); + }); + + const mappings = new Mappings(options.hires); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.sources.forEach((source, i) => { + if (i > 0) { + mappings.advance(this.separator); + } + + const sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1; + const magicString = source.content; + const locate = getLocator(magicString.original); + + if (magicString.intro) { + mappings.advance(magicString.intro); + } + + magicString.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (source.filename) { + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk( + sourceIndex, + chunk, + magicString.original, + loc, + magicString.sourcemapLocations, + ); + } + } else { + mappings.advance(chunk.content); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + if (magicString.outro) { + mappings.advance(magicString.outro); + } + + if (source.ignoreList && sourceIndex !== -1) { + if (x_google_ignoreList === undefined) { + x_google_ignoreList = []; + } + x_google_ignoreList.push(sourceIndex); + } + }); + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: this.uniqueSources.map((source) => { + return options.file ? getRelativePath(options.file, source.filename) : source.filename; + }), + sourcesContent: this.uniqueSources.map((source) => { + return options.includeContent ? source.content : null; + }), + names, + mappings: mappings.raw, + x_google_ignoreList, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + getIndentString() { + const indentStringCounts = {}; + + this.sources.forEach((source) => { + const indentStr = source.content._getRawIndentString(); + + if (indentStr === null) return; + + if (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0; + indentStringCounts[indentStr] += 1; + }); + + return ( + Object.keys(indentStringCounts).sort((a, b) => { + return indentStringCounts[a] - indentStringCounts[b]; + })[0] || '\t' + ); + } + + indent(indentStr) { + if (!arguments.length) { + indentStr = this.getIndentString(); + } + + if (indentStr === '') return this; // noop + + let trailingNewline = !this.intro || this.intro.slice(-1) === '\n'; + + this.sources.forEach((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const indentStart = trailingNewline || (i > 0 && /\r?\n$/.test(separator)); + + source.content.indent(indentStr, { + exclude: source.indentExclusionRanges, + indentStart, //: trailingNewline || /\r?\n$/.test( separator ) //true///\r?\n/.test( separator ) + }); + + trailingNewline = source.content.lastChar() === '\n'; + }); + + if (this.intro) { + this.intro = + indentStr + + this.intro.replace(/^[^\n]/gm, (match, index) => { + return index > 0 ? indentStr + match : match; + }); + } + + return this; + } + + prepend(str) { + this.intro = str + this.intro; + return this; + } + + toString() { + const body = this.sources + .map((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const str = (i > 0 ? separator : '') + source.content.toString(); + + return str; + }) + .join(''); + + return this.intro + body; + } + + isEmpty() { + if (this.intro.length && this.intro.trim()) return false; + if (this.sources.some((source) => !source.content.isEmpty())) return false; + return true; + } + + length() { + return this.sources.reduce( + (length, source) => length + source.content.length(), + this.intro.length, + ); + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimStart(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + this.intro = this.intro.replace(rx, ''); + + if (!this.intro) { + let source; + let i = 0; + + do { + source = this.sources[i++]; + if (!source) { + break; + } + } while (!source.content.trimStartAborted(charType)); + } + + return this; + } + + trimEnd(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + let source; + let i = this.sources.length - 1; + + do { + source = this.sources[i--]; + if (!source) { + this.intro = this.intro.replace(rx, ''); + break; + } + } while (!source.content.trimEndAborted(charType)); + + return this; + } +} + +MagicString.Bundle = Bundle; +MagicString.SourceMap = SourceMap; +MagicString.default = MagicString; // work around TypeScript bug https://github.com/Rich-Harris/magic-string/pull/121 + +module.exports = MagicString; +//# sourceMappingURL=magic-string.cjs.js.map diff --git a/node_modules/magic-string/dist/magic-string.cjs.js.map b/node_modules/magic-string/dist/magic-string.cjs.js.map new file mode 100644 index 0000000000..2ce6464e8a --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.cjs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"magic-string.cjs.js","sources":["../src/BitSet.js","../src/Chunk.js","../src/SourceMap.js","../src/utils/guessIndent.js","../src/utils/getRelativePath.js","../src/utils/isObject.js","../src/utils/getLocator.js","../src/utils/Mappings.js","../src/MagicString.js","../src/Bundle.js","../src/index-legacy.js"],"sourcesContent":["export default class BitSet {\n\tconstructor(arg) {\n\t\tthis.bits = arg instanceof BitSet ? arg.bits.slice() : [];\n\t}\n\n\tadd(n) {\n\t\tthis.bits[n >> 5] |= 1 << (n & 31);\n\t}\n\n\thas(n) {\n\t\treturn !!(this.bits[n >> 5] & (1 << (n & 31)));\n\t}\n}\n","export default class Chunk {\n\tconstructor(start, end, content) {\n\t\tthis.start = start;\n\t\tthis.end = end;\n\t\tthis.original = content;\n\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\n\t\tthis.content = content;\n\t\tthis.storeName = false;\n\t\tthis.edited = false;\n\n\t\tif (DEBUG) {\n\t\t\t// we make these non-enumerable, for sanity while debugging\n\t\t\tObject.defineProperties(this, {\n\t\t\t\tprevious: { writable: true, value: null },\n\t\t\t\tnext: { writable: true, value: null },\n\t\t\t});\n\t\t} else {\n\t\t\tthis.previous = null;\n\t\t\tthis.next = null;\n\t\t}\n\t}\n\n\tappendLeft(content) {\n\t\tthis.outro += content;\n\t}\n\n\tappendRight(content) {\n\t\tthis.intro = this.intro + content;\n\t}\n\n\tclone() {\n\t\tconst chunk = new Chunk(this.start, this.end, this.original);\n\n\t\tchunk.intro = this.intro;\n\t\tchunk.outro = this.outro;\n\t\tchunk.content = this.content;\n\t\tchunk.storeName = this.storeName;\n\t\tchunk.edited = this.edited;\n\n\t\treturn chunk;\n\t}\n\n\tcontains(index) {\n\t\treturn this.start < index && index < this.end;\n\t}\n\n\teachNext(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.next;\n\t\t}\n\t}\n\n\teachPrevious(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.previous;\n\t\t}\n\t}\n\n\tedit(content, storeName, contentOnly) {\n\t\tthis.content = content;\n\t\tif (!contentOnly) {\n\t\t\tthis.intro = '';\n\t\t\tthis.outro = '';\n\t\t}\n\t\tthis.storeName = storeName;\n\n\t\tthis.edited = true;\n\n\t\treturn this;\n\t}\n\n\tprependLeft(content) {\n\t\tthis.outro = content + this.outro;\n\t}\n\n\tprependRight(content) {\n\t\tthis.intro = content + this.intro;\n\t}\n\n\treset() {\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\t\tif (this.edited) {\n\t\t\tthis.content = this.original;\n\t\t\tthis.storeName = false;\n\t\t\tthis.edited = false;\n\t\t}\n\t}\n\n\tsplit(index) {\n\t\tconst sliceIndex = index - this.start;\n\n\t\tconst originalBefore = this.original.slice(0, sliceIndex);\n\t\tconst originalAfter = this.original.slice(sliceIndex);\n\n\t\tthis.original = originalBefore;\n\n\t\tconst newChunk = new Chunk(index, this.end, originalAfter);\n\t\tnewChunk.outro = this.outro;\n\t\tthis.outro = '';\n\n\t\tthis.end = index;\n\n\t\tif (this.edited) {\n\t\t\t// after split we should save the edit content record into the correct chunk\n\t\t\t// to make sure sourcemap correct\n\t\t\t// For example:\n\t\t\t// ' test'.trim()\n\t\t\t// split -> ' ' + 'test'\n\t\t\t// ✔️ edit -> '' + 'test'\n\t\t\t// ✖️ edit -> 'test' + ''\n\t\t\t// TODO is this block necessary?...\n\t\t\tnewChunk.edit('', false);\n\t\t\tthis.content = '';\n\t\t} else {\n\t\t\tthis.content = originalBefore;\n\t\t}\n\n\t\tnewChunk.next = this.next;\n\t\tif (newChunk.next) newChunk.next.previous = newChunk;\n\t\tnewChunk.previous = this;\n\t\tthis.next = newChunk;\n\n\t\treturn newChunk;\n\t}\n\n\ttoString() {\n\t\treturn this.intro + this.content + this.outro;\n\t}\n\n\ttrimEnd(rx) {\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tthis.split(this.start + trimmed.length).edit('', undefined, true);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tthis.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\tif (this.intro.length) return true;\n\t\t}\n\t}\n\n\ttrimStart(rx) {\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tconst newChunk = this.split(this.end - trimmed.length);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tnewChunk.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t\tthis.edit('', undefined, true);\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.outro = this.outro.replace(rx, '');\n\t\t\tif (this.outro.length) return true;\n\t\t}\n\t}\n}\n","import { encode } from '@jridgewell/sourcemap-codec';\n\nfunction getBtoa() {\n\tif (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') {\n\t\treturn (str) => globalThis.btoa(unescape(encodeURIComponent(str)));\n\t} else if (typeof Buffer === 'function') {\n\t\treturn (str) => Buffer.from(str, 'utf-8').toString('base64');\n\t} else {\n\t\treturn () => {\n\t\t\tthrow new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');\n\t\t};\n\t}\n}\n\nconst btoa = /*#__PURE__*/ getBtoa();\n\nexport default class SourceMap {\n\tconstructor(properties) {\n\t\tthis.version = 3;\n\t\tthis.file = properties.file;\n\t\tthis.sources = properties.sources;\n\t\tthis.sourcesContent = properties.sourcesContent;\n\t\tthis.names = properties.names;\n\t\tthis.mappings = encode(properties.mappings);\n\t\tif (typeof properties.x_google_ignoreList !== 'undefined') {\n\t\t\tthis.x_google_ignoreList = properties.x_google_ignoreList;\n\t\t}\n\t\tif (typeof properties.debugId !== 'undefined') {\n\t\t\tthis.debugId = properties.debugId;\n\t\t}\n\t}\n\n\ttoString() {\n\t\treturn JSON.stringify(this);\n\t}\n\n\ttoUrl() {\n\t\treturn 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());\n\t}\n}\n","export default function guessIndent(code) {\n\tconst lines = code.split('\\n');\n\n\tconst tabbed = lines.filter((line) => /^\\t+/.test(line));\n\tconst spaced = lines.filter((line) => /^ {2,}/.test(line));\n\n\tif (tabbed.length === 0 && spaced.length === 0) {\n\t\treturn null;\n\t}\n\n\t// More lines tabbed than spaced? Assume tabs, and\n\t// default to tabs in the case of a tie (or nothing\n\t// to go on)\n\tif (tabbed.length >= spaced.length) {\n\t\treturn '\\t';\n\t}\n\n\t// Otherwise, we need to guess the multiple\n\tconst min = spaced.reduce((previous, current) => {\n\t\tconst numSpaces = /^ +/.exec(current)[0].length;\n\t\treturn Math.min(numSpaces, previous);\n\t}, Infinity);\n\n\treturn new Array(min + 1).join(' ');\n}\n","export default function getRelativePath(from, to) {\n\tconst fromParts = from.split(/[/\\\\]/);\n\tconst toParts = to.split(/[/\\\\]/);\n\n\tfromParts.pop(); // get dirname\n\n\twhile (fromParts[0] === toParts[0]) {\n\t\tfromParts.shift();\n\t\ttoParts.shift();\n\t}\n\n\tif (fromParts.length) {\n\t\tlet i = fromParts.length;\n\t\twhile (i--) fromParts[i] = '..';\n\t}\n\n\treturn fromParts.concat(toParts).join('/');\n}\n","const toString = Object.prototype.toString;\n\nexport default function isObject(thing) {\n\treturn toString.call(thing) === '[object Object]';\n}\n","export default function getLocator(source) {\n\tconst originalLines = source.split('\\n');\n\tconst lineOffsets = [];\n\n\tfor (let i = 0, pos = 0; i < originalLines.length; i++) {\n\t\tlineOffsets.push(pos);\n\t\tpos += originalLines[i].length + 1;\n\t}\n\n\treturn function locate(index) {\n\t\tlet i = 0;\n\t\tlet j = lineOffsets.length;\n\t\twhile (i < j) {\n\t\t\tconst m = (i + j) >> 1;\n\t\t\tif (index < lineOffsets[m]) {\n\t\t\t\tj = m;\n\t\t\t} else {\n\t\t\t\ti = m + 1;\n\t\t\t}\n\t\t}\n\t\tconst line = i - 1;\n\t\tconst column = index - lineOffsets[line];\n\t\treturn { line, column };\n\t};\n}\n","const wordRegex = /\\w/;\n\nexport default class Mappings {\n\tconstructor(hires) {\n\t\tthis.hires = hires;\n\t\tthis.generatedCodeLine = 0;\n\t\tthis.generatedCodeColumn = 0;\n\t\tthis.raw = [];\n\t\tthis.rawSegments = this.raw[this.generatedCodeLine] = [];\n\t\tthis.pending = null;\n\t}\n\n\taddEdit(sourceIndex, content, loc, nameIndex) {\n\t\tif (content.length) {\n\t\t\tconst contentLengthMinusOne = content.length - 1;\n\t\t\tlet contentLineEnd = content.indexOf('\\n', 0);\n\t\t\tlet previousContentLineEnd = -1;\n\t\t\t// Loop through each line in the content and add a segment, but stop if the last line is empty,\n\t\t\t// else code afterwards would fill one line too many\n\t\t\twhile (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {\n\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\t\tif (nameIndex >= 0) {\n\t\t\t\t\tsegment.push(nameIndex);\n\t\t\t\t}\n\t\t\t\tthis.rawSegments.push(segment);\n\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\n\t\t\t\tpreviousContentLineEnd = contentLineEnd;\n\t\t\t\tcontentLineEnd = content.indexOf('\\n', contentLineEnd + 1);\n\t\t\t}\n\n\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\tif (nameIndex >= 0) {\n\t\t\t\tsegment.push(nameIndex);\n\t\t\t}\n\t\t\tthis.rawSegments.push(segment);\n\n\t\t\tthis.advance(content.slice(previousContentLineEnd + 1));\n\t\t} else if (this.pending) {\n\t\t\tthis.rawSegments.push(this.pending);\n\t\t\tthis.advance(content);\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\taddUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {\n\t\tlet originalCharIndex = chunk.start;\n\t\tlet first = true;\n\t\t// when iterating each char, check if it's in a word boundary\n\t\tlet charInHiresBoundary = false;\n\n\t\twhile (originalCharIndex < chunk.end) {\n\t\t\tif (original[originalCharIndex] === '\\n') {\n\t\t\t\tloc.line += 1;\n\t\t\t\tloc.column = 0;\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\t\t\t\tfirst = true;\n\t\t\t\tcharInHiresBoundary = false;\n\t\t\t} else {\n\t\t\t\tif (this.hires || first || sourcemapLocations.has(originalCharIndex)) {\n\t\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\n\t\t\t\t\tif (this.hires === 'boundary') {\n\t\t\t\t\t\t// in hires \"boundary\", group segments per word boundary than per char\n\t\t\t\t\t\tif (wordRegex.test(original[originalCharIndex])) {\n\t\t\t\t\t\t\t// for first char in the boundary found, start the boundary by pushing a segment\n\t\t\t\t\t\t\tif (!charInHiresBoundary) {\n\t\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\t\tcharInHiresBoundary = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// for non-word char, end the boundary by pushing a segment\n\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\tcharInHiresBoundary = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tloc.column += 1;\n\t\t\t\tthis.generatedCodeColumn += 1;\n\t\t\t\tfirst = false;\n\t\t\t}\n\n\t\t\toriginalCharIndex += 1;\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\tadvance(str) {\n\t\tif (!str) return;\n\n\t\tconst lines = str.split('\\n');\n\n\t\tif (lines.length > 1) {\n\t\t\tfor (let i = 0; i < lines.length - 1; i++) {\n\t\t\t\tthis.generatedCodeLine++;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t}\n\t\t\tthis.generatedCodeColumn = 0;\n\t\t}\n\n\t\tthis.generatedCodeColumn += lines[lines.length - 1].length;\n\t}\n}\n","import BitSet from './BitSet.js';\nimport Chunk from './Chunk.js';\nimport SourceMap from './SourceMap.js';\nimport guessIndent from './utils/guessIndent.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\nimport Stats from './utils/Stats.js';\n\nconst n = '\\n';\n\nconst warned = {\n\tinsertLeft: false,\n\tinsertRight: false,\n\tstoreName: false,\n};\n\nexport default class MagicString {\n\tconstructor(string, options = {}) {\n\t\tconst chunk = new Chunk(0, string.length, string);\n\n\t\tObject.defineProperties(this, {\n\t\t\toriginal: { writable: true, value: string },\n\t\t\toutro: { writable: true, value: '' },\n\t\t\tintro: { writable: true, value: '' },\n\t\t\tfirstChunk: { writable: true, value: chunk },\n\t\t\tlastChunk: { writable: true, value: chunk },\n\t\t\tlastSearchedChunk: { writable: true, value: chunk },\n\t\t\tbyStart: { writable: true, value: {} },\n\t\t\tbyEnd: { writable: true, value: {} },\n\t\t\tfilename: { writable: true, value: options.filename },\n\t\t\tindentExclusionRanges: { writable: true, value: options.indentExclusionRanges },\n\t\t\tsourcemapLocations: { writable: true, value: new BitSet() },\n\t\t\tstoredNames: { writable: true, value: {} },\n\t\t\tindentStr: { writable: true, value: undefined },\n\t\t\tignoreList: { writable: true, value: options.ignoreList },\n\t\t\toffset: { writable: true, value: options.offset || 0 },\n\t\t});\n\n\t\tif (DEBUG) {\n\t\t\tObject.defineProperty(this, 'stats', { value: new Stats() });\n\t\t}\n\n\t\tthis.byStart[0] = chunk;\n\t\tthis.byEnd[string.length] = chunk;\n\t}\n\n\taddSourcemapLocation(char) {\n\t\tthis.sourcemapLocations.add(char);\n\t}\n\n\tappend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.outro += content;\n\t\treturn this;\n\t}\n\n\tappendLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendLeft');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendLeft(content);\n\t\t} else {\n\t\t\tthis.intro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendLeft');\n\t\treturn this;\n\t}\n\n\tappendRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendRight(content);\n\t\t} else {\n\t\t\tthis.outro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendRight');\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset });\n\n\t\tlet originalChunk = this.firstChunk;\n\t\tlet clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());\n\n\t\twhile (originalChunk) {\n\t\t\tcloned.byStart[clonedChunk.start] = clonedChunk;\n\t\t\tcloned.byEnd[clonedChunk.end] = clonedChunk;\n\n\t\t\tconst nextOriginalChunk = originalChunk.next;\n\t\t\tconst nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();\n\n\t\t\tif (nextClonedChunk) {\n\t\t\t\tclonedChunk.next = nextClonedChunk;\n\t\t\t\tnextClonedChunk.previous = clonedChunk;\n\n\t\t\t\tclonedChunk = nextClonedChunk;\n\t\t\t}\n\n\t\t\toriginalChunk = nextOriginalChunk;\n\t\t}\n\n\t\tcloned.lastChunk = clonedChunk;\n\n\t\tif (this.indentExclusionRanges) {\n\t\t\tcloned.indentExclusionRanges = this.indentExclusionRanges.slice();\n\t\t}\n\n\t\tcloned.sourcemapLocations = new BitSet(this.sourcemapLocations);\n\n\t\tcloned.intro = this.intro;\n\t\tcloned.outro = this.outro;\n\n\t\treturn cloned;\n\t}\n\n\tgenerateDecodedMap(options) {\n\t\toptions = options || {};\n\n\t\tconst sourceIndex = 0;\n\t\tconst names = Object.keys(this.storedNames);\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tconst locate = getLocator(this.original);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.firstChunk.eachNext((chunk) => {\n\t\t\tconst loc = locate(chunk.start);\n\n\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tmappings.addEdit(\n\t\t\t\t\tsourceIndex,\n\t\t\t\t\tchunk.content,\n\t\t\t\t\tloc,\n\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tmappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);\n\t\t\t}\n\n\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t});\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: [\n\t\t\t\toptions.source ? getRelativePath(options.file || '', options.source) : options.file || '',\n\t\t\t],\n\t\t\tsourcesContent: options.includeContent ? [this.original] : undefined,\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\t_ensureindentStr() {\n\t\tif (this.indentStr === undefined) {\n\t\t\tthis.indentStr = guessIndent(this.original);\n\t\t}\n\t}\n\n\t_getRawIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr;\n\t}\n\n\tgetIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr === null ? '\\t' : this.indentStr;\n\t}\n\n\tindent(indentStr, options) {\n\t\tconst pattern = /^[^\\r\\n]/gm;\n\n\t\tif (isObject(indentStr)) {\n\t\t\toptions = indentStr;\n\t\t\tindentStr = undefined;\n\t\t}\n\n\t\tif (indentStr === undefined) {\n\t\t\tthis._ensureindentStr();\n\t\t\tindentStr = this.indentStr || '\\t';\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\toptions = options || {};\n\n\t\t// Process exclusion ranges\n\t\tconst isExcluded = {};\n\n\t\tif (options.exclude) {\n\t\t\tconst exclusions =\n\t\t\t\ttypeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;\n\t\t\texclusions.forEach((exclusion) => {\n\t\t\t\tfor (let i = exclusion[0]; i < exclusion[1]; i += 1) {\n\t\t\t\t\tisExcluded[i] = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tlet shouldIndentNextCharacter = options.indentStart !== false;\n\t\tconst replacer = (match) => {\n\t\t\tif (shouldIndentNextCharacter) return `${indentStr}${match}`;\n\t\t\tshouldIndentNextCharacter = true;\n\t\t\treturn match;\n\t\t};\n\n\t\tthis.intro = this.intro.replace(pattern, replacer);\n\n\t\tlet charIndex = 0;\n\t\tlet chunk = this.firstChunk;\n\n\t\twhile (chunk) {\n\t\t\tconst end = chunk.end;\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\tchunk.content = chunk.content.replace(pattern, replacer);\n\n\t\t\t\t\tif (chunk.content.length) {\n\t\t\t\t\t\tshouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\\n';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcharIndex = chunk.start;\n\n\t\t\t\twhile (charIndex < end) {\n\t\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\t\tconst char = this.original[charIndex];\n\n\t\t\t\t\t\tif (char === '\\n') {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = true;\n\t\t\t\t\t\t} else if (char !== '\\r' && shouldIndentNextCharacter) {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = false;\n\n\t\t\t\t\t\t\tif (charIndex === chunk.start) {\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis._splitChunk(chunk, charIndex);\n\t\t\t\t\t\t\t\tchunk = chunk.next;\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcharIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcharIndex = chunk.end;\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tthis.outro = this.outro.replace(pattern, replacer);\n\n\t\treturn this;\n\t}\n\n\tinsert() {\n\t\tthrow new Error(\n\t\t\t'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)',\n\t\t);\n\t}\n\n\tinsertLeft(index, content) {\n\t\tif (!warned.insertLeft) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead',\n\t\t\t);\n\t\t\twarned.insertLeft = true;\n\t\t}\n\n\t\treturn this.appendLeft(index, content);\n\t}\n\n\tinsertRight(index, content) {\n\t\tif (!warned.insertRight) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead',\n\t\t\t);\n\t\t\twarned.insertRight = true;\n\t\t}\n\n\t\treturn this.prependRight(index, content);\n\t}\n\n\tmove(start, end, index) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\t\tindex = index + this.offset;\n\n\t\tif (index >= start && index <= end) throw new Error('Cannot move a selection inside itself');\n\n\t\tif (DEBUG) this.stats.time('move');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\t\tthis._split(index);\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tconst oldLeft = first.previous;\n\t\tconst oldRight = last.next;\n\n\t\tconst newRight = this.byStart[index];\n\t\tif (!newRight && last === this.lastChunk) return this;\n\t\tconst newLeft = newRight ? newRight.previous : this.lastChunk;\n\n\t\tif (oldLeft) oldLeft.next = oldRight;\n\t\tif (oldRight) oldRight.previous = oldLeft;\n\n\t\tif (newLeft) newLeft.next = first;\n\t\tif (newRight) newRight.previous = last;\n\n\t\tif (!first.previous) this.firstChunk = last.next;\n\t\tif (!last.next) {\n\t\t\tthis.lastChunk = first.previous;\n\t\t\tthis.lastChunk.next = null;\n\t\t}\n\n\t\tfirst.previous = newLeft;\n\t\tlast.next = newRight || null;\n\n\t\tif (!newLeft) this.firstChunk = first;\n\t\tif (!newRight) this.lastChunk = last;\n\n\t\tif (DEBUG) this.stats.timeEnd('move');\n\t\treturn this;\n\t}\n\n\toverwrite(start, end, content, options) {\n\t\toptions = options || {};\n\t\treturn this.update(start, end, content, { ...options, overwrite: !options.contentOnly });\n\t}\n\n\tupdate(start, end, content, options) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('replacement content must be a string');\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (end > this.original.length) throw new Error('end is out of bounds');\n\t\tif (start === end)\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',\n\t\t\t);\n\n\t\tif (DEBUG) this.stats.time('overwrite');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tif (options === true) {\n\t\t\tif (!warned.storeName) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string',\n\t\t\t\t);\n\t\t\t\twarned.storeName = true;\n\t\t\t}\n\n\t\t\toptions = { storeName: true };\n\t\t}\n\t\tconst storeName = options !== undefined ? options.storeName : false;\n\t\tconst overwrite = options !== undefined ? options.overwrite : false;\n\n\t\tif (storeName) {\n\t\t\tconst original = this.original.slice(start, end);\n\t\t\tObject.defineProperty(this.storedNames, original, {\n\t\t\t\twritable: true,\n\t\t\t\tvalue: true,\n\t\t\t\tenumerable: true,\n\t\t\t});\n\t\t}\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tif (first) {\n\t\t\tlet chunk = first;\n\t\t\twhile (chunk !== last) {\n\t\t\t\tif (chunk.next !== this.byStart[chunk.end]) {\n\t\t\t\t\tthrow new Error('Cannot overwrite across a split point');\n\t\t\t\t}\n\t\t\t\tchunk = chunk.next;\n\t\t\t\tchunk.edit('', false);\n\t\t\t}\n\n\t\t\tfirst.edit(content, storeName, !overwrite);\n\t\t} else {\n\t\t\t// must be inserting at the end\n\t\t\tconst newChunk = new Chunk(start, end, '').edit(content, storeName);\n\n\t\t\t// TODO last chunk in the array may not be the last chunk, if it's moved...\n\t\t\tlast.next = newChunk;\n\t\t\tnewChunk.previous = last;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('overwrite');\n\t\treturn this;\n\t}\n\n\tprepend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.intro = content + this.intro;\n\t\treturn this;\n\t}\n\n\tprependLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependLeft(content);\n\t\t} else {\n\t\t\tthis.intro = content + this.intro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tprependRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependRight(content);\n\t\t} else {\n\t\t\tthis.outro = content + this.outro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tremove(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('remove');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.intro = '';\n\t\t\tchunk.outro = '';\n\t\t\tchunk.edit('');\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('remove');\n\t\treturn this;\n\t}\n\n\treset(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('reset');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.reset();\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('reset');\n\t\treturn this;\n\t}\n\n\tlastChar() {\n\t\tif (this.outro.length) return this.outro[this.outro.length - 1];\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];\n\t\t\tif (chunk.content.length) return chunk.content[chunk.content.length - 1];\n\t\t\tif (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];\n\t\t} while ((chunk = chunk.previous));\n\t\tif (this.intro.length) return this.intro[this.intro.length - 1];\n\t\treturn '';\n\t}\n\n\tlastLine() {\n\t\tlet lineIndex = this.outro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.outro.substr(lineIndex + 1);\n\t\tlet lineStr = this.outro;\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length > 0) {\n\t\t\t\tlineIndex = chunk.outro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.outro + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.content.length > 0) {\n\t\t\t\tlineIndex = chunk.content.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.content + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.intro.length > 0) {\n\t\t\t\tlineIndex = chunk.intro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.intro + lineStr;\n\t\t\t}\n\t\t} while ((chunk = chunk.previous));\n\t\tlineIndex = this.intro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;\n\t\treturn this.intro + lineStr;\n\t}\n\n\tslice(start = 0, end = this.original.length - this.offset) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tlet result = '';\n\n\t\t// find start chunk\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk && (chunk.start > start || chunk.end <= start)) {\n\t\t\t// found end chunk before start\n\t\t\tif (chunk.start < end && chunk.end >= end) {\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tif (chunk && chunk.edited && chunk.start !== start)\n\t\t\tthrow new Error(`Cannot use replaced character ${start} as slice start anchor.`);\n\n\t\tconst startChunk = chunk;\n\t\twhile (chunk) {\n\t\t\tif (chunk.intro && (startChunk !== chunk || chunk.start === start)) {\n\t\t\t\tresult += chunk.intro;\n\t\t\t}\n\n\t\t\tconst containsEnd = chunk.start < end && chunk.end >= end;\n\t\t\tif (containsEnd && chunk.edited && chunk.end !== end)\n\t\t\t\tthrow new Error(`Cannot use replaced character ${end} as slice end anchor.`);\n\n\t\t\tconst sliceStart = startChunk === chunk ? start - chunk.start : 0;\n\t\t\tconst sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;\n\n\t\t\tresult += chunk.content.slice(sliceStart, sliceEnd);\n\n\t\t\tif (chunk.outro && (!containsEnd || chunk.end === end)) {\n\t\t\t\tresult += chunk.outro;\n\t\t\t}\n\n\t\t\tif (containsEnd) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// TODO deprecate this? not really very useful\n\tsnip(start, end) {\n\t\tconst clone = this.clone();\n\t\tclone.remove(0, start);\n\t\tclone.remove(end, clone.original.length);\n\n\t\treturn clone;\n\t}\n\n\t_split(index) {\n\t\tif (this.byStart[index] || this.byEnd[index]) return;\n\n\t\tif (DEBUG) this.stats.time('_split');\n\n\t\tlet chunk = this.lastSearchedChunk;\n\t\tlet previousChunk = chunk;\n\t\tconst searchForward = index > chunk.end;\n\n\t\twhile (chunk) {\n\t\t\tif (chunk.contains(index)) return this._splitChunk(chunk, index);\n\n\t\t\tchunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];\n\n\t\t\t// Prevent infinite loop (e.g. via empty chunks, where start === end)\n\t\t\tif (chunk === previousChunk) return;\n\n\t\t\tpreviousChunk = chunk;\n\t\t}\n\t}\n\n\t_splitChunk(chunk, index) {\n\t\tif (chunk.edited && chunk.content.length) {\n\t\t\t// zero-length edited chunks are a special case (overlapping replacements)\n\t\t\tconst loc = getLocator(this.original)(index);\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – \"${chunk.original}\")`,\n\t\t\t);\n\t\t}\n\n\t\tconst newChunk = chunk.split(index);\n\n\t\tthis.byEnd[index] = chunk;\n\t\tthis.byStart[index] = newChunk;\n\t\tthis.byEnd[newChunk.end] = newChunk;\n\n\t\tif (chunk === this.lastChunk) this.lastChunk = newChunk;\n\n\t\tthis.lastSearchedChunk = chunk;\n\t\tif (DEBUG) this.stats.timeEnd('_split');\n\t\treturn true;\n\t}\n\n\ttoString() {\n\t\tlet str = this.intro;\n\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk) {\n\t\t\tstr += chunk.toString();\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn str + this.outro;\n\t}\n\n\tisEmpty() {\n\t\tlet chunk = this.firstChunk;\n\t\tdo {\n\t\t\tif (\n\t\t\t\t(chunk.intro.length && chunk.intro.trim()) ||\n\t\t\t\t(chunk.content.length && chunk.content.trim()) ||\n\t\t\t\t(chunk.outro.length && chunk.outro.trim())\n\t\t\t)\n\t\t\t\treturn false;\n\t\t} while ((chunk = chunk.next));\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\tlet chunk = this.firstChunk;\n\t\tlet length = 0;\n\t\tdo {\n\t\t\tlength += chunk.intro.length + chunk.content.length + chunk.outro.length;\n\t\t} while ((chunk = chunk.next));\n\t\treturn length;\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimEndAborted(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tlet chunk = this.lastChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimEnd(rx);\n\n\t\t\t// if chunk was trimmed, we have a new lastChunk\n\t\t\tif (chunk.end !== end) {\n\t\t\t\tif (this.lastChunk === chunk) {\n\t\t\t\t\tthis.lastChunk = chunk.next;\n\t\t\t\t}\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.previous;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimEnd(charType) {\n\t\tthis.trimEndAborted(charType);\n\t\treturn this;\n\t}\n\ttrimStartAborted(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tlet chunk = this.firstChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimStart(rx);\n\n\t\t\tif (chunk.end !== end) {\n\t\t\t\t// special case...\n\t\t\t\tif (chunk === this.lastChunk) this.lastChunk = chunk.next;\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.next;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimStart(charType) {\n\t\tthis.trimStartAborted(charType);\n\t\treturn this;\n\t}\n\n\thasChanged() {\n\t\treturn this.original !== this.toString();\n\t}\n\n\t_replaceRegexp(searchValue, replacement) {\n\t\tfunction getReplacement(match, str) {\n\t\t\tif (typeof replacement === 'string') {\n\t\t\t\treturn replacement.replace(/\\$(\\$|&|\\d+)/g, (_, i) => {\n\t\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter\n\t\t\t\t\tif (i === '$') return '$';\n\t\t\t\t\tif (i === '&') return match[0];\n\t\t\t\t\tconst num = +i;\n\t\t\t\t\tif (num < match.length) return match[+i];\n\t\t\t\t\treturn `$${i}`;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treturn replacement(...match, match.index, str, match.groups);\n\t\t\t}\n\t\t}\n\t\tfunction matchAll(re, str) {\n\t\t\tlet match;\n\t\t\tconst matches = [];\n\t\t\twhile ((match = re.exec(str))) {\n\t\t\t\tmatches.push(match);\n\t\t\t}\n\t\t\treturn matches;\n\t\t}\n\t\tif (searchValue.global) {\n\t\t\tconst matches = matchAll(searchValue, this.original);\n\t\t\tmatches.forEach((match) => {\n\t\t\t\tif (match.index != null) {\n\t\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tconst match = this.original.match(searchValue);\n\t\t\tif (match && match.index != null) {\n\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t_replaceString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst index = original.indexOf(string);\n\n\t\tif (index !== -1) {\n\t\t\tthis.overwrite(index, index + string.length, replacement);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplace(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceString(searchValue, replacement);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n\n\t_replaceAllString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst stringLength = string.length;\n\t\tfor (\n\t\t\tlet index = original.indexOf(string);\n\t\t\tindex !== -1;\n\t\t\tindex = original.indexOf(string, index + stringLength)\n\t\t) {\n\t\t\tconst previous = original.slice(index, index + stringLength);\n\t\t\tif (previous !== replacement) this.overwrite(index, index + stringLength, replacement);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplaceAll(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceAllString(searchValue, replacement);\n\t\t}\n\n\t\tif (!searchValue.global) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'MagicString.prototype.replaceAll called with a non-global RegExp argument',\n\t\t\t);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n}\n","import MagicString from './MagicString.js';\nimport SourceMap from './SourceMap.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\n\nconst hasOwnProp = Object.prototype.hasOwnProperty;\n\nexport default class Bundle {\n\tconstructor(options = {}) {\n\t\tthis.intro = options.intro || '';\n\t\tthis.separator = options.separator !== undefined ? options.separator : '\\n';\n\t\tthis.sources = [];\n\t\tthis.uniqueSources = [];\n\t\tthis.uniqueSourceIndexByFilename = {};\n\t}\n\n\taddSource(source) {\n\t\tif (source instanceof MagicString) {\n\t\t\treturn this.addSource({\n\t\t\t\tcontent: source,\n\t\t\t\tfilename: source.filename,\n\t\t\t\tseparator: this.separator,\n\t\t\t});\n\t\t}\n\n\t\tif (!isObject(source) || !source.content) {\n\t\t\tthrow new Error(\n\t\t\t\t'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`',\n\t\t\t);\n\t\t}\n\n\t\t['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => {\n\t\t\tif (!hasOwnProp.call(source, option)) source[option] = source.content[option];\n\t\t});\n\n\t\tif (source.separator === undefined) {\n\t\t\t// TODO there's a bunch of this sort of thing, needs cleaning up\n\t\t\tsource.separator = this.separator;\n\t\t}\n\n\t\tif (source.filename) {\n\t\t\tif (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) {\n\t\t\t\tthis.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length;\n\t\t\t\tthis.uniqueSources.push({ filename: source.filename, content: source.content.original });\n\t\t\t} else {\n\t\t\t\tconst uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]];\n\t\t\t\tif (source.content.original !== uniqueSource.content) {\n\t\t\t\t\tthrow new Error(`Illegal source: same filename (${source.filename}), different contents`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.sources.push(source);\n\t\treturn this;\n\t}\n\n\tappend(str, options) {\n\t\tthis.addSource({\n\t\t\tcontent: new MagicString(str),\n\t\t\tseparator: (options && options.separator) || '',\n\t\t});\n\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst bundle = new Bundle({\n\t\t\tintro: this.intro,\n\t\t\tseparator: this.separator,\n\t\t});\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tbundle.addSource({\n\t\t\t\tfilename: source.filename,\n\t\t\t\tcontent: source.content.clone(),\n\t\t\t\tseparator: source.separator,\n\t\t\t});\n\t\t});\n\n\t\treturn bundle;\n\t}\n\n\tgenerateDecodedMap(options = {}) {\n\t\tconst names = [];\n\t\tlet x_google_ignoreList = undefined;\n\t\tthis.sources.forEach((source) => {\n\t\t\tObject.keys(source.content.storedNames).forEach((name) => {\n\t\t\t\tif (!~names.indexOf(name)) names.push(name);\n\t\t\t});\n\t\t});\n\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tif (i > 0) {\n\t\t\t\tmappings.advance(this.separator);\n\t\t\t}\n\n\t\t\tconst sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1;\n\t\t\tconst magicString = source.content;\n\t\t\tconst locate = getLocator(magicString.original);\n\n\t\t\tif (magicString.intro) {\n\t\t\t\tmappings.advance(magicString.intro);\n\t\t\t}\n\n\t\t\tmagicString.firstChunk.eachNext((chunk) => {\n\t\t\t\tconst loc = locate(chunk.start);\n\n\t\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\t\tif (source.filename) {\n\t\t\t\t\tif (chunk.edited) {\n\t\t\t\t\t\tmappings.addEdit(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk.content,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmappings.addUneditedChunk(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\tmagicString.original,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tmagicString.sourcemapLocations,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmappings.advance(chunk.content);\n\t\t\t\t}\n\n\t\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t\t});\n\n\t\t\tif (magicString.outro) {\n\t\t\t\tmappings.advance(magicString.outro);\n\t\t\t}\n\n\t\t\tif (source.ignoreList && sourceIndex !== -1) {\n\t\t\t\tif (x_google_ignoreList === undefined) {\n\t\t\t\t\tx_google_ignoreList = [];\n\t\t\t\t}\n\t\t\t\tx_google_ignoreList.push(sourceIndex);\n\t\t\t}\n\t\t});\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.file ? getRelativePath(options.file, source.filename) : source.filename;\n\t\t\t}),\n\t\t\tsourcesContent: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.includeContent ? source.content : null;\n\t\t\t}),\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\tgetIndentString() {\n\t\tconst indentStringCounts = {};\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tconst indentStr = source.content._getRawIndentString();\n\n\t\t\tif (indentStr === null) return;\n\n\t\t\tif (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0;\n\t\t\tindentStringCounts[indentStr] += 1;\n\t\t});\n\n\t\treturn (\n\t\t\tObject.keys(indentStringCounts).sort((a, b) => {\n\t\t\t\treturn indentStringCounts[a] - indentStringCounts[b];\n\t\t\t})[0] || '\\t'\n\t\t);\n\t}\n\n\tindent(indentStr) {\n\t\tif (!arguments.length) {\n\t\t\tindentStr = this.getIndentString();\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\tlet trailingNewline = !this.intro || this.intro.slice(-1) === '\\n';\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\tconst indentStart = trailingNewline || (i > 0 && /\\r?\\n$/.test(separator));\n\n\t\t\tsource.content.indent(indentStr, {\n\t\t\t\texclude: source.indentExclusionRanges,\n\t\t\t\tindentStart, //: trailingNewline || /\\r?\\n$/.test( separator ) //true///\\r?\\n/.test( separator )\n\t\t\t});\n\n\t\t\ttrailingNewline = source.content.lastChar() === '\\n';\n\t\t});\n\n\t\tif (this.intro) {\n\t\t\tthis.intro =\n\t\t\t\tindentStr +\n\t\t\t\tthis.intro.replace(/^[^\\n]/gm, (match, index) => {\n\t\t\t\t\treturn index > 0 ? indentStr + match : match;\n\t\t\t\t});\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprepend(str) {\n\t\tthis.intro = str + this.intro;\n\t\treturn this;\n\t}\n\n\ttoString() {\n\t\tconst body = this.sources\n\t\t\t.map((source, i) => {\n\t\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\t\tconst str = (i > 0 ? separator : '') + source.content.toString();\n\n\t\t\t\treturn str;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn this.intro + body;\n\t}\n\n\tisEmpty() {\n\t\tif (this.intro.length && this.intro.trim()) return false;\n\t\tif (this.sources.some((source) => !source.content.isEmpty())) return false;\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\treturn this.sources.reduce(\n\t\t\t(length, source) => length + source.content.length(),\n\t\t\tthis.intro.length,\n\t\t);\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimStart(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\t\tthis.intro = this.intro.replace(rx, '');\n\n\t\tif (!this.intro) {\n\t\t\tlet source;\n\t\t\tlet i = 0;\n\n\t\t\tdo {\n\t\t\t\tsource = this.sources[i++];\n\t\t\t\tif (!source) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} while (!source.content.trimStartAborted(charType));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\ttrimEnd(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tlet source;\n\t\tlet i = this.sources.length - 1;\n\n\t\tdo {\n\t\t\tsource = this.sources[i--];\n\t\t\tif (!source) {\n\t\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (!source.content.trimEndAborted(charType));\n\n\t\treturn this;\n\t}\n}\n","import MagicString from './MagicString.js';\nimport Bundle from './Bundle.js';\nimport SourceMap from './SourceMap.js';\n\nMagicString.Bundle = Bundle;\nMagicString.SourceMap = SourceMap;\nMagicString.default = MagicString; // work around TypeScript bug https://github.com/Rich-Harris/magic-string/pull/121\n\nexport default MagicString;\n"],"names":["encode"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/magic-string/dist/magic-string.es.d.mts b/node_modules/magic-string/dist/magic-string.es.d.mts new file mode 100644 index 0000000000..76cc537d1c --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.es.d.mts @@ -0,0 +1,289 @@ +export interface BundleOptions { + intro?: string; + separator?: string; +} + +export interface SourceMapOptions { + /** + * Whether the mapping should be high-resolution. + * Hi-res mappings map every single character, meaning (for example) your devtools will always + * be able to pinpoint the exact location of function calls and so on. + * With lo-res mappings, devtools may only be able to identify the correct + * line - but they're quicker to generate and less bulky. + * You can also set `"boundary"` to generate a semi-hi-res mappings segmented per word boundary + * instead of per character, suitable for string semantics that are separated by words. + * If sourcemap locations have been specified with s.addSourceMapLocation(), they will be used here. + */ + hires?: boolean | 'boundary'; + /** + * The filename where you plan to write the sourcemap. + */ + file?: string; + /** + * The filename of the file containing the original source. + */ + source?: string; + /** + * Whether to include the original content in the map's sourcesContent array. + */ + includeContent?: boolean; +} + +export type SourceMapSegment = + | [number] + | [number, number, number, number] + | [number, number, number, number, number]; + +export interface DecodedSourceMap { + file: string; + sources: string[]; + sourcesContent?: string[]; + names: string[]; + mappings: SourceMapSegment[][]; + x_google_ignoreList?: number[]; +} + +export class SourceMap { + constructor(properties: DecodedSourceMap); + + version: number; + file: string; + sources: string[]; + sourcesContent?: string[]; + names: string[]; + mappings: string; + x_google_ignoreList?: number[]; + debugId?: string; + + /** + * Returns the equivalent of `JSON.stringify(map)` + */ + toString(): string; + /** + * Returns a DataURI containing the sourcemap. Useful for doing this sort of thing: + * `generateMap(options?: SourceMapOptions): SourceMap;` + */ + toUrl(): string; +} + +export class Bundle { + constructor(options?: BundleOptions); + /** + * Adds the specified source to the bundle, which can either be a `MagicString` object directly, + * or an options object that holds a magic string `content` property and optionally provides + * a `filename` for the source within the bundle, as well as an optional `ignoreList` hint + * (which defaults to `false`). The `filename` is used when constructing the source map for the + * bundle, to identify this `source` in the source map's `sources` field. The `ignoreList` hint + * is used to populate the `x_google_ignoreList` extension field in the source map, which is a + * mechanism for tools to signal to debuggers that certain sources should be ignored by default + * (depending on user preferences). + */ + addSource( + source: MagicString | { filename?: string; content: MagicString; ignoreList?: boolean }, + ): this; + append(str: string, options?: BundleOptions): this; + clone(): this; + generateMap( + options?: SourceMapOptions, + ): Omit & { sourcesContent: Array }; + generateDecodedMap( + options?: SourceMapOptions, + ): Omit & { sourcesContent: Array }; + getIndentString(): string; + indent(indentStr?: string): this; + indentExclusionRanges: ExclusionRange | Array; + prepend(str: string): this; + toString(): string; + trimLines(): this; + trim(charType?: string): this; + trimStart(charType?: string): this; + trimEnd(charType?: string): this; + isEmpty(): boolean; + length(): number; +} + +export type ExclusionRange = [number, number]; + +export interface MagicStringOptions { + filename?: string; + indentExclusionRanges?: ExclusionRange | Array; + offset?: number; +} + +export interface IndentOptions { + exclude?: ExclusionRange | Array; + indentStart?: boolean; +} + +export interface OverwriteOptions { + storeName?: boolean; + contentOnly?: boolean; +} + +export interface UpdateOptions { + storeName?: boolean; + overwrite?: boolean; +} + +export default class MagicString { + constructor(str: string, options?: MagicStringOptions); + /** + * Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is false. + */ + addSourcemapLocation(char: number): void; + /** + * Appends the specified content to the end of the string. + */ + append(content: string): this; + /** + * Appends the specified content at the index in the original string. + * If a range *ending* with index is subsequently moved, the insert will be moved with it. + * See also `s.prependLeft(...)`. + */ + appendLeft(index: number, content: string): this; + /** + * Appends the specified content at the index in the original string. + * If a range *starting* with index is subsequently moved, the insert will be moved with it. + * See also `s.prependRight(...)`. + */ + appendRight(index: number, content: string): this; + /** + * Does what you'd expect. + */ + clone(): this; + /** + * Generates a version 3 sourcemap. + */ + generateMap(options?: SourceMapOptions): SourceMap; + /** + * Generates a sourcemap object with raw mappings in array form, rather than encoded as a string. + * Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead. + */ + generateDecodedMap(options?: SourceMapOptions): DecodedSourceMap; + getIndentString(): string; + + /** + * Prefixes each line of the string with prefix. + * If prefix is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. + */ + indent(options?: IndentOptions): this; + /** + * Prefixes each line of the string with prefix. + * If prefix is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. + * + * The options argument can have an exclude property, which is an array of [start, end] character ranges. + * These ranges will be excluded from the indentation - useful for (e.g.) multiline strings. + */ + indent(indentStr?: string, options?: IndentOptions): this; + indentExclusionRanges: ExclusionRange | Array; + + /** + * Moves the characters from `start` and `end` to `index`. + */ + move(start: number, end: number, index: number): this; + /** + * Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in + * that range. The same restrictions as `s.remove()` apply. + * + * The fourth argument is optional. It can have a storeName property — if true, the original name will be stored + * for later inclusion in a sourcemap's names array — and a contentOnly property which determines whether only + * the content is overwritten, or anything that was appended/prepended to the range as well. + * + * It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content. + */ + overwrite( + start: number, + end: number, + content: string, + options?: boolean | OverwriteOptions, + ): this; + /** + * Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply. + * + * The fourth argument is optional. It can have a storeName property — if true, the original name will be stored + * for later inclusion in a sourcemap's names array — and an overwrite property which determines whether only + * the content is overwritten, or anything that was appended/prepended to the range as well. + */ + update(start: number, end: number, content: string, options?: boolean | UpdateOptions): this; + /** + * Prepends the string with the specified content. + */ + prepend(content: string): this; + /** + * Same as `s.appendLeft(...)`, except that the inserted content will go *before* any previous appends or prepends at index + */ + prependLeft(index: number, content: string): this; + /** + * Same as `s.appendRight(...)`, except that the inserted content will go *before* any previous appends or prepends at `index` + */ + prependRight(index: number, content: string): this; + /** + * Removes the characters from `start` to `end` (of the original string, **not** the generated string). + * Removing the same content twice, or making removals that partially overlap, will cause an error. + */ + remove(start: number, end: number): this; + /** + * Reset the modified characters from `start` to `end` (of the original string, **not** the generated string). + */ + reset(start: number, end: number): this; + /** + * Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string. + * Throws error if the indices are for characters that were already removed. + */ + slice(start: number, end: number): string; + /** + * Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed. + */ + snip(start: number, end: number): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end. + */ + trim(charType?: string): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start. + */ + trimStart(charType?: string): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end. + */ + trimEnd(charType?: string): this; + /** + * Removes empty lines from the start and end. + */ + trimLines(): this; + /** + * String replacement with RegExp or string. + */ + replace( + regex: RegExp | string, + replacement: string | ((substring: string, ...args: any[]) => string), + ): this; + /** + * Same as `s.replace`, but replace all matched strings instead of just one. + */ + replaceAll( + regex: RegExp | string, + replacement: string | ((substring: string, ...args: any[]) => string), + ): this; + + lastChar(): string; + lastLine(): string; + /** + * Returns true if the resulting source is empty (disregarding white space). + */ + isEmpty(): boolean; + length(): number; + + /** + * Indicates if the string has been changed. + */ + hasChanged(): boolean; + + original: string; + /** + * Returns the generated string. + */ + toString(): string; + + offset: number; +} diff --git a/node_modules/magic-string/dist/magic-string.es.mjs b/node_modules/magic-string/dist/magic-string.es.mjs new file mode 100644 index 0000000000..9f9ca591f0 --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.es.mjs @@ -0,0 +1,1575 @@ +import { encode } from '@jridgewell/sourcemap-codec'; + +class BitSet { + constructor(arg) { + this.bits = arg instanceof BitSet ? arg.bits.slice() : []; + } + + add(n) { + this.bits[n >> 5] |= 1 << (n & 31); + } + + has(n) { + return !!(this.bits[n >> 5] & (1 << (n & 31))); + } +} + +class Chunk { + constructor(start, end, content) { + this.start = start; + this.end = end; + this.original = content; + + this.intro = ''; + this.outro = ''; + + this.content = content; + this.storeName = false; + this.edited = false; + + { + this.previous = null; + this.next = null; + } + } + + appendLeft(content) { + this.outro += content; + } + + appendRight(content) { + this.intro = this.intro + content; + } + + clone() { + const chunk = new Chunk(this.start, this.end, this.original); + + chunk.intro = this.intro; + chunk.outro = this.outro; + chunk.content = this.content; + chunk.storeName = this.storeName; + chunk.edited = this.edited; + + return chunk; + } + + contains(index) { + return this.start < index && index < this.end; + } + + eachNext(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.next; + } + } + + eachPrevious(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.previous; + } + } + + edit(content, storeName, contentOnly) { + this.content = content; + if (!contentOnly) { + this.intro = ''; + this.outro = ''; + } + this.storeName = storeName; + + this.edited = true; + + return this; + } + + prependLeft(content) { + this.outro = content + this.outro; + } + + prependRight(content) { + this.intro = content + this.intro; + } + + reset() { + this.intro = ''; + this.outro = ''; + if (this.edited) { + this.content = this.original; + this.storeName = false; + this.edited = false; + } + } + + split(index) { + const sliceIndex = index - this.start; + + const originalBefore = this.original.slice(0, sliceIndex); + const originalAfter = this.original.slice(sliceIndex); + + this.original = originalBefore; + + const newChunk = new Chunk(index, this.end, originalAfter); + newChunk.outro = this.outro; + this.outro = ''; + + this.end = index; + + if (this.edited) { + // after split we should save the edit content record into the correct chunk + // to make sure sourcemap correct + // For example: + // ' test'.trim() + // split -> ' ' + 'test' + // ✔️ edit -> '' + 'test' + // ✖️ edit -> 'test' + '' + // TODO is this block necessary?... + newChunk.edit('', false); + this.content = ''; + } else { + this.content = originalBefore; + } + + newChunk.next = this.next; + if (newChunk.next) newChunk.next.previous = newChunk; + newChunk.previous = this; + this.next = newChunk; + + return newChunk; + } + + toString() { + return this.intro + this.content + this.outro; + } + + trimEnd(rx) { + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + this.split(this.start + trimmed.length).edit('', undefined, true); + if (this.edited) { + // save the change, if it has been edited + this.edit(trimmed, this.storeName, true); + } + } + return true; + } else { + this.edit('', undefined, true); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + } + } + + trimStart(rx) { + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + const newChunk = this.split(this.end - trimmed.length); + if (this.edited) { + // save the change, if it has been edited + newChunk.edit(trimmed, this.storeName, true); + } + this.edit('', undefined, true); + } + return true; + } else { + this.edit('', undefined, true); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + } + } +} + +function getBtoa() { + if (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') { + return (str) => globalThis.btoa(unescape(encodeURIComponent(str))); + } else if (typeof Buffer === 'function') { + return (str) => Buffer.from(str, 'utf-8').toString('base64'); + } else { + return () => { + throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.'); + }; + } +} + +const btoa = /*#__PURE__*/ getBtoa(); + +class SourceMap { + constructor(properties) { + this.version = 3; + this.file = properties.file; + this.sources = properties.sources; + this.sourcesContent = properties.sourcesContent; + this.names = properties.names; + this.mappings = encode(properties.mappings); + if (typeof properties.x_google_ignoreList !== 'undefined') { + this.x_google_ignoreList = properties.x_google_ignoreList; + } + if (typeof properties.debugId !== 'undefined') { + this.debugId = properties.debugId; + } + } + + toString() { + return JSON.stringify(this); + } + + toUrl() { + return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString()); + } +} + +function guessIndent(code) { + const lines = code.split('\n'); + + const tabbed = lines.filter((line) => /^\t+/.test(line)); + const spaced = lines.filter((line) => /^ {2,}/.test(line)); + + if (tabbed.length === 0 && spaced.length === 0) { + return null; + } + + // More lines tabbed than spaced? Assume tabs, and + // default to tabs in the case of a tie (or nothing + // to go on) + if (tabbed.length >= spaced.length) { + return '\t'; + } + + // Otherwise, we need to guess the multiple + const min = spaced.reduce((previous, current) => { + const numSpaces = /^ +/.exec(current)[0].length; + return Math.min(numSpaces, previous); + }, Infinity); + + return new Array(min + 1).join(' '); +} + +function getRelativePath(from, to) { + const fromParts = from.split(/[/\\]/); + const toParts = to.split(/[/\\]/); + + fromParts.pop(); // get dirname + + while (fromParts[0] === toParts[0]) { + fromParts.shift(); + toParts.shift(); + } + + if (fromParts.length) { + let i = fromParts.length; + while (i--) fromParts[i] = '..'; + } + + return fromParts.concat(toParts).join('/'); +} + +const toString = Object.prototype.toString; + +function isObject(thing) { + return toString.call(thing) === '[object Object]'; +} + +function getLocator(source) { + const originalLines = source.split('\n'); + const lineOffsets = []; + + for (let i = 0, pos = 0; i < originalLines.length; i++) { + lineOffsets.push(pos); + pos += originalLines[i].length + 1; + } + + return function locate(index) { + let i = 0; + let j = lineOffsets.length; + while (i < j) { + const m = (i + j) >> 1; + if (index < lineOffsets[m]) { + j = m; + } else { + i = m + 1; + } + } + const line = i - 1; + const column = index - lineOffsets[line]; + return { line, column }; + }; +} + +const wordRegex = /\w/; + +class Mappings { + constructor(hires) { + this.hires = hires; + this.generatedCodeLine = 0; + this.generatedCodeColumn = 0; + this.raw = []; + this.rawSegments = this.raw[this.generatedCodeLine] = []; + this.pending = null; + } + + addEdit(sourceIndex, content, loc, nameIndex) { + if (content.length) { + const contentLengthMinusOne = content.length - 1; + let contentLineEnd = content.indexOf('\n', 0); + let previousContentLineEnd = -1; + // Loop through each line in the content and add a segment, but stop if the last line is empty, + // else code afterwards would fill one line too many + while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + + previousContentLineEnd = contentLineEnd; + contentLineEnd = content.indexOf('\n', contentLineEnd + 1); + } + + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.advance(content.slice(previousContentLineEnd + 1)); + } else if (this.pending) { + this.rawSegments.push(this.pending); + this.advance(content); + } + + this.pending = null; + } + + addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) { + let originalCharIndex = chunk.start; + let first = true; + // when iterating each char, check if it's in a word boundary + let charInHiresBoundary = false; + + while (originalCharIndex < chunk.end) { + if (original[originalCharIndex] === '\n') { + loc.line += 1; + loc.column = 0; + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + first = true; + charInHiresBoundary = false; + } else { + if (this.hires || first || sourcemapLocations.has(originalCharIndex)) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + + if (this.hires === 'boundary') { + // in hires "boundary", group segments per word boundary than per char + if (wordRegex.test(original[originalCharIndex])) { + // for first char in the boundary found, start the boundary by pushing a segment + if (!charInHiresBoundary) { + this.rawSegments.push(segment); + charInHiresBoundary = true; + } + } else { + // for non-word char, end the boundary by pushing a segment + this.rawSegments.push(segment); + charInHiresBoundary = false; + } + } else { + this.rawSegments.push(segment); + } + } + + loc.column += 1; + this.generatedCodeColumn += 1; + first = false; + } + + originalCharIndex += 1; + } + + this.pending = null; + } + + advance(str) { + if (!str) return; + + const lines = str.split('\n'); + + if (lines.length > 1) { + for (let i = 0; i < lines.length - 1; i++) { + this.generatedCodeLine++; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + } + this.generatedCodeColumn = 0; + } + + this.generatedCodeColumn += lines[lines.length - 1].length; + } +} + +const n = '\n'; + +const warned = { + insertLeft: false, + insertRight: false, + storeName: false, +}; + +class MagicString { + constructor(string, options = {}) { + const chunk = new Chunk(0, string.length, string); + + Object.defineProperties(this, { + original: { writable: true, value: string }, + outro: { writable: true, value: '' }, + intro: { writable: true, value: '' }, + firstChunk: { writable: true, value: chunk }, + lastChunk: { writable: true, value: chunk }, + lastSearchedChunk: { writable: true, value: chunk }, + byStart: { writable: true, value: {} }, + byEnd: { writable: true, value: {} }, + filename: { writable: true, value: options.filename }, + indentExclusionRanges: { writable: true, value: options.indentExclusionRanges }, + sourcemapLocations: { writable: true, value: new BitSet() }, + storedNames: { writable: true, value: {} }, + indentStr: { writable: true, value: undefined }, + ignoreList: { writable: true, value: options.ignoreList }, + offset: { writable: true, value: options.offset || 0 }, + }); + + this.byStart[0] = chunk; + this.byEnd[string.length] = chunk; + } + + addSourcemapLocation(char) { + this.sourcemapLocations.add(char); + } + + append(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.outro += content; + return this; + } + + appendLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.appendLeft(content); + } else { + this.intro += content; + } + return this; + } + + appendRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.appendRight(content); + } else { + this.outro += content; + } + return this; + } + + clone() { + const cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset }); + + let originalChunk = this.firstChunk; + let clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone()); + + while (originalChunk) { + cloned.byStart[clonedChunk.start] = clonedChunk; + cloned.byEnd[clonedChunk.end] = clonedChunk; + + const nextOriginalChunk = originalChunk.next; + const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone(); + + if (nextClonedChunk) { + clonedChunk.next = nextClonedChunk; + nextClonedChunk.previous = clonedChunk; + + clonedChunk = nextClonedChunk; + } + + originalChunk = nextOriginalChunk; + } + + cloned.lastChunk = clonedChunk; + + if (this.indentExclusionRanges) { + cloned.indentExclusionRanges = this.indentExclusionRanges.slice(); + } + + cloned.sourcemapLocations = new BitSet(this.sourcemapLocations); + + cloned.intro = this.intro; + cloned.outro = this.outro; + + return cloned; + } + + generateDecodedMap(options) { + options = options || {}; + + const sourceIndex = 0; + const names = Object.keys(this.storedNames); + const mappings = new Mappings(options.hires); + + const locate = getLocator(this.original); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: [ + options.source ? getRelativePath(options.file || '', options.source) : options.file || '', + ], + sourcesContent: options.includeContent ? [this.original] : undefined, + names, + mappings: mappings.raw, + x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + _ensureindentStr() { + if (this.indentStr === undefined) { + this.indentStr = guessIndent(this.original); + } + } + + _getRawIndentString() { + this._ensureindentStr(); + return this.indentStr; + } + + getIndentString() { + this._ensureindentStr(); + return this.indentStr === null ? '\t' : this.indentStr; + } + + indent(indentStr, options) { + const pattern = /^[^\r\n]/gm; + + if (isObject(indentStr)) { + options = indentStr; + indentStr = undefined; + } + + if (indentStr === undefined) { + this._ensureindentStr(); + indentStr = this.indentStr || '\t'; + } + + if (indentStr === '') return this; // noop + + options = options || {}; + + // Process exclusion ranges + const isExcluded = {}; + + if (options.exclude) { + const exclusions = + typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude; + exclusions.forEach((exclusion) => { + for (let i = exclusion[0]; i < exclusion[1]; i += 1) { + isExcluded[i] = true; + } + }); + } + + let shouldIndentNextCharacter = options.indentStart !== false; + const replacer = (match) => { + if (shouldIndentNextCharacter) return `${indentStr}${match}`; + shouldIndentNextCharacter = true; + return match; + }; + + this.intro = this.intro.replace(pattern, replacer); + + let charIndex = 0; + let chunk = this.firstChunk; + + while (chunk) { + const end = chunk.end; + + if (chunk.edited) { + if (!isExcluded[charIndex]) { + chunk.content = chunk.content.replace(pattern, replacer); + + if (chunk.content.length) { + shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n'; + } + } + } else { + charIndex = chunk.start; + + while (charIndex < end) { + if (!isExcluded[charIndex]) { + const char = this.original[charIndex]; + + if (char === '\n') { + shouldIndentNextCharacter = true; + } else if (char !== '\r' && shouldIndentNextCharacter) { + shouldIndentNextCharacter = false; + + if (charIndex === chunk.start) { + chunk.prependRight(indentStr); + } else { + this._splitChunk(chunk, charIndex); + chunk = chunk.next; + chunk.prependRight(indentStr); + } + } + } + + charIndex += 1; + } + } + + charIndex = chunk.end; + chunk = chunk.next; + } + + this.outro = this.outro.replace(pattern, replacer); + + return this; + } + + insert() { + throw new Error( + 'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)', + ); + } + + insertLeft(index, content) { + if (!warned.insertLeft) { + console.warn( + 'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead', + ); + warned.insertLeft = true; + } + + return this.appendLeft(index, content); + } + + insertRight(index, content) { + if (!warned.insertRight) { + console.warn( + 'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead', + ); + warned.insertRight = true; + } + + return this.prependRight(index, content); + } + + move(start, end, index) { + start = start + this.offset; + end = end + this.offset; + index = index + this.offset; + + if (index >= start && index <= end) throw new Error('Cannot move a selection inside itself'); + + this._split(start); + this._split(end); + this._split(index); + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + const oldLeft = first.previous; + const oldRight = last.next; + + const newRight = this.byStart[index]; + if (!newRight && last === this.lastChunk) return this; + const newLeft = newRight ? newRight.previous : this.lastChunk; + + if (oldLeft) oldLeft.next = oldRight; + if (oldRight) oldRight.previous = oldLeft; + + if (newLeft) newLeft.next = first; + if (newRight) newRight.previous = last; + + if (!first.previous) this.firstChunk = last.next; + if (!last.next) { + this.lastChunk = first.previous; + this.lastChunk.next = null; + } + + first.previous = newLeft; + last.next = newRight || null; + + if (!newLeft) this.firstChunk = first; + if (!newRight) this.lastChunk = last; + return this; + } + + overwrite(start, end, content, options) { + options = options || {}; + return this.update(start, end, content, { ...options, overwrite: !options.contentOnly }); + } + + update(start, end, content, options) { + start = start + this.offset; + end = end + this.offset; + + if (typeof content !== 'string') throw new TypeError('replacement content must be a string'); + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (end > this.original.length) throw new Error('end is out of bounds'); + if (start === end) + throw new Error( + 'Cannot overwrite a zero-length range – use appendLeft or prependRight instead', + ); + + this._split(start); + this._split(end); + + if (options === true) { + if (!warned.storeName) { + console.warn( + 'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string', + ); + warned.storeName = true; + } + + options = { storeName: true }; + } + const storeName = options !== undefined ? options.storeName : false; + const overwrite = options !== undefined ? options.overwrite : false; + + if (storeName) { + const original = this.original.slice(start, end); + Object.defineProperty(this.storedNames, original, { + writable: true, + value: true, + enumerable: true, + }); + } + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + if (first) { + let chunk = first; + while (chunk !== last) { + if (chunk.next !== this.byStart[chunk.end]) { + throw new Error('Cannot overwrite across a split point'); + } + chunk = chunk.next; + chunk.edit('', false); + } + + first.edit(content, storeName, !overwrite); + } else { + // must be inserting at the end + const newChunk = new Chunk(start, end, '').edit(content, storeName); + + // TODO last chunk in the array may not be the last chunk, if it's moved... + last.next = newChunk; + newChunk.previous = last; + } + return this; + } + + prepend(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.intro = content + this.intro; + return this; + } + + prependLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.prependLeft(content); + } else { + this.intro = content + this.intro; + } + return this; + } + + prependRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.prependRight(content); + } else { + this.outro = content + this.outro; + } + return this; + } + + remove(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.intro = ''; + chunk.outro = ''; + chunk.edit(''); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + reset(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.reset(); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + lastChar() { + if (this.outro.length) return this.outro[this.outro.length - 1]; + let chunk = this.lastChunk; + do { + if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1]; + if (chunk.content.length) return chunk.content[chunk.content.length - 1]; + if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1]; + } while ((chunk = chunk.previous)); + if (this.intro.length) return this.intro[this.intro.length - 1]; + return ''; + } + + lastLine() { + let lineIndex = this.outro.lastIndexOf(n); + if (lineIndex !== -1) return this.outro.substr(lineIndex + 1); + let lineStr = this.outro; + let chunk = this.lastChunk; + do { + if (chunk.outro.length > 0) { + lineIndex = chunk.outro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.outro + lineStr; + } + + if (chunk.content.length > 0) { + lineIndex = chunk.content.lastIndexOf(n); + if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr; + lineStr = chunk.content + lineStr; + } + + if (chunk.intro.length > 0) { + lineIndex = chunk.intro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.intro + lineStr; + } + } while ((chunk = chunk.previous)); + lineIndex = this.intro.lastIndexOf(n); + if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr; + return this.intro + lineStr; + } + + slice(start = 0, end = this.original.length - this.offset) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + let result = ''; + + // find start chunk + let chunk = this.firstChunk; + while (chunk && (chunk.start > start || chunk.end <= start)) { + // found end chunk before start + if (chunk.start < end && chunk.end >= end) { + return result; + } + + chunk = chunk.next; + } + + if (chunk && chunk.edited && chunk.start !== start) + throw new Error(`Cannot use replaced character ${start} as slice start anchor.`); + + const startChunk = chunk; + while (chunk) { + if (chunk.intro && (startChunk !== chunk || chunk.start === start)) { + result += chunk.intro; + } + + const containsEnd = chunk.start < end && chunk.end >= end; + if (containsEnd && chunk.edited && chunk.end !== end) + throw new Error(`Cannot use replaced character ${end} as slice end anchor.`); + + const sliceStart = startChunk === chunk ? start - chunk.start : 0; + const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length; + + result += chunk.content.slice(sliceStart, sliceEnd); + + if (chunk.outro && (!containsEnd || chunk.end === end)) { + result += chunk.outro; + } + + if (containsEnd) { + break; + } + + chunk = chunk.next; + } + + return result; + } + + // TODO deprecate this? not really very useful + snip(start, end) { + const clone = this.clone(); + clone.remove(0, start); + clone.remove(end, clone.original.length); + + return clone; + } + + _split(index) { + if (this.byStart[index] || this.byEnd[index]) return; + + let chunk = this.lastSearchedChunk; + let previousChunk = chunk; + const searchForward = index > chunk.end; + + while (chunk) { + if (chunk.contains(index)) return this._splitChunk(chunk, index); + + chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start]; + + // Prevent infinite loop (e.g. via empty chunks, where start === end) + if (chunk === previousChunk) return; + + previousChunk = chunk; + } + } + + _splitChunk(chunk, index) { + if (chunk.edited && chunk.content.length) { + // zero-length edited chunks are a special case (overlapping replacements) + const loc = getLocator(this.original)(index); + throw new Error( + `Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`, + ); + } + + const newChunk = chunk.split(index); + + this.byEnd[index] = chunk; + this.byStart[index] = newChunk; + this.byEnd[newChunk.end] = newChunk; + + if (chunk === this.lastChunk) this.lastChunk = newChunk; + + this.lastSearchedChunk = chunk; + return true; + } + + toString() { + let str = this.intro; + + let chunk = this.firstChunk; + while (chunk) { + str += chunk.toString(); + chunk = chunk.next; + } + + return str + this.outro; + } + + isEmpty() { + let chunk = this.firstChunk; + do { + if ( + (chunk.intro.length && chunk.intro.trim()) || + (chunk.content.length && chunk.content.trim()) || + (chunk.outro.length && chunk.outro.trim()) + ) + return false; + } while ((chunk = chunk.next)); + return true; + } + + length() { + let chunk = this.firstChunk; + let length = 0; + do { + length += chunk.intro.length + chunk.content.length + chunk.outro.length; + } while ((chunk = chunk.next)); + return length; + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimEndAborted(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + let chunk = this.lastChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimEnd(rx); + + // if chunk was trimmed, we have a new lastChunk + if (chunk.end !== end) { + if (this.lastChunk === chunk) { + this.lastChunk = chunk.next; + } + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.previous; + } while (chunk); + + return false; + } + + trimEnd(charType) { + this.trimEndAborted(charType); + return this; + } + trimStartAborted(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + let chunk = this.firstChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimStart(rx); + + if (chunk.end !== end) { + // special case... + if (chunk === this.lastChunk) this.lastChunk = chunk.next; + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.next; + } while (chunk); + + return false; + } + + trimStart(charType) { + this.trimStartAborted(charType); + return this; + } + + hasChanged() { + return this.original !== this.toString(); + } + + _replaceRegexp(searchValue, replacement) { + function getReplacement(match, str) { + if (typeof replacement === 'string') { + return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter + if (i === '$') return '$'; + if (i === '&') return match[0]; + const num = +i; + if (num < match.length) return match[+i]; + return `$${i}`; + }); + } else { + return replacement(...match, match.index, str, match.groups); + } + } + function matchAll(re, str) { + let match; + const matches = []; + while ((match = re.exec(str))) { + matches.push(match); + } + return matches; + } + if (searchValue.global) { + const matches = matchAll(searchValue, this.original); + matches.forEach((match) => { + if (match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + }); + } else { + const match = this.original.match(searchValue); + if (match && match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + } + return this; + } + + _replaceString(string, replacement) { + const { original } = this; + const index = original.indexOf(string); + + if (index !== -1) { + this.overwrite(index, index + string.length, replacement); + } + + return this; + } + + replace(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceString(searchValue, replacement); + } + + return this._replaceRegexp(searchValue, replacement); + } + + _replaceAllString(string, replacement) { + const { original } = this; + const stringLength = string.length; + for ( + let index = original.indexOf(string); + index !== -1; + index = original.indexOf(string, index + stringLength) + ) { + const previous = original.slice(index, index + stringLength); + if (previous !== replacement) this.overwrite(index, index + stringLength, replacement); + } + + return this; + } + + replaceAll(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceAllString(searchValue, replacement); + } + + if (!searchValue.global) { + throw new TypeError( + 'MagicString.prototype.replaceAll called with a non-global RegExp argument', + ); + } + + return this._replaceRegexp(searchValue, replacement); + } +} + +const hasOwnProp = Object.prototype.hasOwnProperty; + +class Bundle { + constructor(options = {}) { + this.intro = options.intro || ''; + this.separator = options.separator !== undefined ? options.separator : '\n'; + this.sources = []; + this.uniqueSources = []; + this.uniqueSourceIndexByFilename = {}; + } + + addSource(source) { + if (source instanceof MagicString) { + return this.addSource({ + content: source, + filename: source.filename, + separator: this.separator, + }); + } + + if (!isObject(source) || !source.content) { + throw new Error( + 'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`', + ); + } + + ['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => { + if (!hasOwnProp.call(source, option)) source[option] = source.content[option]; + }); + + if (source.separator === undefined) { + // TODO there's a bunch of this sort of thing, needs cleaning up + source.separator = this.separator; + } + + if (source.filename) { + if (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) { + this.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length; + this.uniqueSources.push({ filename: source.filename, content: source.content.original }); + } else { + const uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]]; + if (source.content.original !== uniqueSource.content) { + throw new Error(`Illegal source: same filename (${source.filename}), different contents`); + } + } + } + + this.sources.push(source); + return this; + } + + append(str, options) { + this.addSource({ + content: new MagicString(str), + separator: (options && options.separator) || '', + }); + + return this; + } + + clone() { + const bundle = new Bundle({ + intro: this.intro, + separator: this.separator, + }); + + this.sources.forEach((source) => { + bundle.addSource({ + filename: source.filename, + content: source.content.clone(), + separator: source.separator, + }); + }); + + return bundle; + } + + generateDecodedMap(options = {}) { + const names = []; + let x_google_ignoreList = undefined; + this.sources.forEach((source) => { + Object.keys(source.content.storedNames).forEach((name) => { + if (!~names.indexOf(name)) names.push(name); + }); + }); + + const mappings = new Mappings(options.hires); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.sources.forEach((source, i) => { + if (i > 0) { + mappings.advance(this.separator); + } + + const sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1; + const magicString = source.content; + const locate = getLocator(magicString.original); + + if (magicString.intro) { + mappings.advance(magicString.intro); + } + + magicString.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (source.filename) { + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk( + sourceIndex, + chunk, + magicString.original, + loc, + magicString.sourcemapLocations, + ); + } + } else { + mappings.advance(chunk.content); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + if (magicString.outro) { + mappings.advance(magicString.outro); + } + + if (source.ignoreList && sourceIndex !== -1) { + if (x_google_ignoreList === undefined) { + x_google_ignoreList = []; + } + x_google_ignoreList.push(sourceIndex); + } + }); + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: this.uniqueSources.map((source) => { + return options.file ? getRelativePath(options.file, source.filename) : source.filename; + }), + sourcesContent: this.uniqueSources.map((source) => { + return options.includeContent ? source.content : null; + }), + names, + mappings: mappings.raw, + x_google_ignoreList, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + getIndentString() { + const indentStringCounts = {}; + + this.sources.forEach((source) => { + const indentStr = source.content._getRawIndentString(); + + if (indentStr === null) return; + + if (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0; + indentStringCounts[indentStr] += 1; + }); + + return ( + Object.keys(indentStringCounts).sort((a, b) => { + return indentStringCounts[a] - indentStringCounts[b]; + })[0] || '\t' + ); + } + + indent(indentStr) { + if (!arguments.length) { + indentStr = this.getIndentString(); + } + + if (indentStr === '') return this; // noop + + let trailingNewline = !this.intro || this.intro.slice(-1) === '\n'; + + this.sources.forEach((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const indentStart = trailingNewline || (i > 0 && /\r?\n$/.test(separator)); + + source.content.indent(indentStr, { + exclude: source.indentExclusionRanges, + indentStart, //: trailingNewline || /\r?\n$/.test( separator ) //true///\r?\n/.test( separator ) + }); + + trailingNewline = source.content.lastChar() === '\n'; + }); + + if (this.intro) { + this.intro = + indentStr + + this.intro.replace(/^[^\n]/gm, (match, index) => { + return index > 0 ? indentStr + match : match; + }); + } + + return this; + } + + prepend(str) { + this.intro = str + this.intro; + return this; + } + + toString() { + const body = this.sources + .map((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const str = (i > 0 ? separator : '') + source.content.toString(); + + return str; + }) + .join(''); + + return this.intro + body; + } + + isEmpty() { + if (this.intro.length && this.intro.trim()) return false; + if (this.sources.some((source) => !source.content.isEmpty())) return false; + return true; + } + + length() { + return this.sources.reduce( + (length, source) => length + source.content.length(), + this.intro.length, + ); + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimStart(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + this.intro = this.intro.replace(rx, ''); + + if (!this.intro) { + let source; + let i = 0; + + do { + source = this.sources[i++]; + if (!source) { + break; + } + } while (!source.content.trimStartAborted(charType)); + } + + return this; + } + + trimEnd(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + let source; + let i = this.sources.length - 1; + + do { + source = this.sources[i--]; + if (!source) { + this.intro = this.intro.replace(rx, ''); + break; + } + } while (!source.content.trimEndAborted(charType)); + + return this; + } +} + +export { Bundle, SourceMap, MagicString as default }; +//# sourceMappingURL=magic-string.es.mjs.map diff --git a/node_modules/magic-string/dist/magic-string.es.mjs.map b/node_modules/magic-string/dist/magic-string.es.mjs.map new file mode 100644 index 0000000000..6b274b5d97 --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.es.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"magic-string.es.mjs","sources":["../src/BitSet.js","../src/Chunk.js","../src/SourceMap.js","../src/utils/guessIndent.js","../src/utils/getRelativePath.js","../src/utils/isObject.js","../src/utils/getLocator.js","../src/utils/Mappings.js","../src/MagicString.js","../src/Bundle.js"],"sourcesContent":["export default class BitSet {\n\tconstructor(arg) {\n\t\tthis.bits = arg instanceof BitSet ? arg.bits.slice() : [];\n\t}\n\n\tadd(n) {\n\t\tthis.bits[n >> 5] |= 1 << (n & 31);\n\t}\n\n\thas(n) {\n\t\treturn !!(this.bits[n >> 5] & (1 << (n & 31)));\n\t}\n}\n","export default class Chunk {\n\tconstructor(start, end, content) {\n\t\tthis.start = start;\n\t\tthis.end = end;\n\t\tthis.original = content;\n\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\n\t\tthis.content = content;\n\t\tthis.storeName = false;\n\t\tthis.edited = false;\n\n\t\tif (DEBUG) {\n\t\t\t// we make these non-enumerable, for sanity while debugging\n\t\t\tObject.defineProperties(this, {\n\t\t\t\tprevious: { writable: true, value: null },\n\t\t\t\tnext: { writable: true, value: null },\n\t\t\t});\n\t\t} else {\n\t\t\tthis.previous = null;\n\t\t\tthis.next = null;\n\t\t}\n\t}\n\n\tappendLeft(content) {\n\t\tthis.outro += content;\n\t}\n\n\tappendRight(content) {\n\t\tthis.intro = this.intro + content;\n\t}\n\n\tclone() {\n\t\tconst chunk = new Chunk(this.start, this.end, this.original);\n\n\t\tchunk.intro = this.intro;\n\t\tchunk.outro = this.outro;\n\t\tchunk.content = this.content;\n\t\tchunk.storeName = this.storeName;\n\t\tchunk.edited = this.edited;\n\n\t\treturn chunk;\n\t}\n\n\tcontains(index) {\n\t\treturn this.start < index && index < this.end;\n\t}\n\n\teachNext(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.next;\n\t\t}\n\t}\n\n\teachPrevious(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.previous;\n\t\t}\n\t}\n\n\tedit(content, storeName, contentOnly) {\n\t\tthis.content = content;\n\t\tif (!contentOnly) {\n\t\t\tthis.intro = '';\n\t\t\tthis.outro = '';\n\t\t}\n\t\tthis.storeName = storeName;\n\n\t\tthis.edited = true;\n\n\t\treturn this;\n\t}\n\n\tprependLeft(content) {\n\t\tthis.outro = content + this.outro;\n\t}\n\n\tprependRight(content) {\n\t\tthis.intro = content + this.intro;\n\t}\n\n\treset() {\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\t\tif (this.edited) {\n\t\t\tthis.content = this.original;\n\t\t\tthis.storeName = false;\n\t\t\tthis.edited = false;\n\t\t}\n\t}\n\n\tsplit(index) {\n\t\tconst sliceIndex = index - this.start;\n\n\t\tconst originalBefore = this.original.slice(0, sliceIndex);\n\t\tconst originalAfter = this.original.slice(sliceIndex);\n\n\t\tthis.original = originalBefore;\n\n\t\tconst newChunk = new Chunk(index, this.end, originalAfter);\n\t\tnewChunk.outro = this.outro;\n\t\tthis.outro = '';\n\n\t\tthis.end = index;\n\n\t\tif (this.edited) {\n\t\t\t// after split we should save the edit content record into the correct chunk\n\t\t\t// to make sure sourcemap correct\n\t\t\t// For example:\n\t\t\t// ' test'.trim()\n\t\t\t// split -> ' ' + 'test'\n\t\t\t// ✔️ edit -> '' + 'test'\n\t\t\t// ✖️ edit -> 'test' + ''\n\t\t\t// TODO is this block necessary?...\n\t\t\tnewChunk.edit('', false);\n\t\t\tthis.content = '';\n\t\t} else {\n\t\t\tthis.content = originalBefore;\n\t\t}\n\n\t\tnewChunk.next = this.next;\n\t\tif (newChunk.next) newChunk.next.previous = newChunk;\n\t\tnewChunk.previous = this;\n\t\tthis.next = newChunk;\n\n\t\treturn newChunk;\n\t}\n\n\ttoString() {\n\t\treturn this.intro + this.content + this.outro;\n\t}\n\n\ttrimEnd(rx) {\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tthis.split(this.start + trimmed.length).edit('', undefined, true);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tthis.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\tif (this.intro.length) return true;\n\t\t}\n\t}\n\n\ttrimStart(rx) {\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tconst newChunk = this.split(this.end - trimmed.length);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tnewChunk.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t\tthis.edit('', undefined, true);\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.outro = this.outro.replace(rx, '');\n\t\t\tif (this.outro.length) return true;\n\t\t}\n\t}\n}\n","import { encode } from '@jridgewell/sourcemap-codec';\n\nfunction getBtoa() {\n\tif (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') {\n\t\treturn (str) => globalThis.btoa(unescape(encodeURIComponent(str)));\n\t} else if (typeof Buffer === 'function') {\n\t\treturn (str) => Buffer.from(str, 'utf-8').toString('base64');\n\t} else {\n\t\treturn () => {\n\t\t\tthrow new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');\n\t\t};\n\t}\n}\n\nconst btoa = /*#__PURE__*/ getBtoa();\n\nexport default class SourceMap {\n\tconstructor(properties) {\n\t\tthis.version = 3;\n\t\tthis.file = properties.file;\n\t\tthis.sources = properties.sources;\n\t\tthis.sourcesContent = properties.sourcesContent;\n\t\tthis.names = properties.names;\n\t\tthis.mappings = encode(properties.mappings);\n\t\tif (typeof properties.x_google_ignoreList !== 'undefined') {\n\t\t\tthis.x_google_ignoreList = properties.x_google_ignoreList;\n\t\t}\n\t\tif (typeof properties.debugId !== 'undefined') {\n\t\t\tthis.debugId = properties.debugId;\n\t\t}\n\t}\n\n\ttoString() {\n\t\treturn JSON.stringify(this);\n\t}\n\n\ttoUrl() {\n\t\treturn 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());\n\t}\n}\n","export default function guessIndent(code) {\n\tconst lines = code.split('\\n');\n\n\tconst tabbed = lines.filter((line) => /^\\t+/.test(line));\n\tconst spaced = lines.filter((line) => /^ {2,}/.test(line));\n\n\tif (tabbed.length === 0 && spaced.length === 0) {\n\t\treturn null;\n\t}\n\n\t// More lines tabbed than spaced? Assume tabs, and\n\t// default to tabs in the case of a tie (or nothing\n\t// to go on)\n\tif (tabbed.length >= spaced.length) {\n\t\treturn '\\t';\n\t}\n\n\t// Otherwise, we need to guess the multiple\n\tconst min = spaced.reduce((previous, current) => {\n\t\tconst numSpaces = /^ +/.exec(current)[0].length;\n\t\treturn Math.min(numSpaces, previous);\n\t}, Infinity);\n\n\treturn new Array(min + 1).join(' ');\n}\n","export default function getRelativePath(from, to) {\n\tconst fromParts = from.split(/[/\\\\]/);\n\tconst toParts = to.split(/[/\\\\]/);\n\n\tfromParts.pop(); // get dirname\n\n\twhile (fromParts[0] === toParts[0]) {\n\t\tfromParts.shift();\n\t\ttoParts.shift();\n\t}\n\n\tif (fromParts.length) {\n\t\tlet i = fromParts.length;\n\t\twhile (i--) fromParts[i] = '..';\n\t}\n\n\treturn fromParts.concat(toParts).join('/');\n}\n","const toString = Object.prototype.toString;\n\nexport default function isObject(thing) {\n\treturn toString.call(thing) === '[object Object]';\n}\n","export default function getLocator(source) {\n\tconst originalLines = source.split('\\n');\n\tconst lineOffsets = [];\n\n\tfor (let i = 0, pos = 0; i < originalLines.length; i++) {\n\t\tlineOffsets.push(pos);\n\t\tpos += originalLines[i].length + 1;\n\t}\n\n\treturn function locate(index) {\n\t\tlet i = 0;\n\t\tlet j = lineOffsets.length;\n\t\twhile (i < j) {\n\t\t\tconst m = (i + j) >> 1;\n\t\t\tif (index < lineOffsets[m]) {\n\t\t\t\tj = m;\n\t\t\t} else {\n\t\t\t\ti = m + 1;\n\t\t\t}\n\t\t}\n\t\tconst line = i - 1;\n\t\tconst column = index - lineOffsets[line];\n\t\treturn { line, column };\n\t};\n}\n","const wordRegex = /\\w/;\n\nexport default class Mappings {\n\tconstructor(hires) {\n\t\tthis.hires = hires;\n\t\tthis.generatedCodeLine = 0;\n\t\tthis.generatedCodeColumn = 0;\n\t\tthis.raw = [];\n\t\tthis.rawSegments = this.raw[this.generatedCodeLine] = [];\n\t\tthis.pending = null;\n\t}\n\n\taddEdit(sourceIndex, content, loc, nameIndex) {\n\t\tif (content.length) {\n\t\t\tconst contentLengthMinusOne = content.length - 1;\n\t\t\tlet contentLineEnd = content.indexOf('\\n', 0);\n\t\t\tlet previousContentLineEnd = -1;\n\t\t\t// Loop through each line in the content and add a segment, but stop if the last line is empty,\n\t\t\t// else code afterwards would fill one line too many\n\t\t\twhile (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {\n\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\t\tif (nameIndex >= 0) {\n\t\t\t\t\tsegment.push(nameIndex);\n\t\t\t\t}\n\t\t\t\tthis.rawSegments.push(segment);\n\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\n\t\t\t\tpreviousContentLineEnd = contentLineEnd;\n\t\t\t\tcontentLineEnd = content.indexOf('\\n', contentLineEnd + 1);\n\t\t\t}\n\n\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\tif (nameIndex >= 0) {\n\t\t\t\tsegment.push(nameIndex);\n\t\t\t}\n\t\t\tthis.rawSegments.push(segment);\n\n\t\t\tthis.advance(content.slice(previousContentLineEnd + 1));\n\t\t} else if (this.pending) {\n\t\t\tthis.rawSegments.push(this.pending);\n\t\t\tthis.advance(content);\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\taddUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {\n\t\tlet originalCharIndex = chunk.start;\n\t\tlet first = true;\n\t\t// when iterating each char, check if it's in a word boundary\n\t\tlet charInHiresBoundary = false;\n\n\t\twhile (originalCharIndex < chunk.end) {\n\t\t\tif (original[originalCharIndex] === '\\n') {\n\t\t\t\tloc.line += 1;\n\t\t\t\tloc.column = 0;\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\t\t\t\tfirst = true;\n\t\t\t\tcharInHiresBoundary = false;\n\t\t\t} else {\n\t\t\t\tif (this.hires || first || sourcemapLocations.has(originalCharIndex)) {\n\t\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\n\t\t\t\t\tif (this.hires === 'boundary') {\n\t\t\t\t\t\t// in hires \"boundary\", group segments per word boundary than per char\n\t\t\t\t\t\tif (wordRegex.test(original[originalCharIndex])) {\n\t\t\t\t\t\t\t// for first char in the boundary found, start the boundary by pushing a segment\n\t\t\t\t\t\t\tif (!charInHiresBoundary) {\n\t\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\t\tcharInHiresBoundary = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// for non-word char, end the boundary by pushing a segment\n\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\tcharInHiresBoundary = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tloc.column += 1;\n\t\t\t\tthis.generatedCodeColumn += 1;\n\t\t\t\tfirst = false;\n\t\t\t}\n\n\t\t\toriginalCharIndex += 1;\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\tadvance(str) {\n\t\tif (!str) return;\n\n\t\tconst lines = str.split('\\n');\n\n\t\tif (lines.length > 1) {\n\t\t\tfor (let i = 0; i < lines.length - 1; i++) {\n\t\t\t\tthis.generatedCodeLine++;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t}\n\t\t\tthis.generatedCodeColumn = 0;\n\t\t}\n\n\t\tthis.generatedCodeColumn += lines[lines.length - 1].length;\n\t}\n}\n","import BitSet from './BitSet.js';\nimport Chunk from './Chunk.js';\nimport SourceMap from './SourceMap.js';\nimport guessIndent from './utils/guessIndent.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\nimport Stats from './utils/Stats.js';\n\nconst n = '\\n';\n\nconst warned = {\n\tinsertLeft: false,\n\tinsertRight: false,\n\tstoreName: false,\n};\n\nexport default class MagicString {\n\tconstructor(string, options = {}) {\n\t\tconst chunk = new Chunk(0, string.length, string);\n\n\t\tObject.defineProperties(this, {\n\t\t\toriginal: { writable: true, value: string },\n\t\t\toutro: { writable: true, value: '' },\n\t\t\tintro: { writable: true, value: '' },\n\t\t\tfirstChunk: { writable: true, value: chunk },\n\t\t\tlastChunk: { writable: true, value: chunk },\n\t\t\tlastSearchedChunk: { writable: true, value: chunk },\n\t\t\tbyStart: { writable: true, value: {} },\n\t\t\tbyEnd: { writable: true, value: {} },\n\t\t\tfilename: { writable: true, value: options.filename },\n\t\t\tindentExclusionRanges: { writable: true, value: options.indentExclusionRanges },\n\t\t\tsourcemapLocations: { writable: true, value: new BitSet() },\n\t\t\tstoredNames: { writable: true, value: {} },\n\t\t\tindentStr: { writable: true, value: undefined },\n\t\t\tignoreList: { writable: true, value: options.ignoreList },\n\t\t\toffset: { writable: true, value: options.offset || 0 },\n\t\t});\n\n\t\tif (DEBUG) {\n\t\t\tObject.defineProperty(this, 'stats', { value: new Stats() });\n\t\t}\n\n\t\tthis.byStart[0] = chunk;\n\t\tthis.byEnd[string.length] = chunk;\n\t}\n\n\taddSourcemapLocation(char) {\n\t\tthis.sourcemapLocations.add(char);\n\t}\n\n\tappend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.outro += content;\n\t\treturn this;\n\t}\n\n\tappendLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendLeft');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendLeft(content);\n\t\t} else {\n\t\t\tthis.intro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendLeft');\n\t\treturn this;\n\t}\n\n\tappendRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendRight(content);\n\t\t} else {\n\t\t\tthis.outro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendRight');\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset });\n\n\t\tlet originalChunk = this.firstChunk;\n\t\tlet clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());\n\n\t\twhile (originalChunk) {\n\t\t\tcloned.byStart[clonedChunk.start] = clonedChunk;\n\t\t\tcloned.byEnd[clonedChunk.end] = clonedChunk;\n\n\t\t\tconst nextOriginalChunk = originalChunk.next;\n\t\t\tconst nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();\n\n\t\t\tif (nextClonedChunk) {\n\t\t\t\tclonedChunk.next = nextClonedChunk;\n\t\t\t\tnextClonedChunk.previous = clonedChunk;\n\n\t\t\t\tclonedChunk = nextClonedChunk;\n\t\t\t}\n\n\t\t\toriginalChunk = nextOriginalChunk;\n\t\t}\n\n\t\tcloned.lastChunk = clonedChunk;\n\n\t\tif (this.indentExclusionRanges) {\n\t\t\tcloned.indentExclusionRanges = this.indentExclusionRanges.slice();\n\t\t}\n\n\t\tcloned.sourcemapLocations = new BitSet(this.sourcemapLocations);\n\n\t\tcloned.intro = this.intro;\n\t\tcloned.outro = this.outro;\n\n\t\treturn cloned;\n\t}\n\n\tgenerateDecodedMap(options) {\n\t\toptions = options || {};\n\n\t\tconst sourceIndex = 0;\n\t\tconst names = Object.keys(this.storedNames);\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tconst locate = getLocator(this.original);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.firstChunk.eachNext((chunk) => {\n\t\t\tconst loc = locate(chunk.start);\n\n\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tmappings.addEdit(\n\t\t\t\t\tsourceIndex,\n\t\t\t\t\tchunk.content,\n\t\t\t\t\tloc,\n\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tmappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);\n\t\t\t}\n\n\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t});\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: [\n\t\t\t\toptions.source ? getRelativePath(options.file || '', options.source) : options.file || '',\n\t\t\t],\n\t\t\tsourcesContent: options.includeContent ? [this.original] : undefined,\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\t_ensureindentStr() {\n\t\tif (this.indentStr === undefined) {\n\t\t\tthis.indentStr = guessIndent(this.original);\n\t\t}\n\t}\n\n\t_getRawIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr;\n\t}\n\n\tgetIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr === null ? '\\t' : this.indentStr;\n\t}\n\n\tindent(indentStr, options) {\n\t\tconst pattern = /^[^\\r\\n]/gm;\n\n\t\tif (isObject(indentStr)) {\n\t\t\toptions = indentStr;\n\t\t\tindentStr = undefined;\n\t\t}\n\n\t\tif (indentStr === undefined) {\n\t\t\tthis._ensureindentStr();\n\t\t\tindentStr = this.indentStr || '\\t';\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\toptions = options || {};\n\n\t\t// Process exclusion ranges\n\t\tconst isExcluded = {};\n\n\t\tif (options.exclude) {\n\t\t\tconst exclusions =\n\t\t\t\ttypeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;\n\t\t\texclusions.forEach((exclusion) => {\n\t\t\t\tfor (let i = exclusion[0]; i < exclusion[1]; i += 1) {\n\t\t\t\t\tisExcluded[i] = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tlet shouldIndentNextCharacter = options.indentStart !== false;\n\t\tconst replacer = (match) => {\n\t\t\tif (shouldIndentNextCharacter) return `${indentStr}${match}`;\n\t\t\tshouldIndentNextCharacter = true;\n\t\t\treturn match;\n\t\t};\n\n\t\tthis.intro = this.intro.replace(pattern, replacer);\n\n\t\tlet charIndex = 0;\n\t\tlet chunk = this.firstChunk;\n\n\t\twhile (chunk) {\n\t\t\tconst end = chunk.end;\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\tchunk.content = chunk.content.replace(pattern, replacer);\n\n\t\t\t\t\tif (chunk.content.length) {\n\t\t\t\t\t\tshouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\\n';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcharIndex = chunk.start;\n\n\t\t\t\twhile (charIndex < end) {\n\t\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\t\tconst char = this.original[charIndex];\n\n\t\t\t\t\t\tif (char === '\\n') {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = true;\n\t\t\t\t\t\t} else if (char !== '\\r' && shouldIndentNextCharacter) {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = false;\n\n\t\t\t\t\t\t\tif (charIndex === chunk.start) {\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis._splitChunk(chunk, charIndex);\n\t\t\t\t\t\t\t\tchunk = chunk.next;\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcharIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcharIndex = chunk.end;\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tthis.outro = this.outro.replace(pattern, replacer);\n\n\t\treturn this;\n\t}\n\n\tinsert() {\n\t\tthrow new Error(\n\t\t\t'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)',\n\t\t);\n\t}\n\n\tinsertLeft(index, content) {\n\t\tif (!warned.insertLeft) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead',\n\t\t\t);\n\t\t\twarned.insertLeft = true;\n\t\t}\n\n\t\treturn this.appendLeft(index, content);\n\t}\n\n\tinsertRight(index, content) {\n\t\tif (!warned.insertRight) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead',\n\t\t\t);\n\t\t\twarned.insertRight = true;\n\t\t}\n\n\t\treturn this.prependRight(index, content);\n\t}\n\n\tmove(start, end, index) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\t\tindex = index + this.offset;\n\n\t\tif (index >= start && index <= end) throw new Error('Cannot move a selection inside itself');\n\n\t\tif (DEBUG) this.stats.time('move');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\t\tthis._split(index);\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tconst oldLeft = first.previous;\n\t\tconst oldRight = last.next;\n\n\t\tconst newRight = this.byStart[index];\n\t\tif (!newRight && last === this.lastChunk) return this;\n\t\tconst newLeft = newRight ? newRight.previous : this.lastChunk;\n\n\t\tif (oldLeft) oldLeft.next = oldRight;\n\t\tif (oldRight) oldRight.previous = oldLeft;\n\n\t\tif (newLeft) newLeft.next = first;\n\t\tif (newRight) newRight.previous = last;\n\n\t\tif (!first.previous) this.firstChunk = last.next;\n\t\tif (!last.next) {\n\t\t\tthis.lastChunk = first.previous;\n\t\t\tthis.lastChunk.next = null;\n\t\t}\n\n\t\tfirst.previous = newLeft;\n\t\tlast.next = newRight || null;\n\n\t\tif (!newLeft) this.firstChunk = first;\n\t\tif (!newRight) this.lastChunk = last;\n\n\t\tif (DEBUG) this.stats.timeEnd('move');\n\t\treturn this;\n\t}\n\n\toverwrite(start, end, content, options) {\n\t\toptions = options || {};\n\t\treturn this.update(start, end, content, { ...options, overwrite: !options.contentOnly });\n\t}\n\n\tupdate(start, end, content, options) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('replacement content must be a string');\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (end > this.original.length) throw new Error('end is out of bounds');\n\t\tif (start === end)\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',\n\t\t\t);\n\n\t\tif (DEBUG) this.stats.time('overwrite');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tif (options === true) {\n\t\t\tif (!warned.storeName) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string',\n\t\t\t\t);\n\t\t\t\twarned.storeName = true;\n\t\t\t}\n\n\t\t\toptions = { storeName: true };\n\t\t}\n\t\tconst storeName = options !== undefined ? options.storeName : false;\n\t\tconst overwrite = options !== undefined ? options.overwrite : false;\n\n\t\tif (storeName) {\n\t\t\tconst original = this.original.slice(start, end);\n\t\t\tObject.defineProperty(this.storedNames, original, {\n\t\t\t\twritable: true,\n\t\t\t\tvalue: true,\n\t\t\t\tenumerable: true,\n\t\t\t});\n\t\t}\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tif (first) {\n\t\t\tlet chunk = first;\n\t\t\twhile (chunk !== last) {\n\t\t\t\tif (chunk.next !== this.byStart[chunk.end]) {\n\t\t\t\t\tthrow new Error('Cannot overwrite across a split point');\n\t\t\t\t}\n\t\t\t\tchunk = chunk.next;\n\t\t\t\tchunk.edit('', false);\n\t\t\t}\n\n\t\t\tfirst.edit(content, storeName, !overwrite);\n\t\t} else {\n\t\t\t// must be inserting at the end\n\t\t\tconst newChunk = new Chunk(start, end, '').edit(content, storeName);\n\n\t\t\t// TODO last chunk in the array may not be the last chunk, if it's moved...\n\t\t\tlast.next = newChunk;\n\t\t\tnewChunk.previous = last;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('overwrite');\n\t\treturn this;\n\t}\n\n\tprepend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.intro = content + this.intro;\n\t\treturn this;\n\t}\n\n\tprependLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependLeft(content);\n\t\t} else {\n\t\t\tthis.intro = content + this.intro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tprependRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependRight(content);\n\t\t} else {\n\t\t\tthis.outro = content + this.outro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tremove(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('remove');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.intro = '';\n\t\t\tchunk.outro = '';\n\t\t\tchunk.edit('');\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('remove');\n\t\treturn this;\n\t}\n\n\treset(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('reset');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.reset();\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('reset');\n\t\treturn this;\n\t}\n\n\tlastChar() {\n\t\tif (this.outro.length) return this.outro[this.outro.length - 1];\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];\n\t\t\tif (chunk.content.length) return chunk.content[chunk.content.length - 1];\n\t\t\tif (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];\n\t\t} while ((chunk = chunk.previous));\n\t\tif (this.intro.length) return this.intro[this.intro.length - 1];\n\t\treturn '';\n\t}\n\n\tlastLine() {\n\t\tlet lineIndex = this.outro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.outro.substr(lineIndex + 1);\n\t\tlet lineStr = this.outro;\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length > 0) {\n\t\t\t\tlineIndex = chunk.outro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.outro + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.content.length > 0) {\n\t\t\t\tlineIndex = chunk.content.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.content + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.intro.length > 0) {\n\t\t\t\tlineIndex = chunk.intro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.intro + lineStr;\n\t\t\t}\n\t\t} while ((chunk = chunk.previous));\n\t\tlineIndex = this.intro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;\n\t\treturn this.intro + lineStr;\n\t}\n\n\tslice(start = 0, end = this.original.length - this.offset) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tlet result = '';\n\n\t\t// find start chunk\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk && (chunk.start > start || chunk.end <= start)) {\n\t\t\t// found end chunk before start\n\t\t\tif (chunk.start < end && chunk.end >= end) {\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tif (chunk && chunk.edited && chunk.start !== start)\n\t\t\tthrow new Error(`Cannot use replaced character ${start} as slice start anchor.`);\n\n\t\tconst startChunk = chunk;\n\t\twhile (chunk) {\n\t\t\tif (chunk.intro && (startChunk !== chunk || chunk.start === start)) {\n\t\t\t\tresult += chunk.intro;\n\t\t\t}\n\n\t\t\tconst containsEnd = chunk.start < end && chunk.end >= end;\n\t\t\tif (containsEnd && chunk.edited && chunk.end !== end)\n\t\t\t\tthrow new Error(`Cannot use replaced character ${end} as slice end anchor.`);\n\n\t\t\tconst sliceStart = startChunk === chunk ? start - chunk.start : 0;\n\t\t\tconst sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;\n\n\t\t\tresult += chunk.content.slice(sliceStart, sliceEnd);\n\n\t\t\tif (chunk.outro && (!containsEnd || chunk.end === end)) {\n\t\t\t\tresult += chunk.outro;\n\t\t\t}\n\n\t\t\tif (containsEnd) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// TODO deprecate this? not really very useful\n\tsnip(start, end) {\n\t\tconst clone = this.clone();\n\t\tclone.remove(0, start);\n\t\tclone.remove(end, clone.original.length);\n\n\t\treturn clone;\n\t}\n\n\t_split(index) {\n\t\tif (this.byStart[index] || this.byEnd[index]) return;\n\n\t\tif (DEBUG) this.stats.time('_split');\n\n\t\tlet chunk = this.lastSearchedChunk;\n\t\tlet previousChunk = chunk;\n\t\tconst searchForward = index > chunk.end;\n\n\t\twhile (chunk) {\n\t\t\tif (chunk.contains(index)) return this._splitChunk(chunk, index);\n\n\t\t\tchunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];\n\n\t\t\t// Prevent infinite loop (e.g. via empty chunks, where start === end)\n\t\t\tif (chunk === previousChunk) return;\n\n\t\t\tpreviousChunk = chunk;\n\t\t}\n\t}\n\n\t_splitChunk(chunk, index) {\n\t\tif (chunk.edited && chunk.content.length) {\n\t\t\t// zero-length edited chunks are a special case (overlapping replacements)\n\t\t\tconst loc = getLocator(this.original)(index);\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – \"${chunk.original}\")`,\n\t\t\t);\n\t\t}\n\n\t\tconst newChunk = chunk.split(index);\n\n\t\tthis.byEnd[index] = chunk;\n\t\tthis.byStart[index] = newChunk;\n\t\tthis.byEnd[newChunk.end] = newChunk;\n\n\t\tif (chunk === this.lastChunk) this.lastChunk = newChunk;\n\n\t\tthis.lastSearchedChunk = chunk;\n\t\tif (DEBUG) this.stats.timeEnd('_split');\n\t\treturn true;\n\t}\n\n\ttoString() {\n\t\tlet str = this.intro;\n\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk) {\n\t\t\tstr += chunk.toString();\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn str + this.outro;\n\t}\n\n\tisEmpty() {\n\t\tlet chunk = this.firstChunk;\n\t\tdo {\n\t\t\tif (\n\t\t\t\t(chunk.intro.length && chunk.intro.trim()) ||\n\t\t\t\t(chunk.content.length && chunk.content.trim()) ||\n\t\t\t\t(chunk.outro.length && chunk.outro.trim())\n\t\t\t)\n\t\t\t\treturn false;\n\t\t} while ((chunk = chunk.next));\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\tlet chunk = this.firstChunk;\n\t\tlet length = 0;\n\t\tdo {\n\t\t\tlength += chunk.intro.length + chunk.content.length + chunk.outro.length;\n\t\t} while ((chunk = chunk.next));\n\t\treturn length;\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimEndAborted(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tlet chunk = this.lastChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimEnd(rx);\n\n\t\t\t// if chunk was trimmed, we have a new lastChunk\n\t\t\tif (chunk.end !== end) {\n\t\t\t\tif (this.lastChunk === chunk) {\n\t\t\t\t\tthis.lastChunk = chunk.next;\n\t\t\t\t}\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.previous;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimEnd(charType) {\n\t\tthis.trimEndAborted(charType);\n\t\treturn this;\n\t}\n\ttrimStartAborted(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tlet chunk = this.firstChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimStart(rx);\n\n\t\t\tif (chunk.end !== end) {\n\t\t\t\t// special case...\n\t\t\t\tif (chunk === this.lastChunk) this.lastChunk = chunk.next;\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.next;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimStart(charType) {\n\t\tthis.trimStartAborted(charType);\n\t\treturn this;\n\t}\n\n\thasChanged() {\n\t\treturn this.original !== this.toString();\n\t}\n\n\t_replaceRegexp(searchValue, replacement) {\n\t\tfunction getReplacement(match, str) {\n\t\t\tif (typeof replacement === 'string') {\n\t\t\t\treturn replacement.replace(/\\$(\\$|&|\\d+)/g, (_, i) => {\n\t\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter\n\t\t\t\t\tif (i === '$') return '$';\n\t\t\t\t\tif (i === '&') return match[0];\n\t\t\t\t\tconst num = +i;\n\t\t\t\t\tif (num < match.length) return match[+i];\n\t\t\t\t\treturn `$${i}`;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treturn replacement(...match, match.index, str, match.groups);\n\t\t\t}\n\t\t}\n\t\tfunction matchAll(re, str) {\n\t\t\tlet match;\n\t\t\tconst matches = [];\n\t\t\twhile ((match = re.exec(str))) {\n\t\t\t\tmatches.push(match);\n\t\t\t}\n\t\t\treturn matches;\n\t\t}\n\t\tif (searchValue.global) {\n\t\t\tconst matches = matchAll(searchValue, this.original);\n\t\t\tmatches.forEach((match) => {\n\t\t\t\tif (match.index != null) {\n\t\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tconst match = this.original.match(searchValue);\n\t\t\tif (match && match.index != null) {\n\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t_replaceString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst index = original.indexOf(string);\n\n\t\tif (index !== -1) {\n\t\t\tthis.overwrite(index, index + string.length, replacement);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplace(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceString(searchValue, replacement);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n\n\t_replaceAllString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst stringLength = string.length;\n\t\tfor (\n\t\t\tlet index = original.indexOf(string);\n\t\t\tindex !== -1;\n\t\t\tindex = original.indexOf(string, index + stringLength)\n\t\t) {\n\t\t\tconst previous = original.slice(index, index + stringLength);\n\t\t\tif (previous !== replacement) this.overwrite(index, index + stringLength, replacement);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplaceAll(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceAllString(searchValue, replacement);\n\t\t}\n\n\t\tif (!searchValue.global) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'MagicString.prototype.replaceAll called with a non-global RegExp argument',\n\t\t\t);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n}\n","import MagicString from './MagicString.js';\nimport SourceMap from './SourceMap.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\n\nconst hasOwnProp = Object.prototype.hasOwnProperty;\n\nexport default class Bundle {\n\tconstructor(options = {}) {\n\t\tthis.intro = options.intro || '';\n\t\tthis.separator = options.separator !== undefined ? options.separator : '\\n';\n\t\tthis.sources = [];\n\t\tthis.uniqueSources = [];\n\t\tthis.uniqueSourceIndexByFilename = {};\n\t}\n\n\taddSource(source) {\n\t\tif (source instanceof MagicString) {\n\t\t\treturn this.addSource({\n\t\t\t\tcontent: source,\n\t\t\t\tfilename: source.filename,\n\t\t\t\tseparator: this.separator,\n\t\t\t});\n\t\t}\n\n\t\tif (!isObject(source) || !source.content) {\n\t\t\tthrow new Error(\n\t\t\t\t'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`',\n\t\t\t);\n\t\t}\n\n\t\t['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => {\n\t\t\tif (!hasOwnProp.call(source, option)) source[option] = source.content[option];\n\t\t});\n\n\t\tif (source.separator === undefined) {\n\t\t\t// TODO there's a bunch of this sort of thing, needs cleaning up\n\t\t\tsource.separator = this.separator;\n\t\t}\n\n\t\tif (source.filename) {\n\t\t\tif (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) {\n\t\t\t\tthis.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length;\n\t\t\t\tthis.uniqueSources.push({ filename: source.filename, content: source.content.original });\n\t\t\t} else {\n\t\t\t\tconst uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]];\n\t\t\t\tif (source.content.original !== uniqueSource.content) {\n\t\t\t\t\tthrow new Error(`Illegal source: same filename (${source.filename}), different contents`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.sources.push(source);\n\t\treturn this;\n\t}\n\n\tappend(str, options) {\n\t\tthis.addSource({\n\t\t\tcontent: new MagicString(str),\n\t\t\tseparator: (options && options.separator) || '',\n\t\t});\n\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst bundle = new Bundle({\n\t\t\tintro: this.intro,\n\t\t\tseparator: this.separator,\n\t\t});\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tbundle.addSource({\n\t\t\t\tfilename: source.filename,\n\t\t\t\tcontent: source.content.clone(),\n\t\t\t\tseparator: source.separator,\n\t\t\t});\n\t\t});\n\n\t\treturn bundle;\n\t}\n\n\tgenerateDecodedMap(options = {}) {\n\t\tconst names = [];\n\t\tlet x_google_ignoreList = undefined;\n\t\tthis.sources.forEach((source) => {\n\t\t\tObject.keys(source.content.storedNames).forEach((name) => {\n\t\t\t\tif (!~names.indexOf(name)) names.push(name);\n\t\t\t});\n\t\t});\n\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tif (i > 0) {\n\t\t\t\tmappings.advance(this.separator);\n\t\t\t}\n\n\t\t\tconst sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1;\n\t\t\tconst magicString = source.content;\n\t\t\tconst locate = getLocator(magicString.original);\n\n\t\t\tif (magicString.intro) {\n\t\t\t\tmappings.advance(magicString.intro);\n\t\t\t}\n\n\t\t\tmagicString.firstChunk.eachNext((chunk) => {\n\t\t\t\tconst loc = locate(chunk.start);\n\n\t\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\t\tif (source.filename) {\n\t\t\t\t\tif (chunk.edited) {\n\t\t\t\t\t\tmappings.addEdit(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk.content,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmappings.addUneditedChunk(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\tmagicString.original,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tmagicString.sourcemapLocations,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmappings.advance(chunk.content);\n\t\t\t\t}\n\n\t\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t\t});\n\n\t\t\tif (magicString.outro) {\n\t\t\t\tmappings.advance(magicString.outro);\n\t\t\t}\n\n\t\t\tif (source.ignoreList && sourceIndex !== -1) {\n\t\t\t\tif (x_google_ignoreList === undefined) {\n\t\t\t\t\tx_google_ignoreList = [];\n\t\t\t\t}\n\t\t\t\tx_google_ignoreList.push(sourceIndex);\n\t\t\t}\n\t\t});\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.file ? getRelativePath(options.file, source.filename) : source.filename;\n\t\t\t}),\n\t\t\tsourcesContent: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.includeContent ? source.content : null;\n\t\t\t}),\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\tgetIndentString() {\n\t\tconst indentStringCounts = {};\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tconst indentStr = source.content._getRawIndentString();\n\n\t\t\tif (indentStr === null) return;\n\n\t\t\tif (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0;\n\t\t\tindentStringCounts[indentStr] += 1;\n\t\t});\n\n\t\treturn (\n\t\t\tObject.keys(indentStringCounts).sort((a, b) => {\n\t\t\t\treturn indentStringCounts[a] - indentStringCounts[b];\n\t\t\t})[0] || '\\t'\n\t\t);\n\t}\n\n\tindent(indentStr) {\n\t\tif (!arguments.length) {\n\t\t\tindentStr = this.getIndentString();\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\tlet trailingNewline = !this.intro || this.intro.slice(-1) === '\\n';\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\tconst indentStart = trailingNewline || (i > 0 && /\\r?\\n$/.test(separator));\n\n\t\t\tsource.content.indent(indentStr, {\n\t\t\t\texclude: source.indentExclusionRanges,\n\t\t\t\tindentStart, //: trailingNewline || /\\r?\\n$/.test( separator ) //true///\\r?\\n/.test( separator )\n\t\t\t});\n\n\t\t\ttrailingNewline = source.content.lastChar() === '\\n';\n\t\t});\n\n\t\tif (this.intro) {\n\t\t\tthis.intro =\n\t\t\t\tindentStr +\n\t\t\t\tthis.intro.replace(/^[^\\n]/gm, (match, index) => {\n\t\t\t\t\treturn index > 0 ? indentStr + match : match;\n\t\t\t\t});\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprepend(str) {\n\t\tthis.intro = str + this.intro;\n\t\treturn this;\n\t}\n\n\ttoString() {\n\t\tconst body = this.sources\n\t\t\t.map((source, i) => {\n\t\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\t\tconst str = (i > 0 ? separator : '') + source.content.toString();\n\n\t\t\t\treturn str;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn this.intro + body;\n\t}\n\n\tisEmpty() {\n\t\tif (this.intro.length && this.intro.trim()) return false;\n\t\tif (this.sources.some((source) => !source.content.isEmpty())) return false;\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\treturn this.sources.reduce(\n\t\t\t(length, source) => length + source.content.length(),\n\t\t\tthis.intro.length,\n\t\t);\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimStart(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\t\tthis.intro = this.intro.replace(rx, '');\n\n\t\tif (!this.intro) {\n\t\t\tlet source;\n\t\t\tlet i = 0;\n\n\t\t\tdo {\n\t\t\t\tsource = this.sources[i++];\n\t\t\t\tif (!source) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} while (!source.content.trimStartAborted(charType));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\ttrimEnd(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tlet source;\n\t\tlet i = this.sources.length - 1;\n\n\t\tdo {\n\t\t\tsource = this.sources[i--];\n\t\t\tif (!source) {\n\t\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (!source.content.trimEndAborted(charType));\n\n\t\treturn this;\n\t}\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/magic-string/dist/magic-string.umd.js b/node_modules/magic-string/dist/magic-string.umd.js new file mode 100644 index 0000000000..35ca8f98e4 --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.umd.js @@ -0,0 +1,1669 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.MagicString = factory()); +})(this, (function () { 'use strict'; + + class BitSet { + constructor(arg) { + this.bits = arg instanceof BitSet ? arg.bits.slice() : []; + } + + add(n) { + this.bits[n >> 5] |= 1 << (n & 31); + } + + has(n) { + return !!(this.bits[n >> 5] & (1 << (n & 31))); + } + } + + class Chunk { + constructor(start, end, content) { + this.start = start; + this.end = end; + this.original = content; + + this.intro = ''; + this.outro = ''; + + this.content = content; + this.storeName = false; + this.edited = false; + + { + this.previous = null; + this.next = null; + } + } + + appendLeft(content) { + this.outro += content; + } + + appendRight(content) { + this.intro = this.intro + content; + } + + clone() { + const chunk = new Chunk(this.start, this.end, this.original); + + chunk.intro = this.intro; + chunk.outro = this.outro; + chunk.content = this.content; + chunk.storeName = this.storeName; + chunk.edited = this.edited; + + return chunk; + } + + contains(index) { + return this.start < index && index < this.end; + } + + eachNext(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.next; + } + } + + eachPrevious(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.previous; + } + } + + edit(content, storeName, contentOnly) { + this.content = content; + if (!contentOnly) { + this.intro = ''; + this.outro = ''; + } + this.storeName = storeName; + + this.edited = true; + + return this; + } + + prependLeft(content) { + this.outro = content + this.outro; + } + + prependRight(content) { + this.intro = content + this.intro; + } + + reset() { + this.intro = ''; + this.outro = ''; + if (this.edited) { + this.content = this.original; + this.storeName = false; + this.edited = false; + } + } + + split(index) { + const sliceIndex = index - this.start; + + const originalBefore = this.original.slice(0, sliceIndex); + const originalAfter = this.original.slice(sliceIndex); + + this.original = originalBefore; + + const newChunk = new Chunk(index, this.end, originalAfter); + newChunk.outro = this.outro; + this.outro = ''; + + this.end = index; + + if (this.edited) { + // after split we should save the edit content record into the correct chunk + // to make sure sourcemap correct + // For example: + // ' test'.trim() + // split -> ' ' + 'test' + // ✔️ edit -> '' + 'test' + // ✖️ edit -> 'test' + '' + // TODO is this block necessary?... + newChunk.edit('', false); + this.content = ''; + } else { + this.content = originalBefore; + } + + newChunk.next = this.next; + if (newChunk.next) newChunk.next.previous = newChunk; + newChunk.previous = this; + this.next = newChunk; + + return newChunk; + } + + toString() { + return this.intro + this.content + this.outro; + } + + trimEnd(rx) { + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + this.split(this.start + trimmed.length).edit('', undefined, true); + if (this.edited) { + // save the change, if it has been edited + this.edit(trimmed, this.storeName, true); + } + } + return true; + } else { + this.edit('', undefined, true); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + } + } + + trimStart(rx) { + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + const newChunk = this.split(this.end - trimmed.length); + if (this.edited) { + // save the change, if it has been edited + newChunk.edit(trimmed, this.storeName, true); + } + this.edit('', undefined, true); + } + return true; + } else { + this.edit('', undefined, true); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + } + } + } + + // src/vlq.ts + var comma = ",".charCodeAt(0); + var semicolon = ";".charCodeAt(0); + var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var intToChar = new Uint8Array(64); + var charToInt = new Uint8Array(128); + for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; + } + function encodeInteger(builder, num, relative) { + let delta = num - relative; + delta = delta < 0 ? -delta << 1 | 1 : delta << 1; + do { + let clamped = delta & 31; + delta >>>= 5; + if (delta > 0) clamped |= 32; + builder.write(intToChar[clamped]); + } while (delta > 0); + return num; + } + + // src/strings.ts + var bufLength = 1024 * 16; + var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { + decode(buf) { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + } + } : { + decode(buf) { + let out = ""; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + } + }; + var StringWriter = class { + constructor() { + this.pos = 0; + this.out = ""; + this.buffer = new Uint8Array(bufLength); + } + write(v) { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + flush() { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } + }; + function encode(decoded) { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + let genColumn = 0; + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + genColumn = encodeInteger(writer, segment[0], genColumn); + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + return writer.flush(); + } + + function getBtoa() { + if (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') { + return (str) => globalThis.btoa(unescape(encodeURIComponent(str))); + } else if (typeof Buffer === 'function') { + return (str) => Buffer.from(str, 'utf-8').toString('base64'); + } else { + return () => { + throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.'); + }; + } + } + + const btoa = /*#__PURE__*/ getBtoa(); + + class SourceMap { + constructor(properties) { + this.version = 3; + this.file = properties.file; + this.sources = properties.sources; + this.sourcesContent = properties.sourcesContent; + this.names = properties.names; + this.mappings = encode(properties.mappings); + if (typeof properties.x_google_ignoreList !== 'undefined') { + this.x_google_ignoreList = properties.x_google_ignoreList; + } + if (typeof properties.debugId !== 'undefined') { + this.debugId = properties.debugId; + } + } + + toString() { + return JSON.stringify(this); + } + + toUrl() { + return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString()); + } + } + + function guessIndent(code) { + const lines = code.split('\n'); + + const tabbed = lines.filter((line) => /^\t+/.test(line)); + const spaced = lines.filter((line) => /^ {2,}/.test(line)); + + if (tabbed.length === 0 && spaced.length === 0) { + return null; + } + + // More lines tabbed than spaced? Assume tabs, and + // default to tabs in the case of a tie (or nothing + // to go on) + if (tabbed.length >= spaced.length) { + return '\t'; + } + + // Otherwise, we need to guess the multiple + const min = spaced.reduce((previous, current) => { + const numSpaces = /^ +/.exec(current)[0].length; + return Math.min(numSpaces, previous); + }, Infinity); + + return new Array(min + 1).join(' '); + } + + function getRelativePath(from, to) { + const fromParts = from.split(/[/\\]/); + const toParts = to.split(/[/\\]/); + + fromParts.pop(); // get dirname + + while (fromParts[0] === toParts[0]) { + fromParts.shift(); + toParts.shift(); + } + + if (fromParts.length) { + let i = fromParts.length; + while (i--) fromParts[i] = '..'; + } + + return fromParts.concat(toParts).join('/'); + } + + const toString = Object.prototype.toString; + + function isObject(thing) { + return toString.call(thing) === '[object Object]'; + } + + function getLocator(source) { + const originalLines = source.split('\n'); + const lineOffsets = []; + + for (let i = 0, pos = 0; i < originalLines.length; i++) { + lineOffsets.push(pos); + pos += originalLines[i].length + 1; + } + + return function locate(index) { + let i = 0; + let j = lineOffsets.length; + while (i < j) { + const m = (i + j) >> 1; + if (index < lineOffsets[m]) { + j = m; + } else { + i = m + 1; + } + } + const line = i - 1; + const column = index - lineOffsets[line]; + return { line, column }; + }; + } + + const wordRegex = /\w/; + + class Mappings { + constructor(hires) { + this.hires = hires; + this.generatedCodeLine = 0; + this.generatedCodeColumn = 0; + this.raw = []; + this.rawSegments = this.raw[this.generatedCodeLine] = []; + this.pending = null; + } + + addEdit(sourceIndex, content, loc, nameIndex) { + if (content.length) { + const contentLengthMinusOne = content.length - 1; + let contentLineEnd = content.indexOf('\n', 0); + let previousContentLineEnd = -1; + // Loop through each line in the content and add a segment, but stop if the last line is empty, + // else code afterwards would fill one line too many + while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + + previousContentLineEnd = contentLineEnd; + contentLineEnd = content.indexOf('\n', contentLineEnd + 1); + } + + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.advance(content.slice(previousContentLineEnd + 1)); + } else if (this.pending) { + this.rawSegments.push(this.pending); + this.advance(content); + } + + this.pending = null; + } + + addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) { + let originalCharIndex = chunk.start; + let first = true; + // when iterating each char, check if it's in a word boundary + let charInHiresBoundary = false; + + while (originalCharIndex < chunk.end) { + if (original[originalCharIndex] === '\n') { + loc.line += 1; + loc.column = 0; + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + first = true; + charInHiresBoundary = false; + } else { + if (this.hires || first || sourcemapLocations.has(originalCharIndex)) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + + if (this.hires === 'boundary') { + // in hires "boundary", group segments per word boundary than per char + if (wordRegex.test(original[originalCharIndex])) { + // for first char in the boundary found, start the boundary by pushing a segment + if (!charInHiresBoundary) { + this.rawSegments.push(segment); + charInHiresBoundary = true; + } + } else { + // for non-word char, end the boundary by pushing a segment + this.rawSegments.push(segment); + charInHiresBoundary = false; + } + } else { + this.rawSegments.push(segment); + } + } + + loc.column += 1; + this.generatedCodeColumn += 1; + first = false; + } + + originalCharIndex += 1; + } + + this.pending = null; + } + + advance(str) { + if (!str) return; + + const lines = str.split('\n'); + + if (lines.length > 1) { + for (let i = 0; i < lines.length - 1; i++) { + this.generatedCodeLine++; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + } + this.generatedCodeColumn = 0; + } + + this.generatedCodeColumn += lines[lines.length - 1].length; + } + } + + const n = '\n'; + + const warned = { + insertLeft: false, + insertRight: false, + storeName: false, + }; + + class MagicString { + constructor(string, options = {}) { + const chunk = new Chunk(0, string.length, string); + + Object.defineProperties(this, { + original: { writable: true, value: string }, + outro: { writable: true, value: '' }, + intro: { writable: true, value: '' }, + firstChunk: { writable: true, value: chunk }, + lastChunk: { writable: true, value: chunk }, + lastSearchedChunk: { writable: true, value: chunk }, + byStart: { writable: true, value: {} }, + byEnd: { writable: true, value: {} }, + filename: { writable: true, value: options.filename }, + indentExclusionRanges: { writable: true, value: options.indentExclusionRanges }, + sourcemapLocations: { writable: true, value: new BitSet() }, + storedNames: { writable: true, value: {} }, + indentStr: { writable: true, value: undefined }, + ignoreList: { writable: true, value: options.ignoreList }, + offset: { writable: true, value: options.offset || 0 }, + }); + + this.byStart[0] = chunk; + this.byEnd[string.length] = chunk; + } + + addSourcemapLocation(char) { + this.sourcemapLocations.add(char); + } + + append(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.outro += content; + return this; + } + + appendLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.appendLeft(content); + } else { + this.intro += content; + } + return this; + } + + appendRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.appendRight(content); + } else { + this.outro += content; + } + return this; + } + + clone() { + const cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset }); + + let originalChunk = this.firstChunk; + let clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone()); + + while (originalChunk) { + cloned.byStart[clonedChunk.start] = clonedChunk; + cloned.byEnd[clonedChunk.end] = clonedChunk; + + const nextOriginalChunk = originalChunk.next; + const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone(); + + if (nextClonedChunk) { + clonedChunk.next = nextClonedChunk; + nextClonedChunk.previous = clonedChunk; + + clonedChunk = nextClonedChunk; + } + + originalChunk = nextOriginalChunk; + } + + cloned.lastChunk = clonedChunk; + + if (this.indentExclusionRanges) { + cloned.indentExclusionRanges = this.indentExclusionRanges.slice(); + } + + cloned.sourcemapLocations = new BitSet(this.sourcemapLocations); + + cloned.intro = this.intro; + cloned.outro = this.outro; + + return cloned; + } + + generateDecodedMap(options) { + options = options || {}; + + const sourceIndex = 0; + const names = Object.keys(this.storedNames); + const mappings = new Mappings(options.hires); + + const locate = getLocator(this.original); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: [ + options.source ? getRelativePath(options.file || '', options.source) : options.file || '', + ], + sourcesContent: options.includeContent ? [this.original] : undefined, + names, + mappings: mappings.raw, + x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + _ensureindentStr() { + if (this.indentStr === undefined) { + this.indentStr = guessIndent(this.original); + } + } + + _getRawIndentString() { + this._ensureindentStr(); + return this.indentStr; + } + + getIndentString() { + this._ensureindentStr(); + return this.indentStr === null ? '\t' : this.indentStr; + } + + indent(indentStr, options) { + const pattern = /^[^\r\n]/gm; + + if (isObject(indentStr)) { + options = indentStr; + indentStr = undefined; + } + + if (indentStr === undefined) { + this._ensureindentStr(); + indentStr = this.indentStr || '\t'; + } + + if (indentStr === '') return this; // noop + + options = options || {}; + + // Process exclusion ranges + const isExcluded = {}; + + if (options.exclude) { + const exclusions = + typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude; + exclusions.forEach((exclusion) => { + for (let i = exclusion[0]; i < exclusion[1]; i += 1) { + isExcluded[i] = true; + } + }); + } + + let shouldIndentNextCharacter = options.indentStart !== false; + const replacer = (match) => { + if (shouldIndentNextCharacter) return `${indentStr}${match}`; + shouldIndentNextCharacter = true; + return match; + }; + + this.intro = this.intro.replace(pattern, replacer); + + let charIndex = 0; + let chunk = this.firstChunk; + + while (chunk) { + const end = chunk.end; + + if (chunk.edited) { + if (!isExcluded[charIndex]) { + chunk.content = chunk.content.replace(pattern, replacer); + + if (chunk.content.length) { + shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n'; + } + } + } else { + charIndex = chunk.start; + + while (charIndex < end) { + if (!isExcluded[charIndex]) { + const char = this.original[charIndex]; + + if (char === '\n') { + shouldIndentNextCharacter = true; + } else if (char !== '\r' && shouldIndentNextCharacter) { + shouldIndentNextCharacter = false; + + if (charIndex === chunk.start) { + chunk.prependRight(indentStr); + } else { + this._splitChunk(chunk, charIndex); + chunk = chunk.next; + chunk.prependRight(indentStr); + } + } + } + + charIndex += 1; + } + } + + charIndex = chunk.end; + chunk = chunk.next; + } + + this.outro = this.outro.replace(pattern, replacer); + + return this; + } + + insert() { + throw new Error( + 'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)', + ); + } + + insertLeft(index, content) { + if (!warned.insertLeft) { + console.warn( + 'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead', + ); + warned.insertLeft = true; + } + + return this.appendLeft(index, content); + } + + insertRight(index, content) { + if (!warned.insertRight) { + console.warn( + 'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead', + ); + warned.insertRight = true; + } + + return this.prependRight(index, content); + } + + move(start, end, index) { + start = start + this.offset; + end = end + this.offset; + index = index + this.offset; + + if (index >= start && index <= end) throw new Error('Cannot move a selection inside itself'); + + this._split(start); + this._split(end); + this._split(index); + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + const oldLeft = first.previous; + const oldRight = last.next; + + const newRight = this.byStart[index]; + if (!newRight && last === this.lastChunk) return this; + const newLeft = newRight ? newRight.previous : this.lastChunk; + + if (oldLeft) oldLeft.next = oldRight; + if (oldRight) oldRight.previous = oldLeft; + + if (newLeft) newLeft.next = first; + if (newRight) newRight.previous = last; + + if (!first.previous) this.firstChunk = last.next; + if (!last.next) { + this.lastChunk = first.previous; + this.lastChunk.next = null; + } + + first.previous = newLeft; + last.next = newRight || null; + + if (!newLeft) this.firstChunk = first; + if (!newRight) this.lastChunk = last; + return this; + } + + overwrite(start, end, content, options) { + options = options || {}; + return this.update(start, end, content, { ...options, overwrite: !options.contentOnly }); + } + + update(start, end, content, options) { + start = start + this.offset; + end = end + this.offset; + + if (typeof content !== 'string') throw new TypeError('replacement content must be a string'); + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (end > this.original.length) throw new Error('end is out of bounds'); + if (start === end) + throw new Error( + 'Cannot overwrite a zero-length range – use appendLeft or prependRight instead', + ); + + this._split(start); + this._split(end); + + if (options === true) { + if (!warned.storeName) { + console.warn( + 'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string', + ); + warned.storeName = true; + } + + options = { storeName: true }; + } + const storeName = options !== undefined ? options.storeName : false; + const overwrite = options !== undefined ? options.overwrite : false; + + if (storeName) { + const original = this.original.slice(start, end); + Object.defineProperty(this.storedNames, original, { + writable: true, + value: true, + enumerable: true, + }); + } + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + if (first) { + let chunk = first; + while (chunk !== last) { + if (chunk.next !== this.byStart[chunk.end]) { + throw new Error('Cannot overwrite across a split point'); + } + chunk = chunk.next; + chunk.edit('', false); + } + + first.edit(content, storeName, !overwrite); + } else { + // must be inserting at the end + const newChunk = new Chunk(start, end, '').edit(content, storeName); + + // TODO last chunk in the array may not be the last chunk, if it's moved... + last.next = newChunk; + newChunk.previous = last; + } + return this; + } + + prepend(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.intro = content + this.intro; + return this; + } + + prependLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.prependLeft(content); + } else { + this.intro = content + this.intro; + } + return this; + } + + prependRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.prependRight(content); + } else { + this.outro = content + this.outro; + } + return this; + } + + remove(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.intro = ''; + chunk.outro = ''; + chunk.edit(''); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + reset(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.reset(); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + lastChar() { + if (this.outro.length) return this.outro[this.outro.length - 1]; + let chunk = this.lastChunk; + do { + if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1]; + if (chunk.content.length) return chunk.content[chunk.content.length - 1]; + if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1]; + } while ((chunk = chunk.previous)); + if (this.intro.length) return this.intro[this.intro.length - 1]; + return ''; + } + + lastLine() { + let lineIndex = this.outro.lastIndexOf(n); + if (lineIndex !== -1) return this.outro.substr(lineIndex + 1); + let lineStr = this.outro; + let chunk = this.lastChunk; + do { + if (chunk.outro.length > 0) { + lineIndex = chunk.outro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.outro + lineStr; + } + + if (chunk.content.length > 0) { + lineIndex = chunk.content.lastIndexOf(n); + if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr; + lineStr = chunk.content + lineStr; + } + + if (chunk.intro.length > 0) { + lineIndex = chunk.intro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.intro + lineStr; + } + } while ((chunk = chunk.previous)); + lineIndex = this.intro.lastIndexOf(n); + if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr; + return this.intro + lineStr; + } + + slice(start = 0, end = this.original.length - this.offset) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + let result = ''; + + // find start chunk + let chunk = this.firstChunk; + while (chunk && (chunk.start > start || chunk.end <= start)) { + // found end chunk before start + if (chunk.start < end && chunk.end >= end) { + return result; + } + + chunk = chunk.next; + } + + if (chunk && chunk.edited && chunk.start !== start) + throw new Error(`Cannot use replaced character ${start} as slice start anchor.`); + + const startChunk = chunk; + while (chunk) { + if (chunk.intro && (startChunk !== chunk || chunk.start === start)) { + result += chunk.intro; + } + + const containsEnd = chunk.start < end && chunk.end >= end; + if (containsEnd && chunk.edited && chunk.end !== end) + throw new Error(`Cannot use replaced character ${end} as slice end anchor.`); + + const sliceStart = startChunk === chunk ? start - chunk.start : 0; + const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length; + + result += chunk.content.slice(sliceStart, sliceEnd); + + if (chunk.outro && (!containsEnd || chunk.end === end)) { + result += chunk.outro; + } + + if (containsEnd) { + break; + } + + chunk = chunk.next; + } + + return result; + } + + // TODO deprecate this? not really very useful + snip(start, end) { + const clone = this.clone(); + clone.remove(0, start); + clone.remove(end, clone.original.length); + + return clone; + } + + _split(index) { + if (this.byStart[index] || this.byEnd[index]) return; + + let chunk = this.lastSearchedChunk; + let previousChunk = chunk; + const searchForward = index > chunk.end; + + while (chunk) { + if (chunk.contains(index)) return this._splitChunk(chunk, index); + + chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start]; + + // Prevent infinite loop (e.g. via empty chunks, where start === end) + if (chunk === previousChunk) return; + + previousChunk = chunk; + } + } + + _splitChunk(chunk, index) { + if (chunk.edited && chunk.content.length) { + // zero-length edited chunks are a special case (overlapping replacements) + const loc = getLocator(this.original)(index); + throw new Error( + `Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`, + ); + } + + const newChunk = chunk.split(index); + + this.byEnd[index] = chunk; + this.byStart[index] = newChunk; + this.byEnd[newChunk.end] = newChunk; + + if (chunk === this.lastChunk) this.lastChunk = newChunk; + + this.lastSearchedChunk = chunk; + return true; + } + + toString() { + let str = this.intro; + + let chunk = this.firstChunk; + while (chunk) { + str += chunk.toString(); + chunk = chunk.next; + } + + return str + this.outro; + } + + isEmpty() { + let chunk = this.firstChunk; + do { + if ( + (chunk.intro.length && chunk.intro.trim()) || + (chunk.content.length && chunk.content.trim()) || + (chunk.outro.length && chunk.outro.trim()) + ) + return false; + } while ((chunk = chunk.next)); + return true; + } + + length() { + let chunk = this.firstChunk; + let length = 0; + do { + length += chunk.intro.length + chunk.content.length + chunk.outro.length; + } while ((chunk = chunk.next)); + return length; + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimEndAborted(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + let chunk = this.lastChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimEnd(rx); + + // if chunk was trimmed, we have a new lastChunk + if (chunk.end !== end) { + if (this.lastChunk === chunk) { + this.lastChunk = chunk.next; + } + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.previous; + } while (chunk); + + return false; + } + + trimEnd(charType) { + this.trimEndAborted(charType); + return this; + } + trimStartAborted(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + let chunk = this.firstChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimStart(rx); + + if (chunk.end !== end) { + // special case... + if (chunk === this.lastChunk) this.lastChunk = chunk.next; + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.next; + } while (chunk); + + return false; + } + + trimStart(charType) { + this.trimStartAborted(charType); + return this; + } + + hasChanged() { + return this.original !== this.toString(); + } + + _replaceRegexp(searchValue, replacement) { + function getReplacement(match, str) { + if (typeof replacement === 'string') { + return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter + if (i === '$') return '$'; + if (i === '&') return match[0]; + const num = +i; + if (num < match.length) return match[+i]; + return `$${i}`; + }); + } else { + return replacement(...match, match.index, str, match.groups); + } + } + function matchAll(re, str) { + let match; + const matches = []; + while ((match = re.exec(str))) { + matches.push(match); + } + return matches; + } + if (searchValue.global) { + const matches = matchAll(searchValue, this.original); + matches.forEach((match) => { + if (match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + }); + } else { + const match = this.original.match(searchValue); + if (match && match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + } + return this; + } + + _replaceString(string, replacement) { + const { original } = this; + const index = original.indexOf(string); + + if (index !== -1) { + this.overwrite(index, index + string.length, replacement); + } + + return this; + } + + replace(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceString(searchValue, replacement); + } + + return this._replaceRegexp(searchValue, replacement); + } + + _replaceAllString(string, replacement) { + const { original } = this; + const stringLength = string.length; + for ( + let index = original.indexOf(string); + index !== -1; + index = original.indexOf(string, index + stringLength) + ) { + const previous = original.slice(index, index + stringLength); + if (previous !== replacement) this.overwrite(index, index + stringLength, replacement); + } + + return this; + } + + replaceAll(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceAllString(searchValue, replacement); + } + + if (!searchValue.global) { + throw new TypeError( + 'MagicString.prototype.replaceAll called with a non-global RegExp argument', + ); + } + + return this._replaceRegexp(searchValue, replacement); + } + } + + const hasOwnProp = Object.prototype.hasOwnProperty; + + class Bundle { + constructor(options = {}) { + this.intro = options.intro || ''; + this.separator = options.separator !== undefined ? options.separator : '\n'; + this.sources = []; + this.uniqueSources = []; + this.uniqueSourceIndexByFilename = {}; + } + + addSource(source) { + if (source instanceof MagicString) { + return this.addSource({ + content: source, + filename: source.filename, + separator: this.separator, + }); + } + + if (!isObject(source) || !source.content) { + throw new Error( + 'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`', + ); + } + + ['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => { + if (!hasOwnProp.call(source, option)) source[option] = source.content[option]; + }); + + if (source.separator === undefined) { + // TODO there's a bunch of this sort of thing, needs cleaning up + source.separator = this.separator; + } + + if (source.filename) { + if (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) { + this.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length; + this.uniqueSources.push({ filename: source.filename, content: source.content.original }); + } else { + const uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]]; + if (source.content.original !== uniqueSource.content) { + throw new Error(`Illegal source: same filename (${source.filename}), different contents`); + } + } + } + + this.sources.push(source); + return this; + } + + append(str, options) { + this.addSource({ + content: new MagicString(str), + separator: (options && options.separator) || '', + }); + + return this; + } + + clone() { + const bundle = new Bundle({ + intro: this.intro, + separator: this.separator, + }); + + this.sources.forEach((source) => { + bundle.addSource({ + filename: source.filename, + content: source.content.clone(), + separator: source.separator, + }); + }); + + return bundle; + } + + generateDecodedMap(options = {}) { + const names = []; + let x_google_ignoreList = undefined; + this.sources.forEach((source) => { + Object.keys(source.content.storedNames).forEach((name) => { + if (!~names.indexOf(name)) names.push(name); + }); + }); + + const mappings = new Mappings(options.hires); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.sources.forEach((source, i) => { + if (i > 0) { + mappings.advance(this.separator); + } + + const sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1; + const magicString = source.content; + const locate = getLocator(magicString.original); + + if (magicString.intro) { + mappings.advance(magicString.intro); + } + + magicString.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (source.filename) { + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk( + sourceIndex, + chunk, + magicString.original, + loc, + magicString.sourcemapLocations, + ); + } + } else { + mappings.advance(chunk.content); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + if (magicString.outro) { + mappings.advance(magicString.outro); + } + + if (source.ignoreList && sourceIndex !== -1) { + if (x_google_ignoreList === undefined) { + x_google_ignoreList = []; + } + x_google_ignoreList.push(sourceIndex); + } + }); + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: this.uniqueSources.map((source) => { + return options.file ? getRelativePath(options.file, source.filename) : source.filename; + }), + sourcesContent: this.uniqueSources.map((source) => { + return options.includeContent ? source.content : null; + }), + names, + mappings: mappings.raw, + x_google_ignoreList, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + getIndentString() { + const indentStringCounts = {}; + + this.sources.forEach((source) => { + const indentStr = source.content._getRawIndentString(); + + if (indentStr === null) return; + + if (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0; + indentStringCounts[indentStr] += 1; + }); + + return ( + Object.keys(indentStringCounts).sort((a, b) => { + return indentStringCounts[a] - indentStringCounts[b]; + })[0] || '\t' + ); + } + + indent(indentStr) { + if (!arguments.length) { + indentStr = this.getIndentString(); + } + + if (indentStr === '') return this; // noop + + let trailingNewline = !this.intro || this.intro.slice(-1) === '\n'; + + this.sources.forEach((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const indentStart = trailingNewline || (i > 0 && /\r?\n$/.test(separator)); + + source.content.indent(indentStr, { + exclude: source.indentExclusionRanges, + indentStart, //: trailingNewline || /\r?\n$/.test( separator ) //true///\r?\n/.test( separator ) + }); + + trailingNewline = source.content.lastChar() === '\n'; + }); + + if (this.intro) { + this.intro = + indentStr + + this.intro.replace(/^[^\n]/gm, (match, index) => { + return index > 0 ? indentStr + match : match; + }); + } + + return this; + } + + prepend(str) { + this.intro = str + this.intro; + return this; + } + + toString() { + const body = this.sources + .map((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const str = (i > 0 ? separator : '') + source.content.toString(); + + return str; + }) + .join(''); + + return this.intro + body; + } + + isEmpty() { + if (this.intro.length && this.intro.trim()) return false; + if (this.sources.some((source) => !source.content.isEmpty())) return false; + return true; + } + + length() { + return this.sources.reduce( + (length, source) => length + source.content.length(), + this.intro.length, + ); + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimStart(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + this.intro = this.intro.replace(rx, ''); + + if (!this.intro) { + let source; + let i = 0; + + do { + source = this.sources[i++]; + if (!source) { + break; + } + } while (!source.content.trimStartAborted(charType)); + } + + return this; + } + + trimEnd(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + let source; + let i = this.sources.length - 1; + + do { + source = this.sources[i--]; + if (!source) { + this.intro = this.intro.replace(rx, ''); + break; + } + } while (!source.content.trimEndAborted(charType)); + + return this; + } + } + + MagicString.Bundle = Bundle; + MagicString.SourceMap = SourceMap; + MagicString.default = MagicString; // work around TypeScript bug https://github.com/Rich-Harris/magic-string/pull/121 + + return MagicString; + +})); +//# sourceMappingURL=magic-string.umd.js.map diff --git a/node_modules/magic-string/dist/magic-string.umd.js.map b/node_modules/magic-string/dist/magic-string.umd.js.map new file mode 100644 index 0000000000..dad32bbaa9 --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"magic-string.umd.js","sources":["../src/BitSet.js","../src/Chunk.js","../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs","../src/SourceMap.js","../src/utils/guessIndent.js","../src/utils/getRelativePath.js","../src/utils/isObject.js","../src/utils/getLocator.js","../src/utils/Mappings.js","../src/MagicString.js","../src/Bundle.js","../src/index-legacy.js"],"sourcesContent":["export default class BitSet {\n\tconstructor(arg) {\n\t\tthis.bits = arg instanceof BitSet ? arg.bits.slice() : [];\n\t}\n\n\tadd(n) {\n\t\tthis.bits[n >> 5] |= 1 << (n & 31);\n\t}\n\n\thas(n) {\n\t\treturn !!(this.bits[n >> 5] & (1 << (n & 31)));\n\t}\n}\n","export default class Chunk {\n\tconstructor(start, end, content) {\n\t\tthis.start = start;\n\t\tthis.end = end;\n\t\tthis.original = content;\n\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\n\t\tthis.content = content;\n\t\tthis.storeName = false;\n\t\tthis.edited = false;\n\n\t\tif (DEBUG) {\n\t\t\t// we make these non-enumerable, for sanity while debugging\n\t\t\tObject.defineProperties(this, {\n\t\t\t\tprevious: { writable: true, value: null },\n\t\t\t\tnext: { writable: true, value: null },\n\t\t\t});\n\t\t} else {\n\t\t\tthis.previous = null;\n\t\t\tthis.next = null;\n\t\t}\n\t}\n\n\tappendLeft(content) {\n\t\tthis.outro += content;\n\t}\n\n\tappendRight(content) {\n\t\tthis.intro = this.intro + content;\n\t}\n\n\tclone() {\n\t\tconst chunk = new Chunk(this.start, this.end, this.original);\n\n\t\tchunk.intro = this.intro;\n\t\tchunk.outro = this.outro;\n\t\tchunk.content = this.content;\n\t\tchunk.storeName = this.storeName;\n\t\tchunk.edited = this.edited;\n\n\t\treturn chunk;\n\t}\n\n\tcontains(index) {\n\t\treturn this.start < index && index < this.end;\n\t}\n\n\teachNext(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.next;\n\t\t}\n\t}\n\n\teachPrevious(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.previous;\n\t\t}\n\t}\n\n\tedit(content, storeName, contentOnly) {\n\t\tthis.content = content;\n\t\tif (!contentOnly) {\n\t\t\tthis.intro = '';\n\t\t\tthis.outro = '';\n\t\t}\n\t\tthis.storeName = storeName;\n\n\t\tthis.edited = true;\n\n\t\treturn this;\n\t}\n\n\tprependLeft(content) {\n\t\tthis.outro = content + this.outro;\n\t}\n\n\tprependRight(content) {\n\t\tthis.intro = content + this.intro;\n\t}\n\n\treset() {\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\t\tif (this.edited) {\n\t\t\tthis.content = this.original;\n\t\t\tthis.storeName = false;\n\t\t\tthis.edited = false;\n\t\t}\n\t}\n\n\tsplit(index) {\n\t\tconst sliceIndex = index - this.start;\n\n\t\tconst originalBefore = this.original.slice(0, sliceIndex);\n\t\tconst originalAfter = this.original.slice(sliceIndex);\n\n\t\tthis.original = originalBefore;\n\n\t\tconst newChunk = new Chunk(index, this.end, originalAfter);\n\t\tnewChunk.outro = this.outro;\n\t\tthis.outro = '';\n\n\t\tthis.end = index;\n\n\t\tif (this.edited) {\n\t\t\t// after split we should save the edit content record into the correct chunk\n\t\t\t// to make sure sourcemap correct\n\t\t\t// For example:\n\t\t\t// ' test'.trim()\n\t\t\t// split -> ' ' + 'test'\n\t\t\t// ✔️ edit -> '' + 'test'\n\t\t\t// ✖️ edit -> 'test' + ''\n\t\t\t// TODO is this block necessary?...\n\t\t\tnewChunk.edit('', false);\n\t\t\tthis.content = '';\n\t\t} else {\n\t\t\tthis.content = originalBefore;\n\t\t}\n\n\t\tnewChunk.next = this.next;\n\t\tif (newChunk.next) newChunk.next.previous = newChunk;\n\t\tnewChunk.previous = this;\n\t\tthis.next = newChunk;\n\n\t\treturn newChunk;\n\t}\n\n\ttoString() {\n\t\treturn this.intro + this.content + this.outro;\n\t}\n\n\ttrimEnd(rx) {\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tthis.split(this.start + trimmed.length).edit('', undefined, true);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tthis.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\tif (this.intro.length) return true;\n\t\t}\n\t}\n\n\ttrimStart(rx) {\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tconst newChunk = this.split(this.end - trimmed.length);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tnewChunk.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t\tthis.edit('', undefined, true);\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.outro = this.outro.replace(rx, '');\n\t\t\tif (this.outro.length) return true;\n\t\t}\n\t}\n}\n","// src/vlq.ts\nvar comma = \",\".charCodeAt(0);\nvar semicolon = \";\".charCodeAt(0);\nvar chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nvar intToChar = new Uint8Array(64);\nvar charToInt = new Uint8Array(128);\nfor (let i = 0; i < chars.length; i++) {\n const c = chars.charCodeAt(i);\n intToChar[i] = c;\n charToInt[c] = i;\n}\nfunction decodeInteger(reader, relative) {\n let value = 0;\n let shift = 0;\n let integer = 0;\n do {\n const c = reader.next();\n integer = charToInt[c];\n value |= (integer & 31) << shift;\n shift += 5;\n } while (integer & 32);\n const shouldNegate = value & 1;\n value >>>= 1;\n if (shouldNegate) {\n value = -2147483648 | -value;\n }\n return relative + value;\n}\nfunction encodeInteger(builder, num, relative) {\n let delta = num - relative;\n delta = delta < 0 ? -delta << 1 | 1 : delta << 1;\n do {\n let clamped = delta & 31;\n delta >>>= 5;\n if (delta > 0) clamped |= 32;\n builder.write(intToChar[clamped]);\n } while (delta > 0);\n return num;\n}\nfunction hasMoreVlq(reader, max) {\n if (reader.pos >= max) return false;\n return reader.peek() !== comma;\n}\n\n// src/strings.ts\nvar bufLength = 1024 * 16;\nvar td = typeof TextDecoder !== \"undefined\" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== \"undefined\" ? {\n decode(buf) {\n const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);\n return out.toString();\n }\n} : {\n decode(buf) {\n let out = \"\";\n for (let i = 0; i < buf.length; i++) {\n out += String.fromCharCode(buf[i]);\n }\n return out;\n }\n};\nvar StringWriter = class {\n constructor() {\n this.pos = 0;\n this.out = \"\";\n this.buffer = new Uint8Array(bufLength);\n }\n write(v) {\n const { buffer } = this;\n buffer[this.pos++] = v;\n if (this.pos === bufLength) {\n this.out += td.decode(buffer);\n this.pos = 0;\n }\n }\n flush() {\n const { buffer, out, pos } = this;\n return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;\n }\n};\nvar StringReader = class {\n constructor(buffer) {\n this.pos = 0;\n this.buffer = buffer;\n }\n next() {\n return this.buffer.charCodeAt(this.pos++);\n }\n peek() {\n return this.buffer.charCodeAt(this.pos);\n }\n indexOf(char) {\n const { buffer, pos } = this;\n const idx = buffer.indexOf(char, pos);\n return idx === -1 ? buffer.length : idx;\n }\n};\n\n// src/scopes.ts\nvar EMPTY = [];\nfunction decodeOriginalScopes(input) {\n const { length } = input;\n const reader = new StringReader(input);\n const scopes = [];\n const stack = [];\n let line = 0;\n for (; reader.pos < length; reader.pos++) {\n line = decodeInteger(reader, line);\n const column = decodeInteger(reader, 0);\n if (!hasMoreVlq(reader, length)) {\n const last = stack.pop();\n last[2] = line;\n last[3] = column;\n continue;\n }\n const kind = decodeInteger(reader, 0);\n const fields = decodeInteger(reader, 0);\n const hasName = fields & 1;\n const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind];\n let vars = EMPTY;\n if (hasMoreVlq(reader, length)) {\n vars = [];\n do {\n const varsIndex = decodeInteger(reader, 0);\n vars.push(varsIndex);\n } while (hasMoreVlq(reader, length));\n }\n scope.vars = vars;\n scopes.push(scope);\n stack.push(scope);\n }\n return scopes;\n}\nfunction encodeOriginalScopes(scopes) {\n const writer = new StringWriter();\n for (let i = 0; i < scopes.length; ) {\n i = _encodeOriginalScopes(scopes, i, writer, [0]);\n }\n return writer.flush();\n}\nfunction _encodeOriginalScopes(scopes, index, writer, state) {\n const scope = scopes[index];\n const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope;\n if (index > 0) writer.write(comma);\n state[0] = encodeInteger(writer, startLine, state[0]);\n encodeInteger(writer, startColumn, 0);\n encodeInteger(writer, kind, 0);\n const fields = scope.length === 6 ? 1 : 0;\n encodeInteger(writer, fields, 0);\n if (scope.length === 6) encodeInteger(writer, scope[5], 0);\n for (const v of vars) {\n encodeInteger(writer, v, 0);\n }\n for (index++; index < scopes.length; ) {\n const next = scopes[index];\n const { 0: l, 1: c } = next;\n if (l > endLine || l === endLine && c >= endColumn) {\n break;\n }\n index = _encodeOriginalScopes(scopes, index, writer, state);\n }\n writer.write(comma);\n state[0] = encodeInteger(writer, endLine, state[0]);\n encodeInteger(writer, endColumn, 0);\n return index;\n}\nfunction decodeGeneratedRanges(input) {\n const { length } = input;\n const reader = new StringReader(input);\n const ranges = [];\n const stack = [];\n let genLine = 0;\n let definitionSourcesIndex = 0;\n let definitionScopeIndex = 0;\n let callsiteSourcesIndex = 0;\n let callsiteLine = 0;\n let callsiteColumn = 0;\n let bindingLine = 0;\n let bindingColumn = 0;\n do {\n const semi = reader.indexOf(\";\");\n let genColumn = 0;\n for (; reader.pos < semi; reader.pos++) {\n genColumn = decodeInteger(reader, genColumn);\n if (!hasMoreVlq(reader, semi)) {\n const last = stack.pop();\n last[2] = genLine;\n last[3] = genColumn;\n continue;\n }\n const fields = decodeInteger(reader, 0);\n const hasDefinition = fields & 1;\n const hasCallsite = fields & 2;\n const hasScope = fields & 4;\n let callsite = null;\n let bindings = EMPTY;\n let range;\n if (hasDefinition) {\n const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex);\n definitionScopeIndex = decodeInteger(\n reader,\n definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0\n );\n definitionSourcesIndex = defSourcesIndex;\n range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex];\n } else {\n range = [genLine, genColumn, 0, 0];\n }\n range.isScope = !!hasScope;\n if (hasCallsite) {\n const prevCsi = callsiteSourcesIndex;\n const prevLine = callsiteLine;\n callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex);\n const sameSource = prevCsi === callsiteSourcesIndex;\n callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0);\n callsiteColumn = decodeInteger(\n reader,\n sameSource && prevLine === callsiteLine ? callsiteColumn : 0\n );\n callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn];\n }\n range.callsite = callsite;\n if (hasMoreVlq(reader, semi)) {\n bindings = [];\n do {\n bindingLine = genLine;\n bindingColumn = genColumn;\n const expressionsCount = decodeInteger(reader, 0);\n let expressionRanges;\n if (expressionsCount < -1) {\n expressionRanges = [[decodeInteger(reader, 0)]];\n for (let i = -1; i > expressionsCount; i--) {\n const prevBl = bindingLine;\n bindingLine = decodeInteger(reader, bindingLine);\n bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0);\n const expression = decodeInteger(reader, 0);\n expressionRanges.push([expression, bindingLine, bindingColumn]);\n }\n } else {\n expressionRanges = [[expressionsCount]];\n }\n bindings.push(expressionRanges);\n } while (hasMoreVlq(reader, semi));\n }\n range.bindings = bindings;\n ranges.push(range);\n stack.push(range);\n }\n genLine++;\n reader.pos = semi + 1;\n } while (reader.pos < length);\n return ranges;\n}\nfunction encodeGeneratedRanges(ranges) {\n if (ranges.length === 0) return \"\";\n const writer = new StringWriter();\n for (let i = 0; i < ranges.length; ) {\n i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]);\n }\n return writer.flush();\n}\nfunction _encodeGeneratedRanges(ranges, index, writer, state) {\n const range = ranges[index];\n const {\n 0: startLine,\n 1: startColumn,\n 2: endLine,\n 3: endColumn,\n isScope,\n callsite,\n bindings\n } = range;\n if (state[0] < startLine) {\n catchupLine(writer, state[0], startLine);\n state[0] = startLine;\n state[1] = 0;\n } else if (index > 0) {\n writer.write(comma);\n }\n state[1] = encodeInteger(writer, range[1], state[1]);\n const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0);\n encodeInteger(writer, fields, 0);\n if (range.length === 6) {\n const { 4: sourcesIndex, 5: scopesIndex } = range;\n if (sourcesIndex !== state[2]) {\n state[3] = 0;\n }\n state[2] = encodeInteger(writer, sourcesIndex, state[2]);\n state[3] = encodeInteger(writer, scopesIndex, state[3]);\n }\n if (callsite) {\n const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite;\n if (sourcesIndex !== state[4]) {\n state[5] = 0;\n state[6] = 0;\n } else if (callLine !== state[5]) {\n state[6] = 0;\n }\n state[4] = encodeInteger(writer, sourcesIndex, state[4]);\n state[5] = encodeInteger(writer, callLine, state[5]);\n state[6] = encodeInteger(writer, callColumn, state[6]);\n }\n if (bindings) {\n for (const binding of bindings) {\n if (binding.length > 1) encodeInteger(writer, -binding.length, 0);\n const expression = binding[0][0];\n encodeInteger(writer, expression, 0);\n let bindingStartLine = startLine;\n let bindingStartColumn = startColumn;\n for (let i = 1; i < binding.length; i++) {\n const expRange = binding[i];\n bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine);\n bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn);\n encodeInteger(writer, expRange[0], 0);\n }\n }\n }\n for (index++; index < ranges.length; ) {\n const next = ranges[index];\n const { 0: l, 1: c } = next;\n if (l > endLine || l === endLine && c >= endColumn) {\n break;\n }\n index = _encodeGeneratedRanges(ranges, index, writer, state);\n }\n if (state[0] < endLine) {\n catchupLine(writer, state[0], endLine);\n state[0] = endLine;\n state[1] = 0;\n } else {\n writer.write(comma);\n }\n state[1] = encodeInteger(writer, endColumn, state[1]);\n return index;\n}\nfunction catchupLine(writer, lastLine, line) {\n do {\n writer.write(semicolon);\n } while (++lastLine < line);\n}\n\n// src/sourcemap-codec.ts\nfunction decode(mappings) {\n const { length } = mappings;\n const reader = new StringReader(mappings);\n const decoded = [];\n let genColumn = 0;\n let sourcesIndex = 0;\n let sourceLine = 0;\n let sourceColumn = 0;\n let namesIndex = 0;\n do {\n const semi = reader.indexOf(\";\");\n const line = [];\n let sorted = true;\n let lastCol = 0;\n genColumn = 0;\n while (reader.pos < semi) {\n let seg;\n genColumn = decodeInteger(reader, genColumn);\n if (genColumn < lastCol) sorted = false;\n lastCol = genColumn;\n if (hasMoreVlq(reader, semi)) {\n sourcesIndex = decodeInteger(reader, sourcesIndex);\n sourceLine = decodeInteger(reader, sourceLine);\n sourceColumn = decodeInteger(reader, sourceColumn);\n if (hasMoreVlq(reader, semi)) {\n namesIndex = decodeInteger(reader, namesIndex);\n seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex];\n } else {\n seg = [genColumn, sourcesIndex, sourceLine, sourceColumn];\n }\n } else {\n seg = [genColumn];\n }\n line.push(seg);\n reader.pos++;\n }\n if (!sorted) sort(line);\n decoded.push(line);\n reader.pos = semi + 1;\n } while (reader.pos <= length);\n return decoded;\n}\nfunction sort(line) {\n line.sort(sortComparator);\n}\nfunction sortComparator(a, b) {\n return a[0] - b[0];\n}\nfunction encode(decoded) {\n const writer = new StringWriter();\n let sourcesIndex = 0;\n let sourceLine = 0;\n let sourceColumn = 0;\n let namesIndex = 0;\n for (let i = 0; i < decoded.length; i++) {\n const line = decoded[i];\n if (i > 0) writer.write(semicolon);\n if (line.length === 0) continue;\n let genColumn = 0;\n for (let j = 0; j < line.length; j++) {\n const segment = line[j];\n if (j > 0) writer.write(comma);\n genColumn = encodeInteger(writer, segment[0], genColumn);\n if (segment.length === 1) continue;\n sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);\n sourceLine = encodeInteger(writer, segment[2], sourceLine);\n sourceColumn = encodeInteger(writer, segment[3], sourceColumn);\n if (segment.length === 4) continue;\n namesIndex = encodeInteger(writer, segment[4], namesIndex);\n }\n }\n return writer.flush();\n}\nexport {\n decode,\n decodeGeneratedRanges,\n decodeOriginalScopes,\n encode,\n encodeGeneratedRanges,\n encodeOriginalScopes\n};\n//# sourceMappingURL=sourcemap-codec.mjs.map\n","import { encode } from '@jridgewell/sourcemap-codec';\n\nfunction getBtoa() {\n\tif (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') {\n\t\treturn (str) => globalThis.btoa(unescape(encodeURIComponent(str)));\n\t} else if (typeof Buffer === 'function') {\n\t\treturn (str) => Buffer.from(str, 'utf-8').toString('base64');\n\t} else {\n\t\treturn () => {\n\t\t\tthrow new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');\n\t\t};\n\t}\n}\n\nconst btoa = /*#__PURE__*/ getBtoa();\n\nexport default class SourceMap {\n\tconstructor(properties) {\n\t\tthis.version = 3;\n\t\tthis.file = properties.file;\n\t\tthis.sources = properties.sources;\n\t\tthis.sourcesContent = properties.sourcesContent;\n\t\tthis.names = properties.names;\n\t\tthis.mappings = encode(properties.mappings);\n\t\tif (typeof properties.x_google_ignoreList !== 'undefined') {\n\t\t\tthis.x_google_ignoreList = properties.x_google_ignoreList;\n\t\t}\n\t\tif (typeof properties.debugId !== 'undefined') {\n\t\t\tthis.debugId = properties.debugId;\n\t\t}\n\t}\n\n\ttoString() {\n\t\treturn JSON.stringify(this);\n\t}\n\n\ttoUrl() {\n\t\treturn 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());\n\t}\n}\n","export default function guessIndent(code) {\n\tconst lines = code.split('\\n');\n\n\tconst tabbed = lines.filter((line) => /^\\t+/.test(line));\n\tconst spaced = lines.filter((line) => /^ {2,}/.test(line));\n\n\tif (tabbed.length === 0 && spaced.length === 0) {\n\t\treturn null;\n\t}\n\n\t// More lines tabbed than spaced? Assume tabs, and\n\t// default to tabs in the case of a tie (or nothing\n\t// to go on)\n\tif (tabbed.length >= spaced.length) {\n\t\treturn '\\t';\n\t}\n\n\t// Otherwise, we need to guess the multiple\n\tconst min = spaced.reduce((previous, current) => {\n\t\tconst numSpaces = /^ +/.exec(current)[0].length;\n\t\treturn Math.min(numSpaces, previous);\n\t}, Infinity);\n\n\treturn new Array(min + 1).join(' ');\n}\n","export default function getRelativePath(from, to) {\n\tconst fromParts = from.split(/[/\\\\]/);\n\tconst toParts = to.split(/[/\\\\]/);\n\n\tfromParts.pop(); // get dirname\n\n\twhile (fromParts[0] === toParts[0]) {\n\t\tfromParts.shift();\n\t\ttoParts.shift();\n\t}\n\n\tif (fromParts.length) {\n\t\tlet i = fromParts.length;\n\t\twhile (i--) fromParts[i] = '..';\n\t}\n\n\treturn fromParts.concat(toParts).join('/');\n}\n","const toString = Object.prototype.toString;\n\nexport default function isObject(thing) {\n\treturn toString.call(thing) === '[object Object]';\n}\n","export default function getLocator(source) {\n\tconst originalLines = source.split('\\n');\n\tconst lineOffsets = [];\n\n\tfor (let i = 0, pos = 0; i < originalLines.length; i++) {\n\t\tlineOffsets.push(pos);\n\t\tpos += originalLines[i].length + 1;\n\t}\n\n\treturn function locate(index) {\n\t\tlet i = 0;\n\t\tlet j = lineOffsets.length;\n\t\twhile (i < j) {\n\t\t\tconst m = (i + j) >> 1;\n\t\t\tif (index < lineOffsets[m]) {\n\t\t\t\tj = m;\n\t\t\t} else {\n\t\t\t\ti = m + 1;\n\t\t\t}\n\t\t}\n\t\tconst line = i - 1;\n\t\tconst column = index - lineOffsets[line];\n\t\treturn { line, column };\n\t};\n}\n","const wordRegex = /\\w/;\n\nexport default class Mappings {\n\tconstructor(hires) {\n\t\tthis.hires = hires;\n\t\tthis.generatedCodeLine = 0;\n\t\tthis.generatedCodeColumn = 0;\n\t\tthis.raw = [];\n\t\tthis.rawSegments = this.raw[this.generatedCodeLine] = [];\n\t\tthis.pending = null;\n\t}\n\n\taddEdit(sourceIndex, content, loc, nameIndex) {\n\t\tif (content.length) {\n\t\t\tconst contentLengthMinusOne = content.length - 1;\n\t\t\tlet contentLineEnd = content.indexOf('\\n', 0);\n\t\t\tlet previousContentLineEnd = -1;\n\t\t\t// Loop through each line in the content and add a segment, but stop if the last line is empty,\n\t\t\t// else code afterwards would fill one line too many\n\t\t\twhile (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {\n\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\t\tif (nameIndex >= 0) {\n\t\t\t\t\tsegment.push(nameIndex);\n\t\t\t\t}\n\t\t\t\tthis.rawSegments.push(segment);\n\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\n\t\t\t\tpreviousContentLineEnd = contentLineEnd;\n\t\t\t\tcontentLineEnd = content.indexOf('\\n', contentLineEnd + 1);\n\t\t\t}\n\n\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\tif (nameIndex >= 0) {\n\t\t\t\tsegment.push(nameIndex);\n\t\t\t}\n\t\t\tthis.rawSegments.push(segment);\n\n\t\t\tthis.advance(content.slice(previousContentLineEnd + 1));\n\t\t} else if (this.pending) {\n\t\t\tthis.rawSegments.push(this.pending);\n\t\t\tthis.advance(content);\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\taddUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {\n\t\tlet originalCharIndex = chunk.start;\n\t\tlet first = true;\n\t\t// when iterating each char, check if it's in a word boundary\n\t\tlet charInHiresBoundary = false;\n\n\t\twhile (originalCharIndex < chunk.end) {\n\t\t\tif (original[originalCharIndex] === '\\n') {\n\t\t\t\tloc.line += 1;\n\t\t\t\tloc.column = 0;\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\t\t\t\tfirst = true;\n\t\t\t\tcharInHiresBoundary = false;\n\t\t\t} else {\n\t\t\t\tif (this.hires || first || sourcemapLocations.has(originalCharIndex)) {\n\t\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\n\t\t\t\t\tif (this.hires === 'boundary') {\n\t\t\t\t\t\t// in hires \"boundary\", group segments per word boundary than per char\n\t\t\t\t\t\tif (wordRegex.test(original[originalCharIndex])) {\n\t\t\t\t\t\t\t// for first char in the boundary found, start the boundary by pushing a segment\n\t\t\t\t\t\t\tif (!charInHiresBoundary) {\n\t\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\t\tcharInHiresBoundary = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// for non-word char, end the boundary by pushing a segment\n\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\tcharInHiresBoundary = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tloc.column += 1;\n\t\t\t\tthis.generatedCodeColumn += 1;\n\t\t\t\tfirst = false;\n\t\t\t}\n\n\t\t\toriginalCharIndex += 1;\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\tadvance(str) {\n\t\tif (!str) return;\n\n\t\tconst lines = str.split('\\n');\n\n\t\tif (lines.length > 1) {\n\t\t\tfor (let i = 0; i < lines.length - 1; i++) {\n\t\t\t\tthis.generatedCodeLine++;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t}\n\t\t\tthis.generatedCodeColumn = 0;\n\t\t}\n\n\t\tthis.generatedCodeColumn += lines[lines.length - 1].length;\n\t}\n}\n","import BitSet from './BitSet.js';\nimport Chunk from './Chunk.js';\nimport SourceMap from './SourceMap.js';\nimport guessIndent from './utils/guessIndent.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\nimport Stats from './utils/Stats.js';\n\nconst n = '\\n';\n\nconst warned = {\n\tinsertLeft: false,\n\tinsertRight: false,\n\tstoreName: false,\n};\n\nexport default class MagicString {\n\tconstructor(string, options = {}) {\n\t\tconst chunk = new Chunk(0, string.length, string);\n\n\t\tObject.defineProperties(this, {\n\t\t\toriginal: { writable: true, value: string },\n\t\t\toutro: { writable: true, value: '' },\n\t\t\tintro: { writable: true, value: '' },\n\t\t\tfirstChunk: { writable: true, value: chunk },\n\t\t\tlastChunk: { writable: true, value: chunk },\n\t\t\tlastSearchedChunk: { writable: true, value: chunk },\n\t\t\tbyStart: { writable: true, value: {} },\n\t\t\tbyEnd: { writable: true, value: {} },\n\t\t\tfilename: { writable: true, value: options.filename },\n\t\t\tindentExclusionRanges: { writable: true, value: options.indentExclusionRanges },\n\t\t\tsourcemapLocations: { writable: true, value: new BitSet() },\n\t\t\tstoredNames: { writable: true, value: {} },\n\t\t\tindentStr: { writable: true, value: undefined },\n\t\t\tignoreList: { writable: true, value: options.ignoreList },\n\t\t\toffset: { writable: true, value: options.offset || 0 },\n\t\t});\n\n\t\tif (DEBUG) {\n\t\t\tObject.defineProperty(this, 'stats', { value: new Stats() });\n\t\t}\n\n\t\tthis.byStart[0] = chunk;\n\t\tthis.byEnd[string.length] = chunk;\n\t}\n\n\taddSourcemapLocation(char) {\n\t\tthis.sourcemapLocations.add(char);\n\t}\n\n\tappend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.outro += content;\n\t\treturn this;\n\t}\n\n\tappendLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendLeft');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendLeft(content);\n\t\t} else {\n\t\t\tthis.intro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendLeft');\n\t\treturn this;\n\t}\n\n\tappendRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendRight(content);\n\t\t} else {\n\t\t\tthis.outro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendRight');\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset });\n\n\t\tlet originalChunk = this.firstChunk;\n\t\tlet clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());\n\n\t\twhile (originalChunk) {\n\t\t\tcloned.byStart[clonedChunk.start] = clonedChunk;\n\t\t\tcloned.byEnd[clonedChunk.end] = clonedChunk;\n\n\t\t\tconst nextOriginalChunk = originalChunk.next;\n\t\t\tconst nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();\n\n\t\t\tif (nextClonedChunk) {\n\t\t\t\tclonedChunk.next = nextClonedChunk;\n\t\t\t\tnextClonedChunk.previous = clonedChunk;\n\n\t\t\t\tclonedChunk = nextClonedChunk;\n\t\t\t}\n\n\t\t\toriginalChunk = nextOriginalChunk;\n\t\t}\n\n\t\tcloned.lastChunk = clonedChunk;\n\n\t\tif (this.indentExclusionRanges) {\n\t\t\tcloned.indentExclusionRanges = this.indentExclusionRanges.slice();\n\t\t}\n\n\t\tcloned.sourcemapLocations = new BitSet(this.sourcemapLocations);\n\n\t\tcloned.intro = this.intro;\n\t\tcloned.outro = this.outro;\n\n\t\treturn cloned;\n\t}\n\n\tgenerateDecodedMap(options) {\n\t\toptions = options || {};\n\n\t\tconst sourceIndex = 0;\n\t\tconst names = Object.keys(this.storedNames);\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tconst locate = getLocator(this.original);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.firstChunk.eachNext((chunk) => {\n\t\t\tconst loc = locate(chunk.start);\n\n\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tmappings.addEdit(\n\t\t\t\t\tsourceIndex,\n\t\t\t\t\tchunk.content,\n\t\t\t\t\tloc,\n\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tmappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);\n\t\t\t}\n\n\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t});\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: [\n\t\t\t\toptions.source ? getRelativePath(options.file || '', options.source) : options.file || '',\n\t\t\t],\n\t\t\tsourcesContent: options.includeContent ? [this.original] : undefined,\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\t_ensureindentStr() {\n\t\tif (this.indentStr === undefined) {\n\t\t\tthis.indentStr = guessIndent(this.original);\n\t\t}\n\t}\n\n\t_getRawIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr;\n\t}\n\n\tgetIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr === null ? '\\t' : this.indentStr;\n\t}\n\n\tindent(indentStr, options) {\n\t\tconst pattern = /^[^\\r\\n]/gm;\n\n\t\tif (isObject(indentStr)) {\n\t\t\toptions = indentStr;\n\t\t\tindentStr = undefined;\n\t\t}\n\n\t\tif (indentStr === undefined) {\n\t\t\tthis._ensureindentStr();\n\t\t\tindentStr = this.indentStr || '\\t';\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\toptions = options || {};\n\n\t\t// Process exclusion ranges\n\t\tconst isExcluded = {};\n\n\t\tif (options.exclude) {\n\t\t\tconst exclusions =\n\t\t\t\ttypeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;\n\t\t\texclusions.forEach((exclusion) => {\n\t\t\t\tfor (let i = exclusion[0]; i < exclusion[1]; i += 1) {\n\t\t\t\t\tisExcluded[i] = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tlet shouldIndentNextCharacter = options.indentStart !== false;\n\t\tconst replacer = (match) => {\n\t\t\tif (shouldIndentNextCharacter) return `${indentStr}${match}`;\n\t\t\tshouldIndentNextCharacter = true;\n\t\t\treturn match;\n\t\t};\n\n\t\tthis.intro = this.intro.replace(pattern, replacer);\n\n\t\tlet charIndex = 0;\n\t\tlet chunk = this.firstChunk;\n\n\t\twhile (chunk) {\n\t\t\tconst end = chunk.end;\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\tchunk.content = chunk.content.replace(pattern, replacer);\n\n\t\t\t\t\tif (chunk.content.length) {\n\t\t\t\t\t\tshouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\\n';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcharIndex = chunk.start;\n\n\t\t\t\twhile (charIndex < end) {\n\t\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\t\tconst char = this.original[charIndex];\n\n\t\t\t\t\t\tif (char === '\\n') {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = true;\n\t\t\t\t\t\t} else if (char !== '\\r' && shouldIndentNextCharacter) {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = false;\n\n\t\t\t\t\t\t\tif (charIndex === chunk.start) {\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis._splitChunk(chunk, charIndex);\n\t\t\t\t\t\t\t\tchunk = chunk.next;\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcharIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcharIndex = chunk.end;\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tthis.outro = this.outro.replace(pattern, replacer);\n\n\t\treturn this;\n\t}\n\n\tinsert() {\n\t\tthrow new Error(\n\t\t\t'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)',\n\t\t);\n\t}\n\n\tinsertLeft(index, content) {\n\t\tif (!warned.insertLeft) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead',\n\t\t\t);\n\t\t\twarned.insertLeft = true;\n\t\t}\n\n\t\treturn this.appendLeft(index, content);\n\t}\n\n\tinsertRight(index, content) {\n\t\tif (!warned.insertRight) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead',\n\t\t\t);\n\t\t\twarned.insertRight = true;\n\t\t}\n\n\t\treturn this.prependRight(index, content);\n\t}\n\n\tmove(start, end, index) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\t\tindex = index + this.offset;\n\n\t\tif (index >= start && index <= end) throw new Error('Cannot move a selection inside itself');\n\n\t\tif (DEBUG) this.stats.time('move');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\t\tthis._split(index);\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tconst oldLeft = first.previous;\n\t\tconst oldRight = last.next;\n\n\t\tconst newRight = this.byStart[index];\n\t\tif (!newRight && last === this.lastChunk) return this;\n\t\tconst newLeft = newRight ? newRight.previous : this.lastChunk;\n\n\t\tif (oldLeft) oldLeft.next = oldRight;\n\t\tif (oldRight) oldRight.previous = oldLeft;\n\n\t\tif (newLeft) newLeft.next = first;\n\t\tif (newRight) newRight.previous = last;\n\n\t\tif (!first.previous) this.firstChunk = last.next;\n\t\tif (!last.next) {\n\t\t\tthis.lastChunk = first.previous;\n\t\t\tthis.lastChunk.next = null;\n\t\t}\n\n\t\tfirst.previous = newLeft;\n\t\tlast.next = newRight || null;\n\n\t\tif (!newLeft) this.firstChunk = first;\n\t\tif (!newRight) this.lastChunk = last;\n\n\t\tif (DEBUG) this.stats.timeEnd('move');\n\t\treturn this;\n\t}\n\n\toverwrite(start, end, content, options) {\n\t\toptions = options || {};\n\t\treturn this.update(start, end, content, { ...options, overwrite: !options.contentOnly });\n\t}\n\n\tupdate(start, end, content, options) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('replacement content must be a string');\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (end > this.original.length) throw new Error('end is out of bounds');\n\t\tif (start === end)\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',\n\t\t\t);\n\n\t\tif (DEBUG) this.stats.time('overwrite');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tif (options === true) {\n\t\t\tif (!warned.storeName) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string',\n\t\t\t\t);\n\t\t\t\twarned.storeName = true;\n\t\t\t}\n\n\t\t\toptions = { storeName: true };\n\t\t}\n\t\tconst storeName = options !== undefined ? options.storeName : false;\n\t\tconst overwrite = options !== undefined ? options.overwrite : false;\n\n\t\tif (storeName) {\n\t\t\tconst original = this.original.slice(start, end);\n\t\t\tObject.defineProperty(this.storedNames, original, {\n\t\t\t\twritable: true,\n\t\t\t\tvalue: true,\n\t\t\t\tenumerable: true,\n\t\t\t});\n\t\t}\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tif (first) {\n\t\t\tlet chunk = first;\n\t\t\twhile (chunk !== last) {\n\t\t\t\tif (chunk.next !== this.byStart[chunk.end]) {\n\t\t\t\t\tthrow new Error('Cannot overwrite across a split point');\n\t\t\t\t}\n\t\t\t\tchunk = chunk.next;\n\t\t\t\tchunk.edit('', false);\n\t\t\t}\n\n\t\t\tfirst.edit(content, storeName, !overwrite);\n\t\t} else {\n\t\t\t// must be inserting at the end\n\t\t\tconst newChunk = new Chunk(start, end, '').edit(content, storeName);\n\n\t\t\t// TODO last chunk in the array may not be the last chunk, if it's moved...\n\t\t\tlast.next = newChunk;\n\t\t\tnewChunk.previous = last;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('overwrite');\n\t\treturn this;\n\t}\n\n\tprepend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.intro = content + this.intro;\n\t\treturn this;\n\t}\n\n\tprependLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependLeft(content);\n\t\t} else {\n\t\t\tthis.intro = content + this.intro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tprependRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependRight(content);\n\t\t} else {\n\t\t\tthis.outro = content + this.outro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tremove(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('remove');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.intro = '';\n\t\t\tchunk.outro = '';\n\t\t\tchunk.edit('');\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('remove');\n\t\treturn this;\n\t}\n\n\treset(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('reset');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.reset();\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('reset');\n\t\treturn this;\n\t}\n\n\tlastChar() {\n\t\tif (this.outro.length) return this.outro[this.outro.length - 1];\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];\n\t\t\tif (chunk.content.length) return chunk.content[chunk.content.length - 1];\n\t\t\tif (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];\n\t\t} while ((chunk = chunk.previous));\n\t\tif (this.intro.length) return this.intro[this.intro.length - 1];\n\t\treturn '';\n\t}\n\n\tlastLine() {\n\t\tlet lineIndex = this.outro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.outro.substr(lineIndex + 1);\n\t\tlet lineStr = this.outro;\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length > 0) {\n\t\t\t\tlineIndex = chunk.outro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.outro + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.content.length > 0) {\n\t\t\t\tlineIndex = chunk.content.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.content + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.intro.length > 0) {\n\t\t\t\tlineIndex = chunk.intro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.intro + lineStr;\n\t\t\t}\n\t\t} while ((chunk = chunk.previous));\n\t\tlineIndex = this.intro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;\n\t\treturn this.intro + lineStr;\n\t}\n\n\tslice(start = 0, end = this.original.length - this.offset) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tlet result = '';\n\n\t\t// find start chunk\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk && (chunk.start > start || chunk.end <= start)) {\n\t\t\t// found end chunk before start\n\t\t\tif (chunk.start < end && chunk.end >= end) {\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tif (chunk && chunk.edited && chunk.start !== start)\n\t\t\tthrow new Error(`Cannot use replaced character ${start} as slice start anchor.`);\n\n\t\tconst startChunk = chunk;\n\t\twhile (chunk) {\n\t\t\tif (chunk.intro && (startChunk !== chunk || chunk.start === start)) {\n\t\t\t\tresult += chunk.intro;\n\t\t\t}\n\n\t\t\tconst containsEnd = chunk.start < end && chunk.end >= end;\n\t\t\tif (containsEnd && chunk.edited && chunk.end !== end)\n\t\t\t\tthrow new Error(`Cannot use replaced character ${end} as slice end anchor.`);\n\n\t\t\tconst sliceStart = startChunk === chunk ? start - chunk.start : 0;\n\t\t\tconst sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;\n\n\t\t\tresult += chunk.content.slice(sliceStart, sliceEnd);\n\n\t\t\tif (chunk.outro && (!containsEnd || chunk.end === end)) {\n\t\t\t\tresult += chunk.outro;\n\t\t\t}\n\n\t\t\tif (containsEnd) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// TODO deprecate this? not really very useful\n\tsnip(start, end) {\n\t\tconst clone = this.clone();\n\t\tclone.remove(0, start);\n\t\tclone.remove(end, clone.original.length);\n\n\t\treturn clone;\n\t}\n\n\t_split(index) {\n\t\tif (this.byStart[index] || this.byEnd[index]) return;\n\n\t\tif (DEBUG) this.stats.time('_split');\n\n\t\tlet chunk = this.lastSearchedChunk;\n\t\tlet previousChunk = chunk;\n\t\tconst searchForward = index > chunk.end;\n\n\t\twhile (chunk) {\n\t\t\tif (chunk.contains(index)) return this._splitChunk(chunk, index);\n\n\t\t\tchunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];\n\n\t\t\t// Prevent infinite loop (e.g. via empty chunks, where start === end)\n\t\t\tif (chunk === previousChunk) return;\n\n\t\t\tpreviousChunk = chunk;\n\t\t}\n\t}\n\n\t_splitChunk(chunk, index) {\n\t\tif (chunk.edited && chunk.content.length) {\n\t\t\t// zero-length edited chunks are a special case (overlapping replacements)\n\t\t\tconst loc = getLocator(this.original)(index);\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – \"${chunk.original}\")`,\n\t\t\t);\n\t\t}\n\n\t\tconst newChunk = chunk.split(index);\n\n\t\tthis.byEnd[index] = chunk;\n\t\tthis.byStart[index] = newChunk;\n\t\tthis.byEnd[newChunk.end] = newChunk;\n\n\t\tif (chunk === this.lastChunk) this.lastChunk = newChunk;\n\n\t\tthis.lastSearchedChunk = chunk;\n\t\tif (DEBUG) this.stats.timeEnd('_split');\n\t\treturn true;\n\t}\n\n\ttoString() {\n\t\tlet str = this.intro;\n\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk) {\n\t\t\tstr += chunk.toString();\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn str + this.outro;\n\t}\n\n\tisEmpty() {\n\t\tlet chunk = this.firstChunk;\n\t\tdo {\n\t\t\tif (\n\t\t\t\t(chunk.intro.length && chunk.intro.trim()) ||\n\t\t\t\t(chunk.content.length && chunk.content.trim()) ||\n\t\t\t\t(chunk.outro.length && chunk.outro.trim())\n\t\t\t)\n\t\t\t\treturn false;\n\t\t} while ((chunk = chunk.next));\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\tlet chunk = this.firstChunk;\n\t\tlet length = 0;\n\t\tdo {\n\t\t\tlength += chunk.intro.length + chunk.content.length + chunk.outro.length;\n\t\t} while ((chunk = chunk.next));\n\t\treturn length;\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimEndAborted(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tlet chunk = this.lastChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimEnd(rx);\n\n\t\t\t// if chunk was trimmed, we have a new lastChunk\n\t\t\tif (chunk.end !== end) {\n\t\t\t\tif (this.lastChunk === chunk) {\n\t\t\t\t\tthis.lastChunk = chunk.next;\n\t\t\t\t}\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.previous;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimEnd(charType) {\n\t\tthis.trimEndAborted(charType);\n\t\treturn this;\n\t}\n\ttrimStartAborted(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tlet chunk = this.firstChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimStart(rx);\n\n\t\t\tif (chunk.end !== end) {\n\t\t\t\t// special case...\n\t\t\t\tif (chunk === this.lastChunk) this.lastChunk = chunk.next;\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.next;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimStart(charType) {\n\t\tthis.trimStartAborted(charType);\n\t\treturn this;\n\t}\n\n\thasChanged() {\n\t\treturn this.original !== this.toString();\n\t}\n\n\t_replaceRegexp(searchValue, replacement) {\n\t\tfunction getReplacement(match, str) {\n\t\t\tif (typeof replacement === 'string') {\n\t\t\t\treturn replacement.replace(/\\$(\\$|&|\\d+)/g, (_, i) => {\n\t\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter\n\t\t\t\t\tif (i === '$') return '$';\n\t\t\t\t\tif (i === '&') return match[0];\n\t\t\t\t\tconst num = +i;\n\t\t\t\t\tif (num < match.length) return match[+i];\n\t\t\t\t\treturn `$${i}`;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treturn replacement(...match, match.index, str, match.groups);\n\t\t\t}\n\t\t}\n\t\tfunction matchAll(re, str) {\n\t\t\tlet match;\n\t\t\tconst matches = [];\n\t\t\twhile ((match = re.exec(str))) {\n\t\t\t\tmatches.push(match);\n\t\t\t}\n\t\t\treturn matches;\n\t\t}\n\t\tif (searchValue.global) {\n\t\t\tconst matches = matchAll(searchValue, this.original);\n\t\t\tmatches.forEach((match) => {\n\t\t\t\tif (match.index != null) {\n\t\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tconst match = this.original.match(searchValue);\n\t\t\tif (match && match.index != null) {\n\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t_replaceString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst index = original.indexOf(string);\n\n\t\tif (index !== -1) {\n\t\t\tthis.overwrite(index, index + string.length, replacement);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplace(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceString(searchValue, replacement);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n\n\t_replaceAllString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst stringLength = string.length;\n\t\tfor (\n\t\t\tlet index = original.indexOf(string);\n\t\t\tindex !== -1;\n\t\t\tindex = original.indexOf(string, index + stringLength)\n\t\t) {\n\t\t\tconst previous = original.slice(index, index + stringLength);\n\t\t\tif (previous !== replacement) this.overwrite(index, index + stringLength, replacement);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplaceAll(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceAllString(searchValue, replacement);\n\t\t}\n\n\t\tif (!searchValue.global) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'MagicString.prototype.replaceAll called with a non-global RegExp argument',\n\t\t\t);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n}\n","import MagicString from './MagicString.js';\nimport SourceMap from './SourceMap.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\n\nconst hasOwnProp = Object.prototype.hasOwnProperty;\n\nexport default class Bundle {\n\tconstructor(options = {}) {\n\t\tthis.intro = options.intro || '';\n\t\tthis.separator = options.separator !== undefined ? options.separator : '\\n';\n\t\tthis.sources = [];\n\t\tthis.uniqueSources = [];\n\t\tthis.uniqueSourceIndexByFilename = {};\n\t}\n\n\taddSource(source) {\n\t\tif (source instanceof MagicString) {\n\t\t\treturn this.addSource({\n\t\t\t\tcontent: source,\n\t\t\t\tfilename: source.filename,\n\t\t\t\tseparator: this.separator,\n\t\t\t});\n\t\t}\n\n\t\tif (!isObject(source) || !source.content) {\n\t\t\tthrow new Error(\n\t\t\t\t'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`',\n\t\t\t);\n\t\t}\n\n\t\t['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => {\n\t\t\tif (!hasOwnProp.call(source, option)) source[option] = source.content[option];\n\t\t});\n\n\t\tif (source.separator === undefined) {\n\t\t\t// TODO there's a bunch of this sort of thing, needs cleaning up\n\t\t\tsource.separator = this.separator;\n\t\t}\n\n\t\tif (source.filename) {\n\t\t\tif (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) {\n\t\t\t\tthis.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length;\n\t\t\t\tthis.uniqueSources.push({ filename: source.filename, content: source.content.original });\n\t\t\t} else {\n\t\t\t\tconst uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]];\n\t\t\t\tif (source.content.original !== uniqueSource.content) {\n\t\t\t\t\tthrow new Error(`Illegal source: same filename (${source.filename}), different contents`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.sources.push(source);\n\t\treturn this;\n\t}\n\n\tappend(str, options) {\n\t\tthis.addSource({\n\t\t\tcontent: new MagicString(str),\n\t\t\tseparator: (options && options.separator) || '',\n\t\t});\n\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst bundle = new Bundle({\n\t\t\tintro: this.intro,\n\t\t\tseparator: this.separator,\n\t\t});\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tbundle.addSource({\n\t\t\t\tfilename: source.filename,\n\t\t\t\tcontent: source.content.clone(),\n\t\t\t\tseparator: source.separator,\n\t\t\t});\n\t\t});\n\n\t\treturn bundle;\n\t}\n\n\tgenerateDecodedMap(options = {}) {\n\t\tconst names = [];\n\t\tlet x_google_ignoreList = undefined;\n\t\tthis.sources.forEach((source) => {\n\t\t\tObject.keys(source.content.storedNames).forEach((name) => {\n\t\t\t\tif (!~names.indexOf(name)) names.push(name);\n\t\t\t});\n\t\t});\n\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tif (i > 0) {\n\t\t\t\tmappings.advance(this.separator);\n\t\t\t}\n\n\t\t\tconst sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1;\n\t\t\tconst magicString = source.content;\n\t\t\tconst locate = getLocator(magicString.original);\n\n\t\t\tif (magicString.intro) {\n\t\t\t\tmappings.advance(magicString.intro);\n\t\t\t}\n\n\t\t\tmagicString.firstChunk.eachNext((chunk) => {\n\t\t\t\tconst loc = locate(chunk.start);\n\n\t\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\t\tif (source.filename) {\n\t\t\t\t\tif (chunk.edited) {\n\t\t\t\t\t\tmappings.addEdit(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk.content,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmappings.addUneditedChunk(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\tmagicString.original,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tmagicString.sourcemapLocations,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmappings.advance(chunk.content);\n\t\t\t\t}\n\n\t\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t\t});\n\n\t\t\tif (magicString.outro) {\n\t\t\t\tmappings.advance(magicString.outro);\n\t\t\t}\n\n\t\t\tif (source.ignoreList && sourceIndex !== -1) {\n\t\t\t\tif (x_google_ignoreList === undefined) {\n\t\t\t\t\tx_google_ignoreList = [];\n\t\t\t\t}\n\t\t\t\tx_google_ignoreList.push(sourceIndex);\n\t\t\t}\n\t\t});\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.file ? getRelativePath(options.file, source.filename) : source.filename;\n\t\t\t}),\n\t\t\tsourcesContent: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.includeContent ? source.content : null;\n\t\t\t}),\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\tgetIndentString() {\n\t\tconst indentStringCounts = {};\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tconst indentStr = source.content._getRawIndentString();\n\n\t\t\tif (indentStr === null) return;\n\n\t\t\tif (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0;\n\t\t\tindentStringCounts[indentStr] += 1;\n\t\t});\n\n\t\treturn (\n\t\t\tObject.keys(indentStringCounts).sort((a, b) => {\n\t\t\t\treturn indentStringCounts[a] - indentStringCounts[b];\n\t\t\t})[0] || '\\t'\n\t\t);\n\t}\n\n\tindent(indentStr) {\n\t\tif (!arguments.length) {\n\t\t\tindentStr = this.getIndentString();\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\tlet trailingNewline = !this.intro || this.intro.slice(-1) === '\\n';\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\tconst indentStart = trailingNewline || (i > 0 && /\\r?\\n$/.test(separator));\n\n\t\t\tsource.content.indent(indentStr, {\n\t\t\t\texclude: source.indentExclusionRanges,\n\t\t\t\tindentStart, //: trailingNewline || /\\r?\\n$/.test( separator ) //true///\\r?\\n/.test( separator )\n\t\t\t});\n\n\t\t\ttrailingNewline = source.content.lastChar() === '\\n';\n\t\t});\n\n\t\tif (this.intro) {\n\t\t\tthis.intro =\n\t\t\t\tindentStr +\n\t\t\t\tthis.intro.replace(/^[^\\n]/gm, (match, index) => {\n\t\t\t\t\treturn index > 0 ? indentStr + match : match;\n\t\t\t\t});\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprepend(str) {\n\t\tthis.intro = str + this.intro;\n\t\treturn this;\n\t}\n\n\ttoString() {\n\t\tconst body = this.sources\n\t\t\t.map((source, i) => {\n\t\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\t\tconst str = (i > 0 ? separator : '') + source.content.toString();\n\n\t\t\t\treturn str;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn this.intro + body;\n\t}\n\n\tisEmpty() {\n\t\tif (this.intro.length && this.intro.trim()) return false;\n\t\tif (this.sources.some((source) => !source.content.isEmpty())) return false;\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\treturn this.sources.reduce(\n\t\t\t(length, source) => length + source.content.length(),\n\t\t\tthis.intro.length,\n\t\t);\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimStart(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\t\tthis.intro = this.intro.replace(rx, '');\n\n\t\tif (!this.intro) {\n\t\t\tlet source;\n\t\t\tlet i = 0;\n\n\t\t\tdo {\n\t\t\t\tsource = this.sources[i++];\n\t\t\t\tif (!source) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} while (!source.content.trimStartAborted(charType));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\ttrimEnd(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tlet source;\n\t\tlet i = this.sources.length - 1;\n\n\t\tdo {\n\t\t\tsource = this.sources[i--];\n\t\t\tif (!source) {\n\t\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (!source.content.trimEndAborted(charType));\n\n\t\treturn this;\n\t}\n}\n","import MagicString from './MagicString.js';\nimport Bundle from './Bundle.js';\nimport SourceMap from './SourceMap.js';\n\nMagicString.Bundle = Bundle;\nMagicString.SourceMap = SourceMap;\nMagicString.default = MagicString; // work around TypeScript bug https://github.com/Rich-Harris/magic-string/pull/121\n\nexport default MagicString;\n"],"names":[],"mappings":"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","x_google_ignoreList":[2]} \ No newline at end of file diff --git a/node_modules/magic-string/package.json b/node_modules/magic-string/package.json new file mode 100644 index 0000000000..c668e8e49a --- /dev/null +++ b/node_modules/magic-string/package.json @@ -0,0 +1,70 @@ +{ + "name": "magic-string", + "version": "0.30.18", + "type": "commonjs", + "packageManager": "pnpm@10.15.0", + "description": "Modify strings, generate sourcemaps", + "keywords": [ + "string", + "string manipulation", + "sourcemap", + "templating", + "transpilation" + ], + "repository": { + "type": "git", + "url": "https://github.com/rich-harris/magic-string.git" + }, + "license": "MIT", + "author": "Rich Harris", + "main": "./dist/magic-string.cjs.js", + "module": "./dist/magic-string.es.mjs", + "sideEffects": false, + "jsnext:main": "./dist/magic-string.es.mjs", + "types": "./dist/magic-string.cjs.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "import": "./dist/magic-string.es.mjs", + "require": "./dist/magic-string.cjs.js" + } + }, + "files": [ + "dist/*", + "index.d.ts", + "README.md" + ], + "scripts": { + "build": "rollup -c", + "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", + "format": "prettier --single-quote --print-width 100 --use-tabs --write .", + "lint": "eslint src test && publint", + "lint:fix": "eslint src test --fix", + "prepare": "npm run build", + "prepublishOnly": "npm run lint && rm -rf dist && npm test", + "release": "bumpp -x \"npm run changelog\" --all --commit --tag --push && npm publish", + "pretest": "npm run build", + "test": "vitest run", + "test:dev": "vitest", + "bench": "npm run build && node benchmark/index.mjs", + "watch": "rollup -cw" + }, + "devDependencies": { + "@eslint/js": "^9.33.0", + "@rollup/plugin-node-resolve": "^16.0.1", + "@rollup/plugin-replace": "^6.0.2", + "benchmark": "^2.1.4", + "bumpp": "^10.2.3", + "conventional-changelog-cli": "^5.0.0", + "eslint": "^9.33.0", + "prettier": "^3.6.2", + "publint": "^0.3.12", + "rollup": "^4.47.1", + "source-map-js": "^1.2.1", + "source-map-support": "^0.5.21", + "vitest": "^3.2.4" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } +} diff --git a/node_modules/ms/index.js b/node_modules/ms/index.js new file mode 100644 index 0000000000..ea734fb738 --- /dev/null +++ b/node_modules/ms/index.js @@ -0,0 +1,162 @@ +/** + * Helpers. + */ + +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var w = d * 7; +var y = d * 365.25; + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ + +module.exports = function (val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); +}; + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'weeks': + case 'week': + case 'w': + return n * w; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + 'd'; + } + if (msAbs >= h) { + return Math.round(ms / h) + 'h'; + } + if (msAbs >= m) { + return Math.round(ms / m) + 'm'; + } + if (msAbs >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, 'day'); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, 'hour'); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, 'minute'); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, 'second'); + } + return ms + ' ms'; +} + +/** + * Pluralization helper. + */ + +function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); +} diff --git a/node_modules/ms/license.md b/node_modules/ms/license.md new file mode 100644 index 0000000000..fa5d39b621 --- /dev/null +++ b/node_modules/ms/license.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Vercel, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/ms/package.json b/node_modules/ms/package.json new file mode 100644 index 0000000000..49971890df --- /dev/null +++ b/node_modules/ms/package.json @@ -0,0 +1,38 @@ +{ + "name": "ms", + "version": "2.1.3", + "description": "Tiny millisecond conversion utility", + "repository": "vercel/ms", + "main": "./index", + "files": [ + "index.js" + ], + "scripts": { + "precommit": "lint-staged", + "lint": "eslint lib/* bin/*", + "test": "mocha tests.js" + }, + "eslintConfig": { + "extends": "eslint:recommended", + "env": { + "node": true, + "es6": true + } + }, + "lint-staged": { + "*.js": [ + "npm run lint", + "prettier --single-quote --write", + "git add" + ] + }, + "license": "MIT", + "devDependencies": { + "eslint": "4.18.2", + "expect.js": "0.3.1", + "husky": "0.14.3", + "lint-staged": "5.0.0", + "mocha": "4.0.1", + "prettier": "2.0.5" + } +} diff --git a/node_modules/ms/readme.md b/node_modules/ms/readme.md new file mode 100644 index 0000000000..0fc1abb3b8 --- /dev/null +++ b/node_modules/ms/readme.md @@ -0,0 +1,59 @@ +# ms + +![CI](https://github.com/vercel/ms/workflows/CI/badge.svg) + +Use this package to easily convert various time formats to milliseconds. + +## Examples + +```js +ms('2 days') // 172800000 +ms('1d') // 86400000 +ms('10h') // 36000000 +ms('2.5 hrs') // 9000000 +ms('2h') // 7200000 +ms('1m') // 60000 +ms('5s') // 5000 +ms('1y') // 31557600000 +ms('100') // 100 +ms('-3 days') // -259200000 +ms('-1h') // -3600000 +ms('-200') // -200 +``` + +### Convert from Milliseconds + +```js +ms(60000) // "1m" +ms(2 * 60000) // "2m" +ms(-3 * 60000) // "-3m" +ms(ms('10 hours')) // "10h" +``` + +### Time Format Written-Out + +```js +ms(60000, { long: true }) // "1 minute" +ms(2 * 60000, { long: true }) // "2 minutes" +ms(-3 * 60000, { long: true }) // "-3 minutes" +ms(ms('10 hours'), { long: true }) // "10 hours" +``` + +## Features + +- Works both in [Node.js](https://nodejs.org) and in the browser +- If a number is supplied to `ms`, a string with a unit is returned +- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`) +- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned + +## Related Packages + +- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time. + +## Caught a Bug? + +1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device +2. Link the package to the global module directory: `npm link` +3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms! + +As always, you can run the tests using: `npm test` diff --git a/node_modules/nanoid/LICENSE b/node_modules/nanoid/LICENSE new file mode 100644 index 0000000000..37f56aa49f --- /dev/null +++ b/node_modules/nanoid/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2017 Andrey Sitnik + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/nanoid/README.md b/node_modules/nanoid/README.md new file mode 100644 index 0000000000..35abb57d88 --- /dev/null +++ b/node_modules/nanoid/README.md @@ -0,0 +1,39 @@ +# Nano ID + +Nano ID logo by Anton Lovchikov + +**English** | [Русский](./README.ru.md) | [简体中文](./README.zh-CN.md) | [Bahasa Indonesia](./README.id-ID.md) + +A tiny, secure, URL-friendly, unique string ID generator for JavaScript. + +> “An amazing level of senseless perfectionism, +> which is simply impossible not to respect.” + +* **Small.** 130 bytes (minified and gzipped). No dependencies. + [Size Limit] controls the size. +* **Fast.** It is 2 times faster than UUID. +* **Safe.** It uses hardware random generator. Can be used in clusters. +* **Short IDs.** It uses a larger alphabet than UUID (`A-Za-z0-9_-`). + So ID size was reduced from 36 to 21 symbols. +* **Portable.** Nano ID was ported + to [20 programming languages](#other-programming-languages). + +```js +import { nanoid } from 'nanoid' +model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" +``` + +Supports modern browsers, IE [with Babel], Node.js and React Native. + +[online tool]: https://gitpod.io/#https://github.com/ai/nanoid/ +[with Babel]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/ +[Size Limit]: https://github.com/ai/size-limit + + + Sponsored by Evil Martians + + +## Docs +Read full docs **[here](https://github.com/ai/nanoid#readme)**. diff --git a/node_modules/nanoid/async/index.browser.cjs b/node_modules/nanoid/async/index.browser.cjs new file mode 100644 index 0000000000..80d18716fe --- /dev/null +++ b/node_modules/nanoid/async/index.browser.cjs @@ -0,0 +1,69 @@ +let random = async bytes => crypto.getRandomValues(new Uint8Array(bytes)) + +let customAlphabet = (alphabet, defaultSize = 21) => { + // First, a bitmask is necessary to generate the ID. The bitmask makes bytes + // values closer to the alphabet size. The bitmask calculates the closest + // `2^31 - 1` number, which exceeds the alphabet size. + // For example, the bitmask for the alphabet size 30 is 31 (00011111). + // `Math.clz32` is not used, because it is not available in browsers. + let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 + // Though, the bitmask solution is not perfect since the bytes exceeding + // the alphabet size are refused. Therefore, to reliably generate the ID, + // the random bytes redundancy has to be satisfied. + + // Note: every hardware random generator call is performance expensive, + // because the system call for entropy collection takes a lot of time. + // So, to avoid additional system calls, extra bytes are requested in advance. + + // Next, a step determines how many random bytes to generate. + // The number of random bytes gets decided upon the ID size, mask, + // alphabet size, and magic number 1.6 (using 1.6 peaks at performance + // according to benchmarks). + + // `-~f => Math.ceil(f)` if f is a float + // `-~i => i + 1` if i is an integer + let step = -~((1.6 * mask * defaultSize) / alphabet.length) + + return async (size = defaultSize) => { + let id = '' + while (true) { + let bytes = crypto.getRandomValues(new Uint8Array(step)) + // A compact alternative for `for (var i = 0; i < step; i++)`. + let i = step | 0 + while (i--) { + // Adding `|| ''` refuses a random byte that exceeds the alphabet size. + id += alphabet[bytes[i] & mask] || '' + if (id.length === size) return id + } + } + } +} + +let nanoid = async (size = 21) => { + let id = '' + let bytes = crypto.getRandomValues(new Uint8Array((size |= 0))) + + // A compact alternative for `for (var i = 0; i < step; i++)`. + while (size--) { + // It is incorrect to use bytes exceeding the alphabet size. + // The following mask reduces the random byte in the 0-255 value + // range to the 0-63 value range. Therefore, adding hacks, such + // as empty string fallback or magic numbers, is unneccessary because + // the bitmask trims bytes down to the alphabet size. + let byte = bytes[size] & 63 + if (byte < 36) { + // `0-9a-z` + id += byte.toString(36) + } else if (byte < 62) { + // `A-Z` + id += (byte - 26).toString(36).toUpperCase() + } else if (byte < 63) { + id += '_' + } else { + id += '-' + } + } + return id +} + +module.exports = { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/index.browser.js b/node_modules/nanoid/async/index.browser.js new file mode 100644 index 0000000000..fbaa23005c --- /dev/null +++ b/node_modules/nanoid/async/index.browser.js @@ -0,0 +1,34 @@ +let random = async bytes => crypto.getRandomValues(new Uint8Array(bytes)) +let customAlphabet = (alphabet, defaultSize = 21) => { + let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 + let step = -~((1.6 * mask * defaultSize) / alphabet.length) + return async (size = defaultSize) => { + let id = '' + while (true) { + let bytes = crypto.getRandomValues(new Uint8Array(step)) + let i = step | 0 + while (i--) { + id += alphabet[bytes[i] & mask] || '' + if (id.length === size) return id + } + } + } +} +let nanoid = async (size = 21) => { + let id = '' + let bytes = crypto.getRandomValues(new Uint8Array((size |= 0))) + while (size--) { + let byte = bytes[size] & 63 + if (byte < 36) { + id += byte.toString(36) + } else if (byte < 62) { + id += (byte - 26).toString(36).toUpperCase() + } else if (byte < 63) { + id += '_' + } else { + id += '-' + } + } + return id +} +export { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/index.cjs b/node_modules/nanoid/async/index.cjs new file mode 100644 index 0000000000..f1b0ad0267 --- /dev/null +++ b/node_modules/nanoid/async/index.cjs @@ -0,0 +1,71 @@ +let crypto = require('crypto') + +let { urlAlphabet } = require('../url-alphabet/index.cjs') + +// `crypto.randomFill()` is a little faster than `crypto.randomBytes()`, +// because it is possible to use in combination with `Buffer.allocUnsafe()`. +let random = bytes => + new Promise((resolve, reject) => { + // `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory. + // Memory flushing is unnecessary since the buffer allocation itself resets + // the memory with the new bytes. + crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => { + if (err) { + reject(err) + } else { + resolve(buf) + } + }) + }) + +let customAlphabet = (alphabet, defaultSize = 21) => { + // First, a bitmask is necessary to generate the ID. The bitmask makes bytes + // values closer to the alphabet size. The bitmask calculates the closest + // `2^31 - 1` number, which exceeds the alphabet size. + // For example, the bitmask for the alphabet size 30 is 31 (00011111). + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + // Though, the bitmask solution is not perfect since the bytes exceeding + // the alphabet size are refused. Therefore, to reliably generate the ID, + // the random bytes redundancy has to be satisfied. + + // Note: every hardware random generator call is performance expensive, + // because the system call for entropy collection takes a lot of time. + // So, to avoid additional system calls, extra bytes are requested in advance. + + // Next, a step determines how many random bytes to generate. + // The number of random bytes gets decided upon the ID size, mask, + // alphabet size, and magic number 1.6 (using 1.6 peaks at performance + // according to benchmarks). + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + + let tick = (id, size = defaultSize) => + random(step).then(bytes => { + // A compact alternative for `for (var i = 0; i < step; i++)`. + let i = step + while (i--) { + // Adding `|| ''` refuses a random byte that exceeds the alphabet size. + id += alphabet[bytes[i] & mask] || '' + if (id.length >= size) return id + } + return tick(id, size) + }) + + return size => tick('', size) +} + +let nanoid = (size = 21) => + random((size |= 0)).then(bytes => { + let id = '' + // A compact alternative for `for (var i = 0; i < step; i++)`. + while (size--) { + // It is incorrect to use bytes exceeding the alphabet size. + // The following mask reduces the random byte in the 0-255 value + // range to the 0-63 value range. Therefore, adding hacks, such + // as empty string fallback or magic numbers, is unneccessary because + // the bitmask trims bytes down to the alphabet size. + id += urlAlphabet[bytes[size] & 63] + } + return id + }) + +module.exports = { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/index.d.ts b/node_modules/nanoid/async/index.d.ts new file mode 100644 index 0000000000..9e919658b8 --- /dev/null +++ b/node_modules/nanoid/async/index.d.ts @@ -0,0 +1,56 @@ +/** + * Generate secure URL-friendly unique ID. The non-blocking version. + * + * By default, the ID will have 21 symbols to have a collision probability + * similar to UUID v4. + * + * ```js + * import { nanoid } from 'nanoid/async' + * nanoid().then(id => { + * model.id = id + * }) + * ``` + * + * @param size Size of the ID. The default size is 21. + * @returns A promise with a random string. + */ +export function nanoid(size?: number): Promise + +/** + * A low-level function. + * Generate secure unique ID with custom alphabet. The non-blocking version. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * @param alphabet Alphabet used to generate the ID. + * @param defaultSize Size of the ID. The default size is 21. + * @returns A function that returns a promise with a random string. + * + * ```js + * import { customAlphabet } from 'nanoid/async' + * const nanoid = customAlphabet('0123456789абвгдеё', 5) + * nanoid().then(id => { + * model.id = id //=> "8ё56а" + * }) + * ``` + */ +export function customAlphabet( + alphabet: string, + defaultSize?: number +): (size?: number) => Promise + +/** + * Generate an array of random bytes collected from hardware noise. + * + * ```js + * import { random } from 'nanoid/async' + * random(5).then(bytes => { + * bytes //=> [10, 67, 212, 67, 89] + * }) + * ``` + * + * @param bytes Size of the array. + * @returns A promise with a random bytes array. + */ +export function random(bytes: number): Promise diff --git a/node_modules/nanoid/async/index.js b/node_modules/nanoid/async/index.js new file mode 100644 index 0000000000..cec454a2a1 --- /dev/null +++ b/node_modules/nanoid/async/index.js @@ -0,0 +1,35 @@ +import crypto from 'crypto' +import { urlAlphabet } from '../url-alphabet/index.js' +let random = bytes => + new Promise((resolve, reject) => { + crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => { + if (err) { + reject(err) + } else { + resolve(buf) + } + }) + }) +let customAlphabet = (alphabet, defaultSize = 21) => { + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + let tick = (id, size = defaultSize) => + random(step).then(bytes => { + let i = step + while (i--) { + id += alphabet[bytes[i] & mask] || '' + if (id.length >= size) return id + } + return tick(id, size) + }) + return size => tick('', size) +} +let nanoid = (size = 21) => + random((size |= 0)).then(bytes => { + let id = '' + while (size--) { + id += urlAlphabet[bytes[size] & 63] + } + return id + }) +export { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/index.native.js b/node_modules/nanoid/async/index.native.js new file mode 100644 index 0000000000..7c1d6f39e3 --- /dev/null +++ b/node_modules/nanoid/async/index.native.js @@ -0,0 +1,26 @@ +import { getRandomBytesAsync } from 'expo-random' +import { urlAlphabet } from '../url-alphabet/index.js' +let random = getRandomBytesAsync +let customAlphabet = (alphabet, defaultSize = 21) => { + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + let tick = (id, size = defaultSize) => + random(step).then(bytes => { + let i = step + while (i--) { + id += alphabet[bytes[i] & mask] || '' + if (id.length >= size) return id + } + return tick(id, size) + }) + return size => tick('', size) +} +let nanoid = (size = 21) => + random((size |= 0)).then(bytes => { + let id = '' + while (size--) { + id += urlAlphabet[bytes[size] & 63] + } + return id + }) +export { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/package.json b/node_modules/nanoid/async/package.json new file mode 100644 index 0000000000..578cdb4cb9 --- /dev/null +++ b/node_modules/nanoid/async/package.json @@ -0,0 +1,12 @@ +{ + "type": "module", + "main": "index.cjs", + "module": "index.js", + "react-native": { + "./index.js": "./index.native.js" + }, + "browser": { + "./index.js": "./index.browser.js", + "./index.cjs": "./index.browser.cjs" + } +} \ No newline at end of file diff --git a/node_modules/nanoid/bin/nanoid.cjs b/node_modules/nanoid/bin/nanoid.cjs new file mode 100755 index 0000000000..c76db0faa8 --- /dev/null +++ b/node_modules/nanoid/bin/nanoid.cjs @@ -0,0 +1,55 @@ +#!/usr/bin/env node + +let { nanoid, customAlphabet } = require('..') + +function print(msg) { + process.stdout.write(msg + '\n') +} + +function error(msg) { + process.stderr.write(msg + '\n') + process.exit(1) +} + +if (process.argv.includes('--help') || process.argv.includes('-h')) { + print(` + Usage + $ nanoid [options] + + Options + -s, --size Generated ID size + -a, --alphabet Alphabet to use + -h, --help Show this help + + Examples + $ nanoid --s 15 + S9sBF77U6sDB8Yg + + $ nanoid --size 10 --alphabet abc + bcabababca`) + process.exit() +} + +let alphabet, size +for (let i = 2; i < process.argv.length; i++) { + let arg = process.argv[i] + if (arg === '--size' || arg === '-s') { + size = Number(process.argv[i + 1]) + i += 1 + if (Number.isNaN(size) || size <= 0) { + error('Size must be positive integer') + } + } else if (arg === '--alphabet' || arg === '-a') { + alphabet = process.argv[i + 1] + i += 1 + } else { + error('Unknown argument ' + arg) + } +} + +if (alphabet) { + let customNanoid = customAlphabet(alphabet, size) + print(customNanoid()) +} else { + print(nanoid(size)) +} diff --git a/node_modules/nanoid/index.browser.cjs b/node_modules/nanoid/index.browser.cjs new file mode 100644 index 0000000000..d21a91fcf3 --- /dev/null +++ b/node_modules/nanoid/index.browser.cjs @@ -0,0 +1,72 @@ +// This file replaces `index.js` in bundlers like webpack or Rollup, +// according to `browser` config in `package.json`. + +let { urlAlphabet } = require('./url-alphabet/index.cjs') + +let random = bytes => crypto.getRandomValues(new Uint8Array(bytes)) + +let customRandom = (alphabet, defaultSize, getRandom) => { + // First, a bitmask is necessary to generate the ID. The bitmask makes bytes + // values closer to the alphabet size. The bitmask calculates the closest + // `2^31 - 1` number, which exceeds the alphabet size. + // For example, the bitmask for the alphabet size 30 is 31 (00011111). + // `Math.clz32` is not used, because it is not available in browsers. + let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 + // Though, the bitmask solution is not perfect since the bytes exceeding + // the alphabet size are refused. Therefore, to reliably generate the ID, + // the random bytes redundancy has to be satisfied. + + // Note: every hardware random generator call is performance expensive, + // because the system call for entropy collection takes a lot of time. + // So, to avoid additional system calls, extra bytes are requested in advance. + + // Next, a step determines how many random bytes to generate. + // The number of random bytes gets decided upon the ID size, mask, + // alphabet size, and magic number 1.6 (using 1.6 peaks at performance + // according to benchmarks). + + // `-~f => Math.ceil(f)` if f is a float + // `-~i => i + 1` if i is an integer + let step = -~((1.6 * mask * defaultSize) / alphabet.length) + + return (size = defaultSize) => { + let id = '' + while (true) { + let bytes = getRandom(step) + // A compact alternative for `for (var i = 0; i < step; i++)`. + let j = step | 0 + while (j--) { + // Adding `|| ''` refuses a random byte that exceeds the alphabet size. + id += alphabet[bytes[j] & mask] || '' + if (id.length === size) return id + } + } + } +} + +let customAlphabet = (alphabet, size = 21) => + customRandom(alphabet, size, random) + +let nanoid = (size = 21) => + crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => { + // It is incorrect to use bytes exceeding the alphabet size. + // The following mask reduces the random byte in the 0-255 value + // range to the 0-63 value range. Therefore, adding hacks, such + // as empty string fallback or magic numbers, is unneccessary because + // the bitmask trims bytes down to the alphabet size. + byte &= 63 + if (byte < 36) { + // `0-9a-z` + id += byte.toString(36) + } else if (byte < 62) { + // `A-Z` + id += (byte - 26).toString(36).toUpperCase() + } else if (byte > 62) { + id += '-' + } else { + id += '_' + } + return id + }, '') + +module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random } diff --git a/node_modules/nanoid/index.browser.js b/node_modules/nanoid/index.browser.js new file mode 100644 index 0000000000..7d3b876cae --- /dev/null +++ b/node_modules/nanoid/index.browser.js @@ -0,0 +1,34 @@ +import { urlAlphabet } from './url-alphabet/index.js' +let random = bytes => crypto.getRandomValues(new Uint8Array(bytes)) +let customRandom = (alphabet, defaultSize, getRandom) => { + let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 + let step = -~((1.6 * mask * defaultSize) / alphabet.length) + return (size = defaultSize) => { + let id = '' + while (true) { + let bytes = getRandom(step) + let j = step | 0 + while (j--) { + id += alphabet[bytes[j] & mask] || '' + if (id.length === size) return id + } + } + } +} +let customAlphabet = (alphabet, size = 21) => + customRandom(alphabet, size, random) +let nanoid = (size = 21) => + crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => { + byte &= 63 + if (byte < 36) { + id += byte.toString(36) + } else if (byte < 62) { + id += (byte - 26).toString(36).toUpperCase() + } else if (byte > 62) { + id += '-' + } else { + id += '_' + } + return id + }, '') +export { nanoid, customAlphabet, customRandom, urlAlphabet, random } diff --git a/node_modules/nanoid/index.cjs b/node_modules/nanoid/index.cjs new file mode 100644 index 0000000000..c20e3744d2 --- /dev/null +++ b/node_modules/nanoid/index.cjs @@ -0,0 +1,85 @@ +let crypto = require('crypto') + +let { urlAlphabet } = require('./url-alphabet/index.cjs') + +// It is best to make fewer, larger requests to the crypto module to +// avoid system call overhead. So, random numbers are generated in a +// pool. The pool is a Buffer that is larger than the initial random +// request size by this multiplier. The pool is enlarged if subsequent +// requests exceed the maximum buffer size. +const POOL_SIZE_MULTIPLIER = 128 +let pool, poolOffset + +let fillPool = bytes => { + if (!pool || pool.length < bytes) { + pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER) + crypto.randomFillSync(pool) + poolOffset = 0 + } else if (poolOffset + bytes > pool.length) { + crypto.randomFillSync(pool) + poolOffset = 0 + } + poolOffset += bytes +} + +let random = bytes => { + // `|=` convert `bytes` to number to prevent `valueOf` abusing and pool pollution + fillPool((bytes |= 0)) + return pool.subarray(poolOffset - bytes, poolOffset) +} + +let customRandom = (alphabet, defaultSize, getRandom) => { + // First, a bitmask is necessary to generate the ID. The bitmask makes bytes + // values closer to the alphabet size. The bitmask calculates the closest + // `2^31 - 1` number, which exceeds the alphabet size. + // For example, the bitmask for the alphabet size 30 is 31 (00011111). + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + // Though, the bitmask solution is not perfect since the bytes exceeding + // the alphabet size are refused. Therefore, to reliably generate the ID, + // the random bytes redundancy has to be satisfied. + + // Note: every hardware random generator call is performance expensive, + // because the system call for entropy collection takes a lot of time. + // So, to avoid additional system calls, extra bytes are requested in advance. + + // Next, a step determines how many random bytes to generate. + // The number of random bytes gets decided upon the ID size, mask, + // alphabet size, and magic number 1.6 (using 1.6 peaks at performance + // according to benchmarks). + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + + return (size = defaultSize) => { + let id = '' + while (true) { + let bytes = getRandom(step) + // A compact alternative for `for (let i = 0; i < step; i++)`. + let i = step + while (i--) { + // Adding `|| ''` refuses a random byte that exceeds the alphabet size. + id += alphabet[bytes[i] & mask] || '' + if (id.length === size) return id + } + } + } +} + +let customAlphabet = (alphabet, size = 21) => + customRandom(alphabet, size, random) + +let nanoid = (size = 21) => { + // `|=` convert `size` to number to prevent `valueOf` abusing and pool pollution + fillPool((size |= 0)) + let id = '' + // We are reading directly from the random pool to avoid creating new array + for (let i = poolOffset - size; i < poolOffset; i++) { + // It is incorrect to use bytes exceeding the alphabet size. + // The following mask reduces the random byte in the 0-255 value + // range to the 0-63 value range. Therefore, adding hacks, such + // as empty string fallback or magic numbers, is unneccessary because + // the bitmask trims bytes down to the alphabet size. + id += urlAlphabet[pool[i] & 63] + } + return id +} + +module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random } diff --git a/node_modules/nanoid/index.d.cts b/node_modules/nanoid/index.d.cts new file mode 100644 index 0000000000..3e111a39de --- /dev/null +++ b/node_modules/nanoid/index.d.cts @@ -0,0 +1,91 @@ +/** + * Generate secure URL-friendly unique ID. + * + * By default, the ID will have 21 symbols to have a collision probability + * similar to UUID v4. + * + * ```js + * import { nanoid } from 'nanoid' + * model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL" + * ``` + * + * @param size Size of the ID. The default size is 21. + * @returns A random string. + */ +export function nanoid(size?: number): string + +/** + * Generate secure unique ID with custom alphabet. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * @param alphabet Alphabet used to generate the ID. + * @param defaultSize Size of the ID. The default size is 21. + * @returns A random string generator. + * + * ```js + * const { customAlphabet } = require('nanoid') + * const nanoid = customAlphabet('0123456789абвгдеё', 5) + * nanoid() //=> "8ё56а" + * ``` + */ +export function customAlphabet( + alphabet: string, + defaultSize?: number +): (size?: number) => string + +/** + * Generate unique ID with custom random generator and alphabet. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * ```js + * import { customRandom } from 'nanoid/format' + * + * const nanoid = customRandom('abcdef', 5, size => { + * const random = [] + * for (let i = 0; i < size; i++) { + * random.push(randomByte()) + * } + * return random + * }) + * + * nanoid() //=> "fbaef" + * ``` + * + * @param alphabet Alphabet used to generate a random string. + * @param size Size of the random string. + * @param random A random bytes generator. + * @returns A random string generator. + */ +export function customRandom( + alphabet: string, + size: number, + random: (bytes: number) => Uint8Array +): () => string + +/** + * URL safe symbols. + * + * ```js + * import { urlAlphabet } from 'nanoid' + * const nanoid = customAlphabet(urlAlphabet, 10) + * nanoid() //=> "Uakgb_J5m9" + * ``` + */ +export const urlAlphabet: string + +/** + * Generate an array of random bytes collected from hardware noise. + * + * ```js + * import { customRandom, random } from 'nanoid' + * const nanoid = customRandom("abcdef", 5, random) + * ``` + * + * @param bytes Size of the array. + * @returns An array of random bytes. + */ +export function random(bytes: number): Uint8Array diff --git a/node_modules/nanoid/index.d.ts b/node_modules/nanoid/index.d.ts new file mode 100644 index 0000000000..3e111a39de --- /dev/null +++ b/node_modules/nanoid/index.d.ts @@ -0,0 +1,91 @@ +/** + * Generate secure URL-friendly unique ID. + * + * By default, the ID will have 21 symbols to have a collision probability + * similar to UUID v4. + * + * ```js + * import { nanoid } from 'nanoid' + * model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL" + * ``` + * + * @param size Size of the ID. The default size is 21. + * @returns A random string. + */ +export function nanoid(size?: number): string + +/** + * Generate secure unique ID with custom alphabet. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * @param alphabet Alphabet used to generate the ID. + * @param defaultSize Size of the ID. The default size is 21. + * @returns A random string generator. + * + * ```js + * const { customAlphabet } = require('nanoid') + * const nanoid = customAlphabet('0123456789абвгдеё', 5) + * nanoid() //=> "8ё56а" + * ``` + */ +export function customAlphabet( + alphabet: string, + defaultSize?: number +): (size?: number) => string + +/** + * Generate unique ID with custom random generator and alphabet. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * ```js + * import { customRandom } from 'nanoid/format' + * + * const nanoid = customRandom('abcdef', 5, size => { + * const random = [] + * for (let i = 0; i < size; i++) { + * random.push(randomByte()) + * } + * return random + * }) + * + * nanoid() //=> "fbaef" + * ``` + * + * @param alphabet Alphabet used to generate a random string. + * @param size Size of the random string. + * @param random A random bytes generator. + * @returns A random string generator. + */ +export function customRandom( + alphabet: string, + size: number, + random: (bytes: number) => Uint8Array +): () => string + +/** + * URL safe symbols. + * + * ```js + * import { urlAlphabet } from 'nanoid' + * const nanoid = customAlphabet(urlAlphabet, 10) + * nanoid() //=> "Uakgb_J5m9" + * ``` + */ +export const urlAlphabet: string + +/** + * Generate an array of random bytes collected from hardware noise. + * + * ```js + * import { customRandom, random } from 'nanoid' + * const nanoid = customRandom("abcdef", 5, random) + * ``` + * + * @param bytes Size of the array. + * @returns An array of random bytes. + */ +export function random(bytes: number): Uint8Array diff --git a/node_modules/nanoid/index.js b/node_modules/nanoid/index.js new file mode 100644 index 0000000000..9bc909d90c --- /dev/null +++ b/node_modules/nanoid/index.js @@ -0,0 +1,45 @@ +import crypto from 'crypto' +import { urlAlphabet } from './url-alphabet/index.js' +const POOL_SIZE_MULTIPLIER = 128 +let pool, poolOffset +let fillPool = bytes => { + if (!pool || pool.length < bytes) { + pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER) + crypto.randomFillSync(pool) + poolOffset = 0 + } else if (poolOffset + bytes > pool.length) { + crypto.randomFillSync(pool) + poolOffset = 0 + } + poolOffset += bytes +} +let random = bytes => { + fillPool((bytes |= 0)) + return pool.subarray(poolOffset - bytes, poolOffset) +} +let customRandom = (alphabet, defaultSize, getRandom) => { + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + return (size = defaultSize) => { + let id = '' + while (true) { + let bytes = getRandom(step) + let i = step + while (i--) { + id += alphabet[bytes[i] & mask] || '' + if (id.length === size) return id + } + } + } +} +let customAlphabet = (alphabet, size = 21) => + customRandom(alphabet, size, random) +let nanoid = (size = 21) => { + fillPool((size |= 0)) + let id = '' + for (let i = poolOffset - size; i < poolOffset; i++) { + id += urlAlphabet[pool[i] & 63] + } + return id +} +export { nanoid, customAlphabet, customRandom, urlAlphabet, random } diff --git a/node_modules/nanoid/nanoid.js b/node_modules/nanoid/nanoid.js new file mode 100644 index 0000000000..ec242eadc8 --- /dev/null +++ b/node_modules/nanoid/nanoid.js @@ -0,0 +1 @@ +export let nanoid=(t=21)=>crypto.getRandomValues(new Uint8Array(t)).reduce(((t,e)=>t+=(e&=63)<36?e.toString(36):e<62?(e-26).toString(36).toUpperCase():e<63?"_":"-"),""); \ No newline at end of file diff --git a/node_modules/nanoid/non-secure/index.cjs b/node_modules/nanoid/non-secure/index.cjs new file mode 100644 index 0000000000..d51fcb6ced --- /dev/null +++ b/node_modules/nanoid/non-secure/index.cjs @@ -0,0 +1,34 @@ +// This alphabet uses `A-Za-z0-9_-` symbols. +// The order of characters is optimized for better gzip and brotli compression. +// References to the same file (works both for gzip and brotli): +// `'use`, `andom`, and `rict'` +// References to the brotli default dictionary: +// `-26T`, `1983`, `40px`, `75px`, `bush`, `jack`, `mind`, `very`, and `wolf` +let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' + +let customAlphabet = (alphabet, defaultSize = 21) => { + return (size = defaultSize) => { + let id = '' + // A compact alternative for `for (var i = 0; i < step; i++)`. + let i = size | 0 + while (i--) { + // `| 0` is more compact and faster than `Math.floor()`. + id += alphabet[(Math.random() * alphabet.length) | 0] + } + return id + } +} + +let nanoid = (size = 21) => { + let id = '' + // A compact alternative for `for (var i = 0; i < step; i++)`. + let i = size | 0 + while (i--) { + // `| 0` is more compact and faster than `Math.floor()`. + id += urlAlphabet[(Math.random() * 64) | 0] + } + return id +} + +module.exports = { nanoid, customAlphabet } diff --git a/node_modules/nanoid/non-secure/index.d.ts b/node_modules/nanoid/non-secure/index.d.ts new file mode 100644 index 0000000000..4965322d63 --- /dev/null +++ b/node_modules/nanoid/non-secure/index.d.ts @@ -0,0 +1,33 @@ +/** + * Generate URL-friendly unique ID. This method uses the non-secure + * predictable random generator with bigger collision probability. + * + * ```js + * import { nanoid } from 'nanoid/non-secure' + * model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL" + * ``` + * + * @param size Size of the ID. The default size is 21. + * @returns A random string. + */ +export function nanoid(size?: number): string + +/** + * Generate a unique ID based on a custom alphabet. + * This method uses the non-secure predictable random generator + * with bigger collision probability. + * + * @param alphabet Alphabet used to generate the ID. + * @param defaultSize Size of the ID. The default size is 21. + * @returns A random string generator. + * + * ```js + * import { customAlphabet } from 'nanoid/non-secure' + * const nanoid = customAlphabet('0123456789абвгдеё', 5) + * model.id = //=> "8ё56а" + * ``` + */ +export function customAlphabet( + alphabet: string, + defaultSize?: number +): (size?: number) => string diff --git a/node_modules/nanoid/non-secure/index.js b/node_modules/nanoid/non-secure/index.js new file mode 100644 index 0000000000..2ea5827c62 --- /dev/null +++ b/node_modules/nanoid/non-secure/index.js @@ -0,0 +1,21 @@ +let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' +let customAlphabet = (alphabet, defaultSize = 21) => { + return (size = defaultSize) => { + let id = '' + let i = size | 0 + while (i--) { + id += alphabet[(Math.random() * alphabet.length) | 0] + } + return id + } +} +let nanoid = (size = 21) => { + let id = '' + let i = size | 0 + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0] + } + return id +} +export { nanoid, customAlphabet } diff --git a/node_modules/nanoid/non-secure/package.json b/node_modules/nanoid/non-secure/package.json new file mode 100644 index 0000000000..9930d6ad16 --- /dev/null +++ b/node_modules/nanoid/non-secure/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "main": "index.cjs", + "module": "index.js", + "react-native": "index.js" +} \ No newline at end of file diff --git a/node_modules/nanoid/package.json b/node_modules/nanoid/package.json new file mode 100644 index 0000000000..a3d3f44526 --- /dev/null +++ b/node_modules/nanoid/package.json @@ -0,0 +1,89 @@ +{ + "name": "nanoid", + "version": "3.3.11", + "description": "A tiny (116 bytes), secure URL-friendly unique string ID generator", + "keywords": [ + "uuid", + "random", + "id", + "url" + ], + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "author": "Andrey Sitnik ", + "license": "MIT", + "repository": "ai/nanoid", + "browser": { + "./index.js": "./index.browser.js", + "./async/index.js": "./async/index.browser.js", + "./async/index.cjs": "./async/index.browser.cjs", + "./index.cjs": "./index.browser.cjs" + }, + "react-native": "index.js", + "bin": "./bin/nanoid.cjs", + "sideEffects": false, + "types": "./index.d.ts", + "type": "module", + "main": "index.cjs", + "module": "index.js", + "exports": { + ".": { + "react-native": "./index.browser.js", + "browser": "./index.browser.js", + "require": { + "types": "./index.d.cts", + "default": "./index.cjs" + }, + "import": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "default": "./index.js" + }, + "./package.json": "./package.json", + "./async/package.json": "./async/package.json", + "./async": { + "browser": "./async/index.browser.js", + "require": { + "types": "./index.d.cts", + "default": "./async/index.cjs" + }, + "import": { + "types": "./index.d.ts", + "default": "./async/index.js" + }, + "default": "./async/index.js" + }, + "./non-secure/package.json": "./non-secure/package.json", + "./non-secure": { + "require": { + "types": "./index.d.cts", + "default": "./non-secure/index.cjs" + }, + "import": { + "types": "./index.d.ts", + "default": "./non-secure/index.js" + }, + "default": "./non-secure/index.js" + }, + "./url-alphabet/package.json": "./url-alphabet/package.json", + "./url-alphabet": { + "require": { + "types": "./index.d.cts", + "default": "./url-alphabet/index.cjs" + }, + "import": { + "types": "./index.d.ts", + "default": "./url-alphabet/index.js" + }, + "default": "./url-alphabet/index.js" + } + } +} diff --git a/node_modules/nanoid/url-alphabet/index.cjs b/node_modules/nanoid/url-alphabet/index.cjs new file mode 100644 index 0000000000..a332f0bff6 --- /dev/null +++ b/node_modules/nanoid/url-alphabet/index.cjs @@ -0,0 +1,7 @@ +// This alphabet uses `A-Za-z0-9_-` symbols. +// The order of characters is optimized for better gzip and brotli compression. +// Same as in non-secure/index.js +let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' + +module.exports = { urlAlphabet } diff --git a/node_modules/nanoid/url-alphabet/index.js b/node_modules/nanoid/url-alphabet/index.js new file mode 100644 index 0000000000..c2782e592e --- /dev/null +++ b/node_modules/nanoid/url-alphabet/index.js @@ -0,0 +1,3 @@ +let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' +export { urlAlphabet } diff --git a/node_modules/nanoid/url-alphabet/package.json b/node_modules/nanoid/url-alphabet/package.json new file mode 100644 index 0000000000..9930d6ad16 --- /dev/null +++ b/node_modules/nanoid/url-alphabet/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "main": "index.cjs", + "module": "index.js", + "react-native": "index.js" +} \ No newline at end of file diff --git a/node_modules/pathe/LICENSE b/node_modules/pathe/LICENSE new file mode 100644 index 0000000000..8eb90c4357 --- /dev/null +++ b/node_modules/pathe/LICENSE @@ -0,0 +1,70 @@ +MIT License + +Copyright (c) Pooya Parsa - Daniel Roe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- + +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +Bundled zeptomatch (https://github.com/fabiospampinato/zeptomatch) + +The MIT License (MIT) + +Copyright (c) 2023-present Fabio Spampinato + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/node_modules/pathe/README.md b/node_modules/pathe/README.md new file mode 100644 index 0000000000..8eddf93546 --- /dev/null +++ b/node_modules/pathe/README.md @@ -0,0 +1,73 @@ +# 🛣️ pathe + +> Universal filesystem path utils + +[![version][npm-v-src]][npm-v-href] +[![downloads][npm-d-src]][npm-d-href] +[![size][size-src]][size-href] + +## ❓ Why + +For [historical reasons](https://docs.microsoft.com/en-us/archive/blogs/larryosterman/why-is-the-dos-path-character), windows followed MS-DOS and used backslash for separating paths rather than slash used for macOS, Linux, and other Posix operating systems. Nowadays, [Windows](https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN) supports both Slash and Backslash for paths. [Node.js's built-in `path` module](https://nodejs.org/api/path.html) in the default operation of the path module varies based on the operating system on which a Node.js application is running. Specifically, when running on a Windows operating system, the path module will assume that Windows-style paths are being used. **This makes inconsistent code behavior between Windows and POSIX.** + +Compared to popular [upath](https://github.com/anodynos/upath), pathe provides **identical exports** of Node.js with normalization on **all operations** and is written in modern **ESM/TypeScript** and has **no dependency on Node.js**! + +This package is a drop-in replacement of the Node.js's [path module](https://nodejs.org/api/path.html) module and ensures paths are normalized with slash `/` and work in environments including Node.js. + +## 💿 Usage + +Install using npm or yarn: + +```bash +# npm +npm i pathe + +# yarn +yarn add pathe + +# pnpm +pnpm i pathe +``` + +Import: + +```js +// ESM / Typescript +import { resolve, matchesGlob } from "pathe"; + +// CommonJS +const { resolve, matchesGlob } = require("pathe"); +``` + +Read more about path utils from [Node.js documentation](https://nodejs.org/api/path.html) and rest assured behavior is consistently like POSIX regardless of your input paths format and running platform (the only exception is `delimiter` constant export, it will be set to `;` on windows platform). + +### Extra utilities + +Pathe exports some extra utilities that do not exist in standard Node.js [path module](https://nodejs.org/api/path.html). +In order to use them, you can import from `pathe/utils` subpath: + +```js +import { + filename, + normalizeAliases, + resolveAlias, + reverseResolveAlias, +} from "pathe/utils"; +``` + +## License + +Made with 💛 Published under the [MIT](./LICENSE) license. + +Some code was used from the Node.js project. Glob supported is powered by [zeptomatch](https://github.com/fabiospampinato/zeptomatch). + + + +[npm-v-src]: https://img.shields.io/npm/v/pathe?style=flat-square +[npm-v-href]: https://npmjs.com/package/pathe +[npm-d-src]: https://img.shields.io/npm/dm/pathe?style=flat-square +[npm-d-href]: https://npmjs.com/package/pathe +[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/pathe/ci/main?style=flat-square +[github-actions-href]: https://github.com/unjs/pathe/actions?query=workflow%3Aci +[size-src]: https://packagephobia.now.sh/badge?p=pathe +[size-href]: https://packagephobia.now.sh/result?p=pathe diff --git a/node_modules/pathe/dist/index.cjs b/node_modules/pathe/dist/index.cjs new file mode 100644 index 0000000000..d64a6d2232 --- /dev/null +++ b/node_modules/pathe/dist/index.cjs @@ -0,0 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const _path = require('./shared/pathe.BSlhyZSM.cjs'); + +const delimiter = /* @__PURE__ */ (() => globalThis.process?.platform === "win32" ? ";" : ":")(); +const _platforms = { posix: void 0, win32: void 0 }; +const mix = (del = delimiter) => { + return new Proxy(_path._path, { + get(_, prop) { + if (prop === "delimiter") return del; + if (prop === "posix") return posix; + if (prop === "win32") return win32; + return _platforms[prop] || _path._path[prop]; + } + }); +}; +const posix = /* @__PURE__ */ mix(":"); +const win32 = /* @__PURE__ */ mix(";"); + +exports.basename = _path.basename; +exports.dirname = _path.dirname; +exports.extname = _path.extname; +exports.format = _path.format; +exports.isAbsolute = _path.isAbsolute; +exports.join = _path.join; +exports.matchesGlob = _path.matchesGlob; +exports.normalize = _path.normalize; +exports.normalizeString = _path.normalizeString; +exports.parse = _path.parse; +exports.relative = _path.relative; +exports.resolve = _path.resolve; +exports.sep = _path.sep; +exports.toNamespacedPath = _path.toNamespacedPath; +exports.default = posix; +exports.delimiter = delimiter; +exports.posix = posix; +exports.win32 = win32; diff --git a/node_modules/pathe/dist/index.d.cts b/node_modules/pathe/dist/index.d.cts new file mode 100644 index 0000000000..61046da2a5 --- /dev/null +++ b/node_modules/pathe/dist/index.d.cts @@ -0,0 +1,47 @@ +import * as path from 'node:path'; +import path__default from 'node:path'; + +/** + * Constant for path separator. + * + * Always equals to `"/"`. + */ +declare const sep = "/"; +declare const normalize: typeof path__default.normalize; +declare const join: typeof path__default.join; +declare const resolve: typeof path__default.resolve; +/** + * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root. + * + * @param path - The path to normalise. + * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory. + * @returns the normalised path string. + */ +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path__default.isAbsolute; +declare const toNamespacedPath: typeof path__default.toNamespacedPath; +declare const extname: typeof path__default.extname; +declare const relative: typeof path__default.relative; +declare const dirname: typeof path__default.dirname; +declare const format: typeof path__default.format; +declare const basename: typeof path__default.basename; +declare const parse: typeof path__default.parse; +/** + * The `path.matchesGlob()` method determines if `path` matches the `pattern`. + * @param path The path to glob-match against. + * @param pattern The glob to check the path against. + */ +declare const matchesGlob: (path: string, pattern: string | string[]) => boolean; + +type NodePath = typeof path; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +declare const delimiter: ";" | ":"; +declare const posix: NodePath["posix"]; +declare const win32: NodePath["win32"]; +declare const _default: NodePath; + +export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 }; diff --git a/node_modules/pathe/dist/index.d.mts b/node_modules/pathe/dist/index.d.mts new file mode 100644 index 0000000000..61046da2a5 --- /dev/null +++ b/node_modules/pathe/dist/index.d.mts @@ -0,0 +1,47 @@ +import * as path from 'node:path'; +import path__default from 'node:path'; + +/** + * Constant for path separator. + * + * Always equals to `"/"`. + */ +declare const sep = "/"; +declare const normalize: typeof path__default.normalize; +declare const join: typeof path__default.join; +declare const resolve: typeof path__default.resolve; +/** + * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root. + * + * @param path - The path to normalise. + * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory. + * @returns the normalised path string. + */ +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path__default.isAbsolute; +declare const toNamespacedPath: typeof path__default.toNamespacedPath; +declare const extname: typeof path__default.extname; +declare const relative: typeof path__default.relative; +declare const dirname: typeof path__default.dirname; +declare const format: typeof path__default.format; +declare const basename: typeof path__default.basename; +declare const parse: typeof path__default.parse; +/** + * The `path.matchesGlob()` method determines if `path` matches the `pattern`. + * @param path The path to glob-match against. + * @param pattern The glob to check the path against. + */ +declare const matchesGlob: (path: string, pattern: string | string[]) => boolean; + +type NodePath = typeof path; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +declare const delimiter: ";" | ":"; +declare const posix: NodePath["posix"]; +declare const win32: NodePath["win32"]; +declare const _default: NodePath; + +export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 }; diff --git a/node_modules/pathe/dist/index.d.ts b/node_modules/pathe/dist/index.d.ts new file mode 100644 index 0000000000..61046da2a5 --- /dev/null +++ b/node_modules/pathe/dist/index.d.ts @@ -0,0 +1,47 @@ +import * as path from 'node:path'; +import path__default from 'node:path'; + +/** + * Constant for path separator. + * + * Always equals to `"/"`. + */ +declare const sep = "/"; +declare const normalize: typeof path__default.normalize; +declare const join: typeof path__default.join; +declare const resolve: typeof path__default.resolve; +/** + * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root. + * + * @param path - The path to normalise. + * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory. + * @returns the normalised path string. + */ +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path__default.isAbsolute; +declare const toNamespacedPath: typeof path__default.toNamespacedPath; +declare const extname: typeof path__default.extname; +declare const relative: typeof path__default.relative; +declare const dirname: typeof path__default.dirname; +declare const format: typeof path__default.format; +declare const basename: typeof path__default.basename; +declare const parse: typeof path__default.parse; +/** + * The `path.matchesGlob()` method determines if `path` matches the `pattern`. + * @param path The path to glob-match against. + * @param pattern The glob to check the path against. + */ +declare const matchesGlob: (path: string, pattern: string | string[]) => boolean; + +type NodePath = typeof path; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +declare const delimiter: ";" | ":"; +declare const posix: NodePath["posix"]; +declare const win32: NodePath["win32"]; +declare const _default: NodePath; + +export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 }; diff --git a/node_modules/pathe/dist/index.mjs b/node_modules/pathe/dist/index.mjs new file mode 100644 index 0000000000..0582c1f492 --- /dev/null +++ b/node_modules/pathe/dist/index.mjs @@ -0,0 +1,19 @@ +import { _ as _path } from './shared/pathe.M-eThtNZ.mjs'; +export { c as basename, d as dirname, e as extname, f as format, i as isAbsolute, j as join, m as matchesGlob, n as normalize, a as normalizeString, p as parse, b as relative, r as resolve, s as sep, t as toNamespacedPath } from './shared/pathe.M-eThtNZ.mjs'; + +const delimiter = /* @__PURE__ */ (() => globalThis.process?.platform === "win32" ? ";" : ":")(); +const _platforms = { posix: void 0, win32: void 0 }; +const mix = (del = delimiter) => { + return new Proxy(_path, { + get(_, prop) { + if (prop === "delimiter") return del; + if (prop === "posix") return posix; + if (prop === "win32") return win32; + return _platforms[prop] || _path[prop]; + } + }); +}; +const posix = /* @__PURE__ */ mix(":"); +const win32 = /* @__PURE__ */ mix(";"); + +export { posix as default, delimiter, posix, win32 }; diff --git a/node_modules/pathe/dist/shared/pathe.BSlhyZSM.cjs b/node_modules/pathe/dist/shared/pathe.BSlhyZSM.cjs new file mode 100644 index 0000000000..f4a62e3195 --- /dev/null +++ b/node_modules/pathe/dist/shared/pathe.BSlhyZSM.cjs @@ -0,0 +1,266 @@ +'use strict'; + +let _lazyMatch = () => { var __lib__=(()=>{var m=Object.defineProperty,V=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyNames,T=Object.prototype.hasOwnProperty,q=(r,e)=>{for(var n in e)m(r,n,{get:e[n],enumerable:true});},H=(r,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of G(e))!T.call(r,t)&&t!==n&&m(r,t,{get:()=>e[t],enumerable:!(a=V(e,t))||a.enumerable});return r},J=r=>H(m({},"__esModule",{value:true}),r),w={};q(w,{default:()=>re});var A=r=>Array.isArray(r),d=r=>typeof r=="function",Q=r=>r.length===0,W=r=>typeof r=="number",K=r=>typeof r=="object"&&r!==null,X=r=>r instanceof RegExp,b=r=>typeof r=="string",h=r=>r===void 0,Y=r=>{const e=new Map;return n=>{const a=e.get(n);if(a)return a;const t=r(n);return e.set(n,t),t}},rr=(r,e,n={})=>{const a={cache:{},input:r,index:0,indexMax:0,options:n,output:[]};if(v(e)(a)&&a.index===r.length)return a.output;throw new Error(`Failed to parse at index ${a.indexMax}`)},i=(r,e)=>A(r)?er(r,e):b(r)?ar(r,e):nr(r,e),er=(r,e)=>{const n={};for(const a of r){if(a.length!==1)throw new Error(`Invalid character: "${a}"`);const t=a.charCodeAt(0);n[t]=true;}return a=>{const t=a.index,o=a.input;for(;a.indext){if(!h(e)&&!a.options.silent){const s=a.input.slice(t,u),c=d(e)?e(s,o,String(t)):e;h(c)||a.output.push(c);}a.indexMax=Math.max(a.indexMax,a.index);}return true}},nr=(r,e)=>{const n=r.source,a=r.flags.replace(/y|$/,"y"),t=new RegExp(n,a);return g(o=>{t.lastIndex=o.index;const u=t.exec(o.input);if(u){if(!h(e)&&!o.options.silent){const s=d(e)?e(...u,o.input,String(o.index)):e;h(s)||o.output.push(s);}return o.index+=u[0].length,o.indexMax=Math.max(o.indexMax,o.index),true}else return false})},ar=(r,e)=>n=>{if(n.input.startsWith(r,n.index)){if(!h(e)&&!n.options.silent){const t=d(e)?e(r,n.input,String(n.index)):e;h(t)||n.output.push(t);}return n.index+=r.length,n.indexMax=Math.max(n.indexMax,n.index),true}else return false},C=(r,e,n,a)=>{const t=v(r);return g(_(M(o=>{let u=0;for(;u=e})))},tr=(r,e)=>C(r,0,1),f=(r,e)=>C(r,0,1/0),x=(r,e)=>{const n=r.map(v);return g(_(M(a=>{for(let t=0,o=n.length;t{const n=r.map(v);return g(_(a=>{for(let t=0,o=n.length;t{const n=v(r);return a=>{const t=a.index,o=a.output.length,u=n(a);return (!u||e)&&(a.index=t,a.output.length!==o&&(a.output.length=o)),u}},_=(r,e)=>{const n=v(r);return n},g=(()=>{let r=0;return e=>{const n=v(e),a=r+=1;return t=>{var o;if(t.options.memoization===false)return n(t);const u=t.index,s=(o=t.cache)[a]||(o[a]=new Map),c=s.get(u);if(c===false)return false;if(W(c))return t.index=c,true;if(c)return t.index=c.index,c.output?.length&&t.output.push(...c.output),true;{const Z=t.output.length;if(n(t)){const D=t.index,U=t.output.length;if(U>Z){const ee=t.output.slice(Z,U);s.set(u,{index:D,output:ee});}else s.set(u,D);return true}else return s.set(u,false),false}}}})(),E=r=>{let e;return n=>(e||(e=v(r())),e(n))},v=Y(r=>{if(d(r))return Q(r)?E(r):r;if(b(r)||X(r))return i(r);if(A(r))return x(r);if(K(r))return l(Object.values(r));throw new Error("Invalid rule")}),P="abcdefghijklmnopqrstuvwxyz",ir=r=>{let e="";for(;r>0;){const n=(r-1)%26;e=P[n]+e,r=Math.floor((r-1)/26);}return e},O=r=>{let e=0;for(let n=0,a=r.length;n{if(eS(r,e).map(a=>String(a).padStart(n,"0")),R=(r,e)=>S(O(r),O(e)).map(ir),p=r=>r,z=r=>ur(e=>rr(e,r,{memoization:false}).join("")),ur=r=>{const e={};return n=>e[n]??(e[n]=r(n))},sr=i(/^\*\*\/\*$/,".*"),cr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]+)$/,(r,e,n)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}`),lr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]*)\{([ a-zA-Z0-9._-]+(?:,[ a-zA-Z0-9._-]+)*)\}$/,(r,e,n,a)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}(?:${a.replaceAll(",","|").replaceAll(".","\\.")})`),y=i(/\\./,p),pr=i(/[$.*+?^(){}[\]\|]/,r=>`\\${r}`),vr=i(/./,p),hr=i(/^(?:!!)*!(.*)$/,(r,e)=>`(?!^${L(e)}$).*?`),dr=i(/^(!!)+/,""),fr=l([hr,dr]),xr=i(/\/(\*\*\/)+/,"(?:/.+/|/)"),gr=i(/^(\*\*\/)+/,"(?:^|.*/)"),mr=i(/\/(\*\*)$/,"(?:/.*|$)"),_r=i(/\*\*/,".*"),j=l([xr,gr,mr,_r]),Sr=i(/\*\/(?!\*\*\/)/,"[^/]*/"),yr=i(/\*/,"[^/]*"),N=l([Sr,yr]),k=i("?","[^/]"),$r=i("[",p),wr=i("]",p),Ar=i(/[!^]/,"^/"),br=i(/[a-z]-[a-z]|[0-9]-[0-9]/i,p),Cr=i(/[$.*+?^(){}[\|]/,r=>`\\${r}`),Mr=i(/[^\]]/,p),Er=l([y,Cr,br,Mr]),B=x([$r,tr(Ar),f(Er),wr]),Pr=i("{","(?:"),Or=i("}",")"),Rr=i(/(\d+)\.\.(\d+)/,(r,e,n)=>or(+e,+n,Math.min(e.length,n.length)).join("|")),zr=i(/([a-z]+)\.\.([a-z]+)/,(r,e,n)=>R(e,n).join("|")),jr=i(/([A-Z]+)\.\.([A-Z]+)/,(r,e,n)=>R(e.toLowerCase(),n.toLowerCase()).join("|").toUpperCase()),Nr=l([Rr,zr,jr]),I=x([Pr,Nr,Or]),kr=i("{","(?:"),Br=i("}",")"),Ir=i(",","|"),Fr=i(/[$.*+?^(){[\]\|]/,r=>`\\${r}`),Lr=i(/[^}]/,p),Zr=E(()=>F),Dr=l([j,N,k,B,I,Zr,y,Fr,Ir,Lr]),F=x([kr,f(Dr),Br]),Ur=f(l([sr,cr,lr,fr,j,N,k,B,I,F,y,pr,vr])),Vr=Ur,Gr=z(Vr),L=Gr,Tr=i(/\\./,p),qr=i(/./,p),Hr=i(/\*\*\*+/,"*"),Jr=i(/([^/{[(!])\*\*/,(r,e)=>`${e}*`),Qr=i(/(^|.)\*\*(?=[^*/)\]}])/,(r,e)=>`${e}*`),Wr=f(l([Tr,Hr,Jr,Qr,qr])),Kr=Wr,Xr=z(Kr),Yr=Xr,$=(r,e)=>{const n=Array.isArray(r)?r:[r];if(!n.length)return false;const a=n.map($.compile),t=n.every(s=>/(\/(?:\*\*)?|\[\/\])$/.test(s)),o=e.replace(/[\\\/]+/g,"/").replace(/\/$/,t?"/":"");return a.some(s=>s.test(o))};$.compile=r=>new RegExp(`^${L(Yr(r))}$`,"s");var re=$;return J(w)})(); + return __lib__.default || __lib__; }; +let _match; +const zeptomatch = (path, pattern) => { + if (!_match) { + _match = _lazyMatch(); + _lazyMatch = null; + } + return _match(path, pattern); +}; + +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; +const _EXTNAME_RE = /.(\.[^./]+|\.)$/; +const _PATH_ROOT_RE = /^[/\\]|^[a-zA-Z]:[/\\]/; +const sep = "/"; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...segments) { + let path = ""; + for (const seg of segments) { + if (!seg) { + continue; + } + if (path.length > 0) { + const pathTrailing = path[path.length - 1] === "/"; + const segLeading = seg[0] === "/"; + const both = pathTrailing && segLeading; + if (both) { + path += seg.slice(1); + } else { + path += pathTrailing || segLeading ? seg : `/${seg}`; + } + } else { + path += seg; + } + } + return normalize(path); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const toNamespacedPath = function(p) { + return normalizeWindowsPath(p); +}; +const extname = function(p) { + if (p === "..") return ""; + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const relative = function(from, to) { + const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); + const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); + if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { + return _to.join("/"); + } + const _fromCopy = [..._from]; + for (const segment of _fromCopy) { + if (_to[0] !== segment) { + break; + } + _from.shift(); + _to.shift(); + } + return [..._from.map(() => ".."), ..._to].join("/"); +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { + segments[0] += "/"; + } + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const format = function(p) { + const ext = p.ext ? p.ext.startsWith(".") ? p.ext : `.${p.ext}` : ""; + const segments = [p.root, p.dir, p.base ?? (p.name ?? "") + ext].filter( + Boolean + ); + return normalizeWindowsPath( + p.root ? resolve(...segments) : segments.join("/") + ); +}; +const basename = function(p, extension) { + const segments = normalizeWindowsPath(p).split("/"); + let lastSegment = ""; + for (let i = segments.length - 1; i >= 0; i--) { + const val = segments[i]; + if (val) { + lastSegment = val; + break; + } + } + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; +const parse = function(p) { + const root = _PATH_ROOT_RE.exec(p)?.[0]?.replace(/\\/g, "/") || ""; + const base = basename(p); + const extension = extname(base); + return { + root, + dir: dirname(p), + base, + ext: extension, + name: base.slice(0, base.length - extension.length) + }; +}; +const matchesGlob = (path, pattern) => { + return zeptomatch(pattern, normalize(path)); +}; + +const _path = { + __proto__: null, + basename: basename, + dirname: dirname, + extname: extname, + format: format, + isAbsolute: isAbsolute, + join: join, + matchesGlob: matchesGlob, + normalize: normalize, + normalizeString: normalizeString, + parse: parse, + relative: relative, + resolve: resolve, + sep: sep, + toNamespacedPath: toNamespacedPath +}; + +exports._path = _path; +exports.basename = basename; +exports.dirname = dirname; +exports.extname = extname; +exports.format = format; +exports.isAbsolute = isAbsolute; +exports.join = join; +exports.matchesGlob = matchesGlob; +exports.normalize = normalize; +exports.normalizeString = normalizeString; +exports.normalizeWindowsPath = normalizeWindowsPath; +exports.parse = parse; +exports.relative = relative; +exports.resolve = resolve; +exports.sep = sep; +exports.toNamespacedPath = toNamespacedPath; diff --git a/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs b/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs new file mode 100644 index 0000000000..81d714d6ea --- /dev/null +++ b/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs @@ -0,0 +1,249 @@ +let _lazyMatch = () => { var __lib__=(()=>{var m=Object.defineProperty,V=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyNames,T=Object.prototype.hasOwnProperty,q=(r,e)=>{for(var n in e)m(r,n,{get:e[n],enumerable:true});},H=(r,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of G(e))!T.call(r,t)&&t!==n&&m(r,t,{get:()=>e[t],enumerable:!(a=V(e,t))||a.enumerable});return r},J=r=>H(m({},"__esModule",{value:true}),r),w={};q(w,{default:()=>re});var A=r=>Array.isArray(r),d=r=>typeof r=="function",Q=r=>r.length===0,W=r=>typeof r=="number",K=r=>typeof r=="object"&&r!==null,X=r=>r instanceof RegExp,b=r=>typeof r=="string",h=r=>r===void 0,Y=r=>{const e=new Map;return n=>{const a=e.get(n);if(a)return a;const t=r(n);return e.set(n,t),t}},rr=(r,e,n={})=>{const a={cache:{},input:r,index:0,indexMax:0,options:n,output:[]};if(v(e)(a)&&a.index===r.length)return a.output;throw new Error(`Failed to parse at index ${a.indexMax}`)},i=(r,e)=>A(r)?er(r,e):b(r)?ar(r,e):nr(r,e),er=(r,e)=>{const n={};for(const a of r){if(a.length!==1)throw new Error(`Invalid character: "${a}"`);const t=a.charCodeAt(0);n[t]=true;}return a=>{const t=a.index,o=a.input;for(;a.indext){if(!h(e)&&!a.options.silent){const s=a.input.slice(t,u),c=d(e)?e(s,o,String(t)):e;h(c)||a.output.push(c);}a.indexMax=Math.max(a.indexMax,a.index);}return true}},nr=(r,e)=>{const n=r.source,a=r.flags.replace(/y|$/,"y"),t=new RegExp(n,a);return g(o=>{t.lastIndex=o.index;const u=t.exec(o.input);if(u){if(!h(e)&&!o.options.silent){const s=d(e)?e(...u,o.input,String(o.index)):e;h(s)||o.output.push(s);}return o.index+=u[0].length,o.indexMax=Math.max(o.indexMax,o.index),true}else return false})},ar=(r,e)=>n=>{if(n.input.startsWith(r,n.index)){if(!h(e)&&!n.options.silent){const t=d(e)?e(r,n.input,String(n.index)):e;h(t)||n.output.push(t);}return n.index+=r.length,n.indexMax=Math.max(n.indexMax,n.index),true}else return false},C=(r,e,n,a)=>{const t=v(r);return g(_(M(o=>{let u=0;for(;u=e})))},tr=(r,e)=>C(r,0,1),f=(r,e)=>C(r,0,1/0),x=(r,e)=>{const n=r.map(v);return g(_(M(a=>{for(let t=0,o=n.length;t{const n=r.map(v);return g(_(a=>{for(let t=0,o=n.length;t{const n=v(r);return a=>{const t=a.index,o=a.output.length,u=n(a);return (!u||e)&&(a.index=t,a.output.length!==o&&(a.output.length=o)),u}},_=(r,e)=>{const n=v(r);return n},g=(()=>{let r=0;return e=>{const n=v(e),a=r+=1;return t=>{var o;if(t.options.memoization===false)return n(t);const u=t.index,s=(o=t.cache)[a]||(o[a]=new Map),c=s.get(u);if(c===false)return false;if(W(c))return t.index=c,true;if(c)return t.index=c.index,c.output?.length&&t.output.push(...c.output),true;{const Z=t.output.length;if(n(t)){const D=t.index,U=t.output.length;if(U>Z){const ee=t.output.slice(Z,U);s.set(u,{index:D,output:ee});}else s.set(u,D);return true}else return s.set(u,false),false}}}})(),E=r=>{let e;return n=>(e||(e=v(r())),e(n))},v=Y(r=>{if(d(r))return Q(r)?E(r):r;if(b(r)||X(r))return i(r);if(A(r))return x(r);if(K(r))return l(Object.values(r));throw new Error("Invalid rule")}),P="abcdefghijklmnopqrstuvwxyz",ir=r=>{let e="";for(;r>0;){const n=(r-1)%26;e=P[n]+e,r=Math.floor((r-1)/26);}return e},O=r=>{let e=0;for(let n=0,a=r.length;n{if(eS(r,e).map(a=>String(a).padStart(n,"0")),R=(r,e)=>S(O(r),O(e)).map(ir),p=r=>r,z=r=>ur(e=>rr(e,r,{memoization:false}).join("")),ur=r=>{const e={};return n=>e[n]??(e[n]=r(n))},sr=i(/^\*\*\/\*$/,".*"),cr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]+)$/,(r,e,n)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}`),lr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]*)\{([ a-zA-Z0-9._-]+(?:,[ a-zA-Z0-9._-]+)*)\}$/,(r,e,n,a)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}(?:${a.replaceAll(",","|").replaceAll(".","\\.")})`),y=i(/\\./,p),pr=i(/[$.*+?^(){}[\]\|]/,r=>`\\${r}`),vr=i(/./,p),hr=i(/^(?:!!)*!(.*)$/,(r,e)=>`(?!^${L(e)}$).*?`),dr=i(/^(!!)+/,""),fr=l([hr,dr]),xr=i(/\/(\*\*\/)+/,"(?:/.+/|/)"),gr=i(/^(\*\*\/)+/,"(?:^|.*/)"),mr=i(/\/(\*\*)$/,"(?:/.*|$)"),_r=i(/\*\*/,".*"),j=l([xr,gr,mr,_r]),Sr=i(/\*\/(?!\*\*\/)/,"[^/]*/"),yr=i(/\*/,"[^/]*"),N=l([Sr,yr]),k=i("?","[^/]"),$r=i("[",p),wr=i("]",p),Ar=i(/[!^]/,"^/"),br=i(/[a-z]-[a-z]|[0-9]-[0-9]/i,p),Cr=i(/[$.*+?^(){}[\|]/,r=>`\\${r}`),Mr=i(/[^\]]/,p),Er=l([y,Cr,br,Mr]),B=x([$r,tr(Ar),f(Er),wr]),Pr=i("{","(?:"),Or=i("}",")"),Rr=i(/(\d+)\.\.(\d+)/,(r,e,n)=>or(+e,+n,Math.min(e.length,n.length)).join("|")),zr=i(/([a-z]+)\.\.([a-z]+)/,(r,e,n)=>R(e,n).join("|")),jr=i(/([A-Z]+)\.\.([A-Z]+)/,(r,e,n)=>R(e.toLowerCase(),n.toLowerCase()).join("|").toUpperCase()),Nr=l([Rr,zr,jr]),I=x([Pr,Nr,Or]),kr=i("{","(?:"),Br=i("}",")"),Ir=i(",","|"),Fr=i(/[$.*+?^(){[\]\|]/,r=>`\\${r}`),Lr=i(/[^}]/,p),Zr=E(()=>F),Dr=l([j,N,k,B,I,Zr,y,Fr,Ir,Lr]),F=x([kr,f(Dr),Br]),Ur=f(l([sr,cr,lr,fr,j,N,k,B,I,F,y,pr,vr])),Vr=Ur,Gr=z(Vr),L=Gr,Tr=i(/\\./,p),qr=i(/./,p),Hr=i(/\*\*\*+/,"*"),Jr=i(/([^/{[(!])\*\*/,(r,e)=>`${e}*`),Qr=i(/(^|.)\*\*(?=[^*/)\]}])/,(r,e)=>`${e}*`),Wr=f(l([Tr,Hr,Jr,Qr,qr])),Kr=Wr,Xr=z(Kr),Yr=Xr,$=(r,e)=>{const n=Array.isArray(r)?r:[r];if(!n.length)return false;const a=n.map($.compile),t=n.every(s=>/(\/(?:\*\*)?|\[\/\])$/.test(s)),o=e.replace(/[\\\/]+/g,"/").replace(/\/$/,t?"/":"");return a.some(s=>s.test(o))};$.compile=r=>new RegExp(`^${L(Yr(r))}$`,"s");var re=$;return J(w)})(); + return __lib__.default || __lib__; }; +let _match; +const zeptomatch = (path, pattern) => { + if (!_match) { + _match = _lazyMatch(); + _lazyMatch = null; + } + return _match(path, pattern); +}; + +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; +const _EXTNAME_RE = /.(\.[^./]+|\.)$/; +const _PATH_ROOT_RE = /^[/\\]|^[a-zA-Z]:[/\\]/; +const sep = "/"; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...segments) { + let path = ""; + for (const seg of segments) { + if (!seg) { + continue; + } + if (path.length > 0) { + const pathTrailing = path[path.length - 1] === "/"; + const segLeading = seg[0] === "/"; + const both = pathTrailing && segLeading; + if (both) { + path += seg.slice(1); + } else { + path += pathTrailing || segLeading ? seg : `/${seg}`; + } + } else { + path += seg; + } + } + return normalize(path); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const toNamespacedPath = function(p) { + return normalizeWindowsPath(p); +}; +const extname = function(p) { + if (p === "..") return ""; + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const relative = function(from, to) { + const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); + const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); + if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { + return _to.join("/"); + } + const _fromCopy = [..._from]; + for (const segment of _fromCopy) { + if (_to[0] !== segment) { + break; + } + _from.shift(); + _to.shift(); + } + return [..._from.map(() => ".."), ..._to].join("/"); +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { + segments[0] += "/"; + } + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const format = function(p) { + const ext = p.ext ? p.ext.startsWith(".") ? p.ext : `.${p.ext}` : ""; + const segments = [p.root, p.dir, p.base ?? (p.name ?? "") + ext].filter( + Boolean + ); + return normalizeWindowsPath( + p.root ? resolve(...segments) : segments.join("/") + ); +}; +const basename = function(p, extension) { + const segments = normalizeWindowsPath(p).split("/"); + let lastSegment = ""; + for (let i = segments.length - 1; i >= 0; i--) { + const val = segments[i]; + if (val) { + lastSegment = val; + break; + } + } + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; +const parse = function(p) { + const root = _PATH_ROOT_RE.exec(p)?.[0]?.replace(/\\/g, "/") || ""; + const base = basename(p); + const extension = extname(base); + return { + root, + dir: dirname(p), + base, + ext: extension, + name: base.slice(0, base.length - extension.length) + }; +}; +const matchesGlob = (path, pattern) => { + return zeptomatch(pattern, normalize(path)); +}; + +const _path = { + __proto__: null, + basename: basename, + dirname: dirname, + extname: extname, + format: format, + isAbsolute: isAbsolute, + join: join, + matchesGlob: matchesGlob, + normalize: normalize, + normalizeString: normalizeString, + parse: parse, + relative: relative, + resolve: resolve, + sep: sep, + toNamespacedPath: toNamespacedPath +}; + +export { _path as _, normalizeString as a, relative as b, basename as c, dirname as d, extname as e, format as f, normalizeWindowsPath as g, isAbsolute as i, join as j, matchesGlob as m, normalize as n, parse as p, resolve as r, sep as s, toNamespacedPath as t }; diff --git a/node_modules/pathe/dist/utils.cjs b/node_modules/pathe/dist/utils.cjs new file mode 100644 index 0000000000..03c7ff39fc --- /dev/null +++ b/node_modules/pathe/dist/utils.cjs @@ -0,0 +1,82 @@ +'use strict'; + +const _path = require('./shared/pathe.BSlhyZSM.cjs'); + +const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]); +const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias"); +const SLASH_RE = /[/\\]/; +function normalizeAliases(_aliases) { + if (_aliases[normalizedAliasSymbol]) { + return _aliases; + } + const aliases = Object.fromEntries( + Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b)) + ); + for (const key in aliases) { + for (const alias in aliases) { + if (alias === key || key.startsWith(alias)) { + continue; + } + if (aliases[key]?.startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) { + aliases[key] = aliases[alias] + aliases[key].slice(alias.length); + } + } + } + Object.defineProperty(aliases, normalizedAliasSymbol, { + value: true, + enumerable: false + }); + return aliases; +} +function resolveAlias(path, aliases) { + const _path$1 = _path.normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + for (const [alias, to] of Object.entries(aliases)) { + if (!_path$1.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path$1[_alias.length])) { + return _path.join(to, _path$1.slice(alias.length)); + } + } + return _path$1; +} +function reverseResolveAlias(path, aliases) { + const _path$1 = _path.normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + const matches = []; + for (const [to, alias] of Object.entries(aliases)) { + if (!_path$1.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path$1[_alias.length])) { + matches.push(_path.join(to, _path$1.slice(alias.length))); + } + } + return matches.sort((a, b) => b.length - a.length); +} +function filename(path) { + const base = path.split(SLASH_RE).pop(); + if (!base) { + return void 0; + } + const separatorIndex = base.lastIndexOf("."); + if (separatorIndex <= 0) { + return base; + } + return base.slice(0, separatorIndex); +} +function _compareAliases(a, b) { + return b.split("/").length - a.split("/").length; +} +function hasTrailingSlash(path = "/") { + const lastChar = path[path.length - 1]; + return lastChar === "/" || lastChar === "\\"; +} + +exports.filename = filename; +exports.normalizeAliases = normalizeAliases; +exports.resolveAlias = resolveAlias; +exports.reverseResolveAlias = reverseResolveAlias; diff --git a/node_modules/pathe/dist/utils.d.cts b/node_modules/pathe/dist/utils.d.cts new file mode 100644 index 0000000000..af369d0234 --- /dev/null +++ b/node_modules/pathe/dist/utils.d.cts @@ -0,0 +1,32 @@ +/** + * Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones. + * This function also ensures that aliases do not resolve to themselves cyclically. + * + * @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to. + * @returns a set of normalised alias mappings. + */ +declare function normalizeAliases(_aliases: Record): Record; +/** + * Resolves a path string to its alias if applicable, otherwise returns the original path. + * This function normalises the path, resolves the alias and then joins it to the alias target if necessary. + * + * @param path - The path string to resolve. + * @param aliases - A set of alias mappings to use for resolution. + * @returns the resolved path as a string. + */ +declare function resolveAlias(path: string, aliases: Record): string; +/** + * Resolves a path string to its possible alias. + * + * Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first). + */ +declare function reverseResolveAlias(path: string, aliases: Record): string[]; +/** + * Extracts the filename from a given path, excluding any directory paths and the file extension. + * + * @param path - The full path of the file from which to extract the filename. + * @returns the filename without the extension, or `undefined` if the filename cannot be extracted. + */ +declare function filename(path: string): string | undefined; + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/pathe/dist/utils.d.mts b/node_modules/pathe/dist/utils.d.mts new file mode 100644 index 0000000000..af369d0234 --- /dev/null +++ b/node_modules/pathe/dist/utils.d.mts @@ -0,0 +1,32 @@ +/** + * Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones. + * This function also ensures that aliases do not resolve to themselves cyclically. + * + * @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to. + * @returns a set of normalised alias mappings. + */ +declare function normalizeAliases(_aliases: Record): Record; +/** + * Resolves a path string to its alias if applicable, otherwise returns the original path. + * This function normalises the path, resolves the alias and then joins it to the alias target if necessary. + * + * @param path - The path string to resolve. + * @param aliases - A set of alias mappings to use for resolution. + * @returns the resolved path as a string. + */ +declare function resolveAlias(path: string, aliases: Record): string; +/** + * Resolves a path string to its possible alias. + * + * Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first). + */ +declare function reverseResolveAlias(path: string, aliases: Record): string[]; +/** + * Extracts the filename from a given path, excluding any directory paths and the file extension. + * + * @param path - The full path of the file from which to extract the filename. + * @returns the filename without the extension, or `undefined` if the filename cannot be extracted. + */ +declare function filename(path: string): string | undefined; + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/pathe/dist/utils.d.ts b/node_modules/pathe/dist/utils.d.ts new file mode 100644 index 0000000000..af369d0234 --- /dev/null +++ b/node_modules/pathe/dist/utils.d.ts @@ -0,0 +1,32 @@ +/** + * Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones. + * This function also ensures that aliases do not resolve to themselves cyclically. + * + * @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to. + * @returns a set of normalised alias mappings. + */ +declare function normalizeAliases(_aliases: Record): Record; +/** + * Resolves a path string to its alias if applicable, otherwise returns the original path. + * This function normalises the path, resolves the alias and then joins it to the alias target if necessary. + * + * @param path - The path string to resolve. + * @param aliases - A set of alias mappings to use for resolution. + * @returns the resolved path as a string. + */ +declare function resolveAlias(path: string, aliases: Record): string; +/** + * Resolves a path string to its possible alias. + * + * Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first). + */ +declare function reverseResolveAlias(path: string, aliases: Record): string[]; +/** + * Extracts the filename from a given path, excluding any directory paths and the file extension. + * + * @param path - The full path of the file from which to extract the filename. + * @returns the filename without the extension, or `undefined` if the filename cannot be extracted. + */ +declare function filename(path: string): string | undefined; + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/pathe/dist/utils.mjs b/node_modules/pathe/dist/utils.mjs new file mode 100644 index 0000000000..748072e997 --- /dev/null +++ b/node_modules/pathe/dist/utils.mjs @@ -0,0 +1,77 @@ +import { g as normalizeWindowsPath, j as join } from './shared/pathe.M-eThtNZ.mjs'; + +const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]); +const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias"); +const SLASH_RE = /[/\\]/; +function normalizeAliases(_aliases) { + if (_aliases[normalizedAliasSymbol]) { + return _aliases; + } + const aliases = Object.fromEntries( + Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b)) + ); + for (const key in aliases) { + for (const alias in aliases) { + if (alias === key || key.startsWith(alias)) { + continue; + } + if (aliases[key]?.startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) { + aliases[key] = aliases[alias] + aliases[key].slice(alias.length); + } + } + } + Object.defineProperty(aliases, normalizedAliasSymbol, { + value: true, + enumerable: false + }); + return aliases; +} +function resolveAlias(path, aliases) { + const _path = normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + for (const [alias, to] of Object.entries(aliases)) { + if (!_path.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path[_alias.length])) { + return join(to, _path.slice(alias.length)); + } + } + return _path; +} +function reverseResolveAlias(path, aliases) { + const _path = normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + const matches = []; + for (const [to, alias] of Object.entries(aliases)) { + if (!_path.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path[_alias.length])) { + matches.push(join(to, _path.slice(alias.length))); + } + } + return matches.sort((a, b) => b.length - a.length); +} +function filename(path) { + const base = path.split(SLASH_RE).pop(); + if (!base) { + return void 0; + } + const separatorIndex = base.lastIndexOf("."); + if (separatorIndex <= 0) { + return base; + } + return base.slice(0, separatorIndex); +} +function _compareAliases(a, b) { + return b.split("/").length - a.split("/").length; +} +function hasTrailingSlash(path = "/") { + const lastChar = path[path.length - 1]; + return lastChar === "/" || lastChar === "\\"; +} + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/pathe/package.json b/node_modules/pathe/package.json new file mode 100644 index 0000000000..5522b285a8 --- /dev/null +++ b/node_modules/pathe/package.json @@ -0,0 +1,61 @@ +{ + "name": "pathe", + "version": "2.0.3", + "description": "Universal filesystem path utils", + "repository": "unjs/pathe", + "license": "MIT", + "sideEffects": false, + "type": "module", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./utils": { + "import": { + "types": "./dist/utils.d.mts", + "default": "./dist/utils.mjs" + }, + "require": { + "types": "./dist/utils.d.cts", + "default": "./dist/utils.cjs" + } + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "utils.d.ts" + ], + "devDependencies": { + "@types/node": "^22.13.1", + "@vitest/coverage-v8": "^3.0.5", + "changelogen": "^0.5.7", + "esbuild": "^0.25.0", + "eslint": "^9.20.1", + "eslint-config-unjs": "^0.4.2", + "jiti": "^2.4.2", + "prettier": "^3.5.0", + "typescript": "^5.7.3", + "unbuild": "^3.3.1", + "vitest": "^3.0.5", + "zeptomatch": "^2.0.0" + }, + "scripts": { + "build": "unbuild", + "dev": "vitest", + "lint": "eslint . && prettier -c src test", + "lint:fix": "eslint . --fix && prettier -w src test", + "release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags", + "test": "pnpm lint && vitest run --coverage", + "test:types": "tsc --noEmit" + } +} \ No newline at end of file diff --git a/node_modules/pathe/utils.d.ts b/node_modules/pathe/utils.d.ts new file mode 100644 index 0000000000..59cabd3e95 --- /dev/null +++ b/node_modules/pathe/utils.d.ts @@ -0,0 +1 @@ +export * from "./dist/utils"; diff --git a/node_modules/pathval/LICENSE b/node_modules/pathval/LICENSE new file mode 100644 index 0000000000..90d22da6af --- /dev/null +++ b/node_modules/pathval/LICENSE @@ -0,0 +1,16 @@ +MIT License + +Copyright (c) 2011-2013 Jake Luer jake@alogicalparadox.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/pathval/README.md b/node_modules/pathval/README.md new file mode 100644 index 0000000000..22a841eb93 --- /dev/null +++ b/node_modules/pathval/README.md @@ -0,0 +1,147 @@ +

+ + ChaiJS + +
+ pathval +

+ +

+ Tool for Object value retrieval given a string path for node and the browser. +

+ +

+ + license:mit + + + tag:? + + + build:? + + + coverage:? + + + npm:? + + + dependencies:? + + + devDependencies:? + +
+ + Selenium Test Status + +
+ + Join the Slack chat + + + Join the Gitter chat + +

+ +## What is pathval? + +Pathval is a module which you can use to retrieve or set an Object's property for a given `String` path. + +## Installation + +### Node.js + +`pathval` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install pathval + +### Browsers + +You can also use it within the browser; install via npm and use the `pathval.js` file found within the download. For example: + +```html + +``` + +## Usage + +The primary export of `pathval` is an object which has the following methods: + +* `hasProperty(object, name)` - Checks whether an `object` has `name`d property or numeric array index. +* `getPathInfo(object, path)` - Returns an object with info indicating the value of the `parent` of that path, the `name ` of the property we're retrieving and its `value`. +* `getPathValue(object, path)` - Retrieves the value of a property at a given `path` inside an `object`'. +* `setPathValue(object, path, value)` - Sets the `value` of a property at a given `path` inside an `object` and returns the object in which the property has been set. + +```js +var pathval = require('pathval'); +``` + +#### .hasProperty(object, name) + +```js +var pathval = require('pathval'); + +var obj = { prop: 'a value' }; +pathval.hasProperty(obj, 'prop'); // true +``` + +#### .getPathInfo(object, path) + +```js +var pathval = require('pathval'); + +var obj = { earth: { country: 'Brazil' } }; +pathval.getPathInfo(obj, 'earth.country'); // { parent: { country: 'Brazil' }, name: 'country', value: 'Brazil', exists: true } +``` + +#### .getPathValue(object, path) + +```js +var pathval = require('pathval'); + +var obj = { earth: { country: 'Brazil' } }; +pathval.getPathValue(obj, 'earth.country'); // 'Brazil' +``` + +#### .setPathValue(object, path, value) + +```js +var pathval = require('pathval'); + +var obj = { earth: { country: 'Brazil' } }; +pathval.setPathValue(obj, 'earth.country', 'USA'); + +obj.earth.country; // 'USA' +``` diff --git a/node_modules/pathval/index.js b/node_modules/pathval/index.js new file mode 100644 index 0000000000..4db57fabce --- /dev/null +++ b/node_modules/pathval/index.js @@ -0,0 +1,292 @@ +/* ! + * Chai - pathval utility + * Copyright(c) 2012-2014 Jake Luer + * @see https://github.com/logicalparadox/filtr + * MIT Licensed + */ + +/** + * ### .hasProperty(object, name) + * + * This allows checking whether an object has own + * or inherited from prototype chain named property. + * + * Basically does the same thing as the `in` + * operator but works properly with null/undefined values + * and other primitives. + * + * var obj = { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * + * The following would be the results. + * + * hasProperty(obj, 'str'); // true + * hasProperty(obj, 'constructor'); // true + * hasProperty(obj, 'bar'); // false + * + * hasProperty(obj.str, 'length'); // true + * hasProperty(obj.str, 1); // true + * hasProperty(obj.str, 5); // false + * + * hasProperty(obj.arr, 'length'); // true + * hasProperty(obj.arr, 2); // true + * hasProperty(obj.arr, 3); // false + * + * @param {Object} object + * @param {String|Symbol} name + * @returns {Boolean} whether it exists + * @namespace Utils + * @name hasProperty + * @api public + */ + +export function hasProperty(obj, name) { + if (typeof obj === 'undefined' || obj === null) { + return false; + } + + // The `in` operator does not work with primitives. + return name in Object(obj); +} + +/* ! + * ## parsePath(path) + * + * Helper function used to parse string object + * paths. Use in conjunction with `internalGetPathValue`. + * + * var parsed = parsePath('myobject.property.subprop'); + * + * ### Paths: + * + * * Can be infinitely deep and nested. + * * Arrays are also valid using the formal `myobject.document[3].property`. + * * Literal dots and brackets (not delimiter) must be backslash-escaped. + * + * @param {String} path + * @returns {Object} parsed + * @api private + */ + +function parsePath(path) { + const str = path.replace(/([^\\])\[/g, '$1.['); + const parts = str.match(/(\\\.|[^.]+?)+/g); + return parts.map((value) => { + if ( + value === 'constructor' || + value === '__proto__' || + value === 'prototype' + ) { + return {}; + } + const regexp = /^\[(\d+)\]$/; + const mArr = regexp.exec(value); + let parsed = null; + if (mArr) { + parsed = { i: parseFloat(mArr[1]) }; + } else { + parsed = { p: value.replace(/\\([.[\]])/g, '$1') }; + } + + return parsed; + }); +} + +/* ! + * ## internalGetPathValue(obj, parsed[, pathDepth]) + * + * Helper companion function for `.parsePath` that returns + * the value located at the parsed address. + * + * var value = getPathValue(obj, parsed); + * + * @param {Object} object to search against + * @param {Object} parsed definition from `parsePath`. + * @param {Number} depth (nesting level) of the property we want to retrieve + * @returns {Object|Undefined} value + * @api private + */ + +function internalGetPathValue(obj, parsed, pathDepth) { + let temporaryValue = obj; + let res = null; + pathDepth = typeof pathDepth === 'undefined' ? parsed.length : pathDepth; + + for (let i = 0; i < pathDepth; i++) { + const part = parsed[i]; + if (temporaryValue) { + if (typeof part.p === 'undefined') { + temporaryValue = temporaryValue[part.i]; + } else { + temporaryValue = temporaryValue[part.p]; + } + + if (i === pathDepth - 1) { + res = temporaryValue; + } + } + } + + return res; +} + +/* ! + * ## internalSetPathValue(obj, value, parsed) + * + * Companion function for `parsePath` that sets + * the value located at a parsed address. + * + * internalSetPathValue(obj, 'value', parsed); + * + * @param {Object} object to search and define on + * @param {*} value to use upon set + * @param {Object} parsed definition from `parsePath` + * @api private + */ + +function internalSetPathValue(obj, val, parsed) { + let tempObj = obj; + const pathDepth = parsed.length; + let part = null; + // Here we iterate through every part of the path + for (let i = 0; i < pathDepth; i++) { + let propName = null; + let propVal = null; + part = parsed[i]; + + // If it's the last part of the path, we set the 'propName' value with the property name + if (i === pathDepth - 1) { + propName = typeof part.p === 'undefined' ? part.i : part.p; + // Now we set the property with the name held by 'propName' on object with the desired val + tempObj[propName] = val; + } else if (typeof part.p !== 'undefined' && tempObj[part.p]) { + tempObj = tempObj[part.p]; + } else if (typeof part.i !== 'undefined' && tempObj[part.i]) { + tempObj = tempObj[part.i]; + } else { + // If the obj doesn't have the property we create one with that name to define it + const next = parsed[i + 1]; + // Here we set the name of the property which will be defined + propName = typeof part.p === 'undefined' ? part.i : part.p; + // Here we decide if this property will be an array or a new object + propVal = typeof next.p === 'undefined' ? [] : {}; + tempObj[propName] = propVal; + tempObj = tempObj[propName]; + } + } +} + +/** + * ### .getPathInfo(object, path) + * + * This allows the retrieval of property info in an + * object given a string path. + * + * The path info consists of an object with the + * following properties: + * + * * parent - The parent object of the property referenced by `path` + * * name - The name of the final property, a number if it was an array indexer + * * value - The value of the property, if it exists, otherwise `undefined` + * * exists - Whether the property exists or not + * + * @param {Object} object + * @param {String} path + * @returns {Object} info + * @namespace Utils + * @name getPathInfo + * @api public + */ + +export function getPathInfo(obj, path) { + const parsed = parsePath(path); + const last = parsed[parsed.length - 1]; + const info = { + parent: + parsed.length > 1 ? + internalGetPathValue(obj, parsed, parsed.length - 1) : + obj, + name: last.p || last.i, + value: internalGetPathValue(obj, parsed), + }; + info.exists = hasProperty(info.parent, info.name); + + return info; +} + +/** + * ### .getPathValue(object, path) + * + * This allows the retrieval of values in an + * object given a string path. + * + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * } + * + * The following would be the results. + * + * getPathValue(obj, 'prop1.str'); // Hello + * getPathValue(obj, 'prop1.att[2]'); // b + * getPathValue(obj, 'prop2.arr[0].nested'); // Universe + * + * @param {Object} object + * @param {String} path + * @returns {Object} value or `undefined` + * @namespace Utils + * @name getPathValue + * @api public + */ + +export function getPathValue(obj, path) { + const info = getPathInfo(obj, path); + return info.value; +} + +/** + * ### .setPathValue(object, path, value) + * + * Define the value in an object at a given string path. + * + * ```js + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * }; + * ``` + * + * The following would be acceptable. + * + * ```js + * var properties = require('tea-properties'); + * properties.set(obj, 'prop1.str', 'Hello Universe!'); + * properties.set(obj, 'prop1.arr[2]', 'B'); + * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' }); + * ``` + * + * @param {Object} object + * @param {String} path + * @param {Mixed} value + * @api private + */ + +export function setPathValue(obj, path, val) { + const parsed = parsePath(path); + internalSetPathValue(obj, val, parsed); + return obj; +} diff --git a/node_modules/pathval/package.json b/node_modules/pathval/package.json new file mode 100644 index 0000000000..c93b260464 --- /dev/null +++ b/node_modules/pathval/package.json @@ -0,0 +1,64 @@ +{ + "name": "pathval", + "description": "Object value retrieval given a string path", + "homepage": "https://github.com/chaijs/pathval", + "version": "2.0.1", + "keywords": [ + "pathval", + "value retrieval", + "chai util" + ], + "license": "MIT", + "author": "Veselin Todorov ", + "files": [ + "index.js" + ], + "main": "./index.js", + "type": "module", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/chaijs/pathval.git" + }, + "scripts": { + "lint": "eslint --ignore-path .gitignore .", + "lint:fix": "npm run lint -- --fix", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "pretest": "npm run lint", + "test": "npm run test:node && npm run test:browser", + "test:browser": "web-test-runner test/index.js --node-resolve", + "test:node": "mocha", + "prepare": "husky" + }, + "eslintConfig": { + "extends": [ + "strict/es6" + ], + "parserOptions": { + "sourceType": "module" + }, + "env": { + "es6": true + }, + "globals": { + "HTMLElement": false + }, + "rules": { + "complexity": 0, + "max-statements": 0 + } + }, + "devDependencies": { + "@web/test-runner": "^0.17.0", + "eslint": "^7.13.0", + "eslint-config-strict": "^14.0.1", + "eslint-plugin-filenames": "^1.3.2", + "husky": "^9.1.7", + "mocha": "^8.2.1", + "semantic-release": "^17.2.2", + "simple-assert": "^2.0.0", + "validate-commit-msg": "^2.14.0" + }, + "engines": { + "node": ">= 14.16" + } +} diff --git a/node_modules/picocolors/LICENSE b/node_modules/picocolors/LICENSE new file mode 100644 index 0000000000..46c9b95d4b --- /dev/null +++ b/node_modules/picocolors/LICENSE @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2021-2024 Oleksii Raspopov, Kostiantyn Denysov, Anton Verinov + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/picocolors/README.md b/node_modules/picocolors/README.md new file mode 100644 index 0000000000..8e47aa8eea --- /dev/null +++ b/node_modules/picocolors/README.md @@ -0,0 +1,21 @@ +# picocolors + +The tiniest and the fastest library for terminal output formatting with ANSI colors. + +```javascript +import pc from "picocolors" + +console.log( + pc.green(`How are ${pc.italic(`you`)} doing?`) +) +``` + +- **No dependencies.** +- **14 times** smaller and **2 times** faster than chalk. +- Used by popular tools like PostCSS, SVGO, Stylelint, and Browserslist. +- Node.js v6+ & browsers support. Support for both CJS and ESM projects. +- TypeScript type declarations included. +- [`NO_COLOR`](https://no-color.org/) friendly. + +## Docs +Read **[full docs](https://github.com/alexeyraspopov/picocolors#readme)** on GitHub. diff --git a/node_modules/picocolors/package.json b/node_modules/picocolors/package.json new file mode 100644 index 0000000000..372d4b642c --- /dev/null +++ b/node_modules/picocolors/package.json @@ -0,0 +1,25 @@ +{ + "name": "picocolors", + "version": "1.1.1", + "main": "./picocolors.js", + "types": "./picocolors.d.ts", + "browser": { + "./picocolors.js": "./picocolors.browser.js" + }, + "sideEffects": false, + "description": "The tiniest and the fastest library for terminal output formatting with ANSI colors", + "files": [ + "picocolors.*", + "types.d.ts" + ], + "keywords": [ + "terminal", + "colors", + "formatting", + "cli", + "console" + ], + "author": "Alexey Raspopov", + "repository": "alexeyraspopov/picocolors", + "license": "ISC" +} diff --git a/node_modules/picocolors/picocolors.browser.js b/node_modules/picocolors/picocolors.browser.js new file mode 100644 index 0000000000..9dcf637cda --- /dev/null +++ b/node_modules/picocolors/picocolors.browser.js @@ -0,0 +1,4 @@ +var x=String; +var create=function() {return {isColorSupported:false,reset:x,bold:x,dim:x,italic:x,underline:x,inverse:x,hidden:x,strikethrough:x,black:x,red:x,green:x,yellow:x,blue:x,magenta:x,cyan:x,white:x,gray:x,bgBlack:x,bgRed:x,bgGreen:x,bgYellow:x,bgBlue:x,bgMagenta:x,bgCyan:x,bgWhite:x,blackBright:x,redBright:x,greenBright:x,yellowBright:x,blueBright:x,magentaBright:x,cyanBright:x,whiteBright:x,bgBlackBright:x,bgRedBright:x,bgGreenBright:x,bgYellowBright:x,bgBlueBright:x,bgMagentaBright:x,bgCyanBright:x,bgWhiteBright:x}}; +module.exports=create(); +module.exports.createColors = create; diff --git a/node_modules/picocolors/picocolors.d.ts b/node_modules/picocolors/picocolors.d.ts new file mode 100644 index 0000000000..94e146a822 --- /dev/null +++ b/node_modules/picocolors/picocolors.d.ts @@ -0,0 +1,5 @@ +import { Colors } from "./types" + +declare const picocolors: Colors & { createColors: (enabled?: boolean) => Colors } + +export = picocolors diff --git a/node_modules/picocolors/picocolors.js b/node_modules/picocolors/picocolors.js new file mode 100644 index 0000000000..e32df85488 --- /dev/null +++ b/node_modules/picocolors/picocolors.js @@ -0,0 +1,75 @@ +let p = process || {}, argv = p.argv || [], env = p.env || {} +let isColorSupported = + !(!!env.NO_COLOR || argv.includes("--no-color")) && + (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || ((p.stdout || {}).isTTY && env.TERM !== "dumb") || !!env.CI) + +let formatter = (open, close, replace = open) => + input => { + let string = "" + input, index = string.indexOf(close, open.length) + return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close + } + +let replaceClose = (string, close, replace, index) => { + let result = "", cursor = 0 + do { + result += string.substring(cursor, index) + replace + cursor = index + close.length + index = string.indexOf(close, cursor) + } while (~index) + return result + string.substring(cursor) +} + +let createColors = (enabled = isColorSupported) => { + let f = enabled ? formatter : () => String + return { + isColorSupported: enabled, + reset: f("\x1b[0m", "\x1b[0m"), + bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"), + dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"), + italic: f("\x1b[3m", "\x1b[23m"), + underline: f("\x1b[4m", "\x1b[24m"), + inverse: f("\x1b[7m", "\x1b[27m"), + hidden: f("\x1b[8m", "\x1b[28m"), + strikethrough: f("\x1b[9m", "\x1b[29m"), + + black: f("\x1b[30m", "\x1b[39m"), + red: f("\x1b[31m", "\x1b[39m"), + green: f("\x1b[32m", "\x1b[39m"), + yellow: f("\x1b[33m", "\x1b[39m"), + blue: f("\x1b[34m", "\x1b[39m"), + magenta: f("\x1b[35m", "\x1b[39m"), + cyan: f("\x1b[36m", "\x1b[39m"), + white: f("\x1b[37m", "\x1b[39m"), + gray: f("\x1b[90m", "\x1b[39m"), + + bgBlack: f("\x1b[40m", "\x1b[49m"), + bgRed: f("\x1b[41m", "\x1b[49m"), + bgGreen: f("\x1b[42m", "\x1b[49m"), + bgYellow: f("\x1b[43m", "\x1b[49m"), + bgBlue: f("\x1b[44m", "\x1b[49m"), + bgMagenta: f("\x1b[45m", "\x1b[49m"), + bgCyan: f("\x1b[46m", "\x1b[49m"), + bgWhite: f("\x1b[47m", "\x1b[49m"), + + blackBright: f("\x1b[90m", "\x1b[39m"), + redBright: f("\x1b[91m", "\x1b[39m"), + greenBright: f("\x1b[92m", "\x1b[39m"), + yellowBright: f("\x1b[93m", "\x1b[39m"), + blueBright: f("\x1b[94m", "\x1b[39m"), + magentaBright: f("\x1b[95m", "\x1b[39m"), + cyanBright: f("\x1b[96m", "\x1b[39m"), + whiteBright: f("\x1b[97m", "\x1b[39m"), + + bgBlackBright: f("\x1b[100m", "\x1b[49m"), + bgRedBright: f("\x1b[101m", "\x1b[49m"), + bgGreenBright: f("\x1b[102m", "\x1b[49m"), + bgYellowBright: f("\x1b[103m", "\x1b[49m"), + bgBlueBright: f("\x1b[104m", "\x1b[49m"), + bgMagentaBright: f("\x1b[105m", "\x1b[49m"), + bgCyanBright: f("\x1b[106m", "\x1b[49m"), + bgWhiteBright: f("\x1b[107m", "\x1b[49m"), + } +} + +module.exports = createColors() +module.exports.createColors = createColors diff --git a/node_modules/picocolors/types.d.ts b/node_modules/picocolors/types.d.ts new file mode 100644 index 0000000000..cd1aec4679 --- /dev/null +++ b/node_modules/picocolors/types.d.ts @@ -0,0 +1,51 @@ +export type Formatter = (input: string | number | null | undefined) => string + +export interface Colors { + isColorSupported: boolean + + reset: Formatter + bold: Formatter + dim: Formatter + italic: Formatter + underline: Formatter + inverse: Formatter + hidden: Formatter + strikethrough: Formatter + + black: Formatter + red: Formatter + green: Formatter + yellow: Formatter + blue: Formatter + magenta: Formatter + cyan: Formatter + white: Formatter + gray: Formatter + + bgBlack: Formatter + bgRed: Formatter + bgGreen: Formatter + bgYellow: Formatter + bgBlue: Formatter + bgMagenta: Formatter + bgCyan: Formatter + bgWhite: Formatter + + blackBright: Formatter + redBright: Formatter + greenBright: Formatter + yellowBright: Formatter + blueBright: Formatter + magentaBright: Formatter + cyanBright: Formatter + whiteBright: Formatter + + bgBlackBright: Formatter + bgRedBright: Formatter + bgGreenBright: Formatter + bgYellowBright: Formatter + bgBlueBright: Formatter + bgMagentaBright: Formatter + bgCyanBright: Formatter + bgWhiteBright: Formatter +} diff --git a/node_modules/picomatch/LICENSE b/node_modules/picomatch/LICENSE new file mode 100644 index 0000000000..3608dca25e --- /dev/null +++ b/node_modules/picomatch/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/picomatch/README.md b/node_modules/picomatch/README.md new file mode 100644 index 0000000000..07644967ac --- /dev/null +++ b/node_modules/picomatch/README.md @@ -0,0 +1,738 @@ +

Picomatch

+ +

+ +version + + +test status + + +coverage status + + +downloads + +

+ +
+
+ +

+Blazing fast and accurate glob matcher written in JavaScript.
+No dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions. +

+ +
+
+ +## Why picomatch? + +* **Lightweight** - No dependencies +* **Minimal** - Tiny API surface. Main export is a function that takes a glob pattern and returns a matcher function. +* **Fast** - Loads in about 2ms (that's several times faster than a [single frame of a HD movie](http://www.endmemo.com/sconvert/framespersecondframespermillisecond.php) at 60fps) +* **Performant** - Use the returned matcher function to speed up repeat matching (like when watching files) +* **Accurate matching** - Using wildcards (`*` and `?`), globstars (`**`) for nested directories, [advanced globbing](#advanced-globbing) with extglobs, braces, and POSIX brackets, and support for escaping special characters with `\` or quotes. +* **Well tested** - Thousands of unit tests + +See the [library comparison](#library-comparisons) to other libraries. + +
+
+ +## Table of Contents + +
Click to expand + +- [Install](#install) +- [Usage](#usage) +- [API](#api) + * [picomatch](#picomatch) + * [.test](#test) + * [.matchBase](#matchbase) + * [.isMatch](#ismatch) + * [.parse](#parse) + * [.scan](#scan) + * [.compileRe](#compilere) + * [.makeRe](#makere) + * [.toRegex](#toregex) +- [Options](#options) + * [Picomatch options](#picomatch-options) + * [Scan Options](#scan-options) + * [Options Examples](#options-examples) +- [Globbing features](#globbing-features) + * [Basic globbing](#basic-globbing) + * [Advanced globbing](#advanced-globbing) + * [Braces](#braces) + * [Matching special characters as literals](#matching-special-characters-as-literals) +- [Library Comparisons](#library-comparisons) +- [Benchmarks](#benchmarks) +- [Philosophies](#philosophies) +- [About](#about) + * [Author](#author) + * [License](#license) + +_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_ + +
+ +
+
+ +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +npm install --save picomatch +``` + +
+ +## Usage + +The main export is a function that takes a glob pattern and an options object and returns a function for matching strings. + +```js +const pm = require('picomatch'); +const isMatch = pm('*.js'); + +console.log(isMatch('abcd')); //=> false +console.log(isMatch('a.js')); //=> true +console.log(isMatch('a.md')); //=> false +console.log(isMatch('a/b.js')); //=> false +``` + +
+ +## API + +### [picomatch](lib/picomatch.js#L31) + +Creates a matcher function from one or more glob patterns. The returned function takes a string to match as its first argument, and returns true if the string is a match. The returned matcher function also takes a boolean as the second argument that, when true, returns an object with additional information. + +**Params** + +* `globs` **{String|Array}**: One or more glob patterns. +* `options` **{Object=}** +* `returns` **{Function=}**: Returns a matcher function. + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch(glob[, options]); + +const isMatch = picomatch('*.!(*a)'); +console.log(isMatch('a.a')); //=> false +console.log(isMatch('a.b')); //=> true +``` + +**Example without node.js** + +For environments without `node.js`, `picomatch/posix` provides you a dependency-free matcher, without automatic OS detection. + +```js +const picomatch = require('picomatch/posix'); +// the same API, defaulting to posix paths +const isMatch = picomatch('a/*'); +console.log(isMatch('a\\b')); //=> false +console.log(isMatch('a/b')); //=> true + +// you can still configure the matcher function to accept windows paths +const isMatch = picomatch('a/*', { options: windows }); +console.log(isMatch('a\\b')); //=> true +console.log(isMatch('a/b')); //=> true +``` + +### [.test](lib/picomatch.js#L116) + +Test `input` with the given `regex`. This is used by the main `picomatch()` function to test the input string. + +**Params** + +* `input` **{String}**: String to test. +* `regex` **{RegExp}** +* `returns` **{Object}**: Returns an object with matching info. + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.test(input, regex[, options]); + +console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); +// { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } +``` + +### [.matchBase](lib/picomatch.js#L160) + +Match the basename of a filepath. + +**Params** + +* `input` **{String}**: String to test. +* `glob` **{RegExp|String}**: Glob pattern or regex created by [.makeRe](#makeRe). +* `returns` **{Boolean}** + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.matchBase(input, glob[, options]); +console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true +``` + +### [.isMatch](lib/picomatch.js#L182) + +Returns true if **any** of the given glob `patterns` match the specified `string`. + +**Params** + +* **{String|Array}**: str The string to test. +* **{String|Array}**: patterns One or more glob patterns to use for matching. +* **{Object}**: See available [options](#options). +* `returns` **{Boolean}**: Returns true if any patterns match `str` + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.isMatch(string, patterns[, options]); + +console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true +console.log(picomatch.isMatch('a.a', 'b.*')); //=> false +``` + +### [.parse](lib/picomatch.js#L198) + +Parse a glob pattern to create the source string for a regular expression. + +**Params** + +* `pattern` **{String}** +* `options` **{Object}** +* `returns` **{Object}**: Returns an object with useful properties and output to be used as a regex source string. + +**Example** + +```js +const picomatch = require('picomatch'); +const result = picomatch.parse(pattern[, options]); +``` + +### [.scan](lib/picomatch.js#L230) + +Scan a glob pattern to separate the pattern into segments. + +**Params** + +* `input` **{String}**: Glob pattern to scan. +* `options` **{Object}** +* `returns` **{Object}**: Returns an object with + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.scan(input[, options]); + +const result = picomatch.scan('!./foo/*.js'); +console.log(result); +{ prefix: '!./', + input: '!./foo/*.js', + start: 3, + base: 'foo', + glob: '*.js', + isBrace: false, + isBracket: false, + isGlob: true, + isExtglob: false, + isGlobstar: false, + negated: true } +``` + +### [.compileRe](lib/picomatch.js#L244) + +Compile a regular expression from the `state` object returned by the +[parse()](#parse) method. + +**Params** + +* `state` **{Object}** +* `options` **{Object}** +* `returnOutput` **{Boolean}**: Intended for implementors, this argument allows you to return the raw output from the parser. +* `returnState` **{Boolean}**: Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. +* `returns` **{RegExp}** + +### [.makeRe](lib/picomatch.js#L285) + +Create a regular expression from a parsed glob pattern. + +**Params** + +* `state` **{String}**: The object returned from the `.parse` method. +* `options` **{Object}** +* `returnOutput` **{Boolean}**: Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. +* `returnState` **{Boolean}**: Implementors may use this argument to return the state from the parsed glob with the returned regular expression. +* `returns` **{RegExp}**: Returns a regex created from the given pattern. + +**Example** + +```js +const picomatch = require('picomatch'); +const state = picomatch.parse('*.js'); +// picomatch.compileRe(state[, options]); + +console.log(picomatch.compileRe(state)); +//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ +``` + +### [.toRegex](lib/picomatch.js#L320) + +Create a regular expression from the given regex source string. + +**Params** + +* `source` **{String}**: Regular expression source string. +* `options` **{Object}** +* `returns` **{RegExp}** + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.toRegex(source[, options]); + +const { output } = picomatch.parse('*.js'); +console.log(picomatch.toRegex(output)); +//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ +``` + +
+ +## Options + +### Picomatch options + +The following options may be used with the main `picomatch()` function or any of the methods on the picomatch API. + +| **Option** | **Type** | **Default value** | **Description** | +| --- | --- | --- | --- | +| `basename` | `boolean` | `false` | If set, then patterns without slashes will be matched against the basename of the path if it contains slashes. For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. | +| `bash` | `boolean` | `false` | Follow bash matching rules more strictly - disallows backslashes as escape characters, and treats single stars as globstars (`**`). | +| `capture` | `boolean` | `undefined` | Return regex matches in supporting methods. | +| `contains` | `boolean` | `undefined` | Allows glob to match any part of the given string(s). | +| `cwd` | `string` | `process.cwd()` | Current working directory. Used by `picomatch.split()` | +| `debug` | `boolean` | `undefined` | Debug regular expressions when an error is thrown. | +| `dot` | `boolean` | `false` | Enable dotfile matching. By default, dotfiles are ignored unless a `.` is explicitly defined in the pattern, or `options.dot` is true | +| `expandRange` | `function` | `undefined` | Custom function for expanding ranges in brace patterns, such as `{a..z}`. The function receives the range values as two arguments, and it must return a string to be used in the generated regex. It's recommended that returned strings be wrapped in parentheses. | +| `failglob` | `boolean` | `false` | Throws an error if no matches are found. Based on the bash option of the same name. | +| `fastpaths` | `boolean` | `true` | To speed up processing, full parsing is skipped for a handful common glob patterns. Disable this behavior by setting this option to `false`. | +| `flags` | `string` | `undefined` | Regex flags to use in the generated regex. If defined, the `nocase` option will be overridden. | +| [format](#optionsformat) | `function` | `undefined` | Custom function for formatting the returned string. This is useful for removing leading slashes, converting Windows paths to Posix paths, etc. | +| `ignore` | `array\|string` | `undefined` | One or more glob patterns for excluding strings that should not be matched from the result. | +| `keepQuotes` | `boolean` | `false` | Retain quotes in the generated regex, since quotes may also be used as an alternative to backslashes. | +| `literalBrackets` | `boolean` | `undefined` | When `true`, brackets in the glob pattern will be escaped so that only literal brackets will be matched. | +| `matchBase` | `boolean` | `false` | Alias for `basename` | +| `maxLength` | `number` | `65536` | Limit the max length of the input string. An error is thrown if the input string is longer than this value. | +| `nobrace` | `boolean` | `false` | Disable brace matching, so that `{a,b}` and `{1..3}` would be treated as literal characters. | +| `nobracket` | `boolean` | `undefined` | Disable matching with regex brackets. | +| `nocase` | `boolean` | `false` | Make matching case-insensitive. Equivalent to the regex `i` flag. Note that this option is overridden by the `flags` option. | +| `nodupes` | `boolean` | `true` | Deprecated, use `nounique` instead. This option will be removed in a future major release. By default duplicates are removed. Disable uniquification by setting this option to false. | +| `noext` | `boolean` | `false` | Alias for `noextglob` | +| `noextglob` | `boolean` | `false` | Disable support for matching with extglobs (like `+(a\|b)`) | +| `noglobstar` | `boolean` | `false` | Disable support for matching nested directories with globstars (`**`) | +| `nonegate` | `boolean` | `false` | Disable support for negating with leading `!` | +| `noquantifiers` | `boolean` | `false` | Disable support for regex quantifiers (like `a{1,2}`) and treat them as brace patterns to be expanded. | +| [onIgnore](#optionsonIgnore) | `function` | `undefined` | Function to be called on ignored items. | +| [onMatch](#optionsonMatch) | `function` | `undefined` | Function to be called on matched items. | +| [onResult](#optionsonResult) | `function` | `undefined` | Function to be called on all items, regardless of whether or not they are matched or ignored. | +| `posix` | `boolean` | `false` | Support POSIX character classes ("posix brackets"). | +| `posixSlashes` | `boolean` | `undefined` | Convert all slashes in file paths to forward slashes. This does not convert slashes in the glob pattern itself | +| `prepend` | `boolean` | `undefined` | String to prepend to the generated regex used for matching. | +| `regex` | `boolean` | `false` | Use regular expression rules for `+` (instead of matching literal `+`), and for stars that follow closing parentheses or brackets (as in `)*` and `]*`). | +| `strictBrackets` | `boolean` | `undefined` | Throw an error if brackets, braces, or parens are imbalanced. | +| `strictSlashes` | `boolean` | `undefined` | When true, picomatch won't match trailing slashes with single stars. | +| `unescape` | `boolean` | `undefined` | Remove backslashes preceding escaped characters in the glob pattern. By default, backslashes are retained. | +| `unixify` | `boolean` | `undefined` | Alias for `posixSlashes`, for backwards compatibility. | +| `windows` | `boolean` | `false` | Also accept backslashes as the path separator. | + +### Scan Options + +In addition to the main [picomatch options](#picomatch-options), the following options may also be used with the [.scan](#scan) method. + +| **Option** | **Type** | **Default value** | **Description** | +| --- | --- | --- | --- | +| `tokens` | `boolean` | `false` | When `true`, the returned object will include an array of tokens (objects), representing each path "segment" in the scanned glob pattern | +| `parts` | `boolean` | `false` | When `true`, the returned object will include an array of strings representing each path "segment" in the scanned glob pattern. This is automatically enabled when `options.tokens` is true | + +**Example** + +```js +const picomatch = require('picomatch'); +const result = picomatch.scan('!./foo/*.js', { tokens: true }); +console.log(result); +// { +// prefix: '!./', +// input: '!./foo/*.js', +// start: 3, +// base: 'foo', +// glob: '*.js', +// isBrace: false, +// isBracket: false, +// isGlob: true, +// isExtglob: false, +// isGlobstar: false, +// negated: true, +// maxDepth: 2, +// tokens: [ +// { value: '!./', depth: 0, isGlob: false, negated: true, isPrefix: true }, +// { value: 'foo', depth: 1, isGlob: false }, +// { value: '*.js', depth: 1, isGlob: true } +// ], +// slashes: [ 2, 6 ], +// parts: [ 'foo', '*.js' ] +// } +``` + +
+ +### Options Examples + +#### options.expandRange + +**Type**: `function` + +**Default**: `undefined` + +Custom function for expanding ranges in brace patterns. The [fill-range](https://github.com/jonschlinkert/fill-range) library is ideal for this purpose, or you can use custom code to do whatever you need. + +**Example** + +The following example shows how to create a glob that matches a folder + +```js +const fill = require('fill-range'); +const regex = pm.makeRe('foo/{01..25}/bar', { + expandRange(a, b) { + return `(${fill(a, b, { toRegex: true })})`; + } +}); + +console.log(regex); +//=> /^(?:foo\/((?:0[1-9]|1[0-9]|2[0-5]))\/bar)$/ + +console.log(regex.test('foo/00/bar')) // false +console.log(regex.test('foo/01/bar')) // true +console.log(regex.test('foo/10/bar')) // true +console.log(regex.test('foo/22/bar')) // true +console.log(regex.test('foo/25/bar')) // true +console.log(regex.test('foo/26/bar')) // false +``` + +#### options.format + +**Type**: `function` + +**Default**: `undefined` + +Custom function for formatting strings before they're matched. + +**Example** + +```js +// strip leading './' from strings +const format = str => str.replace(/^\.\//, ''); +const isMatch = picomatch('foo/*.js', { format }); +console.log(isMatch('./foo/bar.js')); //=> true +``` + +#### options.onMatch + +```js +const onMatch = ({ glob, regex, input, output }) => { + console.log({ glob, regex, input, output }); +}; + +const isMatch = picomatch('*', { onMatch }); +isMatch('foo'); +isMatch('bar'); +isMatch('baz'); +``` + +#### options.onIgnore + +```js +const onIgnore = ({ glob, regex, input, output }) => { + console.log({ glob, regex, input, output }); +}; + +const isMatch = picomatch('*', { onIgnore, ignore: 'f*' }); +isMatch('foo'); +isMatch('bar'); +isMatch('baz'); +``` + +#### options.onResult + +```js +const onResult = ({ glob, regex, input, output }) => { + console.log({ glob, regex, input, output }); +}; + +const isMatch = picomatch('*', { onResult, ignore: 'f*' }); +isMatch('foo'); +isMatch('bar'); +isMatch('baz'); +``` + +
+
+ +## Globbing features + +* [Basic globbing](#basic-globbing) (Wildcard matching) +* [Advanced globbing](#advanced-globbing) (extglobs, posix brackets, brace matching) + +### Basic globbing + +| **Character** | **Description** | +| --- | --- | +| `*` | Matches any character zero or more times, excluding path separators. Does _not match_ path separators or hidden files or directories ("dotfiles"), unless explicitly enabled by setting the `dot` option to `true`. | +| `**` | Matches any character zero or more times, including path separators. Note that `**` will only match path separators (`/`, and `\\` with the `windows` option) when they are the only characters in a path segment. Thus, `foo**/bar` is equivalent to `foo*/bar`, and `foo/a**b/bar` is equivalent to `foo/a*b/bar`, and _more than two_ consecutive stars in a glob path segment are regarded as _a single star_. Thus, `foo/***/bar` is equivalent to `foo/*/bar`. | +| `?` | Matches any character excluding path separators one time. Does _not match_ path separators or leading dots. | +| `[abc]` | Matches any characters inside the brackets. For example, `[abc]` would match the characters `a`, `b` or `c`, and nothing else. | + +#### Matching behavior vs. Bash + +Picomatch's matching features and expected results in unit tests are based on Bash's unit tests and the Bash 4.3 specification, with the following exceptions: + +* Bash will match `foo/bar/baz` with `*`. Picomatch only matches nested directories with `**`. +* Bash greedily matches with negated extglobs. For example, Bash 4.3 says that `!(foo)*` should match `foo` and `foobar`, since the trailing `*` bracktracks to match the preceding pattern. This is very memory-inefficient, and IMHO, also incorrect. Picomatch would return `false` for both `foo` and `foobar`. + +
+ +### Advanced globbing + +* [extglobs](#extglobs) +* [POSIX brackets](#posix-brackets) +* [Braces](#brace-expansion) + +#### Extglobs + +| **Pattern** | **Description** | +| --- | --- | +| `@(pattern)` | Match _only one_ consecutive occurrence of `pattern` | +| `*(pattern)` | Match _zero or more_ consecutive occurrences of `pattern` | +| `+(pattern)` | Match _one or more_ consecutive occurrences of `pattern` | +| `?(pattern)` | Match _zero or **one**_ consecutive occurrences of `pattern` | +| `!(pattern)` | Match _anything but_ `pattern` | + +**Examples** + +```js +const pm = require('picomatch'); + +// *(pattern) matches ZERO or more of "pattern" +console.log(pm.isMatch('a', 'a*(z)')); // true +console.log(pm.isMatch('az', 'a*(z)')); // true +console.log(pm.isMatch('azzz', 'a*(z)')); // true + +// +(pattern) matches ONE or more of "pattern" +console.log(pm.isMatch('a', 'a+(z)')); // false +console.log(pm.isMatch('az', 'a+(z)')); // true +console.log(pm.isMatch('azzz', 'a+(z)')); // true + +// supports multiple extglobs +console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false + +// supports nested extglobs +console.log(pm.isMatch('foo.bar', '!(!(foo)).!(!(bar))')); // true +``` + +#### POSIX brackets + +POSIX classes are disabled by default. Enable this feature by setting the `posix` option to true. + +**Enable POSIX bracket support** + +```js +console.log(pm.makeRe('[[:word:]]+', { posix: true })); +//=> /^(?:(?=.)[A-Za-z0-9_]+\/?)$/ +``` + +**Supported POSIX classes** + +The following named POSIX bracket expressions are supported: + +* `[:alnum:]` - Alphanumeric characters, equ `[a-zA-Z0-9]` +* `[:alpha:]` - Alphabetical characters, equivalent to `[a-zA-Z]`. +* `[:ascii:]` - ASCII characters, equivalent to `[\\x00-\\x7F]`. +* `[:blank:]` - Space and tab characters, equivalent to `[ \\t]`. +* `[:cntrl:]` - Control characters, equivalent to `[\\x00-\\x1F\\x7F]`. +* `[:digit:]` - Numerical digits, equivalent to `[0-9]`. +* `[:graph:]` - Graph characters, equivalent to `[\\x21-\\x7E]`. +* `[:lower:]` - Lowercase letters, equivalent to `[a-z]`. +* `[:print:]` - Print characters, equivalent to `[\\x20-\\x7E ]`. +* `[:punct:]` - Punctuation and symbols, equivalent to `[\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~]`. +* `[:space:]` - Extended space characters, equivalent to `[ \\t\\r\\n\\v\\f]`. +* `[:upper:]` - Uppercase letters, equivalent to `[A-Z]`. +* `[:word:]` - Word characters (letters, numbers and underscores), equivalent to `[A-Za-z0-9_]`. +* `[:xdigit:]` - Hexadecimal digits, equivalent to `[A-Fa-f0-9]`. + +See the [Bash Reference Manual](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) for more information. + +### Braces + +Picomatch does not do brace expansion. For [brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html) and advanced matching with braces, use [micromatch](https://github.com/micromatch/micromatch) instead. Picomatch has very basic support for braces. + +### Matching special characters as literals + +If you wish to match the following special characters in a filepath, and you want to use these characters in your glob pattern, they must be escaped with backslashes or quotes: + +**Special Characters** + +Some characters that are used for matching in regular expressions are also regarded as valid file path characters on some platforms. + +To match any of the following characters as literals: `$^*+?()[] + +Examples: + +```js +console.log(pm.makeRe('foo/bar \\(1\\)')); +console.log(pm.makeRe('foo/bar \\(1\\)')); +``` + +
+
+ +## Library Comparisons + +The following table shows which features are supported by [minimatch](https://github.com/isaacs/minimatch), [micromatch](https://github.com/micromatch/micromatch), [picomatch](https://github.com/micromatch/picomatch), [nanomatch](https://github.com/micromatch/nanomatch), [extglob](https://github.com/micromatch/extglob), [braces](https://github.com/micromatch/braces), and [expand-brackets](https://github.com/micromatch/expand-brackets). + +| **Feature** | `minimatch` | `micromatch` | `picomatch` | `nanomatch` | `extglob` | `braces` | `expand-brackets` | +| --- | --- | --- | --- | --- | --- | --- | --- | +| Wildcard matching (`*?+`) | ✔ | ✔ | ✔ | ✔ | - | - | - | +| Advancing globbing | ✔ | ✔ | ✔ | - | - | - | - | +| Brace _matching_ | ✔ | ✔ | ✔ | - | - | ✔ | - | +| Brace _expansion_ | ✔ | ✔ | - | - | - | ✔ | - | +| Extglobs | partial | ✔ | ✔ | - | ✔ | - | - | +| Posix brackets | - | ✔ | ✔ | - | - | - | ✔ | +| Regular expression syntax | - | ✔ | ✔ | ✔ | ✔ | - | ✔ | +| File system operations | - | - | - | - | - | - | - | + +
+
+ +## Benchmarks + +Performance comparison of picomatch and minimatch. + +_(Pay special attention to the last three benchmarks. Minimatch freezes on long ranges.)_ + +``` +# .makeRe star (*) + picomatch x 4,449,159 ops/sec ±0.24% (97 runs sampled) + minimatch x 632,772 ops/sec ±0.14% (98 runs sampled) + +# .makeRe star; dot=true (*) + picomatch x 3,500,079 ops/sec ±0.26% (99 runs sampled) + minimatch x 564,916 ops/sec ±0.23% (96 runs sampled) + +# .makeRe globstar (**) + picomatch x 3,261,000 ops/sec ±0.27% (98 runs sampled) + minimatch x 1,664,766 ops/sec ±0.20% (100 runs sampled) + +# .makeRe globstars (**/**/**) + picomatch x 3,284,469 ops/sec ±0.18% (97 runs sampled) + minimatch x 1,435,880 ops/sec ±0.34% (95 runs sampled) + +# .makeRe with leading star (*.txt) + picomatch x 3,100,197 ops/sec ±0.35% (99 runs sampled) + minimatch x 428,347 ops/sec ±0.42% (94 runs sampled) + +# .makeRe - basic braces ({a,b,c}*.txt) + picomatch x 443,578 ops/sec ±1.33% (89 runs sampled) + minimatch x 107,143 ops/sec ±0.35% (94 runs sampled) + +# .makeRe - short ranges ({a..z}*.txt) + picomatch x 415,484 ops/sec ±0.76% (96 runs sampled) + minimatch x 14,299 ops/sec ±0.26% (96 runs sampled) + +# .makeRe - medium ranges ({1..100000}*.txt) + picomatch x 395,020 ops/sec ±0.87% (89 runs sampled) + minimatch x 2 ops/sec ±4.59% (10 runs sampled) + +# .makeRe - long ranges ({1..10000000}*.txt) + picomatch x 400,036 ops/sec ±0.83% (90 runs sampled) + minimatch (FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory) +``` + +
+
+ +## Philosophies + +The goal of this library is to be blazing fast, without compromising on accuracy. + +**Accuracy** + +The number one of goal of this library is accuracy. However, it's not unusual for different glob implementations to have different rules for matching behavior, even with simple wildcard matching. It gets increasingly more complicated when combinations of different features are combined, like when extglobs are combined with globstars, braces, slashes, and so on: `!(**/{a,b,*/c})`. + +Thus, given that there is no canonical glob specification to use as a single source of truth when differences of opinion arise regarding behavior, sometimes we have to implement our best judgement and rely on feedback from users to make improvements. + +**Performance** + +Although this library performs well in benchmarks, and in most cases it's faster than other popular libraries we benchmarked against, we will always choose accuracy over performance. It's not helpful to anyone if our library is faster at returning the wrong answer. + +
+
+ +## About + +
+Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +Please read the [contributing guide](.github/contributing.md) for advice on opening issues, pull requests, and coding standards. + +
+ +
+Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +npm install && npm test +``` + +
+ +
+Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
+ +### Author + +**Jon Schlinkert** + +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +### License + +Copyright © 2017-present, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). diff --git a/node_modules/picomatch/index.js b/node_modules/picomatch/index.js new file mode 100644 index 0000000000..a753b1d9e8 --- /dev/null +++ b/node_modules/picomatch/index.js @@ -0,0 +1,17 @@ +'use strict'; + +const pico = require('./lib/picomatch'); +const utils = require('./lib/utils'); + +function picomatch(glob, options, returnState = false) { + // default to os.platform() + if (options && (options.windows === null || options.windows === undefined)) { + // don't mutate the original options object + options = { ...options, windows: utils.isWindows() }; + } + + return pico(glob, options, returnState); +} + +Object.assign(picomatch, pico); +module.exports = picomatch; diff --git a/node_modules/picomatch/lib/constants.js b/node_modules/picomatch/lib/constants.js new file mode 100644 index 0000000000..3f7ef7e53a --- /dev/null +++ b/node_modules/picomatch/lib/constants.js @@ -0,0 +1,180 @@ +'use strict'; + +const WIN_SLASH = '\\\\/'; +const WIN_NO_SLASH = `[^${WIN_SLASH}]`; + +/** + * Posix glob regex + */ + +const DOT_LITERAL = '\\.'; +const PLUS_LITERAL = '\\+'; +const QMARK_LITERAL = '\\?'; +const SLASH_LITERAL = '\\/'; +const ONE_CHAR = '(?=.)'; +const QMARK = '[^/]'; +const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; +const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; +const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; +const NO_DOT = `(?!${DOT_LITERAL})`; +const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; +const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; +const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; +const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; +const STAR = `${QMARK}*?`; +const SEP = '/'; + +const POSIX_CHARS = { + DOT_LITERAL, + PLUS_LITERAL, + QMARK_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + QMARK, + END_ANCHOR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK_NO_DOT, + STAR, + START_ANCHOR, + SEP +}; + +/** + * Windows glob regex + */ + +const WINDOWS_CHARS = { + ...POSIX_CHARS, + + SLASH_LITERAL: `[${WIN_SLASH}]`, + QMARK: WIN_NO_SLASH, + STAR: `${WIN_NO_SLASH}*?`, + DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, + NO_DOT: `(?!${DOT_LITERAL})`, + NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, + NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + QMARK_NO_DOT: `[^.${WIN_SLASH}]`, + START_ANCHOR: `(?:^|[${WIN_SLASH}])`, + END_ANCHOR: `(?:[${WIN_SLASH}]|$)`, + SEP: '\\' +}; + +/** + * POSIX Bracket Regex + */ + +const POSIX_REGEX_SOURCE = { + alnum: 'a-zA-Z0-9', + alpha: 'a-zA-Z', + ascii: '\\x00-\\x7F', + blank: ' \\t', + cntrl: '\\x00-\\x1F\\x7F', + digit: '0-9', + graph: '\\x21-\\x7E', + lower: 'a-z', + print: '\\x20-\\x7E ', + punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', + space: ' \\t\\r\\n\\v\\f', + upper: 'A-Z', + word: 'A-Za-z0-9_', + xdigit: 'A-Fa-f0-9' +}; + +module.exports = { + MAX_LENGTH: 1024 * 64, + POSIX_REGEX_SOURCE, + + // regular expressions + REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, + REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, + REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, + REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, + REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, + REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, + + // Replace globs with equivalent patterns to reduce parsing time. + REPLACEMENTS: { + __proto__: null, + '***': '*', + '**/**': '**', + '**/**/**': '**' + }, + + // Digits + CHAR_0: 48, /* 0 */ + CHAR_9: 57, /* 9 */ + + // Alphabet chars. + CHAR_UPPERCASE_A: 65, /* A */ + CHAR_LOWERCASE_A: 97, /* a */ + CHAR_UPPERCASE_Z: 90, /* Z */ + CHAR_LOWERCASE_Z: 122, /* z */ + + CHAR_LEFT_PARENTHESES: 40, /* ( */ + CHAR_RIGHT_PARENTHESES: 41, /* ) */ + + CHAR_ASTERISK: 42, /* * */ + + // Non-alphabetic chars. + CHAR_AMPERSAND: 38, /* & */ + CHAR_AT: 64, /* @ */ + CHAR_BACKWARD_SLASH: 92, /* \ */ + CHAR_CARRIAGE_RETURN: 13, /* \r */ + CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ + CHAR_COLON: 58, /* : */ + CHAR_COMMA: 44, /* , */ + CHAR_DOT: 46, /* . */ + CHAR_DOUBLE_QUOTE: 34, /* " */ + CHAR_EQUAL: 61, /* = */ + CHAR_EXCLAMATION_MARK: 33, /* ! */ + CHAR_FORM_FEED: 12, /* \f */ + CHAR_FORWARD_SLASH: 47, /* / */ + CHAR_GRAVE_ACCENT: 96, /* ` */ + CHAR_HASH: 35, /* # */ + CHAR_HYPHEN_MINUS: 45, /* - */ + CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ + CHAR_LEFT_CURLY_BRACE: 123, /* { */ + CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ + CHAR_LINE_FEED: 10, /* \n */ + CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ + CHAR_PERCENT: 37, /* % */ + CHAR_PLUS: 43, /* + */ + CHAR_QUESTION_MARK: 63, /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ + CHAR_RIGHT_CURLY_BRACE: 125, /* } */ + CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ + CHAR_SEMICOLON: 59, /* ; */ + CHAR_SINGLE_QUOTE: 39, /* ' */ + CHAR_SPACE: 32, /* */ + CHAR_TAB: 9, /* \t */ + CHAR_UNDERSCORE: 95, /* _ */ + CHAR_VERTICAL_LINE: 124, /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ + + /** + * Create EXTGLOB_CHARS + */ + + extglobChars(chars) { + return { + '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, + '?': { type: 'qmark', open: '(?:', close: ')?' }, + '+': { type: 'plus', open: '(?:', close: ')+' }, + '*': { type: 'star', open: '(?:', close: ')*' }, + '@': { type: 'at', open: '(?:', close: ')' } + }; + }, + + /** + * Create GLOB_CHARS + */ + + globChars(win32) { + return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; + } +}; diff --git a/node_modules/picomatch/lib/parse.js b/node_modules/picomatch/lib/parse.js new file mode 100644 index 0000000000..8fd8ff499d --- /dev/null +++ b/node_modules/picomatch/lib/parse.js @@ -0,0 +1,1085 @@ +'use strict'; + +const constants = require('./constants'); +const utils = require('./utils'); + +/** + * Constants + */ + +const { + MAX_LENGTH, + POSIX_REGEX_SOURCE, + REGEX_NON_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_BACKREF, + REPLACEMENTS +} = constants; + +/** + * Helpers + */ + +const expandRange = (args, options) => { + if (typeof options.expandRange === 'function') { + return options.expandRange(...args, options); + } + + args.sort(); + const value = `[${args.join('-')}]`; + + try { + /* eslint-disable-next-line no-new */ + new RegExp(value); + } catch (ex) { + return args.map(v => utils.escapeRegex(v)).join('..'); + } + + return value; +}; + +/** + * Create the message for a syntax error + */ + +const syntaxError = (type, char) => { + return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; +}; + +/** + * Parse the given input string. + * @param {String} input + * @param {Object} options + * @return {Object} + */ + +const parse = (input, options) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); + } + + input = REPLACEMENTS[input] || input; + + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + + let len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } + + const bos = { type: 'bos', value: '', output: opts.prepend || '' }; + const tokens = [bos]; + + const capture = opts.capture ? '' : '?:'; + + // create constants based on platform, for windows or posix + const PLATFORM_CHARS = constants.globChars(opts.windows); + const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); + + const { + DOT_LITERAL, + PLUS_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK, + QMARK_NO_DOT, + STAR, + START_ANCHOR + } = PLATFORM_CHARS; + + const globstar = opts => { + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + + const nodot = opts.dot ? '' : NO_DOT; + const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; + let star = opts.bash === true ? globstar(opts) : STAR; + + if (opts.capture) { + star = `(${star})`; + } + + // minimatch options support + if (typeof opts.noext === 'boolean') { + opts.noextglob = opts.noext; + } + + const state = { + input, + index: -1, + start: 0, + dot: opts.dot === true, + consumed: '', + output: '', + prefix: '', + backtrack: false, + negated: false, + brackets: 0, + braces: 0, + parens: 0, + quotes: 0, + globstar: false, + tokens + }; + + input = utils.removePrefix(input, state); + len = input.length; + + const extglobs = []; + const braces = []; + const stack = []; + let prev = bos; + let value; + + /** + * Tokenizing helpers + */ + + const eos = () => state.index === len - 1; + const peek = state.peek = (n = 1) => input[state.index + n]; + const advance = state.advance = () => input[++state.index] || ''; + const remaining = () => input.slice(state.index + 1); + const consume = (value = '', num = 0) => { + state.consumed += value; + state.index += num; + }; + + const append = token => { + state.output += token.output != null ? token.output : token.value; + consume(token.value); + }; + + const negate = () => { + let count = 1; + + while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { + advance(); + state.start++; + count++; + } + + if (count % 2 === 0) { + return false; + } + + state.negated = true; + state.start++; + return true; + }; + + const increment = type => { + state[type]++; + stack.push(type); + }; + + const decrement = type => { + state[type]--; + stack.pop(); + }; + + /** + * Push tokens onto the tokens array. This helper speeds up + * tokenizing by 1) helping us avoid backtracking as much as possible, + * and 2) helping us avoid creating extra tokens when consecutive + * characters are plain text. This improves performance and simplifies + * lookbehinds. + */ + + const push = tok => { + if (prev.type === 'globstar') { + const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); + const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); + + if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { + state.output = state.output.slice(0, -prev.output.length); + prev.type = 'star'; + prev.value = '*'; + prev.output = star; + state.output += prev.output; + } + } + + if (extglobs.length && tok.type !== 'paren') { + extglobs[extglobs.length - 1].inner += tok.value; + } + + if (tok.value || tok.output) append(tok); + if (prev && prev.type === 'text' && tok.type === 'text') { + prev.output = (prev.output || prev.value) + tok.value; + prev.value += tok.value; + return; + } + + tok.prev = prev; + tokens.push(tok); + prev = tok; + }; + + const extglobOpen = (type, value) => { + const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; + + token.prev = prev; + token.parens = state.parens; + token.output = state.output; + const output = (opts.capture ? '(' : '') + token.open; + + increment('parens'); + push({ type, value, output: state.output ? '' : ONE_CHAR }); + push({ type: 'paren', extglob: true, value: advance(), output }); + extglobs.push(token); + }; + + const extglobClose = token => { + let output = token.close + (opts.capture ? ')' : ''); + let rest; + + if (token.type === 'negate') { + let extglobStar = star; + + if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { + extglobStar = globstar(opts); + } + + if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { + output = token.close = `)$))${extglobStar}`; + } + + if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { + // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. + // In this case, we need to parse the string and use it in the output of the original pattern. + // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. + // + // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. + const expression = parse(rest, { ...options, fastpaths: false }).output; + + output = token.close = `)${expression})${extglobStar})`; + } + + if (token.prev.type === 'bos') { + state.negatedExtglob = true; + } + } + + push({ type: 'paren', extglob: true, value, output }); + decrement('parens'); + }; + + /** + * Fast paths + */ + + if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { + let backslashes = false; + + let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { + if (first === '\\') { + backslashes = true; + return m; + } + + if (first === '?') { + if (esc) { + return esc + first + (rest ? QMARK.repeat(rest.length) : ''); + } + if (index === 0) { + return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); + } + return QMARK.repeat(chars.length); + } + + if (first === '.') { + return DOT_LITERAL.repeat(chars.length); + } + + if (first === '*') { + if (esc) { + return esc + first + (rest ? star : ''); + } + return star; + } + return esc ? m : `\\${m}`; + }); + + if (backslashes === true) { + if (opts.unescape === true) { + output = output.replace(/\\/g, ''); + } else { + output = output.replace(/\\+/g, m => { + return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); + }); + } + } + + if (output === input && opts.contains === true) { + state.output = input; + return state; + } + + state.output = utils.wrapOutput(output, state, options); + return state; + } + + /** + * Tokenize input until we reach end-of-string + */ + + while (!eos()) { + value = advance(); + + if (value === '\u0000') { + continue; + } + + /** + * Escaped characters + */ + + if (value === '\\') { + const next = peek(); + + if (next === '/' && opts.bash !== true) { + continue; + } + + if (next === '.' || next === ';') { + continue; + } + + if (!next) { + value += '\\'; + push({ type: 'text', value }); + continue; + } + + // collapse slashes to reduce potential for exploits + const match = /^\\+/.exec(remaining()); + let slashes = 0; + + if (match && match[0].length > 2) { + slashes = match[0].length; + state.index += slashes; + if (slashes % 2 !== 0) { + value += '\\'; + } + } + + if (opts.unescape === true) { + value = advance(); + } else { + value += advance(); + } + + if (state.brackets === 0) { + push({ type: 'text', value }); + continue; + } + } + + /** + * If we're inside a regex character class, continue + * until we reach the closing bracket. + */ + + if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { + if (opts.posix !== false && value === ':') { + const inner = prev.value.slice(1); + if (inner.includes('[')) { + prev.posix = true; + + if (inner.includes(':')) { + const idx = prev.value.lastIndexOf('['); + const pre = prev.value.slice(0, idx); + const rest = prev.value.slice(idx + 2); + const posix = POSIX_REGEX_SOURCE[rest]; + if (posix) { + prev.value = pre + posix; + state.backtrack = true; + advance(); + + if (!bos.output && tokens.indexOf(prev) === 1) { + bos.output = ONE_CHAR; + } + continue; + } + } + } + } + + if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { + value = `\\${value}`; + } + + if (value === ']' && (prev.value === '[' || prev.value === '[^')) { + value = `\\${value}`; + } + + if (opts.posix === true && value === '!' && prev.value === '[') { + value = '^'; + } + + prev.value += value; + append({ value }); + continue; + } + + /** + * If we're inside a quoted string, continue + * until we reach the closing double quote. + */ + + if (state.quotes === 1 && value !== '"') { + value = utils.escapeRegex(value); + prev.value += value; + append({ value }); + continue; + } + + /** + * Double quotes + */ + + if (value === '"') { + state.quotes = state.quotes === 1 ? 0 : 1; + if (opts.keepQuotes === true) { + push({ type: 'text', value }); + } + continue; + } + + /** + * Parentheses + */ + + if (value === '(') { + increment('parens'); + push({ type: 'paren', value }); + continue; + } + + if (value === ')') { + if (state.parens === 0 && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '(')); + } + + const extglob = extglobs[extglobs.length - 1]; + if (extglob && state.parens === extglob.parens + 1) { + extglobClose(extglobs.pop()); + continue; + } + + push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); + decrement('parens'); + continue; + } + + /** + * Square brackets + */ + + if (value === '[') { + if (opts.nobracket === true || !remaining().includes(']')) { + if (opts.nobracket !== true && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('closing', ']')); + } + + value = `\\${value}`; + } else { + increment('brackets'); + } + + push({ type: 'bracket', value }); + continue; + } + + if (value === ']') { + if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { + push({ type: 'text', value, output: `\\${value}` }); + continue; + } + + if (state.brackets === 0) { + if (opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '[')); + } + + push({ type: 'text', value, output: `\\${value}` }); + continue; + } + + decrement('brackets'); + + const prevValue = prev.value.slice(1); + if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { + value = `/${value}`; + } + + prev.value += value; + append({ value }); + + // when literal brackets are explicitly disabled + // assume we should match with a regex character class + if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { + continue; + } + + const escaped = utils.escapeRegex(prev.value); + state.output = state.output.slice(0, -prev.value.length); + + // when literal brackets are explicitly enabled + // assume we should escape the brackets to match literal characters + if (opts.literalBrackets === true) { + state.output += escaped; + prev.value = escaped; + continue; + } + + // when the user specifies nothing, try to match both + prev.value = `(${capture}${escaped}|${prev.value})`; + state.output += prev.value; + continue; + } + + /** + * Braces + */ + + if (value === '{' && opts.nobrace !== true) { + increment('braces'); + + const open = { + type: 'brace', + value, + output: '(', + outputIndex: state.output.length, + tokensIndex: state.tokens.length + }; + + braces.push(open); + push(open); + continue; + } + + if (value === '}') { + const brace = braces[braces.length - 1]; + + if (opts.nobrace === true || !brace) { + push({ type: 'text', value, output: value }); + continue; + } + + let output = ')'; + + if (brace.dots === true) { + const arr = tokens.slice(); + const range = []; + + for (let i = arr.length - 1; i >= 0; i--) { + tokens.pop(); + if (arr[i].type === 'brace') { + break; + } + if (arr[i].type !== 'dots') { + range.unshift(arr[i].value); + } + } + + output = expandRange(range, opts); + state.backtrack = true; + } + + if (brace.comma !== true && brace.dots !== true) { + const out = state.output.slice(0, brace.outputIndex); + const toks = state.tokens.slice(brace.tokensIndex); + brace.value = brace.output = '\\{'; + value = output = '\\}'; + state.output = out; + for (const t of toks) { + state.output += (t.output || t.value); + } + } + + push({ type: 'brace', value, output }); + decrement('braces'); + braces.pop(); + continue; + } + + /** + * Pipes + */ + + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; + } + push({ type: 'text', value }); + continue; + } + + /** + * Commas + */ + + if (value === ',') { + let output = value; + + const brace = braces[braces.length - 1]; + if (brace && stack[stack.length - 1] === 'braces') { + brace.comma = true; + output = '|'; + } + + push({ type: 'comma', value, output }); + continue; + } + + /** + * Slashes + */ + + if (value === '/') { + // if the beginning of the glob is "./", advance the start + // to the current index, and don't add the "./" characters + // to the state. This greatly simplifies lookbehinds when + // checking for BOS characters like "!" and "." (not "./") + if (prev.type === 'dot' && state.index === state.start + 1) { + state.start = state.index + 1; + state.consumed = ''; + state.output = ''; + tokens.pop(); + prev = bos; // reset "prev" to the first token + continue; + } + + push({ type: 'slash', value, output: SLASH_LITERAL }); + continue; + } + + /** + * Dots + */ + + if (value === '.') { + if (state.braces > 0 && prev.type === 'dot') { + if (prev.value === '.') prev.output = DOT_LITERAL; + const brace = braces[braces.length - 1]; + prev.type = 'dots'; + prev.output += value; + prev.value += value; + brace.dots = true; + continue; + } + + if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { + push({ type: 'text', value, output: DOT_LITERAL }); + continue; + } + + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; + } + + /** + * Question marks + */ + + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } + + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; + + if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { + output = `\\${value}`; + } + + push({ type: 'text', value, output }); + continue; + } + + if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { + push({ type: 'qmark', value, output: QMARK_NO_DOT }); + continue; + } + + push({ type: 'qmark', value, output: QMARK }); + continue; + } + + /** + * Exclamation + */ + + if (value === '!') { + if (opts.noextglob !== true && peek() === '(') { + if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { + extglobOpen('negate', value); + continue; + } + } + + if (opts.nonegate !== true && state.index === 0) { + negate(); + continue; + } + } + + /** + * Plus + */ + + if (value === '+') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('plus', value); + continue; + } + + if ((prev && prev.value === '(') || opts.regex === false) { + push({ type: 'plus', value, output: PLUS_LITERAL }); + continue; + } + + if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { + push({ type: 'plus', value }); + continue; + } + + push({ type: 'plus', value: PLUS_LITERAL }); + continue; + } + + /** + * Plain text + */ + + if (value === '@') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + push({ type: 'at', extglob: true, value, output: '' }); + continue; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Plain text + */ + + if (value !== '*') { + if (value === '$' || value === '^') { + value = `\\${value}`; + } + + const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); + if (match) { + value += match[0]; + state.index += match[0].length; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Stars + */ + + if (prev && (prev.type === 'globstar' || prev.star === true)) { + prev.type = 'star'; + prev.star = true; + prev.value += value; + prev.output = star; + state.backtrack = true; + state.globstar = true; + consume(value); + continue; + } + + let rest = remaining(); + if (opts.noextglob !== true && /^\([^?]/.test(rest)) { + extglobOpen('star', value); + continue; + } + + if (prev.type === 'star') { + if (opts.noglobstar === true) { + consume(value); + continue; + } + + const prior = prev.prev; + const before = prior.prev; + const isStart = prior.type === 'slash' || prior.type === 'bos'; + const afterStar = before && (before.type === 'star' || before.type === 'globstar'); + + if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { + push({ type: 'star', value, output: '' }); + continue; + } + + const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); + const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); + if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { + push({ type: 'star', value, output: '' }); + continue; + } + + // strip consecutive `/**/` + while (rest.slice(0, 3) === '/**') { + const after = input[state.index + 4]; + if (after && after !== '/') { + break; + } + rest = rest.slice(3); + consume('/**', 3); + } + + if (prior.type === 'bos' && eos()) { + prev.type = 'globstar'; + prev.value += value; + prev.output = globstar(opts); + state.output = prev.output; + state.globstar = true; + consume(value); + continue; + } + + if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; + + prev.type = 'globstar'; + prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); + prev.value += value; + state.globstar = true; + state.output += prior.output + prev.output; + consume(value); + continue; + } + + if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { + const end = rest[1] !== void 0 ? '|$' : ''; + + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; + + prev.type = 'globstar'; + prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; + prev.value += value; + + state.output += prior.output + prev.output; + state.globstar = true; + + consume(value + advance()); + + push({ type: 'slash', value: '/', output: '' }); + continue; + } + + if (prior.type === 'bos' && rest[0] === '/') { + prev.type = 'globstar'; + prev.value += value; + prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; + state.output = prev.output; + state.globstar = true; + consume(value + advance()); + push({ type: 'slash', value: '/', output: '' }); + continue; + } + + // remove single star from output + state.output = state.output.slice(0, -prev.output.length); + + // reset previous token to globstar + prev.type = 'globstar'; + prev.output = globstar(opts); + prev.value += value; + + // reset output with globstar + state.output += prev.output; + state.globstar = true; + consume(value); + continue; + } + + const token = { type: 'star', value, output: star }; + + if (opts.bash === true) { + token.output = '.*?'; + if (prev.type === 'bos' || prev.type === 'slash') { + token.output = nodot + token.output; + } + push(token); + continue; + } + + if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { + token.output = value; + push(token); + continue; + } + + if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { + if (prev.type === 'dot') { + state.output += NO_DOT_SLASH; + prev.output += NO_DOT_SLASH; + + } else if (opts.dot === true) { + state.output += NO_DOTS_SLASH; + prev.output += NO_DOTS_SLASH; + + } else { + state.output += nodot; + prev.output += nodot; + } + + if (peek() !== '*') { + state.output += ONE_CHAR; + prev.output += ONE_CHAR; + } + } + + push(token); + } + + while (state.brackets > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); + state.output = utils.escapeLast(state.output, '['); + decrement('brackets'); + } + + while (state.parens > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); + state.output = utils.escapeLast(state.output, '('); + decrement('parens'); + } + + while (state.braces > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); + state.output = utils.escapeLast(state.output, '{'); + decrement('braces'); + } + + if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { + push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); + } + + // rebuild the output if we had to backtrack at any point + if (state.backtrack === true) { + state.output = ''; + + for (const token of state.tokens) { + state.output += token.output != null ? token.output : token.value; + + if (token.suffix) { + state.output += token.suffix; + } + } + } + + return state; +}; + +/** + * Fast paths for creating regular expressions for common glob patterns. + * This can significantly speed up processing and has very little downside + * impact when none of the fast paths match. + */ + +parse.fastpaths = (input, options) => { + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + const len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } + + input = REPLACEMENTS[input] || input; + + // create constants based on platform, for windows or posix + const { + DOT_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOTS_SLASH, + STAR, + START_ANCHOR + } = constants.globChars(opts.windows); + + const nodot = opts.dot ? NO_DOTS : NO_DOT; + const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; + const capture = opts.capture ? '' : '?:'; + const state = { negated: false, prefix: '' }; + let star = opts.bash === true ? '.*?' : STAR; + + if (opts.capture) { + star = `(${star})`; + } + + const globstar = opts => { + if (opts.noglobstar === true) return star; + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + + const create = str => { + switch (str) { + case '*': + return `${nodot}${ONE_CHAR}${star}`; + + case '.*': + return `${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*.*': + return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*/*': + return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + + case '**': + return nodot + globstar(opts); + + case '**/*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; + + case '**/*.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '**/.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; + + default: { + const match = /^(.*?)\.(\w+)$/.exec(str); + if (!match) return; + + const source = create(match[1]); + if (!source) return; + + return source + DOT_LITERAL + match[2]; + } + } + }; + + const output = utils.removePrefix(input, state); + let source = create(output); + + if (source && opts.strictSlashes !== true) { + source += `${SLASH_LITERAL}?`; + } + + return source; +}; + +module.exports = parse; diff --git a/node_modules/picomatch/lib/picomatch.js b/node_modules/picomatch/lib/picomatch.js new file mode 100644 index 0000000000..d0ebd9f163 --- /dev/null +++ b/node_modules/picomatch/lib/picomatch.js @@ -0,0 +1,341 @@ +'use strict'; + +const scan = require('./scan'); +const parse = require('./parse'); +const utils = require('./utils'); +const constants = require('./constants'); +const isObject = val => val && typeof val === 'object' && !Array.isArray(val); + +/** + * Creates a matcher function from one or more glob patterns. The + * returned function takes a string to match as its first argument, + * and returns true if the string is a match. The returned matcher + * function also takes a boolean as the second argument that, when true, + * returns an object with additional information. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch(glob[, options]); + * + * const isMatch = picomatch('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @name picomatch + * @param {String|Array} `globs` One or more glob patterns. + * @param {Object=} `options` + * @return {Function=} Returns a matcher function. + * @api public + */ + +const picomatch = (glob, options, returnState = false) => { + if (Array.isArray(glob)) { + const fns = glob.map(input => picomatch(input, options, returnState)); + const arrayMatcher = str => { + for (const isMatch of fns) { + const state = isMatch(str); + if (state) return state; + } + return false; + }; + return arrayMatcher; + } + + const isState = isObject(glob) && glob.tokens && glob.input; + + if (glob === '' || (typeof glob !== 'string' && !isState)) { + throw new TypeError('Expected pattern to be a non-empty string'); + } + + const opts = options || {}; + const posix = opts.windows; + const regex = isState + ? picomatch.compileRe(glob, options) + : picomatch.makeRe(glob, options, false, true); + + const state = regex.state; + delete regex.state; + + let isIgnored = () => false; + if (opts.ignore) { + const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; + isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); + } + + const matcher = (input, returnObject = false) => { + const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); + const result = { glob, state, regex, posix, input, output, match, isMatch }; + + if (typeof opts.onResult === 'function') { + opts.onResult(result); + } + + if (isMatch === false) { + result.isMatch = false; + return returnObject ? result : false; + } + + if (isIgnored(input)) { + if (typeof opts.onIgnore === 'function') { + opts.onIgnore(result); + } + result.isMatch = false; + return returnObject ? result : false; + } + + if (typeof opts.onMatch === 'function') { + opts.onMatch(result); + } + return returnObject ? result : true; + }; + + if (returnState) { + matcher.state = state; + } + + return matcher; +}; + +/** + * Test `input` with the given `regex`. This is used by the main + * `picomatch()` function to test the input string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.test(input, regex[, options]); + * + * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); + * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } + * ``` + * @param {String} `input` String to test. + * @param {RegExp} `regex` + * @return {Object} Returns an object with matching info. + * @api public + */ + +picomatch.test = (input, regex, options, { glob, posix } = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected input to be a string'); + } + + if (input === '') { + return { isMatch: false, output: '' }; + } + + const opts = options || {}; + const format = opts.format || (posix ? utils.toPosixSlashes : null); + let match = input === glob; + let output = (match && format) ? format(input) : input; + + if (match === false) { + output = format ? format(input) : input; + match = output === glob; + } + + if (match === false || opts.capture === true) { + if (opts.matchBase === true || opts.basename === true) { + match = picomatch.matchBase(input, regex, options, posix); + } else { + match = regex.exec(output); + } + } + + return { isMatch: Boolean(match), match, output }; +}; + +/** + * Match the basename of a filepath. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.matchBase(input, glob[, options]); + * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true + * ``` + * @param {String} `input` String to test. + * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). + * @return {Boolean} + * @api public + */ + +picomatch.matchBase = (input, glob, options) => { + const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); + return regex.test(utils.basename(input)); +}; + +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.isMatch(string, patterns[, options]); + * + * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String|Array} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ + +picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); + +/** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const picomatch = require('picomatch'); + * const result = picomatch.parse(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as a regex source string. + * @api public + */ + +picomatch.parse = (pattern, options) => { + if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); + return parse(pattern, { ...options, fastpaths: false }); +}; + +/** + * Scan a glob pattern to separate the pattern into segments. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.scan(input[, options]); + * + * const result = picomatch.scan('!./foo/*.js'); + * console.log(result); + * { prefix: '!./', + * input: '!./foo/*.js', + * start: 3, + * base: 'foo', + * glob: '*.js', + * isBrace: false, + * isBracket: false, + * isGlob: true, + * isExtglob: false, + * isGlobstar: false, + * negated: true } + * ``` + * @param {String} `input` Glob pattern to scan. + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public + */ + +picomatch.scan = (input, options) => scan(input, options); + +/** + * Compile a regular expression from the `state` object returned by the + * [parse()](#parse) method. + * + * @param {Object} `state` + * @param {Object} `options` + * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. + * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. + * @return {RegExp} + * @api public + */ + +picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { + if (returnOutput === true) { + return state.output; + } + + const opts = options || {}; + const prepend = opts.contains ? '' : '^'; + const append = opts.contains ? '' : '$'; + + let source = `${prepend}(?:${state.output})${append}`; + if (state && state.negated === true) { + source = `^(?!${source}).*$`; + } + + const regex = picomatch.toRegex(source, options); + if (returnState === true) { + regex.state = state; + } + + return regex; +}; + +/** + * Create a regular expression from a parsed glob pattern. + * + * ```js + * const picomatch = require('picomatch'); + * const state = picomatch.parse('*.js'); + * // picomatch.compileRe(state[, options]); + * + * console.log(picomatch.compileRe(state)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `state` The object returned from the `.parse` method. + * @param {Object} `options` + * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. + * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ + +picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { + if (!input || typeof input !== 'string') { + throw new TypeError('Expected a non-empty string'); + } + + let parsed = { negated: false, fastpaths: true }; + + if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { + parsed.output = parse.fastpaths(input, options); + } + + if (!parsed.output) { + parsed = parse(input, options); + } + + return picomatch.compileRe(parsed, options, returnOutput, returnState); +}; + +/** + * Create a regular expression from the given regex source string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.toRegex(source[, options]); + * + * const { output } = picomatch.parse('*.js'); + * console.log(picomatch.toRegex(output)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `source` Regular expression source string. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ + +picomatch.toRegex = (source, options) => { + try { + const opts = options || {}; + return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); + } catch (err) { + if (options && options.debug === true) throw err; + return /$^/; + } +}; + +/** + * Picomatch constants. + * @return {Object} + */ + +picomatch.constants = constants; + +/** + * Expose "picomatch" + */ + +module.exports = picomatch; diff --git a/node_modules/picomatch/lib/scan.js b/node_modules/picomatch/lib/scan.js new file mode 100644 index 0000000000..e59cd7a135 --- /dev/null +++ b/node_modules/picomatch/lib/scan.js @@ -0,0 +1,391 @@ +'use strict'; + +const utils = require('./utils'); +const { + CHAR_ASTERISK, /* * */ + CHAR_AT, /* @ */ + CHAR_BACKWARD_SLASH, /* \ */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_EXCLAMATION_MARK, /* ! */ + CHAR_FORWARD_SLASH, /* / */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_PLUS, /* + */ + CHAR_QUESTION_MARK, /* ? */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_RIGHT_SQUARE_BRACKET /* ] */ +} = require('./constants'); + +const isPathSeparator = code => { + return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; +}; + +const depth = token => { + if (token.isPrefix !== true) { + token.depth = token.isGlobstar ? Infinity : 1; + } +}; + +/** + * Quickly scans a glob pattern and returns an object with a handful of + * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), + * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not + * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). + * + * ```js + * const pm = require('picomatch'); + * console.log(pm.scan('foo/bar/*.js')); + * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {Object} Returns an object with tokens and regex source string. + * @api public + */ + +const scan = (input, options) => { + const opts = options || {}; + + const length = input.length - 1; + const scanToEnd = opts.parts === true || opts.scanToEnd === true; + const slashes = []; + const tokens = []; + const parts = []; + + let str = input; + let index = -1; + let start = 0; + let lastIndex = 0; + let isBrace = false; + let isBracket = false; + let isGlob = false; + let isExtglob = false; + let isGlobstar = false; + let braceEscaped = false; + let backslashes = false; + let negated = false; + let negatedExtglob = false; + let finished = false; + let braces = 0; + let prev; + let code; + let token = { value: '', depth: 0, isGlob: false }; + + const eos = () => index >= length; + const peek = () => str.charCodeAt(index + 1); + const advance = () => { + prev = code; + return str.charCodeAt(++index); + }; + + while (index < length) { + code = advance(); + let next; + + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + + if (code === CHAR_LEFT_CURLY_BRACE) { + braceEscaped = true; + } + continue; + } + + if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { + braces++; + + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } + + if (code === CHAR_LEFT_CURLY_BRACE) { + braces++; + continue; + } + + if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (braceEscaped !== true && code === CHAR_COMMA) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (code === CHAR_RIGHT_CURLY_BRACE) { + braces--; + + if (braces === 0) { + braceEscaped = false; + isBrace = token.isBrace = true; + finished = true; + break; + } + } + } + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (code === CHAR_FORWARD_SLASH) { + slashes.push(index); + tokens.push(token); + token = { value: '', depth: 0, isGlob: false }; + + if (finished === true) continue; + if (prev === CHAR_DOT && index === (start + 1)) { + start += 2; + continue; + } + + lastIndex = index + 1; + continue; + } + + if (opts.noext !== true) { + const isExtglobChar = code === CHAR_PLUS + || code === CHAR_AT + || code === CHAR_ASTERISK + || code === CHAR_QUESTION_MARK + || code === CHAR_EXCLAMATION_MARK; + + if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + isExtglob = token.isExtglob = true; + finished = true; + if (code === CHAR_EXCLAMATION_MARK && index === start) { + negatedExtglob = true; + } + + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } + + if (code === CHAR_RIGHT_PARENTHESES) { + isGlob = token.isGlob = true; + finished = true; + break; + } + } + continue; + } + break; + } + } + + if (code === CHAR_ASTERISK) { + if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + break; + } + + if (code === CHAR_QUESTION_MARK) { + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + break; + } + + if (code === CHAR_LEFT_SQUARE_BRACKET) { + while (eos() !== true && (next = advance())) { + if (next === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } + + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + isBracket = token.isBracket = true; + isGlob = token.isGlob = true; + finished = true; + break; + } + } + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { + negated = token.negated = true; + start++; + continue; + } + + if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_LEFT_PARENTHESES) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } + + if (code === CHAR_RIGHT_PARENTHESES) { + finished = true; + break; + } + } + continue; + } + break; + } + + if (isGlob === true) { + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + } + + if (opts.noext === true) { + isExtglob = false; + isGlob = false; + } + + let base = str; + let prefix = ''; + let glob = ''; + + if (start > 0) { + prefix = str.slice(0, start); + str = str.slice(start); + lastIndex -= start; + } + + if (base && isGlob === true && lastIndex > 0) { + base = str.slice(0, lastIndex); + glob = str.slice(lastIndex); + } else if (isGlob === true) { + base = ''; + glob = str; + } else { + base = str; + } + + if (base && base !== '' && base !== '/' && base !== str) { + if (isPathSeparator(base.charCodeAt(base.length - 1))) { + base = base.slice(0, -1); + } + } + + if (opts.unescape === true) { + if (glob) glob = utils.removeBackslashes(glob); + + if (base && backslashes === true) { + base = utils.removeBackslashes(base); + } + } + + const state = { + prefix, + input, + start, + base, + glob, + isBrace, + isBracket, + isGlob, + isExtglob, + isGlobstar, + negated, + negatedExtglob + }; + + if (opts.tokens === true) { + state.maxDepth = 0; + if (!isPathSeparator(code)) { + tokens.push(token); + } + state.tokens = tokens; + } + + if (opts.parts === true || opts.tokens === true) { + let prevIndex; + + for (let idx = 0; idx < slashes.length; idx++) { + const n = prevIndex ? prevIndex + 1 : start; + const i = slashes[idx]; + const value = input.slice(n, i); + if (opts.tokens) { + if (idx === 0 && start !== 0) { + tokens[idx].isPrefix = true; + tokens[idx].value = prefix; + } else { + tokens[idx].value = value; + } + depth(tokens[idx]); + state.maxDepth += tokens[idx].depth; + } + if (idx !== 0 || value !== '') { + parts.push(value); + } + prevIndex = i; + } + + if (prevIndex && prevIndex + 1 < input.length) { + const value = input.slice(prevIndex + 1); + parts.push(value); + + if (opts.tokens) { + tokens[tokens.length - 1].value = value; + depth(tokens[tokens.length - 1]); + state.maxDepth += tokens[tokens.length - 1].depth; + } + } + + state.slashes = slashes; + state.parts = parts; + } + + return state; +}; + +module.exports = scan; diff --git a/node_modules/picomatch/lib/utils.js b/node_modules/picomatch/lib/utils.js new file mode 100644 index 0000000000..9c97cae222 --- /dev/null +++ b/node_modules/picomatch/lib/utils.js @@ -0,0 +1,72 @@ +/*global navigator*/ +'use strict'; + +const { + REGEX_BACKSLASH, + REGEX_REMOVE_BACKSLASH, + REGEX_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_GLOBAL +} = require('./constants'); + +exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); +exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); +exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); +exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); +exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); + +exports.isWindows = () => { + if (typeof navigator !== 'undefined' && navigator.platform) { + const platform = navigator.platform.toLowerCase(); + return platform === 'win32' || platform === 'windows'; + } + + if (typeof process !== 'undefined' && process.platform) { + return process.platform === 'win32'; + } + + return false; +}; + +exports.removeBackslashes = str => { + return str.replace(REGEX_REMOVE_BACKSLASH, match => { + return match === '\\' ? '' : match; + }); +}; + +exports.escapeLast = (input, char, lastIdx) => { + const idx = input.lastIndexOf(char, lastIdx); + if (idx === -1) return input; + if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); + return `${input.slice(0, idx)}\\${input.slice(idx)}`; +}; + +exports.removePrefix = (input, state = {}) => { + let output = input; + if (output.startsWith('./')) { + output = output.slice(2); + state.prefix = './'; + } + return output; +}; + +exports.wrapOutput = (input, state = {}, options = {}) => { + const prepend = options.contains ? '' : '^'; + const append = options.contains ? '' : '$'; + + let output = `${prepend}(?:${input})${append}`; + if (state.negated === true) { + output = `(?:^(?!${output}).*$)`; + } + return output; +}; + +exports.basename = (path, { windows } = {}) => { + const segs = path.split(windows ? /[\\/]/ : '/'); + const last = segs[segs.length - 1]; + + if (last === '') { + return segs[segs.length - 2]; + } + + return last; +}; diff --git a/node_modules/picomatch/package.json b/node_modules/picomatch/package.json new file mode 100644 index 0000000000..372e27e05f --- /dev/null +++ b/node_modules/picomatch/package.json @@ -0,0 +1,83 @@ +{ + "name": "picomatch", + "description": "Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.", + "version": "4.0.3", + "homepage": "https://github.com/micromatch/picomatch", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "funding": "https://github.com/sponsors/jonschlinkert", + "repository": "micromatch/picomatch", + "bugs": { + "url": "https://github.com/micromatch/picomatch/issues" + }, + "license": "MIT", + "files": [ + "index.js", + "posix.js", + "lib" + ], + "sideEffects": false, + "main": "index.js", + "engines": { + "node": ">=12" + }, + "scripts": { + "lint": "eslint --cache --cache-location node_modules/.cache/.eslintcache --report-unused-disable-directives --ignore-path .gitignore .", + "mocha": "mocha --reporter dot", + "test": "npm run lint && npm run mocha", + "test:ci": "npm run test:cover", + "test:cover": "nyc npm run mocha" + }, + "devDependencies": { + "eslint": "^8.57.0", + "fill-range": "^7.0.1", + "gulp-format-md": "^2.0.0", + "mocha": "^10.4.0", + "nyc": "^15.1.0", + "time-require": "github:jonschlinkert/time-require" + }, + "keywords": [ + "glob", + "match", + "picomatch" + ], + "nyc": { + "reporter": [ + "html", + "lcov", + "text-summary" + ] + }, + "verb": { + "toc": { + "render": true, + "method": "preWrite", + "maxdepth": 3 + }, + "layout": "empty", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + }, + "related": { + "list": [ + "braces", + "micromatch" + ] + }, + "reflinks": [ + "braces", + "expand-brackets", + "extglob", + "fill-range", + "micromatch", + "minimatch", + "nanomatch", + "picomatch" + ] + } +} diff --git a/node_modules/picomatch/posix.js b/node_modules/picomatch/posix.js new file mode 100644 index 0000000000..d2f2bc59d0 --- /dev/null +++ b/node_modules/picomatch/posix.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./lib/picomatch'); diff --git a/node_modules/postcss/LICENSE b/node_modules/postcss/LICENSE new file mode 100644 index 0000000000..da057b4562 --- /dev/null +++ b/node_modules/postcss/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2013 Andrey Sitnik + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/postcss/README.md b/node_modules/postcss/README.md new file mode 100644 index 0000000000..05fed079ca --- /dev/null +++ b/node_modules/postcss/README.md @@ -0,0 +1,29 @@ +# PostCSS + +Philosopher’s stone, logo of PostCSS + +PostCSS is a tool for transforming styles with JS plugins. +These plugins can lint your CSS, support variables and mixins, +transpile future CSS syntax, inline images, and more. + +PostCSS is used by industry leaders including Wikipedia, Twitter, Alibaba, +and JetBrains. The [Autoprefixer] and [Stylelint] PostCSS plugins are some of the most popular CSS tools. + +--- + +  Built by + Evil Martians, go-to agency for developer tools. + +--- + +[Abstract Syntax Tree]: https://en.wikipedia.org/wiki/Abstract_syntax_tree +[Evil Martians]: https://evilmartians.com/?utm_source=postcss +[Autoprefixer]: https://github.com/postcss/autoprefixer +[Stylelint]: https://stylelint.io/ +[plugins]: https://github.com/postcss/postcss#plugins + + +## Docs +Read full docs **[here](https://postcss.org/)**. diff --git a/node_modules/postcss/lib/at-rule.d.ts b/node_modules/postcss/lib/at-rule.d.ts new file mode 100644 index 0000000000..89fb505f4a --- /dev/null +++ b/node_modules/postcss/lib/at-rule.d.ts @@ -0,0 +1,140 @@ +import Container, { + ContainerProps, + ContainerWithChildren +} from './container.js' + +declare namespace AtRule { + export interface AtRuleRaws extends Record { + /** + * The space symbols after the last child of the node to the end of the node. + */ + after?: string + + /** + * The space between the at-rule name and its parameters. + */ + afterName?: string + + /** + * The space symbols before the node. It also stores `*` + * and `_` symbols before the declaration (IE hack). + */ + before?: string + + /** + * The symbols between the last parameter and `{` for rules. + */ + between?: string + + /** + * The rule’s selector with comments. + */ + params?: { + raw: string + value: string + } + + /** + * Contains `true` if the last child has an (optional) semicolon. + */ + semicolon?: boolean + } + + export interface AtRuleProps extends ContainerProps { + /** Name of the at-rule. */ + name: string + /** Parameters following the name of the at-rule. */ + params?: number | string + /** Information used to generate byte-to-byte equal node string as it was in the origin input. */ + raws?: AtRuleRaws + } + + // eslint-disable-next-line @typescript-eslint/no-use-before-define + export { AtRule_ as default } +} + +/** + * Represents an at-rule. + * + * ```js + * Once (root, { AtRule }) { + * let media = new AtRule({ name: 'media', params: 'print' }) + * media.append(…) + * root.append(media) + * } + * ``` + * + * If it’s followed in the CSS by a `{}` block, this node will have + * a nodes property representing its children. + * + * ```js + * const root = postcss.parse('@charset "UTF-8"; @media print {}') + * + * const charset = root.first + * charset.type //=> 'atrule' + * charset.nodes //=> undefined + * + * const media = root.last + * media.nodes //=> [] + * ``` + */ +declare class AtRule_ extends Container { + /** + * An array containing the layer’s children. + * + * ```js + * const root = postcss.parse('@layer example { a { color: black } }') + * const layer = root.first + * layer.nodes.length //=> 1 + * layer.nodes[0].selector //=> 'a' + * ``` + * + * Can be `undefinded` if the at-rule has no body. + * + * ```js + * const root = postcss.parse('@layer a, b, c;') + * const layer = root.first + * layer.nodes //=> undefined + * ``` + */ + nodes: Container['nodes'] | undefined + parent: ContainerWithChildren | undefined + + raws: AtRule.AtRuleRaws + type: 'atrule' + /** + * The at-rule’s name immediately follows the `@`. + * + * ```js + * const root = postcss.parse('@media print {}') + * const media = root.first + * media.name //=> 'media' + * ``` + */ + get name(): string + set name(value: string) + + /** + * The at-rule’s parameters, the values that follow the at-rule’s name + * but precede any `{}` block. + * + * ```js + * const root = postcss.parse('@media print, screen {}') + * const media = root.first + * media.params //=> 'print, screen' + * ``` + */ + get params(): string + + set params(value: string) + + constructor(defaults?: AtRule.AtRuleProps) + assign(overrides: AtRule.AtRuleProps | object): this + clone(overrides?: Partial): this + cloneAfter(overrides?: Partial): this + cloneBefore(overrides?: Partial): this +} + +declare class AtRule extends AtRule_ {} + +export = AtRule diff --git a/node_modules/postcss/lib/at-rule.js b/node_modules/postcss/lib/at-rule.js new file mode 100644 index 0000000000..9486447b02 --- /dev/null +++ b/node_modules/postcss/lib/at-rule.js @@ -0,0 +1,25 @@ +'use strict' + +let Container = require('./container') + +class AtRule extends Container { + constructor(defaults) { + super(defaults) + this.type = 'atrule' + } + + append(...children) { + if (!this.proxyOf.nodes) this.nodes = [] + return super.append(...children) + } + + prepend(...children) { + if (!this.proxyOf.nodes) this.nodes = [] + return super.prepend(...children) + } +} + +module.exports = AtRule +AtRule.default = AtRule + +Container.registerAtRule(AtRule) diff --git a/node_modules/postcss/lib/comment.d.ts b/node_modules/postcss/lib/comment.d.ts new file mode 100644 index 0000000000..6f1f66f81d --- /dev/null +++ b/node_modules/postcss/lib/comment.d.ts @@ -0,0 +1,68 @@ +import Container from './container.js' +import Node, { NodeProps } from './node.js' + +declare namespace Comment { + export interface CommentRaws extends Record { + /** + * The space symbols before the node. + */ + before?: string + + /** + * The space symbols between `/*` and the comment’s text. + */ + left?: string + + /** + * The space symbols between the comment’s text. + */ + right?: string + } + + export interface CommentProps extends NodeProps { + /** Information used to generate byte-to-byte equal node string as it was in the origin input. */ + raws?: CommentRaws + /** Content of the comment. */ + text: string + } + + // eslint-disable-next-line @typescript-eslint/no-use-before-define + export { Comment_ as default } +} + +/** + * It represents a class that handles + * [CSS comments](https://developer.mozilla.org/en-US/docs/Web/CSS/Comments) + * + * ```js + * Once (root, { Comment }) { + * const note = new Comment({ text: 'Note: …' }) + * root.append(note) + * } + * ``` + * + * Remember that CSS comments inside selectors, at-rule parameters, + * or declaration values will be stored in the `raws` properties + * explained above. + */ +declare class Comment_ extends Node { + parent: Container | undefined + raws: Comment.CommentRaws + type: 'comment' + /** + * The comment's text. + */ + get text(): string + + set text(value: string) + + constructor(defaults?: Comment.CommentProps) + assign(overrides: Comment.CommentProps | object): this + clone(overrides?: Partial): this + cloneAfter(overrides?: Partial): this + cloneBefore(overrides?: Partial): this +} + +declare class Comment extends Comment_ {} + +export = Comment diff --git a/node_modules/postcss/lib/comment.js b/node_modules/postcss/lib/comment.js new file mode 100644 index 0000000000..c56650645c --- /dev/null +++ b/node_modules/postcss/lib/comment.js @@ -0,0 +1,13 @@ +'use strict' + +let Node = require('./node') + +class Comment extends Node { + constructor(defaults) { + super(defaults) + this.type = 'comment' + } +} + +module.exports = Comment +Comment.default = Comment diff --git a/node_modules/postcss/lib/container.d.ts b/node_modules/postcss/lib/container.d.ts new file mode 100644 index 0000000000..c2b310b6b7 --- /dev/null +++ b/node_modules/postcss/lib/container.d.ts @@ -0,0 +1,483 @@ +import AtRule from './at-rule.js' +import Comment from './comment.js' +import Declaration from './declaration.js' +import Node, { ChildNode, ChildProps, NodeProps } from './node.js' +import { Root } from './postcss.js' +import Rule from './rule.js' + +declare namespace Container { + export type ContainerWithChildren = { + nodes: Child[] + } & ( + | AtRule + | Root + | Rule + ) + + export interface ValueOptions { + /** + * String that’s used to narrow down values and speed up the regexp search. + */ + fast?: string + + /** + * An array of property names. + */ + props?: readonly string[] + } + + export interface ContainerProps extends NodeProps { + nodes?: readonly (ChildProps | Node)[] + } + + /** + * All types that can be passed into container methods to create or add a new + * child node. + */ + export type NewChild = + | ChildProps + | Node + | readonly ChildProps[] + | readonly Node[] + | readonly string[] + | string + | undefined + + // eslint-disable-next-line @typescript-eslint/no-use-before-define + export { Container_ as default } +} + +/** + * The `Root`, `AtRule`, and `Rule` container nodes + * inherit some common methods to help work with their children. + * + * Note that all containers can store any content. If you write a rule inside + * a rule, PostCSS will parse it. + */ +declare abstract class Container_ extends Node { + /** + * An array containing the container’s children. + * + * ```js + * const root = postcss.parse('a { color: black }') + * root.nodes.length //=> 1 + * root.nodes[0].selector //=> 'a' + * root.nodes[0].nodes[0].prop //=> 'color' + * ``` + */ + nodes: Child[] | undefined + + /** + * The container’s first child. + * + * ```js + * rule.first === rules.nodes[0] + * ``` + */ + get first(): Child | undefined + + /** + * The container’s last child. + * + * ```js + * rule.last === rule.nodes[rule.nodes.length - 1] + * ``` + */ + get last(): Child | undefined + /** + * Inserts new nodes to the end of the container. + * + * ```js + * const decl1 = new Declaration({ prop: 'color', value: 'black' }) + * const decl2 = new Declaration({ prop: 'background-color', value: 'white' }) + * rule.append(decl1, decl2) + * + * root.append({ name: 'charset', params: '"UTF-8"' }) // at-rule + * root.append({ selector: 'a' }) // rule + * rule.append({ prop: 'color', value: 'black' }) // declaration + * rule.append({ text: 'Comment' }) // comment + * + * root.append('a {}') + * root.first.append('color: black; z-index: 1') + * ``` + * + * @param nodes New nodes. + * @return This node for methods chain. + */ + append(...nodes: Container.NewChild[]): this + assign(overrides: Container.ContainerProps | object): this + clone(overrides?: Partial): this + + cloneAfter(overrides?: Partial): this + + cloneBefore(overrides?: Partial): this + /** + * Iterates through the container’s immediate children, + * calling `callback` for each child. + * + * Returning `false` in the callback will break iteration. + * + * This method only iterates through the container’s immediate children. + * If you need to recursively iterate through all the container’s descendant + * nodes, use `Container#walk`. + * + * Unlike the for `{}`-cycle or `Array#forEach` this iterator is safe + * if you are mutating the array of child nodes during iteration. + * PostCSS will adjust the current index to match the mutations. + * + * ```js + * const root = postcss.parse('a { color: black; z-index: 1 }') + * const rule = root.first + * + * for (const decl of rule.nodes) { + * decl.cloneBefore({ prop: '-webkit-' + decl.prop }) + * // Cycle will be infinite, because cloneBefore moves the current node + * // to the next index + * } + * + * rule.each(decl => { + * decl.cloneBefore({ prop: '-webkit-' + decl.prop }) + * // Will be executed only for color and z-index + * }) + * ``` + * + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + each( + callback: (node: Child, index: number) => false | void + ): false | undefined + + /** + * Returns `true` if callback returns `true` + * for all of the container’s children. + * + * ```js + * const noPrefixes = rule.every(i => i.prop[0] !== '-') + * ``` + * + * @param condition Iterator returns true or false. + * @return Is every child pass condition. + */ + every( + condition: (node: Child, index: number, nodes: Child[]) => boolean + ): boolean + /** + * Returns a `child`’s index within the `Container#nodes` array. + * + * ```js + * rule.index( rule.nodes[2] ) //=> 2 + * ``` + * + * @param child Child of the current container. + * @return Child index. + */ + index(child: Child | number): number + + /** + * Insert new node after old node within the container. + * + * @param oldNode Child or child’s index. + * @param newNode New node. + * @return This node for methods chain. + */ + insertAfter(oldNode: Child | number, newNode: Container.NewChild): this + + /** + * Traverses the container’s descendant nodes, calling callback + * for each comment node. + * + * Like `Container#each`, this method is safe + * to use if you are mutating arrays during iteration. + * + * ```js + * root.walkComments(comment => { + * comment.remove() + * }) + * ``` + * + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + + /** + * Insert new node before old node within the container. + * + * ```js + * rule.insertBefore(decl, decl.clone({ prop: '-webkit-' + decl.prop })) + * ``` + * + * @param oldNode Child or child’s index. + * @param newNode New node. + * @return This node for methods chain. + */ + insertBefore(oldNode: Child | number, newNode: Container.NewChild): this + /** + * Inserts new nodes to the start of the container. + * + * ```js + * const decl1 = new Declaration({ prop: 'color', value: 'black' }) + * const decl2 = new Declaration({ prop: 'background-color', value: 'white' }) + * rule.prepend(decl1, decl2) + * + * root.append({ name: 'charset', params: '"UTF-8"' }) // at-rule + * root.append({ selector: 'a' }) // rule + * rule.append({ prop: 'color', value: 'black' }) // declaration + * rule.append({ text: 'Comment' }) // comment + * + * root.append('a {}') + * root.first.append('color: black; z-index: 1') + * ``` + * + * @param nodes New nodes. + * @return This node for methods chain. + */ + prepend(...nodes: Container.NewChild[]): this + + /** + * Add child to the end of the node. + * + * ```js + * rule.push(new Declaration({ prop: 'color', value: 'black' })) + * ``` + * + * @param child New node. + * @return This node for methods chain. + */ + push(child: Child): this + + /** + * Removes all children from the container + * and cleans their parent properties. + * + * ```js + * rule.removeAll() + * rule.nodes.length //=> 0 + * ``` + * + * @return This node for methods chain. + */ + removeAll(): this + + /** + * Removes node from the container and cleans the parent properties + * from the node and its children. + * + * ```js + * rule.nodes.length //=> 5 + * rule.removeChild(decl) + * rule.nodes.length //=> 4 + * decl.parent //=> undefined + * ``` + * + * @param child Child or child’s index. + * @return This node for methods chain. + */ + removeChild(child: Child | number): this + + replaceValues( + pattern: RegExp | string, + replaced: { (substring: string, ...args: any[]): string } | string + ): this + /** + * Passes all declaration values within the container that match pattern + * through callback, replacing those values with the returned result + * of callback. + * + * This method is useful if you are using a custom unit or function + * and need to iterate through all values. + * + * ```js + * root.replaceValues(/\d+rem/, { fast: 'rem' }, string => { + * return 15 * parseInt(string) + 'px' + * }) + * ``` + * + * @param pattern Replace pattern. + * @param {object} options Options to speed up the search. + * @param replaced String to replace pattern or callback + * that returns a new value. The callback + * will receive the same arguments + * as those passed to a function parameter + * of `String#replace`. + * @return This node for methods chain. + */ + replaceValues( + pattern: RegExp | string, + options: Container.ValueOptions, + replaced: { (substring: string, ...args: any[]): string } | string + ): this + + /** + * Returns `true` if callback returns `true` for (at least) one + * of the container’s children. + * + * ```js + * const hasPrefix = rule.some(i => i.prop[0] === '-') + * ``` + * + * @param condition Iterator returns true or false. + * @return Is some child pass condition. + */ + some( + condition: (node: Child, index: number, nodes: Child[]) => boolean + ): boolean + + /** + * Traverses the container’s descendant nodes, calling callback + * for each node. + * + * Like container.each(), this method is safe to use + * if you are mutating arrays during iteration. + * + * If you only need to iterate through the container’s immediate children, + * use `Container#each`. + * + * ```js + * root.walk(node => { + * // Traverses all descendant nodes. + * }) + * ``` + * + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + walk( + callback: (node: ChildNode, index: number) => false | void + ): false | undefined + + /** + * Traverses the container’s descendant nodes, calling callback + * for each at-rule node. + * + * If you pass a filter, iteration will only happen over at-rules + * that have matching names. + * + * Like `Container#each`, this method is safe + * to use if you are mutating arrays during iteration. + * + * ```js + * root.walkAtRules(rule => { + * if (isOld(rule.name)) rule.remove() + * }) + * + * let first = false + * root.walkAtRules('charset', rule => { + * if (!first) { + * first = true + * } else { + * rule.remove() + * } + * }) + * ``` + * + * @param name String or regular expression to filter at-rules by name. + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + walkAtRules( + nameFilter: RegExp | string, + callback: (atRule: AtRule, index: number) => false | void + ): false | undefined + walkAtRules( + callback: (atRule: AtRule, index: number) => false | void + ): false | undefined + + walkComments( + callback: (comment: Comment, indexed: number) => false | void + ): false | undefined + walkComments( + callback: (comment: Comment, indexed: number) => false | void + ): false | undefined + + /** + * Traverses the container’s descendant nodes, calling callback + * for each declaration node. + * + * If you pass a filter, iteration will only happen over declarations + * with matching properties. + * + * ```js + * root.walkDecls(decl => { + * checkPropertySupport(decl.prop) + * }) + * + * root.walkDecls('border-radius', decl => { + * decl.remove() + * }) + * + * root.walkDecls(/^background/, decl => { + * decl.value = takeFirstColorFromGradient(decl.value) + * }) + * ``` + * + * Like `Container#each`, this method is safe + * to use if you are mutating arrays during iteration. + * + * @param prop String or regular expression to filter declarations + * by property name. + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + walkDecls( + propFilter: RegExp | string, + callback: (decl: Declaration, index: number) => false | void + ): false | undefined + walkDecls( + callback: (decl: Declaration, index: number) => false | void + ): false | undefined + /** + * Traverses the container’s descendant nodes, calling callback + * for each rule node. + * + * If you pass a filter, iteration will only happen over rules + * with matching selectors. + * + * Like `Container#each`, this method is safe + * to use if you are mutating arrays during iteration. + * + * ```js + * const selectors = [] + * root.walkRules(rule => { + * selectors.push(rule.selector) + * }) + * console.log(`Your CSS uses ${ selectors.length } selectors`) + * ``` + * + * @param selector String or regular expression to filter rules by selector. + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + walkRules( + selectorFilter: RegExp | string, + callback: (rule: Rule, index: number) => false | void + ): false | undefined + walkRules( + callback: (rule: Rule, index: number) => false | void + ): false | undefined + /** + * An internal method that converts a {@link NewChild} into a list of actual + * child nodes that can then be added to this container. + * + * This ensures that the nodes' parent is set to this container, that they use + * the correct prototype chain, and that they're marked as dirty. + * + * @param mnodes The new node or nodes to add. + * @param sample A node from whose raws the new node's `before` raw should be + * taken. + * @param type This should be set to `'prepend'` if the new nodes will be + * inserted at the beginning of the container. + * @hidden + */ + protected normalize( + nodes: Container.NewChild, + sample: Node | undefined, + type?: 'prepend' | false + ): Child[] +} + +declare class Container< + Child extends Node = ChildNode +> extends Container_ {} + +export = Container diff --git a/node_modules/postcss/lib/container.js b/node_modules/postcss/lib/container.js new file mode 100644 index 0000000000..edb07cc2f9 --- /dev/null +++ b/node_modules/postcss/lib/container.js @@ -0,0 +1,447 @@ +'use strict' + +let Comment = require('./comment') +let Declaration = require('./declaration') +let Node = require('./node') +let { isClean, my } = require('./symbols') + +let AtRule, parse, Root, Rule + +function cleanSource(nodes) { + return nodes.map(i => { + if (i.nodes) i.nodes = cleanSource(i.nodes) + delete i.source + return i + }) +} + +function markTreeDirty(node) { + node[isClean] = false + if (node.proxyOf.nodes) { + for (let i of node.proxyOf.nodes) { + markTreeDirty(i) + } + } +} + +class Container extends Node { + get first() { + if (!this.proxyOf.nodes) return undefined + return this.proxyOf.nodes[0] + } + + get last() { + if (!this.proxyOf.nodes) return undefined + return this.proxyOf.nodes[this.proxyOf.nodes.length - 1] + } + + append(...children) { + for (let child of children) { + let nodes = this.normalize(child, this.last) + for (let node of nodes) this.proxyOf.nodes.push(node) + } + + this.markDirty() + + return this + } + + cleanRaws(keepBetween) { + super.cleanRaws(keepBetween) + if (this.nodes) { + for (let node of this.nodes) node.cleanRaws(keepBetween) + } + } + + each(callback) { + if (!this.proxyOf.nodes) return undefined + let iterator = this.getIterator() + + let index, result + while (this.indexes[iterator] < this.proxyOf.nodes.length) { + index = this.indexes[iterator] + result = callback(this.proxyOf.nodes[index], index) + if (result === false) break + + this.indexes[iterator] += 1 + } + + delete this.indexes[iterator] + return result + } + + every(condition) { + return this.nodes.every(condition) + } + + getIterator() { + if (!this.lastEach) this.lastEach = 0 + if (!this.indexes) this.indexes = {} + + this.lastEach += 1 + let iterator = this.lastEach + this.indexes[iterator] = 0 + + return iterator + } + + getProxyProcessor() { + return { + get(node, prop) { + if (prop === 'proxyOf') { + return node + } else if (!node[prop]) { + return node[prop] + } else if ( + prop === 'each' || + (typeof prop === 'string' && prop.startsWith('walk')) + ) { + return (...args) => { + return node[prop]( + ...args.map(i => { + if (typeof i === 'function') { + return (child, index) => i(child.toProxy(), index) + } else { + return i + } + }) + ) + } + } else if (prop === 'every' || prop === 'some') { + return cb => { + return node[prop]((child, ...other) => + cb(child.toProxy(), ...other) + ) + } + } else if (prop === 'root') { + return () => node.root().toProxy() + } else if (prop === 'nodes') { + return node.nodes.map(i => i.toProxy()) + } else if (prop === 'first' || prop === 'last') { + return node[prop].toProxy() + } else { + return node[prop] + } + }, + + set(node, prop, value) { + if (node[prop] === value) return true + node[prop] = value + if (prop === 'name' || prop === 'params' || prop === 'selector') { + node.markDirty() + } + return true + } + } + } + + index(child) { + if (typeof child === 'number') return child + if (child.proxyOf) child = child.proxyOf + return this.proxyOf.nodes.indexOf(child) + } + + insertAfter(exist, add) { + let existIndex = this.index(exist) + let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse() + existIndex = this.index(exist) + for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node) + + let index + for (let id in this.indexes) { + index = this.indexes[id] + if (existIndex < index) { + this.indexes[id] = index + nodes.length + } + } + + this.markDirty() + + return this + } + + insertBefore(exist, add) { + let existIndex = this.index(exist) + let type = existIndex === 0 ? 'prepend' : false + let nodes = this.normalize( + add, + this.proxyOf.nodes[existIndex], + type + ).reverse() + existIndex = this.index(exist) + for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node) + + let index + for (let id in this.indexes) { + index = this.indexes[id] + if (existIndex <= index) { + this.indexes[id] = index + nodes.length + } + } + + this.markDirty() + + return this + } + + normalize(nodes, sample) { + if (typeof nodes === 'string') { + nodes = cleanSource(parse(nodes).nodes) + } else if (typeof nodes === 'undefined') { + nodes = [] + } else if (Array.isArray(nodes)) { + nodes = nodes.slice(0) + for (let i of nodes) { + if (i.parent) i.parent.removeChild(i, 'ignore') + } + } else if (nodes.type === 'root' && this.type !== 'document') { + nodes = nodes.nodes.slice(0) + for (let i of nodes) { + if (i.parent) i.parent.removeChild(i, 'ignore') + } + } else if (nodes.type) { + nodes = [nodes] + } else if (nodes.prop) { + if (typeof nodes.value === 'undefined') { + throw new Error('Value field is missed in node creation') + } else if (typeof nodes.value !== 'string') { + nodes.value = String(nodes.value) + } + nodes = [new Declaration(nodes)] + } else if (nodes.selector || nodes.selectors) { + nodes = [new Rule(nodes)] + } else if (nodes.name) { + nodes = [new AtRule(nodes)] + } else if (nodes.text) { + nodes = [new Comment(nodes)] + } else { + throw new Error('Unknown node type in node creation') + } + + let processed = nodes.map(i => { + /* c8 ignore next */ + if (!i[my]) Container.rebuild(i) + i = i.proxyOf + if (i.parent) i.parent.removeChild(i) + if (i[isClean]) markTreeDirty(i) + + if (!i.raws) i.raws = {} + if (typeof i.raws.before === 'undefined') { + if (sample && typeof sample.raws.before !== 'undefined') { + i.raws.before = sample.raws.before.replace(/\S/g, '') + } + } + i.parent = this.proxyOf + return i + }) + + return processed + } + + prepend(...children) { + children = children.reverse() + for (let child of children) { + let nodes = this.normalize(child, this.first, 'prepend').reverse() + for (let node of nodes) this.proxyOf.nodes.unshift(node) + for (let id in this.indexes) { + this.indexes[id] = this.indexes[id] + nodes.length + } + } + + this.markDirty() + + return this + } + + push(child) { + child.parent = this + this.proxyOf.nodes.push(child) + return this + } + + removeAll() { + for (let node of this.proxyOf.nodes) node.parent = undefined + this.proxyOf.nodes = [] + + this.markDirty() + + return this + } + + removeChild(child) { + child = this.index(child) + this.proxyOf.nodes[child].parent = undefined + this.proxyOf.nodes.splice(child, 1) + + let index + for (let id in this.indexes) { + index = this.indexes[id] + if (index >= child) { + this.indexes[id] = index - 1 + } + } + + this.markDirty() + + return this + } + + replaceValues(pattern, opts, callback) { + if (!callback) { + callback = opts + opts = {} + } + + this.walkDecls(decl => { + if (opts.props && !opts.props.includes(decl.prop)) return + if (opts.fast && !decl.value.includes(opts.fast)) return + + decl.value = decl.value.replace(pattern, callback) + }) + + this.markDirty() + + return this + } + + some(condition) { + return this.nodes.some(condition) + } + + walk(callback) { + return this.each((child, i) => { + let result + try { + result = callback(child, i) + } catch (e) { + throw child.addToError(e) + } + if (result !== false && child.walk) { + result = child.walk(callback) + } + + return result + }) + } + + walkAtRules(name, callback) { + if (!callback) { + callback = name + return this.walk((child, i) => { + if (child.type === 'atrule') { + return callback(child, i) + } + }) + } + if (name instanceof RegExp) { + return this.walk((child, i) => { + if (child.type === 'atrule' && name.test(child.name)) { + return callback(child, i) + } + }) + } + return this.walk((child, i) => { + if (child.type === 'atrule' && child.name === name) { + return callback(child, i) + } + }) + } + + walkComments(callback) { + return this.walk((child, i) => { + if (child.type === 'comment') { + return callback(child, i) + } + }) + } + + walkDecls(prop, callback) { + if (!callback) { + callback = prop + return this.walk((child, i) => { + if (child.type === 'decl') { + return callback(child, i) + } + }) + } + if (prop instanceof RegExp) { + return this.walk((child, i) => { + if (child.type === 'decl' && prop.test(child.prop)) { + return callback(child, i) + } + }) + } + return this.walk((child, i) => { + if (child.type === 'decl' && child.prop === prop) { + return callback(child, i) + } + }) + } + + walkRules(selector, callback) { + if (!callback) { + callback = selector + + return this.walk((child, i) => { + if (child.type === 'rule') { + return callback(child, i) + } + }) + } + if (selector instanceof RegExp) { + return this.walk((child, i) => { + if (child.type === 'rule' && selector.test(child.selector)) { + return callback(child, i) + } + }) + } + return this.walk((child, i) => { + if (child.type === 'rule' && child.selector === selector) { + return callback(child, i) + } + }) + } +} + +Container.registerParse = dependant => { + parse = dependant +} + +Container.registerRule = dependant => { + Rule = dependant +} + +Container.registerAtRule = dependant => { + AtRule = dependant +} + +Container.registerRoot = dependant => { + Root = dependant +} + +module.exports = Container +Container.default = Container + +/* c8 ignore start */ +Container.rebuild = node => { + if (node.type === 'atrule') { + Object.setPrototypeOf(node, AtRule.prototype) + } else if (node.type === 'rule') { + Object.setPrototypeOf(node, Rule.prototype) + } else if (node.type === 'decl') { + Object.setPrototypeOf(node, Declaration.prototype) + } else if (node.type === 'comment') { + Object.setPrototypeOf(node, Comment.prototype) + } else if (node.type === 'root') { + Object.setPrototypeOf(node, Root.prototype) + } + + node[my] = true + + if (node.nodes) { + node.nodes.forEach(child => { + Container.rebuild(child) + }) + } +} +/* c8 ignore stop */ diff --git a/node_modules/postcss/lib/css-syntax-error.d.ts b/node_modules/postcss/lib/css-syntax-error.d.ts new file mode 100644 index 0000000000..e540d84965 --- /dev/null +++ b/node_modules/postcss/lib/css-syntax-error.d.ts @@ -0,0 +1,248 @@ +import { FilePosition } from './input.js' + +declare namespace CssSyntaxError { + /** + * A position that is part of a range. + */ + export interface RangePosition { + /** + * The column number in the input. + */ + column: number + + /** + * The line number in the input. + */ + line: number + } + + // eslint-disable-next-line @typescript-eslint/no-use-before-define + export { CssSyntaxError_ as default } +} + +/** + * The CSS parser throws this error for broken CSS. + * + * Custom parsers can throw this error for broken custom syntax using + * the `Node#error` method. + * + * PostCSS will use the input source map to detect the original error location. + * If you wrote a Sass file, compiled it to CSS and then parsed it with PostCSS, + * PostCSS will show the original position in the Sass file. + * + * If you need the position in the PostCSS input + * (e.g., to debug the previous compiler), use `error.input.file`. + * + * ```js + * // Raising error from plugin + * throw node.error('Unknown variable', { plugin: 'postcss-vars' }) + * ``` + * + * ```js + * // Catching and checking syntax error + * try { + * postcss.parse('a{') + * } catch (error) { + * if (error.name === 'CssSyntaxError') { + * error //=> CssSyntaxError + * } + * } + * ``` + */ +declare class CssSyntaxError_ extends Error { + /** + * Source column of the error. + * + * ```js + * error.column //=> 1 + * error.input.column //=> 4 + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.column`. + */ + column?: number + + /** + * Source column of the error's end, exclusive. Provided if the error pertains + * to a range. + * + * ```js + * error.endColumn //=> 1 + * error.input.endColumn //=> 4 + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.endColumn`. + */ + endColumn?: number + + /** + * Source line of the error's end, exclusive. Provided if the error pertains + * to a range. + * + * ```js + * error.endLine //=> 3 + * error.input.endLine //=> 4 + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.endLine`. + */ + endLine?: number + + /** + * Absolute path to the broken file. + * + * ```js + * error.file //=> 'a.sass' + * error.input.file //=> 'a.css' + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.file`. + */ + file?: string + + /** + * Input object with PostCSS internal information + * about input file. If input has source map + * from previous tool, PostCSS will use origin + * (for example, Sass) source. You can use this + * object to get PostCSS input source. + * + * ```js + * error.input.file //=> 'a.css' + * error.file //=> 'a.sass' + * ``` + */ + input?: FilePosition + + /** + * Source line of the error. + * + * ```js + * error.line //=> 2 + * error.input.line //=> 4 + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.line`. + */ + line?: number + + /** + * Full error text in the GNU error format + * with plugin, file, line and column. + * + * ```js + * error.message //=> 'a.css:1:1: Unclosed block' + * ``` + */ + message: string + + /** + * Always equal to `'CssSyntaxError'`. You should always check error type + * by `error.name === 'CssSyntaxError'` + * instead of `error instanceof CssSyntaxError`, + * because npm could have several PostCSS versions. + * + * ```js + * if (error.name === 'CssSyntaxError') { + * error //=> CssSyntaxError + * } + * ``` + */ + name: 'CssSyntaxError' + + /** + * Plugin name, if error came from plugin. + * + * ```js + * error.plugin //=> 'postcss-vars' + * ``` + */ + plugin?: string + + /** + * Error message. + * + * ```js + * error.message //=> 'Unclosed block' + * ``` + */ + reason: string + + /** + * Source code of the broken file. + * + * ```js + * error.source //=> 'a { b {} }' + * error.input.source //=> 'a b { }' + * ``` + */ + source?: string + + stack: string + + /** + * Instantiates a CSS syntax error. Can be instantiated for a single position + * or for a range. + * @param message Error message. + * @param lineOrStartPos If for a single position, the line number, or if for + * a range, the inclusive start position of the error. + * @param columnOrEndPos If for a single position, the column number, or if for + * a range, the exclusive end position of the error. + * @param source Source code of the broken file. + * @param file Absolute path to the broken file. + * @param plugin PostCSS plugin name, if error came from plugin. + */ + constructor( + message: string, + lineOrStartPos?: CssSyntaxError.RangePosition | number, + columnOrEndPos?: CssSyntaxError.RangePosition | number, + source?: string, + file?: string, + plugin?: string + ) + + /** + * Returns a few lines of CSS source that caused the error. + * + * If the CSS has an input source map without `sourceContent`, + * this method will return an empty string. + * + * ```js + * error.showSourceCode() //=> " 4 | } + * // 5 | a { + * // > 6 | bad + * // | ^ + * // 7 | } + * // 8 | b {" + * ``` + * + * @param color Whether arrow will be colored red by terminal + * color codes. By default, PostCSS will detect + * color support by `process.stdout.isTTY` + * and `process.env.NODE_DISABLE_COLORS`. + * @return Few lines of CSS source that caused the error. + */ + showSourceCode(color?: boolean): string + + /** + * Returns error position, message and source code of the broken part. + * + * ```js + * error.toString() //=> "CssSyntaxError: app.css:1:1: Unclosed block + * // > 1 | a { + * // | ^" + * ``` + * + * @return Error position, message and source code. + */ + toString(): string +} + +declare class CssSyntaxError extends CssSyntaxError_ {} + +export = CssSyntaxError diff --git a/node_modules/postcss/lib/css-syntax-error.js b/node_modules/postcss/lib/css-syntax-error.js new file mode 100644 index 0000000000..275a4f64c2 --- /dev/null +++ b/node_modules/postcss/lib/css-syntax-error.js @@ -0,0 +1,133 @@ +'use strict' + +let pico = require('picocolors') + +let terminalHighlight = require('./terminal-highlight') + +class CssSyntaxError extends Error { + constructor(message, line, column, source, file, plugin) { + super(message) + this.name = 'CssSyntaxError' + this.reason = message + + if (file) { + this.file = file + } + if (source) { + this.source = source + } + if (plugin) { + this.plugin = plugin + } + if (typeof line !== 'undefined' && typeof column !== 'undefined') { + if (typeof line === 'number') { + this.line = line + this.column = column + } else { + this.line = line.line + this.column = line.column + this.endLine = column.line + this.endColumn = column.column + } + } + + this.setMessage() + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, CssSyntaxError) + } + } + + setMessage() { + this.message = this.plugin ? this.plugin + ': ' : '' + this.message += this.file ? this.file : '' + if (typeof this.line !== 'undefined') { + this.message += ':' + this.line + ':' + this.column + } + this.message += ': ' + this.reason + } + + showSourceCode(color) { + if (!this.source) return '' + + let css = this.source + if (color == null) color = pico.isColorSupported + + let aside = text => text + let mark = text => text + let highlight = text => text + if (color) { + let { bold, gray, red } = pico.createColors(true) + mark = text => bold(red(text)) + aside = text => gray(text) + if (terminalHighlight) { + highlight = text => terminalHighlight(text) + } + } + + let lines = css.split(/\r?\n/) + let start = Math.max(this.line - 3, 0) + let end = Math.min(this.line + 2, lines.length) + let maxWidth = String(end).length + + return lines + .slice(start, end) + .map((line, index) => { + let number = start + 1 + index + let gutter = ' ' + (' ' + number).slice(-maxWidth) + ' | ' + if (number === this.line) { + if (line.length > 160) { + let padding = 20 + let subLineStart = Math.max(0, this.column - padding) + let subLineEnd = Math.max( + this.column + padding, + this.endColumn + padding + ) + let subLine = line.slice(subLineStart, subLineEnd) + + let spacing = + aside(gutter.replace(/\d/g, ' ')) + + line + .slice(0, Math.min(this.column - 1, padding - 1)) + .replace(/[^\t]/g, ' ') + + return ( + mark('>') + + aside(gutter) + + highlight(subLine) + + '\n ' + + spacing + + mark('^') + ) + } + + let spacing = + aside(gutter.replace(/\d/g, ' ')) + + line.slice(0, this.column - 1).replace(/[^\t]/g, ' ') + + return ( + mark('>') + + aside(gutter) + + highlight(line) + + '\n ' + + spacing + + mark('^') + ) + } + + return ' ' + aside(gutter) + highlight(line) + }) + .join('\n') + } + + toString() { + let code = this.showSourceCode() + if (code) { + code = '\n\n' + code + '\n' + } + return this.name + ': ' + this.message + code + } +} + +module.exports = CssSyntaxError +CssSyntaxError.default = CssSyntaxError diff --git a/node_modules/postcss/lib/declaration.d.ts b/node_modules/postcss/lib/declaration.d.ts new file mode 100644 index 0000000000..d489b4270a --- /dev/null +++ b/node_modules/postcss/lib/declaration.d.ts @@ -0,0 +1,151 @@ +import { ContainerWithChildren } from './container.js' +import Node from './node.js' + +declare namespace Declaration { + export interface DeclarationRaws extends Record { + /** + * The space symbols before the node. It also stores `*` + * and `_` symbols before the declaration (IE hack). + */ + before?: string + + /** + * The symbols between the property and value for declarations. + */ + between?: string + + /** + * The content of the important statement, if it is not just `!important`. + */ + important?: string + + /** + * Declaration value with comments. + */ + value?: { + raw: string + value: string + } + } + + export interface DeclarationProps { + /** Whether the declaration has an `!important` annotation. */ + important?: boolean + /** Name of the declaration. */ + prop: string + /** Information used to generate byte-to-byte equal node string as it was in the origin input. */ + raws?: DeclarationRaws + /** Value of the declaration. */ + value: string + } + + // eslint-disable-next-line @typescript-eslint/no-use-before-define + export { Declaration_ as default } +} + +/** + * It represents a class that handles + * [CSS declarations](https://developer.mozilla.org/en-US/docs/Web/CSS/Syntax#css_declarations) + * + * ```js + * Once (root, { Declaration }) { + * const color = new Declaration({ prop: 'color', value: 'black' }) + * root.append(color) + * } + * ``` + * + * ```js + * const root = postcss.parse('a { color: black }') + * const decl = root.first?.first + * + * decl.type //=> 'decl' + * decl.toString() //=> ' color: black' + * ``` + */ +declare class Declaration_ extends Node { + parent: ContainerWithChildren | undefined + raws: Declaration.DeclarationRaws + + type: 'decl' + + /** + * It represents a specificity of the declaration. + * + * If true, the CSS declaration will have an + * [important](https://developer.mozilla.org/en-US/docs/Web/CSS/important) + * specifier. + * + * ```js + * const root = postcss.parse('a { color: black !important; color: red }') + * + * root.first.first.important //=> true + * root.first.last.important //=> undefined + * ``` + */ + get important(): boolean + set important(value: boolean) + + /** + * The property name for a CSS declaration. + * + * ```js + * const root = postcss.parse('a { color: black }') + * const decl = root.first.first + * + * decl.prop //=> 'color' + * ``` + */ + get prop(): string + + set prop(value: string) + + /** + * The property value for a CSS declaration. + * + * Any CSS comments inside the value string will be filtered out. + * CSS comments present in the source value will be available in + * the `raws` property. + * + * Assigning new `value` would ignore the comments in `raws` + * property while compiling node to string. + * + * ```js + * const root = postcss.parse('a { color: black }') + * const decl = root.first.first + * + * decl.value //=> 'black' + * ``` + */ + get value(): string + set value(value: string) + + /** + * It represents a getter that returns `true` if a declaration starts with + * `--` or `$`, which are used to declare variables in CSS and SASS/SCSS. + * + * ```js + * const root = postcss.parse(':root { --one: 1 }') + * const one = root.first.first + * + * one.variable //=> true + * ``` + * + * ```js + * const root = postcss.parse('$one: 1') + * const one = root.first + * + * one.variable //=> true + * ``` + */ + get variable(): boolean + constructor(defaults?: Declaration.DeclarationProps) + + assign(overrides: Declaration.DeclarationProps | object): this + clone(overrides?: Partial): this + cloneAfter(overrides?: Partial): this + cloneBefore(overrides?: Partial): this +} + +declare class Declaration extends Declaration_ {} + +export = Declaration diff --git a/node_modules/postcss/lib/declaration.js b/node_modules/postcss/lib/declaration.js new file mode 100644 index 0000000000..65a03aa961 --- /dev/null +++ b/node_modules/postcss/lib/declaration.js @@ -0,0 +1,24 @@ +'use strict' + +let Node = require('./node') + +class Declaration extends Node { + get variable() { + return this.prop.startsWith('--') || this.prop[0] === '$' + } + + constructor(defaults) { + if ( + defaults && + typeof defaults.value !== 'undefined' && + typeof defaults.value !== 'string' + ) { + defaults = { ...defaults, value: String(defaults.value) } + } + super(defaults) + this.type = 'decl' + } +} + +module.exports = Declaration +Declaration.default = Declaration diff --git a/node_modules/postcss/lib/document.d.ts b/node_modules/postcss/lib/document.d.ts new file mode 100644 index 0000000000..f9e8063499 --- /dev/null +++ b/node_modules/postcss/lib/document.d.ts @@ -0,0 +1,69 @@ +import Container, { ContainerProps } from './container.js' +import { ProcessOptions } from './postcss.js' +import Result from './result.js' +import Root from './root.js' + +declare namespace Document { + export interface DocumentProps extends ContainerProps { + nodes?: readonly Root[] + + /** + * Information to generate byte-to-byte equal node string as it was + * in the origin input. + * + * Every parser saves its own properties. + */ + raws?: Record + } + + // eslint-disable-next-line @typescript-eslint/no-use-before-define + export { Document_ as default } +} + +/** + * Represents a file and contains all its parsed nodes. + * + * **Experimental:** some aspects of this node could change within minor + * or patch version releases. + * + * ```js + * const document = htmlParser( + * '' + * ) + * document.type //=> 'document' + * document.nodes.length //=> 2 + * ``` + */ +declare class Document_ extends Container { + nodes: Root[] + parent: undefined + type: 'document' + + constructor(defaults?: Document.DocumentProps) + + assign(overrides: Document.DocumentProps | object): this + clone(overrides?: Partial): this + cloneAfter(overrides?: Partial): this + cloneBefore(overrides?: Partial): this + + /** + * Returns a `Result` instance representing the document’s CSS roots. + * + * ```js + * const root1 = postcss.parse(css1, { from: 'a.css' }) + * const root2 = postcss.parse(css2, { from: 'b.css' }) + * const document = postcss.document() + * document.append(root1) + * document.append(root2) + * const result = document.toResult({ to: 'all.css', map: true }) + * ``` + * + * @param opts Options. + * @return Result with current document’s CSS. + */ + toResult(options?: ProcessOptions): Result +} + +declare class Document extends Document_ {} + +export = Document diff --git a/node_modules/postcss/lib/document.js b/node_modules/postcss/lib/document.js new file mode 100644 index 0000000000..44689917fc --- /dev/null +++ b/node_modules/postcss/lib/document.js @@ -0,0 +1,33 @@ +'use strict' + +let Container = require('./container') + +let LazyResult, Processor + +class Document extends Container { + constructor(defaults) { + // type needs to be passed to super, otherwise child roots won't be normalized correctly + super({ type: 'document', ...defaults }) + + if (!this.nodes) { + this.nodes = [] + } + } + + toResult(opts = {}) { + let lazy = new LazyResult(new Processor(), this, opts) + + return lazy.stringify() + } +} + +Document.registerLazyResult = dependant => { + LazyResult = dependant +} + +Document.registerProcessor = dependant => { + Processor = dependant +} + +module.exports = Document +Document.default = Document diff --git a/node_modules/postcss/lib/fromJSON.d.ts b/node_modules/postcss/lib/fromJSON.d.ts new file mode 100644 index 0000000000..e1deedbd33 --- /dev/null +++ b/node_modules/postcss/lib/fromJSON.d.ts @@ -0,0 +1,9 @@ +import { JSONHydrator } from './postcss.js' + +interface FromJSON extends JSONHydrator { + default: FromJSON +} + +declare const fromJSON: FromJSON + +export = fromJSON diff --git a/node_modules/postcss/lib/fromJSON.js b/node_modules/postcss/lib/fromJSON.js new file mode 100644 index 0000000000..c9ac1a86ca --- /dev/null +++ b/node_modules/postcss/lib/fromJSON.js @@ -0,0 +1,54 @@ +'use strict' + +let AtRule = require('./at-rule') +let Comment = require('./comment') +let Declaration = require('./declaration') +let Input = require('./input') +let PreviousMap = require('./previous-map') +let Root = require('./root') +let Rule = require('./rule') + +function fromJSON(json, inputs) { + if (Array.isArray(json)) return json.map(n => fromJSON(n)) + + let { inputs: ownInputs, ...defaults } = json + if (ownInputs) { + inputs = [] + for (let input of ownInputs) { + let inputHydrated = { ...input, __proto__: Input.prototype } + if (inputHydrated.map) { + inputHydrated.map = { + ...inputHydrated.map, + __proto__: PreviousMap.prototype + } + } + inputs.push(inputHydrated) + } + } + if (defaults.nodes) { + defaults.nodes = json.nodes.map(n => fromJSON(n, inputs)) + } + if (defaults.source) { + let { inputId, ...source } = defaults.source + defaults.source = source + if (inputId != null) { + defaults.source.input = inputs[inputId] + } + } + if (defaults.type === 'root') { + return new Root(defaults) + } else if (defaults.type === 'decl') { + return new Declaration(defaults) + } else if (defaults.type === 'rule') { + return new Rule(defaults) + } else if (defaults.type === 'comment') { + return new Comment(defaults) + } else if (defaults.type === 'atrule') { + return new AtRule(defaults) + } else { + throw new Error('Unknown node type: ' + json.type) + } +} + +module.exports = fromJSON +fromJSON.default = fromJSON diff --git a/node_modules/postcss/lib/input.d.ts b/node_modules/postcss/lib/input.d.ts new file mode 100644 index 0000000000..3207da3e17 --- /dev/null +++ b/node_modules/postcss/lib/input.d.ts @@ -0,0 +1,227 @@ +import { CssSyntaxError, ProcessOptions } from './postcss.js' +import PreviousMap from './previous-map.js' + +declare namespace Input { + export interface FilePosition { + /** + * Column of inclusive start position in source file. + */ + column: number + + /** + * Column of exclusive end position in source file. + */ + endColumn?: number + + /** + * Line of exclusive end position in source file. + */ + endLine?: number + + /** + * Offset of exclusive end position in source file. + */ + endOffset?: number + + /** + * Absolute path to the source file. + */ + file?: string + + /** + * Line of inclusive start position in source file. + */ + line: number + + /** + * Offset of inclusive start position in source file. + */ + offset: number + + /** + * Source code. + */ + source?: string + + /** + * URL for the source file. + */ + url: string + } + + // eslint-disable-next-line @typescript-eslint/no-use-before-define + export { Input_ as default } +} + +/** + * Represents the source CSS. + * + * ```js + * const root = postcss.parse(css, { from: file }) + * const input = root.source.input + * ``` + */ +declare class Input_ { + /** + * Input CSS source. + * + * ```js + * const input = postcss.parse('a{}', { from: file }).input + * input.css //=> "a{}" + * ``` + */ + css: string + + /** + * Input source with support for non-CSS documents. + * + * ```js + * const input = postcss.parse('a{}', { from: file, document: '' }).input + * input.document //=> "" + * input.css //=> "a{}" + * ``` + */ + document: string + + /** + * The absolute path to the CSS source file defined + * with the `from` option. + * + * ```js + * const root = postcss.parse(css, { from: 'a.css' }) + * root.source.input.file //=> '/home/ai/a.css' + * ``` + */ + file?: string + + /** + * The flag to indicate whether or not the source code has Unicode BOM. + */ + hasBOM: boolean + + /** + * The unique ID of the CSS source. It will be created if `from` option + * is not provided (because PostCSS does not know the file path). + * + * ```js + * const root = postcss.parse(css) + * root.source.input.file //=> undefined + * root.source.input.id //=> "" + * ``` + */ + id?: string + + /** + * The input source map passed from a compilation step before PostCSS + * (for example, from Sass compiler). + * + * ```js + * root.source.input.map.consumer().sources //=> ['a.sass'] + * ``` + */ + map: PreviousMap + + /** + * The CSS source identifier. Contains `Input#file` if the user + * set the `from` option, or `Input#id` if they did not. + * + * ```js + * const root = postcss.parse(css, { from: 'a.css' }) + * root.source.input.from //=> "/home/ai/a.css" + * + * const root = postcss.parse(css) + * root.source.input.from //=> "" + * ``` + */ + get from(): string + + /** + * @param css Input CSS source. + * @param opts Process options. + */ + constructor(css: string, opts?: ProcessOptions) + + /** + * Returns `CssSyntaxError` with information about the error and its position. + */ + error( + message: string, + start: + | { + column: number + line: number + } + | { + offset: number + }, + end: + | { + column: number + line: number + } + | { + offset: number + }, + opts?: { plugin?: CssSyntaxError['plugin'] } + ): CssSyntaxError + error( + message: string, + line: number, + column: number, + opts?: { plugin?: CssSyntaxError['plugin'] } + ): CssSyntaxError + error( + message: string, + offset: number, + opts?: { plugin?: CssSyntaxError['plugin'] } + ): CssSyntaxError + + /** + * Converts source line and column to offset. + * + * @param line Source line. + * @param column Source column. + * @return Source offset. + */ + fromLineAndColumn(line: number, column: number): number + + /** + * Converts source offset to line and column. + * + * @param offset Source offset. + */ + fromOffset(offset: number): { col: number; line: number } | null + + /** + * Reads the input source map and returns a symbol position + * in the input source (e.g., in a Sass file that was compiled + * to CSS before being passed to PostCSS). Optionally takes an + * end position, exclusive. + * + * ```js + * root.source.input.origin(1, 1) //=> { file: 'a.css', line: 3, column: 1 } + * root.source.input.origin(1, 1, 1, 4) + * //=> { file: 'a.css', line: 3, column: 1, endLine: 3, endColumn: 4 } + * ``` + * + * @param line Line for inclusive start position in input CSS. + * @param column Column for inclusive start position in input CSS. + * @param endLine Line for exclusive end position in input CSS. + * @param endColumn Column for exclusive end position in input CSS. + * + * @return Position in input source. + */ + origin( + line: number, + column: number, + endLine?: number, + endColumn?: number + ): false | Input.FilePosition + + /** Converts this to a JSON-friendly object representation. */ + toJSON(): object +} + +declare class Input extends Input_ {} + +export = Input diff --git a/node_modules/postcss/lib/input.js b/node_modules/postcss/lib/input.js new file mode 100644 index 0000000000..bb0ccf53a7 --- /dev/null +++ b/node_modules/postcss/lib/input.js @@ -0,0 +1,265 @@ +'use strict' + +let { nanoid } = require('nanoid/non-secure') +let { isAbsolute, resolve } = require('path') +let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') +let { fileURLToPath, pathToFileURL } = require('url') + +let CssSyntaxError = require('./css-syntax-error') +let PreviousMap = require('./previous-map') +let terminalHighlight = require('./terminal-highlight') + +let lineToIndexCache = Symbol('lineToIndexCache') + +let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) +let pathAvailable = Boolean(resolve && isAbsolute) + +function getLineToIndex(input) { + if (input[lineToIndexCache]) return input[lineToIndexCache] + let lines = input.css.split('\n') + let lineToIndex = new Array(lines.length) + let prevIndex = 0 + + for (let i = 0, l = lines.length; i < l; i++) { + lineToIndex[i] = prevIndex + prevIndex += lines[i].length + 1 + } + + input[lineToIndexCache] = lineToIndex + return lineToIndex +} + +class Input { + get from() { + return this.file || this.id + } + + constructor(css, opts = {}) { + if ( + css === null || + typeof css === 'undefined' || + (typeof css === 'object' && !css.toString) + ) { + throw new Error(`PostCSS received ${css} instead of CSS string`) + } + + this.css = css.toString() + + if (this.css[0] === '\uFEFF' || this.css[0] === '\uFFFE') { + this.hasBOM = true + this.css = this.css.slice(1) + } else { + this.hasBOM = false + } + + this.document = this.css + if (opts.document) this.document = opts.document.toString() + + if (opts.from) { + if ( + !pathAvailable || + /^\w+:\/\//.test(opts.from) || + isAbsolute(opts.from) + ) { + this.file = opts.from + } else { + this.file = resolve(opts.from) + } + } + + if (pathAvailable && sourceMapAvailable) { + let map = new PreviousMap(this.css, opts) + if (map.text) { + this.map = map + let file = map.consumer().file + if (!this.file && file) this.file = this.mapResolve(file) + } + } + + if (!this.file) { + this.id = '' + } + if (this.map) this.map.file = this.from + } + + error(message, line, column, opts = {}) { + let endColumn, endLine, endOffset, offset, result + + if (line && typeof line === 'object') { + let start = line + let end = column + if (typeof start.offset === 'number') { + offset = start.offset + let pos = this.fromOffset(offset) + line = pos.line + column = pos.col + } else { + line = start.line + column = start.column + offset = this.fromLineAndColumn(line, column) + } + if (typeof end.offset === 'number') { + endOffset = end.offset + let pos = this.fromOffset(endOffset) + endLine = pos.line + endColumn = pos.col + } else { + endLine = end.line + endColumn = end.column + endOffset = this.fromLineAndColumn(end.line, end.column) + } + } else if (!column) { + offset = line + let pos = this.fromOffset(offset) + line = pos.line + column = pos.col + } else { + offset = this.fromLineAndColumn(line, column) + } + + let origin = this.origin(line, column, endLine, endColumn) + if (origin) { + result = new CssSyntaxError( + message, + origin.endLine === undefined + ? origin.line + : { column: origin.column, line: origin.line }, + origin.endLine === undefined + ? origin.column + : { column: origin.endColumn, line: origin.endLine }, + origin.source, + origin.file, + opts.plugin + ) + } else { + result = new CssSyntaxError( + message, + endLine === undefined ? line : { column, line }, + endLine === undefined ? column : { column: endColumn, line: endLine }, + this.css, + this.file, + opts.plugin + ) + } + + result.input = { column, endColumn, endLine, endOffset, line, offset, source: this.css } + if (this.file) { + if (pathToFileURL) { + result.input.url = pathToFileURL(this.file).toString() + } + result.input.file = this.file + } + + return result + } + + fromLineAndColumn(line, column) { + let lineToIndex = getLineToIndex(this) + let index = lineToIndex[line - 1] + return index + column - 1 + } + + fromOffset(offset) { + let lineToIndex = getLineToIndex(this) + let lastLine = lineToIndex[lineToIndex.length - 1] + + let min = 0 + if (offset >= lastLine) { + min = lineToIndex.length - 1 + } else { + let max = lineToIndex.length - 2 + let mid + while (min < max) { + mid = min + ((max - min) >> 1) + if (offset < lineToIndex[mid]) { + max = mid - 1 + } else if (offset >= lineToIndex[mid + 1]) { + min = mid + 1 + } else { + min = mid + break + } + } + } + return { + col: offset - lineToIndex[min] + 1, + line: min + 1 + } + } + + mapResolve(file) { + if (/^\w+:\/\//.test(file)) { + return file + } + return resolve(this.map.consumer().sourceRoot || this.map.root || '.', file) + } + + origin(line, column, endLine, endColumn) { + if (!this.map) return false + let consumer = this.map.consumer() + + let from = consumer.originalPositionFor({ column, line }) + if (!from.source) return false + + let to + if (typeof endLine === 'number') { + to = consumer.originalPositionFor({ column: endColumn, line: endLine }) + } + + let fromUrl + + if (isAbsolute(from.source)) { + fromUrl = pathToFileURL(from.source) + } else { + fromUrl = new URL( + from.source, + this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile) + ) + } + + let result = { + column: from.column, + endColumn: to && to.column, + endLine: to && to.line, + line: from.line, + url: fromUrl.toString() + } + + if (fromUrl.protocol === 'file:') { + if (fileURLToPath) { + result.file = fileURLToPath(fromUrl) + } else { + /* c8 ignore next 2 */ + throw new Error(`file: protocol is not available in this PostCSS build`) + } + } + + let source = consumer.sourceContentFor(from.source) + if (source) result.source = source + + return result + } + + toJSON() { + let json = {} + for (let name of ['hasBOM', 'css', 'file', 'id']) { + if (this[name] != null) { + json[name] = this[name] + } + } + if (this.map) { + json.map = { ...this.map } + if (json.map.consumerCache) { + json.map.consumerCache = undefined + } + } + return json + } +} + +module.exports = Input +Input.default = Input + +if (terminalHighlight && terminalHighlight.registerInput) { + terminalHighlight.registerInput(Input) +} diff --git a/node_modules/postcss/lib/lazy-result.d.ts b/node_modules/postcss/lib/lazy-result.d.ts new file mode 100644 index 0000000000..2eb72796eb --- /dev/null +++ b/node_modules/postcss/lib/lazy-result.d.ts @@ -0,0 +1,190 @@ +import Document from './document.js' +import { SourceMap } from './postcss.js' +import Processor from './processor.js' +import Result, { Message, ResultOptions } from './result.js' +import Root from './root.js' +import Warning from './warning.js' + +declare namespace LazyResult { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + export { LazyResult_ as default } +} + +/** + * A Promise proxy for the result of PostCSS transformations. + * + * A `LazyResult` instance is returned by `Processor#process`. + * + * ```js + * const lazy = postcss([autoprefixer]).process(css) + * ``` + */ +declare class LazyResult_ + implements PromiseLike> +{ + /** + * Processes input CSS through synchronous and asynchronous plugins + * and calls onRejected for each error thrown in any plugin. + * + * It implements standard Promise API. + * + * ```js + * postcss([autoprefixer]).process(css).then(result => { + * console.log(result.css) + * }).catch(error => { + * console.error(error) + * }) + * ``` + */ + catch: Promise>['catch'] + + /** + * Processes input CSS through synchronous and asynchronous plugins + * and calls onFinally on any error or when all plugins will finish work. + * + * It implements standard Promise API. + * + * ```js + * postcss([autoprefixer]).process(css).finally(() => { + * console.log('processing ended') + * }) + * ``` + */ + finally: Promise>['finally'] + + /** + * Processes input CSS through synchronous and asynchronous plugins + * and calls `onFulfilled` with a Result instance. If a plugin throws + * an error, the `onRejected` callback will be executed. + * + * It implements standard Promise API. + * + * ```js + * postcss([autoprefixer]).process(css, { from: cssPath }).then(result => { + * console.log(result.css) + * }) + * ``` + */ + then: Promise>['then'] + + /** + * An alias for the `css` property. Use it with syntaxes + * that generate non-CSS output. + * + * This property will only work with synchronous plugins. + * If the processor contains any asynchronous plugins + * it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get content(): string + + /** + * Processes input CSS through synchronous plugins, converts `Root` + * to a CSS string and returns `Result#css`. + * + * This property will only work with synchronous plugins. + * If the processor contains any asynchronous plugins + * it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get css(): string + + /** + * Processes input CSS through synchronous plugins + * and returns `Result#map`. + * + * This property will only work with synchronous plugins. + * If the processor contains any asynchronous plugins + * it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get map(): SourceMap + + /** + * Processes input CSS through synchronous plugins + * and returns `Result#messages`. + * + * This property will only work with synchronous plugins. If the processor + * contains any asynchronous plugins it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get messages(): Message[] + + /** + * Options from the `Processor#process` call. + */ + get opts(): ResultOptions + + /** + * Returns a `Processor` instance, which will be used + * for CSS transformations. + */ + get processor(): Processor + + /** + * Processes input CSS through synchronous plugins + * and returns `Result#root`. + * + * This property will only work with synchronous plugins. If the processor + * contains any asynchronous plugins it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get root(): RootNode + + /** + * Returns the default string description of an object. + * Required to implement the Promise interface. + */ + get [Symbol.toStringTag](): string + + /** + * @param processor Processor used for this transformation. + * @param css CSS to parse and transform. + * @param opts Options from the `Processor#process` or `Root#toResult`. + */ + constructor(processor: Processor, css: string, opts: ResultOptions) + + /** + * Run plugin in async way and return `Result`. + * + * @return Result with output content. + */ + async(): Promise> + + /** + * Run plugin in sync way and return `Result`. + * + * @return Result with output content. + */ + sync(): Result + + /** + * Alias for the `LazyResult#css` property. + * + * ```js + * lazy + '' === lazy.css + * ``` + * + * @return Output CSS. + */ + toString(): string + + /** + * Processes input CSS through synchronous plugins + * and calls `Result#warnings`. + * + * @return Warnings from plugins. + */ + warnings(): Warning[] +} + +declare class LazyResult< + RootNode = Document | Root +> extends LazyResult_ {} + +export = LazyResult diff --git a/node_modules/postcss/lib/lazy-result.js b/node_modules/postcss/lib/lazy-result.js new file mode 100644 index 0000000000..1ea52b87a7 --- /dev/null +++ b/node_modules/postcss/lib/lazy-result.js @@ -0,0 +1,550 @@ +'use strict' + +let Container = require('./container') +let Document = require('./document') +let MapGenerator = require('./map-generator') +let parse = require('./parse') +let Result = require('./result') +let Root = require('./root') +let stringify = require('./stringify') +let { isClean, my } = require('./symbols') +let warnOnce = require('./warn-once') + +const TYPE_TO_CLASS_NAME = { + atrule: 'AtRule', + comment: 'Comment', + decl: 'Declaration', + document: 'Document', + root: 'Root', + rule: 'Rule' +} + +const PLUGIN_PROPS = { + AtRule: true, + AtRuleExit: true, + Comment: true, + CommentExit: true, + Declaration: true, + DeclarationExit: true, + Document: true, + DocumentExit: true, + Once: true, + OnceExit: true, + postcssPlugin: true, + prepare: true, + Root: true, + RootExit: true, + Rule: true, + RuleExit: true +} + +const NOT_VISITORS = { + Once: true, + postcssPlugin: true, + prepare: true +} + +const CHILDREN = 0 + +function isPromise(obj) { + return typeof obj === 'object' && typeof obj.then === 'function' +} + +function getEvents(node) { + let key = false + let type = TYPE_TO_CLASS_NAME[node.type] + if (node.type === 'decl') { + key = node.prop.toLowerCase() + } else if (node.type === 'atrule') { + key = node.name.toLowerCase() + } + + if (key && node.append) { + return [ + type, + type + '-' + key, + CHILDREN, + type + 'Exit', + type + 'Exit-' + key + ] + } else if (key) { + return [type, type + '-' + key, type + 'Exit', type + 'Exit-' + key] + } else if (node.append) { + return [type, CHILDREN, type + 'Exit'] + } else { + return [type, type + 'Exit'] + } +} + +function toStack(node) { + let events + if (node.type === 'document') { + events = ['Document', CHILDREN, 'DocumentExit'] + } else if (node.type === 'root') { + events = ['Root', CHILDREN, 'RootExit'] + } else { + events = getEvents(node) + } + + return { + eventIndex: 0, + events, + iterator: 0, + node, + visitorIndex: 0, + visitors: [] + } +} + +function cleanMarks(node) { + node[isClean] = false + if (node.nodes) node.nodes.forEach(i => cleanMarks(i)) + return node +} + +let postcss = {} + +class LazyResult { + get content() { + return this.stringify().content + } + + get css() { + return this.stringify().css + } + + get map() { + return this.stringify().map + } + + get messages() { + return this.sync().messages + } + + get opts() { + return this.result.opts + } + + get processor() { + return this.result.processor + } + + get root() { + return this.sync().root + } + + get [Symbol.toStringTag]() { + return 'LazyResult' + } + + constructor(processor, css, opts) { + this.stringified = false + this.processed = false + + let root + if ( + typeof css === 'object' && + css !== null && + (css.type === 'root' || css.type === 'document') + ) { + root = cleanMarks(css) + } else if (css instanceof LazyResult || css instanceof Result) { + root = cleanMarks(css.root) + if (css.map) { + if (typeof opts.map === 'undefined') opts.map = {} + if (!opts.map.inline) opts.map.inline = false + opts.map.prev = css.map + } + } else { + let parser = parse + if (opts.syntax) parser = opts.syntax.parse + if (opts.parser) parser = opts.parser + if (parser.parse) parser = parser.parse + + try { + root = parser(css, opts) + } catch (error) { + this.processed = true + this.error = error + } + + if (root && !root[my]) { + /* c8 ignore next 2 */ + Container.rebuild(root) + } + } + + this.result = new Result(processor, root, opts) + this.helpers = { ...postcss, postcss, result: this.result } + this.plugins = this.processor.plugins.map(plugin => { + if (typeof plugin === 'object' && plugin.prepare) { + return { ...plugin, ...plugin.prepare(this.result) } + } else { + return plugin + } + }) + } + + async() { + if (this.error) return Promise.reject(this.error) + if (this.processed) return Promise.resolve(this.result) + if (!this.processing) { + this.processing = this.runAsync() + } + return this.processing + } + + catch(onRejected) { + return this.async().catch(onRejected) + } + + finally(onFinally) { + return this.async().then(onFinally, onFinally) + } + + getAsyncError() { + throw new Error('Use process(css).then(cb) to work with async plugins') + } + + handleError(error, node) { + let plugin = this.result.lastPlugin + try { + if (node) node.addToError(error) + this.error = error + if (error.name === 'CssSyntaxError' && !error.plugin) { + error.plugin = plugin.postcssPlugin + error.setMessage() + } else if (plugin.postcssVersion) { + if (process.env.NODE_ENV !== 'production') { + let pluginName = plugin.postcssPlugin + let pluginVer = plugin.postcssVersion + let runtimeVer = this.result.processor.version + let a = pluginVer.split('.') + let b = runtimeVer.split('.') + + if (a[0] !== b[0] || parseInt(a[1]) > parseInt(b[1])) { + // eslint-disable-next-line no-console + console.error( + 'Unknown error from PostCSS plugin. Your current PostCSS ' + + 'version is ' + + runtimeVer + + ', but ' + + pluginName + + ' uses ' + + pluginVer + + '. Perhaps this is the source of the error below.' + ) + } + } + } + } catch (err) { + /* c8 ignore next 3 */ + // eslint-disable-next-line no-console + if (console && console.error) console.error(err) + } + return error + } + + prepareVisitors() { + this.listeners = {} + let add = (plugin, type, cb) => { + if (!this.listeners[type]) this.listeners[type] = [] + this.listeners[type].push([plugin, cb]) + } + for (let plugin of this.plugins) { + if (typeof plugin === 'object') { + for (let event in plugin) { + if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) { + throw new Error( + `Unknown event ${event} in ${plugin.postcssPlugin}. ` + + `Try to update PostCSS (${this.processor.version} now).` + ) + } + if (!NOT_VISITORS[event]) { + if (typeof plugin[event] === 'object') { + for (let filter in plugin[event]) { + if (filter === '*') { + add(plugin, event, plugin[event][filter]) + } else { + add( + plugin, + event + '-' + filter.toLowerCase(), + plugin[event][filter] + ) + } + } + } else if (typeof plugin[event] === 'function') { + add(plugin, event, plugin[event]) + } + } + } + } + } + this.hasListener = Object.keys(this.listeners).length > 0 + } + + async runAsync() { + this.plugin = 0 + for (let i = 0; i < this.plugins.length; i++) { + let plugin = this.plugins[i] + let promise = this.runOnRoot(plugin) + if (isPromise(promise)) { + try { + await promise + } catch (error) { + throw this.handleError(error) + } + } + } + + this.prepareVisitors() + if (this.hasListener) { + let root = this.result.root + while (!root[isClean]) { + root[isClean] = true + let stack = [toStack(root)] + while (stack.length > 0) { + let promise = this.visitTick(stack) + if (isPromise(promise)) { + try { + await promise + } catch (e) { + let node = stack[stack.length - 1].node + throw this.handleError(e, node) + } + } + } + } + + if (this.listeners.OnceExit) { + for (let [plugin, visitor] of this.listeners.OnceExit) { + this.result.lastPlugin = plugin + try { + if (root.type === 'document') { + let roots = root.nodes.map(subRoot => + visitor(subRoot, this.helpers) + ) + + await Promise.all(roots) + } else { + await visitor(root, this.helpers) + } + } catch (e) { + throw this.handleError(e) + } + } + } + } + + this.processed = true + return this.stringify() + } + + runOnRoot(plugin) { + this.result.lastPlugin = plugin + try { + if (typeof plugin === 'object' && plugin.Once) { + if (this.result.root.type === 'document') { + let roots = this.result.root.nodes.map(root => + plugin.Once(root, this.helpers) + ) + + if (isPromise(roots[0])) { + return Promise.all(roots) + } + + return roots + } + + return plugin.Once(this.result.root, this.helpers) + } else if (typeof plugin === 'function') { + return plugin(this.result.root, this.result) + } + } catch (error) { + throw this.handleError(error) + } + } + + stringify() { + if (this.error) throw this.error + if (this.stringified) return this.result + this.stringified = true + + this.sync() + + let opts = this.result.opts + let str = stringify + if (opts.syntax) str = opts.syntax.stringify + if (opts.stringifier) str = opts.stringifier + if (str.stringify) str = str.stringify + + let map = new MapGenerator(str, this.result.root, this.result.opts) + let data = map.generate() + this.result.css = data[0] + this.result.map = data[1] + + return this.result + } + + sync() { + if (this.error) throw this.error + if (this.processed) return this.result + this.processed = true + + if (this.processing) { + throw this.getAsyncError() + } + + for (let plugin of this.plugins) { + let promise = this.runOnRoot(plugin) + if (isPromise(promise)) { + throw this.getAsyncError() + } + } + + this.prepareVisitors() + if (this.hasListener) { + let root = this.result.root + while (!root[isClean]) { + root[isClean] = true + this.walkSync(root) + } + if (this.listeners.OnceExit) { + if (root.type === 'document') { + for (let subRoot of root.nodes) { + this.visitSync(this.listeners.OnceExit, subRoot) + } + } else { + this.visitSync(this.listeners.OnceExit, root) + } + } + } + + return this.result + } + + then(onFulfilled, onRejected) { + if (process.env.NODE_ENV !== 'production') { + if (!('from' in this.opts)) { + warnOnce( + 'Without `from` option PostCSS could generate wrong source map ' + + 'and will not find Browserslist config. Set it to CSS file path ' + + 'or to `undefined` to prevent this warning.' + ) + } + } + return this.async().then(onFulfilled, onRejected) + } + + toString() { + return this.css + } + + visitSync(visitors, node) { + for (let [plugin, visitor] of visitors) { + this.result.lastPlugin = plugin + let promise + try { + promise = visitor(node, this.helpers) + } catch (e) { + throw this.handleError(e, node.proxyOf) + } + if (node.type !== 'root' && node.type !== 'document' && !node.parent) { + return true + } + if (isPromise(promise)) { + throw this.getAsyncError() + } + } + } + + visitTick(stack) { + let visit = stack[stack.length - 1] + let { node, visitors } = visit + + if (node.type !== 'root' && node.type !== 'document' && !node.parent) { + stack.pop() + return + } + + if (visitors.length > 0 && visit.visitorIndex < visitors.length) { + let [plugin, visitor] = visitors[visit.visitorIndex] + visit.visitorIndex += 1 + if (visit.visitorIndex === visitors.length) { + visit.visitors = [] + visit.visitorIndex = 0 + } + this.result.lastPlugin = plugin + try { + return visitor(node.toProxy(), this.helpers) + } catch (e) { + throw this.handleError(e, node) + } + } + + if (visit.iterator !== 0) { + let iterator = visit.iterator + let child + while ((child = node.nodes[node.indexes[iterator]])) { + node.indexes[iterator] += 1 + if (!child[isClean]) { + child[isClean] = true + stack.push(toStack(child)) + return + } + } + visit.iterator = 0 + delete node.indexes[iterator] + } + + let events = visit.events + while (visit.eventIndex < events.length) { + let event = events[visit.eventIndex] + visit.eventIndex += 1 + if (event === CHILDREN) { + if (node.nodes && node.nodes.length) { + node[isClean] = true + visit.iterator = node.getIterator() + } + return + } else if (this.listeners[event]) { + visit.visitors = this.listeners[event] + return + } + } + stack.pop() + } + + walkSync(node) { + node[isClean] = true + let events = getEvents(node) + for (let event of events) { + if (event === CHILDREN) { + if (node.nodes) { + node.each(child => { + if (!child[isClean]) this.walkSync(child) + }) + } + } else { + let visitors = this.listeners[event] + if (visitors) { + if (this.visitSync(visitors, node.toProxy())) return + } + } + } + } + + warnings() { + return this.sync().warnings() + } +} + +LazyResult.registerPostcss = dependant => { + postcss = dependant +} + +module.exports = LazyResult +LazyResult.default = LazyResult + +Root.registerLazyResult(LazyResult) +Document.registerLazyResult(LazyResult) diff --git a/node_modules/postcss/lib/list.d.ts b/node_modules/postcss/lib/list.d.ts new file mode 100644 index 0000000000..e262ad3ff6 --- /dev/null +++ b/node_modules/postcss/lib/list.d.ts @@ -0,0 +1,60 @@ +declare namespace list { + type List = { + /** + * Safely splits comma-separated values (such as those for `transition-*` + * and `background` properties). + * + * ```js + * Once (root, { list }) { + * list.comma('black, linear-gradient(white, black)') + * //=> ['black', 'linear-gradient(white, black)'] + * } + * ``` + * + * @param str Comma-separated values. + * @return Split values. + */ + comma(str: string): string[] + + default: List + + /** + * Safely splits space-separated values (such as those for `background`, + * `border-radius`, and other shorthand properties). + * + * ```js + * Once (root, { list }) { + * list.space('1px calc(10% + 1px)') //=> ['1px', 'calc(10% + 1px)'] + * } + * ``` + * + * @param str Space-separated values. + * @return Split values. + */ + space(str: string): string[] + + /** + * Safely splits values. + * + * ```js + * Once (root, { list }) { + * list.split('1px calc(10% + 1px)', [' ', '\n', '\t']) //=> ['1px', 'calc(10% + 1px)'] + * } + * ``` + * + * @param string separated values. + * @param separators array of separators. + * @param last boolean indicator. + * @return Split values. + */ + split( + string: string, + separators: readonly string[], + last: boolean + ): string[] + } +} + +declare const list: list.List + +export = list diff --git a/node_modules/postcss/lib/list.js b/node_modules/postcss/lib/list.js new file mode 100644 index 0000000000..1b31f9809f --- /dev/null +++ b/node_modules/postcss/lib/list.js @@ -0,0 +1,58 @@ +'use strict' + +let list = { + comma(string) { + return list.split(string, [','], true) + }, + + space(string) { + let spaces = [' ', '\n', '\t'] + return list.split(string, spaces) + }, + + split(string, separators, last) { + let array = [] + let current = '' + let split = false + + let func = 0 + let inQuote = false + let prevQuote = '' + let escape = false + + for (let letter of string) { + if (escape) { + escape = false + } else if (letter === '\\') { + escape = true + } else if (inQuote) { + if (letter === prevQuote) { + inQuote = false + } + } else if (letter === '"' || letter === "'") { + inQuote = true + prevQuote = letter + } else if (letter === '(') { + func += 1 + } else if (letter === ')') { + if (func > 0) func -= 1 + } else if (func === 0) { + if (separators.includes(letter)) split = true + } + + if (split) { + if (current !== '') array.push(current.trim()) + current = '' + split = false + } else { + current += letter + } + } + + if (last || current !== '') array.push(current.trim()) + return array + } +} + +module.exports = list +list.default = list diff --git a/node_modules/postcss/lib/map-generator.js b/node_modules/postcss/lib/map-generator.js new file mode 100644 index 0000000000..89069d3e40 --- /dev/null +++ b/node_modules/postcss/lib/map-generator.js @@ -0,0 +1,368 @@ +'use strict' + +let { dirname, relative, resolve, sep } = require('path') +let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') +let { pathToFileURL } = require('url') + +let Input = require('./input') + +let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) +let pathAvailable = Boolean(dirname && resolve && relative && sep) + +class MapGenerator { + constructor(stringify, root, opts, cssString) { + this.stringify = stringify + this.mapOpts = opts.map || {} + this.root = root + this.opts = opts + this.css = cssString + this.originalCSS = cssString + this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute + + this.memoizedFileURLs = new Map() + this.memoizedPaths = new Map() + this.memoizedURLs = new Map() + } + + addAnnotation() { + let content + + if (this.isInline()) { + content = + 'data:application/json;base64,' + this.toBase64(this.map.toString()) + } else if (typeof this.mapOpts.annotation === 'string') { + content = this.mapOpts.annotation + } else if (typeof this.mapOpts.annotation === 'function') { + content = this.mapOpts.annotation(this.opts.to, this.root) + } else { + content = this.outputFile() + '.map' + } + let eol = '\n' + if (this.css.includes('\r\n')) eol = '\r\n' + + this.css += eol + '/*# sourceMappingURL=' + content + ' */' + } + + applyPrevMaps() { + for (let prev of this.previous()) { + let from = this.toUrl(this.path(prev.file)) + let root = prev.root || dirname(prev.file) + let map + + if (this.mapOpts.sourcesContent === false) { + map = new SourceMapConsumer(prev.text) + if (map.sourcesContent) { + map.sourcesContent = null + } + } else { + map = prev.consumer() + } + + this.map.applySourceMap(map, from, this.toUrl(this.path(root))) + } + } + + clearAnnotation() { + if (this.mapOpts.annotation === false) return + + if (this.root) { + let node + for (let i = this.root.nodes.length - 1; i >= 0; i--) { + node = this.root.nodes[i] + if (node.type !== 'comment') continue + if (node.text.startsWith('# sourceMappingURL=')) { + this.root.removeChild(i) + } + } + } else if (this.css) { + this.css = this.css.replace(/\n*\/\*#[\S\s]*?\*\/$/gm, '') + } + } + + generate() { + this.clearAnnotation() + if (pathAvailable && sourceMapAvailable && this.isMap()) { + return this.generateMap() + } else { + let result = '' + this.stringify(this.root, i => { + result += i + }) + return [result] + } + } + + generateMap() { + if (this.root) { + this.generateString() + } else if (this.previous().length === 1) { + let prev = this.previous()[0].consumer() + prev.file = this.outputFile() + this.map = SourceMapGenerator.fromSourceMap(prev, { + ignoreInvalidMapping: true + }) + } else { + this.map = new SourceMapGenerator({ + file: this.outputFile(), + ignoreInvalidMapping: true + }) + this.map.addMapping({ + generated: { column: 0, line: 1 }, + original: { column: 0, line: 1 }, + source: this.opts.from + ? this.toUrl(this.path(this.opts.from)) + : '' + }) + } + + if (this.isSourcesContent()) this.setSourcesContent() + if (this.root && this.previous().length > 0) this.applyPrevMaps() + if (this.isAnnotation()) this.addAnnotation() + + if (this.isInline()) { + return [this.css] + } else { + return [this.css, this.map] + } + } + + generateString() { + this.css = '' + this.map = new SourceMapGenerator({ + file: this.outputFile(), + ignoreInvalidMapping: true + }) + + let line = 1 + let column = 1 + + let noSource = '' + let mapping = { + generated: { column: 0, line: 0 }, + original: { column: 0, line: 0 }, + source: '' + } + + let last, lines + this.stringify(this.root, (str, node, type) => { + this.css += str + + if (node && type !== 'end') { + mapping.generated.line = line + mapping.generated.column = column - 1 + if (node.source && node.source.start) { + mapping.source = this.sourcePath(node) + mapping.original.line = node.source.start.line + mapping.original.column = node.source.start.column - 1 + this.map.addMapping(mapping) + } else { + mapping.source = noSource + mapping.original.line = 1 + mapping.original.column = 0 + this.map.addMapping(mapping) + } + } + + lines = str.match(/\n/g) + if (lines) { + line += lines.length + last = str.lastIndexOf('\n') + column = str.length - last + } else { + column += str.length + } + + if (node && type !== 'start') { + let p = node.parent || { raws: {} } + let childless = + node.type === 'decl' || (node.type === 'atrule' && !node.nodes) + if (!childless || node !== p.last || p.raws.semicolon) { + if (node.source && node.source.end) { + mapping.source = this.sourcePath(node) + mapping.original.line = node.source.end.line + mapping.original.column = node.source.end.column - 1 + mapping.generated.line = line + mapping.generated.column = column - 2 + this.map.addMapping(mapping) + } else { + mapping.source = noSource + mapping.original.line = 1 + mapping.original.column = 0 + mapping.generated.line = line + mapping.generated.column = column - 1 + this.map.addMapping(mapping) + } + } + } + }) + } + + isAnnotation() { + if (this.isInline()) { + return true + } + if (typeof this.mapOpts.annotation !== 'undefined') { + return this.mapOpts.annotation + } + if (this.previous().length) { + return this.previous().some(i => i.annotation) + } + return true + } + + isInline() { + if (typeof this.mapOpts.inline !== 'undefined') { + return this.mapOpts.inline + } + + let annotation = this.mapOpts.annotation + if (typeof annotation !== 'undefined' && annotation !== true) { + return false + } + + if (this.previous().length) { + return this.previous().some(i => i.inline) + } + return true + } + + isMap() { + if (typeof this.opts.map !== 'undefined') { + return !!this.opts.map + } + return this.previous().length > 0 + } + + isSourcesContent() { + if (typeof this.mapOpts.sourcesContent !== 'undefined') { + return this.mapOpts.sourcesContent + } + if (this.previous().length) { + return this.previous().some(i => i.withContent()) + } + return true + } + + outputFile() { + if (this.opts.to) { + return this.path(this.opts.to) + } else if (this.opts.from) { + return this.path(this.opts.from) + } else { + return 'to.css' + } + } + + path(file) { + if (this.mapOpts.absolute) return file + if (file.charCodeAt(0) === 60 /* `<` */) return file + if (/^\w+:\/\//.test(file)) return file + let cached = this.memoizedPaths.get(file) + if (cached) return cached + + let from = this.opts.to ? dirname(this.opts.to) : '.' + + if (typeof this.mapOpts.annotation === 'string') { + from = dirname(resolve(from, this.mapOpts.annotation)) + } + + let path = relative(from, file) + this.memoizedPaths.set(file, path) + + return path + } + + previous() { + if (!this.previousMaps) { + this.previousMaps = [] + if (this.root) { + this.root.walk(node => { + if (node.source && node.source.input.map) { + let map = node.source.input.map + if (!this.previousMaps.includes(map)) { + this.previousMaps.push(map) + } + } + }) + } else { + let input = new Input(this.originalCSS, this.opts) + if (input.map) this.previousMaps.push(input.map) + } + } + + return this.previousMaps + } + + setSourcesContent() { + let already = {} + if (this.root) { + this.root.walk(node => { + if (node.source) { + let from = node.source.input.from + if (from && !already[from]) { + already[from] = true + let fromUrl = this.usesFileUrls + ? this.toFileUrl(from) + : this.toUrl(this.path(from)) + this.map.setSourceContent(fromUrl, node.source.input.css) + } + } + }) + } else if (this.css) { + let from = this.opts.from + ? this.toUrl(this.path(this.opts.from)) + : '' + this.map.setSourceContent(from, this.css) + } + } + + sourcePath(node) { + if (this.mapOpts.from) { + return this.toUrl(this.mapOpts.from) + } else if (this.usesFileUrls) { + return this.toFileUrl(node.source.input.from) + } else { + return this.toUrl(this.path(node.source.input.from)) + } + } + + toBase64(str) { + if (Buffer) { + return Buffer.from(str).toString('base64') + } else { + return window.btoa(unescape(encodeURIComponent(str))) + } + } + + toFileUrl(path) { + let cached = this.memoizedFileURLs.get(path) + if (cached) return cached + + if (pathToFileURL) { + let fileURL = pathToFileURL(path).toString() + this.memoizedFileURLs.set(path, fileURL) + + return fileURL + } else { + throw new Error( + '`map.absolute` option is not available in this PostCSS build' + ) + } + } + + toUrl(path) { + let cached = this.memoizedURLs.get(path) + if (cached) return cached + + if (sep === '\\') { + path = path.replace(/\\/g, '/') + } + + let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent) + this.memoizedURLs.set(path, url) + + return url + } +} + +module.exports = MapGenerator diff --git a/node_modules/postcss/lib/no-work-result.d.ts b/node_modules/postcss/lib/no-work-result.d.ts new file mode 100644 index 0000000000..094f30ab46 --- /dev/null +++ b/node_modules/postcss/lib/no-work-result.d.ts @@ -0,0 +1,46 @@ +import LazyResult from './lazy-result.js' +import { SourceMap } from './postcss.js' +import Processor from './processor.js' +import Result, { Message, ResultOptions } from './result.js' +import Root from './root.js' +import Warning from './warning.js' + +declare namespace NoWorkResult { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + export { NoWorkResult_ as default } +} + +/** + * A Promise proxy for the result of PostCSS transformations. + * This lazy result instance doesn't parse css unless `NoWorkResult#root` or `Result#root` + * are accessed. See the example below for details. + * A `NoWork` instance is returned by `Processor#process` ONLY when no plugins defined. + * + * ```js + * const noWorkResult = postcss().process(css) // No plugins are defined. + * // CSS is not parsed + * let root = noWorkResult.root // now css is parsed because we accessed the root + * ``` + */ +declare class NoWorkResult_ implements LazyResult { + catch: Promise>['catch'] + finally: Promise>['finally'] + then: Promise>['then'] + get content(): string + get css(): string + get map(): SourceMap + get messages(): Message[] + get opts(): ResultOptions + get processor(): Processor + get root(): Root + get [Symbol.toStringTag](): string + constructor(processor: Processor, css: string, opts: ResultOptions) + async(): Promise> + sync(): Result + toString(): string + warnings(): Warning[] +} + +declare class NoWorkResult extends NoWorkResult_ {} + +export = NoWorkResult diff --git a/node_modules/postcss/lib/no-work-result.js b/node_modules/postcss/lib/no-work-result.js new file mode 100644 index 0000000000..dd46182d4e --- /dev/null +++ b/node_modules/postcss/lib/no-work-result.js @@ -0,0 +1,138 @@ +'use strict' + +let MapGenerator = require('./map-generator') +let parse = require('./parse') +const Result = require('./result') +let stringify = require('./stringify') +let warnOnce = require('./warn-once') + +class NoWorkResult { + get content() { + return this.result.css + } + + get css() { + return this.result.css + } + + get map() { + return this.result.map + } + + get messages() { + return [] + } + + get opts() { + return this.result.opts + } + + get processor() { + return this.result.processor + } + + get root() { + if (this._root) { + return this._root + } + + let root + let parser = parse + + try { + root = parser(this._css, this._opts) + } catch (error) { + this.error = error + } + + if (this.error) { + throw this.error + } else { + this._root = root + return root + } + } + + get [Symbol.toStringTag]() { + return 'NoWorkResult' + } + + constructor(processor, css, opts) { + css = css.toString() + this.stringified = false + + this._processor = processor + this._css = css + this._opts = opts + this._map = undefined + let root + + let str = stringify + this.result = new Result(this._processor, root, this._opts) + this.result.css = css + + let self = this + Object.defineProperty(this.result, 'root', { + get() { + return self.root + } + }) + + let map = new MapGenerator(str, root, this._opts, css) + if (map.isMap()) { + let [generatedCSS, generatedMap] = map.generate() + if (generatedCSS) { + this.result.css = generatedCSS + } + if (generatedMap) { + this.result.map = generatedMap + } + } else { + map.clearAnnotation() + this.result.css = map.css + } + } + + async() { + if (this.error) return Promise.reject(this.error) + return Promise.resolve(this.result) + } + + catch(onRejected) { + return this.async().catch(onRejected) + } + + finally(onFinally) { + return this.async().then(onFinally, onFinally) + } + + sync() { + if (this.error) throw this.error + return this.result + } + + then(onFulfilled, onRejected) { + if (process.env.NODE_ENV !== 'production') { + if (!('from' in this._opts)) { + warnOnce( + 'Without `from` option PostCSS could generate wrong source map ' + + 'and will not find Browserslist config. Set it to CSS file path ' + + 'or to `undefined` to prevent this warning.' + ) + } + } + + return this.async().then(onFulfilled, onRejected) + } + + toString() { + return this._css + } + + warnings() { + return [] + } +} + +module.exports = NoWorkResult +NoWorkResult.default = NoWorkResult diff --git a/node_modules/postcss/lib/node.d.ts b/node_modules/postcss/lib/node.d.ts new file mode 100644 index 0000000000..a09fe4dda2 --- /dev/null +++ b/node_modules/postcss/lib/node.d.ts @@ -0,0 +1,556 @@ +import AtRule = require('./at-rule.js') +import { AtRuleProps } from './at-rule.js' +import Comment, { CommentProps } from './comment.js' +import Container, { NewChild } from './container.js' +import CssSyntaxError from './css-syntax-error.js' +import Declaration, { DeclarationProps } from './declaration.js' +import Document from './document.js' +import Input from './input.js' +import { Stringifier, Syntax } from './postcss.js' +import Result from './result.js' +import Root from './root.js' +import Rule, { RuleProps } from './rule.js' +import Warning, { WarningOptions } from './warning.js' + +declare namespace Node { + export type ChildNode = AtRule.default | Comment | Declaration | Rule + + export type AnyNode = + | AtRule.default + | Comment + | Declaration + | Document + | Root + | Rule + + export type ChildProps = + | AtRuleProps + | CommentProps + | DeclarationProps + | RuleProps + + export interface Position { + /** + * Source line in file. In contrast to `offset` it starts from 1. + */ + column: number + + /** + * Source column in file. + */ + line: number + + /** + * Source offset in file. It starts from 0. + */ + offset: number + } + + export interface Range { + /** + * End position, exclusive. + */ + end: Position + + /** + * Start position, inclusive. + */ + start: Position + } + + /** + * Source represents an interface for the {@link Node.source} property. + */ + export interface Source { + /** + * The inclusive ending position for the source + * code of a node. + * + * However, `end.offset` of a non `Root` node is the exclusive position. + * See https://github.com/postcss/postcss/pull/1879 for details. + * + * ```js + * const root = postcss.parse('a { color: black }') + * const a = root.first + * const color = a.first + * + * // The offset of `Root` node is the inclusive position + * css.source.end // { line: 1, column: 19, offset: 18 } + * + * // The offset of non `Root` node is the exclusive position + * a.source.end // { line: 1, column: 18, offset: 18 } + * color.source.end // { line: 1, column: 16, offset: 16 } + * ``` + */ + end?: Position + + /** + * The source file from where a node has originated. + */ + input: Input + + /** + * The inclusive starting position for the source + * code of a node. + */ + start?: Position + } + + /** + * Interface represents an interface for an object received + * as parameter by Node class constructor. + */ + export interface NodeProps { + source?: Source + } + + export interface NodeErrorOptions { + /** + * An ending index inside a node's string that should be highlighted as + * source of error. + */ + endIndex?: number + /** + * An index inside a node's string that should be highlighted as source + * of error. + */ + index?: number + /** + * Plugin name that created this error. PostCSS will set it automatically. + */ + plugin?: string + /** + * A word inside a node's string, that should be highlighted as source + * of error. + */ + word?: string + } + + // eslint-disable-next-line @typescript-eslint/no-shadow + class Node extends Node_ {} + export { Node as default } +} + +/** + * It represents an abstract class that handles common + * methods for other CSS abstract syntax tree nodes. + * + * Any node that represents CSS selector or value should + * not extend the `Node` class. + */ +declare abstract class Node_ { + /** + * It represents parent of the current node. + * + * ```js + * root.nodes[0].parent === root //=> true + * ``` + */ + parent: Container | Document | undefined + + /** + * It represents unnecessary whitespace and characters present + * in the css source code. + * + * Information to generate byte-to-byte equal node string as it was + * in the origin input. + * + * The properties of the raws object are decided by parser, + * the default parser uses the following properties: + * + * * `before`: the space symbols before the node. It also stores `*` + * and `_` symbols before the declaration (IE hack). + * * `after`: the space symbols after the last child of the node + * to the end of the node. + * * `between`: the symbols between the property and value + * for declarations, selector and `{` for rules, or last parameter + * and `{` for at-rules. + * * `semicolon`: contains true if the last child has + * an (optional) semicolon. + * * `afterName`: the space between the at-rule name and its parameters. + * * `left`: the space symbols between `/*` and the comment’s text. + * * `right`: the space symbols between the comment’s text + * and */. + * - `important`: the content of the important statement, + * if it is not just `!important`. + * + * PostCSS filters out the comments inside selectors, declaration values + * and at-rule parameters but it stores the origin content in raws. + * + * ```js + * const root = postcss.parse('a {\n color:black\n}') + * root.first.first.raws //=> { before: '\n ', between: ':' } + * ``` + */ + raws: any + + /** + * It represents information related to origin of a node and is required + * for generating source maps. + * + * The nodes that are created manually using the public APIs + * provided by PostCSS will have `source` undefined and + * will be absent in the source map. + * + * For this reason, the plugin developer should consider + * duplicating nodes as the duplicate node will have the + * same source as the original node by default or assign + * source to a node created manually. + * + * ```js + * decl.source.input.from //=> '/home/ai/source.css' + * decl.source.start //=> { line: 10, column: 2 } + * decl.source.end //=> { line: 10, column: 12 } + * ``` + * + * ```js + * // Incorrect method, source not specified! + * const prefixed = postcss.decl({ + * prop: '-moz-' + decl.prop, + * value: decl.value + * }) + * + * // Correct method, source is inherited when duplicating. + * const prefixed = decl.clone({ + * prop: '-moz-' + decl.prop + * }) + * ``` + * + * ```js + * if (atrule.name === 'add-link') { + * const rule = postcss.rule({ + * selector: 'a', + * source: atrule.source + * }) + * + * atrule.parent.insertBefore(atrule, rule) + * } + * ``` + */ + source?: Node.Source + + /** + * It represents type of a node in + * an abstract syntax tree. + * + * A type of node helps in identification of a node + * and perform operation based on it's type. + * + * ```js + * const declaration = new Declaration({ + * prop: 'color', + * value: 'black' + * }) + * + * declaration.type //=> 'decl' + * ``` + */ + type: string + + constructor(defaults?: object) + + /** + * Insert new node after current node to current node’s parent. + * + * Just alias for `node.parent.insertAfter(node, add)`. + * + * ```js + * decl.after('color: black') + * ``` + * + * @param newNode New node. + * @return This node for methods chain. + */ + after( + newNode: Node | Node.ChildProps | readonly Node[] | string | undefined + ): this + + /** + * It assigns properties to an existing node instance. + * + * ```js + * decl.assign({ prop: 'word-wrap', value: 'break-word' }) + * ``` + * + * @param overrides New properties to override the node. + * + * @return `this` for method chaining. + */ + assign(overrides: object): this + + /** + * Insert new node before current node to current node’s parent. + * + * Just alias for `node.parent.insertBefore(node, add)`. + * + * ```js + * decl.before('content: ""') + * ``` + * + * @param newNode New node. + * @return This node for methods chain. + */ + before( + newNode: Node | Node.ChildProps | readonly Node[] | string | undefined + ): this + + /** + * Clear the code style properties for the node and its children. + * + * ```js + * node.raws.before //=> ' ' + * node.cleanRaws() + * node.raws.before //=> undefined + * ``` + * + * @param keepBetween Keep the `raws.between` symbols. + */ + cleanRaws(keepBetween?: boolean): void + + /** + * It creates clone of an existing node, which includes all the properties + * and their values, that includes `raws` but not `type`. + * + * ```js + * decl.raws.before //=> "\n " + * const cloned = decl.clone({ prop: '-moz-' + decl.prop }) + * cloned.raws.before //=> "\n " + * cloned.toString() //=> -moz-transform: scale(0) + * ``` + * + * @param overrides New properties to override in the clone. + * + * @return Duplicate of the node instance. + */ + clone(overrides?: object): this + + /** + * Shortcut to clone the node and insert the resulting cloned node + * after the current node. + * + * @param overrides New properties to override in the clone. + * @return New node. + */ + cloneAfter(overrides?: object): this + + /** + * Shortcut to clone the node and insert the resulting cloned node + * before the current node. + * + * ```js + * decl.cloneBefore({ prop: '-moz-' + decl.prop }) + * ``` + * + * @param overrides Mew properties to override in the clone. + * + * @return New node + */ + cloneBefore(overrides?: object): this + + /** + * It creates an instance of the class `CssSyntaxError` and parameters passed + * to this method are assigned to the error instance. + * + * The error instance will have description for the + * error, original position of the node in the + * source, showing line and column number. + * + * If any previous map is present, it would be used + * to get original position of the source. + * + * The Previous Map here is referred to the source map + * generated by previous compilation, example: Less, + * Stylus and Sass. + * + * This method returns the error instance instead of + * throwing it. + * + * ```js + * if (!variables[name]) { + * throw decl.error(`Unknown variable ${name}`, { word: name }) + * // CssSyntaxError: postcss-vars:a.sass:4:3: Unknown variable $black + * // color: $black + * // a + * // ^ + * // background: white + * } + * ``` + * + * @param message Description for the error instance. + * @param options Options for the error instance. + * + * @return Error instance is returned. + */ + error(message: string, options?: Node.NodeErrorOptions): CssSyntaxError + + /** + * Returns the next child of the node’s parent. + * Returns `undefined` if the current node is the last child. + * + * ```js + * if (comment.text === 'delete next') { + * const next = comment.next() + * if (next) { + * next.remove() + * } + * } + * ``` + * + * @return Next node. + */ + next(): Node.ChildNode | undefined + + /** + * Get the position for a word or an index inside the node. + * + * @param opts Options. + * @return Position. + */ + positionBy(opts?: Pick): Node.Position + + /** + * Convert string index to line/column. + * + * @param index The symbol number in the node’s string. + * @return Symbol position in file. + */ + positionInside(index: number): Node.Position + + /** + * Returns the previous child of the node’s parent. + * Returns `undefined` if the current node is the first child. + * + * ```js + * const annotation = decl.prev() + * if (annotation.type === 'comment') { + * readAnnotation(annotation.text) + * } + * ``` + * + * @return Previous node. + */ + prev(): Node.ChildNode | undefined + + /** + * Get the range for a word or start and end index inside the node. + * The start index is inclusive; the end index is exclusive. + * + * @param opts Options. + * @return Range. + */ + rangeBy( + opts?: Pick + ): Node.Range + + /** + * Returns a `raws` value. If the node is missing + * the code style property (because the node was manually built or cloned), + * PostCSS will try to autodetect the code style property by looking + * at other nodes in the tree. + * + * ```js + * const root = postcss.parse('a { background: white }') + * root.nodes[0].append({ prop: 'color', value: 'black' }) + * root.nodes[0].nodes[1].raws.before //=> undefined + * root.nodes[0].nodes[1].raw('before') //=> ' ' + * ``` + * + * @param prop Name of code style property. + * @param defaultType Name of default value, it can be missed + * if the value is the same as prop. + * @return {string} Code style value. + */ + raw(prop: string, defaultType?: string): string + + /** + * It removes the node from its parent and deletes its parent property. + * + * ```js + * if (decl.prop.match(/^-webkit-/)) { + * decl.remove() + * } + * ``` + * + * @return `this` for method chaining. + */ + remove(): this + + /** + * Inserts node(s) before the current node and removes the current node. + * + * ```js + * AtRule: { + * mixin: atrule => { + * atrule.replaceWith(mixinRules[atrule.params]) + * } + * } + * ``` + * + * @param nodes Mode(s) to replace current one. + * @return Current node to methods chain. + */ + replaceWith(...nodes: NewChild[]): this + + /** + * Finds the Root instance of the node’s tree. + * + * ```js + * root.nodes[0].nodes[0].root() === root + * ``` + * + * @return Root parent. + */ + root(): Root + + /** + * Fix circular links on `JSON.stringify()`. + * + * @return Cleaned object. + */ + toJSON(): object + + /** + * It compiles the node to browser readable cascading style sheets string + * depending on it's type. + * + * ```js + * new Rule({ selector: 'a' }).toString() //=> "a {}" + * ``` + * + * @param stringifier A syntax to use in string generation. + * @return CSS string of this node. + */ + toString(stringifier?: Stringifier | Syntax): string + + /** + * It is a wrapper for {@link Result#warn}, providing convenient + * way of generating warnings. + * + * ```js + * Declaration: { + * bad: (decl, { result }) => { + * decl.warn(result, 'Deprecated property: bad') + * } + * } + * ``` + * + * @param result The `Result` instance that will receive the warning. + * @param message Description for the warning. + * @param options Options for the warning. + * + * @return `Warning` instance is returned + */ + warn(result: Result, message: string, options?: WarningOptions): Warning + + /** + * If this node isn't already dirty, marks it and its ancestors as such. This + * indicates to the LazyResult processor that the {@link Root} has been + * modified by the current plugin and may need to be processed again by other + * plugins. + */ + protected markDirty(): void +} + +declare class Node extends Node_ {} + +export = Node diff --git a/node_modules/postcss/lib/node.js b/node_modules/postcss/lib/node.js new file mode 100644 index 0000000000..b403b7136b --- /dev/null +++ b/node_modules/postcss/lib/node.js @@ -0,0 +1,449 @@ +'use strict' + +let CssSyntaxError = require('./css-syntax-error') +let Stringifier = require('./stringifier') +let stringify = require('./stringify') +let { isClean, my } = require('./symbols') + +function cloneNode(obj, parent) { + let cloned = new obj.constructor() + + for (let i in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, i)) { + /* c8 ignore next 2 */ + continue + } + if (i === 'proxyCache') continue + let value = obj[i] + let type = typeof value + + if (i === 'parent' && type === 'object') { + if (parent) cloned[i] = parent + } else if (i === 'source') { + cloned[i] = value + } else if (Array.isArray(value)) { + cloned[i] = value.map(j => cloneNode(j, cloned)) + } else { + if (type === 'object' && value !== null) value = cloneNode(value) + cloned[i] = value + } + } + + return cloned +} + +function sourceOffset(inputCSS, position) { + // Not all custom syntaxes support `offset` in `source.start` and `source.end` + if (position && typeof position.offset !== 'undefined') { + return position.offset + } + + let column = 1 + let line = 1 + let offset = 0 + + for (let i = 0; i < inputCSS.length; i++) { + if (line === position.line && column === position.column) { + offset = i + break + } + + if (inputCSS[i] === '\n') { + column = 1 + line += 1 + } else { + column += 1 + } + } + + return offset +} + +class Node { + get proxyOf() { + return this + } + + constructor(defaults = {}) { + this.raws = {} + this[isClean] = false + this[my] = true + + for (let name in defaults) { + if (name === 'nodes') { + this.nodes = [] + for (let node of defaults[name]) { + if (typeof node.clone === 'function') { + this.append(node.clone()) + } else { + this.append(node) + } + } + } else { + this[name] = defaults[name] + } + } + } + + addToError(error) { + error.postcssNode = this + if (error.stack && this.source && /\n\s{4}at /.test(error.stack)) { + let s = this.source + error.stack = error.stack.replace( + /\n\s{4}at /, + `$&${s.input.from}:${s.start.line}:${s.start.column}$&` + ) + } + return error + } + + after(add) { + this.parent.insertAfter(this, add) + return this + } + + assign(overrides = {}) { + for (let name in overrides) { + this[name] = overrides[name] + } + return this + } + + before(add) { + this.parent.insertBefore(this, add) + return this + } + + cleanRaws(keepBetween) { + delete this.raws.before + delete this.raws.after + if (!keepBetween) delete this.raws.between + } + + clone(overrides = {}) { + let cloned = cloneNode(this) + for (let name in overrides) { + cloned[name] = overrides[name] + } + return cloned + } + + cloneAfter(overrides = {}) { + let cloned = this.clone(overrides) + this.parent.insertAfter(this, cloned) + return cloned + } + + cloneBefore(overrides = {}) { + let cloned = this.clone(overrides) + this.parent.insertBefore(this, cloned) + return cloned + } + + error(message, opts = {}) { + if (this.source) { + let { end, start } = this.rangeBy(opts) + return this.source.input.error( + message, + { column: start.column, line: start.line }, + { column: end.column, line: end.line }, + opts + ) + } + return new CssSyntaxError(message) + } + + getProxyProcessor() { + return { + get(node, prop) { + if (prop === 'proxyOf') { + return node + } else if (prop === 'root') { + return () => node.root().toProxy() + } else { + return node[prop] + } + }, + + set(node, prop, value) { + if (node[prop] === value) return true + node[prop] = value + if ( + prop === 'prop' || + prop === 'value' || + prop === 'name' || + prop === 'params' || + prop === 'important' || + /* c8 ignore next */ + prop === 'text' + ) { + node.markDirty() + } + return true + } + } + } + + /* c8 ignore next 3 */ + markClean() { + this[isClean] = true + } + + markDirty() { + if (this[isClean]) { + this[isClean] = false + let next = this + while ((next = next.parent)) { + next[isClean] = false + } + } + } + + next() { + if (!this.parent) return undefined + let index = this.parent.index(this) + return this.parent.nodes[index + 1] + } + + positionBy(opts = {}) { + let pos = this.source.start + if (opts.index) { + pos = this.positionInside(opts.index) + } else if (opts.word) { + let inputString = + 'document' in this.source.input + ? this.source.input.document + : this.source.input.css + let stringRepresentation = inputString.slice( + sourceOffset(inputString, this.source.start), + sourceOffset(inputString, this.source.end) + ) + let index = stringRepresentation.indexOf(opts.word) + if (index !== -1) pos = this.positionInside(index) + } + return pos + } + + positionInside(index) { + let column = this.source.start.column + let line = this.source.start.line + let inputString = + 'document' in this.source.input + ? this.source.input.document + : this.source.input.css + let offset = sourceOffset(inputString, this.source.start) + let end = offset + index + + for (let i = offset; i < end; i++) { + if (inputString[i] === '\n') { + column = 1 + line += 1 + } else { + column += 1 + } + } + + return { column, line, offset: end } + } + + prev() { + if (!this.parent) return undefined + let index = this.parent.index(this) + return this.parent.nodes[index - 1] + } + + rangeBy(opts = {}) { + let inputString = + 'document' in this.source.input + ? this.source.input.document + : this.source.input.css + let start = { + column: this.source.start.column, + line: this.source.start.line, + offset: sourceOffset(inputString, this.source.start) + } + let end = this.source.end + ? { + column: this.source.end.column + 1, + line: this.source.end.line, + offset: + typeof this.source.end.offset === 'number' + ? // `source.end.offset` is exclusive, so we don't need to add 1 + this.source.end.offset + : // Since line/column in this.source.end is inclusive, + // the `sourceOffset(... , this.source.end)` returns an inclusive offset. + // So, we add 1 to convert it to exclusive. + sourceOffset(inputString, this.source.end) + 1 + } + : { + column: start.column + 1, + line: start.line, + offset: start.offset + 1 + } + + if (opts.word) { + let stringRepresentation = inputString.slice( + sourceOffset(inputString, this.source.start), + sourceOffset(inputString, this.source.end) + ) + let index = stringRepresentation.indexOf(opts.word) + if (index !== -1) { + start = this.positionInside(index) + end = this.positionInside(index + opts.word.length) + } + } else { + if (opts.start) { + start = { + column: opts.start.column, + line: opts.start.line, + offset: sourceOffset(inputString, opts.start) + } + } else if (opts.index) { + start = this.positionInside(opts.index) + } + + if (opts.end) { + end = { + column: opts.end.column, + line: opts.end.line, + offset: sourceOffset(inputString, opts.end) + } + } else if (typeof opts.endIndex === 'number') { + end = this.positionInside(opts.endIndex) + } else if (opts.index) { + end = this.positionInside(opts.index + 1) + } + } + + if ( + end.line < start.line || + (end.line === start.line && end.column <= start.column) + ) { + end = { + column: start.column + 1, + line: start.line, + offset: start.offset + 1 + } + } + + return { end, start } + } + + raw(prop, defaultType) { + let str = new Stringifier() + return str.raw(this, prop, defaultType) + } + + remove() { + if (this.parent) { + this.parent.removeChild(this) + } + this.parent = undefined + return this + } + + replaceWith(...nodes) { + if (this.parent) { + let bookmark = this + let foundSelf = false + for (let node of nodes) { + if (node === this) { + foundSelf = true + } else if (foundSelf) { + this.parent.insertAfter(bookmark, node) + bookmark = node + } else { + this.parent.insertBefore(bookmark, node) + } + } + + if (!foundSelf) { + this.remove() + } + } + + return this + } + + root() { + let result = this + while (result.parent && result.parent.type !== 'document') { + result = result.parent + } + return result + } + + toJSON(_, inputs) { + let fixed = {} + let emitInputs = inputs == null + inputs = inputs || new Map() + let inputsNextIndex = 0 + + for (let name in this) { + if (!Object.prototype.hasOwnProperty.call(this, name)) { + /* c8 ignore next 2 */ + continue + } + if (name === 'parent' || name === 'proxyCache') continue + let value = this[name] + + if (Array.isArray(value)) { + fixed[name] = value.map(i => { + if (typeof i === 'object' && i.toJSON) { + return i.toJSON(null, inputs) + } else { + return i + } + }) + } else if (typeof value === 'object' && value.toJSON) { + fixed[name] = value.toJSON(null, inputs) + } else if (name === 'source') { + if (value == null) continue + let inputId = inputs.get(value.input) + if (inputId == null) { + inputId = inputsNextIndex + inputs.set(value.input, inputsNextIndex) + inputsNextIndex++ + } + fixed[name] = { + end: value.end, + inputId, + start: value.start + } + } else { + fixed[name] = value + } + } + + if (emitInputs) { + fixed.inputs = [...inputs.keys()].map(input => input.toJSON()) + } + + return fixed + } + + toProxy() { + if (!this.proxyCache) { + this.proxyCache = new Proxy(this, this.getProxyProcessor()) + } + return this.proxyCache + } + + toString(stringifier = stringify) { + if (stringifier.stringify) stringifier = stringifier.stringify + let result = '' + stringifier(this, i => { + result += i + }) + return result + } + + warn(result, text, opts = {}) { + let data = { node: this } + for (let i in opts) data[i] = opts[i] + return result.warn(text, data) + } +} + +module.exports = Node +Node.default = Node diff --git a/node_modules/postcss/lib/parse.d.ts b/node_modules/postcss/lib/parse.d.ts new file mode 100644 index 0000000000..4c943a4d62 --- /dev/null +++ b/node_modules/postcss/lib/parse.d.ts @@ -0,0 +1,9 @@ +import { Parser } from './postcss.js' + +interface Parse extends Parser { + default: Parse +} + +declare const parse: Parse + +export = parse diff --git a/node_modules/postcss/lib/parse.js b/node_modules/postcss/lib/parse.js new file mode 100644 index 0000000000..00a1037aa6 --- /dev/null +++ b/node_modules/postcss/lib/parse.js @@ -0,0 +1,42 @@ +'use strict' + +let Container = require('./container') +let Input = require('./input') +let Parser = require('./parser') + +function parse(css, opts) { + let input = new Input(css, opts) + let parser = new Parser(input) + try { + parser.parse() + } catch (e) { + if (process.env.NODE_ENV !== 'production') { + if (e.name === 'CssSyntaxError' && opts && opts.from) { + if (/\.scss$/i.test(opts.from)) { + e.message += + '\nYou tried to parse SCSS with ' + + 'the standard CSS parser; ' + + 'try again with the postcss-scss parser' + } else if (/\.sass/i.test(opts.from)) { + e.message += + '\nYou tried to parse Sass with ' + + 'the standard CSS parser; ' + + 'try again with the postcss-sass parser' + } else if (/\.less$/i.test(opts.from)) { + e.message += + '\nYou tried to parse Less with ' + + 'the standard CSS parser; ' + + 'try again with the postcss-less parser' + } + } + } + throw e + } + + return parser.root +} + +module.exports = parse +parse.default = parse + +Container.registerParse(parse) diff --git a/node_modules/postcss/lib/parser.js b/node_modules/postcss/lib/parser.js new file mode 100644 index 0000000000..64fb5d89b9 --- /dev/null +++ b/node_modules/postcss/lib/parser.js @@ -0,0 +1,611 @@ +'use strict' + +let AtRule = require('./at-rule') +let Comment = require('./comment') +let Declaration = require('./declaration') +let Root = require('./root') +let Rule = require('./rule') +let tokenizer = require('./tokenize') + +const SAFE_COMMENT_NEIGHBOR = { + empty: true, + space: true +} + +function findLastWithPosition(tokens) { + for (let i = tokens.length - 1; i >= 0; i--) { + let token = tokens[i] + let pos = token[3] || token[2] + if (pos) return pos + } +} + +class Parser { + constructor(input) { + this.input = input + + this.root = new Root() + this.current = this.root + this.spaces = '' + this.semicolon = false + + this.createTokenizer() + this.root.source = { input, start: { column: 1, line: 1, offset: 0 } } + } + + atrule(token) { + let node = new AtRule() + node.name = token[1].slice(1) + if (node.name === '') { + this.unnamedAtrule(node, token) + } + this.init(node, token[2]) + + let type + let prev + let shift + let last = false + let open = false + let params = [] + let brackets = [] + + while (!this.tokenizer.endOfFile()) { + token = this.tokenizer.nextToken() + type = token[0] + + if (type === '(' || type === '[') { + brackets.push(type === '(' ? ')' : ']') + } else if (type === '{' && brackets.length > 0) { + brackets.push('}') + } else if (type === brackets[brackets.length - 1]) { + brackets.pop() + } + + if (brackets.length === 0) { + if (type === ';') { + node.source.end = this.getPosition(token[2]) + node.source.end.offset++ + this.semicolon = true + break + } else if (type === '{') { + open = true + break + } else if (type === '}') { + if (params.length > 0) { + shift = params.length - 1 + prev = params[shift] + while (prev && prev[0] === 'space') { + prev = params[--shift] + } + if (prev) { + node.source.end = this.getPosition(prev[3] || prev[2]) + node.source.end.offset++ + } + } + this.end(token) + break + } else { + params.push(token) + } + } else { + params.push(token) + } + + if (this.tokenizer.endOfFile()) { + last = true + break + } + } + + node.raws.between = this.spacesAndCommentsFromEnd(params) + if (params.length) { + node.raws.afterName = this.spacesAndCommentsFromStart(params) + this.raw(node, 'params', params) + if (last) { + token = params[params.length - 1] + node.source.end = this.getPosition(token[3] || token[2]) + node.source.end.offset++ + this.spaces = node.raws.between + node.raws.between = '' + } + } else { + node.raws.afterName = '' + node.params = '' + } + + if (open) { + node.nodes = [] + this.current = node + } + } + + checkMissedSemicolon(tokens) { + let colon = this.colon(tokens) + if (colon === false) return + + let founded = 0 + let token + for (let j = colon - 1; j >= 0; j--) { + token = tokens[j] + if (token[0] !== 'space') { + founded += 1 + if (founded === 2) break + } + } + // If the token is a word, e.g. `!important`, `red` or any other valid property's value. + // Then we need to return the colon after that word token. [3] is the "end" colon of that word. + // And because we need it after that one we do +1 to get the next one. + throw this.input.error( + 'Missed semicolon', + token[0] === 'word' ? token[3] + 1 : token[2] + ) + } + + colon(tokens) { + let brackets = 0 + let prev, token, type + for (let [i, element] of tokens.entries()) { + token = element + type = token[0] + + if (type === '(') { + brackets += 1 + } + if (type === ')') { + brackets -= 1 + } + if (brackets === 0 && type === ':') { + if (!prev) { + this.doubleColon(token) + } else if (prev[0] === 'word' && prev[1] === 'progid') { + continue + } else { + return i + } + } + + prev = token + } + return false + } + + comment(token) { + let node = new Comment() + this.init(node, token[2]) + node.source.end = this.getPosition(token[3] || token[2]) + node.source.end.offset++ + + let text = token[1].slice(2, -2) + if (/^\s*$/.test(text)) { + node.text = '' + node.raws.left = text + node.raws.right = '' + } else { + let match = text.match(/^(\s*)([^]*\S)(\s*)$/) + node.text = match[2] + node.raws.left = match[1] + node.raws.right = match[3] + } + } + + createTokenizer() { + this.tokenizer = tokenizer(this.input) + } + + decl(tokens, customProperty) { + let node = new Declaration() + this.init(node, tokens[0][2]) + + let last = tokens[tokens.length - 1] + if (last[0] === ';') { + this.semicolon = true + tokens.pop() + } + + node.source.end = this.getPosition( + last[3] || last[2] || findLastWithPosition(tokens) + ) + node.source.end.offset++ + + while (tokens[0][0] !== 'word') { + if (tokens.length === 1) this.unknownWord(tokens) + node.raws.before += tokens.shift()[1] + } + node.source.start = this.getPosition(tokens[0][2]) + + node.prop = '' + while (tokens.length) { + let type = tokens[0][0] + if (type === ':' || type === 'space' || type === 'comment') { + break + } + node.prop += tokens.shift()[1] + } + + node.raws.between = '' + + let token + while (tokens.length) { + token = tokens.shift() + + if (token[0] === ':') { + node.raws.between += token[1] + break + } else { + if (token[0] === 'word' && /\w/.test(token[1])) { + this.unknownWord([token]) + } + node.raws.between += token[1] + } + } + + if (node.prop[0] === '_' || node.prop[0] === '*') { + node.raws.before += node.prop[0] + node.prop = node.prop.slice(1) + } + + let firstSpaces = [] + let next + while (tokens.length) { + next = tokens[0][0] + if (next !== 'space' && next !== 'comment') break + firstSpaces.push(tokens.shift()) + } + + this.precheckMissedSemicolon(tokens) + + for (let i = tokens.length - 1; i >= 0; i--) { + token = tokens[i] + if (token[1].toLowerCase() === '!important') { + node.important = true + let string = this.stringFrom(tokens, i) + string = this.spacesFromEnd(tokens) + string + if (string !== ' !important') node.raws.important = string + break + } else if (token[1].toLowerCase() === 'important') { + let cache = tokens.slice(0) + let str = '' + for (let j = i; j > 0; j--) { + let type = cache[j][0] + if (str.trim().startsWith('!') && type !== 'space') { + break + } + str = cache.pop()[1] + str + } + if (str.trim().startsWith('!')) { + node.important = true + node.raws.important = str + tokens = cache + } + } + + if (token[0] !== 'space' && token[0] !== 'comment') { + break + } + } + + let hasWord = tokens.some(i => i[0] !== 'space' && i[0] !== 'comment') + + if (hasWord) { + node.raws.between += firstSpaces.map(i => i[1]).join('') + firstSpaces = [] + } + this.raw(node, 'value', firstSpaces.concat(tokens), customProperty) + + if (node.value.includes(':') && !customProperty) { + this.checkMissedSemicolon(tokens) + } + } + + doubleColon(token) { + throw this.input.error( + 'Double colon', + { offset: token[2] }, + { offset: token[2] + token[1].length } + ) + } + + emptyRule(token) { + let node = new Rule() + this.init(node, token[2]) + node.selector = '' + node.raws.between = '' + this.current = node + } + + end(token) { + if (this.current.nodes && this.current.nodes.length) { + this.current.raws.semicolon = this.semicolon + } + this.semicolon = false + + this.current.raws.after = (this.current.raws.after || '') + this.spaces + this.spaces = '' + + if (this.current.parent) { + this.current.source.end = this.getPosition(token[2]) + this.current.source.end.offset++ + this.current = this.current.parent + } else { + this.unexpectedClose(token) + } + } + + endFile() { + if (this.current.parent) this.unclosedBlock() + if (this.current.nodes && this.current.nodes.length) { + this.current.raws.semicolon = this.semicolon + } + this.current.raws.after = (this.current.raws.after || '') + this.spaces + this.root.source.end = this.getPosition(this.tokenizer.position()) + } + + freeSemicolon(token) { + this.spaces += token[1] + if (this.current.nodes) { + let prev = this.current.nodes[this.current.nodes.length - 1] + if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) { + prev.raws.ownSemicolon = this.spaces + this.spaces = '' + prev.source.end = this.getPosition(token[2]) + prev.source.end.offset += prev.raws.ownSemicolon.length + } + } + } + + // Helpers + + getPosition(offset) { + let pos = this.input.fromOffset(offset) + return { + column: pos.col, + line: pos.line, + offset + } + } + + init(node, offset) { + this.current.push(node) + node.source = { + input: this.input, + start: this.getPosition(offset) + } + node.raws.before = this.spaces + this.spaces = '' + if (node.type !== 'comment') this.semicolon = false + } + + other(start) { + let end = false + let type = null + let colon = false + let bracket = null + let brackets = [] + let customProperty = start[1].startsWith('--') + + let tokens = [] + let token = start + while (token) { + type = token[0] + tokens.push(token) + + if (type === '(' || type === '[') { + if (!bracket) bracket = token + brackets.push(type === '(' ? ')' : ']') + } else if (customProperty && colon && type === '{') { + if (!bracket) bracket = token + brackets.push('}') + } else if (brackets.length === 0) { + if (type === ';') { + if (colon) { + this.decl(tokens, customProperty) + return + } else { + break + } + } else if (type === '{') { + this.rule(tokens) + return + } else if (type === '}') { + this.tokenizer.back(tokens.pop()) + end = true + break + } else if (type === ':') { + colon = true + } + } else if (type === brackets[brackets.length - 1]) { + brackets.pop() + if (brackets.length === 0) bracket = null + } + + token = this.tokenizer.nextToken() + } + + if (this.tokenizer.endOfFile()) end = true + if (brackets.length > 0) this.unclosedBracket(bracket) + + if (end && colon) { + if (!customProperty) { + while (tokens.length) { + token = tokens[tokens.length - 1][0] + if (token !== 'space' && token !== 'comment') break + this.tokenizer.back(tokens.pop()) + } + } + this.decl(tokens, customProperty) + } else { + this.unknownWord(tokens) + } + } + + parse() { + let token + while (!this.tokenizer.endOfFile()) { + token = this.tokenizer.nextToken() + + switch (token[0]) { + case 'space': + this.spaces += token[1] + break + + case ';': + this.freeSemicolon(token) + break + + case '}': + this.end(token) + break + + case 'comment': + this.comment(token) + break + + case 'at-word': + this.atrule(token) + break + + case '{': + this.emptyRule(token) + break + + default: + this.other(token) + break + } + } + this.endFile() + } + + precheckMissedSemicolon(/* tokens */) { + // Hook for Safe Parser + } + + raw(node, prop, tokens, customProperty) { + let token, type + let length = tokens.length + let value = '' + let clean = true + let next, prev + + for (let i = 0; i < length; i += 1) { + token = tokens[i] + type = token[0] + if (type === 'space' && i === length - 1 && !customProperty) { + clean = false + } else if (type === 'comment') { + prev = tokens[i - 1] ? tokens[i - 1][0] : 'empty' + next = tokens[i + 1] ? tokens[i + 1][0] : 'empty' + if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) { + if (value.slice(-1) === ',') { + clean = false + } else { + value += token[1] + } + } else { + clean = false + } + } else { + value += token[1] + } + } + if (!clean) { + let raw = tokens.reduce((all, i) => all + i[1], '') + node.raws[prop] = { raw, value } + } + node[prop] = value + } + + rule(tokens) { + tokens.pop() + + let node = new Rule() + this.init(node, tokens[0][2]) + + node.raws.between = this.spacesAndCommentsFromEnd(tokens) + this.raw(node, 'selector', tokens) + this.current = node + } + + spacesAndCommentsFromEnd(tokens) { + let lastTokenType + let spaces = '' + while (tokens.length) { + lastTokenType = tokens[tokens.length - 1][0] + if (lastTokenType !== 'space' && lastTokenType !== 'comment') break + spaces = tokens.pop()[1] + spaces + } + return spaces + } + + // Errors + + spacesAndCommentsFromStart(tokens) { + let next + let spaces = '' + while (tokens.length) { + next = tokens[0][0] + if (next !== 'space' && next !== 'comment') break + spaces += tokens.shift()[1] + } + return spaces + } + + spacesFromEnd(tokens) { + let lastTokenType + let spaces = '' + while (tokens.length) { + lastTokenType = tokens[tokens.length - 1][0] + if (lastTokenType !== 'space') break + spaces = tokens.pop()[1] + spaces + } + return spaces + } + + stringFrom(tokens, from) { + let result = '' + for (let i = from; i < tokens.length; i++) { + result += tokens[i][1] + } + tokens.splice(from, tokens.length - from) + return result + } + + unclosedBlock() { + let pos = this.current.source.start + throw this.input.error('Unclosed block', pos.line, pos.column) + } + + unclosedBracket(bracket) { + throw this.input.error( + 'Unclosed bracket', + { offset: bracket[2] }, + { offset: bracket[2] + 1 } + ) + } + + unexpectedClose(token) { + throw this.input.error( + 'Unexpected }', + { offset: token[2] }, + { offset: token[2] + 1 } + ) + } + + unknownWord(tokens) { + throw this.input.error( + 'Unknown word ' + tokens[0][1], + { offset: tokens[0][2] }, + { offset: tokens[0][2] + tokens[0][1].length } + ) + } + + unnamedAtrule(node, token) { + throw this.input.error( + 'At-rule without name', + { offset: token[2] }, + { offset: token[2] + token[1].length } + ) + } +} + +module.exports = Parser diff --git a/node_modules/postcss/lib/postcss.d.mts b/node_modules/postcss/lib/postcss.d.mts new file mode 100644 index 0000000000..d343f3cdf3 --- /dev/null +++ b/node_modules/postcss/lib/postcss.d.mts @@ -0,0 +1,69 @@ +export { + // Type-only exports + AcceptedPlugin, + + AnyNode, + atRule, + AtRule, + AtRuleProps, + Builder, + ChildNode, + ChildProps, + comment, + Comment, + CommentProps, + Container, + ContainerProps, + CssSyntaxError, + decl, + Declaration, + DeclarationProps, + // postcss function / namespace + default, + document, + Document, + DocumentProps, + FilePosition, + fromJSON, + Helpers, + Input, + + JSONHydrator, + // This is a class, but it’s not re-exported. That’s why it’s exported as type-only here. + type LazyResult, + list, + Message, + Node, + NodeErrorOptions, + NodeProps, + OldPlugin, + parse, + Parser, + // @ts-expect-error This value exists, but it’s untyped. + plugin, + Plugin, + PluginCreator, + Position, + Postcss, + ProcessOptions, + Processor, + Result, + root, + Root, + RootProps, + rule, + Rule, + RuleProps, + Source, + SourceMap, + SourceMapOptions, + Stringifier, + // Value exports from postcss.mjs + stringify, + Syntax, + TransformCallback, + Transformer, + Warning, + + WarningOptions +} from './postcss.js' diff --git a/node_modules/postcss/lib/postcss.d.ts b/node_modules/postcss/lib/postcss.d.ts new file mode 100644 index 0000000000..c5e36052ec --- /dev/null +++ b/node_modules/postcss/lib/postcss.d.ts @@ -0,0 +1,458 @@ +import { RawSourceMap, SourceMapGenerator } from 'source-map-js' + +import AtRule, { AtRuleProps } from './at-rule.js' +import Comment, { CommentProps } from './comment.js' +import Container, { ContainerProps, NewChild } from './container.js' +import CssSyntaxError from './css-syntax-error.js' +import Declaration, { DeclarationProps } from './declaration.js' +import Document, { DocumentProps } from './document.js' +import Input, { FilePosition } from './input.js' +import LazyResult from './lazy-result.js' +import list from './list.js' +import Node, { + AnyNode, + ChildNode, + ChildProps, + NodeErrorOptions, + NodeProps, + Position, + Source +} from './node.js' +import Processor from './processor.js' +import Result, { Message } from './result.js' +import Root, { RootProps } from './root.js' +import Rule, { RuleProps } from './rule.js' +import Warning, { WarningOptions } from './warning.js' + +type DocumentProcessor = ( + document: Document, + helper: postcss.Helpers +) => Promise | void +type RootProcessor = ( + root: Root, + helper: postcss.Helpers +) => Promise | void +type DeclarationProcessor = ( + decl: Declaration, + helper: postcss.Helpers +) => Promise | void +type RuleProcessor = ( + rule: Rule, + helper: postcss.Helpers +) => Promise | void +type AtRuleProcessor = ( + atRule: AtRule, + helper: postcss.Helpers +) => Promise | void +type CommentProcessor = ( + comment: Comment, + helper: postcss.Helpers +) => Promise | void + +interface Processors { + /** + * Will be called on all`AtRule` nodes. + * + * Will be called again on node or children changes. + */ + AtRule?: { [name: string]: AtRuleProcessor } | AtRuleProcessor + + /** + * Will be called on all `AtRule` nodes, when all children will be processed. + * + * Will be called again on node or children changes. + */ + AtRuleExit?: { [name: string]: AtRuleProcessor } | AtRuleProcessor + + /** + * Will be called on all `Comment` nodes. + * + * Will be called again on node or children changes. + */ + Comment?: CommentProcessor + + /** + * Will be called on all `Comment` nodes after listeners + * for `Comment` event. + * + * Will be called again on node or children changes. + */ + CommentExit?: CommentProcessor + + /** + * Will be called on all `Declaration` nodes after listeners + * for `Declaration` event. + * + * Will be called again on node or children changes. + */ + Declaration?: { [prop: string]: DeclarationProcessor } | DeclarationProcessor + + /** + * Will be called on all `Declaration` nodes. + * + * Will be called again on node or children changes. + */ + DeclarationExit?: + | { [prop: string]: DeclarationProcessor } + | DeclarationProcessor + + /** + * Will be called on `Document` node. + * + * Will be called again on children changes. + */ + Document?: DocumentProcessor + + /** + * Will be called on `Document` node, when all children will be processed. + * + * Will be called again on children changes. + */ + DocumentExit?: DocumentProcessor + + /** + * Will be called on `Root` node once. + */ + Once?: RootProcessor + + /** + * Will be called on `Root` node once, when all children will be processed. + */ + OnceExit?: RootProcessor + + /** + * Will be called on `Root` node. + * + * Will be called again on children changes. + */ + Root?: RootProcessor + + /** + * Will be called on `Root` node, when all children will be processed. + * + * Will be called again on children changes. + */ + RootExit?: RootProcessor + + /** + * Will be called on all `Rule` nodes. + * + * Will be called again on node or children changes. + */ + Rule?: RuleProcessor + + /** + * Will be called on all `Rule` nodes, when all children will be processed. + * + * Will be called again on node or children changes. + */ + RuleExit?: RuleProcessor +} + +declare namespace postcss { + export { + AnyNode, + AtRule, + AtRuleProps, + ChildNode, + ChildProps, + Comment, + CommentProps, + Container, + ContainerProps, + CssSyntaxError, + Declaration, + DeclarationProps, + Document, + DocumentProps, + FilePosition, + Input, + LazyResult, + list, + Message, + NewChild, + Node, + NodeErrorOptions, + NodeProps, + Position, + Processor, + Result, + Root, + RootProps, + Rule, + RuleProps, + Source, + Warning, + WarningOptions + } + + export type SourceMap = { + toJSON(): RawSourceMap + } & SourceMapGenerator + + export type Helpers = { postcss: Postcss; result: Result } & Postcss + + export interface Plugin extends Processors { + postcssPlugin: string + prepare?: (result: Result) => Processors + } + + export interface PluginCreator { + (opts?: PluginOptions): Plugin | Processor + postcss: true + } + + export interface Transformer extends TransformCallback { + postcssPlugin: string + postcssVersion: string + } + + export interface TransformCallback { + (root: Root, result: Result): Promise | void + } + + export interface OldPlugin extends Transformer { + (opts?: T): Transformer + postcss: Transformer + } + + export type AcceptedPlugin = + | { + postcss: Processor | TransformCallback + } + | OldPlugin + | Plugin + | PluginCreator + | Processor + | TransformCallback + + export interface Parser { + ( + css: { toString(): string } | string, + opts?: Pick + ): RootNode + } + + export interface Builder { + (part: string, node?: AnyNode, type?: 'end' | 'start'): void + } + + export interface Stringifier { + (node: AnyNode, builder: Builder): void + } + + export interface JSONHydrator { + (data: object): Node + (data: object[]): Node[] + } + + export interface Syntax { + /** + * Function to generate AST by string. + */ + parse?: Parser + + /** + * Class to generate string by AST. + */ + stringify?: Stringifier + } + + export interface SourceMapOptions { + /** + * Use absolute path in generated source map. + */ + absolute?: boolean + + /** + * Indicates that PostCSS should add annotation comments to the CSS. + * By default, PostCSS will always add a comment with a path + * to the source map. PostCSS will not add annotations to CSS files + * that do not contain any comments. + * + * By default, PostCSS presumes that you want to save the source map as + * `opts.to + '.map'` and will use this path in the annotation comment. + * A different path can be set by providing a string value for annotation. + * + * If you have set `inline: true`, annotation cannot be disabled. + */ + annotation?: ((file: string, root: Root) => string) | boolean | string + + /** + * Override `from` in map’s sources. + */ + from?: string + + /** + * Indicates that the source map should be embedded in the output CSS + * as a Base64-encoded comment. By default, it is `true`. + * But if all previous maps are external, not inline, PostCSS will not embed + * the map even if you do not set this option. + * + * If you have an inline source map, the result.map property will be empty, + * as the source map will be contained within the text of `result.css`. + */ + inline?: boolean + + /** + * Source map content from a previous processing step (e.g., Sass). + * + * PostCSS will try to read the previous source map + * automatically (based on comments within the source CSS), but you can use + * this option to identify it manually. + * + * If desired, you can omit the previous map with prev: `false`. + */ + prev?: ((file: string) => string) | boolean | object | string + + /** + * Indicates that PostCSS should set the origin content (e.g., Sass source) + * of the source map. By default, it is true. But if all previous maps do not + * contain sources content, PostCSS will also leave it out even if you + * do not set this option. + */ + sourcesContent?: boolean + } + + export interface ProcessOptions { + /** + * Input file if it is not simple CSS file, but HTML with + + `; +} + +//#endregion +//#region src/node/server/transformRequest.ts +var import_etag = /* @__PURE__ */ __toESM(require_etag(), 1); +var import_picocolors$14 = /* @__PURE__ */ __toESM(require_picocolors(), 1); +const ERR_LOAD_URL = "ERR_LOAD_URL"; +const ERR_LOAD_PUBLIC_URL = "ERR_LOAD_PUBLIC_URL"; +const ERR_DENIED_ID = "ERR_DENIED_ID"; +const debugLoad = createDebugger("vite:load"); +const debugTransform = createDebugger("vite:transform"); +const debugCache$1 = createDebugger("vite:cache"); +function transformRequest(environment, url$3, options$1 = {}) { + if (environment._closing && environment.config.dev.recoverable) throwClosedServerError(); + const timestamp = monotonicDateNow(); + const pending = environment._pendingRequests.get(url$3); + if (pending) return environment.moduleGraph.getModuleByUrl(removeTimestampQuery(url$3)).then((module$1) => { + if (!module$1 || pending.timestamp > module$1.lastInvalidationTimestamp) return pending.request; + else { + pending.abort(); + return transformRequest(environment, url$3, options$1); + } + }); + const request = doTransform(environment, url$3, options$1, timestamp); + let cleared = false; + const clearCache = () => { + if (!cleared) { + environment._pendingRequests.delete(url$3); + cleared = true; + } + }; + environment._pendingRequests.set(url$3, { + request, + timestamp, + abort: clearCache + }); + return request.finally(clearCache); +} +async function doTransform(environment, url$3, options$1, timestamp) { + url$3 = removeTimestampQuery(url$3); + const { pluginContainer } = environment; + let module$1 = await environment.moduleGraph.getModuleByUrl(url$3); + if (module$1) { + const cached = await getCachedTransformResult(environment, url$3, module$1, timestamp); + if (cached) return cached; + } + const resolved = module$1 ? void 0 : await pluginContainer.resolveId(url$3, void 0) ?? void 0; + const id = module$1?.id ?? resolved?.id ?? url$3; + module$1 ??= environment.moduleGraph.getModuleById(id); + if (module$1) { + await environment.moduleGraph._ensureEntryFromUrl(url$3, void 0, resolved); + const cached = await getCachedTransformResult(environment, url$3, module$1, timestamp); + if (cached) return cached; + } + const result = loadAndTransform(environment, id, url$3, options$1, timestamp, module$1, resolved); + const { depsOptimizer } = environment; + if (!depsOptimizer?.isOptimizedDepFile(id)) environment._registerRequestProcessing(id, () => result); + return result; +} +async function getCachedTransformResult(environment, url$3, module$1, timestamp) { + const prettyUrl = debugCache$1 ? prettifyUrl(url$3, environment.config.root) : ""; + const softInvalidatedTransformResult = await handleModuleSoftInvalidation(environment, module$1, timestamp); + if (softInvalidatedTransformResult) { + debugCache$1?.(`[memory-hmr] ${prettyUrl}`); + return softInvalidatedTransformResult; + } + const cached = module$1.transformResult; + if (cached) { + debugCache$1?.(`[memory] ${prettyUrl}`); + return cached; + } +} +async function loadAndTransform(environment, id, url$3, options$1, timestamp, mod, resolved) { + const { config: config$2, pluginContainer, logger } = environment; + const prettyUrl = debugLoad || debugTransform ? prettifyUrl(url$3, config$2.root) : ""; + const moduleGraph = environment.moduleGraph; + if (options$1.allowId && !options$1.allowId(id)) { + const err$2 = /* @__PURE__ */ new Error(`Denied ID ${id}`); + err$2.code = ERR_DENIED_ID; + err$2.id = id; + throw err$2; + } + let code = null; + let map$1 = null; + const loadStart = debugLoad ? performance$1.now() : 0; + const loadResult = await pluginContainer.load(id); + if (loadResult == null) { + const file = cleanUrl(id); + if (environment.config.consumer === "server" || isFileLoadingAllowed(environment.getTopLevelConfig(), slash(file))) { + try { + code = await fsp.readFile(file, "utf-8"); + debugLoad?.(`${timeFrom(loadStart)} [fs] ${prettyUrl}`); + } catch (e$1) { + if (e$1.code !== "ENOENT" && e$1.code !== "EISDIR") throw e$1; + } + if (code != null && environment.pluginContainer.watcher) ensureWatchedFile(environment.pluginContainer.watcher, file, config$2.root); + } + if (code) try { + const extracted = await extractSourcemapFromFile(code, file); + if (extracted) { + code = extracted.code; + map$1 = extracted.map; + } + } catch (e$1) { + logger.warn(`Failed to load source map for ${file}.\n${e$1}`, { timestamp: true }); + } + } else { + debugLoad?.(`${timeFrom(loadStart)} [plugin] ${prettyUrl}`); + if (isObject(loadResult)) { + code = loadResult.code; + map$1 = loadResult.map; + } else code = loadResult; + } + if (code == null) { + const isPublicFile = checkPublicFile(url$3, environment.getTopLevelConfig()); + let publicDirName = path.relative(config$2.root, config$2.publicDir); + if (publicDirName[0] !== ".") publicDirName = "/" + publicDirName; + const msg = isPublicFile ? `This file is in ${publicDirName} and will be copied as-is during build without going through the plugin transforms, and therefore should not be imported from source code. It can only be referenced via HTML tags.` : `Does the file exist?`; + const importerMod = moduleGraph.idToModuleMap.get(id)?.importers.values().next().value; + const importer = importerMod?.file || importerMod?.url; + const err$2 = /* @__PURE__ */ new Error(`Failed to load url ${url$3} (resolved id: ${id})${importer ? ` in ${importer}` : ""}. ${msg}`); + err$2.code = isPublicFile ? ERR_LOAD_PUBLIC_URL : ERR_LOAD_URL; + throw err$2; + } + if (environment._closing && environment.config.dev.recoverable) throwClosedServerError(); + mod ??= await moduleGraph._ensureEntryFromUrl(url$3, void 0, resolved); + const transformStart = debugTransform ? performance$1.now() : 0; + const transformResult = await pluginContainer.transform(code, id, { inMap: map$1 }); + const originalCode = code; + if (transformResult.code === originalCode) debugTransform?.(timeFrom(transformStart) + import_picocolors$14.default.dim(` [skipped] ${prettyUrl}`)); + else { + debugTransform?.(`${timeFrom(transformStart)} ${prettyUrl}`); + code = transformResult.code; + map$1 = transformResult.map; + } + let normalizedMap; + if (typeof map$1 === "string") normalizedMap = JSON.parse(map$1); + else if (map$1) normalizedMap = map$1; + else normalizedMap = null; + if (normalizedMap && "version" in normalizedMap && mod.file) { + if (normalizedMap.mappings) await injectSourcesContent(normalizedMap, mod.file, logger); + const sourcemapPath = `${mod.file}.map`; + applySourcemapIgnoreList(normalizedMap, sourcemapPath, config$2.server.sourcemapIgnoreList, logger); + if (path.isAbsolute(mod.file)) { + let modDirname; + for (let sourcesIndex = 0; sourcesIndex < normalizedMap.sources.length; ++sourcesIndex) { + const sourcePath = normalizedMap.sources[sourcesIndex]; + if (sourcePath) { + if (path.isAbsolute(sourcePath)) { + modDirname ??= path.dirname(mod.file); + normalizedMap.sources[sourcesIndex] = path.relative(modDirname, sourcePath); + } + } + } + } + } + if (environment._closing && environment.config.dev.recoverable) throwClosedServerError(); + const topLevelConfig = environment.getTopLevelConfig(); + const result = environment.config.dev.moduleRunnerTransform ? await ssrTransform(code, normalizedMap, url$3, originalCode, { json: { stringify: topLevelConfig.json.stringify === true && topLevelConfig.json.namedExports !== true } }) : { + code, + map: normalizedMap, + etag: (0, import_etag.default)(code, { weak: true }) + }; + if (timestamp > mod.lastInvalidationTimestamp) moduleGraph.updateModuleTransformResult(mod, result); + return result; +} +/** +* When a module is soft-invalidated, we can preserve its previous `transformResult` and +* return similar code to before: +* +* - Client: We need to transform the import specifiers with new timestamps +* - SSR: We don't need to change anything as `ssrLoadModule` controls it +*/ +async function handleModuleSoftInvalidation(environment, mod, timestamp) { + const transformResult = mod.invalidationState; + mod.invalidationState = void 0; + if (!transformResult || transformResult === "HARD_INVALIDATED") return; + if (mod.transformResult) throw new Error(`Internal server error: Soft-invalidated module "${mod.url}" should not have existing transform result`); + let result; + if (transformResult.ssr) result = transformResult; + else { + await init; + const source = transformResult.code; + const s$2 = new MagicString(source); + const [imports] = parse(source, mod.id || void 0); + for (const imp of imports) { + let rawUrl = source.slice(imp.s, imp.e); + if (rawUrl === "import.meta") continue; + const hasQuotes = rawUrl[0] === "\"" || rawUrl[0] === "'"; + if (hasQuotes) rawUrl = rawUrl.slice(1, -1); + const urlWithoutTimestamp = removeTimestampQuery(rawUrl); + const hmrUrl = unwrapId(stripBase(removeImportQuery(urlWithoutTimestamp), environment.config.base)); + for (const importedMod of mod.importedModules) { + if (importedMod.url !== hmrUrl) continue; + if (importedMod.lastHMRTimestamp > 0) { + const replacedUrl = injectQuery(urlWithoutTimestamp, `t=${importedMod.lastHMRTimestamp}`); + const start = hasQuotes ? imp.s + 1 : imp.s; + const end = hasQuotes ? imp.e - 1 : imp.e; + s$2.overwrite(start, end, replacedUrl); + } + if (imp.d === -1 && environment.config.dev.preTransformRequests) environment.warmupRequest(hmrUrl); + break; + } + } + const code = s$2.toString(); + result = { + ...transformResult, + code, + etag: (0, import_etag.default)(code, { weak: true }) + }; + } + if (timestamp > mod.lastInvalidationTimestamp) environment.moduleGraph.updateModuleTransformResult(mod, result); + return result; +} + +//#endregion +//#region src/node/assetSource.ts +const ALLOWED_META_NAME = [ + "msapplication-tileimage", + "msapplication-square70x70logo", + "msapplication-square150x150logo", + "msapplication-wide310x150logo", + "msapplication-square310x310logo", + "msapplication-config", + "twitter:image" +]; +const ALLOWED_META_PROPERTY = [ + "og:image", + "og:image:url", + "og:image:secure_url", + "og:audio", + "og:audio:secure_url", + "og:video", + "og:video:secure_url" +]; +const DEFAULT_HTML_ASSET_SOURCES = { + audio: { srcAttributes: ["src"] }, + embed: { srcAttributes: ["src"] }, + img: { + srcAttributes: ["src"], + srcsetAttributes: ["srcset"] + }, + image: { srcAttributes: ["href", "xlink:href"] }, + input: { srcAttributes: ["src"] }, + link: { + srcAttributes: ["href"], + srcsetAttributes: ["imagesrcset"] + }, + object: { srcAttributes: ["data"] }, + source: { + srcAttributes: ["src"], + srcsetAttributes: ["srcset"] + }, + track: { srcAttributes: ["src"] }, + use: { srcAttributes: ["href", "xlink:href"] }, + video: { srcAttributes: ["src", "poster"] }, + meta: { + srcAttributes: ["content"], + filter({ attributes }) { + if (attributes.name && ALLOWED_META_NAME.includes(attributes.name.trim().toLowerCase())) return true; + if (attributes.property && ALLOWED_META_PROPERTY.includes(attributes.property.trim().toLowerCase())) return true; + return false; + } + } +}; +/** +* Given a HTML node, find all attributes that references an asset to be processed +*/ +function getNodeAssetAttributes(node) { + const matched = DEFAULT_HTML_ASSET_SOURCES[node.nodeName]; + if (!matched) return []; + const attributes = {}; + for (const attr of node.attrs) attributes[getAttrKey(attr)] = attr.value; + if ("vite-ignore" in attributes) return [{ + type: "remove", + key: "vite-ignore", + value: "", + attributes, + location: node.sourceCodeLocation.attrs["vite-ignore"] + }]; + const actions = []; + function handleAttributeKey(key, type) { + const value$1 = attributes[key]; + if (!value$1) return; + if (matched.filter && !matched.filter({ + key, + value: value$1, + attributes + })) return; + const location$1 = node.sourceCodeLocation.attrs[key]; + actions.push({ + type, + key, + value: value$1, + attributes, + location: location$1 + }); + } + matched.srcAttributes?.forEach((key) => handleAttributeKey(key, "src")); + matched.srcsetAttributes?.forEach((key) => handleAttributeKey(key, "srcset")); + return actions; +} +function getAttrKey(attr) { + return attr.prefix === void 0 ? attr.name : `${attr.prefix}:${attr.name}`; +} + +//#endregion +//#region src/node/plugins/modulePreloadPolyfill.ts +const modulePreloadPolyfillId = "vite/modulepreload-polyfill"; +const resolvedModulePreloadPolyfillId = "\0" + modulePreloadPolyfillId + ".js"; +function modulePreloadPolyfillPlugin(config$2) { + let polyfillString; + return { + name: "vite:modulepreload-polyfill", + resolveId: { + filter: { id: exactRegex(modulePreloadPolyfillId) }, + handler(_id) { + return resolvedModulePreloadPolyfillId; + } + }, + load: { + filter: { id: exactRegex(resolvedModulePreloadPolyfillId) }, + handler(_id) { + if (config$2.command !== "build" || this.environment.config.consumer !== "client") return ""; + if (!polyfillString) polyfillString = `${isModernFlag}&&(${polyfill.toString()}());`; + return { + code: polyfillString, + moduleSideEffects: true + }; + } + } + }; +} +function polyfill() { + const relList = document.createElement("link").relList; + if (relList && relList.supports && relList.supports("modulepreload")) return; + for (const link of document.querySelectorAll("link[rel=\"modulepreload\"]")) processPreload(link); + new MutationObserver((mutations) => { + for (const mutation of mutations) { + if (mutation.type !== "childList") continue; + for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node); + } + }).observe(document, { + childList: true, + subtree: true + }); + function getFetchOpts(link) { + const fetchOpts = {}; + if (link.integrity) fetchOpts.integrity = link.integrity; + if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy; + if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include"; + else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit"; + else fetchOpts.credentials = "same-origin"; + return fetchOpts; + } + function processPreload(link) { + if (link.ep) return; + link.ep = true; + const fetchOpts = getFetchOpts(link); + fetch(link.href, fetchOpts); + } +} + +//#endregion +//#region src/node/plugins/html.ts +var import_picocolors$13 = /* @__PURE__ */ __toESM(require_picocolors(), 1); +var import_escape_html = /* @__PURE__ */ __toESM(require_escape_html(), 1); +const htmlProxyRE$1 = /[?&]html-proxy=?(?:&inline-css)?(?:&style-attr)?&index=(\d+)\.(?:js|css)$/; +const isHtmlProxyRE = /[?&]html-proxy\b/; +const inlineCSSRE$1 = /__VITE_INLINE_CSS__([a-z\d]{8}_\d+)__/g; +const inlineImportRE = /(?]*type\s*=\s*(?:"importmap"|'importmap'|importmap)[^>]*>.*?<\/script>/is; +const moduleScriptRE = /[ \t]*]*type\s*=\s*(?:"module"|'module'|module)[^>]*>/i; +const modulePreloadLinkRE = /[ \t]*]*rel\s*=\s*(?:"modulepreload"|'modulepreload'|modulepreload)[\s\S]*?\/>/i; +const importMapAppendRE = new RegExp([moduleScriptRE, modulePreloadLinkRE].map((r$2) => r$2.source).join("|"), "i"); +const isHTMLProxy = (id) => isHtmlProxyRE.test(id); +const isHTMLRequest = (request) => htmlLangRE.test(request); +const htmlProxyMap = /* @__PURE__ */ new WeakMap(); +const htmlProxyResult = /* @__PURE__ */ new Map(); +function htmlInlineProxyPlugin(config$2) { + htmlProxyMap.set(config$2, /* @__PURE__ */ new Map()); + return { + name: "vite:html-inline-proxy", + resolveId: { + filter: { id: isHtmlProxyRE }, + handler(id) { + return id; + } + }, + load: { + filter: { id: isHtmlProxyRE }, + handler(id) { + const proxyMatch = htmlProxyRE$1.exec(id); + if (proxyMatch) { + const index = Number(proxyMatch[1]); + const file = cleanUrl(id); + const url$3 = file.replace(normalizePath(config$2.root), ""); + const result = htmlProxyMap.get(config$2).get(url$3)?.[index]; + if (result) return { + ...result, + moduleSideEffects: true + }; + else throw new Error(`No matching HTML proxy module found from ${id}`); + } + } + } + }; +} +function addToHTMLProxyCache(config$2, filePath, index, result) { + if (!htmlProxyMap.get(config$2)) htmlProxyMap.set(config$2, /* @__PURE__ */ new Map()); + if (!htmlProxyMap.get(config$2).get(filePath)) htmlProxyMap.get(config$2).set(filePath, []); + htmlProxyMap.get(config$2).get(filePath)[index] = result; +} +function addToHTMLProxyTransformResult(hash$1, code) { + htmlProxyResult.set(hash$1, code); +} +const noInlineLinkRels = new Set([ + "icon", + "apple-touch-icon", + "apple-touch-startup-image", + "manifest" +]); +const isAsyncScriptMap = /* @__PURE__ */ new WeakMap(); +function nodeIsElement(node) { + return node.nodeName[0] !== "#"; +} +function traverseNodes(node, visitor) { + if (node.nodeName === "template") node = node.content; + visitor(node); + if (nodeIsElement(node) || node.nodeName === "#document" || node.nodeName === "#document-fragment") node.childNodes.forEach((childNode) => traverseNodes(childNode, visitor)); +} +async function traverseHtml(html, filePath, warn, visitor) { + const { parse: parse$17 } = await import("./dep-UEPspf5j.js"); + const warnings = {}; + const ast = parse$17(html, { + scriptingEnabled: false, + sourceCodeLocationInfo: true, + onParseError: (e$1) => { + handleParseError(e$1, html, filePath, warnings); + } + }); + traverseNodes(ast, visitor); + for (const message of Object.values(warnings)) warn(import_picocolors$13.default.yellow(`\n${message}`)); +} +function getScriptInfo(node) { + let src; + let srcSourceCodeLocation; + let isModule = false; + let isAsync = false; + let isIgnored = false; + for (const p of node.attrs) { + if (p.prefix !== void 0) continue; + if (p.name === "src") { + if (!src) { + src = p; + srcSourceCodeLocation = node.sourceCodeLocation?.attrs["src"]; + } + } else if (p.name === "type" && p.value === "module") isModule = true; + else if (p.name === "async") isAsync = true; + else if (p.name === "vite-ignore") isIgnored = true; + } + return { + src, + srcSourceCodeLocation, + isModule, + isAsync, + isIgnored + }; +} +const attrValueStartRE = /=\s*(.)/; +function overwriteAttrValue(s$2, sourceCodeLocation, newValue) { + const srcString = s$2.slice(sourceCodeLocation.startOffset, sourceCodeLocation.endOffset); + const valueStart = attrValueStartRE.exec(srcString); + if (!valueStart) throw new Error(`[vite:html] internal error, failed to overwrite attribute value`); + const wrapOffset = valueStart[1] === "\"" || valueStart[1] === "'" ? 1 : 0; + const valueOffset = valueStart.index + valueStart[0].length - 1; + s$2.update(sourceCodeLocation.startOffset + valueOffset + wrapOffset, sourceCodeLocation.endOffset - wrapOffset, newValue); + return s$2; +} +function removeViteIgnoreAttr(s$2, sourceCodeLocation) { + const loc = sourceCodeLocation.attrs?.["vite-ignore"]; + if (loc) s$2.remove(loc.startOffset, loc.endOffset); + return s$2; +} +/** +* Format parse5 @type {ParserError} to @type {RollupError} +*/ +function formatParseError(parserError, id, html) { + const formattedError = { + code: parserError.code, + message: `parse5 error code ${parserError.code}`, + frame: generateCodeFrame(html, parserError.startOffset, parserError.endOffset), + loc: { + file: id, + line: parserError.startLine, + column: parserError.startCol + } + }; + return formattedError; +} +function handleParseError(parserError, html, filePath, warnings) { + switch (parserError.code) { + case "missing-doctype": return; + case "abandoned-head-element-child": return; + case "duplicate-attribute": return; + case "non-void-html-element-start-tag-with-trailing-solidus": return; + case "unexpected-question-mark-instead-of-tag-name": return; + } + const parseError = formatParseError(parserError, filePath, html); + warnings[parseError.code] ??= `Unable to parse HTML; ${parseError.message}\n at ${parseError.loc.file}:${parseError.loc.line}:${parseError.loc.column}\n` + parseError.frame; +} +/** +* Compiles index.html into an entry js module +*/ +function buildHtmlPlugin(config$2) { + const [preHooks, normalHooks, postHooks] = resolveHtmlTransforms(config$2.plugins); + preHooks.unshift(injectCspNonceMetaTagHook(config$2)); + preHooks.unshift(preImportMapHook(config$2)); + preHooks.push(htmlEnvHook(config$2)); + postHooks.push(injectNonceAttributeTagHook(config$2)); + postHooks.push(postImportMapHook()); + const processedHtml = perEnvironmentState(() => /* @__PURE__ */ new Map()); + const isExcludedUrl = (url$3) => url$3[0] === "#" || isExternalUrl(url$3) || isDataUrl(url$3); + isAsyncScriptMap.set(config$2, /* @__PURE__ */ new Map()); + return { + name: "vite:build-html", + transform: { + filter: { id: /\.html$/ }, + async handler(html, id) { + id = normalizePath(id); + const relativeUrlPath = normalizePath(path.relative(config$2.root, id)); + const publicPath = `/${relativeUrlPath}`; + const publicBase = getBaseInHTML(relativeUrlPath, config$2); + const publicToRelative = (filename) => publicBase + filename; + const toOutputPublicFilePath = (url$3) => toOutputFilePathInHtml(url$3.slice(1), "public", relativeUrlPath, "html", config$2, publicToRelative); + const nodeStartWithLeadingWhitespace = (node) => { + const startOffset = node.sourceCodeLocation.startOffset; + if (startOffset === 0) return 0; + const lineStartOffset = startOffset - node.sourceCodeLocation.startCol; + let isLineEmpty = false; + try { + const line = s$2.slice(Math.max(0, lineStartOffset), startOffset); + isLineEmpty = !line.trim(); + } catch {} + return isLineEmpty ? lineStartOffset : startOffset; + }; + html = await applyHtmlTransforms(html, preHooks, this, { + path: publicPath, + filename: id + }); + let js = ""; + const s$2 = new MagicString(html); + const scriptUrls = []; + const styleUrls = []; + let inlineModuleIndex = -1; + let everyScriptIsAsync = true; + let someScriptsAreAsync = false; + let someScriptsAreDefer = false; + const assetUrlsPromises = []; + const namedOutput = Object.keys(config$2.build.rollupOptions.input || {}); + const processAssetUrl = async (url$3, shouldInline$1) => { + if (url$3 !== "" && !namedOutput.includes(url$3) && !namedOutput.includes(removeLeadingSlash(url$3))) try { + return await urlToBuiltUrl(this, url$3, id, shouldInline$1); + } catch (e$1) { + if (e$1.code !== "ENOENT") throw e$1; + } + return url$3; + }; + const setModuleSideEffectPromises = []; + await traverseHtml(html, id, config$2.logger.warn, (node) => { + if (!nodeIsElement(node)) return; + let shouldRemove = false; + if (node.nodeName === "script") { + const { src, srcSourceCodeLocation, isModule, isAsync, isIgnored } = getScriptInfo(node); + if (isIgnored) removeViteIgnoreAttr(s$2, node.sourceCodeLocation); + else { + const url$3 = src && src.value; + const isPublicFile = !!(url$3 && checkPublicFile(url$3, config$2)); + if (isPublicFile) overwriteAttrValue(s$2, srcSourceCodeLocation, partialEncodeURIPath(toOutputPublicFilePath(url$3))); + if (isModule) { + inlineModuleIndex++; + if (url$3 && !isExcludedUrl(url$3) && !isPublicFile) { + setModuleSideEffectPromises.push(this.resolve(url$3, id).then((resolved) => { + if (!resolved) return Promise.reject(/* @__PURE__ */ new Error(`Failed to resolve ${url$3} from ${id}`)); + const moduleInfo = this.getModuleInfo(resolved.id); + if (moduleInfo) moduleInfo.moduleSideEffects = true; + else if (!resolved.external) return this.load(resolved).then((mod) => { + mod.moduleSideEffects = true; + }); + })); + js += `\nimport ${JSON.stringify(url$3)}`; + shouldRemove = true; + } else if (node.childNodes.length) { + const scriptNode = node.childNodes.pop(); + const contents = scriptNode.value; + const filePath = id.replace(normalizePath(config$2.root), ""); + addToHTMLProxyCache(config$2, filePath, inlineModuleIndex, { code: contents }); + js += `\nimport "${id}?html-proxy&index=${inlineModuleIndex}.js"`; + shouldRemove = true; + } + everyScriptIsAsync &&= isAsync; + someScriptsAreAsync ||= isAsync; + someScriptsAreDefer ||= !isAsync; + } else if (url$3 && !isPublicFile) { + if (!isExcludedUrl(url$3)) config$2.logger.warn(` + + +`, + ts: ` + + + +`, + test: ` +import { expect, test } from 'vitest' +import { render } from 'vitest-browser-vue' +import HelloWorld from './HelloWorld.vue' + +test('renders name', async () => { + const { getByText } = render(HelloWorld, { + props: { name: 'Vitest' }, + }) + await expect.element(getByText('Hello Vitest!')).toBeInTheDocument() +}) +` +}; +const svelteExample = { + name: "HelloWorld.svelte", + js: ` + + +

Hello {name}!

+`, + ts: ` + + +

Hello {name}!

+`, + test: ` +import { expect, test } from 'vitest' +import { render } from 'vitest-browser-svelte' +import HelloWorld from './HelloWorld.svelte' + +test('renders name', async () => { + const { getByText } = render(HelloWorld, { name: 'Vitest' }) + await expect.element(getByText('Hello Vitest!')).toBeInTheDocument() +}) +` +}; +const markoExample = { + name: "HelloWorld.marko", + js: ` +class { + onCreate() { + this.state = { name: null } + } +} + +

Hello \${state.name}!

+`, + ts: ` +export interface Input { + name: string +} + +

Hello \${input.name}!

+`, + test: ` +import { expect, test } from 'vitest' +import { render } from '@marko/testing-library' +import HelloWorld from './HelloWorld.svelte' + +test('renders name', async () => { + const { getByText } = await render(HelloWorld, { name: 'Vitest' }) + const element = getByText('Hello Vitest!') + expect(element).toBeInTheDocument() +}) +` +}; +const litExample = { + name: "HelloWorld.js", + js: ` +import { html, LitElement } from 'lit' + +export class HelloWorld extends LitElement { + static properties = { + name: { type: String }, + } + + constructor() { + super() + this.name = 'World' + } + + render() { + return html\`

Hello \${this.name}!

\` + } +} + +customElements.define('hello-world', HelloWorld) +`, + ts: ` +import { html, LitElement } from 'lit' +import { customElement, property } from 'lit/decorators.js' + +@customElement('hello-world') +export class HelloWorld extends LitElement { + @property({ type: String }) + name = 'World' + + render() { + return html\`

Hello \${this.name}!

\` + } +} + +declare global { + interface HTMLElementTagNameMap { + 'hello-world': HelloWorld + } +} +`, + test: ` +import { expect, test } from 'vitest' +import { render } from 'vitest-browser-lit' +import { html } from 'lit' +import './HelloWorld.js' + +test('renders name', async () => { + const screen = render(html\`\`) + const element = screen.getByText('Hello Vitest!') + await expect.element(element).toBeInTheDocument() +}) +` +}; +const vanillaExample = { + name: "HelloWorld.js", + js: ` +export default function HelloWorld({ name }) { + const parent = document.createElement('div') + + const h1 = document.createElement('h1') + h1.textContent = 'Hello ' + name + '!' + parent.appendChild(h1) + + return parent +} +`, + ts: ` +export default function HelloWorld({ name }: { name: string }): HTMLDivElement { + const parent = document.createElement('div') + + const h1 = document.createElement('h1') + h1.textContent = 'Hello ' + name + '!' + parent.appendChild(h1) + + return parent +} +`, + test: ` +import { expect, test } from 'vitest' +import { getByText } from '@testing-library/dom' +import HelloWorld from './HelloWorld.js' + +test('renders name', () => { + const parent = HelloWorld({ name: 'Vitest' }) + document.body.appendChild(parent) + + const element = getByText(parent, 'Hello Vitest!') + expect(element).toBeInTheDocument() +}) +` +}; +function getExampleTest(framework) { + switch (framework) { + case "solid": return { + ...jsxExample, + test: jsxExample.test.replace("@testing-library/jsx", `@testing-library/${framework}`) + }; + case "preact": + case "react": return { + ...jsxExample, + test: jsxExample.test.replace("@testing-library/jsx", `vitest-browser-${framework}`) + }; + case "vue": return vueExample; + case "svelte": return svelteExample; + case "lit": return litExample; + case "marko": return markoExample; + default: return vanillaExample; + } +} +async function generateExampleFiles(framework, lang) { + const example = getExampleTest(framework); + let fileName = example.name; + const folder = resolve(process.cwd(), "vitest-example"); + const fileContent = example[lang]; + if (!existsSync(folder)) await mkdir(folder, { recursive: true }); + const isJSX = fileName.endsWith(".jsx"); + if (isJSX && lang === "ts") fileName = fileName.replace(".jsx", ".tsx"); + else if (fileName.endsWith(".js") && lang === "ts") fileName = fileName.replace(".js", ".ts"); + const filePath = resolve(folder, fileName); + const testPath = resolve(folder, `HelloWorld.test.${isJSX ? `${lang}x` : lang}`); + writeFileSync(filePath, fileContent.trimStart(), "utf-8"); + writeFileSync(testPath, example.test.trimStart(), "utf-8"); + return testPath; +} + +// eslint-disable-next-line no-console +const log = console.log; +function getProviderOptions() { + const providers = { + playwright: "Playwright relies on Chrome DevTools protocol. Read more: https://playwright.dev", + webdriverio: "WebdriverIO uses WebDriver protocol. Read more: https://webdriver.io", + preview: "Preview is useful to quickly run your tests in the browser, but not suitable for CI." + }; + return Object.entries(providers).map(([provider, description]) => { + return { + title: provider, + description, + value: provider + }; + }); +} +function getBrowserNames(provider) { + switch (provider) { + case "webdriverio": return [ + "chrome", + "firefox", + "edge", + "safari" + ]; + case "playwright": return [ + "chromium", + "firefox", + "webkit" + ]; + case "preview": return [ + "chrome", + "firefox", + "safari" + ]; + } +} +function getProviderPackageNames(provider) { + switch (provider) { + case "webdriverio": return { + types: "@vitest/browser/providers/webdriverio", + pkg: "webdriverio" + }; + case "playwright": return { + types: "@vitest/browser/providers/playwright", + pkg: "playwright" + }; + case "preview": return { + types: "@vitest/browser/matchers", + pkg: null + }; + } + throw new Error(`Unsupported provider: ${provider}`); +} +function getFramework() { + return [ + { + title: "vanilla", + value: "vanilla", + description: "No framework, just plain JavaScript or TypeScript." + }, + { + title: "vue", + value: "vue", + description: "\"The Progressive JavaScript Framework\"" + }, + { + title: "svelte", + value: "svelte", + description: "\"Svelte: cybernetically enhanced web apps\"" + }, + { + title: "react", + value: "react", + description: "\"The library for web and native user interfaces\"" + }, + { + title: "lit", + value: "lit", + description: "\"A simple library for building fast, lightweight web components.\"" + }, + { + title: "preact", + value: "preact", + description: "\"Fast 3kB alternative to React with the same modern API\"" + }, + { + title: "solid", + value: "solid", + description: "\"Simple and performant reactivity for building user interfaces\"" + }, + { + title: "marko", + value: "marko", + description: "\"A declarative, HTML-based language that makes building web apps fun\"" + } + ]; +} +function getFrameworkTestPackage(framework) { + switch (framework) { + case "vanilla": return null; + case "vue": return "vitest-browser-vue"; + case "svelte": return "vitest-browser-svelte"; + case "react": return "vitest-browser-react"; + case "lit": return "vitest-browser-lit"; + case "preact": return "vitest-browser-preact"; + case "solid": return "@solidjs/testing-library"; + case "marko": return "@marko/testing-library"; + } + throw new Error(`Unsupported framework: ${framework}`); +} +function getFrameworkPluginPackage(framework) { + switch (framework) { + case "vue": return "@vitejs/plugin-vue"; + case "svelte": return "@sveltejs/vite-plugin-svelte"; + case "react": return "@vitejs/plugin-react"; + case "preact": return "@preact/preset-vite"; + case "solid": return "vite-plugin-solid"; + case "marko": return "@marko/vite"; + } + return null; +} +async function updateTsConfig(type) { + if (type == null) return; + const msg = `Add "${c.bold(type)}" to your tsconfig.json "${c.bold("compilerOptions.types")}" field to have better intellisense support.`; + log(); + log(c.yellow("◼"), c.yellow(msg)); +} +function getLanguageOptions() { + return [{ + title: "TypeScript", + description: "Use TypeScript.", + value: "ts" + }, { + title: "JavaScript", + description: "Use plain JavaScript.", + value: "js" + }]; +} +async function installPackages(pkgManager, packages) { + if (!packages.length) { + log(c.green("✔"), c.bold("All packages are already installed.")); + return; + } + log(c.cyan("◼"), c.bold("Installing packages...")); + log(c.cyan("◼"), packages.join(", ")); + log(); + await installPackage(packages, { + dev: true, + packageManager: pkgManager ?? void 0 + }); +} +function readPkgJson(path) { + if (!existsSync(path)) return null; + const content = readFileSync(path, "utf-8"); + return JSON.parse(content); +} +function getPossibleDefaults(dependencies) { + const provider = getPossibleProvider(dependencies); + const framework = getPossibleFramework(dependencies); + return { + lang: "ts", + provider, + framework + }; +} +function getPossibleFramework(dependencies) { + if (dependencies.vue || dependencies["vue-tsc"] || dependencies["@vue/reactivity"]) return "vue"; + if (dependencies.react || dependencies["react-dom"]) return "react"; + if (dependencies.svelte || dependencies["@sveltejs/kit"]) return "svelte"; + if (dependencies.lit || dependencies["lit-html"]) return "lit"; + if (dependencies.preact) return "preact"; + if (dependencies["solid-js"] || dependencies["@solidjs/start"]) return "solid"; + if (dependencies.marko) return "marko"; + return "vanilla"; +} +function getPossibleProvider(dependencies) { + if (dependencies.webdriverio || dependencies["@wdio/cli"] || dependencies["@wdio/config"]) return "webdriverio"; + // playwright is the default recommendation + return "playwright"; +} +function getProviderDocsLink(provider) { + switch (provider) { + case "playwright": return "https://vitest.dev/guide/browser/playwright"; + case "webdriverio": return "https://vitest.dev/guide/browser/webdriverio"; + } +} +function sort(choices, value) { + const index = choices.findIndex((i) => i.value === value); + if (index === -1) return choices; + const item = choices.splice(index, 1)[0]; + return [item, ...choices]; +} +function fail() { + process.exitCode = 1; +} +async function generateFrameworkConfigFile(options) { + const frameworkImport = options.framework === "svelte" ? `import { svelte } from '${options.frameworkPlugin}'` : `import ${options.framework} from '${options.frameworkPlugin}'`; + const configContent = [ + `import { defineConfig } from 'vitest/config'`, + options.frameworkPlugin ? frameworkImport : null, + ``, + "export default defineConfig({", + options.frameworkPlugin ? ` plugins: [${options.framework}()],` : null, + ` test: {`, + ` browser: {`, + ` enabled: true,`, + ` provider: '${options.provider}',`, + options.provider !== "preview" && ` // ${getProviderDocsLink(options.provider)}`, + ` instances: [`, + ...options.browsers.map((browser) => ` { browser: '${browser}' },`), + ` ],`, + ` },`, + ` },`, + `})`, + "" + ].filter((t) => typeof t === "string").join("\n"); + await writeFile(options.configPath, configContent); +} +async function updatePkgJsonScripts(pkgJsonPath, vitestScript) { + if (!existsSync(pkgJsonPath)) { + const pkg = { scripts: { "test:browser": vitestScript } }; + await writeFile(pkgJsonPath, `${JSON.stringify(pkg, null, 2)}\n`, "utf-8"); + } else { + const pkg = JSON.parse(readFileSync(pkgJsonPath, "utf-8")); + pkg.scripts = pkg.scripts || {}; + pkg.scripts["test:browser"] = vitestScript; + await writeFile(pkgJsonPath, `${JSON.stringify(pkg, null, 2)}\n`, "utf-8"); + } + log(c.green("✔"), "Added \"test:browser\" script to your package.json."); +} +function getRunScript(pkgManager) { + switch (pkgManager) { + case "yarn@berry": + case "yarn": return "yarn test:browser"; + case "pnpm@6": + case "pnpm": return "pnpm test:browser"; + case "bun": return "bun test:browser"; + default: return "npm run test:browser"; + } +} +function getPlaywrightRunArgs(pkgManager) { + switch (pkgManager) { + case "yarn@berry": + case "yarn": return ["yarn", "exec"]; + case "pnpm@6": + case "pnpm": return ["pnpx"]; + case "bun": return ["bunx"]; + default: return ["npx"]; + } +} +async function create() { + log(c.cyan("◼"), "This utility will help you set up a browser testing environment.\n"); + const pkgJsonPath = resolve(process.cwd(), "package.json"); + const pkg = readPkgJson(pkgJsonPath) || {}; + const dependencies = { + ...pkg.dependencies, + ...pkg.devDependencies + }; + const defaults = getPossibleDefaults(dependencies); + const { lang } = await prompt({ + type: "select", + name: "lang", + message: "Choose a language for your tests", + choices: sort(getLanguageOptions(), defaults?.lang) + }); + if (!lang) return fail(); + const { provider } = await prompt({ + type: "select", + name: "provider", + message: "Choose a browser provider. Vitest will use its API to control the testing environment", + choices: sort(getProviderOptions(), defaults?.provider) + }); + if (!provider) return fail(); + const { browsers } = await prompt({ + type: "multiselect", + name: "browsers", + message: "Choose a browser", + choices: getBrowserNames(provider).map((browser) => ({ + title: browser, + value: browser + })) + }); + if (!provider) return fail(); + const { framework } = await prompt({ + type: "select", + name: "framework", + message: "Choose your framework", + choices: sort(getFramework(), defaults?.framework) + }); + if (!framework) return fail(); + let installPlaywright = false; + if (provider === "playwright") ({installPlaywright} = await prompt({ + type: "confirm", + name: "installPlaywright", + message: `Install Playwright browsers (can be done manually via 'pnpm exec playwright install')?` + })); + if (installPlaywright == null) return fail(); + const dependenciesToInstall = ["@vitest/browser"]; + const frameworkPackage = getFrameworkTestPackage(framework); + if (frameworkPackage) dependenciesToInstall.push(frameworkPackage); + const providerPkg = getProviderPackageNames(provider); + if (providerPkg.pkg) dependenciesToInstall.push(providerPkg.pkg); + const frameworkPlugin = getFrameworkPluginPackage(framework); + if (frameworkPlugin) dependenciesToInstall.push(frameworkPlugin); + const pkgManager = await detectPackageManager(); + log(); + await installPackages(pkgManager, dependenciesToInstall.filter((pkg) => !dependencies[pkg])); + const rootConfig = await findUp(configFiles, { cwd: process.cwd() }); + let scriptCommand = "vitest"; + log(); + if (rootConfig) { + const configPath = resolve(dirname(rootConfig), `vitest.browser.config.${lang}`); + scriptCommand = `vitest --config=${relative(process.cwd(), configPath)}`; + await generateFrameworkConfigFile({ + configPath, + framework, + frameworkPlugin, + provider, + browsers + }); + log( + c.green("✔"), + "Created a new config file for browser tests:", + c.bold(relative(process.cwd(), configPath)), + // TODO: Can we modify the config ourselves? + "\nSince you already have a Vitest config file, it is recommended to copy the contents of the new file ", + "into your existing config located at ", + c.bold(relative(process.cwd(), rootConfig)) + ); + } else { + const configPath = resolve(process.cwd(), `vitest.config.${lang}`); + await generateFrameworkConfigFile({ + configPath, + framework, + frameworkPlugin, + provider, + browsers + }); + log(c.green("✔"), "Created a config file for browser tests:", c.bold(relative(process.cwd(), configPath))); + } + log(); + await updatePkgJsonScripts(pkgJsonPath, scriptCommand); + if (installPlaywright) { + log(); + const [command, ...args] = getPlaywrightRunArgs(pkgManager); + const allArgs = [ + ...args, + "playwright", + "install", + "--with-deps" + ]; + log(c.cyan("◼"), `Installing Playwright dependencies with \`${c.bold(command)} ${c.bold(allArgs.join(" "))}\`...`); + log(); + await x(command, allArgs, { nodeOptions: { stdio: [ + "pipe", + "inherit", + "inherit" + ] } }); + } + // TODO: can we do this ourselves? + if (lang === "ts") await updateTsConfig(providerPkg?.types); + log(); + const exampleTestFile = await generateExampleFiles(framework, lang); + log(c.green("✔"), "Created example test file in", c.bold(relative(process.cwd(), exampleTestFile))); + log(c.dim(" You can safely delete this file once you have written your own tests.")); + log(); + log(c.cyan("◼"), "All done! Run your tests with", c.bold(getRunScript(pkgManager))); +} + +export { create }; diff --git a/node_modules/vitest/dist/chunks/date.Bq6ZW5rf.js b/node_modules/vitest/dist/chunks/date.Bq6ZW5rf.js new file mode 100644 index 0000000000..8bd2322882 --- /dev/null +++ b/node_modules/vitest/dist/chunks/date.Bq6ZW5rf.js @@ -0,0 +1,73 @@ +/* Ported from https://github.com/boblauer/MockDate/blob/master/src/mockdate.ts */ +/* +The MIT License (MIT) + +Copyright (c) 2014 Bob Lauer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +const RealDate = Date; +let now = null; +class MockDate extends RealDate { + constructor(y, m, d, h, M, s, ms) { + super(); + let date; + switch (arguments.length) { + case 0: + if (now !== null) date = new RealDate(now.valueOf()); + else date = new RealDate(); + break; + case 1: + date = new RealDate(y); + break; + default: + d = typeof d === "undefined" ? 1 : d; + h = h || 0; + M = M || 0; + s = s || 0; + ms = ms || 0; + date = new RealDate(y, m, d, h, M, s, ms); + break; + } + Object.setPrototypeOf(date, MockDate.prototype); + return date; + } +} +MockDate.UTC = RealDate.UTC; +MockDate.now = function() { + return new MockDate().valueOf(); +}; +MockDate.parse = function(dateString) { + return RealDate.parse(dateString); +}; +MockDate.toString = function() { + return RealDate.toString(); +}; +function mockDate(date) { + const dateObj = new RealDate(date.valueOf()); + if (Number.isNaN(dateObj.getTime())) throw new TypeError(`mockdate: The time set is an invalid date: ${date}`); + // @ts-expect-error global + globalThis.Date = MockDate; + now = dateObj.valueOf(); +} +function resetDate() { + globalThis.Date = RealDate; +} + +export { RealDate as R, mockDate as m, resetDate as r }; diff --git a/node_modules/vitest/dist/chunks/defaults.B7q_naMc.js b/node_modules/vitest/dist/chunks/defaults.B7q_naMc.js new file mode 100644 index 0000000000..6bb2026bcb --- /dev/null +++ b/node_modules/vitest/dist/chunks/defaults.B7q_naMc.js @@ -0,0 +1,115 @@ +import nodeos__default from 'node:os'; +import './env.D4Lgay0q.js'; +import { isCI } from 'std-env'; + +const defaultInclude = ["**/*.{test,spec}.?(c|m)[jt]s?(x)"]; +const defaultExclude = [ + "**/node_modules/**", + "**/dist/**", + "**/cypress/**", + "**/.{idea,git,cache,output,temp}/**", + "**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*" +]; +const benchmarkConfigDefaults = { + include: ["**/*.{bench,benchmark}.?(c|m)[jt]s?(x)"], + exclude: defaultExclude, + includeSource: [], + reporters: ["default"], + includeSamples: false +}; +const defaultCoverageExcludes = [ + "coverage/**", + "dist/**", + "**/node_modules/**", + "**/[.]**", + "packages/*/test?(s)/**", + "**/*.d.ts", + "**/virtual:*", + "**/__x00__*", + "**/\0*", + "cypress/**", + "test?(s)/**", + "test?(-*).?(c|m)[jt]s?(x)", + "**/*{.,-}{test,spec,bench,benchmark}?(-d).?(c|m)[jt]s?(x)", + "**/__tests__/**", + "**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*", + "**/vitest.{workspace,projects}.[jt]s?(on)", + "**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}" +]; +// These are the generic defaults for coverage. Providers may also set some provider specific defaults. +const coverageConfigDefaults = { + provider: "v8", + enabled: false, + all: true, + clean: true, + cleanOnRerun: true, + reportsDirectory: "./coverage", + exclude: defaultCoverageExcludes, + reportOnFailure: false, + reporter: [ + ["text", {}], + ["html", {}], + ["clover", {}], + ["json", {}] + ], + extension: [ + ".js", + ".cjs", + ".mjs", + ".ts", + ".mts", + ".tsx", + ".jsx", + ".vue", + ".svelte", + ".marko", + ".astro" + ], + allowExternal: false, + excludeAfterRemap: false, + ignoreEmptyLines: true, + processingConcurrency: Math.min(20, nodeos__default.availableParallelism?.() ?? nodeos__default.cpus().length) +}; +const fakeTimersDefaults = { + loopLimit: 1e4, + shouldClearNativeTimers: true +}; +const configDefaults = Object.freeze({ + allowOnly: !isCI, + isolate: true, + watch: !isCI && process.stdin.isTTY, + globals: false, + environment: "node", + pool: "forks", + clearMocks: false, + restoreMocks: false, + mockReset: false, + unstubGlobals: false, + unstubEnvs: false, + include: defaultInclude, + exclude: defaultExclude, + teardownTimeout: 1e4, + forceRerunTriggers: ["**/package.json/**", "**/{vitest,vite}.config.*/**"], + update: false, + reporters: [], + silent: false, + hideSkippedTests: false, + api: false, + ui: false, + uiBase: "/__vitest__/", + open: !isCI, + css: { include: [] }, + coverage: coverageConfigDefaults, + fakeTimers: fakeTimersDefaults, + maxConcurrency: 5, + dangerouslyIgnoreUnhandledErrors: false, + typecheck: { + checker: "tsc", + include: ["**/*.{test,spec}-d.?(c|m)[jt]s?(x)"], + exclude: defaultExclude + }, + slowTestThreshold: 300, + disableConsoleIntercept: false +}); + +export { coverageConfigDefaults as a, defaultInclude as b, configDefaults as c, defaultExclude as d, benchmarkConfigDefaults as e }; diff --git a/node_modules/vitest/dist/chunks/env.D4Lgay0q.js b/node_modules/vitest/dist/chunks/env.D4Lgay0q.js new file mode 100644 index 0000000000..f3389f0475 --- /dev/null +++ b/node_modules/vitest/dist/chunks/env.D4Lgay0q.js @@ -0,0 +1,8 @@ +import { isCI } from 'std-env'; + +const isNode = typeof process < "u" && typeof process.stdout < "u" && !process.versions?.deno && !globalThis.window; +const isDeno = typeof process < "u" && typeof process.stdout < "u" && process.versions?.deno !== void 0; +const isWindows = (isNode || isDeno) && process.platform === "win32"; +const isTTY = (isNode || isDeno) && process.stdout?.isTTY && !isCI; + +export { isWindows as a, isTTY as i }; diff --git a/node_modules/vitest/dist/chunks/environment.d.cL3nLXbE.d.ts b/node_modules/vitest/dist/chunks/environment.d.cL3nLXbE.d.ts new file mode 100644 index 0000000000..a044d132b1 --- /dev/null +++ b/node_modules/vitest/dist/chunks/environment.d.cL3nLXbE.d.ts @@ -0,0 +1,119 @@ +import { happyDomTypes, jsdomTypes } from 'vitest/optional-types.js'; + +type Awaitable = T | PromiseLike; +type Nullable = T | null | undefined; +type Arrayable = T | Array; +type ArgumentsType = T extends (...args: infer U) => any ? U : never; +type MutableArray = { -readonly [k in keyof T] : T[k] }; +interface Constructable { + new (...args: any[]): any; +} +type TransformMode = "web" | "ssr"; +/** @deprecated not used */ +interface ModuleCache { + promise?: Promise; + exports?: any; + code?: string; +} +interface AfterSuiteRunMeta { + coverage?: unknown; + testFiles: string[]; + transformMode: TransformMode | "browser"; + projectName?: string; +} +interface UserConsoleLog { + content: string; + origin?: string; + browser?: boolean; + type: "stdout" | "stderr"; + taskId?: string; + time: number; + size: number; +} +interface ModuleGraphData { + graph: Record; + externalized: string[]; + inlined: string[]; +} +interface ProvidedContext {} +// These need to be compatible with Tinyrainbow's bg-colors, and CSS's background-color +type LabelColor = "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white"; + +type HappyDOMOptions = Omit[0]>, "console">; + +type JSDOMOptions = ConstructorOptionsOverride & Omit; +interface ConstructorOptionsOverride { + /** + * The html content for the test. + * + * @default '' + */ + html?: string | ArrayBufferLike; + /** + * userAgent affects the value read from navigator.userAgent, as well as the User-Agent header sent while fetching subresources. + * + * @default `Mozilla/5.0 (${process.platform}) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/${jsdomVersion}` + */ + userAgent?: string; + /** + * url sets the value returned by window.location, document.URL, and document.documentURI, + * and affects things like resolution of relative URLs within the document + * and the same-origin restrictions and referrer used while fetching subresources. + * + * @default 'http://localhost:3000'. + */ + url?: string; + /** + * Enable console? + * + * @default false + */ + console?: boolean; + /** + * jsdom does not have the capability to render visual content, and will act like a headless browser by default. + * It provides hints to web pages through APIs such as document.hidden that their content is not visible. + * + * When the `pretendToBeVisual` option is set to `true`, jsdom will pretend that it is rendering and displaying + * content. + * + * @default true + */ + pretendToBeVisual?: boolean; + /** + * Enable CookieJar + * + * @default false + */ + cookieJar?: boolean; + resources?: "usable"; +} + +interface EnvironmentReturn { + teardown: (global: any) => Awaitable; +} +interface VmEnvironmentReturn { + getVmContext: () => { + [key: string]: any + }; + teardown: () => Awaitable; +} +interface Environment { + name: string; + transformMode: "web" | "ssr"; + setupVM?: (options: Record) => Awaitable; + setup: (global: any, options: Record) => Awaitable; +} +interface EnvironmentOptions { + /** + * jsdom options. + */ + jsdom?: JSDOMOptions; + happyDOM?: HappyDOMOptions; + [x: string]: unknown; +} +interface ResolvedTestEnvironment { + environment: Environment; + options: Record | null; +} + +export type { AfterSuiteRunMeta as A, Constructable as C, Environment as E, HappyDOMOptions as H, JSDOMOptions as J, LabelColor as L, ModuleGraphData as M, Nullable as N, ProvidedContext as P, ResolvedTestEnvironment as R, TransformMode as T, UserConsoleLog as U, VmEnvironmentReturn as V, EnvironmentReturn as a, Awaitable as b, Arrayable as c, ArgumentsType as d, MutableArray as e, EnvironmentOptions as f, ModuleCache as g }; diff --git a/node_modules/vitest/dist/chunks/execute.B7h3T_Hc.js b/node_modules/vitest/dist/chunks/execute.B7h3T_Hc.js new file mode 100644 index 0000000000..076b14a361 --- /dev/null +++ b/node_modules/vitest/dist/chunks/execute.B7h3T_Hc.js @@ -0,0 +1,708 @@ +import fs from 'node:fs'; +import { pathToFileURL } from 'node:url'; +import vm from 'node:vm'; +import { processError } from '@vitest/utils/error'; +import { normalize as normalize$1 } from 'pathe'; +import { ViteNodeRunner, DEFAULT_REQUEST_STUBS } from 'vite-node/client'; +import { isInternalRequest, isNodeBuiltin as isNodeBuiltin$1, isPrimitive, toFilePath } from 'vite-node/utils'; +import { distDir } from '../path.js'; +import { resolve as resolve$1, isAbsolute as isAbsolute$1 } from 'node:path'; +import { MockerRegistry, mockObject, RedirectedModule, AutomockedModule } from '@vitest/mocker'; +import { builtinModules } from 'node:module'; +import { highlight } from '@vitest/utils'; + +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) return input; + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _EXTNAME_RE = /.(\.[^./]+|\.)$/; +const normalize = function(path) { + if (path.length === 0) return "."; + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) return "/"; + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) path += "/"; + if (_DRIVE_LETTER_RE.test(path)) path += "/"; + if (isUNCPath) { + if (!isPathAbsolute) return `//./${path}`; + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...segments) { + let path = ""; + for (const seg of segments) { + if (!seg) continue; + if (path.length > 0) { + const pathTrailing = path[path.length - 1] === "/"; + const segLeading = seg[0] === "/"; + const both = pathTrailing && segLeading; + if (both) path += seg.slice(1); + else path += pathTrailing || segLeading ? seg : `/${seg}`; + } else path += seg; + } + return normalize(path); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") return process.cwd().replace(/\\/g, "/"); + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) continue; + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) return `/${resolvedPath}`; + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) char = path[index]; + else if (char === "/") break; + else char = "/"; + if (char === "/") { + if (lastSlash === index - 1 || dots === 1); + else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) res += `/${path.slice(lastSlash + 1, index)}`; + else res = path.slice(lastSlash + 1, index); + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) ++dots; + else dots = -1; + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const extname = function(p) { + if (p === "..") return ""; + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) segments[0] += "/"; + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const basename = function(p, extension) { + const segments = normalizeWindowsPath(p).split("/"); + let lastSegment = ""; + for (let i = segments.length - 1; i >= 0; i--) { + const val = segments[i]; + if (val) { + lastSegment = val; + break; + } + } + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; + +const { existsSync, readdirSync, statSync } = fs; +function findMockRedirect(root, mockPath, external) { + const path = external || mockPath; + // it's a node_module alias + // all mocks should be inside /__mocks__ + if (external || isNodeBuiltin(mockPath) || !existsSync(mockPath)) { + const mockDirname = dirname(path); + const mockFolder = join(root, "__mocks__", mockDirname); + if (!existsSync(mockFolder)) return null; + const baseOriginal = basename(path); + function findFile(mockFolder, baseOriginal) { + const files = readdirSync(mockFolder); + for (const file of files) { + const baseFile = basename(file, extname(file)); + if (baseFile === baseOriginal) { + const path = resolve(mockFolder, file); + // if the same name, return the file + if (statSync(path).isFile()) return path; + else { + // find folder/index.{js,ts} + const indexFile = findFile(path, "index"); + if (indexFile) return indexFile; + } + } + } + return null; + } + return findFile(mockFolder, baseOriginal); + } + const dir = dirname(path); + const baseId = basename(path); + const fullPath = resolve(dir, "__mocks__", baseId); + return existsSync(fullPath) ? fullPath : null; +} +const builtins = new Set([ + ...builtinModules, + "assert/strict", + "diagnostics_channel", + "dns/promises", + "fs/promises", + "path/posix", + "path/win32", + "readline/promises", + "stream/consumers", + "stream/promises", + "stream/web", + "timers/promises", + "util/types", + "wasi" +]); +// https://nodejs.org/api/modules.html#built-in-modules-with-mandatory-node-prefix +const prefixedBuiltins = new Set([ + "node:sea", + "node:sqlite", + "node:test", + "node:test/reporters" +]); +const NODE_BUILTIN_NAMESPACE = "node:"; +function isNodeBuiltin(id) { + if (prefixedBuiltins.has(id)) return true; + return builtins.has(id.startsWith(NODE_BUILTIN_NAMESPACE) ? id.slice(NODE_BUILTIN_NAMESPACE.length) : id); +} + +const spyModulePath = resolve$1(distDir, "spy.js"); +class VitestMocker { + static pendingIds = []; + spyModule; + primitives; + filterPublicKeys; + registries = /* @__PURE__ */ new Map(); + mockContext = { callstack: null }; + constructor(executor) { + this.executor = executor; + const context = this.executor.options.context; + if (context) this.primitives = vm.runInContext("({ Object, Error, Function, RegExp, Symbol, Array, Map })", context); + else this.primitives = { + Object, + Error, + Function, + RegExp, + Symbol: globalThis.Symbol, + Array, + Map + }; + const Symbol = this.primitives.Symbol; + this.filterPublicKeys = [ + "__esModule", + Symbol.asyncIterator, + Symbol.hasInstance, + Symbol.isConcatSpreadable, + Symbol.iterator, + Symbol.match, + Symbol.matchAll, + Symbol.replace, + Symbol.search, + Symbol.split, + Symbol.species, + Symbol.toPrimitive, + Symbol.toStringTag, + Symbol.unscopables + ]; + } + get root() { + return this.executor.options.root; + } + get moduleCache() { + return this.executor.moduleCache; + } + get moduleDirectories() { + return this.executor.options.moduleDirectories || []; + } + async initializeSpyModule() { + this.spyModule = await this.executor.executeId(spyModulePath); + } + getMockerRegistry() { + const suite = this.getSuiteFilepath(); + if (!this.registries.has(suite)) this.registries.set(suite, new MockerRegistry()); + return this.registries.get(suite); + } + reset() { + this.registries.clear(); + } + deleteCachedItem(id) { + const mockId = this.getMockPath(id); + if (this.moduleCache.has(mockId)) this.moduleCache.delete(mockId); + } + isModuleDirectory(path) { + return this.moduleDirectories.some((dir) => path.includes(dir)); + } + getSuiteFilepath() { + return this.executor.state.filepath || "global"; + } + createError(message, codeFrame) { + const Error = this.primitives.Error; + const error = new Error(message); + Object.assign(error, { codeFrame }); + return error; + } + async resolvePath(rawId, importer) { + let id; + let fsPath; + try { + [id, fsPath] = await this.executor.originalResolveUrl(rawId, importer); + } catch (error) { + // it's allowed to mock unresolved modules + if (error.code === "ERR_MODULE_NOT_FOUND") { + const { id: unresolvedId } = error[Symbol.for("vitest.error.not_found.data")]; + id = unresolvedId; + fsPath = unresolvedId; + } else throw error; + } + // external is node_module or unresolved module + // for example, some people mock "vscode" and don't have it installed + const external = !isAbsolute$1(fsPath) || this.isModuleDirectory(fsPath) ? rawId : null; + return { + id, + fsPath, + external: external ? this.normalizePath(external) : external + }; + } + async resolveMocks() { + if (!VitestMocker.pendingIds.length) return; + await Promise.all(VitestMocker.pendingIds.map(async (mock) => { + const { fsPath, external } = await this.resolvePath(mock.id, mock.importer); + if (mock.action === "unmock") this.unmockPath(fsPath); + if (mock.action === "mock") this.mockPath(mock.id, fsPath, external, mock.type, mock.factory); + })); + VitestMocker.pendingIds = []; + } + async callFunctionMock(dep, mock) { + const cached = this.moduleCache.get(dep)?.exports; + if (cached) return cached; + const exports = await mock.resolve(); + const moduleExports = new Proxy(exports, { get: (target, prop) => { + const val = target[prop]; + // 'then' can exist on non-Promise objects, need nested instanceof check for logic to work + if (prop === "then") { + if (target instanceof Promise) return target.then.bind(target); + } else if (!(prop in target)) { + if (this.filterPublicKeys.includes(prop)) return void 0; + throw this.createError(`[vitest] No "${String(prop)}" export is defined on the "${mock.raw}" mock. Did you forget to return it from "vi.mock"? +If you need to partially mock a module, you can use "importOriginal" helper inside: +`, highlight(`vi.mock(import("${mock.raw}"), async (importOriginal) => { + const actual = await importOriginal() + return { + ...actual, + // your mocked methods + } +})`)); + } + return val; + } }); + this.moduleCache.set(dep, { exports: moduleExports }); + return moduleExports; + } + // public method to avoid circular dependency + getMockContext() { + return this.mockContext; + } + // path used to store mocked dependencies + getMockPath(dep) { + return `mock:${dep}`; + } + getDependencyMock(id) { + const registry = this.getMockerRegistry(); + return registry.get(id); + } + normalizePath(path) { + return this.moduleCache.normalizePath(path); + } + resolveMockPath(mockPath, external) { + return findMockRedirect(this.root, mockPath, external); + } + mockObject(object, mockExports = {}, behavior = "automock") { + const spyOn = this.spyModule?.spyOn; + if (!spyOn) throw this.createError("[vitest] `spyModule` is not defined. This is a Vitest error. Please open a new issue with reproduction."); + return mockObject({ + globalConstructors: this.primitives, + spyOn, + type: behavior + }, object, mockExports); + } + unmockPath(path) { + const registry = this.getMockerRegistry(); + const id = this.normalizePath(path); + registry.delete(id); + this.deleteCachedItem(id); + } + mockPath(originalId, path, external, mockType, factory) { + const registry = this.getMockerRegistry(); + const id = this.normalizePath(path); + if (mockType === "manual") registry.register("manual", originalId, id, id, factory); + else if (mockType === "autospy") registry.register("autospy", originalId, id, id); + else { + const redirect = this.resolveMockPath(id, external); + if (redirect) registry.register("redirect", originalId, id, id, redirect); + else registry.register("automock", originalId, id, id); + } + // every time the mock is registered, we remove the previous one from the cache + this.deleteCachedItem(id); + } + async importActual(rawId, importer, callstack) { + const { id, fsPath } = await this.resolvePath(rawId, importer); + const result = await this.executor.cachedRequest(id, fsPath, callstack || [importer]); + return result; + } + async importMock(rawId, importee) { + const { id, fsPath, external } = await this.resolvePath(rawId, importee); + const normalizedId = this.normalizePath(fsPath); + let mock = this.getDependencyMock(normalizedId); + if (!mock) { + const redirect = this.resolveMockPath(normalizedId, external); + if (redirect) mock = new RedirectedModule(rawId, normalizedId, normalizedId, redirect); + else mock = new AutomockedModule(rawId, normalizedId, normalizedId); + } + if (mock.type === "automock" || mock.type === "autospy") { + const mod = await this.executor.cachedRequest(id, fsPath, [importee]); + return this.mockObject(mod, {}, mock.type); + } + if (mock.type === "manual") return this.callFunctionMock(fsPath, mock); + return this.executor.dependencyRequest(mock.redirect, mock.redirect, [importee]); + } + async requestWithMock(url, callstack) { + const id = this.normalizePath(url); + const mock = this.getDependencyMock(id); + if (!mock) return; + const mockPath = this.getMockPath(id); + if (mock.type === "automock" || mock.type === "autospy") { + const cache = this.moduleCache.get(mockPath); + if (cache.exports) return cache.exports; + const exports = {}; + // Assign the empty exports object early to allow for cycles to work. The object will be filled by mockObject() + this.moduleCache.set(mockPath, { exports }); + const mod = await this.executor.directRequest(url, url, callstack); + this.mockObject(mod, exports, mock.type); + return exports; + } + if (mock.type === "manual" && !callstack.includes(mockPath) && !callstack.includes(url)) try { + callstack.push(mockPath); + // this will not work if user does Promise.all(import(), import()) + // we can also use AsyncLocalStorage to store callstack, but this won't work in the browser + // maybe we should improve mock API in the future? + this.mockContext.callstack = callstack; + return await this.callFunctionMock(mockPath, mock); + } finally { + this.mockContext.callstack = null; + const indexMock = callstack.indexOf(mockPath); + callstack.splice(indexMock, 1); + } + else if (mock.type === "redirect" && !callstack.includes(mock.redirect)) return mock.redirect; + } + queueMock(id, importer, factoryOrOptions) { + const mockType = getMockType(factoryOrOptions); + VitestMocker.pendingIds.push({ + action: "mock", + id, + importer, + factory: typeof factoryOrOptions === "function" ? factoryOrOptions : void 0, + type: mockType + }); + } + queueUnmock(id, importer) { + VitestMocker.pendingIds.push({ + action: "unmock", + id, + importer + }); + } +} +function getMockType(factoryOrOptions) { + if (!factoryOrOptions) return "automock"; + if (typeof factoryOrOptions === "function") return "manual"; + return factoryOrOptions.spy ? "autospy" : "automock"; +} + +const normalizedDistDir = normalize$1(distDir); +const { readFileSync } = fs; +async function createVitestExecutor(options) { + const runner = new VitestExecutor(options); + await runner.executeId("/@vite/env"); + await runner.mocker.initializeSpyModule(); + return runner; +} +const externalizeMap = /* @__PURE__ */ new Map(); +const bareVitestRegexp = /^@?vitest(?:\/|$)/; +const dispose = []; +function listenForErrors(state) { + dispose.forEach((fn) => fn()); + dispose.length = 0; + function catchError(err, type, event) { + const worker = state(); + const listeners = process.listeners(event); + // if there is another listener, assume that it's handled by user code + // one is Vitest's own listener + if (listeners.length > 1) return; + const error = processError(err); + if (!isPrimitive(error)) { + error.VITEST_TEST_NAME = worker.current?.type === "test" ? worker.current.name : void 0; + if (worker.filepath) error.VITEST_TEST_PATH = worker.filepath; + error.VITEST_AFTER_ENV_TEARDOWN = worker.environmentTeardownRun; + } + state().rpc.onUnhandledError(error, type); + } + const uncaughtException = (e) => catchError(e, "Uncaught Exception", "uncaughtException"); + const unhandledRejection = (e) => catchError(e, "Unhandled Rejection", "unhandledRejection"); + process.on("uncaughtException", uncaughtException); + process.on("unhandledRejection", unhandledRejection); + dispose.push(() => { + process.off("uncaughtException", uncaughtException); + process.off("unhandledRejection", unhandledRejection); + }); +} +const relativeIds = {}; +function getVitestImport(id, state) { + if (externalizeMap.has(id)) return { externalize: externalizeMap.get(id) }; + // always externalize Vitest because we import from there before running tests + // so we already have it cached by Node.js + const root = state().config.root; + const relativeRoot = relativeIds[root] ?? (relativeIds[root] = normalizedDistDir.slice(root.length)); + if (id.includes(distDir) || id.includes(normalizedDistDir) || relativeRoot && relativeRoot !== "/" && id.startsWith(relativeRoot)) { + const { path } = toFilePath(id, root); + const externalize = pathToFileURL(path).toString(); + externalizeMap.set(id, externalize); + return { externalize }; + } + if (bareVitestRegexp.test(id)) { + externalizeMap.set(id, id); + return { externalize: id }; + } + return null; +} +async function startVitestExecutor(options) { + const state = () => globalThis.__vitest_worker__ || options.state; + const rpc = () => state().rpc; + process.exit = (code = process.exitCode || 0) => { + throw new Error(`process.exit unexpectedly called with "${code}"`); + }; + listenForErrors(state); + const getTransformMode = () => { + return state().environment.transformMode ?? "ssr"; + }; + return await createVitestExecutor({ + async fetchModule(id) { + const vitest = getVitestImport(id, state); + if (vitest) return vitest; + const result = await rpc().fetch(id, getTransformMode()); + if (result.id && !result.externalize) { + const code = readFileSync(result.id, "utf-8"); + return { code }; + } + return result; + }, + resolveId(id, importer) { + return rpc().resolveId(id, importer, getTransformMode()); + }, + get moduleCache() { + return state().moduleCache; + }, + get moduleExecutionInfo() { + return state().moduleExecutionInfo; + }, + get interopDefault() { + return state().config.deps.interopDefault; + }, + get moduleDirectories() { + return state().config.deps.moduleDirectories; + }, + get root() { + return state().config.root; + }, + get base() { + return state().config.base; + }, + ...options + }); +} +function updateStyle(id, css) { + if (typeof document === "undefined") return; + const element = document.querySelector(`[data-vite-dev-id="${id}"]`); + if (element) { + element.textContent = css; + return; + } + const head = document.querySelector("head"); + const style = document.createElement("style"); + style.setAttribute("type", "text/css"); + style.setAttribute("data-vite-dev-id", id); + style.textContent = css; + head?.appendChild(style); +} +function removeStyle(id) { + if (typeof document === "undefined") return; + const sheet = document.querySelector(`[data-vite-dev-id="${id}"]`); + if (sheet) document.head.removeChild(sheet); +} +function getDefaultRequestStubs(context) { + if (!context) { + const clientStub = { + ...DEFAULT_REQUEST_STUBS["@vite/client"], + updateStyle, + removeStyle + }; + return { + "/@vite/client": clientStub, + "@vite/client": clientStub + }; + } + const clientStub = vm.runInContext(`(defaultClient) => ({ ...defaultClient, updateStyle: ${updateStyle.toString()}, removeStyle: ${removeStyle.toString()} })`, context)(DEFAULT_REQUEST_STUBS["@vite/client"]); + return { + "/@vite/client": clientStub, + "@vite/client": clientStub + }; +} +class VitestExecutor extends ViteNodeRunner { + mocker; + externalModules; + primitives; + constructor(options) { + super({ + ...options, + interopDefault: options.context ? false : options.interopDefault + }); + this.options = options; + this.mocker = new VitestMocker(this); + if (!options.context) { + Object.defineProperty(globalThis, "__vitest_mocker__", { + value: this.mocker, + writable: true, + configurable: true + }); + this.primitives = { + Object, + Reflect, + Symbol + }; + } else if (options.externalModulesExecutor) { + this.primitives = vm.runInContext("({ Object, Reflect, Symbol })", options.context); + this.externalModules = options.externalModulesExecutor; + } else throw new Error("When context is provided, externalModulesExecutor must be provided as well."); + } + getContextPrimitives() { + return this.primitives; + } + get state() { + // @ts-expect-error injected untyped global + return globalThis.__vitest_worker__ || this.options.state; + } + get moduleExecutionInfo() { + return this.options.moduleExecutionInfo; + } + shouldResolveId(id, _importee) { + if (isInternalRequest(id) || id.startsWith("data:")) return false; + const transformMode = this.state.environment?.transformMode ?? "ssr"; + // do not try and resolve node builtins in Node + // import('url') returns Node internal even if 'url' package is installed + return transformMode === "ssr" ? !isNodeBuiltin$1(id) : !id.startsWith("node:"); + } + async originalResolveUrl(id, importer) { + return super.resolveUrl(id, importer); + } + async resolveUrl(id, importer) { + if (VitestMocker.pendingIds.length) await this.mocker.resolveMocks(); + if (importer && importer.startsWith("mock:")) importer = importer.slice(5); + try { + return await super.resolveUrl(id, importer); + } catch (error) { + if (error.code === "ERR_MODULE_NOT_FOUND") { + const { id } = error[Symbol.for("vitest.error.not_found.data")]; + const path = this.mocker.normalizePath(id); + const mock = this.mocker.getDependencyMock(path); + if (mock !== void 0) return [id, id]; + } + throw error; + } + } + async runModule(context, transformed) { + const vmContext = this.options.context; + if (!vmContext || !this.externalModules) return super.runModule(context, transformed); + // add 'use strict' since ESM enables it by default + const codeDefinition = `'use strict';async (${Object.keys(context).join(",")})=>{{`; + const code = `${codeDefinition}${transformed}\n}}`; + const options = { + filename: context.__filename, + lineOffset: 0, + columnOffset: -codeDefinition.length + }; + const finishModuleExecutionInfo = this.startCalculateModuleExecutionInfo(options.filename, codeDefinition.length); + try { + const fn = vm.runInContext(code, vmContext, { + ...options, + importModuleDynamically: this.externalModules.importModuleDynamically + }); + await fn(...Object.values(context)); + } finally { + this.options.moduleExecutionInfo?.set(options.filename, finishModuleExecutionInfo()); + } + } + async importExternalModule(path) { + if (this.externalModules) return this.externalModules.import(path); + return super.importExternalModule(path); + } + async dependencyRequest(id, fsPath, callstack) { + const mocked = await this.mocker.requestWithMock(fsPath, callstack); + if (typeof mocked === "string") return super.dependencyRequest(mocked, mocked, callstack); + if (mocked && typeof mocked === "object") return mocked; + return super.dependencyRequest(id, fsPath, callstack); + } + prepareContext(context) { + // support `import.meta.vitest` for test entry + if (this.state.filepath && normalize$1(this.state.filepath) === normalize$1(context.__filename)) { + const globalNamespace = this.options.context || globalThis; + Object.defineProperty(context.__vite_ssr_import_meta__, "vitest", { get: () => globalNamespace.__vitest_index__ }); + } + if (this.options.context && this.externalModules) context.require = this.externalModules.createRequire(context.__filename); + return context; + } +} + +export { VitestExecutor as V, getDefaultRequestStubs as g, startVitestExecutor as s }; diff --git a/node_modules/vitest/dist/chunks/git.BVQ8w_Sw.js b/node_modules/vitest/dist/chunks/git.BVQ8w_Sw.js new file mode 100644 index 0000000000..d13e265ebf --- /dev/null +++ b/node_modules/vitest/dist/chunks/git.BVQ8w_Sw.js @@ -0,0 +1,72 @@ +import { resolve } from 'pathe'; +import { x } from 'tinyexec'; + +class VitestGit { + root; + constructor(cwd) { + this.cwd = cwd; + } + async resolveFilesWithGitCommand(args) { + let result; + try { + result = await x("git", args, { nodeOptions: { cwd: this.root } }); + } catch (e) { + e.message = e.stderr; + throw e; + } + return result.stdout.split("\n").filter((s) => s !== "").map((changedPath) => resolve(this.root, changedPath)); + } + async findChangedFiles(options) { + const root = await this.getRoot(this.cwd); + if (!root) return null; + this.root = root; + const changedSince = options.changedSince; + if (typeof changedSince === "string") { + const [committed, staged, unstaged] = await Promise.all([ + this.getFilesSince(changedSince), + this.getStagedFiles(), + this.getUnstagedFiles() + ]); + return [ + ...committed, + ...staged, + ...unstaged + ]; + } + const [staged, unstaged] = await Promise.all([this.getStagedFiles(), this.getUnstagedFiles()]); + return [...staged, ...unstaged]; + } + getFilesSince(hash) { + return this.resolveFilesWithGitCommand([ + "diff", + "--name-only", + `${hash}...HEAD` + ]); + } + getStagedFiles() { + return this.resolveFilesWithGitCommand([ + "diff", + "--cached", + "--name-only" + ]); + } + getUnstagedFiles() { + return this.resolveFilesWithGitCommand([ + "ls-files", + "--other", + "--modified", + "--exclude-standard" + ]); + } + async getRoot(cwd) { + const args = ["rev-parse", "--show-cdup"]; + try { + const result = await x("git", args, { nodeOptions: { cwd } }); + return resolve(cwd, result.stdout.trim()); + } catch { + return null; + } + } +} + +export { VitestGit }; diff --git a/node_modules/vitest/dist/chunks/global.d.MAmajcmJ.d.ts b/node_modules/vitest/dist/chunks/global.d.MAmajcmJ.d.ts new file mode 100644 index 0000000000..3fa6a6e96f --- /dev/null +++ b/node_modules/vitest/dist/chunks/global.d.MAmajcmJ.d.ts @@ -0,0 +1,136 @@ +import { PromisifyAssertion, Tester, ExpectStatic } from '@vitest/expect'; +import { Plugin } from '@vitest/pretty-format'; +import { SnapshotState } from '@vitest/snapshot'; +import { B as BenchmarkResult } from './benchmark.d.BwvBVTda.js'; +import { U as UserConsoleLog } from './environment.d.cL3nLXbE.js'; + +type RawErrsMap = Map; +interface TscErrorInfo { + filePath: string; + errCode: number; + errMsg: string; + line: number; + column: number; +} +interface CollectLineNumbers { + target: number; + next: number; + prev?: number; +} +type CollectLines = { [key in keyof CollectLineNumbers] : string }; +interface RootAndTarget { + root: string; + targetAbsPath: string; +} +type Context = RootAndTarget & { + rawErrsMap: RawErrsMap + openedDirs: Set + lastActivePath?: string +}; + +declare global { + // eslint-disable-next-line ts/no-namespace + namespace Chai { + interface Assertion { + containSubset: (expected: any) => Assertion; + } + interface Assert { + containSubset: (val: any, exp: any, msg?: string) => void; + } + } +} +interface SnapshotMatcher { + (snapshot: Partial, hint?: string): void; + (hint?: string): void; +} +interface InlineSnapshotMatcher { + (properties: Partial, snapshot?: string, hint?: string): void; + (hint?: string): void; +} +declare module "@vitest/expect" { + interface MatcherState { + environment: string; + snapshotState: SnapshotState; + } + interface ExpectPollOptions { + interval?: number; + timeout?: number; + message?: string; + } + interface ExpectStatic { + unreachable: (message?: string) => never; + soft: (actual: T, message?: string) => Assertion; + poll: (actual: () => T, options?: ExpectPollOptions) => PromisifyAssertion>; + addEqualityTesters: (testers: Array) => void; + assertions: (expected: number) => void; + hasAssertions: () => void; + addSnapshotSerializer: (plugin: Plugin) => void; + } + interface Assertion { + // Snapshots are extended in @vitest/snapshot and are not part of @vitest/expect + matchSnapshot: SnapshotMatcher; + toMatchSnapshot: SnapshotMatcher; + toMatchInlineSnapshot: InlineSnapshotMatcher; + /** + * Checks that an error thrown by a function matches a previously recorded snapshot. + * + * @param hint - Optional custom error message. + * + * @example + * expect(functionWithError).toThrowErrorMatchingSnapshot(); + */ + toThrowErrorMatchingSnapshot: (hint?: string) => void; + /** + * Checks that an error thrown by a function matches an inline snapshot within the test file. + * Useful for keeping snapshots close to the test code. + * + * @param snapshot - Optional inline snapshot string to match. + * @param hint - Optional custom error message. + * + * @example + * const throwError = () => { throw new Error('Error occurred') }; + * expect(throwError).toThrowErrorMatchingInlineSnapshot(`"Error occurred"`); + */ + toThrowErrorMatchingInlineSnapshot: (snapshot?: string, hint?: string) => void; + /** + * Compares the received value to a snapshot saved in a specified file. + * Useful for cases where snapshot content is large or needs to be shared across tests. + * + * @param filepath - Path to the snapshot file. + * @param hint - Optional custom error message. + * + * @example + * await expect(largeData).toMatchFileSnapshot('path/to/snapshot.json'); + */ + toMatchFileSnapshot: (filepath: string, hint?: string) => Promise; + } +} +declare module "@vitest/runner" { + interface TestContext { + /** + * `expect` instance bound to the current test. + * + * This API is useful for running snapshot tests concurrently because global expect cannot track them. + */ + readonly expect: ExpectStatic; + /** @internal */ + _local: boolean; + } + interface TaskMeta { + typecheck?: boolean; + benchmark?: boolean; + failScreenshotPath?: string; + } + interface File { + prepareDuration?: number; + environmentLoad?: number; + } + interface TaskBase { + logs?: UserConsoleLog[]; + } + interface TaskResult { + benchmark?: BenchmarkResult; + } +} + +export type { CollectLineNumbers as C, RawErrsMap as R, TscErrorInfo as T, CollectLines as a, RootAndTarget as b, Context as c }; diff --git a/node_modules/vitest/dist/chunks/globals.DEHgCU4V.js b/node_modules/vitest/dist/chunks/globals.DEHgCU4V.js new file mode 100644 index 0000000000..6404167848 --- /dev/null +++ b/node_modules/vitest/dist/chunks/globals.DEHgCU4V.js @@ -0,0 +1,26 @@ +import { g as globalApis } from './constants.DnKduX2e.js'; +import { V as VitestIndex } from './index.CdQS2e2Q.js'; +import './vi.bdSIJ99Y.js'; +import '@vitest/expect'; +import '@vitest/runner'; +import '@vitest/runner/utils'; +import 'chai'; +import './utils.XdZDrNZV.js'; +import '@vitest/utils'; +import './_commonjsHelpers.BFTU3MAI.js'; +import '@vitest/snapshot'; +import '@vitest/utils/error'; +import '@vitest/spy'; +import '@vitest/utils/source-map'; +import './date.Bq6ZW5rf.js'; +import './benchmark.CYdenmiT.js'; +import 'expect-type'; + +function registerApiGlobally() { + globalApis.forEach((api) => { + // @ts-expect-error I know what I am doing :P + globalThis[api] = VitestIndex[api]; + }); +} + +export { registerApiGlobally }; diff --git a/node_modules/vitest/dist/chunks/index.B521nVV-.js b/node_modules/vitest/dist/chunks/index.B521nVV-.js new file mode 100644 index 0000000000..e0ecf12950 --- /dev/null +++ b/node_modules/vitest/dist/chunks/index.B521nVV-.js @@ -0,0 +1,157 @@ +const TYPE_REQUEST = "q"; +const TYPE_RESPONSE = "s"; +const DEFAULT_TIMEOUT = 6e4; +function defaultSerialize(i) { + return i; +} +const defaultDeserialize = defaultSerialize; +const { clearTimeout, setTimeout } = globalThis; +const random = Math.random.bind(Math); +function createBirpc(functions, options) { + const { + post, + on, + off = () => { + }, + eventNames = [], + serialize = defaultSerialize, + deserialize = defaultDeserialize, + resolver, + bind = "rpc", + timeout = DEFAULT_TIMEOUT + } = options; + const rpcPromiseMap = /* @__PURE__ */ new Map(); + let _promise; + let closed = false; + const rpc = new Proxy({}, { + get(_, method) { + if (method === "$functions") + return functions; + if (method === "$close") + return close; + if (method === "$closed") + return closed; + if (method === "then" && !eventNames.includes("then") && !("then" in functions)) + return undefined; + const sendEvent = (...args) => { + post(serialize({ m: method, a: args, t: TYPE_REQUEST })); + }; + if (eventNames.includes(method)) { + sendEvent.asEvent = sendEvent; + return sendEvent; + } + const sendCall = async (...args) => { + if (closed) + throw new Error(`[birpc] rpc is closed, cannot call "${method}"`); + if (_promise) { + try { + await _promise; + } finally { + _promise = undefined; + } + } + return new Promise((resolve, reject) => { + const id = nanoid(); + let timeoutId; + if (timeout >= 0) { + timeoutId = setTimeout(() => { + try { + const handleResult = options.onTimeoutError?.(method, args); + if (handleResult !== true) + throw new Error(`[birpc] timeout on calling "${method}"`); + } catch (e) { + reject(e); + } + rpcPromiseMap.delete(id); + }, timeout); + if (typeof timeoutId === "object") + timeoutId = timeoutId.unref?.(); + } + rpcPromiseMap.set(id, { resolve, reject, timeoutId, method }); + post(serialize({ m: method, a: args, i: id, t: "q" })); + }); + }; + sendCall.asEvent = sendEvent; + return sendCall; + } + }); + function close(error) { + closed = true; + rpcPromiseMap.forEach(({ reject, method }) => { + reject(error || new Error(`[birpc] rpc is closed, cannot call "${method}"`)); + }); + rpcPromiseMap.clear(); + off(onMessage); + } + async function onMessage(data, ...extra) { + let msg; + try { + msg = deserialize(data); + } catch (e) { + if (options.onGeneralError?.(e) !== true) + throw e; + return; + } + if (msg.t === TYPE_REQUEST) { + const { m: method, a: args } = msg; + let result, error; + const fn = resolver ? resolver(method, functions[method]) : functions[method]; + if (!fn) { + error = new Error(`[birpc] function "${method}" not found`); + } else { + try { + result = await fn.apply(bind === "rpc" ? rpc : functions, args); + } catch (e) { + error = e; + } + } + if (msg.i) { + if (error && options.onError) + options.onError(error, method, args); + if (error && options.onFunctionError) { + if (options.onFunctionError(error, method, args) === true) + return; + } + if (!error) { + try { + post(serialize({ t: TYPE_RESPONSE, i: msg.i, r: result }), ...extra); + return; + } catch (e) { + error = e; + if (options.onGeneralError?.(e, method, args) !== true) + throw e; + } + } + try { + post(serialize({ t: TYPE_RESPONSE, i: msg.i, e: error }), ...extra); + } catch (e) { + if (options.onGeneralError?.(e, method, args) !== true) + throw e; + } + } + } else { + const { i: ack, r: result, e: error } = msg; + const promise = rpcPromiseMap.get(ack); + if (promise) { + clearTimeout(promise.timeoutId); + if (error) + promise.reject(error); + else + promise.resolve(result); + } + rpcPromiseMap.delete(ack); + } + } + _promise = on(onMessage); + return rpc; +} +const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; +function nanoid(size = 21) { + let id = ""; + let i = size; + while (i--) + id += urlAlphabet[random() * 64 | 0]; + return id; +} + +export { createBirpc as c }; diff --git a/node_modules/vitest/dist/chunks/index.BCWujgDG.js b/node_modules/vitest/dist/chunks/index.BCWujgDG.js new file mode 100644 index 0000000000..429903321d --- /dev/null +++ b/node_modules/vitest/dist/chunks/index.BCWujgDG.js @@ -0,0 +1,231 @@ +import fs from 'node:fs'; +import { getTasks, getFullName, getTests } from '@vitest/runner/utils'; +import * as pathe from 'pathe'; +import c from 'tinyrainbow'; +import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName } from './index.VByaPkjc.js'; +import { stripVTControlCharacters } from 'node:util'; +import { notNullish } from '@vitest/utils'; + +function createBenchmarkJsonReport(files) { + const report = { files: [] }; + for (const file of files) { + const groups = []; + for (const task of getTasks(file)) if (task?.type === "suite") { + const benchmarks = []; + for (const t of task.tasks) { + const benchmark = t.meta.benchmark && t.result?.benchmark; + if (benchmark) benchmarks.push({ + id: t.id, + ...benchmark, + samples: [] + }); + } + if (benchmarks.length) groups.push({ + fullName: getFullName(task, " > "), + benchmarks + }); + } + report.files.push({ + filepath: file.filepath, + groups + }); + } + return report; +} +function flattenFormattedBenchmarkReport(report) { + const flat = {}; + for (const file of report.files) for (const group of file.groups) for (const t of group.benchmarks) flat[t.id] = t; + return flat; +} + +const outputMap = /* @__PURE__ */ new WeakMap(); +function formatNumber(number) { + const res = String(number.toFixed(number < 100 ? 4 : 2)).split("."); + return res[0].replace(/(?=(?:\d{3})+$)\B/g, ",") + (res[1] ? `.${res[1]}` : ""); +} +const tableHead = [ + "name", + "hz", + "min", + "max", + "mean", + "p75", + "p99", + "p995", + "p999", + "rme", + "samples" +]; +function renderBenchmarkItems(result) { + return [ + result.name, + formatNumber(result.hz || 0), + formatNumber(result.min || 0), + formatNumber(result.max || 0), + formatNumber(result.mean || 0), + formatNumber(result.p75 || 0), + formatNumber(result.p99 || 0), + formatNumber(result.p995 || 0), + formatNumber(result.p999 || 0), + `±${(result.rme || 0).toFixed(2)}%`, + (result.sampleCount || 0).toString() + ]; +} +function computeColumnWidths(results) { + const rows = [tableHead, ...results.map((v) => renderBenchmarkItems(v))]; + return Array.from(tableHead, (_, i) => Math.max(...rows.map((row) => stripVTControlCharacters(row[i]).length))); +} +function padRow(row, widths) { + return row.map((v, i) => i ? v.padStart(widths[i], " ") : v.padEnd(widths[i], " ")); +} +function renderTableHead(widths) { + return " ".repeat(3) + padRow(tableHead, widths).map(c.bold).join(" "); +} +function renderBenchmark(result, widths) { + const padded = padRow(renderBenchmarkItems(result), widths); + return [ + padded[0], + c.blue(padded[1]), + c.cyan(padded[2]), + c.cyan(padded[3]), + c.cyan(padded[4]), + c.cyan(padded[5]), + c.cyan(padded[6]), + c.cyan(padded[7]), + c.cyan(padded[8]), + c.dim(padded[9]), + c.dim(padded[10]) + ].join(" "); +} +function renderTable(options) { + const output = []; + const benchMap = {}; + for (const task of options.tasks) if (task.meta.benchmark && task.result?.benchmark) benchMap[task.id] = { + current: task.result.benchmark, + baseline: options.compare?.[task.id] + }; + const benchCount = Object.entries(benchMap).length; + const columnWidths = computeColumnWidths(Object.values(benchMap).flatMap((v) => [v.current, v.baseline]).filter(notNullish)); + let idx = 0; + const padding = " ".repeat(1 ); + for (const task of options.tasks) { + const duration = task.result?.duration; + const bench = benchMap[task.id]; + let prefix = ""; + if (idx === 0 && task.meta?.benchmark) prefix += `${renderTableHead(columnWidths)}\n${padding}`; + prefix += ` ${getStateSymbol(task)} `; + let suffix = ""; + if (task.type === "suite") suffix += c.dim(` (${getTests(task).length})`); + if (task.mode === "skip" || task.mode === "todo") suffix += c.dim(c.gray(" [skipped]")); + if (duration != null) { + const color = duration > options.slowTestThreshold ? c.yellow : c.green; + suffix += color(` ${Math.round(duration)}${c.dim("ms")}`); + } + if (options.showHeap && task.result?.heap != null) suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`); + if (bench) { + let body = renderBenchmark(bench.current, columnWidths); + if (options.compare && bench.baseline) { + if (bench.current.hz) { + const diff = bench.current.hz / bench.baseline.hz; + const diffFixed = diff.toFixed(2); + if (diffFixed === "1.0.0") body += c.gray(` [${diffFixed}x]`); + if (diff > 1) body += c.blue(` [${diffFixed}x] ⇑`); + else body += c.red(` [${diffFixed}x] ⇓`); + } + output.push(padding + prefix + body + suffix); + const bodyBaseline = renderBenchmark(bench.baseline, columnWidths); + output.push(`${padding} ${bodyBaseline} ${c.dim("(baseline)")}`); + } else { + if (bench.current.rank === 1 && benchCount > 1) body += c.bold(c.green(" fastest")); + if (bench.current.rank === benchCount && benchCount > 2) body += c.bold(c.gray(" slowest")); + output.push(padding + prefix + body + suffix); + } + } else output.push(padding + prefix + task.name + suffix); + if (task.result?.state !== "pass" && outputMap.get(task) != null) { + let data = outputMap.get(task); + if (typeof data === "string") { + data = stripVTControlCharacters(data.trim().split("\n").filter(Boolean).pop()); + if (data === "") data = void 0; + } + if (data != null) { + const out = ` ${" ".repeat(options.level)}${F_RIGHT} ${data}`; + output.push(c.gray(truncateString(out, options.columns))); + } + } + idx++; + } + return output.filter(Boolean).join("\n"); +} + +class BenchmarkReporter extends DefaultReporter { + compare; + async onInit(ctx) { + super.onInit(ctx); + if (this.ctx.config.benchmark?.compare) { + const compareFile = pathe.resolve(this.ctx.config.root, this.ctx.config.benchmark?.compare); + try { + this.compare = flattenFormattedBenchmarkReport(JSON.parse(await fs.promises.readFile(compareFile, "utf-8"))); + } catch (e) { + this.error(`Failed to read '${compareFile}'`, e); + } + } + } + onTaskUpdate(packs) { + for (const pack of packs) { + const task = this.ctx.state.idMap.get(pack[0]); + if (task?.type === "suite" && task.result?.state !== "run") task.tasks.filter((task) => task.result?.benchmark).sort((benchA, benchB) => benchA.result.benchmark.mean - benchB.result.benchmark.mean).forEach((bench, idx) => { + bench.result.benchmark.rank = Number(idx) + 1; + }); + } + } + onTestSuiteResult(testSuite) { + super.onTestSuiteResult(testSuite); + this.printSuiteTable(testSuite); + } + printTestModule(testModule) { + this.printSuiteTable(testModule); + } + printSuiteTable(testTask) { + const state = testTask.state(); + if (state === "pending" || state === "queued") return; + const benches = testTask.task.tasks.filter((t) => t.meta.benchmark); + const duration = testTask.task.result?.duration || 0; + if (benches.length > 0 && benches.every((t) => t.result?.state !== "run" && t.result?.state !== "queued")) { + let title = `\n ${getStateSymbol(testTask.task)} ${formatProjectName(testTask.project)}${getFullName(testTask.task, c.dim(" > "))}`; + if (duration != null && duration > this.ctx.config.slowTestThreshold) title += c.yellow(` ${Math.round(duration)}${c.dim("ms")}`); + this.log(title); + this.log(renderTable({ + tasks: benches, + level: 1, + columns: this.ctx.logger.getColumns(), + compare: this.compare, + showHeap: this.ctx.config.logHeapUsage, + slowTestThreshold: this.ctx.config.slowTestThreshold + })); + } + } + async onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) { + super.onFinished(files, errors); + // write output for future comparison + let outputFile = this.ctx.config.benchmark?.outputJson; + if (outputFile) { + outputFile = pathe.resolve(this.ctx.config.root, outputFile); + const outputDirectory = pathe.dirname(outputFile); + if (!fs.existsSync(outputDirectory)) await fs.promises.mkdir(outputDirectory, { recursive: true }); + const output = createBenchmarkJsonReport(files); + await fs.promises.writeFile(outputFile, JSON.stringify(output, null, 2)); + this.log(`Benchmark report written to ${outputFile}`); + } + } +} + +class VerboseBenchmarkReporter extends BenchmarkReporter { + verbose = true; +} + +const BenchmarkReportsMap = { + default: BenchmarkReporter, + verbose: VerboseBenchmarkReporter +}; + +export { BenchmarkReporter as B, VerboseBenchmarkReporter as V, BenchmarkReportsMap as a }; diff --git a/node_modules/vitest/dist/chunks/index.CdQS2e2Q.js b/node_modules/vitest/dist/chunks/index.CdQS2e2Q.js new file mode 100644 index 0000000000..b3c5154c9f --- /dev/null +++ b/node_modules/vitest/dist/chunks/index.CdQS2e2Q.js @@ -0,0 +1,37 @@ +import { c as createExpect, a as globalExpect, i as inject, v as vi, b as vitest } from './vi.bdSIJ99Y.js'; +import { b as bench } from './benchmark.CYdenmiT.js'; +import { expectTypeOf } from 'expect-type'; +import { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner'; +import * as chai from 'chai'; +import { assert, should } from 'chai'; + +const assertType = function assertType() {}; + +// TODO: deprecate in favor of `` + +var VitestIndex = /*#__PURE__*/Object.freeze({ + __proto__: null, + afterAll: afterAll, + afterEach: afterEach, + assert: assert, + assertType: assertType, + beforeAll: beforeAll, + beforeEach: beforeEach, + bench: bench, + chai: chai, + createExpect: createExpect, + describe: describe, + expect: globalExpect, + expectTypeOf: expectTypeOf, + inject: inject, + it: it, + onTestFailed: onTestFailed, + onTestFinished: onTestFinished, + should: should, + suite: suite, + test: test, + vi: vi, + vitest: vitest +}); + +export { VitestIndex as V, assertType as a }; diff --git a/node_modules/vitest/dist/chunks/index.CmSc2RE5.js b/node_modules/vitest/dist/chunks/index.CmSc2RE5.js new file mode 100644 index 0000000000..90004b3064 --- /dev/null +++ b/node_modules/vitest/dist/chunks/index.CmSc2RE5.js @@ -0,0 +1,587 @@ +import { Console } from 'node:console'; + +// SEE https://github.com/jsdom/jsdom/blob/master/lib/jsdom/living/interfaces.js +const LIVING_KEYS = [ + "DOMException", + "URL", + "URLSearchParams", + "EventTarget", + "NamedNodeMap", + "Node", + "Attr", + "Element", + "DocumentFragment", + "DOMImplementation", + "Document", + "XMLDocument", + "CharacterData", + "Text", + "CDATASection", + "ProcessingInstruction", + "Comment", + "DocumentType", + "NodeList", + "RadioNodeList", + "HTMLCollection", + "HTMLOptionsCollection", + "DOMStringMap", + "DOMTokenList", + "StyleSheetList", + "HTMLElement", + "HTMLHeadElement", + "HTMLTitleElement", + "HTMLBaseElement", + "HTMLLinkElement", + "HTMLMetaElement", + "HTMLStyleElement", + "HTMLBodyElement", + "HTMLHeadingElement", + "HTMLParagraphElement", + "HTMLHRElement", + "HTMLPreElement", + "HTMLUListElement", + "HTMLOListElement", + "HTMLLIElement", + "HTMLMenuElement", + "HTMLDListElement", + "HTMLDivElement", + "HTMLAnchorElement", + "HTMLAreaElement", + "HTMLBRElement", + "HTMLButtonElement", + "HTMLCanvasElement", + "HTMLDataElement", + "HTMLDataListElement", + "HTMLDetailsElement", + "HTMLDialogElement", + "HTMLDirectoryElement", + "HTMLFieldSetElement", + "HTMLFontElement", + "HTMLFormElement", + "HTMLHtmlElement", + "HTMLImageElement", + "HTMLInputElement", + "HTMLLabelElement", + "HTMLLegendElement", + "HTMLMapElement", + "HTMLMarqueeElement", + "HTMLMediaElement", + "HTMLMeterElement", + "HTMLModElement", + "HTMLOptGroupElement", + "HTMLOptionElement", + "HTMLOutputElement", + "HTMLPictureElement", + "HTMLProgressElement", + "HTMLQuoteElement", + "HTMLScriptElement", + "HTMLSelectElement", + "HTMLSlotElement", + "HTMLSourceElement", + "HTMLSpanElement", + "HTMLTableCaptionElement", + "HTMLTableCellElement", + "HTMLTableColElement", + "HTMLTableElement", + "HTMLTimeElement", + "HTMLTableRowElement", + "HTMLTableSectionElement", + "HTMLTemplateElement", + "HTMLTextAreaElement", + "HTMLUnknownElement", + "HTMLFrameElement", + "HTMLFrameSetElement", + "HTMLIFrameElement", + "HTMLEmbedElement", + "HTMLObjectElement", + "HTMLParamElement", + "HTMLVideoElement", + "HTMLAudioElement", + "HTMLTrackElement", + "HTMLFormControlsCollection", + "SVGElement", + "SVGGraphicsElement", + "SVGSVGElement", + "SVGTitleElement", + "SVGAnimatedString", + "SVGNumber", + "SVGStringList", + "Event", + "CloseEvent", + "CustomEvent", + "MessageEvent", + "ErrorEvent", + "HashChangeEvent", + "PopStateEvent", + "StorageEvent", + "ProgressEvent", + "PageTransitionEvent", + "SubmitEvent", + "UIEvent", + "FocusEvent", + "InputEvent", + "MouseEvent", + "KeyboardEvent", + "TouchEvent", + "CompositionEvent", + "WheelEvent", + "BarProp", + "External", + "Location", + "History", + "Screen", + "Crypto", + "Performance", + "Navigator", + "PluginArray", + "MimeTypeArray", + "Plugin", + "MimeType", + "FileReader", + "Blob", + "File", + "FileList", + "ValidityState", + "DOMParser", + "XMLSerializer", + "FormData", + "XMLHttpRequestEventTarget", + "XMLHttpRequestUpload", + "XMLHttpRequest", + "WebSocket", + "NodeFilter", + "NodeIterator", + "TreeWalker", + "AbstractRange", + "Range", + "StaticRange", + "Selection", + "Storage", + "CustomElementRegistry", + "ShadowRoot", + "MutationObserver", + "MutationRecord", + "Headers", + "AbortController", + "AbortSignal", + "Uint8Array", + "Uint16Array", + "Uint32Array", + "Uint8ClampedArray", + "Int8Array", + "Int16Array", + "Int32Array", + "Float32Array", + "Float64Array", + "ArrayBuffer", + "DOMRectReadOnly", + "DOMRect", + "Image", + "Audio", + "Option", + "CSS" +]; +const OTHER_KEYS = [ + "addEventListener", + "alert", + "blur", + "cancelAnimationFrame", + "close", + "confirm", + "createPopup", + "dispatchEvent", + "document", + "focus", + "frames", + "getComputedStyle", + "history", + "innerHeight", + "innerWidth", + "length", + "location", + "matchMedia", + "moveBy", + "moveTo", + "name", + "navigator", + "open", + "outerHeight", + "outerWidth", + "pageXOffset", + "pageYOffset", + "parent", + "postMessage", + "print", + "prompt", + "removeEventListener", + "requestAnimationFrame", + "resizeBy", + "resizeTo", + "screen", + "screenLeft", + "screenTop", + "screenX", + "screenY", + "scroll", + "scrollBy", + "scrollLeft", + "scrollTo", + "scrollTop", + "scrollX", + "scrollY", + "self", + "stop", + "top", + "Window", + "window" +]; +const KEYS = LIVING_KEYS.concat(OTHER_KEYS); + +const skipKeys = [ + "window", + "self", + "top", + "parent" +]; +function getWindowKeys(global, win, additionalKeys = []) { + const keysArray = [...additionalKeys, ...KEYS]; + const keys = new Set(keysArray.concat(Object.getOwnPropertyNames(win)).filter((k) => { + if (skipKeys.includes(k)) return false; + if (k in global) return keysArray.includes(k); + return true; + })); + return keys; +} +function isClassLikeName(name) { + return name[0] === name[0].toUpperCase(); +} +function populateGlobal(global, win, options = {}) { + const { bindFunctions = false } = options; + const keys = getWindowKeys(global, win, options.additionalKeys); + const originals = /* @__PURE__ */ new Map(); + const overrideObject = /* @__PURE__ */ new Map(); + for (const key of keys) { + const boundFunction = bindFunctions && typeof win[key] === "function" && !isClassLikeName(key) && win[key].bind(win); + if (KEYS.includes(key) && key in global) originals.set(key, global[key]); + Object.defineProperty(global, key, { + get() { + if (overrideObject.has(key)) return overrideObject.get(key); + if (boundFunction) return boundFunction; + return win[key]; + }, + set(v) { + overrideObject.set(key, v); + }, + configurable: true + }); + } + global.window = global; + global.self = global; + global.top = global; + global.parent = global; + if (global.global) global.global = global; + // rewrite defaultView to reference the same global context + if (global.document && global.document.defaultView) Object.defineProperty(global.document, "defaultView", { + get: () => global, + enumerable: true, + configurable: true + }); + skipKeys.forEach((k) => keys.add(k)); + return { + keys, + skipKeys, + originals + }; +} + +var edge = { + name: "edge-runtime", + transformMode: "ssr", + async setupVM() { + const { EdgeVM } = await import('@edge-runtime/vm'); + const vm = new EdgeVM({ extend: (context) => { + context.global = context; + context.Buffer = Buffer; + return context; + } }); + return { + getVmContext() { + return vm.context; + }, + teardown() { + // nothing to teardown + } + }; + }, + async setup(global) { + const { EdgeVM } = await import('@edge-runtime/vm'); + const vm = new EdgeVM({ extend: (context) => { + context.global = context; + context.Buffer = Buffer; + KEYS.forEach((key) => { + if (key in global) context[key] = global[key]; + }); + return context; + } }); + const { keys, originals } = populateGlobal(global, vm.context, { bindFunctions: true }); + return { teardown(global) { + keys.forEach((key) => delete global[key]); + originals.forEach((v, k) => global[k] = v); + } }; + } +}; + +async function teardownWindow(win) { + if (win.close && win.happyDOM.abort) { + await win.happyDOM.abort(); + win.close(); + } else win.happyDOM.cancelAsync(); +} +var happy = { + name: "happy-dom", + transformMode: "web", + async setupVM({ happyDOM = {} }) { + const { Window } = await import('happy-dom'); + let win = new Window({ + ...happyDOM, + console: console && globalThis.console ? globalThis.console : void 0, + url: happyDOM.url || "http://localhost:3000", + settings: { + ...happyDOM.settings, + disableErrorCapturing: true + } + }); + // TODO: browser doesn't expose Buffer, but a lot of dependencies use it + win.Buffer = Buffer; + // inject structuredClone if it exists + if (typeof structuredClone !== "undefined" && !win.structuredClone) win.structuredClone = structuredClone; + return { + getVmContext() { + return win; + }, + async teardown() { + await teardownWindow(win); + win = void 0; + } + }; + }, + async setup(global, { happyDOM = {} }) { + // happy-dom v3 introduced a breaking change to Window, but + // provides GlobalWindow as a way to use previous behaviour + const { Window, GlobalWindow } = await import('happy-dom'); + const win = new (GlobalWindow || Window)({ + ...happyDOM, + console: console && global.console ? global.console : void 0, + url: happyDOM.url || "http://localhost:3000", + settings: { + ...happyDOM.settings, + disableErrorCapturing: true + } + }); + const { keys, originals } = populateGlobal(global, win, { + bindFunctions: true, + additionalKeys: [ + "Request", + "Response", + "MessagePort", + "fetch" + ] + }); + return { async teardown(global) { + await teardownWindow(win); + keys.forEach((key) => delete global[key]); + originals.forEach((v, k) => global[k] = v); + } }; + } +}; + +function catchWindowErrors(window) { + let userErrorListenerCount = 0; + function throwUnhandlerError(e) { + if (userErrorListenerCount === 0 && e.error != null) process.emit("uncaughtException", e.error); + } + const addEventListener = window.addEventListener.bind(window); + const removeEventListener = window.removeEventListener.bind(window); + window.addEventListener("error", throwUnhandlerError); + window.addEventListener = function(...args) { + if (args[0] === "error") userErrorListenerCount++; + return addEventListener.apply(this, args); + }; + window.removeEventListener = function(...args) { + if (args[0] === "error" && userErrorListenerCount) userErrorListenerCount--; + return removeEventListener.apply(this, args); + }; + return function clearErrorHandlers() { + window.removeEventListener("error", throwUnhandlerError); + }; +} +var jsdom = { + name: "jsdom", + transformMode: "web", + async setupVM({ jsdom = {} }) { + const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = await import('jsdom'); + const { html = "", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom; + let dom = new JSDOM(html, { + pretendToBeVisual, + resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : void 0), + runScripts, + url, + virtualConsole: console && globalThis.console ? new VirtualConsole().sendTo(globalThis.console) : void 0, + cookieJar: cookieJar ? new CookieJar() : void 0, + includeNodeLocations, + contentType, + userAgent, + ...restOptions + }); + const clearWindowErrors = catchWindowErrors(dom.window); + // TODO: browser doesn't expose Buffer, but a lot of dependencies use it + dom.window.Buffer = Buffer; + dom.window.jsdom = dom; + // inject web globals if they missing in JSDOM but otherwise available in Nodejs + // https://nodejs.org/dist/latest/docs/api/globals.html + const globalNames = [ + "structuredClone", + "fetch", + "Request", + "Response", + "BroadcastChannel", + "MessageChannel", + "MessagePort", + "TextEncoder", + "TextDecoder" + ]; + for (const name of globalNames) { + const value = globalThis[name]; + if (typeof value !== "undefined" && typeof dom.window[name] === "undefined") dom.window[name] = value; + } + return { + getVmContext() { + return dom.getInternalVMContext(); + }, + teardown() { + clearWindowErrors(); + dom.window.close(); + dom = void 0; + } + }; + }, + async setup(global, { jsdom = {} }) { + const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = await import('jsdom'); + const { html = "", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom; + const dom = new JSDOM(html, { + pretendToBeVisual, + resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : void 0), + runScripts, + url, + virtualConsole: console && global.console ? new VirtualConsole().sendTo(global.console) : void 0, + cookieJar: cookieJar ? new CookieJar() : void 0, + includeNodeLocations, + contentType, + userAgent, + ...restOptions + }); + const { keys, originals } = populateGlobal(global, dom.window, { bindFunctions: true }); + const clearWindowErrors = catchWindowErrors(global); + global.jsdom = dom; + return { teardown(global) { + clearWindowErrors(); + dom.window.close(); + delete global.jsdom; + keys.forEach((key) => delete global[key]); + originals.forEach((v, k) => global[k] = v); + } }; + } +}; + +// some globals we do not want, either because deprecated or we set it ourselves +const denyList = new Set([ + "GLOBAL", + "root", + "global", + "Buffer", + "ArrayBuffer", + "Uint8Array" +]); +const nodeGlobals = new Map(Object.getOwnPropertyNames(globalThis).filter((global) => !denyList.has(global)).map((nodeGlobalsKey) => { + const descriptor = Object.getOwnPropertyDescriptor(globalThis, nodeGlobalsKey); + if (!descriptor) throw new Error(`No property descriptor for ${nodeGlobalsKey}, this is a bug in Vitest.`); + return [nodeGlobalsKey, descriptor]; +})); +var node = { + name: "node", + transformMode: "ssr", + async setupVM() { + const vm = await import('node:vm'); + let context = vm.createContext(); + let global = vm.runInContext("this", context); + const contextGlobals = new Set(Object.getOwnPropertyNames(global)); + for (const [nodeGlobalsKey, descriptor] of nodeGlobals) if (!contextGlobals.has(nodeGlobalsKey)) if (descriptor.configurable) Object.defineProperty(global, nodeGlobalsKey, { + configurable: true, + enumerable: descriptor.enumerable, + get() { + // @ts-expect-error: no index signature + const val = globalThis[nodeGlobalsKey]; + // override lazy getter + Object.defineProperty(global, nodeGlobalsKey, { + configurable: true, + enumerable: descriptor.enumerable, + value: val, + writable: descriptor.writable === true || nodeGlobalsKey === "performance" + }); + return val; + }, + set(val) { + // override lazy getter + Object.defineProperty(global, nodeGlobalsKey, { + configurable: true, + enumerable: descriptor.enumerable, + value: val, + writable: true + }); + } + }); + else if ("value" in descriptor) Object.defineProperty(global, nodeGlobalsKey, { + configurable: false, + enumerable: descriptor.enumerable, + value: descriptor.value, + writable: descriptor.writable + }); + else Object.defineProperty(global, nodeGlobalsKey, { + configurable: false, + enumerable: descriptor.enumerable, + get: descriptor.get, + set: descriptor.set + }); + global.global = global; + global.Buffer = Buffer; + global.ArrayBuffer = ArrayBuffer; + // TextEncoder (global or via 'util') references a Uint8Array constructor + // different than the global one used by users in tests. This makes sure the + // same constructor is referenced by both. + global.Uint8Array = Uint8Array; + return { + getVmContext() { + return context; + }, + teardown() { + context = void 0; + global = void 0; + } + }; + }, + async setup(global) { + global.console.Console = Console; + return { teardown(global) { + delete global.console.Console; + } }; + } +}; + +const environments = { + node, + jsdom, + "happy-dom": happy, + "edge-runtime": edge +}; + +export { environments as e, populateGlobal as p }; diff --git a/node_modules/vitest/dist/chunks/index.CwejwG0H.js b/node_modules/vitest/dist/chunks/index.CwejwG0H.js new file mode 100644 index 0000000000..f9a069d66b --- /dev/null +++ b/node_modules/vitest/dist/chunks/index.CwejwG0H.js @@ -0,0 +1,105 @@ +import * as chai from 'chai'; +import { resolve } from 'node:path'; +import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.Dd054P77.js'; +import { distDir } from '../path.js'; +import { r as rpc } from './rpc.-pEldfrD.js'; +import { g as getWorkerState } from './utils.XdZDrNZV.js'; + +function setupChaiConfig(config) { + Object.assign(chai.config, config); +} + +async function resolveSnapshotEnvironment(config, executor) { + if (!config.snapshotEnvironment) { + const { VitestNodeSnapshotEnvironment } = await import('./node.fjCdwEIl.js'); + return new VitestNodeSnapshotEnvironment(); + } + const mod = await executor.executeId(config.snapshotEnvironment); + if (typeof mod.default !== "object" || !mod.default) throw new Error("Snapshot environment module must have a default export object with a shape of `SnapshotEnvironment`"); + return mod.default; +} + +const runnersFile = resolve(distDir, "runners.js"); +async function getTestRunnerConstructor(config, executor) { + if (!config.runner) { + const { VitestTestRunner, NodeBenchmarkRunner } = await executor.executeFile(runnersFile); + return config.mode === "test" ? VitestTestRunner : NodeBenchmarkRunner; + } + const mod = await executor.executeId(config.runner); + if (!mod.default && typeof mod.default !== "function") throw new Error(`Runner must export a default function, but got ${typeof mod.default} imported from ${config.runner}`); + return mod.default; +} +async function resolveTestRunner(config, executor) { + const TestRunner = await getTestRunnerConstructor(config, executor); + const testRunner = new TestRunner(config); + // inject private executor to every runner + Object.defineProperty(testRunner, "__vitest_executor", { + value: executor, + enumerable: false, + configurable: false + }); + if (!testRunner.config) testRunner.config = config; + if (!testRunner.importFile) throw new Error("Runner must implement \"importFile\" method."); + const [diffOptions] = await Promise.all([loadDiffConfig(config, executor), loadSnapshotSerializers(config, executor)]); + testRunner.config.diffOptions = diffOptions; + // patch some methods, so custom runners don't need to call RPC + const originalOnTaskUpdate = testRunner.onTaskUpdate; + testRunner.onTaskUpdate = async (task, events) => { + const p = rpc().onTaskUpdate(task, events); + await originalOnTaskUpdate?.call(testRunner, task, events); + return p; + }; + // patch some methods, so custom runners don't need to call RPC + const originalOnTestAnnotate = testRunner.onTestAnnotate; + testRunner.onTestAnnotate = async (test, annotation) => { + const p = rpc().onTaskAnnotate(test.id, annotation); + const overridenResult = await originalOnTestAnnotate?.call(testRunner, test, annotation); + const vitestResult = await p; + return overridenResult || vitestResult; + }; + const originalOnCollectStart = testRunner.onCollectStart; + testRunner.onCollectStart = async (file) => { + await rpc().onQueued(file); + await originalOnCollectStart?.call(testRunner, file); + }; + const originalOnCollected = testRunner.onCollected; + testRunner.onCollected = async (files) => { + const state = getWorkerState(); + files.forEach((file) => { + file.prepareDuration = state.durations.prepare; + file.environmentLoad = state.durations.environment; + // should be collected only for a single test file in a batch + state.durations.prepare = 0; + state.durations.environment = 0; + }); + rpc().onCollected(files); + await originalOnCollected?.call(testRunner, files); + }; + const originalOnAfterRun = testRunner.onAfterRunFiles; + testRunner.onAfterRunFiles = async (files) => { + const state = getWorkerState(); + const coverage = await takeCoverageInsideWorker(config.coverage, executor); + if (coverage) rpc().onAfterSuiteRun({ + coverage, + testFiles: files.map((file) => file.name).sort(), + transformMode: state.environment.transformMode, + projectName: state.ctx.projectName + }); + await originalOnAfterRun?.call(testRunner, files); + }; + const originalOnAfterRunTask = testRunner.onAfterRunTask; + testRunner.onAfterRunTask = async (test) => { + if (config.bail && test.result?.state === "fail") { + const previousFailures = await rpc().getCountOfFailedTests(); + const currentFailures = 1 + previousFailures; + if (currentFailures >= config.bail) { + rpc().onCancel("test-failure"); + testRunner.cancel?.("test-failure"); + } + } + await originalOnAfterRunTask?.call(testRunner, test); + }; + return testRunner; +} + +export { resolveSnapshotEnvironment as a, resolveTestRunner as r, setupChaiConfig as s }; diff --git a/node_modules/vitest/dist/chunks/index.D3XRDfWc.js b/node_modules/vitest/dist/chunks/index.D3XRDfWc.js new file mode 100644 index 0000000000..5a69ef7636 --- /dev/null +++ b/node_modules/vitest/dist/chunks/index.D3XRDfWc.js @@ -0,0 +1,213 @@ +import process from 'node:process'; +import fs from 'node:fs/promises'; +import path, { resolve } from 'node:path'; +import { existsSync } from 'node:fs'; +import { x } from 'tinyexec'; + +const AGENTS = [ + "npm", + "yarn", + "yarn@berry", + "pnpm", + "pnpm@6", + "bun", + "deno" +]; +const LOCKS = { + "bun.lock": "bun", + "bun.lockb": "bun", + "deno.lock": "deno", + "pnpm-lock.yaml": "pnpm", + "pnpm-workspace.yaml": "pnpm", + "yarn.lock": "yarn", + "package-lock.json": "npm", + "npm-shrinkwrap.json": "npm" +}; +const INSTALL_METADATA = { + "node_modules/.deno/": "deno", + "node_modules/.pnpm/": "pnpm", + "node_modules/.yarn-state.yml": "yarn", + // yarn v2+ (node-modules) + "node_modules/.yarn_integrity": "yarn", + // yarn v1 + "node_modules/.package-lock.json": "npm", + ".pnp.cjs": "yarn", + // yarn v3+ (pnp) + ".pnp.js": "yarn", + // yarn v2 (pnp) + "bun.lock": "bun", + "bun.lockb": "bun" +}; + +async function pathExists(path2, type) { + try { + const stat = await fs.stat(path2); + return type === "file" ? stat.isFile() : stat.isDirectory(); + } catch { + return false; + } +} +function* lookup(cwd = process.cwd()) { + let directory = path.resolve(cwd); + const { root } = path.parse(directory); + while (directory && directory !== root) { + yield directory; + directory = path.dirname(directory); + } +} +async function parsePackageJson(filepath, onUnknown) { + return !filepath || !pathExists(filepath, "file") ? null : await handlePackageManager(filepath, onUnknown); +} +async function detect(options = {}) { + const { + cwd, + strategies = ["lockfile", "packageManager-field", "devEngines-field"], + onUnknown + } = options; + let stopDir; + if (typeof options.stopDir === "string") { + const resolved = path.resolve(options.stopDir); + stopDir = (dir) => dir === resolved; + } else { + stopDir = options.stopDir; + } + for (const directory of lookup(cwd)) { + for (const strategy of strategies) { + switch (strategy) { + case "lockfile": { + for (const lock of Object.keys(LOCKS)) { + if (await pathExists(path.join(directory, lock), "file")) { + const name = LOCKS[lock]; + const result = await parsePackageJson(path.join(directory, "package.json"), onUnknown); + if (result) + return result; + else + return { name, agent: name }; + } + } + break; + } + case "packageManager-field": + case "devEngines-field": { + const result = await parsePackageJson(path.join(directory, "package.json"), onUnknown); + if (result) + return result; + break; + } + case "install-metadata": { + for (const metadata of Object.keys(INSTALL_METADATA)) { + const fileOrDir = metadata.endsWith("/") ? "dir" : "file"; + if (await pathExists(path.join(directory, metadata), fileOrDir)) { + const name = INSTALL_METADATA[metadata]; + const agent = name === "yarn" ? isMetadataYarnClassic(metadata) ? "yarn" : "yarn@berry" : name; + return { name, agent }; + } + } + break; + } + } + } + if (stopDir?.(directory)) + break; + } + return null; +} +function getNameAndVer(pkg) { + const handelVer = (version) => version?.match(/\d+(\.\d+){0,2}/)?.[0] ?? version; + if (typeof pkg.packageManager === "string") { + const [name, ver] = pkg.packageManager.replace(/^\^/, "").split("@"); + return { name, ver: handelVer(ver) }; + } + if (typeof pkg.devEngines?.packageManager?.name === "string") { + return { + name: pkg.devEngines.packageManager.name, + ver: handelVer(pkg.devEngines.packageManager.version) + }; + } + return void 0; +} +async function handlePackageManager(filepath, onUnknown) { + try { + const pkg = JSON.parse(await fs.readFile(filepath, "utf8")); + let agent; + const nameAndVer = getNameAndVer(pkg); + if (nameAndVer) { + const name = nameAndVer.name; + const ver = nameAndVer.ver; + let version = ver; + if (name === "yarn" && ver && Number.parseInt(ver) > 1) { + agent = "yarn@berry"; + version = "berry"; + return { name, agent, version }; + } else if (name === "pnpm" && ver && Number.parseInt(ver) < 7) { + agent = "pnpm@6"; + return { name, agent, version }; + } else if (AGENTS.includes(name)) { + agent = name; + return { name, agent, version }; + } else { + return onUnknown?.(pkg.packageManager) ?? null; + } + } + } catch { + } + return null; +} +function isMetadataYarnClassic(metadataPath) { + return metadataPath.endsWith(".yarn_integrity"); +} + +// src/detect.ts +async function detectPackageManager(cwd = process.cwd()) { + const result = await detect({ + cwd, + onUnknown(packageManager) { + console.warn("[@antfu/install-pkg] Unknown packageManager:", packageManager); + return void 0; + } + }); + return result?.agent || null; +} +async function installPackage(names, options = {}) { + const detectedAgent = options.packageManager || await detectPackageManager(options.cwd) || "npm"; + const [agent] = detectedAgent.split("@"); + if (!Array.isArray(names)) + names = [names]; + const args = (typeof options.additionalArgs === "function" ? options.additionalArgs(agent, detectedAgent) : options.additionalArgs) || []; + if (options.preferOffline) { + if (detectedAgent === "yarn@berry") + args.unshift("--cached"); + else + args.unshift("--prefer-offline"); + } + if (agent === "pnpm") { + args.unshift( + /** + * Prevent pnpm from removing installed devDeps while `NODE_ENV` is `production` + * @see https://pnpm.io/cli/install#--prod--p + */ + "--prod=false" + ); + if (existsSync(resolve(options.cwd ?? process.cwd(), "pnpm-workspace.yaml"))) { + args.unshift("-w"); + } + } + return x( + agent, + [ + agent === "yarn" ? "add" : "install", + options.dev ? "-D" : "", + ...args, + ...names + ].filter(Boolean), + { + nodeOptions: { + stdio: options.silent ? "ignore" : "inherit", + cwd: options.cwd + }, + throwOnError: true + } + ); +} + +export { detectPackageManager, installPackage }; diff --git a/node_modules/vitest/dist/chunks/index.VByaPkjc.js b/node_modules/vitest/dist/chunks/index.VByaPkjc.js new file mode 100644 index 0000000000..490fd49e09 --- /dev/null +++ b/node_modules/vitest/dist/chunks/index.VByaPkjc.js @@ -0,0 +1,2183 @@ +import { performance as performance$1 } from 'node:perf_hooks'; +import { getTestName, getFullName, hasFailed, getTests, getSuites, getTasks } from '@vitest/runner/utils'; +import { slash, toArray, isPrimitive, inspect, positionToOffset, lineSplitRE } from '@vitest/utils'; +import { parseStacktrace, parseErrorStacktrace } from '@vitest/utils/source-map'; +import { isAbsolute, relative, dirname, basename, resolve, normalize } from 'pathe'; +import c from 'tinyrainbow'; +import { i as isTTY } from './env.D4Lgay0q.js'; +import { h as hasFailedSnapshot, g as getOutputFile, T as TypeCheckError } from './typechecker.DRKU1-1g.js'; +import { stripVTControlCharacters } from 'node:util'; +import { existsSync, readFileSync, promises } from 'node:fs'; +import { mkdir, writeFile, readdir, stat, readFile } from 'node:fs/promises'; +import { Console } from 'node:console'; +import { Writable } from 'node:stream'; +import { createRequire } from 'node:module'; +import { hostname } from 'node:os'; + +const F_RIGHT = "→"; +const F_DOWN = "↓"; +const F_DOWN_RIGHT = "↳"; +const F_POINTER = "❯"; +const F_DOT = "·"; +const F_CHECK = "✓"; +const F_CROSS = "×"; +const F_LONG_DASH = "⎯"; +const F_TREE_NODE_MIDDLE = "├──"; +const F_TREE_NODE_END = "└──"; + +const pointer = c.yellow(F_POINTER); +const skipped = c.dim(c.gray(F_DOWN)); +const benchmarkPass = c.green(F_DOT); +const testPass = c.green(F_CHECK); +const taskFail = c.red(F_CROSS); +const suiteFail = c.red(F_POINTER); +const pending$1 = c.gray("·"); +const labelDefaultColors = [ + c.bgYellow, + c.bgCyan, + c.bgGreen, + c.bgMagenta +]; +function getCols(delta = 0) { + let length = process.stdout?.columns; + if (!length || Number.isNaN(length)) length = 30; + return Math.max(length + delta, 0); +} +function errorBanner(message) { + return divider(c.bold(c.bgRed(` ${message} `)), null, null, c.red); +} +function divider(text, left, right, color) { + const cols = getCols(); + const c = color || ((text) => text); + if (text) { + const textLength = stripVTControlCharacters(text).length; + if (left == null && right != null) left = cols - textLength - right; + else { + left = left ?? Math.floor((cols - textLength) / 2); + right = cols - textLength - left; + } + left = Math.max(0, left); + right = Math.max(0, right); + return `${c(F_LONG_DASH.repeat(left))}${text}${c(F_LONG_DASH.repeat(right))}`; + } + return F_LONG_DASH.repeat(cols); +} +function formatTestPath(root, path) { + if (isAbsolute(path)) path = relative(root, path); + const dir = dirname(path); + const ext = path.match(/(\.(spec|test)\.[cm]?[tj]sx?)$/)?.[0] || ""; + const base = basename(path, ext); + return slash(c.dim(`${dir}/`) + c.bold(base)) + c.dim(ext); +} +function renderSnapshotSummary(rootDir, snapshots) { + const summary = []; + if (snapshots.added) summary.push(c.bold(c.green(`${snapshots.added} written`))); + if (snapshots.unmatched) summary.push(c.bold(c.red(`${snapshots.unmatched} failed`))); + if (snapshots.updated) summary.push(c.bold(c.green(`${snapshots.updated} updated `))); + if (snapshots.filesRemoved) if (snapshots.didUpdate) summary.push(c.bold(c.green(`${snapshots.filesRemoved} files removed `))); + else summary.push(c.bold(c.yellow(`${snapshots.filesRemoved} files obsolete `))); + if (snapshots.filesRemovedList && snapshots.filesRemovedList.length) { + const [head, ...tail] = snapshots.filesRemovedList; + summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, head)}`); + tail.forEach((key) => { + summary.push(` ${c.gray(F_DOT)} ${formatTestPath(rootDir, key)}`); + }); + } + if (snapshots.unchecked) { + if (snapshots.didUpdate) summary.push(c.bold(c.green(`${snapshots.unchecked} removed`))); + else summary.push(c.bold(c.yellow(`${snapshots.unchecked} obsolete`))); + snapshots.uncheckedKeysByFile.forEach((uncheckedFile) => { + summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, uncheckedFile.filePath)}`); + uncheckedFile.keys.forEach((key) => summary.push(` ${c.gray(F_DOT)} ${key}`)); + }); + } + return summary; +} +function countTestErrors(tasks) { + return tasks.reduce((c, i) => c + (i.result?.errors?.length || 0), 0); +} +function getStateString$1(tasks, name = "tests", showTotal = true) { + if (tasks.length === 0) return c.dim(`no ${name}`); + const passed = tasks.filter((i) => i.result?.state === "pass"); + const failed = tasks.filter((i) => i.result?.state === "fail"); + const skipped = tasks.filter((i) => i.mode === "skip"); + const todo = tasks.filter((i) => i.mode === "todo"); + return [ + failed.length ? c.bold(c.red(`${failed.length} failed`)) : null, + passed.length ? c.bold(c.green(`${passed.length} passed`)) : null, + skipped.length ? c.yellow(`${skipped.length} skipped`) : null, + todo.length ? c.gray(`${todo.length} todo`) : null + ].filter(Boolean).join(c.dim(" | ")) + (showTotal ? c.gray(` (${tasks.length})`) : ""); +} +function getStateSymbol(task) { + if (task.mode === "skip" || task.mode === "todo") return skipped; + if (!task.result) return pending$1; + if (task.result.state === "run" || task.result.state === "queued") { + if (task.type === "suite") return pointer; + } + if (task.result.state === "pass") return task.meta?.benchmark ? benchmarkPass : testPass; + if (task.result.state === "fail") return task.type === "suite" ? suiteFail : taskFail; + return " "; +} +function formatTimeString(date) { + return date.toTimeString().split(" ")[0]; +} +function formatTime(time) { + if (time > 1e3) return `${(time / 1e3).toFixed(2)}s`; + return `${Math.round(time)}ms`; +} +function formatProjectName(project, suffix = " ") { + if (!project?.name) return ""; + if (!c.isColorSupported) return `|${project.name}|${suffix}`; + let background = project.color && c[`bg${capitalize(project.color)}`]; + if (!background) { + const index = project.name.split("").reduce((acc, v, idx) => acc + v.charCodeAt(0) + idx, 0); + background = labelDefaultColors[index % labelDefaultColors.length]; + } + return c.black(background(` ${project.name} `)) + suffix; +} +function withLabel(color, label, message) { + const bgColor = `bg${color.charAt(0).toUpperCase()}${color.slice(1)}`; + return `${c.bold(c[bgColor](` ${label} `))} ${message ? c[color](message) : ""}`; +} +function padSummaryTitle(str) { + return c.dim(`${str.padStart(11)} `); +} +function truncateString(text, maxLength) { + const plainText = stripVTControlCharacters(text); + if (plainText.length <= maxLength) return text; + return `${plainText.slice(0, maxLength - 1)}…`; +} +function capitalize(text) { + return `${text[0].toUpperCase()}${text.slice(1)}`; +} + +var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + benchmarkPass: benchmarkPass, + countTestErrors: countTestErrors, + divider: divider, + errorBanner: errorBanner, + formatProjectName: formatProjectName, + formatTestPath: formatTestPath, + formatTime: formatTime, + formatTimeString: formatTimeString, + getStateString: getStateString$1, + getStateSymbol: getStateSymbol, + padSummaryTitle: padSummaryTitle, + pending: pending$1, + pointer: pointer, + renderSnapshotSummary: renderSnapshotSummary, + skipped: skipped, + suiteFail: suiteFail, + taskFail: taskFail, + testPass: testPass, + truncateString: truncateString, + withLabel: withLabel +}); + +const BADGE_PADDING = " "; +class BaseReporter { + start = 0; + end = 0; + watchFilters; + failedUnwatchedFiles = []; + isTTY; + ctx = void 0; + renderSucceed = false; + verbose = false; + _filesInWatchMode = /* @__PURE__ */ new Map(); + _timeStart = formatTimeString(/* @__PURE__ */ new Date()); + constructor(options = {}) { + this.isTTY = options.isTTY ?? isTTY; + } + onInit(ctx) { + this.ctx = ctx; + this.ctx.logger.printBanner(); + this.start = performance$1.now(); + } + log(...messages) { + this.ctx.logger.log(...messages); + } + error(...messages) { + this.ctx.logger.error(...messages); + } + relative(path) { + return relative(this.ctx.config.root, path); + } + onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) { + this.end = performance$1.now(); + if (!files.length && !errors.length) this.ctx.logger.printNoTestFound(this.ctx.filenamePattern); + else this.reportSummary(files, errors); + } + onTestCaseResult(testCase) { + if (testCase.result().state === "failed") this.logFailedTask(testCase.task); + } + onTestSuiteResult(testSuite) { + if (testSuite.state() === "failed") this.logFailedTask(testSuite.task); + } + onTestModuleEnd(testModule) { + if (testModule.state() === "failed") this.logFailedTask(testModule.task); + this.printTestModule(testModule); + } + logFailedTask(task) { + if (this.ctx.config.silent === "passed-only") for (const log of task.logs || []) this.onUserConsoleLog(log, "failed"); + } + printTestModule(testModule) { + const moduleState = testModule.state(); + if (moduleState === "queued" || moduleState === "pending") return; + let testsCount = 0; + let failedCount = 0; + let skippedCount = 0; + // delaying logs to calculate the test stats first + // which minimizes the amount of for loops + const logs = []; + const originalLog = this.log.bind(this); + this.log = (msg) => logs.push(msg); + const visit = (suiteState, children) => { + for (const child of children) if (child.type === "suite") { + const suiteState = child.state(); + // Skipped suites are hidden when --hideSkippedTests, print otherwise + if (!this.ctx.config.hideSkippedTests || suiteState !== "skipped") this.printTestSuite(child); + visit(suiteState, child.children); + } else { + const testResult = child.result(); + testsCount++; + if (testResult.state === "failed") failedCount++; + else if (testResult.state === "skipped") skippedCount++; + if (this.ctx.config.hideSkippedTests && suiteState === "skipped") + // Skipped suites are hidden when --hideSkippedTests + continue; + this.printTestCase(moduleState, child); + } + }; + try { + visit(moduleState, testModule.children); + } finally { + this.log = originalLog; + } + this.log(this.getModuleLog(testModule, { + tests: testsCount, + failed: failedCount, + skipped: skippedCount + })); + logs.forEach((log) => this.log(log)); + } + printTestCase(moduleState, test) { + const testResult = test.result(); + const { duration, retryCount, repeatCount } = test.diagnostic() || {}; + const padding = this.getTestIndentation(test.task); + let suffix = this.getDurationPrefix(test.task); + if (retryCount != null && retryCount > 0) suffix += c.yellow(` (retry x${retryCount})`); + if (repeatCount != null && repeatCount > 0) suffix += c.yellow(` (repeat x${repeatCount})`); + if (testResult.state === "failed") { + this.log(c.red(` ${padding}${taskFail} ${this.getTestName(test.task, c.dim(" > "))}`) + suffix); + // print short errors, full errors will be at the end in summary + testResult.errors.forEach((error) => { + const message = this.formatShortError(error); + if (message) this.log(c.red(` ${padding}${message}`)); + }); + } else if (duration && duration > this.ctx.config.slowTestThreshold) this.log(` ${padding}${c.yellow(c.dim(F_CHECK))} ${this.getTestName(test.task, c.dim(" > "))} ${suffix}`); + else if (this.ctx.config.hideSkippedTests && testResult.state === "skipped") ; else if (testResult.state === "skipped" && testResult.note) this.log(` ${padding}${getStateSymbol(test.task)} ${this.getTestName(test.task, c.dim(" > "))}${c.dim(c.gray(` [${testResult.note}]`))}`); + else if (this.renderSucceed || moduleState === "failed") this.log(` ${padding}${getStateSymbol(test.task)} ${this.getTestName(test.task, c.dim(" > "))}${suffix}`); + } + getModuleLog(testModule, counts) { + let state = c.dim(`${counts.tests} test${counts.tests > 1 ? "s" : ""}`); + if (counts.failed) state += c.dim(" | ") + c.red(`${counts.failed} failed`); + if (counts.skipped) state += c.dim(" | ") + c.yellow(`${counts.skipped} skipped`); + let suffix = c.dim("(") + state + c.dim(")") + this.getDurationPrefix(testModule.task); + const diagnostic = testModule.diagnostic(); + if (diagnostic.heap != null) suffix += c.magenta(` ${Math.floor(diagnostic.heap / 1024 / 1024)} MB heap used`); + let title = getStateSymbol(testModule.task); + if (testModule.meta().typecheck) title += ` ${c.bgBlue(c.bold(" TS "))}`; + if (testModule.project.name) title += ` ${formatProjectName(testModule.project, "")}`; + return ` ${title} ${testModule.task.name} ${suffix}`; + } + printTestSuite(_suite) { + // Suite name is included in getTestName by default + } + getTestName(test, separator) { + return getTestName(test, separator); + } + getFullName(test, separator) { + return getFullName(test, separator); + } + formatShortError(error) { + return `${F_RIGHT} ${error.message}`; + } + getTestIndentation(_test) { + return " "; + } + printAnnotations(test, console, padding = 0) { + const annotations = test.annotations(); + if (!annotations.length) return; + const PADDING = " ".repeat(padding); + annotations.forEach(({ location, type, message }) => { + if (location) { + const file = relative(test.project.config.root, location.file); + this[console](`${PADDING}${c.blue(F_POINTER)} ${c.gray(`${file}:${location.line}:${location.column}`)} ${c.bold(type)}`); + } else this[console](`${PADDING}${c.blue(F_POINTER)} ${c.bold(type)}`); + this[console](`${PADDING} ${c.blue(F_DOWN_RIGHT)} ${message}`); + }); + } + getDurationPrefix(task) { + if (!task.result?.duration) return ""; + const color = task.result.duration > this.ctx.config.slowTestThreshold ? c.yellow : c.green; + return color(` ${Math.round(task.result.duration)}${c.dim("ms")}`); + } + onWatcherStart(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) { + const failed = errors.length > 0 || hasFailed(files); + if (failed) this.log(withLabel("red", "FAIL", "Tests failed. Watching for file changes...")); + else if (this.ctx.isCancelling) this.log(withLabel("red", "CANCELLED", "Test run cancelled. Watching for file changes...")); + else this.log(withLabel("green", "PASS", "Waiting for file changes...")); + const hints = [c.dim("press ") + c.bold("h") + c.dim(" to show help")]; + if (hasFailedSnapshot(files)) hints.unshift(c.dim("press ") + c.bold(c.yellow("u")) + c.dim(" to update snapshot")); + else hints.push(c.dim("press ") + c.bold("q") + c.dim(" to quit")); + this.log(BADGE_PADDING + hints.join(c.dim(", "))); + } + onWatcherRerun(files, trigger) { + this.watchFilters = files; + this.failedUnwatchedFiles = this.ctx.state.getTestModules().filter((testModule) => !files.includes(testModule.task.filepath) && testModule.state() === "failed"); + // Update re-run count for each file + files.forEach((filepath) => { + let reruns = this._filesInWatchMode.get(filepath) ?? 0; + this._filesInWatchMode.set(filepath, ++reruns); + }); + let banner = trigger ? c.dim(`${this.relative(trigger)} `) : ""; + if (files.length === 1) { + const rerun = this._filesInWatchMode.get(files[0]) ?? 1; + banner += c.blue(`x${rerun} `); + } + this.ctx.logger.clearFullScreen(); + this.log(withLabel("blue", "RERUN", banner)); + if (this.ctx.configOverride.project) this.log(BADGE_PADDING + c.dim(" Project name: ") + c.blue(toArray(this.ctx.configOverride.project).join(", "))); + if (this.ctx.filenamePattern) this.log(BADGE_PADDING + c.dim(" Filename pattern: ") + c.blue(this.ctx.filenamePattern.join(", "))); + if (this.ctx.configOverride.testNamePattern) this.log(BADGE_PADDING + c.dim(" Test name pattern: ") + c.blue(String(this.ctx.configOverride.testNamePattern))); + this.log(""); + for (const testModule of this.failedUnwatchedFiles) this.printTestModule(testModule); + this._timeStart = formatTimeString(/* @__PURE__ */ new Date()); + this.start = performance$1.now(); + } + onUserConsoleLog(log, taskState) { + if (!this.shouldLog(log, taskState)) return; + const output = log.type === "stdout" ? this.ctx.logger.outputStream : this.ctx.logger.errorStream; + const write = (msg) => output.write(msg); + let headerText = "unknown test"; + const task = log.taskId ? this.ctx.state.idMap.get(log.taskId) : void 0; + if (task) headerText = this.getFullName(task, c.dim(" > ")); + else if (log.taskId && log.taskId !== "__vitest__unknown_test__") headerText = log.taskId; + write(c.gray(log.type + c.dim(` | ${headerText}\n`)) + log.content); + if (log.origin) { + // browser logs don't have an extra end of line at the end like Node.js does + if (log.browser) write("\n"); + const project = task ? this.ctx.getProjectByName(task.file.projectName || "") : this.ctx.getRootProject(); + const stack = log.browser ? project.browser?.parseStacktrace(log.origin) || [] : parseStacktrace(log.origin); + const highlight = task && stack.find((i) => i.file === task.file.filepath); + for (const frame of stack) { + const color = frame === highlight ? c.cyan : c.gray; + const path = relative(project.config.root, frame.file); + const positions = [frame.method, `${path}:${c.dim(`${frame.line}:${frame.column}`)}`].filter(Boolean).join(" "); + write(color(` ${c.dim(F_POINTER)} ${positions}\n`)); + } + } + write("\n"); + } + onTestRemoved(trigger) { + this.log(c.yellow("Test removed...") + (trigger ? c.dim(` [ ${this.relative(trigger)} ]\n`) : "")); + } + shouldLog(log, taskState) { + if (this.ctx.config.silent === true) return false; + if (this.ctx.config.silent === "passed-only" && taskState !== "failed") return false; + const shouldLog = this.ctx.config.onConsoleLog?.(log.content, log.type); + if (shouldLog === false) return shouldLog; + return true; + } + onServerRestart(reason) { + this.log(c.bold(c.magenta(reason === "config" ? "\nRestarting due to config changes..." : "\nRestarting Vitest..."))); + } + reportSummary(files, errors) { + this.printErrorsSummary(files, errors); + if (this.ctx.config.mode === "benchmark") this.reportBenchmarkSummary(files); + else this.reportTestSummary(files, errors); + } + reportTestSummary(files, errors) { + this.log(); + const affectedFiles = [...this.failedUnwatchedFiles.map((m) => m.task), ...files]; + const tests = getTests(affectedFiles); + const snapshotOutput = renderSnapshotSummary(this.ctx.config.root, this.ctx.snapshot.summary); + for (const [index, snapshot] of snapshotOutput.entries()) { + const title = index === 0 ? "Snapshots" : ""; + this.log(`${padSummaryTitle(title)} ${snapshot}`); + } + if (snapshotOutput.length > 1) this.log(); + this.log(padSummaryTitle("Test Files"), getStateString$1(affectedFiles)); + this.log(padSummaryTitle("Tests"), getStateString$1(tests)); + if (this.ctx.projects.some((c) => c.config.typecheck.enabled)) { + const failed = tests.filter((t) => t.meta?.typecheck && t.result?.errors?.length); + this.log(padSummaryTitle("Type Errors"), failed.length ? c.bold(c.red(`${failed.length} failed`)) : c.dim("no errors")); + } + if (errors.length) this.log(padSummaryTitle("Errors"), c.bold(c.red(`${errors.length} error${errors.length > 1 ? "s" : ""}`))); + this.log(padSummaryTitle("Start at"), this._timeStart); + const collectTime = sum(files, (file) => file.collectDuration); + const testsTime = sum(files, (file) => file.result?.duration); + const setupTime = sum(files, (file) => file.setupDuration); + if (this.watchFilters) this.log(padSummaryTitle("Duration"), formatTime(collectTime + testsTime + setupTime)); + else { + const blobs = this.ctx.state.blobs; + // Execution time is either sum of all runs of `--merge-reports` or the current run's time + const executionTime = blobs?.executionTimes ? sum(blobs.executionTimes, (time) => time) : this.end - this.start; + const environmentTime = sum(files, (file) => file.environmentLoad); + const prepareTime = sum(files, (file) => file.prepareDuration); + const transformTime = sum(this.ctx.projects, (project) => project.vitenode.getTotalDuration()); + const typecheck = sum(this.ctx.projects, (project) => project.typechecker?.getResult().time); + const timers = [ + `transform ${formatTime(transformTime)}`, + `setup ${formatTime(setupTime)}`, + `collect ${formatTime(collectTime)}`, + `tests ${formatTime(testsTime)}`, + `environment ${formatTime(environmentTime)}`, + `prepare ${formatTime(prepareTime)}`, + typecheck && `typecheck ${formatTime(typecheck)}` + ].filter(Boolean).join(", "); + this.log(padSummaryTitle("Duration"), formatTime(executionTime) + c.dim(` (${timers})`)); + if (blobs?.executionTimes) this.log(padSummaryTitle("Per blob") + blobs.executionTimes.map((time) => ` ${formatTime(time)}`).join("")); + } + this.log(); + } + printErrorsSummary(files, errors) { + const suites = getSuites(files); + const tests = getTests(files); + const failedSuites = suites.filter((i) => i.result?.errors); + const failedTests = tests.filter((i) => i.result?.state === "fail"); + const failedTotal = countTestErrors(failedSuites) + countTestErrors(failedTests); + let current = 1; + const errorDivider = () => this.error(`${c.red(c.dim(divider(`[${current++}/${failedTotal}]`, void 0, 1)))}\n`); + if (failedSuites.length) { + this.error(`\n${errorBanner(`Failed Suites ${failedSuites.length}`)}\n`); + this.printTaskErrors(failedSuites, errorDivider); + } + if (failedTests.length) { + this.error(`\n${errorBanner(`Failed Tests ${failedTests.length}`)}\n`); + this.printTaskErrors(failedTests, errorDivider); + } + if (errors.length) { + this.ctx.logger.printUnhandledErrors(errors); + this.error(); + } + } + reportBenchmarkSummary(files) { + const benches = getTests(files); + const topBenches = benches.filter((i) => i.result?.benchmark?.rank === 1); + this.log(`\n${withLabel("cyan", "BENCH", "Summary\n")}`); + for (const bench of topBenches) { + const group = bench.suite || bench.file; + if (!group) continue; + const groupName = this.getFullName(group, c.dim(" > ")); + const project = this.ctx.projects.find((p) => p.name === bench.file.projectName); + this.log(` ${formatProjectName(project)}${bench.name}${c.dim(` - ${groupName}`)}`); + const siblings = group.tasks.filter((i) => i.meta.benchmark && i.result?.benchmark && i !== bench).sort((a, b) => a.result.benchmark.rank - b.result.benchmark.rank); + for (const sibling of siblings) { + const number = (sibling.result.benchmark.mean / bench.result.benchmark.mean).toFixed(2); + this.log(c.green(` ${number}x `) + c.gray("faster than ") + sibling.name); + } + this.log(""); + } + } + printTaskErrors(tasks, errorDivider) { + const errorsQueue = []; + for (const task of tasks) + // Merge identical errors + task.result?.errors?.forEach((error) => { + let previous; + if (error?.stack) previous = errorsQueue.find((i) => { + if (i[0]?.stack !== error.stack) return false; + const currentProjectName = task?.projectName || task.file?.projectName || ""; + const projectName = i[1][0]?.projectName || i[1][0].file?.projectName || ""; + const currentAnnotations = task.type === "test" && task.annotations; + const itemAnnotations = i[1][0].type === "test" && i[1][0].annotations; + return projectName === currentProjectName && deepEqual(currentAnnotations, itemAnnotations); + }); + if (previous) previous[1].push(task); + else errorsQueue.push([error, [task]]); + }); + for (const [error, tasks] of errorsQueue) { + for (const task of tasks) { + const filepath = task?.filepath || ""; + const projectName = task?.projectName || task.file?.projectName || ""; + const project = this.ctx.projects.find((p) => p.name === projectName); + let name = this.getFullName(task, c.dim(" > ")); + if (filepath) name += c.dim(` [ ${this.relative(filepath)} ]`); + this.ctx.logger.error(`${c.bgRed(c.bold(" FAIL "))} ${formatProjectName(project)}${name}`); + } + const screenshotPaths = tasks.map((t) => t.meta?.failScreenshotPath).filter((screenshot) => screenshot != null); + this.ctx.logger.printError(error, { + project: this.ctx.getProjectByName(tasks[0].file.projectName || ""), + verbose: this.verbose, + screenshotPaths, + task: tasks[0] + }); + if (tasks[0].type === "test" && tasks[0].annotations.length) { + const test = this.ctx.state.getReportedEntity(tasks[0]); + this.printAnnotations(test, "error", 1); + this.error(); + } + errorDivider(); + } + } +} +function deepEqual(a, b) { + if (a === b) return true; + if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false; + const keysA = Object.keys(a); + const keysB = Object.keys(b); + if (keysA.length !== keysB.length) return false; + for (const key of keysA) if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false; + return true; +} +function sum(items, cb) { + return items.reduce((total, next) => { + return total + Math.max(cb(next) || 0, 0); + }, 0); +} + +class BasicReporter extends BaseReporter { + constructor() { + super(); + this.isTTY = false; + } + onInit(ctx) { + super.onInit(ctx); + ctx.logger.deprecate(`'basic' reporter is deprecated and will be removed in Vitest v3.\nRemove 'basic' from 'reporters' option. To match 'basic' reporter 100%, use configuration:\n${JSON.stringify({ test: { reporters: [["default", { summary: false }]] } }, null, 2)}`); + } + reportSummary(files, errors) { + // non-tty mode doesn't add a new line + this.ctx.logger.log(); + return super.reportSummary(files, errors); + } +} + +/// + +// (c) 2020-present Andrea Giammarchi + +const {parse: $parse, stringify: $stringify} = JSON; +const {keys} = Object; + +const Primitive = String; // it could be Number +const primitive = 'string'; // it could be 'number' + +const ignore = {}; +const object = 'object'; + +const noop = (_, value) => value; + +const primitives = value => ( + value instanceof Primitive ? Primitive(value) : value +); + +const Primitives = (_, value) => ( + typeof value === primitive ? new Primitive(value) : value +); + +const revive = (input, parsed, output, $) => { + const lazy = []; + for (let ke = keys(output), {length} = ke, y = 0; y < length; y++) { + const k = ke[y]; + const value = output[k]; + if (value instanceof Primitive) { + const tmp = input[value]; + if (typeof tmp === object && !parsed.has(tmp)) { + parsed.add(tmp); + output[k] = ignore; + lazy.push({k, a: [input, parsed, tmp, $]}); + } + else + output[k] = $.call(output, k, tmp); + } + else if (output[k] !== ignore) + output[k] = $.call(output, k, value); + } + for (let {length} = lazy, i = 0; i < length; i++) { + const {k, a} = lazy[i]; + output[k] = $.call(output, k, revive.apply(null, a)); + } + return output; +}; + +const set = (known, input, value) => { + const index = Primitive(input.push(value) - 1); + known.set(value, index); + return index; +}; + +/** + * Converts a specialized flatted string into a JS value. + * @param {string} text + * @param {(this: any, key: string, value: any) => any} [reviver] + * @returns {any} + */ +const parse = (text, reviver) => { + const input = $parse(text, Primitives).map(primitives); + const value = input[0]; + const $ = reviver || noop; + const tmp = typeof value === object && value ? + revive(input, new Set, value, $) : + value; + return $.call({'': tmp}, '', tmp); +}; + +/** + * Converts a JS value into a specialized flatted string. + * @param {any} value + * @param {((this: any, key: string, value: any) => any) | (string | number)[] | null | undefined} [replacer] + * @param {string | number | undefined} [space] + * @returns {string} + */ +const stringify = (value, replacer, space) => { + const $ = replacer && typeof replacer === object ? + (k, v) => (k === '' || -1 < replacer.indexOf(k) ? v : void 0) : + (replacer || noop); + const known = new Map; + const input = []; + const output = []; + let i = +set(known, input, $.call({'': value}, '', value)); + let firstRun = !i; + while (i < input.length) { + firstRun = true; + output[i] = $stringify(input[i++], replace, space); + } + return '[' + output.join(',') + ']'; + function replace(key, value) { + if (firstRun) { + firstRun = !firstRun; + return value; + } + const after = $.call(this, key, value); + switch (typeof after) { + case object: + if (after === null) return after; + case primitive: + return known.get(after) || set(known, input, after); + } + return after; + } +}; + +class BlobReporter { + start = 0; + ctx; + options; + constructor(options) { + this.options = options; + } + onInit(ctx) { + if (ctx.config.watch) throw new Error("Blob reporter is not supported in watch mode"); + this.ctx = ctx; + this.start = performance.now(); + } + async onFinished(files = [], errors = [], coverage) { + const executionTime = performance.now() - this.start; + let outputFile = this.options.outputFile ?? getOutputFile(this.ctx.config, "blob"); + if (!outputFile) { + const shard = this.ctx.config.shard; + outputFile = shard ? `.vitest-reports/blob-${shard.index}-${shard.count}.json` : ".vitest-reports/blob.json"; + } + const modules = this.ctx.projects.map((project) => { + return [project.name, [...project.vite.moduleGraph.idToModuleMap.entries()].map((mod) => { + if (!mod[1].file) return null; + return [ + mod[0], + mod[1].file, + mod[1].url + ]; + }).filter((x) => x != null)]; + }); + const report = [ + this.ctx.version, + files, + errors, + modules, + coverage, + executionTime + ]; + const reportFile = resolve(this.ctx.config.root, outputFile); + await writeBlob(report, reportFile); + this.ctx.logger.log("blob report written to", reportFile); + } +} +async function writeBlob(content, filename) { + const report = stringify(content); + const dir = dirname(filename); + if (!existsSync(dir)) await mkdir(dir, { recursive: true }); + await writeFile(filename, report, "utf-8"); +} +async function readBlobs(currentVersion, blobsDirectory, projectsArray) { + // using process.cwd() because --merge-reports can only be used in CLI + const resolvedDir = resolve(process.cwd(), blobsDirectory); + const blobsFiles = await readdir(resolvedDir); + const promises = blobsFiles.map(async (filename) => { + const fullPath = resolve(resolvedDir, filename); + const stats = await stat(fullPath); + if (!stats.isFile()) throw new TypeError(`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a file`); + const content = await readFile(fullPath, "utf-8"); + const [version, files, errors, moduleKeys, coverage, executionTime] = parse(content); + if (!version) throw new TypeError(`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a valid blob file`); + return { + version, + files, + errors, + moduleKeys, + coverage, + file: filename, + executionTime + }; + }); + const blobs = await Promise.all(promises); + if (!blobs.length) throw new Error(`vitest.mergeReports() requires at least one blob file in "${blobsDirectory}" directory, but none were found`); + const versions = new Set(blobs.map((blob) => blob.version)); + if (versions.size > 1) throw new Error(`vitest.mergeReports() requires all blob files to be generated by the same Vitest version, received\n\n${blobs.map((b) => `- "${b.file}" uses v${b.version}`).join("\n")}`); + if (!versions.has(currentVersion)) throw new Error(`the blobs in "${blobsDirectory}" were generated by a different version of Vitest. Expected v${currentVersion}, but received v${blobs[0].version}`); + // fake module graph - it is used to check if module is imported, but we don't use values inside + const projects = Object.fromEntries(projectsArray.map((p) => [p.name, p])); + blobs.forEach((blob) => { + blob.moduleKeys.forEach(([projectName, moduleIds]) => { + const project = projects[projectName]; + if (!project) return; + moduleIds.forEach(([moduleId, file, url]) => { + const moduleNode = project.vite.moduleGraph.createFileOnlyEntry(file); + moduleNode.url = url; + moduleNode.id = moduleId; + project.vite.moduleGraph.idToModuleMap.set(moduleId, moduleNode); + }); + }); + }); + const files = blobs.flatMap((blob) => blob.files).sort((f1, f2) => { + const time1 = f1.result?.startTime || 0; + const time2 = f2.result?.startTime || 0; + return time1 - time2; + }); + const errors = blobs.flatMap((blob) => blob.errors); + const coverages = blobs.map((blob) => blob.coverage); + const executionTimes = blobs.map((blob) => blob.executionTime); + return { + files, + errors, + coverages, + executionTimes + }; +} + +const DEFAULT_RENDER_INTERVAL_MS = 1e3; +const ESC = "\x1B["; +const CLEAR_LINE = `${ESC}K`; +const MOVE_CURSOR_ONE_ROW_UP = `${ESC}1A`; +const SYNC_START = `${ESC}?2026h`; +const SYNC_END = `${ESC}?2026l`; +/** +* Renders content of `getWindow` at the bottom of the terminal and +* forwards all other intercepted `stdout` and `stderr` logs above it. +*/ +class WindowRenderer { + options; + streams; + buffer = []; + renderInterval = void 0; + renderScheduled = false; + windowHeight = 0; + finished = false; + cleanups = []; + constructor(options) { + this.options = { + interval: DEFAULT_RENDER_INTERVAL_MS, + ...options + }; + this.streams = { + output: options.logger.outputStream.write.bind(options.logger.outputStream), + error: options.logger.errorStream.write.bind(options.logger.errorStream) + }; + this.cleanups.push(this.interceptStream(process.stdout, "output"), this.interceptStream(process.stderr, "error")); + // Write buffered content on unexpected exits, e.g. direct `process.exit()` calls + this.options.logger.onTerminalCleanup(() => { + this.flushBuffer(); + this.stop(); + }); + this.start(); + } + start() { + this.finished = false; + this.renderInterval = setInterval(() => this.schedule(), this.options.interval).unref(); + } + stop() { + this.cleanups.splice(0).map((fn) => fn()); + clearInterval(this.renderInterval); + } + /** + * Write all buffered output and stop buffering. + * All intercepted writes are forwarded to actual write after this. + */ + finish() { + this.finished = true; + this.flushBuffer(); + clearInterval(this.renderInterval); + } + /** + * Queue new render update + */ + schedule() { + if (!this.renderScheduled) { + this.renderScheduled = true; + this.flushBuffer(); + setTimeout(() => { + this.renderScheduled = false; + }, 100).unref(); + } + } + flushBuffer() { + if (this.buffer.length === 0) return this.render(); + let current; + // Concatenate same types into a single render + for (const next of this.buffer.splice(0)) { + if (!current) { + current = next; + continue; + } + if (current.type !== next.type) { + this.render(current.message, current.type); + current = next; + continue; + } + current.message += next.message; + } + if (current) this.render(current?.message, current?.type); + } + render(message, type = "output") { + if (this.finished) { + this.clearWindow(); + return this.write(message || "", type); + } + const windowContent = this.options.getWindow(); + const rowCount = getRenderedRowCount(windowContent, this.options.logger.getColumns()); + let padding = this.windowHeight - rowCount; + if (padding > 0 && message) padding -= getRenderedRowCount([message], this.options.logger.getColumns()); + this.write(SYNC_START); + this.clearWindow(); + if (message) this.write(message, type); + if (padding > 0) this.write("\n".repeat(padding)); + this.write(windowContent.join("\n")); + this.write(SYNC_END); + this.windowHeight = rowCount + Math.max(0, padding); + } + clearWindow() { + if (this.windowHeight === 0) return; + this.write(CLEAR_LINE); + for (let i = 1; i < this.windowHeight; i++) this.write(`${MOVE_CURSOR_ONE_ROW_UP}${CLEAR_LINE}`); + this.windowHeight = 0; + } + interceptStream(stream, type) { + const original = stream.write; + // @ts-expect-error -- not sure how 2 overloads should be typed + stream.write = (chunk, _, callback) => { + if (chunk) if (this.finished) this.write(chunk.toString(), type); + else this.buffer.push({ + type, + message: chunk.toString() + }); + callback?.(); + }; + return function restore() { + stream.write = original; + }; + } + write(message, type = "output") { + this.streams[type](message); + } +} +/** Calculate the actual row count needed to render `rows` into `stream` */ +function getRenderedRowCount(rows, columns) { + let count = 0; + for (const row of rows) { + const text = stripVTControlCharacters(row); + count += Math.max(1, Math.ceil(text.length / columns)); + } + return count; +} + +const DURATION_UPDATE_INTERVAL_MS = 100; +const FINISHED_TEST_CLEANUP_TIME_MS = 1e3; +/** +* Reporter extension that renders summary and forwards all other logs above itself. +* Intended to be used by other reporters, not as a standalone reporter. +*/ +class SummaryReporter { + ctx; + options; + renderer; + modules = emptyCounters(); + tests = emptyCounters(); + maxParallelTests = 0; + /** Currently running test modules, may include finished test modules too */ + runningModules = /* @__PURE__ */ new Map(); + /** ID of finished `this.runningModules` that are currently being shown */ + finishedModules = /* @__PURE__ */ new Map(); + startTime = ""; + currentTime = 0; + duration = 0; + durationInterval = void 0; + onInit(ctx, options = {}) { + this.ctx = ctx; + this.options = { + verbose: false, + ...options + }; + this.renderer = new WindowRenderer({ + logger: ctx.logger, + getWindow: () => this.createSummary() + }); + this.ctx.onClose(() => { + clearInterval(this.durationInterval); + this.renderer.stop(); + }); + } + onTestRunStart(specifications) { + this.runningModules.clear(); + this.finishedModules.clear(); + this.modules = emptyCounters(); + this.tests = emptyCounters(); + this.startTimers(); + this.renderer.start(); + this.modules.total = specifications.length; + } + onTestRunEnd() { + this.runningModules.clear(); + this.finishedModules.clear(); + this.renderer.finish(); + clearInterval(this.durationInterval); + } + onTestModuleQueued(module) { + // When new test module starts, take the place of previously finished test module, if any + if (this.finishedModules.size) { + const finished = this.finishedModules.keys().next().value; + this.removeTestModule(finished); + } + this.runningModules.set(module.id, initializeStats(module)); + this.renderer.schedule(); + } + onTestModuleCollected(module) { + let stats = this.runningModules.get(module.id); + if (!stats) { + stats = initializeStats(module); + this.runningModules.set(module.id, stats); + } + const total = Array.from(module.children.allTests()).length; + this.tests.total += total; + stats.total = total; + this.maxParallelTests = Math.max(this.maxParallelTests, this.runningModules.size); + this.renderer.schedule(); + } + onHookStart(options) { + const stats = this.getHookStats(options); + if (!stats) return; + const hook = { + name: options.name, + visible: false, + startTime: performance.now(), + onFinish: () => {} + }; + stats.hook?.onFinish?.(); + stats.hook = hook; + const timeout = setTimeout(() => { + hook.visible = true; + }, this.ctx.config.slowTestThreshold).unref(); + hook.onFinish = () => clearTimeout(timeout); + } + onHookEnd(options) { + const stats = this.getHookStats(options); + if (stats?.hook?.name !== options.name) return; + stats.hook.onFinish(); + stats.hook.visible = false; + } + onTestCaseReady(test) { + // Track slow running tests only on verbose mode + if (!this.options.verbose) return; + const stats = this.runningModules.get(test.module.id); + if (!stats || stats.tests.has(test.id)) return; + const slowTest = { + name: test.name, + visible: false, + startTime: performance.now(), + onFinish: () => {} + }; + const timeout = setTimeout(() => { + slowTest.visible = true; + }, this.ctx.config.slowTestThreshold).unref(); + slowTest.onFinish = () => { + slowTest.hook?.onFinish(); + clearTimeout(timeout); + }; + stats.tests.set(test.id, slowTest); + } + onTestCaseResult(test) { + const stats = this.runningModules.get(test.module.id); + if (!stats) return; + stats.tests.get(test.id)?.onFinish(); + stats.tests.delete(test.id); + stats.completed++; + const result = test.result(); + if (result?.state === "passed") this.tests.passed++; + else if (result?.state === "failed") this.tests.failed++; + else if (!result?.state || result?.state === "skipped") this.tests.skipped++; + this.renderer.schedule(); + } + onTestModuleEnd(module) { + const state = module.state(); + this.modules.completed++; + if (state === "passed") this.modules.passed++; + else if (state === "failed") this.modules.failed++; + else if (module.task.mode === "todo" && state === "skipped") this.modules.todo++; + else if (state === "skipped") this.modules.skipped++; + const left = this.modules.total - this.modules.completed; + // Keep finished tests visible in summary for a while if there are more tests left. + // When a new test starts in onTestModuleQueued it will take this ones place. + // This reduces flickering by making summary more stable. + if (left > this.maxParallelTests) this.finishedModules.set(module.id, setTimeout(() => { + this.removeTestModule(module.id); + }, FINISHED_TEST_CLEANUP_TIME_MS).unref()); + else + // Run is about to end as there are less tests left than whole run had parallel at max. + // Remove finished test immediately. + this.removeTestModule(module.id); + this.renderer.schedule(); + } + getHookStats({ entity }) { + // Track slow running hooks only on verbose mode + if (!this.options.verbose) return; + const module = entity.type === "module" ? entity : entity.module; + const stats = this.runningModules.get(module.id); + if (!stats) return; + return entity.type === "test" ? stats.tests.get(entity.id) : stats; + } + createSummary() { + const summary = [""]; + for (const testFile of Array.from(this.runningModules.values()).sort(sortRunningModules)) { + const typecheck = testFile.typecheck ? `${c.bgBlue(c.bold(" TS "))} ` : ""; + summary.push(c.bold(c.yellow(` ${F_POINTER} `)) + formatProjectName({ + name: testFile.projectName, + color: testFile.projectColor + }) + typecheck + testFile.filename + c.dim(!testFile.completed && !testFile.total ? " [queued]" : ` ${testFile.completed}/${testFile.total}`)); + const slowTasks = [testFile.hook, ...Array.from(testFile.tests.values())].filter((t) => t != null && t.visible); + for (const [index, task] of slowTasks.entries()) { + const elapsed = this.currentTime - task.startTime; + const icon = index === slowTasks.length - 1 ? F_TREE_NODE_END : F_TREE_NODE_MIDDLE; + summary.push(c.bold(c.yellow(` ${icon} `)) + task.name + c.bold(c.yellow(` ${formatTime(Math.max(0, elapsed))}`))); + if (task.hook?.visible) summary.push(c.bold(c.yellow(` ${F_TREE_NODE_END} `)) + task.hook.name); + } + } + if (this.runningModules.size > 0) summary.push(""); + summary.push(padSummaryTitle("Test Files") + getStateString(this.modules)); + summary.push(padSummaryTitle("Tests") + getStateString(this.tests)); + summary.push(padSummaryTitle("Start at") + this.startTime); + summary.push(padSummaryTitle("Duration") + formatTime(this.duration)); + summary.push(""); + return summary; + } + startTimers() { + const start = performance.now(); + this.startTime = formatTimeString(/* @__PURE__ */ new Date()); + this.durationInterval = setInterval(() => { + this.currentTime = performance.now(); + this.duration = this.currentTime - start; + }, DURATION_UPDATE_INTERVAL_MS).unref(); + } + removeTestModule(id) { + if (!id) return; + const testFile = this.runningModules.get(id); + testFile?.hook?.onFinish(); + testFile?.tests?.forEach((test) => test.onFinish()); + this.runningModules.delete(id); + clearTimeout(this.finishedModules.get(id)); + this.finishedModules.delete(id); + } +} +function emptyCounters() { + return { + completed: 0, + passed: 0, + failed: 0, + skipped: 0, + todo: 0, + total: 0 + }; +} +function getStateString(entry) { + return [ + entry.failed ? c.bold(c.red(`${entry.failed} failed`)) : null, + c.bold(c.green(`${entry.passed} passed`)), + entry.skipped ? c.yellow(`${entry.skipped} skipped`) : null, + entry.todo ? c.gray(`${entry.todo} todo`) : null + ].filter(Boolean).join(c.dim(" | ")) + c.gray(` (${entry.total})`); +} +function sortRunningModules(a, b) { + if ((a.projectName || "") > (b.projectName || "")) return 1; + if ((a.projectName || "") < (b.projectName || "")) return -1; + return a.filename.localeCompare(b.filename); +} +function initializeStats(module) { + return { + total: 0, + completed: 0, + filename: module.task.name, + projectName: module.project.name, + projectColor: module.project.color, + tests: /* @__PURE__ */ new Map(), + typecheck: !!module.task.meta.typecheck + }; +} + +class DefaultReporter extends BaseReporter { + options; + summary; + constructor(options = {}) { + super(options); + this.options = { + summary: true, + ...options + }; + if (!this.isTTY) this.options.summary = false; + if (this.options.summary) this.summary = new SummaryReporter(); + } + onTestRunStart(specifications) { + if (this.isTTY) { + if (this.renderSucceed === void 0) this.renderSucceed = !!this.renderSucceed; + if (this.renderSucceed !== true) this.renderSucceed = specifications.length <= 1; + } + this.summary?.onTestRunStart(specifications); + } + onTestModuleQueued(file) { + this.summary?.onTestModuleQueued(file); + } + onTestModuleCollected(module) { + this.summary?.onTestModuleCollected(module); + } + onTestModuleEnd(module) { + super.onTestModuleEnd(module); + this.summary?.onTestModuleEnd(module); + } + onTestCaseReady(test) { + this.summary?.onTestCaseReady(test); + } + onTestCaseResult(test) { + super.onTestCaseResult(test); + this.summary?.onTestCaseResult(test); + } + onHookStart(hook) { + this.summary?.onHookStart(hook); + } + onHookEnd(hook) { + this.summary?.onHookEnd(hook); + } + onInit(ctx) { + super.onInit(ctx); + this.summary?.onInit(ctx, { verbose: this.verbose }); + } + onTestRunEnd() { + this.summary?.onTestRunEnd(); + } +} + +class DotReporter extends BaseReporter { + renderer; + tests = /* @__PURE__ */ new Map(); + finishedTests = /* @__PURE__ */ new Set(); + onInit(ctx) { + super.onInit(ctx); + if (this.isTTY) { + this.renderer = new WindowRenderer({ + logger: ctx.logger, + getWindow: () => this.createSummary() + }); + this.ctx.onClose(() => this.renderer?.stop()); + } + } + // Ignore default logging of base reporter + printTestModule() {} + onWatcherRerun(files, trigger) { + this.tests.clear(); + this.renderer?.start(); + super.onWatcherRerun(files, trigger); + } + onFinished(files, errors) { + if (this.isTTY) { + const finalLog = formatTests(Array.from(this.tests.values())); + this.ctx.logger.log(finalLog); + } else this.ctx.logger.log(); + this.tests.clear(); + this.renderer?.finish(); + super.onFinished(files, errors); + } + onTestModuleCollected(module) { + for (const test of module.children.allTests()) + // Dot reporter marks pending tests as running + this.onTestCaseReady(test); + } + onTestCaseReady(test) { + if (this.finishedTests.has(test.id)) return; + this.tests.set(test.id, test.result().state || "run"); + this.renderer?.schedule(); + } + onTestCaseResult(test) { + const result = test.result().state; + // On non-TTY the finished tests are printed immediately + if (!this.isTTY && result !== "pending") this.ctx.logger.outputStream.write(formatTests([result])); + super.onTestCaseResult(test); + this.finishedTests.add(test.id); + this.tests.set(test.id, result || "skipped"); + this.renderer?.schedule(); + } + onTestModuleEnd(testModule) { + super.onTestModuleEnd(testModule); + if (!this.isTTY) return; + const columns = this.ctx.logger.getColumns(); + if (this.tests.size < columns) return; + const finishedTests = Array.from(this.tests).filter((entry) => entry[1] !== "pending"); + if (finishedTests.length < columns) return; + // Remove finished tests from state and render them in static output + const states = []; + let count = 0; + for (const [id, state] of finishedTests) { + if (count++ >= columns) break; + this.tests.delete(id); + states.push(state); + } + this.ctx.logger.log(formatTests(states)); + this.renderer?.schedule(); + } + createSummary() { + return [formatTests(Array.from(this.tests.values())), ""]; + } +} +// These are compared with reference equality in formatTests +const pass = { + char: "·", + color: c.green +}; +const fail = { + char: "x", + color: c.red +}; +const pending = { + char: "*", + color: c.yellow +}; +const skip = { + char: "-", + color: (char) => c.dim(c.gray(char)) +}; +function getIcon(state) { + switch (state) { + case "passed": return pass; + case "failed": return fail; + case "skipped": return skip; + default: return pending; + } +} +/** +* Format test states into string while keeping ANSI escapes at minimal. +* Sibling icons with same color are merged into a single c.color() call. +*/ +function formatTests(states) { + let currentIcon = pending; + let count = 0; + let output = ""; + for (const state of states) { + const icon = getIcon(state); + if (currentIcon === icon) { + count++; + continue; + } + output += currentIcon.color(currentIcon.char.repeat(count)); + // Start tracking new group + count = 1; + currentIcon = icon; + } + output += currentIcon.color(currentIcon.char.repeat(count)); + return output; +} + +// use Logger with custom Console to capture entire error printing +function capturePrintError(error, ctx, options) { + let output = ""; + const writable = new Writable({ write(chunk, _encoding, callback) { + output += String(chunk); + callback(); + } }); + const console = new Console(writable); + const logger = { + error: console.error.bind(console), + highlight: ctx.logger.highlight.bind(ctx.logger) + }; + const result = printError(error, ctx, logger, { + showCodeFrame: false, + ...options + }); + return { + nearest: result?.nearest, + output + }; +} +function printError(error, ctx, logger, options) { + const project = options.project ?? ctx.coreWorkspaceProject ?? ctx.projects[0]; + return printErrorInner(error, project, { + logger, + type: options.type, + showCodeFrame: options.showCodeFrame, + screenshotPaths: options.screenshotPaths, + printProperties: options.verbose, + parseErrorStacktrace(error) { + // browser stack trace needs to be processed differently, + // so there is a separate method for that + if (options.task?.file.pool === "browser" && project.browser) return project.browser.parseErrorStacktrace(error, { ignoreStackEntries: options.fullStack ? [] : void 0 }); + // node.js stack trace already has correct source map locations + return parseErrorStacktrace(error, { + frameFilter: project.config.onStackTrace, + ignoreStackEntries: options.fullStack ? [] : void 0 + }); + } + }); +} +function printErrorInner(error, project, options) { + const { showCodeFrame = true, type, printProperties = true } = options; + const logger = options.logger; + let e = error; + if (isPrimitive(e)) e = { + message: String(error).split(/\n/g)[0], + stack: String(error) + }; + if (!e) { + const error = new Error("unknown error"); + e = { + message: e ?? error.message, + stack: error.stack + }; + } + // Error may have occurred even before the configuration was resolved + if (!project) { + printErrorMessage(e, logger); + return; + } + const stacks = options.parseErrorStacktrace(e); + const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find((stack) => { + try { + return project._vite && project.getModuleById(stack.file) && existsSync(stack.file); + } catch { + return false; + } + }); + if (type) printErrorType(type, project.vitest); + printErrorMessage(e, logger); + if (options.screenshotPaths?.length) { + const length = options.screenshotPaths.length; + logger.error(`\nFailure screenshot${length > 1 ? "s" : ""}:`); + logger.error(options.screenshotPaths.map((p) => ` - ${c.dim(relative(process.cwd(), p))}`).join("\n")); + if (!e.diff) logger.error(); + } + if (e.codeFrame) logger.error(`${e.codeFrame}\n`); + if ("__vitest_rollup_error__" in e) { + // https://github.com/vitejs/vite/blob/95020ab49e12d143262859e095025cf02423c1d9/packages/vite/src/node/server/middlewares/error.ts#L25-L36 + const err = e.__vitest_rollup_error__; + logger.error([ + err.plugin && ` Plugin: ${c.magenta(err.plugin)}`, + err.id && ` File: ${c.cyan(err.id)}${err.loc ? `:${err.loc.line}:${err.loc.column}` : ""}`, + err.frame && c.yellow(err.frame.split(/\r?\n/g).map((l) => ` `.repeat(2) + l).join(`\n`)) + ].filter(Boolean).join("\n")); + } + // E.g. AssertionError from assert does not set showDiff but has both actual and expected properties + if (e.diff) logger.error(`\n${e.diff}\n`); + // if the error provide the frame + if (e.frame) logger.error(c.yellow(e.frame)); + else { + const errorProperties = printProperties ? getErrorProperties(e) : {}; + printStack(logger, project, stacks, nearest, errorProperties, (s) => { + if (showCodeFrame && s === nearest && nearest) { + const sourceCode = readFileSync(nearest.file, "utf-8"); + logger.error(generateCodeFrame(sourceCode.length > 1e5 ? sourceCode : logger.highlight(nearest.file, sourceCode), 4, s)); + } + }); + } + const testPath = e.VITEST_TEST_PATH; + const testName = e.VITEST_TEST_NAME; + const afterEnvTeardown = e.VITEST_AFTER_ENV_TEARDOWN; + // testName has testPath inside + if (testPath) logger.error(c.red(`This error originated in "${c.bold(relative(project.config.root, testPath))}" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.`)); + if (testName) logger.error(c.red(`The latest test that might've caused the error is "${c.bold(testName)}". It might mean one of the following: +- The error was thrown, while Vitest was running this test. +- If the error occurred after the test had been completed, this was the last documented test before it was thrown.`)); + if (afterEnvTeardown) logger.error(c.red("This error was caught after test environment was torn down. Make sure to cancel any running tasks before test finishes:\n- cancel timeouts using clearTimeout and clearInterval\n- wait for promises to resolve using the await keyword")); + if (typeof e.cause === "object" && e.cause && "name" in e.cause) { + e.cause.name = `Caused by: ${e.cause.name}`; + printErrorInner(e.cause, project, { + showCodeFrame: false, + logger: options.logger, + parseErrorStacktrace: options.parseErrorStacktrace + }); + } + handleImportOutsideModuleError(e.stack || "", logger); + return { nearest }; +} +function printErrorType(type, ctx) { + ctx.logger.error(`\n${errorBanner(type)}`); +} +const skipErrorProperties = new Set([ + "cause", + "stacks", + "type", + "showDiff", + "ok", + "operator", + "diff", + "codeFrame", + "actual", + "expected", + "diffOptions", + "sourceURL", + "column", + "line", + "fileName", + "lineNumber", + "columnNumber", + "VITEST_TEST_NAME", + "VITEST_TEST_PATH", + "VITEST_AFTER_ENV_TEARDOWN", + "__vitest_rollup_error__", + ...Object.getOwnPropertyNames(Error.prototype), + ...Object.getOwnPropertyNames(Object.prototype) +]); +function getErrorProperties(e) { + const errorObject = Object.create(null); + if (e.name === "AssertionError") return errorObject; + for (const key of Object.getOwnPropertyNames(e)) + // print the original stack if it was ever changed manually by the user + if (key === "stack" && e[key] != null && typeof e[key] !== "string") errorObject[key] = e[key]; + else if (key !== "stack" && !skipErrorProperties.has(key)) errorObject[key] = e[key]; + return errorObject; +} +const esmErrors = ["Cannot use import statement outside a module", "Unexpected token 'export'"]; +function handleImportOutsideModuleError(stack, logger) { + if (!esmErrors.some((e) => stack.includes(e))) return; + const path = normalize(stack.split("\n")[0].trim()); + let name = path.split("/node_modules/").pop() || ""; + if (name?.startsWith("@")) name = name.split("/").slice(0, 2).join("/"); + else name = name.split("/")[0]; + if (name) printModuleWarningForPackage(logger, path, name); + else printModuleWarningForSourceCode(logger, path); +} +function printModuleWarningForPackage(logger, path, name) { + logger.error(c.yellow(`Module ${path} seems to be an ES Module but shipped in a CommonJS package. You might want to create an issue to the package ${c.bold(`"${name}"`)} asking them to ship the file in .mjs extension or add "type": "module" in their package.json. + +As a temporary workaround you can try to inline the package by updating your config: + +` + c.gray(c.dim("// vitest.config.js")) + "\n" + c.green(`export default { + test: { + server: { + deps: { + inline: [ + ${c.yellow(c.bold(`"${name}"`))} + ] + } + } + } +}\n`))); +} +function printModuleWarningForSourceCode(logger, path) { + logger.error(c.yellow(`Module ${path} seems to be an ES Module but shipped in a CommonJS package. To fix this issue, change the file extension to .mjs or add "type": "module" in your package.json.`)); +} +function printErrorMessage(error, logger) { + const errorName = error.name || "Unknown Error"; + if (!error.message) { + logger.error(error); + return; + } + if (error.message.length > 5e3) + // Protect against infinite stack trace in tinyrainbow + logger.error(`${c.red(c.bold(errorName))}: ${error.message}`); + else logger.error(c.red(`${c.bold(errorName)}: ${error.message}`)); +} +function printStack(logger, project, stack, highlight, errorProperties, onStack) { + for (const frame of stack) { + const color = frame === highlight ? c.cyan : c.gray; + const path = relative(project.config.root, frame.file); + logger.error(color(` ${c.dim(F_POINTER)} ${[frame.method, `${path}:${c.dim(`${frame.line}:${frame.column}`)}`].filter(Boolean).join(" ")}`)); + onStack?.(frame); + } + if (stack.length) logger.error(); + if (hasProperties(errorProperties)) { + logger.error(c.red(c.dim(divider()))); + const propertiesString = inspect(errorProperties); + logger.error(c.red(c.bold("Serialized Error:")), c.gray(propertiesString)); + } +} +function hasProperties(obj) { + // eslint-disable-next-line no-unreachable-loop + for (const _key in obj) return true; + return false; +} +function generateCodeFrame(source, indent = 0, loc, range = 2) { + const start = typeof loc === "object" ? positionToOffset(source, loc.line, loc.column) : loc; + const end = start; + const lines = source.split(lineSplitRE); + const nl = /\r\n/.test(source) ? 2 : 1; + let count = 0; + let res = []; + const columns = process.stdout?.columns || 80; + for (let i = 0; i < lines.length; i++) { + count += lines[i].length + nl; + if (count >= start) { + for (let j = i - range; j <= i + range || end > count; j++) { + if (j < 0 || j >= lines.length) continue; + const lineLength = lines[j].length; + // too long, maybe it's a minified file, skip for codeframe + if (stripVTControlCharacters(lines[j]).length > 200) return ""; + res.push(lineNo(j + 1) + truncateString(lines[j].replace(/\t/g, " "), columns - 5 - indent)); + if (j === i) { + // push underline + const pad = start - (count - lineLength) + (nl - 1); + const length = Math.max(1, end > count ? lineLength - pad : end - start); + res.push(lineNo() + " ".repeat(pad) + c.red("^".repeat(length))); + } else if (j > i) { + if (end > count) { + const length = Math.max(1, Math.min(end - count, lineLength)); + res.push(lineNo() + c.red("^".repeat(length))); + } + count += lineLength + 1; + } + } + break; + } + } + if (indent) res = res.map((line) => " ".repeat(indent) + line); + return res.join("\n"); +} +function lineNo(no = "") { + return c.gray(`${String(no).padStart(3, " ")}| `); +} + +class GithubActionsReporter { + ctx = void 0; + options; + constructor(options = {}) { + this.options = options; + } + onInit(ctx) { + this.ctx = ctx; + } + onTestCaseAnnotate(testCase, annotation) { + if (!annotation.location) return; + const type = getTitle(annotation.type); + const formatted = formatMessage({ + command: getType(annotation.type), + properties: { + file: annotation.location.file, + line: String(annotation.location.line), + column: String(annotation.location.column), + ...type && { title: type } + }, + message: stripVTControlCharacters(annotation.message) + }); + this.ctx.logger.log(`\n${formatted}`); + } + onFinished(files = [], errors = []) { + // collect all errors and associate them with projects + const projectErrors = new Array(); + for (const error of errors) projectErrors.push({ + project: this.ctx.getRootProject(), + title: "Unhandled error", + error + }); + for (const file of files) { + const tasks = getTasks(file); + const project = this.ctx.getProjectByName(file.projectName || ""); + for (const task of tasks) { + if (task.result?.state !== "fail") continue; + const title = getFullName(task, " > "); + for (const error of task.result?.errors ?? []) projectErrors.push({ + project, + title, + error, + file + }); + } + } + const onWritePath = this.options.onWritePath ?? defaultOnWritePath; + // format errors via `printError` + for (const { project, title, error, file } of projectErrors) { + const result = capturePrintError(error, this.ctx, { + project, + task: file + }); + const stack = result?.nearest; + if (!stack) continue; + const formatted = formatMessage({ + command: "error", + properties: { + file: onWritePath(stack.file), + title, + line: String(stack.line), + column: String(stack.column) + }, + message: stripVTControlCharacters(result.output) + }); + this.ctx.logger.log(`\n${formatted}`); + } + } +} +const BUILT_IN_TYPES = [ + "notice", + "error", + "warning" +]; +function getTitle(type) { + if (BUILT_IN_TYPES.includes(type)) return void 0; + return type; +} +function getType(type) { + if (BUILT_IN_TYPES.includes(type)) return type; + return "notice"; +} +function defaultOnWritePath(path) { + return path; +} +// workflow command formatting based on +// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message +// https://github.com/actions/toolkit/blob/f1d9b4b985e6f0f728b4b766db73498403fd5ca3/packages/core/src/command.ts#L80-L85 +function formatMessage({ command, properties, message }) { + let result = `::${command}`; + Object.entries(properties).forEach(([k, v], i) => { + result += i === 0 ? " " : ","; + result += `${k}=${escapeProperty(v)}`; + }); + result += `::${escapeData(message)}`; + return result; +} +function escapeData(s) { + return s.replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A"); +} +function escapeProperty(s) { + return s.replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A").replace(/:/g, "%3A").replace(/,/g, "%2C"); +} + +class HangingProcessReporter { + whyRunning; + onInit() { + const _require = createRequire(import.meta.url); + this.whyRunning = _require("why-is-node-running"); + } + onProcessTimeout() { + this.whyRunning?.(); + } +} + +const StatusMap = { + fail: "failed", + only: "pending", + pass: "passed", + run: "pending", + skip: "skipped", + todo: "todo", + queued: "pending" +}; +class JsonReporter { + start = 0; + ctx; + options; + constructor(options) { + this.options = options; + } + onInit(ctx) { + this.ctx = ctx; + this.start = Date.now(); + } + async logTasks(files, coverageMap) { + const suites = getSuites(files); + const numTotalTestSuites = suites.length; + const tests = getTests(files); + const numTotalTests = tests.length; + const numFailedTestSuites = suites.filter((s) => s.result?.state === "fail").length; + const numPendingTestSuites = suites.filter((s) => s.result?.state === "run" || s.result?.state === "queued" || s.mode === "todo").length; + const numPassedTestSuites = numTotalTestSuites - numFailedTestSuites - numPendingTestSuites; + const numFailedTests = tests.filter((t) => t.result?.state === "fail").length; + const numPassedTests = tests.filter((t) => t.result?.state === "pass").length; + const numPendingTests = tests.filter((t) => t.result?.state === "run" || t.result?.state === "queued" || t.mode === "skip" || t.result?.state === "skip").length; + const numTodoTests = tests.filter((t) => t.mode === "todo").length; + const testResults = []; + const success = !!(files.length > 0 || this.ctx.config.passWithNoTests) && numFailedTestSuites === 0 && numFailedTests === 0; + for (const file of files) { + const tests = getTests([file]); + let startTime = tests.reduce((prev, next) => Math.min(prev, next.result?.startTime ?? Number.POSITIVE_INFINITY), Number.POSITIVE_INFINITY); + if (startTime === Number.POSITIVE_INFINITY) startTime = this.start; + const endTime = tests.reduce((prev, next) => Math.max(prev, (next.result?.startTime ?? 0) + (next.result?.duration ?? 0)), startTime); + const assertionResults = tests.map((t) => { + const ancestorTitles = []; + let iter = t.suite; + while (iter) { + ancestorTitles.push(iter.name); + iter = iter.suite; + } + ancestorTitles.reverse(); + return { + ancestorTitles, + fullName: t.name ? [...ancestorTitles, t.name].join(" ") : ancestorTitles.join(" "), + status: StatusMap[t.result?.state || t.mode] || "skipped", + title: t.name, + duration: t.result?.duration, + failureMessages: t.result?.errors?.map((e) => e.stack || e.message) || [], + location: t.location, + meta: t.meta + }; + }); + if (tests.some((t) => t.result?.state === "run" || t.result?.state === "queued")) this.ctx.logger.warn("WARNING: Some tests are still running when generating the JSON report.This is likely an internal bug in Vitest.Please report it to https://github.com/vitest-dev/vitest/issues"); + const hasFailedTests = tests.some((t) => t.result?.state === "fail"); + testResults.push({ + assertionResults, + startTime, + endTime, + status: file.result?.state === "fail" || hasFailedTests ? "failed" : "passed", + message: file.result?.errors?.[0]?.message ?? "", + name: file.filepath + }); + } + const result = { + numTotalTestSuites, + numPassedTestSuites, + numFailedTestSuites, + numPendingTestSuites, + numTotalTests, + numPassedTests, + numFailedTests, + numPendingTests, + numTodoTests, + snapshot: this.ctx.snapshot.summary, + startTime: this.start, + success, + testResults, + coverageMap + }; + await this.writeReport(JSON.stringify(result)); + } + async onFinished(files = this.ctx.state.getFiles(), _errors = [], coverageMap) { + await this.logTasks(files, coverageMap); + } + /** + * Writes the report to an output file if specified in the config, + * or logs it to the console otherwise. + * @param report + */ + async writeReport(report) { + const outputFile = this.options.outputFile ?? getOutputFile(this.ctx.config, "json"); + if (outputFile) { + const reportFile = resolve(this.ctx.config.root, outputFile); + const outputDirectory = dirname(reportFile); + if (!existsSync(outputDirectory)) await promises.mkdir(outputDirectory, { recursive: true }); + await promises.writeFile(reportFile, report, "utf-8"); + this.ctx.logger.log(`JSON report written to ${reportFile}`); + } else this.ctx.logger.log(report); + } +} + +class IndentedLogger { + currentIndent = ""; + constructor(baseLog) { + this.baseLog = baseLog; + } + indent() { + this.currentIndent += " "; + } + unindent() { + this.currentIndent = this.currentIndent.substring(0, this.currentIndent.length - 4); + } + log(text) { + return this.baseLog(this.currentIndent + text); + } +} + +function flattenTasks$1(task, baseName = "") { + const base = baseName ? `${baseName} > ` : ""; + if (task.type === "suite") return task.tasks.flatMap((child) => flattenTasks$1(child, `${base}${task.name}`)); + else return [{ + ...task, + name: `${base}${task.name}` + }]; +} +// https://gist.github.com/john-doherty/b9195065884cdbfd2017a4756e6409cc +function removeInvalidXMLCharacters(value, removeDiscouragedChars) { + let regex = /([\0-\x08\v\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g; + value = String(value || "").replace(regex, ""); + { + // remove everything discouraged by XML 1.0 specifications + regex = new RegExp( + /* eslint-disable regexp/prefer-character-class, regexp/no-obscure-range, regexp/no-useless-non-capturing-group */ + "([\\x7F-\\x84]|[\\x86-\\x9F]|[\\uFDD0-\\uFDEF]|\\uD83F[\\uDFFE\\uDFFF]|(?:\\uD87F[\\uDFFE\\uDFFF])|\\uD8BF[\\uDFFE\\uDFFF]|\\uD8FF[\\uDFFE\\uDFFF]|(?:\\uD93F[\\uDFFE\\uDFFF])|\\uD97F[\\uDFFE\\uDFFF]|\\uD9BF[\\uDFFE\\uDFFF]|\\uD9FF[\\uDFFE\\uDFFF]|\\uDA3F[\\uDFFE\\uDFFF]|\\uDA7F[\\uDFFE\\uDFFF]|\\uDABF[\\uDFFE\\uDFFF]|(?:\\uDAFF[\\uDFFE\\uDFFF])|\\uDB3F[\\uDFFE\\uDFFF]|\\uDB7F[\\uDFFE\\uDFFF]|(?:\\uDBBF[\\uDFFE\\uDFFF])|\\uDBFF[\\uDFFE\\uDFFF](?:[\\0-\\t\\v\\f\\x0E-\\u2027\\u202A-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]))", + "g" + /* eslint-enable */ + ); + value = value.replace(regex, ""); + } + return value; +} +function escapeXML(value) { + return removeInvalidXMLCharacters(String(value).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(//g, ">")); +} +function executionTime(durationMS) { + return (durationMS / 1e3).toLocaleString("en-US", { + useGrouping: false, + maximumFractionDigits: 10 + }); +} +function getDuration(task) { + const duration = task.result?.duration ?? 0; + return executionTime(duration); +} +class JUnitReporter { + ctx; + reportFile; + baseLog; + logger; + _timeStart = /* @__PURE__ */ new Date(); + fileFd; + options; + constructor(options) { + this.options = { ...options }; + this.options.includeConsoleOutput ??= true; + } + async onInit(ctx) { + this.ctx = ctx; + const outputFile = this.options.outputFile ?? getOutputFile(this.ctx.config, "junit"); + if (outputFile) { + this.reportFile = resolve(this.ctx.config.root, outputFile); + const outputDirectory = dirname(this.reportFile); + if (!existsSync(outputDirectory)) await promises.mkdir(outputDirectory, { recursive: true }); + const fileFd = await promises.open(this.reportFile, "w+"); + this.fileFd = fileFd; + this.baseLog = async (text) => { + if (!this.fileFd) this.fileFd = await promises.open(this.reportFile, "w+"); + await promises.writeFile(this.fileFd, `${text}\n`); + }; + } else this.baseLog = async (text) => this.ctx.logger.log(text); + this._timeStart = /* @__PURE__ */ new Date(); + this.logger = new IndentedLogger(this.baseLog); + } + async writeElement(name, attrs, children) { + const pairs = []; + for (const key in attrs) { + const attr = attrs[key]; + if (attr === void 0) continue; + pairs.push(`${key}="${escapeXML(attr)}"`); + } + await this.logger.log(`<${name}${pairs.length ? ` ${pairs.join(" ")}` : ""}>`); + this.logger.indent(); + await children.call(this); + this.logger.unindent(); + await this.logger.log(``); + } + async writeLogs(task, type) { + if (task.logs == null || task.logs.length === 0) return; + const logType = type === "err" ? "stderr" : "stdout"; + const logs = task.logs.filter((log) => log.type === logType); + if (logs.length === 0) return; + await this.writeElement(`system-${type}`, {}, async () => { + for (const log of logs) await this.baseLog(escapeXML(log.content)); + }); + } + async writeTasks(tasks, filename) { + for (const task of tasks) { + let classname = filename; + const templateVars = { + filename: task.file.name, + filepath: task.file.filepath + }; + if (typeof this.options.classnameTemplate === "function") classname = this.options.classnameTemplate(templateVars); + else if (typeof this.options.classnameTemplate === "string") classname = this.options.classnameTemplate.replace(/\{filename\}/g, templateVars.filename).replace(/\{filepath\}/g, templateVars.filepath); + else if (typeof this.options.classname === "string") classname = this.options.classname; + await this.writeElement("testcase", { + classname, + file: this.options.addFileAttribute ? filename : void 0, + name: task.name, + time: getDuration(task) + }, async () => { + if (this.options.includeConsoleOutput) { + await this.writeLogs(task, "out"); + await this.writeLogs(task, "err"); + } + if (task.mode === "skip" || task.mode === "todo") await this.logger.log(""); + if (task.type === "test" && task.annotations.length) { + await this.logger.log(""); + this.logger.indent(); + for (const annotation of task.annotations) { + await this.logger.log(``); + await this.logger.log(""); + } + this.logger.unindent(); + await this.logger.log(""); + } + if (task.result?.state === "fail") { + const errors = task.result.errors || []; + for (const error of errors) await this.writeElement("failure", { + message: error?.message, + type: error?.name + }, async () => { + if (!error) return; + const result = capturePrintError(error, this.ctx, { + project: this.ctx.getProjectByName(task.file.projectName || ""), + task + }); + await this.baseLog(escapeXML(stripVTControlCharacters(result.output.trim()))); + }); + } + }); + } + } + async onFinished(files = this.ctx.state.getFiles()) { + await this.logger.log(""); + const transformed = files.map((file) => { + const tasks = file.tasks.flatMap((task) => flattenTasks$1(task)); + const stats = tasks.reduce((stats, task) => { + return { + passed: stats.passed + Number(task.result?.state === "pass"), + failures: stats.failures + Number(task.result?.state === "fail"), + skipped: stats.skipped + Number(task.mode === "skip" || task.mode === "todo") + }; + }, { + passed: 0, + failures: 0, + skipped: 0 + }); + // inject failed suites to surface errors during beforeAll/afterAll + const suites = getSuites(file); + for (const suite of suites) if (suite.result?.errors) { + tasks.push(suite); + stats.failures += 1; + } + // If there are no tests, but the file failed to load, we still want to report it as a failure + if (tasks.length === 0 && file.result?.state === "fail") { + stats.failures = 1; + tasks.push({ + id: file.id, + type: "test", + name: file.name, + mode: "run", + result: file.result, + meta: {}, + timeout: 0, + context: null, + suite: null, + file: null, + annotations: [] + }); + } + return { + ...file, + tasks, + stats + }; + }); + const stats = transformed.reduce((stats, file) => { + stats.tests += file.tasks.length; + stats.failures += file.stats.failures; + stats.time += file.result?.duration || 0; + return stats; + }, { + name: this.options.suiteName || "vitest tests", + tests: 0, + failures: 0, + errors: 0, + time: 0 + }); + await this.writeElement("testsuites", { + ...stats, + time: executionTime(stats.time) + }, async () => { + for (const file of transformed) { + const filename = relative(this.ctx.config.root, file.filepath); + await this.writeElement("testsuite", { + name: filename, + timestamp: (/* @__PURE__ */ new Date()).toISOString(), + hostname: hostname(), + tests: file.tasks.length, + failures: file.stats.failures, + errors: 0, + skipped: file.stats.skipped, + time: getDuration(file) + }, async () => { + await this.writeTasks(file.tasks, filename); + }); + } + }); + if (this.reportFile) this.ctx.logger.log(`JUNIT report written to ${this.reportFile}`); + await this.fileFd?.close(); + this.fileFd = void 0; + } +} + +function yamlString(str) { + return `"${str.replace(/"/g, "\\\"")}"`; +} +function tapString(str) { + return str.replace(/\\/g, "\\\\").replace(/#/g, "\\#").replace(/\n/g, " "); +} +class TapReporter { + ctx; + logger; + onInit(ctx) { + this.ctx = ctx; + this.logger = new IndentedLogger(ctx.logger.log.bind(ctx.logger)); + } + static getComment(task) { + if (task.mode === "skip") return " # SKIP"; + else if (task.mode === "todo") return " # TODO"; + else if (task.result?.duration != null) return ` # time=${task.result.duration.toFixed(2)}ms`; + else return ""; + } + logErrorDetails(error, stack) { + const errorName = error.name || "Unknown Error"; + this.logger.log(`name: ${yamlString(String(errorName))}`); + this.logger.log(`message: ${yamlString(String(error.message))}`); + if (stack) + // For compatibility with tap-mocha-reporter + this.logger.log(`stack: ${yamlString(`${stack.file}:${stack.line}:${stack.column}`)}`); + } + logTasks(tasks) { + this.logger.log(`1..${tasks.length}`); + for (const [i, task] of tasks.entries()) { + const id = i + 1; + const ok = task.result?.state === "pass" || task.mode === "skip" || task.mode === "todo" ? "ok" : "not ok"; + const comment = TapReporter.getComment(task); + if (task.type === "suite" && task.tasks.length > 0) { + this.logger.log(`${ok} ${id} - ${tapString(task.name)}${comment} {`); + this.logger.indent(); + this.logTasks(task.tasks); + this.logger.unindent(); + this.logger.log("}"); + } else { + this.logger.log(`${ok} ${id} - ${tapString(task.name)}${comment}`); + const project = this.ctx.getProjectByName(task.file.projectName || ""); + if (task.type === "test" && task.annotations) { + this.logger.indent(); + task.annotations.forEach(({ type, message }) => { + this.logger.log(`# ${type}: ${message}`); + }); + this.logger.unindent(); + } + if (task.result?.state === "fail" && task.result.errors) { + this.logger.indent(); + task.result.errors.forEach((error) => { + const stacks = task.file.pool === "browser" ? project.browser?.parseErrorStacktrace(error) || [] : parseErrorStacktrace(error, { frameFilter: this.ctx.config.onStackTrace }); + const stack = stacks[0]; + this.logger.log("---"); + this.logger.log("error:"); + this.logger.indent(); + this.logErrorDetails(error); + this.logger.unindent(); + if (stack) this.logger.log(`at: ${yamlString(`${stack.file}:${stack.line}:${stack.column}`)}`); + if (error.showDiff) { + this.logger.log(`actual: ${yamlString(error.actual)}`); + this.logger.log(`expected: ${yamlString(error.expected)}`); + } + }); + this.logger.log("..."); + this.logger.unindent(); + } + } + } + } + onFinished(files = this.ctx.state.getFiles()) { + this.logger.log("TAP version 13"); + this.logTasks(files); + } +} + +function flattenTasks(task, baseName = "") { + const base = baseName ? `${baseName} > ` : ""; + if (task.type === "suite" && task.tasks.length > 0) return task.tasks.flatMap((child) => flattenTasks(child, `${base}${task.name}`)); + else return [{ + ...task, + name: `${base}${task.name}` + }]; +} +class TapFlatReporter extends TapReporter { + onInit(ctx) { + super.onInit(ctx); + } + onFinished(files = this.ctx.state.getFiles()) { + this.ctx.logger.log("TAP version 13"); + const flatTasks = files.flatMap((task) => flattenTasks(task)); + this.logTasks(flatTasks); + } +} + +class VerboseReporter extends DefaultReporter { + verbose = true; + renderSucceed = true; + printTestModule(module) { + // still print the test module in TTY, + // but don't print it in the CLI because we + // print all the tests when they finish + // instead of printing them when the test file finishes + if (this.isTTY) return super.printTestModule(module); + } + onTestCaseResult(test) { + super.onTestCaseResult(test); + // don't print tests in TTY as they go, only print them + // in the CLI when they finish + if (this.isTTY) return; + const testResult = test.result(); + if (this.ctx.config.hideSkippedTests && testResult.state === "skipped") return; + let title = ` ${getStateSymbol(test.task)} `; + if (test.project.name) title += formatProjectName(test.project); + title += getFullName(test.task, c.dim(" > ")); + title += this.getDurationPrefix(test.task); + const diagnostic = test.diagnostic(); + if (diagnostic?.heap != null) title += c.magenta(` ${Math.floor(diagnostic.heap / 1024 / 1024)} MB heap used`); + if (testResult.state === "skipped" && testResult.note) title += c.dim(c.gray(` [${testResult.note}]`)); + this.log(title); + if (testResult.state === "failed") testResult.errors.forEach((error) => this.log(c.red(` ${F_RIGHT} ${error?.message}`))); + if (test.annotations().length) { + this.log(); + this.printAnnotations(test, "log", 3); + this.log(); + } + } + printTestSuite(testSuite) { + const indentation = " ".repeat(getIndentation(testSuite.task)); + const tests = Array.from(testSuite.children.allTests()); + const state = getStateSymbol(testSuite.task); + this.log(` ${indentation}${state} ${testSuite.name} ${c.dim(`(${tests.length})`)}`); + } + getTestName(test) { + return test.name; + } + getTestIndentation(test) { + return " ".repeat(getIndentation(test)); + } + formatShortError() { + // Short errors are not shown in tree-view + return ""; + } +} +function getIndentation(suite, level = 1) { + if (suite.suite && !("filepath" in suite.suite)) return getIndentation(suite.suite, level + 1); + return level; +} + +const ReportersMap = { + "default": DefaultReporter, + "basic": BasicReporter, + "blob": BlobReporter, + "verbose": VerboseReporter, + "dot": DotReporter, + "json": JsonReporter, + "tap": TapReporter, + "tap-flat": TapFlatReporter, + "junit": JUnitReporter, + "hanging-process": HangingProcessReporter, + "github-actions": GithubActionsReporter +}; + +export { BasicReporter as B, DefaultReporter as D, F_RIGHT as F, GithubActionsReporter as G, HangingProcessReporter as H, JsonReporter as J, ReportersMap as R, TapFlatReporter as T, VerboseReporter as V, DotReporter as a, JUnitReporter as b, TapReporter as c, printError as d, errorBanner as e, formatProjectName as f, getStateSymbol as g, divider as h, generateCodeFrame as i, BlobReporter as j, parse as p, readBlobs as r, stringify as s, truncateString as t, utils as u, withLabel as w }; diff --git a/node_modules/vitest/dist/chunks/index.X0nbfr6-.js b/node_modules/vitest/dist/chunks/index.X0nbfr6-.js new file mode 100644 index 0000000000..0fb262fe71 --- /dev/null +++ b/node_modules/vitest/dist/chunks/index.X0nbfr6-.js @@ -0,0 +1,6584 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import process$1 from 'node:process'; +import { promises } from 'node:fs'; +import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js'; +import require$$0 from 'readline'; +import require$$0$1 from 'events'; + +function _mergeNamespaces(n, m) { + m.forEach(function (e) { + e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) { + if (k !== 'default' && !(k in n)) { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: function () { return e[k]; } + }); + } + }); + }); + return Object.freeze(n); +} + +/* +How it works: +`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value. +*/ + +class Node { + value; + next; + + constructor(value) { + this.value = value; + } +} + +class Queue { + #head; + #tail; + #size; + + constructor() { + this.clear(); + } + + enqueue(value) { + const node = new Node(value); + + if (this.#head) { + this.#tail.next = node; + this.#tail = node; + } else { + this.#head = node; + this.#tail = node; + } + + this.#size++; + } + + dequeue() { + const current = this.#head; + if (!current) { + return; + } + + this.#head = this.#head.next; + this.#size--; + return current.value; + } + + clear() { + this.#head = undefined; + this.#tail = undefined; + this.#size = 0; + } + + get size() { + return this.#size; + } + + * [Symbol.iterator]() { + let current = this.#head; + + while (current) { + yield current.value; + current = current.next; + } + } +} + +function pLimit(concurrency) { + if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) { + throw new TypeError('Expected `concurrency` to be a number from 1 and up'); + } + + const queue = new Queue(); + let activeCount = 0; + + const next = () => { + activeCount--; + + if (queue.size > 0) { + queue.dequeue()(); + } + }; + + const run = async (fn, resolve, args) => { + activeCount++; + + const result = (async () => fn(...args))(); + + resolve(result); + + try { + await result; + } catch {} + + next(); + }; + + const enqueue = (fn, resolve, args) => { + queue.enqueue(run.bind(undefined, fn, resolve, args)); + + (async () => { + // This function needs to wait until the next microtask before comparing + // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously + // when the run function is dequeued and called. The comparison in the if-statement + // needs to happen asynchronously as well to get an up-to-date value for `activeCount`. + await Promise.resolve(); + + if (activeCount < concurrency && queue.size > 0) { + queue.dequeue()(); + } + })(); + }; + + const generator = (fn, ...args) => new Promise(resolve => { + enqueue(fn, resolve, args); + }); + + Object.defineProperties(generator, { + activeCount: { + get: () => activeCount, + }, + pendingCount: { + get: () => queue.size, + }, + clearQueue: { + value: () => { + queue.clear(); + }, + }, + }); + + return generator; +} + +class EndError extends Error { + constructor(value) { + super(); + this.value = value; + } +} + +// The input can also be a promise, so we await it. +const testElement = async (element, tester) => tester(await element); + +// The input can also be a promise, so we `Promise.all()` them both. +const finder = async element => { + const values = await Promise.all(element); + if (values[1] === true) { + throw new EndError(values[0]); + } + + return false; +}; + +async function pLocate( + iterable, + tester, + { + concurrency = Number.POSITIVE_INFINITY, + preserveOrder = true, + } = {}, +) { + const limit = pLimit(concurrency); + + // Start all the promises concurrently with optional limit. + const items = [...iterable].map(element => [element, limit(testElement, element, tester)]); + + // Check the promises either serially or concurrently. + const checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY); + + try { + await Promise.all(items.map(element => checkLimit(finder, element))); + } catch (error) { + if (error instanceof EndError) { + return error.value; + } + + throw error; + } +} + +const typeMappings = { + directory: 'isDirectory', + file: 'isFile', +}; + +function checkType(type) { + if (Object.hasOwnProperty.call(typeMappings, type)) { + return; + } + + throw new Error(`Invalid type specified: ${type}`); +} + +const matchType = (type, stat) => stat[typeMappings[type]](); + +const toPath$1 = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath; + +async function locatePath( + paths, + { + cwd = process$1.cwd(), + type = 'file', + allowSymlinks = true, + concurrency, + preserveOrder, + } = {}, +) { + checkType(type); + cwd = toPath$1(cwd); + + const statFunction = allowSymlinks ? promises.stat : promises.lstat; + + return pLocate(paths, async path_ => { + try { + const stat = await statFunction(path.resolve(cwd, path_)); + return matchType(type, stat); + } catch { + return false; + } + }, {concurrency, preserveOrder}); +} + +const toPath = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath; + +const findUpStop = Symbol('findUpStop'); + +async function findUpMultiple(name, options = {}) { + let directory = path.resolve(toPath(options.cwd) || ''); + const {root} = path.parse(directory); + const stopAt = path.resolve(directory, options.stopAt || root); + const limit = options.limit || Number.POSITIVE_INFINITY; + const paths = [name].flat(); + + const runMatcher = async locateOptions => { + if (typeof name !== 'function') { + return locatePath(paths, locateOptions); + } + + const foundPath = await name(locateOptions.cwd); + if (typeof foundPath === 'string') { + return locatePath([foundPath], locateOptions); + } + + return foundPath; + }; + + const matches = []; + // eslint-disable-next-line no-constant-condition + while (true) { + // eslint-disable-next-line no-await-in-loop + const foundPath = await runMatcher({...options, cwd: directory}); + + if (foundPath === findUpStop) { + break; + } + + if (foundPath) { + matches.push(path.resolve(directory, foundPath)); + } + + if (directory === stopAt || matches.length >= limit) { + break; + } + + directory = path.dirname(directory); + } + + return matches; +} + +async function findUp(name, options = {}) { + const matches = await findUpMultiple(name, {...options, limit: 1}); + return matches[0]; +} + +var prompts$2 = {}; + +var kleur; +var hasRequiredKleur; + +function requireKleur () { + if (hasRequiredKleur) return kleur; + hasRequiredKleur = 1; + + const { FORCE_COLOR, NODE_DISABLE_COLORS, TERM } = process.env; + + const $ = { + enabled: !NODE_DISABLE_COLORS && TERM !== 'dumb' && FORCE_COLOR !== '0', + + // modifiers + reset: init(0, 0), + bold: init(1, 22), + dim: init(2, 22), + italic: init(3, 23), + underline: init(4, 24), + inverse: init(7, 27), + hidden: init(8, 28), + strikethrough: init(9, 29), + + // colors + black: init(30, 39), + red: init(31, 39), + green: init(32, 39), + yellow: init(33, 39), + blue: init(34, 39), + magenta: init(35, 39), + cyan: init(36, 39), + white: init(37, 39), + gray: init(90, 39), + grey: init(90, 39), + + // background colors + bgBlack: init(40, 49), + bgRed: init(41, 49), + bgGreen: init(42, 49), + bgYellow: init(43, 49), + bgBlue: init(44, 49), + bgMagenta: init(45, 49), + bgCyan: init(46, 49), + bgWhite: init(47, 49) + }; + + function run(arr, str) { + let i=0, tmp, beg='', end=''; + for (; i < arr.length; i++) { + tmp = arr[i]; + beg += tmp.open; + end += tmp.close; + if (str.includes(tmp.close)) { + str = str.replace(tmp.rgx, tmp.close + tmp.open); + } + } + return beg + str + end; + } + + function chain(has, keys) { + let ctx = { has, keys }; + + ctx.reset = $.reset.bind(ctx); + ctx.bold = $.bold.bind(ctx); + ctx.dim = $.dim.bind(ctx); + ctx.italic = $.italic.bind(ctx); + ctx.underline = $.underline.bind(ctx); + ctx.inverse = $.inverse.bind(ctx); + ctx.hidden = $.hidden.bind(ctx); + ctx.strikethrough = $.strikethrough.bind(ctx); + + ctx.black = $.black.bind(ctx); + ctx.red = $.red.bind(ctx); + ctx.green = $.green.bind(ctx); + ctx.yellow = $.yellow.bind(ctx); + ctx.blue = $.blue.bind(ctx); + ctx.magenta = $.magenta.bind(ctx); + ctx.cyan = $.cyan.bind(ctx); + ctx.white = $.white.bind(ctx); + ctx.gray = $.gray.bind(ctx); + ctx.grey = $.grey.bind(ctx); + + ctx.bgBlack = $.bgBlack.bind(ctx); + ctx.bgRed = $.bgRed.bind(ctx); + ctx.bgGreen = $.bgGreen.bind(ctx); + ctx.bgYellow = $.bgYellow.bind(ctx); + ctx.bgBlue = $.bgBlue.bind(ctx); + ctx.bgMagenta = $.bgMagenta.bind(ctx); + ctx.bgCyan = $.bgCyan.bind(ctx); + ctx.bgWhite = $.bgWhite.bind(ctx); + + return ctx; + } + + function init(open, close) { + let blk = { + open: `\x1b[${open}m`, + close: `\x1b[${close}m`, + rgx: new RegExp(`\\x1b\\[${close}m`, 'g') + }; + return function (txt) { + if (this !== void 0 && this.has !== void 0) { + this.has.includes(open) || (this.has.push(open),this.keys.push(blk)); + return txt === void 0 ? this : $.enabled ? run(this.keys, txt+'') : txt+''; + } + return txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt+'') : txt+''; + }; + } + + kleur = $; + return kleur; +} + +var action$1; +var hasRequiredAction$1; + +function requireAction$1 () { + if (hasRequiredAction$1) return action$1; + hasRequiredAction$1 = 1; + + action$1 = (key, isSelect) => { + if (key.meta && key.name !== 'escape') return; + + if (key.ctrl) { + if (key.name === 'a') return 'first'; + if (key.name === 'c') return 'abort'; + if (key.name === 'd') return 'abort'; + if (key.name === 'e') return 'last'; + if (key.name === 'g') return 'reset'; + } + + if (isSelect) { + if (key.name === 'j') return 'down'; + if (key.name === 'k') return 'up'; + } + + if (key.name === 'return') return 'submit'; + if (key.name === 'enter') return 'submit'; // ctrl + J + + if (key.name === 'backspace') return 'delete'; + if (key.name === 'delete') return 'deleteForward'; + if (key.name === 'abort') return 'abort'; + if (key.name === 'escape') return 'exit'; + if (key.name === 'tab') return 'next'; + if (key.name === 'pagedown') return 'nextPage'; + if (key.name === 'pageup') return 'prevPage'; // TODO create home() in prompt types (e.g. TextPrompt) + + if (key.name === 'home') return 'home'; // TODO create end() in prompt types (e.g. TextPrompt) + + if (key.name === 'end') return 'end'; + if (key.name === 'up') return 'up'; + if (key.name === 'down') return 'down'; + if (key.name === 'right') return 'right'; + if (key.name === 'left') return 'left'; + return false; + }; + return action$1; +} + +var strip$1; +var hasRequiredStrip$1; + +function requireStrip$1 () { + if (hasRequiredStrip$1) return strip$1; + hasRequiredStrip$1 = 1; + + strip$1 = str => { + const pattern = ['[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))'].join('|'); + const RGX = new RegExp(pattern, 'g'); + return typeof str === 'string' ? str.replace(RGX, '') : str; + }; + return strip$1; +} + +var src; +var hasRequiredSrc; + +function requireSrc () { + if (hasRequiredSrc) return src; + hasRequiredSrc = 1; + + const ESC = '\x1B'; + const CSI = `${ESC}[`; + const beep = '\u0007'; + + const cursor = { + to(x, y) { + if (!y) return `${CSI}${x + 1}G`; + return `${CSI}${y + 1};${x + 1}H`; + }, + move(x, y) { + let ret = ''; + + if (x < 0) ret += `${CSI}${-x}D`; + else if (x > 0) ret += `${CSI}${x}C`; + + if (y < 0) ret += `${CSI}${-y}A`; + else if (y > 0) ret += `${CSI}${y}B`; + + return ret; + }, + up: (count = 1) => `${CSI}${count}A`, + down: (count = 1) => `${CSI}${count}B`, + forward: (count = 1) => `${CSI}${count}C`, + backward: (count = 1) => `${CSI}${count}D`, + nextLine: (count = 1) => `${CSI}E`.repeat(count), + prevLine: (count = 1) => `${CSI}F`.repeat(count), + left: `${CSI}G`, + hide: `${CSI}?25l`, + show: `${CSI}?25h`, + save: `${ESC}7`, + restore: `${ESC}8` + }; + + const scroll = { + up: (count = 1) => `${CSI}S`.repeat(count), + down: (count = 1) => `${CSI}T`.repeat(count) + }; + + const erase = { + screen: `${CSI}2J`, + up: (count = 1) => `${CSI}1J`.repeat(count), + down: (count = 1) => `${CSI}J`.repeat(count), + line: `${CSI}2K`, + lineEnd: `${CSI}K`, + lineStart: `${CSI}1K`, + lines(count) { + let clear = ''; + for (let i = 0; i < count; i++) + clear += this.line + (i < count - 1 ? cursor.up() : ''); + if (count) + clear += cursor.left; + return clear; + } + }; + + src = { cursor, scroll, erase, beep }; + return src; +} + +var clear$1; +var hasRequiredClear$1; + +function requireClear$1 () { + if (hasRequiredClear$1) return clear$1; + hasRequiredClear$1 = 1; + + function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike) { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + + function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } + + const strip = requireStrip$1(); + + const _require = requireSrc(), + erase = _require.erase, + cursor = _require.cursor; + + const width = str => [...strip(str)].length; + /** + * @param {string} prompt + * @param {number} perLine + */ + + + clear$1 = function (prompt, perLine) { + if (!perLine) return erase.line + cursor.to(0); + let rows = 0; + const lines = prompt.split(/\r?\n/); + + var _iterator = _createForOfIteratorHelper(lines), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + let line = _step.value; + rows += 1 + Math.floor(Math.max(width(line) - 1, 0) / perLine); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return erase.lines(rows); + }; + return clear$1; +} + +var figures_1$1; +var hasRequiredFigures$1; + +function requireFigures$1 () { + if (hasRequiredFigures$1) return figures_1$1; + hasRequiredFigures$1 = 1; + + const main = { + arrowUp: '↑', + arrowDown: '↓', + arrowLeft: '←', + arrowRight: '→', + radioOn: '◉', + radioOff: '◯', + tick: '✔', + cross: '✖', + ellipsis: '…', + pointerSmall: '›', + line: '─', + pointer: '❯' + }; + const win = { + arrowUp: main.arrowUp, + arrowDown: main.arrowDown, + arrowLeft: main.arrowLeft, + arrowRight: main.arrowRight, + radioOn: '(*)', + radioOff: '( )', + tick: '√', + cross: '×', + ellipsis: '...', + pointerSmall: '»', + line: '─', + pointer: '>' + }; + const figures = process.platform === 'win32' ? win : main; + figures_1$1 = figures; + return figures_1$1; +} + +var style$1; +var hasRequiredStyle$1; + +function requireStyle$1 () { + if (hasRequiredStyle$1) return style$1; + hasRequiredStyle$1 = 1; + + const c = requireKleur(); + + const figures = requireFigures$1(); // rendering user input. + + + const styles = Object.freeze({ + password: { + scale: 1, + render: input => '*'.repeat(input.length) + }, + emoji: { + scale: 2, + render: input => '😃'.repeat(input.length) + }, + invisible: { + scale: 0, + render: input => '' + }, + default: { + scale: 1, + render: input => `${input}` + } + }); + + const render = type => styles[type] || styles.default; // icon to signalize a prompt. + + + const symbols = Object.freeze({ + aborted: c.red(figures.cross), + done: c.green(figures.tick), + exited: c.yellow(figures.cross), + default: c.cyan('?') + }); + + const symbol = (done, aborted, exited) => aborted ? symbols.aborted : exited ? symbols.exited : done ? symbols.done : symbols.default; // between the question and the user's input. + + + const delimiter = completing => c.gray(completing ? figures.ellipsis : figures.pointerSmall); + + const item = (expandable, expanded) => c.gray(expandable ? expanded ? figures.pointerSmall : '+' : figures.line); + + style$1 = { + styles, + render, + symbols, + symbol, + delimiter, + item + }; + return style$1; +} + +var lines$1; +var hasRequiredLines$1; + +function requireLines$1 () { + if (hasRequiredLines$1) return lines$1; + hasRequiredLines$1 = 1; + + const strip = requireStrip$1(); + /** + * @param {string} msg + * @param {number} perLine + */ + + + lines$1 = function (msg, perLine) { + let lines = String(strip(msg) || '').split(/\r?\n/); + if (!perLine) return lines.length; + return lines.map(l => Math.ceil(l.length / perLine)).reduce((a, b) => a + b); + }; + return lines$1; +} + +var wrap$1; +var hasRequiredWrap$1; + +function requireWrap$1 () { + if (hasRequiredWrap$1) return wrap$1; + hasRequiredWrap$1 = 1; + /** + * @param {string} msg The message to wrap + * @param {object} opts + * @param {number|string} [opts.margin] Left margin + * @param {number} opts.width Maximum characters per line including the margin + */ + + wrap$1 = (msg, opts = {}) => { + const tab = Number.isSafeInteger(parseInt(opts.margin)) ? new Array(parseInt(opts.margin)).fill(' ').join('') : opts.margin || ''; + const width = opts.width; + return (msg || '').split(/\r?\n/g).map(line => line.split(/\s+/g).reduce((arr, w) => { + if (w.length + tab.length >= width || arr[arr.length - 1].length + w.length + 1 < width) arr[arr.length - 1] += ` ${w}`;else arr.push(`${tab}${w}`); + return arr; + }, [tab]).join('\n')).join('\n'); + }; + return wrap$1; +} + +var entriesToDisplay$1; +var hasRequiredEntriesToDisplay$1; + +function requireEntriesToDisplay$1 () { + if (hasRequiredEntriesToDisplay$1) return entriesToDisplay$1; + hasRequiredEntriesToDisplay$1 = 1; + /** + * Determine what entries should be displayed on the screen, based on the + * currently selected index and the maximum visible. Used in list-based + * prompts like `select` and `multiselect`. + * + * @param {number} cursor the currently selected entry + * @param {number} total the total entries available to display + * @param {number} [maxVisible] the number of entries that can be displayed + */ + + entriesToDisplay$1 = (cursor, total, maxVisible) => { + maxVisible = maxVisible || total; + let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2)); + if (startIndex < 0) startIndex = 0; + let endIndex = Math.min(startIndex + maxVisible, total); + return { + startIndex, + endIndex + }; + }; + return entriesToDisplay$1; +} + +var util$1; +var hasRequiredUtil$1; + +function requireUtil$1 () { + if (hasRequiredUtil$1) return util$1; + hasRequiredUtil$1 = 1; + + util$1 = { + action: requireAction$1(), + clear: requireClear$1(), + style: requireStyle$1(), + strip: requireStrip$1(), + figures: requireFigures$1(), + lines: requireLines$1(), + wrap: requireWrap$1(), + entriesToDisplay: requireEntriesToDisplay$1() + }; + return util$1; +} + +var prompt$2; +var hasRequiredPrompt$1; + +function requirePrompt$1 () { + if (hasRequiredPrompt$1) return prompt$2; + hasRequiredPrompt$1 = 1; + + const readline = require$$0; + + const _require = requireUtil$1(), + action = _require.action; + + const EventEmitter = require$$0$1; + + const _require2 = requireSrc(), + beep = _require2.beep, + cursor = _require2.cursor; + + const color = requireKleur(); + /** + * Base prompt skeleton + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + + + class Prompt extends EventEmitter { + constructor(opts = {}) { + super(); + this.firstRender = true; + this.in = opts.stdin || process.stdin; + this.out = opts.stdout || process.stdout; + + this.onRender = (opts.onRender || (() => void 0)).bind(this); + + const rl = readline.createInterface({ + input: this.in, + escapeCodeTimeout: 50 + }); + readline.emitKeypressEvents(this.in, rl); + if (this.in.isTTY) this.in.setRawMode(true); + const isSelect = ['SelectPrompt', 'MultiselectPrompt'].indexOf(this.constructor.name) > -1; + + const keypress = (str, key) => { + let a = action(key, isSelect); + + if (a === false) { + this._ && this._(str, key); + } else if (typeof this[a] === 'function') { + this[a](key); + } else { + this.bell(); + } + }; + + this.close = () => { + this.out.write(cursor.show); + this.in.removeListener('keypress', keypress); + if (this.in.isTTY) this.in.setRawMode(false); + rl.close(); + this.emit(this.aborted ? 'abort' : this.exited ? 'exit' : 'submit', this.value); + this.closed = true; + }; + + this.in.on('keypress', keypress); + } + + fire() { + this.emit('state', { + value: this.value, + aborted: !!this.aborted, + exited: !!this.exited + }); + } + + bell() { + this.out.write(beep); + } + + render() { + this.onRender(color); + if (this.firstRender) this.firstRender = false; + } + + } + + prompt$2 = Prompt; + return prompt$2; +} + +var text$1; +var hasRequiredText$1; + +function requireText$1 () { + if (hasRequiredText$1) return text$1; + hasRequiredText$1 = 1; + + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + + function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + + const color = requireKleur(); + + const Prompt = requirePrompt$1(); + + const _require = requireSrc(), + erase = _require.erase, + cursor = _require.cursor; + + const _require2 = requireUtil$1(), + style = _require2.style, + clear = _require2.clear, + lines = _require2.lines, + figures = _require2.figures; + /** + * TextPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {String} [opts.style='default'] Render style + * @param {String} [opts.initial] Default value + * @param {Function} [opts.validate] Validate function + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {String} [opts.error] The invalid error label + */ + + + class TextPrompt extends Prompt { + constructor(opts = {}) { + super(opts); + this.transform = style.render(opts.style); + this.scale = this.transform.scale; + this.msg = opts.message; + this.initial = opts.initial || ``; + + this.validator = opts.validate || (() => true); + + this.value = ``; + this.errorMsg = opts.error || `Please Enter A Valid Value`; + this.cursor = Number(!!this.initial); + this.cursorOffset = 0; + this.clear = clear(``, this.out.columns); + this.render(); + } + + set value(v) { + if (!v && this.initial) { + this.placeholder = true; + this.rendered = color.gray(this.transform.render(this.initial)); + } else { + this.placeholder = false; + this.rendered = this.transform.render(v); + } + + this._value = v; + this.fire(); + } + + get value() { + return this._value; + } + + reset() { + this.value = ``; + this.cursor = Number(!!this.initial); + this.cursorOffset = 0; + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.value = this.value || this.initial; + this.done = this.aborted = true; + this.error = false; + this.red = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + validate() { + var _this = this; + + return _asyncToGenerator(function* () { + let valid = yield _this.validator(_this.value); + + if (typeof valid === `string`) { + _this.errorMsg = valid; + valid = false; + } + + _this.error = !valid; + })(); + } + + submit() { + var _this2 = this; + + return _asyncToGenerator(function* () { + _this2.value = _this2.value || _this2.initial; + _this2.cursorOffset = 0; + _this2.cursor = _this2.rendered.length; + yield _this2.validate(); + + if (_this2.error) { + _this2.red = true; + + _this2.fire(); + + _this2.render(); + + return; + } + + _this2.done = true; + _this2.aborted = false; + + _this2.fire(); + + _this2.render(); + + _this2.out.write('\n'); + + _this2.close(); + })(); + } + + next() { + if (!this.placeholder) return this.bell(); + this.value = this.initial; + this.cursor = this.rendered.length; + this.fire(); + this.render(); + } + + moveCursor(n) { + if (this.placeholder) return; + this.cursor = this.cursor + n; + this.cursorOffset += n; + } + + _(c, key) { + let s1 = this.value.slice(0, this.cursor); + let s2 = this.value.slice(this.cursor); + this.value = `${s1}${c}${s2}`; + this.red = false; + this.cursor = this.placeholder ? 0 : s1.length + 1; + this.render(); + } + + delete() { + if (this.isCursorAtStart()) return this.bell(); + let s1 = this.value.slice(0, this.cursor - 1); + let s2 = this.value.slice(this.cursor); + this.value = `${s1}${s2}`; + this.red = false; + + if (this.isCursorAtStart()) { + this.cursorOffset = 0; + } else { + this.cursorOffset++; + this.moveCursor(-1); + } + + this.render(); + } + + deleteForward() { + if (this.cursor * this.scale >= this.rendered.length || this.placeholder) return this.bell(); + let s1 = this.value.slice(0, this.cursor); + let s2 = this.value.slice(this.cursor + 1); + this.value = `${s1}${s2}`; + this.red = false; + + if (this.isCursorAtEnd()) { + this.cursorOffset = 0; + } else { + this.cursorOffset++; + } + + this.render(); + } + + first() { + this.cursor = 0; + this.render(); + } + + last() { + this.cursor = this.value.length; + this.render(); + } + + left() { + if (this.cursor <= 0 || this.placeholder) return this.bell(); + this.moveCursor(-1); + this.render(); + } + + right() { + if (this.cursor * this.scale >= this.rendered.length || this.placeholder) return this.bell(); + this.moveCursor(1); + this.render(); + } + + isCursorAtStart() { + return this.cursor === 0 || this.placeholder && this.cursor === 1; + } + + isCursorAtEnd() { + return this.cursor === this.rendered.length || this.placeholder && this.cursor === this.rendered.length + 1; + } + + render() { + if (this.closed) return; + + if (!this.firstRender) { + if (this.outputError) this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns)); + this.out.write(clear(this.outputText, this.out.columns)); + } + + super.render(); + this.outputError = ''; + this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.red ? color.red(this.rendered) : this.rendered].join(` `); + + if (this.error) { + this.outputError += this.errorMsg.split(`\n`).reduce((a, l, i) => a + `\n${i ? ' ' : figures.pointerSmall} ${color.red().italic(l)}`, ``); + } + + this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore + cursor.move(this.cursorOffset, 0)); + } + + } + + text$1 = TextPrompt; + return text$1; +} + +var select$1; +var hasRequiredSelect$1; + +function requireSelect$1 () { + if (hasRequiredSelect$1) return select$1; + hasRequiredSelect$1 = 1; + + const color = requireKleur(); + + const Prompt = requirePrompt$1(); + + const _require = requireUtil$1(), + style = _require.style, + clear = _require.clear, + figures = _require.figures, + wrap = _require.wrap, + entriesToDisplay = _require.entriesToDisplay; + + const _require2 = requireSrc(), + cursor = _require2.cursor; + /** + * SelectPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Array} opts.choices Array of choice objects + * @param {String} [opts.hint] Hint to display + * @param {Number} [opts.initial] Index of default value + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {Number} [opts.optionsPerPage=10] Max options to display at once + */ + + + class SelectPrompt extends Prompt { + constructor(opts = {}) { + super(opts); + this.msg = opts.message; + this.hint = opts.hint || '- Use arrow-keys. Return to submit.'; + this.warn = opts.warn || '- This option is disabled'; + this.cursor = opts.initial || 0; + this.choices = opts.choices.map((ch, idx) => { + if (typeof ch === 'string') ch = { + title: ch, + value: idx + }; + return { + title: ch && (ch.title || ch.value || ch), + value: ch && (ch.value === undefined ? idx : ch.value), + description: ch && ch.description, + selected: ch && ch.selected, + disabled: ch && ch.disabled + }; + }); + this.optionsPerPage = opts.optionsPerPage || 10; + this.value = (this.choices[this.cursor] || {}).value; + this.clear = clear('', this.out.columns); + this.render(); + } + + moveCursor(n) { + this.cursor = n; + this.value = this.choices[n].value; + this.fire(); + } + + reset() { + this.moveCursor(0); + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + if (!this.selection.disabled) { + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } else this.bell(); + } + + first() { + this.moveCursor(0); + this.render(); + } + + last() { + this.moveCursor(this.choices.length - 1); + this.render(); + } + + up() { + if (this.cursor === 0) { + this.moveCursor(this.choices.length - 1); + } else { + this.moveCursor(this.cursor - 1); + } + + this.render(); + } + + down() { + if (this.cursor === this.choices.length - 1) { + this.moveCursor(0); + } else { + this.moveCursor(this.cursor + 1); + } + + this.render(); + } + + next() { + this.moveCursor((this.cursor + 1) % this.choices.length); + this.render(); + } + + _(c, key) { + if (c === ' ') return this.submit(); + } + + get selection() { + return this.choices[this.cursor]; + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); + + let _entriesToDisplay = entriesToDisplay(this.cursor, this.choices.length, this.optionsPerPage), + startIndex = _entriesToDisplay.startIndex, + endIndex = _entriesToDisplay.endIndex; // Print prompt + + + this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.done ? this.selection.title : this.selection.disabled ? color.yellow(this.warn) : color.gray(this.hint)].join(' '); // Print choices + + if (!this.done) { + this.outputText += '\n'; + + for (let i = startIndex; i < endIndex; i++) { + let title, + prefix, + desc = '', + v = this.choices[i]; // Determine whether to display "more choices" indicators + + if (i === startIndex && startIndex > 0) { + prefix = figures.arrowUp; + } else if (i === endIndex - 1 && endIndex < this.choices.length) { + prefix = figures.arrowDown; + } else { + prefix = ' '; + } + + if (v.disabled) { + title = this.cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title); + prefix = (this.cursor === i ? color.bold().gray(figures.pointer) + ' ' : ' ') + prefix; + } else { + title = this.cursor === i ? color.cyan().underline(v.title) : v.title; + prefix = (this.cursor === i ? color.cyan(figures.pointer) + ' ' : ' ') + prefix; + + if (v.description && this.cursor === i) { + desc = ` - ${v.description}`; + + if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) { + desc = '\n' + wrap(v.description, { + margin: 3, + width: this.out.columns + }); + } + } + } + + this.outputText += `${prefix} ${title}${color.gray(desc)}\n`; + } + } + + this.out.write(this.outputText); + } + + } + + select$1 = SelectPrompt; + return select$1; +} + +var toggle$1; +var hasRequiredToggle$1; + +function requireToggle$1 () { + if (hasRequiredToggle$1) return toggle$1; + hasRequiredToggle$1 = 1; + + const color = requireKleur(); + + const Prompt = requirePrompt$1(); + + const _require = requireUtil$1(), + style = _require.style, + clear = _require.clear; + + const _require2 = requireSrc(), + cursor = _require2.cursor, + erase = _require2.erase; + /** + * TogglePrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Boolean} [opts.initial=false] Default value + * @param {String} [opts.active='no'] Active label + * @param {String} [opts.inactive='off'] Inactive label + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + + + class TogglePrompt extends Prompt { + constructor(opts = {}) { + super(opts); + this.msg = opts.message; + this.value = !!opts.initial; + this.active = opts.active || 'on'; + this.inactive = opts.inactive || 'off'; + this.initialValue = this.value; + this.render(); + } + + reset() { + this.value = this.initialValue; + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + deactivate() { + if (this.value === false) return this.bell(); + this.value = false; + this.render(); + } + + activate() { + if (this.value === true) return this.bell(); + this.value = true; + this.render(); + } + + delete() { + this.deactivate(); + } + + left() { + this.deactivate(); + } + + right() { + this.activate(); + } + + down() { + this.deactivate(); + } + + up() { + this.activate(); + } + + next() { + this.value = !this.value; + this.fire(); + this.render(); + } + + _(c, key) { + if (c === ' ') { + this.value = !this.value; + } else if (c === '1') { + this.value = true; + } else if (c === '0') { + this.value = false; + } else return this.bell(); + + this.render(); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); + this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.value ? this.inactive : color.cyan().underline(this.inactive), color.gray('/'), this.value ? color.cyan().underline(this.active) : this.active].join(' '); + this.out.write(erase.line + cursor.to(0) + this.outputText); + } + + } + + toggle$1 = TogglePrompt; + return toggle$1; +} + +var datepart$1; +var hasRequiredDatepart$1; + +function requireDatepart$1 () { + if (hasRequiredDatepart$1) return datepart$1; + hasRequiredDatepart$1 = 1; + + class DatePart { + constructor({ + token, + date, + parts, + locales + }) { + this.token = token; + this.date = date || new Date(); + this.parts = parts || [this]; + this.locales = locales || {}; + } + + up() {} + + down() {} + + next() { + const currentIdx = this.parts.indexOf(this); + return this.parts.find((part, idx) => idx > currentIdx && part instanceof DatePart); + } + + setTo(val) {} + + prev() { + let parts = [].concat(this.parts).reverse(); + const currentIdx = parts.indexOf(this); + return parts.find((part, idx) => idx > currentIdx && part instanceof DatePart); + } + + toString() { + return String(this.date); + } + + } + + datepart$1 = DatePart; + return datepart$1; +} + +var meridiem$1; +var hasRequiredMeridiem$1; + +function requireMeridiem$1 () { + if (hasRequiredMeridiem$1) return meridiem$1; + hasRequiredMeridiem$1 = 1; + + const DatePart = requireDatepart$1(); + + class Meridiem extends DatePart { + constructor(opts = {}) { + super(opts); + } + + up() { + this.date.setHours((this.date.getHours() + 12) % 24); + } + + down() { + this.up(); + } + + toString() { + let meridiem = this.date.getHours() > 12 ? 'pm' : 'am'; + return /\A/.test(this.token) ? meridiem.toUpperCase() : meridiem; + } + + } + + meridiem$1 = Meridiem; + return meridiem$1; +} + +var day$1; +var hasRequiredDay$1; + +function requireDay$1 () { + if (hasRequiredDay$1) return day$1; + hasRequiredDay$1 = 1; + + const DatePart = requireDatepart$1(); + + const pos = n => { + n = n % 10; + return n === 1 ? 'st' : n === 2 ? 'nd' : n === 3 ? 'rd' : 'th'; + }; + + class Day extends DatePart { + constructor(opts = {}) { + super(opts); + } + + up() { + this.date.setDate(this.date.getDate() + 1); + } + + down() { + this.date.setDate(this.date.getDate() - 1); + } + + setTo(val) { + this.date.setDate(parseInt(val.substr(-2))); + } + + toString() { + let date = this.date.getDate(); + let day = this.date.getDay(); + return this.token === 'DD' ? String(date).padStart(2, '0') : this.token === 'Do' ? date + pos(date) : this.token === 'd' ? day + 1 : this.token === 'ddd' ? this.locales.weekdaysShort[day] : this.token === 'dddd' ? this.locales.weekdays[day] : date; + } + + } + + day$1 = Day; + return day$1; +} + +var hours$1; +var hasRequiredHours$1; + +function requireHours$1 () { + if (hasRequiredHours$1) return hours$1; + hasRequiredHours$1 = 1; + + const DatePart = requireDatepart$1(); + + class Hours extends DatePart { + constructor(opts = {}) { + super(opts); + } + + up() { + this.date.setHours(this.date.getHours() + 1); + } + + down() { + this.date.setHours(this.date.getHours() - 1); + } + + setTo(val) { + this.date.setHours(parseInt(val.substr(-2))); + } + + toString() { + let hours = this.date.getHours(); + if (/h/.test(this.token)) hours = hours % 12 || 12; + return this.token.length > 1 ? String(hours).padStart(2, '0') : hours; + } + + } + + hours$1 = Hours; + return hours$1; +} + +var milliseconds$1; +var hasRequiredMilliseconds$1; + +function requireMilliseconds$1 () { + if (hasRequiredMilliseconds$1) return milliseconds$1; + hasRequiredMilliseconds$1 = 1; + + const DatePart = requireDatepart$1(); + + class Milliseconds extends DatePart { + constructor(opts = {}) { + super(opts); + } + + up() { + this.date.setMilliseconds(this.date.getMilliseconds() + 1); + } + + down() { + this.date.setMilliseconds(this.date.getMilliseconds() - 1); + } + + setTo(val) { + this.date.setMilliseconds(parseInt(val.substr(-this.token.length))); + } + + toString() { + return String(this.date.getMilliseconds()).padStart(4, '0').substr(0, this.token.length); + } + + } + + milliseconds$1 = Milliseconds; + return milliseconds$1; +} + +var minutes$1; +var hasRequiredMinutes$1; + +function requireMinutes$1 () { + if (hasRequiredMinutes$1) return minutes$1; + hasRequiredMinutes$1 = 1; + + const DatePart = requireDatepart$1(); + + class Minutes extends DatePart { + constructor(opts = {}) { + super(opts); + } + + up() { + this.date.setMinutes(this.date.getMinutes() + 1); + } + + down() { + this.date.setMinutes(this.date.getMinutes() - 1); + } + + setTo(val) { + this.date.setMinutes(parseInt(val.substr(-2))); + } + + toString() { + let m = this.date.getMinutes(); + return this.token.length > 1 ? String(m).padStart(2, '0') : m; + } + + } + + minutes$1 = Minutes; + return minutes$1; +} + +var month$1; +var hasRequiredMonth$1; + +function requireMonth$1 () { + if (hasRequiredMonth$1) return month$1; + hasRequiredMonth$1 = 1; + + const DatePart = requireDatepart$1(); + + class Month extends DatePart { + constructor(opts = {}) { + super(opts); + } + + up() { + this.date.setMonth(this.date.getMonth() + 1); + } + + down() { + this.date.setMonth(this.date.getMonth() - 1); + } + + setTo(val) { + val = parseInt(val.substr(-2)) - 1; + this.date.setMonth(val < 0 ? 0 : val); + } + + toString() { + let month = this.date.getMonth(); + let tl = this.token.length; + return tl === 2 ? String(month + 1).padStart(2, '0') : tl === 3 ? this.locales.monthsShort[month] : tl === 4 ? this.locales.months[month] : String(month + 1); + } + + } + + month$1 = Month; + return month$1; +} + +var seconds$1; +var hasRequiredSeconds$1; + +function requireSeconds$1 () { + if (hasRequiredSeconds$1) return seconds$1; + hasRequiredSeconds$1 = 1; + + const DatePart = requireDatepart$1(); + + class Seconds extends DatePart { + constructor(opts = {}) { + super(opts); + } + + up() { + this.date.setSeconds(this.date.getSeconds() + 1); + } + + down() { + this.date.setSeconds(this.date.getSeconds() - 1); + } + + setTo(val) { + this.date.setSeconds(parseInt(val.substr(-2))); + } + + toString() { + let s = this.date.getSeconds(); + return this.token.length > 1 ? String(s).padStart(2, '0') : s; + } + + } + + seconds$1 = Seconds; + return seconds$1; +} + +var year$1; +var hasRequiredYear$1; + +function requireYear$1 () { + if (hasRequiredYear$1) return year$1; + hasRequiredYear$1 = 1; + + const DatePart = requireDatepart$1(); + + class Year extends DatePart { + constructor(opts = {}) { + super(opts); + } + + up() { + this.date.setFullYear(this.date.getFullYear() + 1); + } + + down() { + this.date.setFullYear(this.date.getFullYear() - 1); + } + + setTo(val) { + this.date.setFullYear(val.substr(-4)); + } + + toString() { + let year = String(this.date.getFullYear()).padStart(4, '0'); + return this.token.length === 2 ? year.substr(-2) : year; + } + + } + + year$1 = Year; + return year$1; +} + +var dateparts$1; +var hasRequiredDateparts$1; + +function requireDateparts$1 () { + if (hasRequiredDateparts$1) return dateparts$1; + hasRequiredDateparts$1 = 1; + + dateparts$1 = { + DatePart: requireDatepart$1(), + Meridiem: requireMeridiem$1(), + Day: requireDay$1(), + Hours: requireHours$1(), + Milliseconds: requireMilliseconds$1(), + Minutes: requireMinutes$1(), + Month: requireMonth$1(), + Seconds: requireSeconds$1(), + Year: requireYear$1() + }; + return dateparts$1; +} + +var date$1; +var hasRequiredDate$1; + +function requireDate$1 () { + if (hasRequiredDate$1) return date$1; + hasRequiredDate$1 = 1; + + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + + function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + + const color = requireKleur(); + + const Prompt = requirePrompt$1(); + + const _require = requireUtil$1(), + style = _require.style, + clear = _require.clear, + figures = _require.figures; + + const _require2 = requireSrc(), + erase = _require2.erase, + cursor = _require2.cursor; + + const _require3 = requireDateparts$1(), + DatePart = _require3.DatePart, + Meridiem = _require3.Meridiem, + Day = _require3.Day, + Hours = _require3.Hours, + Milliseconds = _require3.Milliseconds, + Minutes = _require3.Minutes, + Month = _require3.Month, + Seconds = _require3.Seconds, + Year = _require3.Year; + + const regex = /\\(.)|"((?:\\["\\]|[^"])+)"|(D[Do]?|d{3,4}|d)|(M{1,4})|(YY(?:YY)?)|([aA])|([Hh]{1,2})|(m{1,2})|(s{1,2})|(S{1,4})|./g; + const regexGroups = { + 1: ({ + token + }) => token.replace(/\\(.)/g, '$1'), + 2: opts => new Day(opts), + // Day // TODO + 3: opts => new Month(opts), + // Month + 4: opts => new Year(opts), + // Year + 5: opts => new Meridiem(opts), + // AM/PM // TODO (special) + 6: opts => new Hours(opts), + // Hours + 7: opts => new Minutes(opts), + // Minutes + 8: opts => new Seconds(opts), + // Seconds + 9: opts => new Milliseconds(opts) // Fractional seconds + + }; + const dfltLocales = { + months: 'January,February,March,April,May,June,July,August,September,October,November,December'.split(','), + monthsShort: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','), + weekdays: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(','), + weekdaysShort: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(',') + }; + /** + * DatePrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Number} [opts.initial] Index of default value + * @param {String} [opts.mask] The format mask + * @param {object} [opts.locales] The date locales + * @param {String} [opts.error] The error message shown on invalid value + * @param {Function} [opts.validate] Function to validate the submitted value + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + + class DatePrompt extends Prompt { + constructor(opts = {}) { + super(opts); + this.msg = opts.message; + this.cursor = 0; + this.typed = ''; + this.locales = Object.assign(dfltLocales, opts.locales); + this._date = opts.initial || new Date(); + this.errorMsg = opts.error || 'Please Enter A Valid Value'; + + this.validator = opts.validate || (() => true); + + this.mask = opts.mask || 'YYYY-MM-DD HH:mm:ss'; + this.clear = clear('', this.out.columns); + this.render(); + } + + get value() { + return this.date; + } + + get date() { + return this._date; + } + + set date(date) { + if (date) this._date.setTime(date.getTime()); + } + + set mask(mask) { + let result; + this.parts = []; + + while (result = regex.exec(mask)) { + let match = result.shift(); + let idx = result.findIndex(gr => gr != null); + this.parts.push(idx in regexGroups ? regexGroups[idx]({ + token: result[idx] || match, + date: this.date, + parts: this.parts, + locales: this.locales + }) : result[idx] || match); + } + + let parts = this.parts.reduce((arr, i) => { + if (typeof i === 'string' && typeof arr[arr.length - 1] === 'string') arr[arr.length - 1] += i;else arr.push(i); + return arr; + }, []); + this.parts.splice(0); + this.parts.push(...parts); + this.reset(); + } + + moveCursor(n) { + this.typed = ''; + this.cursor = n; + this.fire(); + } + + reset() { + this.moveCursor(this.parts.findIndex(p => p instanceof DatePart)); + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.error = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + validate() { + var _this = this; + + return _asyncToGenerator(function* () { + let valid = yield _this.validator(_this.value); + + if (typeof valid === 'string') { + _this.errorMsg = valid; + valid = false; + } + + _this.error = !valid; + })(); + } + + submit() { + var _this2 = this; + + return _asyncToGenerator(function* () { + yield _this2.validate(); + + if (_this2.error) { + _this2.color = 'red'; + + _this2.fire(); + + _this2.render(); + + return; + } + + _this2.done = true; + _this2.aborted = false; + + _this2.fire(); + + _this2.render(); + + _this2.out.write('\n'); + + _this2.close(); + })(); + } + + up() { + this.typed = ''; + this.parts[this.cursor].up(); + this.render(); + } + + down() { + this.typed = ''; + this.parts[this.cursor].down(); + this.render(); + } + + left() { + let prev = this.parts[this.cursor].prev(); + if (prev == null) return this.bell(); + this.moveCursor(this.parts.indexOf(prev)); + this.render(); + } + + right() { + let next = this.parts[this.cursor].next(); + if (next == null) return this.bell(); + this.moveCursor(this.parts.indexOf(next)); + this.render(); + } + + next() { + let next = this.parts[this.cursor].next(); + this.moveCursor(next ? this.parts.indexOf(next) : this.parts.findIndex(part => part instanceof DatePart)); + this.render(); + } + + _(c) { + if (/\d/.test(c)) { + this.typed += c; + this.parts[this.cursor].setTo(this.typed); + this.render(); + } + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); // Print prompt + + this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.parts.reduce((arr, p, idx) => arr.concat(idx === this.cursor && !this.done ? color.cyan().underline(p.toString()) : p), []).join('')].join(' '); // Print error + + if (this.error) { + this.outputText += this.errorMsg.split('\n').reduce((a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``); + } + + this.out.write(erase.line + cursor.to(0) + this.outputText); + } + + } + + date$1 = DatePrompt; + return date$1; +} + +var number$1; +var hasRequiredNumber$1; + +function requireNumber$1 () { + if (hasRequiredNumber$1) return number$1; + hasRequiredNumber$1 = 1; + + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + + function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + + const color = requireKleur(); + + const Prompt = requirePrompt$1(); + + const _require = requireSrc(), + cursor = _require.cursor, + erase = _require.erase; + + const _require2 = requireUtil$1(), + style = _require2.style, + figures = _require2.figures, + clear = _require2.clear, + lines = _require2.lines; + + const isNumber = /[0-9]/; + + const isDef = any => any !== undefined; + + const round = (number, precision) => { + let factor = Math.pow(10, precision); + return Math.round(number * factor) / factor; + }; + /** + * NumberPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {String} [opts.style='default'] Render style + * @param {Number} [opts.initial] Default value + * @param {Number} [opts.max=+Infinity] Max value + * @param {Number} [opts.min=-Infinity] Min value + * @param {Boolean} [opts.float=false] Parse input as floats + * @param {Number} [opts.round=2] Round floats to x decimals + * @param {Number} [opts.increment=1] Number to increment by when using arrow-keys + * @param {Function} [opts.validate] Validate function + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {String} [opts.error] The invalid error label + */ + + + class NumberPrompt extends Prompt { + constructor(opts = {}) { + super(opts); + this.transform = style.render(opts.style); + this.msg = opts.message; + this.initial = isDef(opts.initial) ? opts.initial : ''; + this.float = !!opts.float; + this.round = opts.round || 2; + this.inc = opts.increment || 1; + this.min = isDef(opts.min) ? opts.min : -Infinity; + this.max = isDef(opts.max) ? opts.max : Infinity; + this.errorMsg = opts.error || `Please Enter A Valid Value`; + + this.validator = opts.validate || (() => true); + + this.color = `cyan`; + this.value = ``; + this.typed = ``; + this.lastHit = 0; + this.render(); + } + + set value(v) { + if (!v && v !== 0) { + this.placeholder = true; + this.rendered = color.gray(this.transform.render(`${this.initial}`)); + this._value = ``; + } else { + this.placeholder = false; + this.rendered = this.transform.render(`${round(v, this.round)}`); + this._value = round(v, this.round); + } + + this.fire(); + } + + get value() { + return this._value; + } + + parse(x) { + return this.float ? parseFloat(x) : parseInt(x); + } + + valid(c) { + return c === `-` || c === `.` && this.float || isNumber.test(c); + } + + reset() { + this.typed = ``; + this.value = ``; + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + let x = this.value; + this.value = x !== `` ? x : this.initial; + this.done = this.aborted = true; + this.error = false; + this.fire(); + this.render(); + this.out.write(`\n`); + this.close(); + } + + validate() { + var _this = this; + + return _asyncToGenerator(function* () { + let valid = yield _this.validator(_this.value); + + if (typeof valid === `string`) { + _this.errorMsg = valid; + valid = false; + } + + _this.error = !valid; + })(); + } + + submit() { + var _this2 = this; + + return _asyncToGenerator(function* () { + yield _this2.validate(); + + if (_this2.error) { + _this2.color = `red`; + + _this2.fire(); + + _this2.render(); + + return; + } + + let x = _this2.value; + _this2.value = x !== `` ? x : _this2.initial; + _this2.done = true; + _this2.aborted = false; + _this2.error = false; + + _this2.fire(); + + _this2.render(); + + _this2.out.write(`\n`); + + _this2.close(); + })(); + } + + up() { + this.typed = ``; + + if (this.value === '') { + this.value = this.min - this.inc; + } + + if (this.value >= this.max) return this.bell(); + this.value += this.inc; + this.color = `cyan`; + this.fire(); + this.render(); + } + + down() { + this.typed = ``; + + if (this.value === '') { + this.value = this.min + this.inc; + } + + if (this.value <= this.min) return this.bell(); + this.value -= this.inc; + this.color = `cyan`; + this.fire(); + this.render(); + } + + delete() { + let val = this.value.toString(); + if (val.length === 0) return this.bell(); + this.value = this.parse(val = val.slice(0, -1)) || ``; + + if (this.value !== '' && this.value < this.min) { + this.value = this.min; + } + + this.color = `cyan`; + this.fire(); + this.render(); + } + + next() { + this.value = this.initial; + this.fire(); + this.render(); + } + + _(c, key) { + if (!this.valid(c)) return this.bell(); + const now = Date.now(); + if (now - this.lastHit > 1000) this.typed = ``; // 1s elapsed + + this.typed += c; + this.lastHit = now; + this.color = `cyan`; + if (c === `.`) return this.fire(); + this.value = Math.min(this.parse(this.typed), this.max); + if (this.value > this.max) this.value = this.max; + if (this.value < this.min) this.value = this.min; + this.fire(); + this.render(); + } + + render() { + if (this.closed) return; + + if (!this.firstRender) { + if (this.outputError) this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns)); + this.out.write(clear(this.outputText, this.out.columns)); + } + + super.render(); + this.outputError = ''; // Print prompt + + this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), !this.done || !this.done && !this.placeholder ? color[this.color]().underline(this.rendered) : this.rendered].join(` `); // Print error + + if (this.error) { + this.outputError += this.errorMsg.split(`\n`).reduce((a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``); + } + + this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore); + } + + } + + number$1 = NumberPrompt; + return number$1; +} + +var multiselect$1; +var hasRequiredMultiselect$1; + +function requireMultiselect$1 () { + if (hasRequiredMultiselect$1) return multiselect$1; + hasRequiredMultiselect$1 = 1; + + const color = requireKleur(); + + const _require = requireSrc(), + cursor = _require.cursor; + + const Prompt = requirePrompt$1(); + + const _require2 = requireUtil$1(), + clear = _require2.clear, + figures = _require2.figures, + style = _require2.style, + wrap = _require2.wrap, + entriesToDisplay = _require2.entriesToDisplay; + /** + * MultiselectPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Array} opts.choices Array of choice objects + * @param {String} [opts.hint] Hint to display + * @param {String} [opts.warn] Hint shown for disabled choices + * @param {Number} [opts.max] Max choices + * @param {Number} [opts.cursor=0] Cursor start position + * @param {Number} [opts.optionsPerPage=10] Max options to display at once + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + + + class MultiselectPrompt extends Prompt { + constructor(opts = {}) { + super(opts); + this.msg = opts.message; + this.cursor = opts.cursor || 0; + this.scrollIndex = opts.cursor || 0; + this.hint = opts.hint || ''; + this.warn = opts.warn || '- This option is disabled -'; + this.minSelected = opts.min; + this.showMinError = false; + this.maxChoices = opts.max; + this.instructions = opts.instructions; + this.optionsPerPage = opts.optionsPerPage || 10; + this.value = opts.choices.map((ch, idx) => { + if (typeof ch === 'string') ch = { + title: ch, + value: idx + }; + return { + title: ch && (ch.title || ch.value || ch), + description: ch && ch.description, + value: ch && (ch.value === undefined ? idx : ch.value), + selected: ch && ch.selected, + disabled: ch && ch.disabled + }; + }); + this.clear = clear('', this.out.columns); + + if (!opts.overrideRender) { + this.render(); + } + } + + reset() { + this.value.map(v => !v.selected); + this.cursor = 0; + this.fire(); + this.render(); + } + + selected() { + return this.value.filter(v => v.selected); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + const selected = this.value.filter(e => e.selected); + + if (this.minSelected && selected.length < this.minSelected) { + this.showMinError = true; + this.render(); + } else { + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + } + + first() { + this.cursor = 0; + this.render(); + } + + last() { + this.cursor = this.value.length - 1; + this.render(); + } + + next() { + this.cursor = (this.cursor + 1) % this.value.length; + this.render(); + } + + up() { + if (this.cursor === 0) { + this.cursor = this.value.length - 1; + } else { + this.cursor--; + } + + this.render(); + } + + down() { + if (this.cursor === this.value.length - 1) { + this.cursor = 0; + } else { + this.cursor++; + } + + this.render(); + } + + left() { + this.value[this.cursor].selected = false; + this.render(); + } + + right() { + if (this.value.filter(e => e.selected).length >= this.maxChoices) return this.bell(); + this.value[this.cursor].selected = true; + this.render(); + } + + handleSpaceToggle() { + const v = this.value[this.cursor]; + + if (v.selected) { + v.selected = false; + this.render(); + } else if (v.disabled || this.value.filter(e => e.selected).length >= this.maxChoices) { + return this.bell(); + } else { + v.selected = true; + this.render(); + } + } + + toggleAll() { + if (this.maxChoices !== undefined || this.value[this.cursor].disabled) { + return this.bell(); + } + + const newSelected = !this.value[this.cursor].selected; + this.value.filter(v => !v.disabled).forEach(v => v.selected = newSelected); + this.render(); + } + + _(c, key) { + if (c === ' ') { + this.handleSpaceToggle(); + } else if (c === 'a') { + this.toggleAll(); + } else { + return this.bell(); + } + } + + renderInstructions() { + if (this.instructions === undefined || this.instructions) { + if (typeof this.instructions === 'string') { + return this.instructions; + } + + return '\nInstructions:\n' + ` ${figures.arrowUp}/${figures.arrowDown}: Highlight option\n` + ` ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection\n` + (this.maxChoices === undefined ? ` a: Toggle all\n` : '') + ` enter/return: Complete answer`; + } + + return ''; + } + + renderOption(cursor, v, i, arrowIndicator) { + const prefix = (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + arrowIndicator + ' '; + let title, desc; + + if (v.disabled) { + title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title); + } else { + title = cursor === i ? color.cyan().underline(v.title) : v.title; + + if (cursor === i && v.description) { + desc = ` - ${v.description}`; + + if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) { + desc = '\n' + wrap(v.description, { + margin: prefix.length, + width: this.out.columns + }); + } + } + } + + return prefix + title + color.gray(desc || ''); + } // shared with autocompleteMultiselect + + + paginateOptions(options) { + if (options.length === 0) { + return color.red('No matches for this query.'); + } + + let _entriesToDisplay = entriesToDisplay(this.cursor, options.length, this.optionsPerPage), + startIndex = _entriesToDisplay.startIndex, + endIndex = _entriesToDisplay.endIndex; + + let prefix, + styledOptions = []; + + for (let i = startIndex; i < endIndex; i++) { + if (i === startIndex && startIndex > 0) { + prefix = figures.arrowUp; + } else if (i === endIndex - 1 && endIndex < options.length) { + prefix = figures.arrowDown; + } else { + prefix = ' '; + } + + styledOptions.push(this.renderOption(this.cursor, options[i], i, prefix)); + } + + return '\n' + styledOptions.join('\n'); + } // shared with autocomleteMultiselect + + + renderOptions(options) { + if (!this.done) { + return this.paginateOptions(options); + } + + return ''; + } + + renderDoneOrInstructions() { + if (this.done) { + return this.value.filter(e => e.selected).map(v => v.title).join(', '); + } + + const output = [color.gray(this.hint), this.renderInstructions()]; + + if (this.value[this.cursor].disabled) { + output.push(color.yellow(this.warn)); + } + + return output.join(' '); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + super.render(); // print prompt + + let prompt = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.renderDoneOrInstructions()].join(' '); + + if (this.showMinError) { + prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`); + this.showMinError = false; + } + + prompt += this.renderOptions(this.value); + this.out.write(this.clear + prompt); + this.clear = clear(prompt, this.out.columns); + } + + } + + multiselect$1 = MultiselectPrompt; + return multiselect$1; +} + +var autocomplete$1; +var hasRequiredAutocomplete$1; + +function requireAutocomplete$1 () { + if (hasRequiredAutocomplete$1) return autocomplete$1; + hasRequiredAutocomplete$1 = 1; + + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + + function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + + const color = requireKleur(); + + const Prompt = requirePrompt$1(); + + const _require = requireSrc(), + erase = _require.erase, + cursor = _require.cursor; + + const _require2 = requireUtil$1(), + style = _require2.style, + clear = _require2.clear, + figures = _require2.figures, + wrap = _require2.wrap, + entriesToDisplay = _require2.entriesToDisplay; + + const getVal = (arr, i) => arr[i] && (arr[i].value || arr[i].title || arr[i]); + + const getTitle = (arr, i) => arr[i] && (arr[i].title || arr[i].value || arr[i]); + + const getIndex = (arr, valOrTitle) => { + const index = arr.findIndex(el => el.value === valOrTitle || el.title === valOrTitle); + return index > -1 ? index : undefined; + }; + /** + * TextPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Array} opts.choices Array of auto-complete choices objects + * @param {Function} [opts.suggest] Filter function. Defaults to sort by title + * @param {Number} [opts.limit=10] Max number of results to show + * @param {Number} [opts.cursor=0] Cursor start position + * @param {String} [opts.style='default'] Render style + * @param {String} [opts.fallback] Fallback message - initial to default value + * @param {String} [opts.initial] Index of the default value + * @param {Boolean} [opts.clearFirst] The first ESCAPE keypress will clear the input + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {String} [opts.noMatches] The no matches found label + */ + + + class AutocompletePrompt extends Prompt { + constructor(opts = {}) { + super(opts); + this.msg = opts.message; + this.suggest = opts.suggest; + this.choices = opts.choices; + this.initial = typeof opts.initial === 'number' ? opts.initial : getIndex(opts.choices, opts.initial); + this.select = this.initial || opts.cursor || 0; + this.i18n = { + noMatches: opts.noMatches || 'no matches found' + }; + this.fallback = opts.fallback || this.initial; + this.clearFirst = opts.clearFirst || false; + this.suggestions = []; + this.input = ''; + this.limit = opts.limit || 10; + this.cursor = 0; + this.transform = style.render(opts.style); + this.scale = this.transform.scale; + this.render = this.render.bind(this); + this.complete = this.complete.bind(this); + this.clear = clear('', this.out.columns); + this.complete(this.render); + this.render(); + } + + set fallback(fb) { + this._fb = Number.isSafeInteger(parseInt(fb)) ? parseInt(fb) : fb; + } + + get fallback() { + let choice; + if (typeof this._fb === 'number') choice = this.choices[this._fb];else if (typeof this._fb === 'string') choice = { + title: this._fb + }; + return choice || this._fb || { + title: this.i18n.noMatches + }; + } + + moveSelect(i) { + this.select = i; + if (this.suggestions.length > 0) this.value = getVal(this.suggestions, i);else this.value = this.fallback.value; + this.fire(); + } + + complete(cb) { + var _this = this; + + return _asyncToGenerator(function* () { + const p = _this.completing = _this.suggest(_this.input, _this.choices); + + const suggestions = yield p; + if (_this.completing !== p) return; + _this.suggestions = suggestions.map((s, i, arr) => ({ + title: getTitle(arr, i), + value: getVal(arr, i), + description: s.description + })); + _this.completing = false; + const l = Math.max(suggestions.length - 1, 0); + + _this.moveSelect(Math.min(l, _this.select)); + + cb && cb(); + })(); + } + + reset() { + this.input = ''; + this.complete(() => { + this.moveSelect(this.initial !== void 0 ? this.initial : 0); + this.render(); + }); + this.render(); + } + + exit() { + if (this.clearFirst && this.input.length > 0) { + this.reset(); + } else { + this.done = this.exited = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + } + + abort() { + this.done = this.aborted = true; + this.exited = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + this.done = true; + this.aborted = this.exited = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + _(c, key) { + let s1 = this.input.slice(0, this.cursor); + let s2 = this.input.slice(this.cursor); + this.input = `${s1}${c}${s2}`; + this.cursor = s1.length + 1; + this.complete(this.render); + this.render(); + } + + delete() { + if (this.cursor === 0) return this.bell(); + let s1 = this.input.slice(0, this.cursor - 1); + let s2 = this.input.slice(this.cursor); + this.input = `${s1}${s2}`; + this.complete(this.render); + this.cursor = this.cursor - 1; + this.render(); + } + + deleteForward() { + if (this.cursor * this.scale >= this.rendered.length) return this.bell(); + let s1 = this.input.slice(0, this.cursor); + let s2 = this.input.slice(this.cursor + 1); + this.input = `${s1}${s2}`; + this.complete(this.render); + this.render(); + } + + first() { + this.moveSelect(0); + this.render(); + } + + last() { + this.moveSelect(this.suggestions.length - 1); + this.render(); + } + + up() { + if (this.select === 0) { + this.moveSelect(this.suggestions.length - 1); + } else { + this.moveSelect(this.select - 1); + } + + this.render(); + } + + down() { + if (this.select === this.suggestions.length - 1) { + this.moveSelect(0); + } else { + this.moveSelect(this.select + 1); + } + + this.render(); + } + + next() { + if (this.select === this.suggestions.length - 1) { + this.moveSelect(0); + } else this.moveSelect(this.select + 1); + + this.render(); + } + + nextPage() { + this.moveSelect(Math.min(this.select + this.limit, this.suggestions.length - 1)); + this.render(); + } + + prevPage() { + this.moveSelect(Math.max(this.select - this.limit, 0)); + this.render(); + } + + left() { + if (this.cursor <= 0) return this.bell(); + this.cursor = this.cursor - 1; + this.render(); + } + + right() { + if (this.cursor * this.scale >= this.rendered.length) return this.bell(); + this.cursor = this.cursor + 1; + this.render(); + } + + renderOption(v, hovered, isStart, isEnd) { + let desc; + let prefix = isStart ? figures.arrowUp : isEnd ? figures.arrowDown : ' '; + let title = hovered ? color.cyan().underline(v.title) : v.title; + prefix = (hovered ? color.cyan(figures.pointer) + ' ' : ' ') + prefix; + + if (v.description) { + desc = ` - ${v.description}`; + + if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) { + desc = '\n' + wrap(v.description, { + margin: 3, + width: this.out.columns + }); + } + } + + return prefix + ' ' + title + color.gray(desc || ''); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); + + let _entriesToDisplay = entriesToDisplay(this.select, this.choices.length, this.limit), + startIndex = _entriesToDisplay.startIndex, + endIndex = _entriesToDisplay.endIndex; + + this.outputText = [style.symbol(this.done, this.aborted, this.exited), color.bold(this.msg), style.delimiter(this.completing), this.done && this.suggestions[this.select] ? this.suggestions[this.select].title : this.rendered = this.transform.render(this.input)].join(' '); + + if (!this.done) { + const suggestions = this.suggestions.slice(startIndex, endIndex).map((item, i) => this.renderOption(item, this.select === i + startIndex, i === 0 && startIndex > 0, i + startIndex === endIndex - 1 && endIndex < this.choices.length)).join('\n'); + this.outputText += `\n` + (suggestions || color.gray(this.fallback.title)); + } + + this.out.write(erase.line + cursor.to(0) + this.outputText); + } + + } + + autocomplete$1 = AutocompletePrompt; + return autocomplete$1; +} + +var autocompleteMultiselect$1; +var hasRequiredAutocompleteMultiselect$1; + +function requireAutocompleteMultiselect$1 () { + if (hasRequiredAutocompleteMultiselect$1) return autocompleteMultiselect$1; + hasRequiredAutocompleteMultiselect$1 = 1; + + const color = requireKleur(); + + const _require = requireSrc(), + cursor = _require.cursor; + + const MultiselectPrompt = requireMultiselect$1(); + + const _require2 = requireUtil$1(), + clear = _require2.clear, + style = _require2.style, + figures = _require2.figures; + /** + * MultiselectPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Array} opts.choices Array of choice objects + * @param {String} [opts.hint] Hint to display + * @param {String} [opts.warn] Hint shown for disabled choices + * @param {Number} [opts.max] Max choices + * @param {Number} [opts.cursor=0] Cursor start position + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + + + class AutocompleteMultiselectPrompt extends MultiselectPrompt { + constructor(opts = {}) { + opts.overrideRender = true; + super(opts); + this.inputValue = ''; + this.clear = clear('', this.out.columns); + this.filteredOptions = this.value; + this.render(); + } + + last() { + this.cursor = this.filteredOptions.length - 1; + this.render(); + } + + next() { + this.cursor = (this.cursor + 1) % this.filteredOptions.length; + this.render(); + } + + up() { + if (this.cursor === 0) { + this.cursor = this.filteredOptions.length - 1; + } else { + this.cursor--; + } + + this.render(); + } + + down() { + if (this.cursor === this.filteredOptions.length - 1) { + this.cursor = 0; + } else { + this.cursor++; + } + + this.render(); + } + + left() { + this.filteredOptions[this.cursor].selected = false; + this.render(); + } + + right() { + if (this.value.filter(e => e.selected).length >= this.maxChoices) return this.bell(); + this.filteredOptions[this.cursor].selected = true; + this.render(); + } + + delete() { + if (this.inputValue.length) { + this.inputValue = this.inputValue.substr(0, this.inputValue.length - 1); + this.updateFilteredOptions(); + } + } + + updateFilteredOptions() { + const currentHighlight = this.filteredOptions[this.cursor]; + this.filteredOptions = this.value.filter(v => { + if (this.inputValue) { + if (typeof v.title === 'string') { + if (v.title.toLowerCase().includes(this.inputValue.toLowerCase())) { + return true; + } + } + + if (typeof v.value === 'string') { + if (v.value.toLowerCase().includes(this.inputValue.toLowerCase())) { + return true; + } + } + + return false; + } + + return true; + }); + const newHighlightIndex = this.filteredOptions.findIndex(v => v === currentHighlight); + this.cursor = newHighlightIndex < 0 ? 0 : newHighlightIndex; + this.render(); + } + + handleSpaceToggle() { + const v = this.filteredOptions[this.cursor]; + + if (v.selected) { + v.selected = false; + this.render(); + } else if (v.disabled || this.value.filter(e => e.selected).length >= this.maxChoices) { + return this.bell(); + } else { + v.selected = true; + this.render(); + } + } + + handleInputChange(c) { + this.inputValue = this.inputValue + c; + this.updateFilteredOptions(); + } + + _(c, key) { + if (c === ' ') { + this.handleSpaceToggle(); + } else { + this.handleInputChange(c); + } + } + + renderInstructions() { + if (this.instructions === undefined || this.instructions) { + if (typeof this.instructions === 'string') { + return this.instructions; + } + + return ` +Instructions: + ${figures.arrowUp}/${figures.arrowDown}: Highlight option + ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection + [a,b,c]/delete: Filter choices + enter/return: Complete answer +`; + } + + return ''; + } + + renderCurrentInput() { + return ` +Filtered results for: ${this.inputValue ? this.inputValue : color.gray('Enter something to filter')}\n`; + } + + renderOption(cursor, v, i) { + let title; + if (v.disabled) title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);else title = cursor === i ? color.cyan().underline(v.title) : v.title; + return (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + title; + } + + renderDoneOrInstructions() { + if (this.done) { + return this.value.filter(e => e.selected).map(v => v.title).join(', '); + } + + const output = [color.gray(this.hint), this.renderInstructions(), this.renderCurrentInput()]; + + if (this.filteredOptions.length && this.filteredOptions[this.cursor].disabled) { + output.push(color.yellow(this.warn)); + } + + return output.join(' '); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + super.render(); // print prompt + + let prompt = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.renderDoneOrInstructions()].join(' '); + + if (this.showMinError) { + prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`); + this.showMinError = false; + } + + prompt += this.renderOptions(this.filteredOptions); + this.out.write(this.clear + prompt); + this.clear = clear(prompt, this.out.columns); + } + + } + + autocompleteMultiselect$1 = AutocompleteMultiselectPrompt; + return autocompleteMultiselect$1; +} + +var confirm$1; +var hasRequiredConfirm$1; + +function requireConfirm$1 () { + if (hasRequiredConfirm$1) return confirm$1; + hasRequiredConfirm$1 = 1; + + const color = requireKleur(); + + const Prompt = requirePrompt$1(); + + const _require = requireUtil$1(), + style = _require.style, + clear = _require.clear; + + const _require2 = requireSrc(), + erase = _require2.erase, + cursor = _require2.cursor; + /** + * ConfirmPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Boolean} [opts.initial] Default value (true/false) + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {String} [opts.yes] The "Yes" label + * @param {String} [opts.yesOption] The "Yes" option when choosing between yes/no + * @param {String} [opts.no] The "No" label + * @param {String} [opts.noOption] The "No" option when choosing between yes/no + */ + + + class ConfirmPrompt extends Prompt { + constructor(opts = {}) { + super(opts); + this.msg = opts.message; + this.value = opts.initial; + this.initialValue = !!opts.initial; + this.yesMsg = opts.yes || 'yes'; + this.yesOption = opts.yesOption || '(Y/n)'; + this.noMsg = opts.no || 'no'; + this.noOption = opts.noOption || '(y/N)'; + this.render(); + } + + reset() { + this.value = this.initialValue; + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + this.value = this.value || false; + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + _(c, key) { + if (c.toLowerCase() === 'y') { + this.value = true; + return this.submit(); + } + + if (c.toLowerCase() === 'n') { + this.value = false; + return this.submit(); + } + + return this.bell(); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); + this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.done ? this.value ? this.yesMsg : this.noMsg : color.gray(this.initialValue ? this.yesOption : this.noOption)].join(' '); + this.out.write(erase.line + cursor.to(0) + this.outputText); + } + + } + + confirm$1 = ConfirmPrompt; + return confirm$1; +} + +var elements$1; +var hasRequiredElements$1; + +function requireElements$1 () { + if (hasRequiredElements$1) return elements$1; + hasRequiredElements$1 = 1; + + elements$1 = { + TextPrompt: requireText$1(), + SelectPrompt: requireSelect$1(), + TogglePrompt: requireToggle$1(), + DatePrompt: requireDate$1(), + NumberPrompt: requireNumber$1(), + MultiselectPrompt: requireMultiselect$1(), + AutocompletePrompt: requireAutocomplete$1(), + AutocompleteMultiselectPrompt: requireAutocompleteMultiselect$1(), + ConfirmPrompt: requireConfirm$1() + }; + return elements$1; +} + +var hasRequiredPrompts$2; + +function requirePrompts$2 () { + if (hasRequiredPrompts$2) return prompts$2; + hasRequiredPrompts$2 = 1; + (function (exports) { + + const $ = exports; + + const el = requireElements$1(); + + const noop = v => v; + + function toPrompt(type, args, opts = {}) { + return new Promise((res, rej) => { + const p = new el[type](args); + const onAbort = opts.onAbort || noop; + const onSubmit = opts.onSubmit || noop; + const onExit = opts.onExit || noop; + p.on('state', args.onState || noop); + p.on('submit', x => res(onSubmit(x))); + p.on('exit', x => res(onExit(x))); + p.on('abort', x => rej(onAbort(x))); + }); + } + /** + * Text prompt + * @param {string} args.message Prompt message to display + * @param {string} [args.initial] Default string value + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {function} [args.onState] On state change callback + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.text = args => toPrompt('TextPrompt', args); + /** + * Password prompt with masked input + * @param {string} args.message Prompt message to display + * @param {string} [args.initial] Default string value + * @param {function} [args.onState] On state change callback + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.password = args => { + args.style = 'password'; + return $.text(args); + }; + /** + * Prompt where input is invisible, like sudo + * @param {string} args.message Prompt message to display + * @param {string} [args.initial] Default string value + * @param {function} [args.onState] On state change callback + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.invisible = args => { + args.style = 'invisible'; + return $.text(args); + }; + /** + * Number prompt + * @param {string} args.message Prompt message to display + * @param {number} args.initial Default number value + * @param {function} [args.onState] On state change callback + * @param {number} [args.max] Max value + * @param {number} [args.min] Min value + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {Boolean} [opts.float=false] Parse input as floats + * @param {Number} [opts.round=2] Round floats to x decimals + * @param {Number} [opts.increment=1] Number to increment by when using arrow-keys + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.number = args => toPrompt('NumberPrompt', args); + /** + * Date prompt + * @param {string} args.message Prompt message to display + * @param {number} args.initial Default number value + * @param {function} [args.onState] On state change callback + * @param {number} [args.max] Max value + * @param {number} [args.min] Min value + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {Boolean} [opts.float=false] Parse input as floats + * @param {Number} [opts.round=2] Round floats to x decimals + * @param {Number} [opts.increment=1] Number to increment by when using arrow-keys + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.date = args => toPrompt('DatePrompt', args); + /** + * Classic yes/no prompt + * @param {string} args.message Prompt message to display + * @param {boolean} [args.initial=false] Default value + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.confirm = args => toPrompt('ConfirmPrompt', args); + /** + * List prompt, split intput string by `seperator` + * @param {string} args.message Prompt message to display + * @param {string} [args.initial] Default string value + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {string} [args.separator] String separator + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input, in form of an `Array` + */ + + + $.list = args => { + const sep = args.separator || ','; + return toPrompt('TextPrompt', args, { + onSubmit: str => str.split(sep).map(s => s.trim()) + }); + }; + /** + * Toggle/switch prompt + * @param {string} args.message Prompt message to display + * @param {boolean} [args.initial=false] Default value + * @param {string} [args.active="on"] Text for `active` state + * @param {string} [args.inactive="off"] Text for `inactive` state + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.toggle = args => toPrompt('TogglePrompt', args); + /** + * Interactive select prompt + * @param {string} args.message Prompt message to display + * @param {Array} args.choices Array of choices objects `[{ title, value }, ...]` + * @param {number} [args.initial] Index of default value + * @param {String} [args.hint] Hint to display + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.select = args => toPrompt('SelectPrompt', args); + /** + * Interactive multi-select / autocompleteMultiselect prompt + * @param {string} args.message Prompt message to display + * @param {Array} args.choices Array of choices objects `[{ title, value, [selected] }, ...]` + * @param {number} [args.max] Max select + * @param {string} [args.hint] Hint to display user + * @param {Number} [args.cursor=0] Cursor start position + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.multiselect = args => { + args.choices = [].concat(args.choices || []); + + const toSelected = items => items.filter(item => item.selected).map(item => item.value); + + return toPrompt('MultiselectPrompt', args, { + onAbort: toSelected, + onSubmit: toSelected + }); + }; + + $.autocompleteMultiselect = args => { + args.choices = [].concat(args.choices || []); + + const toSelected = items => items.filter(item => item.selected).map(item => item.value); + + return toPrompt('AutocompleteMultiselectPrompt', args, { + onAbort: toSelected, + onSubmit: toSelected + }); + }; + + const byTitle = (input, choices) => Promise.resolve(choices.filter(item => item.title.slice(0, input.length).toLowerCase() === input.toLowerCase())); + /** + * Interactive auto-complete prompt + * @param {string} args.message Prompt message to display + * @param {Array} args.choices Array of auto-complete choices objects `[{ title, value }, ...]` + * @param {Function} [args.suggest] Function to filter results based on user input. Defaults to sort by `title` + * @param {number} [args.limit=10] Max number of results to show + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {String} [args.initial] Index of the default value + * @param {boolean} [opts.clearFirst] The first ESCAPE keypress will clear the input + * @param {String} [args.fallback] Fallback message - defaults to initial value + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + + + $.autocomplete = args => { + args.suggest = args.suggest || byTitle; + args.choices = [].concat(args.choices || []); + return toPrompt('AutocompletePrompt', args); + }; + } (prompts$2)); + return prompts$2; +} + +var dist; +var hasRequiredDist; + +function requireDist () { + if (hasRequiredDist) return dist; + hasRequiredDist = 1; + + function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike) { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + + function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } + + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + + function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + + const prompts = requirePrompts$2(); + + const passOn = ['suggest', 'format', 'onState', 'validate', 'onRender', 'type']; + + const noop = () => {}; + /** + * Prompt for a series of questions + * @param {Array|Object} questions Single question object or Array of question objects + * @param {Function} [onSubmit] Callback function called on prompt submit + * @param {Function} [onCancel] Callback function called on cancel/abort + * @returns {Object} Object with values from user input + */ + + + function prompt() { + return _prompt.apply(this, arguments); + } + + function _prompt() { + _prompt = _asyncToGenerator(function* (questions = [], { + onSubmit = noop, + onCancel = noop + } = {}) { + const answers = {}; + const override = prompt._override || {}; + questions = [].concat(questions); + let answer, question, quit, name, type, lastPrompt; + + const getFormattedAnswer = /*#__PURE__*/function () { + var _ref = _asyncToGenerator(function* (question, answer, skipValidation = false) { + if (!skipValidation && question.validate && question.validate(answer) !== true) { + return; + } + + return question.format ? yield question.format(answer, answers) : answer; + }); + + return function getFormattedAnswer(_x, _x2) { + return _ref.apply(this, arguments); + }; + }(); + + var _iterator = _createForOfIteratorHelper(questions), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + question = _step.value; + var _question = question; + name = _question.name; + type = _question.type; + + // evaluate type first and skip if type is a falsy value + if (typeof type === 'function') { + type = yield type(answer, _objectSpread({}, answers), question); + question['type'] = type; + } + + if (!type) continue; // if property is a function, invoke it unless it's a special function + + for (let key in question) { + if (passOn.includes(key)) continue; + let value = question[key]; + question[key] = typeof value === 'function' ? yield value(answer, _objectSpread({}, answers), lastPrompt) : value; + } + + lastPrompt = question; + + if (typeof question.message !== 'string') { + throw new Error('prompt message is required'); + } // update vars in case they changed + + + var _question2 = question; + name = _question2.name; + type = _question2.type; + + if (prompts[type] === void 0) { + throw new Error(`prompt type (${type}) is not defined`); + } + + if (override[question.name] !== undefined) { + answer = yield getFormattedAnswer(question, override[question.name]); + + if (answer !== undefined) { + answers[name] = answer; + continue; + } + } + + try { + // Get the injected answer if there is one or prompt the user + answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : yield prompts[type](question); + answers[name] = answer = yield getFormattedAnswer(question, answer, true); + quit = yield onSubmit(question, answer, answers); + } catch (err) { + quit = !(yield onCancel(question, answers)); + } + + if (quit) return answers; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return answers; + }); + return _prompt.apply(this, arguments); + } + + function getInjectedAnswer(injected, deafultValue) { + const answer = injected.shift(); + + if (answer instanceof Error) { + throw answer; + } + + return answer === undefined ? deafultValue : answer; + } + + function inject(answers) { + prompt._injected = (prompt._injected || []).concat(answers); + } + + function override(answers) { + prompt._override = Object.assign({}, answers); + } + + dist = Object.assign(prompt, { + prompt, + prompts, + inject, + override + }); + return dist; +} + +var prompts$1 = {}; + +var action; +var hasRequiredAction; + +function requireAction () { + if (hasRequiredAction) return action; + hasRequiredAction = 1; + + action = (key, isSelect) => { + if (key.meta && key.name !== 'escape') return; + + if (key.ctrl) { + if (key.name === 'a') return 'first'; + if (key.name === 'c') return 'abort'; + if (key.name === 'd') return 'abort'; + if (key.name === 'e') return 'last'; + if (key.name === 'g') return 'reset'; + } + + if (isSelect) { + if (key.name === 'j') return 'down'; + if (key.name === 'k') return 'up'; + } + + if (key.name === 'return') return 'submit'; + if (key.name === 'enter') return 'submit'; // ctrl + J + if (key.name === 'backspace') return 'delete'; + if (key.name === 'delete') return 'deleteForward'; + if (key.name === 'abort') return 'abort'; + if (key.name === 'escape') return 'exit'; + if (key.name === 'tab') return 'next'; + if (key.name === 'pagedown') return 'nextPage'; + if (key.name === 'pageup') return 'prevPage'; + // TODO create home() in prompt types (e.g. TextPrompt) + if (key.name === 'home') return 'home'; + // TODO create end() in prompt types (e.g. TextPrompt) + if (key.name === 'end') return 'end'; + + if (key.name === 'up') return 'up'; + if (key.name === 'down') return 'down'; + if (key.name === 'right') return 'right'; + if (key.name === 'left') return 'left'; + + return false; + }; + return action; +} + +var strip; +var hasRequiredStrip; + +function requireStrip () { + if (hasRequiredStrip) return strip; + hasRequiredStrip = 1; + + strip = str => { + const pattern = [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))' + ].join('|'); + + const RGX = new RegExp(pattern, 'g'); + return typeof str === 'string' ? str.replace(RGX, '') : str; + }; + return strip; +} + +var clear; +var hasRequiredClear; + +function requireClear () { + if (hasRequiredClear) return clear; + hasRequiredClear = 1; + + const strip = requireStrip(); + const { erase, cursor } = requireSrc(); + + const width = str => [...strip(str)].length; + + /** + * @param {string} prompt + * @param {number} perLine + */ + clear = function(prompt, perLine) { + if (!perLine) return erase.line + cursor.to(0); + + let rows = 0; + const lines = prompt.split(/\r?\n/); + for (let line of lines) { + rows += 1 + Math.floor(Math.max(width(line) - 1, 0) / perLine); + } + + return erase.lines(rows); + }; + return clear; +} + +var figures_1; +var hasRequiredFigures; + +function requireFigures () { + if (hasRequiredFigures) return figures_1; + hasRequiredFigures = 1; + + const main = { + arrowUp: '↑', + arrowDown: '↓', + arrowLeft: '←', + arrowRight: '→', + radioOn: '◉', + radioOff: '◯', + tick: '✔', + cross: '✖', + ellipsis: '…', + pointerSmall: '›', + line: '─', + pointer: '❯' + }; + const win = { + arrowUp: main.arrowUp, + arrowDown: main.arrowDown, + arrowLeft: main.arrowLeft, + arrowRight: main.arrowRight, + radioOn: '(*)', + radioOff: '( )', + tick: '√', + cross: '×', + ellipsis: '...', + pointerSmall: '»', + line: '─', + pointer: '>' + }; + const figures = process.platform === 'win32' ? win : main; + + figures_1 = figures; + return figures_1; +} + +var style; +var hasRequiredStyle; + +function requireStyle () { + if (hasRequiredStyle) return style; + hasRequiredStyle = 1; + + const c = requireKleur(); + const figures = requireFigures(); + + // rendering user input. + const styles = Object.freeze({ + password: { scale: 1, render: input => '*'.repeat(input.length) }, + emoji: { scale: 2, render: input => '😃'.repeat(input.length) }, + invisible: { scale: 0, render: input => '' }, + default: { scale: 1, render: input => `${input}` } + }); + const render = type => styles[type] || styles.default; + + // icon to signalize a prompt. + const symbols = Object.freeze({ + aborted: c.red(figures.cross), + done: c.green(figures.tick), + exited: c.yellow(figures.cross), + default: c.cyan('?') + }); + + const symbol = (done, aborted, exited) => + aborted ? symbols.aborted : exited ? symbols.exited : done ? symbols.done : symbols.default; + + // between the question and the user's input. + const delimiter = completing => + c.gray(completing ? figures.ellipsis : figures.pointerSmall); + + const item = (expandable, expanded) => + c.gray(expandable ? (expanded ? figures.pointerSmall : '+') : figures.line); + + style = { + styles, + render, + symbols, + symbol, + delimiter, + item + }; + return style; +} + +var lines; +var hasRequiredLines; + +function requireLines () { + if (hasRequiredLines) return lines; + hasRequiredLines = 1; + + const strip = requireStrip(); + + /** + * @param {string} msg + * @param {number} perLine + */ + lines = function (msg, perLine) { + let lines = String(strip(msg) || '').split(/\r?\n/); + + if (!perLine) return lines.length; + return lines.map(l => Math.ceil(l.length / perLine)) + .reduce((a, b) => a + b); + }; + return lines; +} + +var wrap; +var hasRequiredWrap; + +function requireWrap () { + if (hasRequiredWrap) return wrap; + hasRequiredWrap = 1; + + /** + * @param {string} msg The message to wrap + * @param {object} opts + * @param {number|string} [opts.margin] Left margin + * @param {number} opts.width Maximum characters per line including the margin + */ + wrap = (msg, opts = {}) => { + const tab = Number.isSafeInteger(parseInt(opts.margin)) + ? new Array(parseInt(opts.margin)).fill(' ').join('') + : (opts.margin || ''); + + const width = opts.width; + + return (msg || '').split(/\r?\n/g) + .map(line => line + .split(/\s+/g) + .reduce((arr, w) => { + if (w.length + tab.length >= width || arr[arr.length - 1].length + w.length + 1 < width) + arr[arr.length - 1] += ` ${w}`; + else arr.push(`${tab}${w}`); + return arr; + }, [ tab ]) + .join('\n')) + .join('\n'); + }; + return wrap; +} + +var entriesToDisplay; +var hasRequiredEntriesToDisplay; + +function requireEntriesToDisplay () { + if (hasRequiredEntriesToDisplay) return entriesToDisplay; + hasRequiredEntriesToDisplay = 1; + + /** + * Determine what entries should be displayed on the screen, based on the + * currently selected index and the maximum visible. Used in list-based + * prompts like `select` and `multiselect`. + * + * @param {number} cursor the currently selected entry + * @param {number} total the total entries available to display + * @param {number} [maxVisible] the number of entries that can be displayed + */ + entriesToDisplay = (cursor, total, maxVisible) => { + maxVisible = maxVisible || total; + + let startIndex = Math.min(total- maxVisible, cursor - Math.floor(maxVisible / 2)); + if (startIndex < 0) startIndex = 0; + + let endIndex = Math.min(startIndex + maxVisible, total); + + return { startIndex, endIndex }; + }; + return entriesToDisplay; +} + +var util; +var hasRequiredUtil; + +function requireUtil () { + if (hasRequiredUtil) return util; + hasRequiredUtil = 1; + + util = { + action: requireAction(), + clear: requireClear(), + style: requireStyle(), + strip: requireStrip(), + figures: requireFigures(), + lines: requireLines(), + wrap: requireWrap(), + entriesToDisplay: requireEntriesToDisplay() + }; + return util; +} + +var prompt$1; +var hasRequiredPrompt; + +function requirePrompt () { + if (hasRequiredPrompt) return prompt$1; + hasRequiredPrompt = 1; + + const readline = require$$0; + const { action } = requireUtil(); + const EventEmitter = require$$0$1; + const { beep, cursor } = requireSrc(); + const color = requireKleur(); + + /** + * Base prompt skeleton + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + class Prompt extends EventEmitter { + constructor(opts={}) { + super(); + + this.firstRender = true; + this.in = opts.stdin || process.stdin; + this.out = opts.stdout || process.stdout; + this.onRender = (opts.onRender || (() => void 0)).bind(this); + const rl = readline.createInterface({ input:this.in, escapeCodeTimeout:50 }); + readline.emitKeypressEvents(this.in, rl); + + if (this.in.isTTY) this.in.setRawMode(true); + const isSelect = [ 'SelectPrompt', 'MultiselectPrompt' ].indexOf(this.constructor.name) > -1; + const keypress = (str, key) => { + let a = action(key, isSelect); + if (a === false) { + this._ && this._(str, key); + } else if (typeof this[a] === 'function') { + this[a](key); + } else { + this.bell(); + } + }; + + this.close = () => { + this.out.write(cursor.show); + this.in.removeListener('keypress', keypress); + if (this.in.isTTY) this.in.setRawMode(false); + rl.close(); + this.emit(this.aborted ? 'abort' : this.exited ? 'exit' : 'submit', this.value); + this.closed = true; + }; + + this.in.on('keypress', keypress); + } + + fire() { + this.emit('state', { + value: this.value, + aborted: !!this.aborted, + exited: !!this.exited + }); + } + + bell() { + this.out.write(beep); + } + + render() { + this.onRender(color); + if (this.firstRender) this.firstRender = false; + } + } + + prompt$1 = Prompt; + return prompt$1; +} + +var text; +var hasRequiredText; + +function requireText () { + if (hasRequiredText) return text; + hasRequiredText = 1; + const color = requireKleur(); + const Prompt = requirePrompt(); + const { erase, cursor } = requireSrc(); + const { style, clear, lines, figures } = requireUtil(); + + /** + * TextPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {String} [opts.style='default'] Render style + * @param {String} [opts.initial] Default value + * @param {Function} [opts.validate] Validate function + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {String} [opts.error] The invalid error label + */ + class TextPrompt extends Prompt { + constructor(opts={}) { + super(opts); + this.transform = style.render(opts.style); + this.scale = this.transform.scale; + this.msg = opts.message; + this.initial = opts.initial || ``; + this.validator = opts.validate || (() => true); + this.value = ``; + this.errorMsg = opts.error || `Please Enter A Valid Value`; + this.cursor = Number(!!this.initial); + this.cursorOffset = 0; + this.clear = clear(``, this.out.columns); + this.render(); + } + + set value(v) { + if (!v && this.initial) { + this.placeholder = true; + this.rendered = color.gray(this.transform.render(this.initial)); + } else { + this.placeholder = false; + this.rendered = this.transform.render(v); + } + this._value = v; + this.fire(); + } + + get value() { + return this._value; + } + + reset() { + this.value = ``; + this.cursor = Number(!!this.initial); + this.cursorOffset = 0; + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.value = this.value || this.initial; + this.done = this.aborted = true; + this.error = false; + this.red = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + async validate() { + let valid = await this.validator(this.value); + if (typeof valid === `string`) { + this.errorMsg = valid; + valid = false; + } + this.error = !valid; + } + + async submit() { + this.value = this.value || this.initial; + this.cursorOffset = 0; + this.cursor = this.rendered.length; + await this.validate(); + if (this.error) { + this.red = true; + this.fire(); + this.render(); + return; + } + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + next() { + if (!this.placeholder) return this.bell(); + this.value = this.initial; + this.cursor = this.rendered.length; + this.fire(); + this.render(); + } + + moveCursor(n) { + if (this.placeholder) return; + this.cursor = this.cursor+n; + this.cursorOffset += n; + } + + _(c, key) { + let s1 = this.value.slice(0, this.cursor); + let s2 = this.value.slice(this.cursor); + this.value = `${s1}${c}${s2}`; + this.red = false; + this.cursor = this.placeholder ? 0 : s1.length+1; + this.render(); + } + + delete() { + if (this.isCursorAtStart()) return this.bell(); + let s1 = this.value.slice(0, this.cursor-1); + let s2 = this.value.slice(this.cursor); + this.value = `${s1}${s2}`; + this.red = false; + if (this.isCursorAtStart()) { + this.cursorOffset = 0; + } else { + this.cursorOffset++; + this.moveCursor(-1); + } + this.render(); + } + + deleteForward() { + if(this.cursor*this.scale >= this.rendered.length || this.placeholder) return this.bell(); + let s1 = this.value.slice(0, this.cursor); + let s2 = this.value.slice(this.cursor+1); + this.value = `${s1}${s2}`; + this.red = false; + if (this.isCursorAtEnd()) { + this.cursorOffset = 0; + } else { + this.cursorOffset++; + } + this.render(); + } + + first() { + this.cursor = 0; + this.render(); + } + + last() { + this.cursor = this.value.length; + this.render(); + } + + left() { + if (this.cursor <= 0 || this.placeholder) return this.bell(); + this.moveCursor(-1); + this.render(); + } + + right() { + if (this.cursor*this.scale >= this.rendered.length || this.placeholder) return this.bell(); + this.moveCursor(1); + this.render(); + } + + isCursorAtStart() { + return this.cursor === 0 || (this.placeholder && this.cursor === 1); + } + + isCursorAtEnd() { + return this.cursor === this.rendered.length || (this.placeholder && this.cursor === this.rendered.length + 1) + } + + render() { + if (this.closed) return; + if (!this.firstRender) { + if (this.outputError) + this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns)); + this.out.write(clear(this.outputText, this.out.columns)); + } + super.render(); + this.outputError = ''; + + this.outputText = [ + style.symbol(this.done, this.aborted), + color.bold(this.msg), + style.delimiter(this.done), + this.red ? color.red(this.rendered) : this.rendered + ].join(` `); + + if (this.error) { + this.outputError += this.errorMsg.split(`\n`) + .reduce((a, l, i) => a + `\n${i ? ' ' : figures.pointerSmall} ${color.red().italic(l)}`, ``); + } + + this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore + cursor.move(this.cursorOffset, 0)); + } + } + + text = TextPrompt; + return text; +} + +var select; +var hasRequiredSelect; + +function requireSelect () { + if (hasRequiredSelect) return select; + hasRequiredSelect = 1; + + const color = requireKleur(); + const Prompt = requirePrompt(); + const { style, clear, figures, wrap, entriesToDisplay } = requireUtil(); + const { cursor } = requireSrc(); + + /** + * SelectPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Array} opts.choices Array of choice objects + * @param {String} [opts.hint] Hint to display + * @param {Number} [opts.initial] Index of default value + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {Number} [opts.optionsPerPage=10] Max options to display at once + */ + class SelectPrompt extends Prompt { + constructor(opts={}) { + super(opts); + this.msg = opts.message; + this.hint = opts.hint || '- Use arrow-keys. Return to submit.'; + this.warn = opts.warn || '- This option is disabled'; + this.cursor = opts.initial || 0; + this.choices = opts.choices.map((ch, idx) => { + if (typeof ch === 'string') + ch = {title: ch, value: idx}; + return { + title: ch && (ch.title || ch.value || ch), + value: ch && (ch.value === undefined ? idx : ch.value), + description: ch && ch.description, + selected: ch && ch.selected, + disabled: ch && ch.disabled + }; + }); + this.optionsPerPage = opts.optionsPerPage || 10; + this.value = (this.choices[this.cursor] || {}).value; + this.clear = clear('', this.out.columns); + this.render(); + } + + moveCursor(n) { + this.cursor = n; + this.value = this.choices[n].value; + this.fire(); + } + + reset() { + this.moveCursor(0); + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + if (!this.selection.disabled) { + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } else + this.bell(); + } + + first() { + this.moveCursor(0); + this.render(); + } + + last() { + this.moveCursor(this.choices.length - 1); + this.render(); + } + + up() { + if (this.cursor === 0) { + this.moveCursor(this.choices.length - 1); + } else { + this.moveCursor(this.cursor - 1); + } + this.render(); + } + + down() { + if (this.cursor === this.choices.length - 1) { + this.moveCursor(0); + } else { + this.moveCursor(this.cursor + 1); + } + this.render(); + } + + next() { + this.moveCursor((this.cursor + 1) % this.choices.length); + this.render(); + } + + _(c, key) { + if (c === ' ') return this.submit(); + } + + get selection() { + return this.choices[this.cursor]; + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); + + let { startIndex, endIndex } = entriesToDisplay(this.cursor, this.choices.length, this.optionsPerPage); + + // Print prompt + this.outputText = [ + style.symbol(this.done, this.aborted), + color.bold(this.msg), + style.delimiter(false), + this.done ? this.selection.title : this.selection.disabled + ? color.yellow(this.warn) : color.gray(this.hint) + ].join(' '); + + // Print choices + if (!this.done) { + this.outputText += '\n'; + for (let i = startIndex; i < endIndex; i++) { + let title, prefix, desc = '', v = this.choices[i]; + + // Determine whether to display "more choices" indicators + if (i === startIndex && startIndex > 0) { + prefix = figures.arrowUp; + } else if (i === endIndex - 1 && endIndex < this.choices.length) { + prefix = figures.arrowDown; + } else { + prefix = ' '; + } + + if (v.disabled) { + title = this.cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title); + prefix = (this.cursor === i ? color.bold().gray(figures.pointer) + ' ' : ' ') + prefix; + } else { + title = this.cursor === i ? color.cyan().underline(v.title) : v.title; + prefix = (this.cursor === i ? color.cyan(figures.pointer) + ' ' : ' ') + prefix; + if (v.description && this.cursor === i) { + desc = ` - ${v.description}`; + if (prefix.length + title.length + desc.length >= this.out.columns + || v.description.split(/\r?\n/).length > 1) { + desc = '\n' + wrap(v.description, { margin: 3, width: this.out.columns }); + } + } + } + + this.outputText += `${prefix} ${title}${color.gray(desc)}\n`; + } + } + + this.out.write(this.outputText); + } + } + + select = SelectPrompt; + return select; +} + +var toggle; +var hasRequiredToggle; + +function requireToggle () { + if (hasRequiredToggle) return toggle; + hasRequiredToggle = 1; + const color = requireKleur(); + const Prompt = requirePrompt(); + const { style, clear } = requireUtil(); + const { cursor, erase } = requireSrc(); + + /** + * TogglePrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Boolean} [opts.initial=false] Default value + * @param {String} [opts.active='no'] Active label + * @param {String} [opts.inactive='off'] Inactive label + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + class TogglePrompt extends Prompt { + constructor(opts={}) { + super(opts); + this.msg = opts.message; + this.value = !!opts.initial; + this.active = opts.active || 'on'; + this.inactive = opts.inactive || 'off'; + this.initialValue = this.value; + this.render(); + } + + reset() { + this.value = this.initialValue; + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + deactivate() { + if (this.value === false) return this.bell(); + this.value = false; + this.render(); + } + + activate() { + if (this.value === true) return this.bell(); + this.value = true; + this.render(); + } + + delete() { + this.deactivate(); + } + left() { + this.deactivate(); + } + right() { + this.activate(); + } + down() { + this.deactivate(); + } + up() { + this.activate(); + } + + next() { + this.value = !this.value; + this.fire(); + this.render(); + } + + _(c, key) { + if (c === ' ') { + this.value = !this.value; + } else if (c === '1') { + this.value = true; + } else if (c === '0') { + this.value = false; + } else return this.bell(); + this.render(); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); + + this.outputText = [ + style.symbol(this.done, this.aborted), + color.bold(this.msg), + style.delimiter(this.done), + this.value ? this.inactive : color.cyan().underline(this.inactive), + color.gray('/'), + this.value ? color.cyan().underline(this.active) : this.active + ].join(' '); + + this.out.write(erase.line + cursor.to(0) + this.outputText); + } + } + + toggle = TogglePrompt; + return toggle; +} + +var datepart; +var hasRequiredDatepart; + +function requireDatepart () { + if (hasRequiredDatepart) return datepart; + hasRequiredDatepart = 1; + + class DatePart { + constructor({token, date, parts, locales}) { + this.token = token; + this.date = date || new Date(); + this.parts = parts || [this]; + this.locales = locales || {}; + } + + up() {} + + down() {} + + next() { + const currentIdx = this.parts.indexOf(this); + return this.parts.find((part, idx) => idx > currentIdx && part instanceof DatePart); + } + + setTo(val) {} + + prev() { + let parts = [].concat(this.parts).reverse(); + const currentIdx = parts.indexOf(this); + return parts.find((part, idx) => idx > currentIdx && part instanceof DatePart); + } + + toString() { + return String(this.date); + } + } + + datepart = DatePart; + return datepart; +} + +var meridiem; +var hasRequiredMeridiem; + +function requireMeridiem () { + if (hasRequiredMeridiem) return meridiem; + hasRequiredMeridiem = 1; + + const DatePart = requireDatepart(); + + class Meridiem extends DatePart { + constructor(opts={}) { + super(opts); + } + + up() { + this.date.setHours((this.date.getHours() + 12) % 24); + } + + down() { + this.up(); + } + + toString() { + let meridiem = this.date.getHours() > 12 ? 'pm' : 'am'; + return /\A/.test(this.token) ? meridiem.toUpperCase() : meridiem; + } + } + + meridiem = Meridiem; + return meridiem; +} + +var day; +var hasRequiredDay; + +function requireDay () { + if (hasRequiredDay) return day; + hasRequiredDay = 1; + + const DatePart = requireDatepart(); + + const pos = n => { + n = n % 10; + return n === 1 ? 'st' + : n === 2 ? 'nd' + : n === 3 ? 'rd' + : 'th'; + }; + + class Day extends DatePart { + constructor(opts={}) { + super(opts); + } + + up() { + this.date.setDate(this.date.getDate() + 1); + } + + down() { + this.date.setDate(this.date.getDate() - 1); + } + + setTo(val) { + this.date.setDate(parseInt(val.substr(-2))); + } + + toString() { + let date = this.date.getDate(); + let day = this.date.getDay(); + return this.token === 'DD' ? String(date).padStart(2, '0') + : this.token === 'Do' ? date + pos(date) + : this.token === 'd' ? day + 1 + : this.token === 'ddd' ? this.locales.weekdaysShort[day] + : this.token === 'dddd' ? this.locales.weekdays[day] + : date; + } + } + + day = Day; + return day; +} + +var hours; +var hasRequiredHours; + +function requireHours () { + if (hasRequiredHours) return hours; + hasRequiredHours = 1; + + const DatePart = requireDatepart(); + + class Hours extends DatePart { + constructor(opts={}) { + super(opts); + } + + up() { + this.date.setHours(this.date.getHours() + 1); + } + + down() { + this.date.setHours(this.date.getHours() - 1); + } + + setTo(val) { + this.date.setHours(parseInt(val.substr(-2))); + } + + toString() { + let hours = this.date.getHours(); + if (/h/.test(this.token)) + hours = (hours % 12) || 12; + return this.token.length > 1 ? String(hours).padStart(2, '0') : hours; + } + } + + hours = Hours; + return hours; +} + +var milliseconds; +var hasRequiredMilliseconds; + +function requireMilliseconds () { + if (hasRequiredMilliseconds) return milliseconds; + hasRequiredMilliseconds = 1; + + const DatePart = requireDatepart(); + + class Milliseconds extends DatePart { + constructor(opts={}) { + super(opts); + } + + up() { + this.date.setMilliseconds(this.date.getMilliseconds() + 1); + } + + down() { + this.date.setMilliseconds(this.date.getMilliseconds() - 1); + } + + setTo(val) { + this.date.setMilliseconds(parseInt(val.substr(-(this.token.length)))); + } + + toString() { + return String(this.date.getMilliseconds()).padStart(4, '0') + .substr(0, this.token.length); + } + } + + milliseconds = Milliseconds; + return milliseconds; +} + +var minutes; +var hasRequiredMinutes; + +function requireMinutes () { + if (hasRequiredMinutes) return minutes; + hasRequiredMinutes = 1; + + const DatePart = requireDatepart(); + + class Minutes extends DatePart { + constructor(opts={}) { + super(opts); + } + + up() { + this.date.setMinutes(this.date.getMinutes() + 1); + } + + down() { + this.date.setMinutes(this.date.getMinutes() - 1); + } + + setTo(val) { + this.date.setMinutes(parseInt(val.substr(-2))); + } + + toString() { + let m = this.date.getMinutes(); + return this.token.length > 1 ? String(m).padStart(2, '0') : m; + } + } + + minutes = Minutes; + return minutes; +} + +var month; +var hasRequiredMonth; + +function requireMonth () { + if (hasRequiredMonth) return month; + hasRequiredMonth = 1; + + const DatePart = requireDatepart(); + + class Month extends DatePart { + constructor(opts={}) { + super(opts); + } + + up() { + this.date.setMonth(this.date.getMonth() + 1); + } + + down() { + this.date.setMonth(this.date.getMonth() - 1); + } + + setTo(val) { + val = parseInt(val.substr(-2)) - 1; + this.date.setMonth(val < 0 ? 0 : val); + } + + toString() { + let month = this.date.getMonth(); + let tl = this.token.length; + return tl === 2 ? String(month + 1).padStart(2, '0') + : tl === 3 ? this.locales.monthsShort[month] + : tl === 4 ? this.locales.months[month] + : String(month + 1); + } + } + + month = Month; + return month; +} + +var seconds; +var hasRequiredSeconds; + +function requireSeconds () { + if (hasRequiredSeconds) return seconds; + hasRequiredSeconds = 1; + + const DatePart = requireDatepart(); + + class Seconds extends DatePart { + constructor(opts={}) { + super(opts); + } + + up() { + this.date.setSeconds(this.date.getSeconds() + 1); + } + + down() { + this.date.setSeconds(this.date.getSeconds() - 1); + } + + setTo(val) { + this.date.setSeconds(parseInt(val.substr(-2))); + } + + toString() { + let s = this.date.getSeconds(); + return this.token.length > 1 ? String(s).padStart(2, '0') : s; + } + } + + seconds = Seconds; + return seconds; +} + +var year; +var hasRequiredYear; + +function requireYear () { + if (hasRequiredYear) return year; + hasRequiredYear = 1; + + const DatePart = requireDatepart(); + + class Year extends DatePart { + constructor(opts={}) { + super(opts); + } + + up() { + this.date.setFullYear(this.date.getFullYear() + 1); + } + + down() { + this.date.setFullYear(this.date.getFullYear() - 1); + } + + setTo(val) { + this.date.setFullYear(val.substr(-4)); + } + + toString() { + let year = String(this.date.getFullYear()).padStart(4, '0'); + return this.token.length === 2 ? year.substr(-2) : year; + } + } + + year = Year; + return year; +} + +var dateparts; +var hasRequiredDateparts; + +function requireDateparts () { + if (hasRequiredDateparts) return dateparts; + hasRequiredDateparts = 1; + + dateparts = { + DatePart: requireDatepart(), + Meridiem: requireMeridiem(), + Day: requireDay(), + Hours: requireHours(), + Milliseconds: requireMilliseconds(), + Minutes: requireMinutes(), + Month: requireMonth(), + Seconds: requireSeconds(), + Year: requireYear(), + }; + return dateparts; +} + +var date; +var hasRequiredDate; + +function requireDate () { + if (hasRequiredDate) return date; + hasRequiredDate = 1; + + const color = requireKleur(); + const Prompt = requirePrompt(); + const { style, clear, figures } = requireUtil(); + const { erase, cursor } = requireSrc(); + const { DatePart, Meridiem, Day, Hours, Milliseconds, Minutes, Month, Seconds, Year } = requireDateparts(); + + const regex = /\\(.)|"((?:\\["\\]|[^"])+)"|(D[Do]?|d{3,4}|d)|(M{1,4})|(YY(?:YY)?)|([aA])|([Hh]{1,2})|(m{1,2})|(s{1,2})|(S{1,4})|./g; + const regexGroups = { + 1: ({token}) => token.replace(/\\(.)/g, '$1'), + 2: (opts) => new Day(opts), // Day // TODO + 3: (opts) => new Month(opts), // Month + 4: (opts) => new Year(opts), // Year + 5: (opts) => new Meridiem(opts), // AM/PM // TODO (special) + 6: (opts) => new Hours(opts), // Hours + 7: (opts) => new Minutes(opts), // Minutes + 8: (opts) => new Seconds(opts), // Seconds + 9: (opts) => new Milliseconds(opts), // Fractional seconds + }; + + const dfltLocales = { + months: 'January,February,March,April,May,June,July,August,September,October,November,December'.split(','), + monthsShort: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','), + weekdays: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(','), + weekdaysShort: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(',') + }; + + + /** + * DatePrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Number} [opts.initial] Index of default value + * @param {String} [opts.mask] The format mask + * @param {object} [opts.locales] The date locales + * @param {String} [opts.error] The error message shown on invalid value + * @param {Function} [opts.validate] Function to validate the submitted value + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + class DatePrompt extends Prompt { + constructor(opts={}) { + super(opts); + this.msg = opts.message; + this.cursor = 0; + this.typed = ''; + this.locales = Object.assign(dfltLocales, opts.locales); + this._date = opts.initial || new Date(); + this.errorMsg = opts.error || 'Please Enter A Valid Value'; + this.validator = opts.validate || (() => true); + this.mask = opts.mask || 'YYYY-MM-DD HH:mm:ss'; + this.clear = clear('', this.out.columns); + this.render(); + } + + get value() { + return this.date + } + + get date() { + return this._date; + } + + set date(date) { + if (date) this._date.setTime(date.getTime()); + } + + set mask(mask) { + let result; + this.parts = []; + while(result = regex.exec(mask)) { + let match = result.shift(); + let idx = result.findIndex(gr => gr != null); + this.parts.push(idx in regexGroups + ? regexGroups[idx]({ token: result[idx] || match, date: this.date, parts: this.parts, locales: this.locales }) + : result[idx] || match); + } + + let parts = this.parts.reduce((arr, i) => { + if (typeof i === 'string' && typeof arr[arr.length - 1] === 'string') + arr[arr.length - 1] += i; + else arr.push(i); + return arr; + }, []); + + this.parts.splice(0); + this.parts.push(...parts); + this.reset(); + } + + moveCursor(n) { + this.typed = ''; + this.cursor = n; + this.fire(); + } + + reset() { + this.moveCursor(this.parts.findIndex(p => p instanceof DatePart)); + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.error = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + async validate() { + let valid = await this.validator(this.value); + if (typeof valid === 'string') { + this.errorMsg = valid; + valid = false; + } + this.error = !valid; + } + + async submit() { + await this.validate(); + if (this.error) { + this.color = 'red'; + this.fire(); + this.render(); + return; + } + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + up() { + this.typed = ''; + this.parts[this.cursor].up(); + this.render(); + } + + down() { + this.typed = ''; + this.parts[this.cursor].down(); + this.render(); + } + + left() { + let prev = this.parts[this.cursor].prev(); + if (prev == null) return this.bell(); + this.moveCursor(this.parts.indexOf(prev)); + this.render(); + } + + right() { + let next = this.parts[this.cursor].next(); + if (next == null) return this.bell(); + this.moveCursor(this.parts.indexOf(next)); + this.render(); + } + + next() { + let next = this.parts[this.cursor].next(); + this.moveCursor(next + ? this.parts.indexOf(next) + : this.parts.findIndex((part) => part instanceof DatePart)); + this.render(); + } + + _(c) { + if (/\d/.test(c)) { + this.typed += c; + this.parts[this.cursor].setTo(this.typed); + this.render(); + } + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); + + // Print prompt + this.outputText = [ + style.symbol(this.done, this.aborted), + color.bold(this.msg), + style.delimiter(false), + this.parts.reduce((arr, p, idx) => arr.concat(idx === this.cursor && !this.done ? color.cyan().underline(p.toString()) : p), []) + .join('') + ].join(' '); + + // Print error + if (this.error) { + this.outputText += this.errorMsg.split('\n').reduce( + (a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``); + } + + this.out.write(erase.line + cursor.to(0) + this.outputText); + } + } + + date = DatePrompt; + return date; +} + +var number; +var hasRequiredNumber; + +function requireNumber () { + if (hasRequiredNumber) return number; + hasRequiredNumber = 1; + const color = requireKleur(); + const Prompt = requirePrompt(); + const { cursor, erase } = requireSrc(); + const { style, figures, clear, lines } = requireUtil(); + + const isNumber = /[0-9]/; + const isDef = any => any !== undefined; + const round = (number, precision) => { + let factor = Math.pow(10, precision); + return Math.round(number * factor) / factor; + }; + + /** + * NumberPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {String} [opts.style='default'] Render style + * @param {Number} [opts.initial] Default value + * @param {Number} [opts.max=+Infinity] Max value + * @param {Number} [opts.min=-Infinity] Min value + * @param {Boolean} [opts.float=false] Parse input as floats + * @param {Number} [opts.round=2] Round floats to x decimals + * @param {Number} [opts.increment=1] Number to increment by when using arrow-keys + * @param {Function} [opts.validate] Validate function + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {String} [opts.error] The invalid error label + */ + class NumberPrompt extends Prompt { + constructor(opts={}) { + super(opts); + this.transform = style.render(opts.style); + this.msg = opts.message; + this.initial = isDef(opts.initial) ? opts.initial : ''; + this.float = !!opts.float; + this.round = opts.round || 2; + this.inc = opts.increment || 1; + this.min = isDef(opts.min) ? opts.min : -Infinity; + this.max = isDef(opts.max) ? opts.max : Infinity; + this.errorMsg = opts.error || `Please Enter A Valid Value`; + this.validator = opts.validate || (() => true); + this.color = `cyan`; + this.value = ``; + this.typed = ``; + this.lastHit = 0; + this.render(); + } + + set value(v) { + if (!v && v !== 0) { + this.placeholder = true; + this.rendered = color.gray(this.transform.render(`${this.initial}`)); + this._value = ``; + } else { + this.placeholder = false; + this.rendered = this.transform.render(`${round(v, this.round)}`); + this._value = round(v, this.round); + } + this.fire(); + } + + get value() { + return this._value; + } + + parse(x) { + return this.float ? parseFloat(x) : parseInt(x); + } + + valid(c) { + return c === `-` || c === `.` && this.float || isNumber.test(c) + } + + reset() { + this.typed = ``; + this.value = ``; + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + let x = this.value; + this.value = x !== `` ? x : this.initial; + this.done = this.aborted = true; + this.error = false; + this.fire(); + this.render(); + this.out.write(`\n`); + this.close(); + } + + async validate() { + let valid = await this.validator(this.value); + if (typeof valid === `string`) { + this.errorMsg = valid; + valid = false; + } + this.error = !valid; + } + + async submit() { + await this.validate(); + if (this.error) { + this.color = `red`; + this.fire(); + this.render(); + return; + } + let x = this.value; + this.value = x !== `` ? x : this.initial; + this.done = true; + this.aborted = false; + this.error = false; + this.fire(); + this.render(); + this.out.write(`\n`); + this.close(); + } + + up() { + this.typed = ``; + if(this.value === '') { + this.value = this.min - this.inc; + } + if (this.value >= this.max) return this.bell(); + this.value += this.inc; + this.color = `cyan`; + this.fire(); + this.render(); + } + + down() { + this.typed = ``; + if(this.value === '') { + this.value = this.min + this.inc; + } + if (this.value <= this.min) return this.bell(); + this.value -= this.inc; + this.color = `cyan`; + this.fire(); + this.render(); + } + + delete() { + let val = this.value.toString(); + if (val.length === 0) return this.bell(); + this.value = this.parse((val = val.slice(0, -1))) || ``; + if (this.value !== '' && this.value < this.min) { + this.value = this.min; + } + this.color = `cyan`; + this.fire(); + this.render(); + } + + next() { + this.value = this.initial; + this.fire(); + this.render(); + } + + _(c, key) { + if (!this.valid(c)) return this.bell(); + + const now = Date.now(); + if (now - this.lastHit > 1000) this.typed = ``; // 1s elapsed + this.typed += c; + this.lastHit = now; + this.color = `cyan`; + + if (c === `.`) return this.fire(); + + this.value = Math.min(this.parse(this.typed), this.max); + if (this.value > this.max) this.value = this.max; + if (this.value < this.min) this.value = this.min; + this.fire(); + this.render(); + } + + render() { + if (this.closed) return; + if (!this.firstRender) { + if (this.outputError) + this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns)); + this.out.write(clear(this.outputText, this.out.columns)); + } + super.render(); + this.outputError = ''; + + // Print prompt + this.outputText = [ + style.symbol(this.done, this.aborted), + color.bold(this.msg), + style.delimiter(this.done), + !this.done || (!this.done && !this.placeholder) + ? color[this.color]().underline(this.rendered) : this.rendered + ].join(` `); + + // Print error + if (this.error) { + this.outputError += this.errorMsg.split(`\n`) + .reduce((a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``); + } + + this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore); + } + } + + number = NumberPrompt; + return number; +} + +var multiselect; +var hasRequiredMultiselect; + +function requireMultiselect () { + if (hasRequiredMultiselect) return multiselect; + hasRequiredMultiselect = 1; + + const color = requireKleur(); + const { cursor } = requireSrc(); + const Prompt = requirePrompt(); + const { clear, figures, style, wrap, entriesToDisplay } = requireUtil(); + + /** + * MultiselectPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Array} opts.choices Array of choice objects + * @param {String} [opts.hint] Hint to display + * @param {String} [opts.warn] Hint shown for disabled choices + * @param {Number} [opts.max] Max choices + * @param {Number} [opts.cursor=0] Cursor start position + * @param {Number} [opts.optionsPerPage=10] Max options to display at once + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + class MultiselectPrompt extends Prompt { + constructor(opts={}) { + super(opts); + this.msg = opts.message; + this.cursor = opts.cursor || 0; + this.scrollIndex = opts.cursor || 0; + this.hint = opts.hint || ''; + this.warn = opts.warn || '- This option is disabled -'; + this.minSelected = opts.min; + this.showMinError = false; + this.maxChoices = opts.max; + this.instructions = opts.instructions; + this.optionsPerPage = opts.optionsPerPage || 10; + this.value = opts.choices.map((ch, idx) => { + if (typeof ch === 'string') + ch = {title: ch, value: idx}; + return { + title: ch && (ch.title || ch.value || ch), + description: ch && ch.description, + value: ch && (ch.value === undefined ? idx : ch.value), + selected: ch && ch.selected, + disabled: ch && ch.disabled + }; + }); + this.clear = clear('', this.out.columns); + if (!opts.overrideRender) { + this.render(); + } + } + + reset() { + this.value.map(v => !v.selected); + this.cursor = 0; + this.fire(); + this.render(); + } + + selected() { + return this.value.filter(v => v.selected); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + const selected = this.value + .filter(e => e.selected); + if (this.minSelected && selected.length < this.minSelected) { + this.showMinError = true; + this.render(); + } else { + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + } + + first() { + this.cursor = 0; + this.render(); + } + + last() { + this.cursor = this.value.length - 1; + this.render(); + } + next() { + this.cursor = (this.cursor + 1) % this.value.length; + this.render(); + } + + up() { + if (this.cursor === 0) { + this.cursor = this.value.length - 1; + } else { + this.cursor--; + } + this.render(); + } + + down() { + if (this.cursor === this.value.length - 1) { + this.cursor = 0; + } else { + this.cursor++; + } + this.render(); + } + + left() { + this.value[this.cursor].selected = false; + this.render(); + } + + right() { + if (this.value.filter(e => e.selected).length >= this.maxChoices) return this.bell(); + this.value[this.cursor].selected = true; + this.render(); + } + + handleSpaceToggle() { + const v = this.value[this.cursor]; + + if (v.selected) { + v.selected = false; + this.render(); + } else if (v.disabled || this.value.filter(e => e.selected).length >= this.maxChoices) { + return this.bell(); + } else { + v.selected = true; + this.render(); + } + } + + toggleAll() { + if (this.maxChoices !== undefined || this.value[this.cursor].disabled) { + return this.bell(); + } + + const newSelected = !this.value[this.cursor].selected; + this.value.filter(v => !v.disabled).forEach(v => v.selected = newSelected); + this.render(); + } + + _(c, key) { + if (c === ' ') { + this.handleSpaceToggle(); + } else if (c === 'a') { + this.toggleAll(); + } else { + return this.bell(); + } + } + + renderInstructions() { + if (this.instructions === undefined || this.instructions) { + if (typeof this.instructions === 'string') { + return this.instructions; + } + return '\nInstructions:\n' + + ` ${figures.arrowUp}/${figures.arrowDown}: Highlight option\n` + + ` ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection\n` + + (this.maxChoices === undefined ? ` a: Toggle all\n` : '') + + ` enter/return: Complete answer`; + } + return ''; + } + + renderOption(cursor, v, i, arrowIndicator) { + const prefix = (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + arrowIndicator + ' '; + let title, desc; + + if (v.disabled) { + title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title); + } else { + title = cursor === i ? color.cyan().underline(v.title) : v.title; + if (cursor === i && v.description) { + desc = ` - ${v.description}`; + if (prefix.length + title.length + desc.length >= this.out.columns + || v.description.split(/\r?\n/).length > 1) { + desc = '\n' + wrap(v.description, { margin: prefix.length, width: this.out.columns }); + } + } + } + + return prefix + title + color.gray(desc || ''); + } + + // shared with autocompleteMultiselect + paginateOptions(options) { + if (options.length === 0) { + return color.red('No matches for this query.'); + } + + let { startIndex, endIndex } = entriesToDisplay(this.cursor, options.length, this.optionsPerPage); + let prefix, styledOptions = []; + + for (let i = startIndex; i < endIndex; i++) { + if (i === startIndex && startIndex > 0) { + prefix = figures.arrowUp; + } else if (i === endIndex - 1 && endIndex < options.length) { + prefix = figures.arrowDown; + } else { + prefix = ' '; + } + styledOptions.push(this.renderOption(this.cursor, options[i], i, prefix)); + } + + return '\n' + styledOptions.join('\n'); + } + + // shared with autocomleteMultiselect + renderOptions(options) { + if (!this.done) { + return this.paginateOptions(options); + } + return ''; + } + + renderDoneOrInstructions() { + if (this.done) { + return this.value + .filter(e => e.selected) + .map(v => v.title) + .join(', '); + } + + const output = [color.gray(this.hint), this.renderInstructions()]; + + if (this.value[this.cursor].disabled) { + output.push(color.yellow(this.warn)); + } + return output.join(' '); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + super.render(); + + // print prompt + let prompt = [ + style.symbol(this.done, this.aborted), + color.bold(this.msg), + style.delimiter(false), + this.renderDoneOrInstructions() + ].join(' '); + if (this.showMinError) { + prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`); + this.showMinError = false; + } + prompt += this.renderOptions(this.value); + + this.out.write(this.clear + prompt); + this.clear = clear(prompt, this.out.columns); + } + } + + multiselect = MultiselectPrompt; + return multiselect; +} + +var autocomplete; +var hasRequiredAutocomplete; + +function requireAutocomplete () { + if (hasRequiredAutocomplete) return autocomplete; + hasRequiredAutocomplete = 1; + + const color = requireKleur(); + const Prompt = requirePrompt(); + const { erase, cursor } = requireSrc(); + const { style, clear, figures, wrap, entriesToDisplay } = requireUtil(); + + const getVal = (arr, i) => arr[i] && (arr[i].value || arr[i].title || arr[i]); + const getTitle = (arr, i) => arr[i] && (arr[i].title || arr[i].value || arr[i]); + const getIndex = (arr, valOrTitle) => { + const index = arr.findIndex(el => el.value === valOrTitle || el.title === valOrTitle); + return index > -1 ? index : undefined; + }; + + /** + * TextPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Array} opts.choices Array of auto-complete choices objects + * @param {Function} [opts.suggest] Filter function. Defaults to sort by title + * @param {Number} [opts.limit=10] Max number of results to show + * @param {Number} [opts.cursor=0] Cursor start position + * @param {String} [opts.style='default'] Render style + * @param {String} [opts.fallback] Fallback message - initial to default value + * @param {String} [opts.initial] Index of the default value + * @param {Boolean} [opts.clearFirst] The first ESCAPE keypress will clear the input + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {String} [opts.noMatches] The no matches found label + */ + class AutocompletePrompt extends Prompt { + constructor(opts={}) { + super(opts); + this.msg = opts.message; + this.suggest = opts.suggest; + this.choices = opts.choices; + this.initial = typeof opts.initial === 'number' + ? opts.initial + : getIndex(opts.choices, opts.initial); + this.select = this.initial || opts.cursor || 0; + this.i18n = { noMatches: opts.noMatches || 'no matches found' }; + this.fallback = opts.fallback || this.initial; + this.clearFirst = opts.clearFirst || false; + this.suggestions = []; + this.input = ''; + this.limit = opts.limit || 10; + this.cursor = 0; + this.transform = style.render(opts.style); + this.scale = this.transform.scale; + this.render = this.render.bind(this); + this.complete = this.complete.bind(this); + this.clear = clear('', this.out.columns); + this.complete(this.render); + this.render(); + } + + set fallback(fb) { + this._fb = Number.isSafeInteger(parseInt(fb)) ? parseInt(fb) : fb; + } + + get fallback() { + let choice; + if (typeof this._fb === 'number') + choice = this.choices[this._fb]; + else if (typeof this._fb === 'string') + choice = { title: this._fb }; + return choice || this._fb || { title: this.i18n.noMatches }; + } + + moveSelect(i) { + this.select = i; + if (this.suggestions.length > 0) + this.value = getVal(this.suggestions, i); + else this.value = this.fallback.value; + this.fire(); + } + + async complete(cb) { + const p = (this.completing = this.suggest(this.input, this.choices)); + const suggestions = await p; + + if (this.completing !== p) return; + this.suggestions = suggestions + .map((s, i, arr) => ({ title: getTitle(arr, i), value: getVal(arr, i), description: s.description })); + this.completing = false; + const l = Math.max(suggestions.length - 1, 0); + this.moveSelect(Math.min(l, this.select)); + + cb && cb(); + } + + reset() { + this.input = ''; + this.complete(() => { + this.moveSelect(this.initial !== void 0 ? this.initial : 0); + this.render(); + }); + this.render(); + } + + exit() { + if (this.clearFirst && this.input.length > 0) { + this.reset(); + } else { + this.done = this.exited = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + } + + abort() { + this.done = this.aborted = true; + this.exited = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + this.done = true; + this.aborted = this.exited = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + _(c, key) { + let s1 = this.input.slice(0, this.cursor); + let s2 = this.input.slice(this.cursor); + this.input = `${s1}${c}${s2}`; + this.cursor = s1.length+1; + this.complete(this.render); + this.render(); + } + + delete() { + if (this.cursor === 0) return this.bell(); + let s1 = this.input.slice(0, this.cursor-1); + let s2 = this.input.slice(this.cursor); + this.input = `${s1}${s2}`; + this.complete(this.render); + this.cursor = this.cursor-1; + this.render(); + } + + deleteForward() { + if(this.cursor*this.scale >= this.rendered.length) return this.bell(); + let s1 = this.input.slice(0, this.cursor); + let s2 = this.input.slice(this.cursor+1); + this.input = `${s1}${s2}`; + this.complete(this.render); + this.render(); + } + + first() { + this.moveSelect(0); + this.render(); + } + + last() { + this.moveSelect(this.suggestions.length - 1); + this.render(); + } + + up() { + if (this.select === 0) { + this.moveSelect(this.suggestions.length - 1); + } else { + this.moveSelect(this.select - 1); + } + this.render(); + } + + down() { + if (this.select === this.suggestions.length - 1) { + this.moveSelect(0); + } else { + this.moveSelect(this.select + 1); + } + this.render(); + } + + next() { + if (this.select === this.suggestions.length - 1) { + this.moveSelect(0); + } else this.moveSelect(this.select + 1); + this.render(); + } + + nextPage() { + this.moveSelect(Math.min(this.select + this.limit, this.suggestions.length - 1)); + this.render(); + } + + prevPage() { + this.moveSelect(Math.max(this.select - this.limit, 0)); + this.render(); + } + + left() { + if (this.cursor <= 0) return this.bell(); + this.cursor = this.cursor-1; + this.render(); + } + + right() { + if (this.cursor*this.scale >= this.rendered.length) return this.bell(); + this.cursor = this.cursor+1; + this.render(); + } + + renderOption(v, hovered, isStart, isEnd) { + let desc; + let prefix = isStart ? figures.arrowUp : isEnd ? figures.arrowDown : ' '; + let title = hovered ? color.cyan().underline(v.title) : v.title; + prefix = (hovered ? color.cyan(figures.pointer) + ' ' : ' ') + prefix; + if (v.description) { + desc = ` - ${v.description}`; + if (prefix.length + title.length + desc.length >= this.out.columns + || v.description.split(/\r?\n/).length > 1) { + desc = '\n' + wrap(v.description, { margin: 3, width: this.out.columns }); + } + } + return prefix + ' ' + title + color.gray(desc || ''); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); + + let { startIndex, endIndex } = entriesToDisplay(this.select, this.choices.length, this.limit); + + this.outputText = [ + style.symbol(this.done, this.aborted, this.exited), + color.bold(this.msg), + style.delimiter(this.completing), + this.done && this.suggestions[this.select] + ? this.suggestions[this.select].title + : this.rendered = this.transform.render(this.input) + ].join(' '); + + if (!this.done) { + const suggestions = this.suggestions + .slice(startIndex, endIndex) + .map((item, i) => this.renderOption(item, + this.select === i + startIndex, + i === 0 && startIndex > 0, + i + startIndex === endIndex - 1 && endIndex < this.choices.length)) + .join('\n'); + this.outputText += `\n` + (suggestions || color.gray(this.fallback.title)); + } + + this.out.write(erase.line + cursor.to(0) + this.outputText); + } + } + + autocomplete = AutocompletePrompt; + return autocomplete; +} + +var autocompleteMultiselect; +var hasRequiredAutocompleteMultiselect; + +function requireAutocompleteMultiselect () { + if (hasRequiredAutocompleteMultiselect) return autocompleteMultiselect; + hasRequiredAutocompleteMultiselect = 1; + + const color = requireKleur(); + const { cursor } = requireSrc(); + const MultiselectPrompt = requireMultiselect(); + const { clear, style, figures } = requireUtil(); + /** + * MultiselectPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Array} opts.choices Array of choice objects + * @param {String} [opts.hint] Hint to display + * @param {String} [opts.warn] Hint shown for disabled choices + * @param {Number} [opts.max] Max choices + * @param {Number} [opts.cursor=0] Cursor start position + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ + class AutocompleteMultiselectPrompt extends MultiselectPrompt { + constructor(opts={}) { + opts.overrideRender = true; + super(opts); + this.inputValue = ''; + this.clear = clear('', this.out.columns); + this.filteredOptions = this.value; + this.render(); + } + + last() { + this.cursor = this.filteredOptions.length - 1; + this.render(); + } + next() { + this.cursor = (this.cursor + 1) % this.filteredOptions.length; + this.render(); + } + + up() { + if (this.cursor === 0) { + this.cursor = this.filteredOptions.length - 1; + } else { + this.cursor--; + } + this.render(); + } + + down() { + if (this.cursor === this.filteredOptions.length - 1) { + this.cursor = 0; + } else { + this.cursor++; + } + this.render(); + } + + left() { + this.filteredOptions[this.cursor].selected = false; + this.render(); + } + + right() { + if (this.value.filter(e => e.selected).length >= this.maxChoices) return this.bell(); + this.filteredOptions[this.cursor].selected = true; + this.render(); + } + + delete() { + if (this.inputValue.length) { + this.inputValue = this.inputValue.substr(0, this.inputValue.length - 1); + this.updateFilteredOptions(); + } + } + + updateFilteredOptions() { + const currentHighlight = this.filteredOptions[this.cursor]; + this.filteredOptions = this.value + .filter(v => { + if (this.inputValue) { + if (typeof v.title === 'string') { + if (v.title.toLowerCase().includes(this.inputValue.toLowerCase())) { + return true; + } + } + if (typeof v.value === 'string') { + if (v.value.toLowerCase().includes(this.inputValue.toLowerCase())) { + return true; + } + } + return false; + } + return true; + }); + const newHighlightIndex = this.filteredOptions.findIndex(v => v === currentHighlight); + this.cursor = newHighlightIndex < 0 ? 0 : newHighlightIndex; + this.render(); + } + + handleSpaceToggle() { + const v = this.filteredOptions[this.cursor]; + + if (v.selected) { + v.selected = false; + this.render(); + } else if (v.disabled || this.value.filter(e => e.selected).length >= this.maxChoices) { + return this.bell(); + } else { + v.selected = true; + this.render(); + } + } + + handleInputChange(c) { + this.inputValue = this.inputValue + c; + this.updateFilteredOptions(); + } + + _(c, key) { + if (c === ' ') { + this.handleSpaceToggle(); + } else { + this.handleInputChange(c); + } + } + + renderInstructions() { + if (this.instructions === undefined || this.instructions) { + if (typeof this.instructions === 'string') { + return this.instructions; + } + return ` +Instructions: + ${figures.arrowUp}/${figures.arrowDown}: Highlight option + ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection + [a,b,c]/delete: Filter choices + enter/return: Complete answer +`; + } + return ''; + } + + renderCurrentInput() { + return ` +Filtered results for: ${this.inputValue ? this.inputValue : color.gray('Enter something to filter')}\n`; + } + + renderOption(cursor, v, i) { + let title; + if (v.disabled) title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title); + else title = cursor === i ? color.cyan().underline(v.title) : v.title; + return (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + title + } + + renderDoneOrInstructions() { + if (this.done) { + return this.value + .filter(e => e.selected) + .map(v => v.title) + .join(', '); + } + + const output = [color.gray(this.hint), this.renderInstructions(), this.renderCurrentInput()]; + + if (this.filteredOptions.length && this.filteredOptions[this.cursor].disabled) { + output.push(color.yellow(this.warn)); + } + return output.join(' '); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + super.render(); + + // print prompt + + let prompt = [ + style.symbol(this.done, this.aborted), + color.bold(this.msg), + style.delimiter(false), + this.renderDoneOrInstructions() + ].join(' '); + + if (this.showMinError) { + prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`); + this.showMinError = false; + } + prompt += this.renderOptions(this.filteredOptions); + + this.out.write(this.clear + prompt); + this.clear = clear(prompt, this.out.columns); + } + } + + autocompleteMultiselect = AutocompleteMultiselectPrompt; + return autocompleteMultiselect; +} + +var confirm; +var hasRequiredConfirm; + +function requireConfirm () { + if (hasRequiredConfirm) return confirm; + hasRequiredConfirm = 1; + const color = requireKleur(); + const Prompt = requirePrompt(); + const { style, clear } = requireUtil(); + const { erase, cursor } = requireSrc(); + + /** + * ConfirmPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Boolean} [opts.initial] Default value (true/false) + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + * @param {String} [opts.yes] The "Yes" label + * @param {String} [opts.yesOption] The "Yes" option when choosing between yes/no + * @param {String} [opts.no] The "No" label + * @param {String} [opts.noOption] The "No" option when choosing between yes/no + */ + class ConfirmPrompt extends Prompt { + constructor(opts={}) { + super(opts); + this.msg = opts.message; + this.value = opts.initial; + this.initialValue = !!opts.initial; + this.yesMsg = opts.yes || 'yes'; + this.yesOption = opts.yesOption || '(Y/n)'; + this.noMsg = opts.no || 'no'; + this.noOption = opts.noOption || '(y/N)'; + this.render(); + } + + reset() { + this.value = this.initialValue; + this.fire(); + this.render(); + } + + exit() { + this.abort(); + } + + abort() { + this.done = this.aborted = true; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + submit() { + this.value = this.value || false; + this.done = true; + this.aborted = false; + this.fire(); + this.render(); + this.out.write('\n'); + this.close(); + } + + _(c, key) { + if (c.toLowerCase() === 'y') { + this.value = true; + return this.submit(); + } + if (c.toLowerCase() === 'n') { + this.value = false; + return this.submit(); + } + return this.bell(); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + else this.out.write(clear(this.outputText, this.out.columns)); + super.render(); + + this.outputText = [ + style.symbol(this.done, this.aborted), + color.bold(this.msg), + style.delimiter(this.done), + this.done ? (this.value ? this.yesMsg : this.noMsg) + : color.gray(this.initialValue ? this.yesOption : this.noOption) + ].join(' '); + + this.out.write(erase.line + cursor.to(0) + this.outputText); + } + } + + confirm = ConfirmPrompt; + return confirm; +} + +var elements; +var hasRequiredElements; + +function requireElements () { + if (hasRequiredElements) return elements; + hasRequiredElements = 1; + + elements = { + TextPrompt: requireText(), + SelectPrompt: requireSelect(), + TogglePrompt: requireToggle(), + DatePrompt: requireDate(), + NumberPrompt: requireNumber(), + MultiselectPrompt: requireMultiselect(), + AutocompletePrompt: requireAutocomplete(), + AutocompleteMultiselectPrompt: requireAutocompleteMultiselect(), + ConfirmPrompt: requireConfirm() + }; + return elements; +} + +var hasRequiredPrompts$1; + +function requirePrompts$1 () { + if (hasRequiredPrompts$1) return prompts$1; + hasRequiredPrompts$1 = 1; + (function (exports) { + const $ = exports; + const el = requireElements(); + const noop = v => v; + + function toPrompt(type, args, opts={}) { + return new Promise((res, rej) => { + const p = new el[type](args); + const onAbort = opts.onAbort || noop; + const onSubmit = opts.onSubmit || noop; + const onExit = opts.onExit || noop; + p.on('state', args.onState || noop); + p.on('submit', x => res(onSubmit(x))); + p.on('exit', x => res(onExit(x))); + p.on('abort', x => rej(onAbort(x))); + }); + } + + /** + * Text prompt + * @param {string} args.message Prompt message to display + * @param {string} [args.initial] Default string value + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {function} [args.onState] On state change callback + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.text = args => toPrompt('TextPrompt', args); + + /** + * Password prompt with masked input + * @param {string} args.message Prompt message to display + * @param {string} [args.initial] Default string value + * @param {function} [args.onState] On state change callback + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.password = args => { + args.style = 'password'; + return $.text(args); + }; + + /** + * Prompt where input is invisible, like sudo + * @param {string} args.message Prompt message to display + * @param {string} [args.initial] Default string value + * @param {function} [args.onState] On state change callback + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.invisible = args => { + args.style = 'invisible'; + return $.text(args); + }; + + /** + * Number prompt + * @param {string} args.message Prompt message to display + * @param {number} args.initial Default number value + * @param {function} [args.onState] On state change callback + * @param {number} [args.max] Max value + * @param {number} [args.min] Min value + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {Boolean} [opts.float=false] Parse input as floats + * @param {Number} [opts.round=2] Round floats to x decimals + * @param {Number} [opts.increment=1] Number to increment by when using arrow-keys + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.number = args => toPrompt('NumberPrompt', args); + + /** + * Date prompt + * @param {string} args.message Prompt message to display + * @param {number} args.initial Default number value + * @param {function} [args.onState] On state change callback + * @param {number} [args.max] Max value + * @param {number} [args.min] Min value + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {Boolean} [opts.float=false] Parse input as floats + * @param {Number} [opts.round=2] Round floats to x decimals + * @param {Number} [opts.increment=1] Number to increment by when using arrow-keys + * @param {function} [args.validate] Function to validate user input + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.date = args => toPrompt('DatePrompt', args); + + /** + * Classic yes/no prompt + * @param {string} args.message Prompt message to display + * @param {boolean} [args.initial=false] Default value + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.confirm = args => toPrompt('ConfirmPrompt', args); + + /** + * List prompt, split intput string by `seperator` + * @param {string} args.message Prompt message to display + * @param {string} [args.initial] Default string value + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {string} [args.separator] String separator + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input, in form of an `Array` + */ + $.list = args => { + const sep = args.separator || ','; + return toPrompt('TextPrompt', args, { + onSubmit: str => str.split(sep).map(s => s.trim()) + }); + }; + + /** + * Toggle/switch prompt + * @param {string} args.message Prompt message to display + * @param {boolean} [args.initial=false] Default value + * @param {string} [args.active="on"] Text for `active` state + * @param {string} [args.inactive="off"] Text for `inactive` state + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.toggle = args => toPrompt('TogglePrompt', args); + + /** + * Interactive select prompt + * @param {string} args.message Prompt message to display + * @param {Array} args.choices Array of choices objects `[{ title, value }, ...]` + * @param {number} [args.initial] Index of default value + * @param {String} [args.hint] Hint to display + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.select = args => toPrompt('SelectPrompt', args); + + /** + * Interactive multi-select / autocompleteMultiselect prompt + * @param {string} args.message Prompt message to display + * @param {Array} args.choices Array of choices objects `[{ title, value, [selected] }, ...]` + * @param {number} [args.max] Max select + * @param {string} [args.hint] Hint to display user + * @param {Number} [args.cursor=0] Cursor start position + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.multiselect = args => { + args.choices = [].concat(args.choices || []); + const toSelected = items => items.filter(item => item.selected).map(item => item.value); + return toPrompt('MultiselectPrompt', args, { + onAbort: toSelected, + onSubmit: toSelected + }); + }; + + $.autocompleteMultiselect = args => { + args.choices = [].concat(args.choices || []); + const toSelected = items => items.filter(item => item.selected).map(item => item.value); + return toPrompt('AutocompleteMultiselectPrompt', args, { + onAbort: toSelected, + onSubmit: toSelected + }); + }; + + const byTitle = (input, choices) => Promise.resolve( + choices.filter(item => item.title.slice(0, input.length).toLowerCase() === input.toLowerCase()) + ); + + /** + * Interactive auto-complete prompt + * @param {string} args.message Prompt message to display + * @param {Array} args.choices Array of auto-complete choices objects `[{ title, value }, ...]` + * @param {Function} [args.suggest] Function to filter results based on user input. Defaults to sort by `title` + * @param {number} [args.limit=10] Max number of results to show + * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') + * @param {String} [args.initial] Index of the default value + * @param {boolean} [opts.clearFirst] The first ESCAPE keypress will clear the input + * @param {String} [args.fallback] Fallback message - defaults to initial value + * @param {function} [args.onState] On state change callback + * @param {Stream} [args.stdin] The Readable stream to listen to + * @param {Stream} [args.stdout] The Writable stream to write readline data to + * @returns {Promise} Promise with user input + */ + $.autocomplete = args => { + args.suggest = args.suggest || byTitle; + args.choices = [].concat(args.choices || []); + return toPrompt('AutocompletePrompt', args); + }; + } (prompts$1)); + return prompts$1; +} + +var lib; +var hasRequiredLib; + +function requireLib () { + if (hasRequiredLib) return lib; + hasRequiredLib = 1; + + const prompts = requirePrompts$1(); + + const passOn = ['suggest', 'format', 'onState', 'validate', 'onRender', 'type']; + const noop = () => {}; + + /** + * Prompt for a series of questions + * @param {Array|Object} questions Single question object or Array of question objects + * @param {Function} [onSubmit] Callback function called on prompt submit + * @param {Function} [onCancel] Callback function called on cancel/abort + * @returns {Object} Object with values from user input + */ + async function prompt(questions=[], { onSubmit=noop, onCancel=noop }={}) { + const answers = {}; + const override = prompt._override || {}; + questions = [].concat(questions); + let answer, question, quit, name, type, lastPrompt; + + const getFormattedAnswer = async (question, answer, skipValidation = false) => { + if (!skipValidation && question.validate && question.validate(answer) !== true) { + return; + } + return question.format ? await question.format(answer, answers) : answer + }; + + for (question of questions) { + ({ name, type } = question); + + // evaluate type first and skip if type is a falsy value + if (typeof type === 'function') { + type = await type(answer, { ...answers }, question); + question['type'] = type; + } + if (!type) continue; + + // if property is a function, invoke it unless it's a special function + for (let key in question) { + if (passOn.includes(key)) continue; + let value = question[key]; + question[key] = typeof value === 'function' ? await value(answer, { ...answers }, lastPrompt) : value; + } + + lastPrompt = question; + + if (typeof question.message !== 'string') { + throw new Error('prompt message is required'); + } + + // update vars in case they changed + ({ name, type } = question); + + if (prompts[type] === void 0) { + throw new Error(`prompt type (${type}) is not defined`); + } + + if (override[question.name] !== undefined) { + answer = await getFormattedAnswer(question, override[question.name]); + if (answer !== undefined) { + answers[name] = answer; + continue; + } + } + + try { + // Get the injected answer if there is one or prompt the user + answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : await prompts[type](question); + answers[name] = answer = await getFormattedAnswer(question, answer, true); + quit = await onSubmit(question, answer, answers); + } catch (err) { + quit = !(await onCancel(question, answers)); + } + + if (quit) return answers; + } + + return answers; + } + + function getInjectedAnswer(injected, deafultValue) { + const answer = injected.shift(); + if (answer instanceof Error) { + throw answer; + } + + return (answer === undefined) ? deafultValue : answer; + } + + function inject(answers) { + prompt._injected = (prompt._injected || []).concat(answers); + } + + function override(answers) { + prompt._override = Object.assign({}, answers); + } + + lib = Object.assign(prompt, { prompt, prompts, inject, override }); + return lib; +} + +var prompts; +var hasRequiredPrompts; + +function requirePrompts () { + if (hasRequiredPrompts) return prompts; + hasRequiredPrompts = 1; + function isNodeLT(tar) { + tar = (Array.isArray(tar) ? tar : tar.split('.')).map(Number); + let i=0, src=process.versions.node.split('.').map(Number); + for (; i < tar.length; i++) { + if (src[i] > tar[i]) return false; + if (tar[i] > src[i]) return true; + } + return false; + } + + prompts = + isNodeLT('8.6.0') + ? requireDist() + : requireLib(); + return prompts; +} + +var promptsExports = requirePrompts(); +var prompt = /*@__PURE__*/getDefaultExportFromCjs(promptsExports); + +var index = /*#__PURE__*/_mergeNamespaces({ + __proto__: null, + default: prompt +}, [promptsExports]); + +export { findUp as f, index as i, prompt as p }; diff --git a/node_modules/vitest/dist/chunks/inspector.C914Efll.js b/node_modules/vitest/dist/chunks/inspector.C914Efll.js new file mode 100644 index 0000000000..0a6a02a07c --- /dev/null +++ b/node_modules/vitest/dist/chunks/inspector.C914Efll.js @@ -0,0 +1,57 @@ +import { createRequire } from 'node:module'; +import { pathToFileURL } from 'node:url'; + +const __require = createRequire(import.meta.url); +let inspector; +let session; +/** +* Enables debugging inside `worker_threads` and `child_process`. +* Should be called as early as possible when worker/process has been set up. +*/ +function setupInspect(ctx) { + const config = ctx.config; + const isEnabled = config.inspector.enabled; + if (isEnabled) { + inspector = __require("node:inspector"); + // Inspector may be open already if "isolate: false" is used + const isOpen = inspector.url() !== void 0; + if (!isOpen) { + inspector.open(config.inspector.port, config.inspector.host, config.inspector.waitForDebugger); + if (config.inspectBrk) { + const firstTestFile = typeof ctx.files[0] === "string" ? ctx.files[0] : ctx.files[0].filepath; + // Stop at first test file + if (firstTestFile) { + session = new inspector.Session(); + session.connect(); + session.post("Debugger.enable"); + session.post("Debugger.setBreakpointByUrl", { + lineNumber: 0, + url: pathToFileURL(firstTestFile) + }); + } + } + } + } + const keepOpen = shouldKeepOpen(config); + return function cleanup() { + if (isEnabled && !keepOpen && inspector) { + inspector.close(); + session?.disconnect(); + } + }; +} +function closeInspector(config) { + const keepOpen = shouldKeepOpen(config); + if (inspector && !keepOpen) { + inspector.close(); + session?.disconnect(); + } +} +function shouldKeepOpen(config) { + // In watch mode the inspector can persist re-runs if isolation is disabled and a single worker is used + const isIsolatedSingleThread = config.pool === "threads" && config.poolOptions?.threads?.isolate === false && config.poolOptions?.threads?.singleThread; + const isIsolatedSingleFork = config.pool === "forks" && config.poolOptions?.forks?.isolate === false && config.poolOptions?.forks?.singleFork; + return config.watch && (isIsolatedSingleFork || isIsolatedSingleThread); +} + +export { closeInspector as c, setupInspect as s }; diff --git a/node_modules/vitest/dist/chunks/mocker.d.BE_2ls6u.d.ts b/node_modules/vitest/dist/chunks/mocker.d.BE_2ls6u.d.ts new file mode 100644 index 0000000000..e5d0dc26a6 --- /dev/null +++ b/node_modules/vitest/dist/chunks/mocker.d.BE_2ls6u.d.ts @@ -0,0 +1,17 @@ +import { MockedModuleType } from '@vitest/mocker'; + +type Promisable = T | Promise; +type MockFactoryWithHelper = (importOriginal: () => Promise) => Promisable>; +type MockFactory = () => any; +interface MockOptions { + spy?: boolean; +} +interface PendingSuiteMock { + id: string; + importer: string; + action: "mock" | "unmock"; + type?: MockedModuleType; + factory?: MockFactory; +} + +export type { MockFactoryWithHelper as M, PendingSuiteMock as P, MockOptions as a, MockFactory as b }; diff --git a/node_modules/vitest/dist/chunks/node.fjCdwEIl.js b/node_modules/vitest/dist/chunks/node.fjCdwEIl.js new file mode 100644 index 0000000000..b8877ea9bd --- /dev/null +++ b/node_modules/vitest/dist/chunks/node.fjCdwEIl.js @@ -0,0 +1,15 @@ +import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment'; +import { g as getWorkerState } from './utils.XdZDrNZV.js'; +import '@vitest/utils'; + +class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment { + getHeader() { + return `// Vitest Snapshot v${this.getVersion()}, https://vitest.dev/guide/snapshot.html`; + } + resolvePath(filepath) { + const rpc = getWorkerState().rpc; + return rpc.resolveSnapshotPath(filepath); + } +} + +export { VitestNodeSnapshotEnvironment }; diff --git a/node_modules/vitest/dist/chunks/reporters.d.BFLkQcL6.d.ts b/node_modules/vitest/dist/chunks/reporters.d.BFLkQcL6.d.ts new file mode 100644 index 0000000000..c304fbcf83 --- /dev/null +++ b/node_modules/vitest/dist/chunks/reporters.d.BFLkQcL6.d.ts @@ -0,0 +1,3155 @@ +import { Task, TaskMeta, Suite, File, TestAnnotation, ImportDuration, TaskResultPack, TaskEventPack, SequenceSetupFiles, SequenceHooks, CancelReason } from '@vitest/runner'; +import { b as Awaitable, U as UserConsoleLog, c as Arrayable$1, A as AfterSuiteRunMeta, L as LabelColor, f as EnvironmentOptions, P as ProvidedContext } from './environment.d.cL3nLXbE.js'; +import { ParsedStack, TestError, SerializedError, ErrorWithDiff, Arrayable, Awaitable as Awaitable$1 } from '@vitest/utils'; +import { Writable } from 'node:stream'; +import { TransformResult as TransformResult$1, UserConfig as UserConfig$1, DepOptimizationConfig, ServerOptions, ConfigEnv, AliasOptions, ViteDevServer, ModuleNode } from 'vite'; +import { Console } from 'node:console'; +import { MockedModule } from '@vitest/mocker'; +import { StackTraceParserOptions } from '@vitest/utils/source-map'; +import { T as TestExecutionMethod } from './worker.d.1GmBbd7G.js'; +import { a as SerializedConfig, F as FakeTimerInstallOpts } from './config.d.D2ROskhv.js'; +import { PrettyFormatOptions } from '@vitest/pretty-format'; +import { SnapshotSummary, SnapshotStateOptions } from '@vitest/snapshot'; +import { SerializedDiffOptions } from '@vitest/utils/diff'; +import { ViteNodeServerOptions } from 'vite-node'; +import * as chai from 'chai'; +import { B as BenchmarkResult } from './benchmark.d.BwvBVTda.js'; +import { a as RuntimeCoverageProviderModule } from './coverage.d.S9RMNXIe.js'; +import { SnapshotManager } from '@vitest/snapshot/manager'; +import { Stats } from 'node:fs'; + +declare class TypeCheckError extends Error { + message: string; + stacks: ParsedStack[]; + name: string; + constructor(message: string, stacks: ParsedStack[]); +} + +interface ErrorOptions { + type?: string; + fullStack?: boolean; + project?: TestProject; + verbose?: boolean; + screenshotPaths?: string[]; + task?: Task; + showCodeFrame?: boolean; +} +type Listener = () => void; +declare class Logger { + ctx: Vitest; + outputStream: NodeJS.WriteStream | Writable; + errorStream: NodeJS.WriteStream | Writable; + private _clearScreenPending; + private _highlights; + private cleanupListeners; + console: Console; + constructor(ctx: Vitest, outputStream?: NodeJS.WriteStream | Writable, errorStream?: NodeJS.WriteStream | Writable); + log(...args: any[]): void; + error(...args: any[]): void; + warn(...args: any[]): void; + clearFullScreen(message?: string): void; + clearScreen(message: string, force?: boolean): void; + private _clearScreen; + printError(err: unknown, options?: ErrorOptions): void; + deprecate(message: string): void; + clearHighlightCache(filename?: string): void; + highlight(filename: string, source: string): string; + printNoTestFound(filters?: string[]): void; + printBanner(): void; + printBrowserBanner(project: TestProject): void; + printUnhandledErrors(errors: unknown[]): void; + printSourceTypeErrors(errors: TypeCheckError[]): void; + getColumns(): number; + onTerminalCleanup(listener: Listener): void; + private addCleanupListeners; + private registerUnhandledRejection; +} + +type SerializedTestSpecification = [project: { + name: string | undefined + root: string +}, file: string, options: { + pool: string + testLines?: number[] | undefined +}]; + +declare class ReportedTaskImplementation { + /** + * The project associated with the test or suite. + */ + readonly project: TestProject; + /** + * Unique identifier. + * This ID is deterministic and will be the same for the same test across multiple runs. + * The ID is based on the project name, module url and test order. + */ + readonly id: string; + /** + * Location in the module where the test or suite is defined. + */ + readonly location: { + line: number + column: number + } | undefined; + /** + * Checks if the test did not fail the suite. + * If the test is not finished yet or was skipped, it will return `true`. + */ + ok(): boolean; + /** + * Custom metadata that was attached to the test during its execution. + */ + meta(): TaskMeta; +} +declare class TestCase extends ReportedTaskImplementation { + #private; + readonly type = "test"; + /** + * Direct reference to the test module where the test or suite is defined. + */ + readonly module: TestModule; + /** + * Name of the test. + */ + readonly name: string; + /** + * Options that the test was initiated with. + */ + readonly options: TaskOptions; + /** + * Parent suite. If the test was called directly inside the module, the parent will be the module itself. + */ + readonly parent: TestSuite | TestModule; + /** + * Full name of the test including all parent suites separated with `>`. + */ + get fullName(): string; + /** + * Test results. + * - **pending**: Test was collected, but didn't finish running yet. + * - **passed**: Test passed successfully + * - **failed**: Test failed to execute + * - **skipped**: Test was skipped during collection or dynamically with `ctx.skip()`. + */ + result(): TestResult; + /** + * Test annotations added via the `task.annotate` API during the test execution. + */ + annotations(): ReadonlyArray; + /** + * Useful information about the test like duration, memory usage, etc. + * Diagnostic is only available after the test has finished. + */ + diagnostic(): TestDiagnostic | undefined; +} +declare class TestCollection { + #private; + constructor(task: Suite | File, project: TestProject); + /** + * Returns the test or suite at a specific index. + */ + at(index: number): TestCase | TestSuite | undefined; + /** + * The number of tests and suites in the collection. + */ + get size(): number; + /** + * Returns the collection in array form for easier manipulation. + */ + array(): (TestCase | TestSuite)[]; + /** + * Filters all tests that are part of this collection and its children. + */ + allTests(state?: TestState): Generator; + /** + * Filters only the tests that are part of this collection. + */ + tests(state?: TestState): Generator; + /** + * Filters only the suites that are part of this collection. + */ + suites(): Generator; + /** + * Filters all suites that are part of this collection and its children. + */ + allSuites(): Generator; + [Symbol.iterator](): Generator; +} + +type ReportedHookContext = { + readonly name: "beforeAll" | "afterAll" + readonly entity: TestSuite | TestModule +} | { + readonly name: "beforeEach" | "afterEach" + readonly entity: TestCase +}; +declare abstract class SuiteImplementation extends ReportedTaskImplementation { + /** + * Collection of suites and tests that are part of this suite. + */ + readonly children: TestCollection; + /** + * Errors that happened outside of the test run during collection, like syntax errors. + */ + errors(): SerializedError[]; +} +declare class TestSuite extends SuiteImplementation { + #private; + readonly type = "suite"; + /** + * Name of the test or the suite. + */ + readonly name: string; + /** + * Direct reference to the test module where the test or suite is defined. + */ + readonly module: TestModule; + /** + * Parent suite. If suite was called directly inside the module, the parent will be the module itself. + */ + readonly parent: TestSuite | TestModule; + /** + * Options that suite was initiated with. + */ + readonly options: TaskOptions; + /** + * Checks if the suite has any failed tests. + * This will also return `false` if suite failed during collection. + */ + ok: () => boolean; + /** + * The meta information attached to the suite during its collection or execution. + */ + meta: () => TaskMeta; + /** + * Checks the running state of the suite. + */ + state(): TestSuiteState; + /** + * Full name of the suite including all parent suites separated with `>`. + */ + get fullName(): string; +} +declare class TestModule extends SuiteImplementation { + readonly location: undefined; + readonly type = "module"; + /** + * This is usually an absolute UNIX file path. + * It can be a virtual ID if the file is not on the disk. + * This value corresponds to the ID in the Vite's module graph. + */ + readonly moduleId: string; + /** + * Checks the running state of the test file. + */ + state(): TestModuleState; + /** + * Checks if the module has any failed tests. + * This will also return `false` if module failed during collection. + */ + ok: () => boolean; + /** + * The meta information attached to the module during its collection or execution. + */ + meta: () => TaskMeta; + /** + * Useful information about the module like duration, memory usage, etc. + * If the module was not executed yet, all diagnostic values will return `0`. + */ + diagnostic(): ModuleDiagnostic; +} +interface TaskOptions { + readonly each: boolean | undefined; + readonly fails: boolean | undefined; + readonly concurrent: boolean | undefined; + readonly shuffle: boolean | undefined; + readonly retry: number | undefined; + readonly repeats: number | undefined; + readonly mode: "run" | "only" | "skip" | "todo"; +} +type TestSuiteState = "skipped" | "pending" | "failed" | "passed"; +type TestModuleState = TestSuiteState | "queued"; +type TestState = TestResult["state"]; +type TestResult = TestResultPassed | TestResultFailed | TestResultSkipped | TestResultPending; +interface TestResultPending { + /** + * The test was collected, but didn't finish running yet. + */ + readonly state: "pending"; + /** + * Pending tests have no errors. + */ + readonly errors: undefined; +} +interface TestResultPassed { + /** + * The test passed successfully. + */ + readonly state: "passed"; + /** + * Errors that were thrown during the test execution. + * + * **Note**: If test was retried successfully, errors will still be reported. + */ + readonly errors: ReadonlyArray | undefined; +} +interface TestResultFailed { + /** + * The test failed to execute. + */ + readonly state: "failed"; + /** + * Errors that were thrown during the test execution. + */ + readonly errors: ReadonlyArray; +} +interface TestResultSkipped { + /** + * The test was skipped with `only` (on another test), `skip` or `todo` flag. + * You can see which one was used in the `options.mode` option. + */ + readonly state: "skipped"; + /** + * Skipped tests have no errors. + */ + readonly errors: undefined; + /** + * A custom note passed down to `ctx.skip(note)`. + */ + readonly note: string | undefined; +} +interface TestDiagnostic { + /** + * If the duration of the test is above `slowTestThreshold`. + */ + readonly slow: boolean; + /** + * The amount of memory used by the test in bytes. + * This value is only available if the test was executed with `logHeapUsage` flag. + */ + readonly heap: number | undefined; + /** + * The time it takes to execute the test in ms. + */ + readonly duration: number; + /** + * The time in ms when the test started. + */ + readonly startTime: number; + /** + * The amount of times the test was retried. + */ + readonly retryCount: number; + /** + * The amount of times the test was repeated as configured by `repeats` option. + * This value can be lower if the test failed during the repeat and no `retry` is configured. + */ + readonly repeatCount: number; + /** + * If test passed on a second retry. + */ + readonly flaky: boolean; +} +interface ModuleDiagnostic { + /** + * The time it takes to import and initiate an environment. + */ + readonly environmentSetupDuration: number; + /** + * The time it takes Vitest to setup test harness (runner, mocks, etc.). + */ + readonly prepareDuration: number; + /** + * The time it takes to import the test module. + * This includes importing everything in the module and executing suite callbacks. + */ + readonly collectDuration: number; + /** + * The time it takes to import the setup module. + */ + readonly setupDuration: number; + /** + * Accumulated duration of all tests and hooks in the module. + */ + readonly duration: number; + /** + * The amount of memory used by the test module in bytes. + * This value is only available if the test was executed with `logHeapUsage` flag. + */ + readonly heap: number | undefined; + /** + * The time spent importing every non-externalized dependency that Vitest has processed. + */ + readonly importDurations: Record; +} + +type BuiltinPool = "browser" | "threads" | "forks" | "vmThreads" | "vmForks" | "typescript"; +type Pool = BuiltinPool | (string & {}); +interface PoolOptions extends Record { + /** + * Run tests in `node:worker_threads`. + * + * Test isolation (when enabled) is done by spawning a new thread for each test file. + * + * This pool is used by default. + */ + threads?: ThreadsOptions & WorkerContextOptions; + /** + * Run tests in `node:child_process` using [`fork()`](https://nodejs.org/api/child_process.html#child_processforkmodulepath-args-options) + * + * Test isolation (when enabled) is done by spawning a new child process for each test file. + */ + forks?: ForksOptions & WorkerContextOptions; + /** + * Run tests in isolated `node:vm`. + * Test files are run parallel using `node:worker_threads`. + * + * This makes tests run faster, but VM module is unstable. Your tests might leak memory. + */ + vmThreads?: ThreadsOptions & VmOptions; + /** + * Run tests in isolated `node:vm`. + * + * Test files are run parallel using `node:child_process` [`fork()`](https://nodejs.org/api/child_process.html#child_processforkmodulepath-args-options) + * + * This makes tests run faster, but VM module is unstable. Your tests might leak memory. + */ + vmForks?: ForksOptions & VmOptions; +} +interface ResolvedPoolOptions extends PoolOptions { + threads?: ResolvedThreadsOptions & WorkerContextOptions; + forks?: ResolvedForksOptions & WorkerContextOptions; + vmThreads?: ResolvedThreadsOptions & VmOptions; + vmForks?: ResolvedForksOptions & VmOptions; +} +interface ThreadsOptions { + /** Minimum amount of threads to use */ + minThreads?: number | string; + /** Maximum amount of threads to use */ + maxThreads?: number | string; + /** + * Run tests inside a single thread. + * + * @default false + */ + singleThread?: boolean; + /** + * Use Atomics to synchronize threads + * + * This can improve performance in some cases, but might cause segfault in older Node versions. + * + * @default false + */ + useAtomics?: boolean; +} +interface ResolvedThreadsOptions extends ThreadsOptions { + minThreads?: number; + maxThreads?: number; +} +interface ForksOptions { + /** Minimum amount of child processes to use */ + minForks?: number | string; + /** Maximum amount of child processes to use */ + maxForks?: number | string; + /** + * Run tests inside a single fork. + * + * @default false + */ + singleFork?: boolean; +} +interface ResolvedForksOptions extends ForksOptions { + minForks?: number; + maxForks?: number; +} +interface WorkerContextOptions { + /** + * Isolate test environment by recycling `worker_threads` or `child_process` after each test + * + * @default true + */ + isolate?: boolean; + /** + * Pass additional arguments to `node` process when spawning `worker_threads` or `child_process`. + * + * See [Command-line API | Node.js](https://nodejs.org/docs/latest/api/cli.html) for more information. + * + * Set to `process.execArgv` to pass all arguments of the current process. + * + * Be careful when using, it as some options may crash worker, e.g. --prof, --title. See https://github.com/nodejs/node/issues/41103 + * + * @default [] // no execution arguments are passed + */ + execArgv?: string[]; +} +interface VmOptions { + /** + * Specifies the memory limit for `worker_thread` or `child_process` before they are recycled. + * If you see memory leaks, try to tinker this value. + */ + memoryLimit?: string | number; + /** Isolation is always enabled */ + isolate?: true; + /** + * Pass additional arguments to `node` process when spawning `worker_threads` or `child_process`. + * + * See [Command-line API | Node.js](https://nodejs.org/docs/latest/api/cli.html) for more information. + * + * Set to `process.execArgv` to pass all arguments of the current process. + * + * Be careful when using, it as some options may crash worker, e.g. --prof, --title. See https://github.com/nodejs/node/issues/41103 + * + * @default [] // no execution arguments are passed + */ + execArgv?: string[]; +} + +declare class TestSpecification { + /** + * @deprecated use `project` instead + */ + readonly 0: TestProject; + /** + * @deprecated use `moduleId` instead + */ + readonly 1: string; + /** + * @deprecated use `pool` instead + */ + readonly 2: { + pool: Pool + }; + /** + * The task ID associated with the test module. + */ + readonly taskId: string; + /** + * The test project that the module belongs to. + */ + readonly project: TestProject; + /** + * The ID of the module in the Vite module graph. It is usually an absolute file path. + */ + readonly moduleId: string; + /** + * The current test pool. It's possible to have multiple pools in a single test project with `poolMatchGlob` and `typecheck.enabled`. + * @experimental In Vitest 4, the project will only support a single pool and this property will be removed. + */ + readonly pool: Pool; + /** + * Line numbers of the test locations to run. + */ + readonly testLines: number[] | undefined; + constructor(project: TestProject, moduleId: string, pool: Pool, testLines?: number[] | undefined); + /** + * Test module associated with the specification. + */ + get testModule(): TestModule | undefined; + toJSON(): SerializedTestSpecification; + /** + * for backwards compatibility + * @deprecated + */ + [Symbol.iterator](): Generator; +} + +type TestRunEndReason = "passed" | "interrupted" | "failed"; +interface Reporter { + onInit?: (vitest: Vitest) => void; + /** + * Called when the project initiated the browser instance. + * project.browser will always be defined. + * @experimental + */ + onBrowserInit?: (project: TestProject) => Awaitable; + /** + * @deprecated use `onTestRunStart` instead + */ + onPathsCollected?: (paths?: string[]) => Awaitable; + /** + * @deprecated use `onTestRunStart` instead + */ + onSpecsCollected?: (specs?: SerializedTestSpecification[]) => Awaitable; + /** + * @deprecated use `onTestModuleCollected` instead + */ + onCollected?: (files: File[]) => Awaitable; + /** + * @deprecated use `onTestRunEnd` instead + */ + onFinished?: (files: File[], errors: unknown[], coverage?: unknown) => Awaitable; + /** + * @deprecated use `onTestModuleQueued`, `onTestModuleStart`, `onTestModuleEnd`, `onTestCaseReady`, `onTestCaseResult` instead + */ + onTaskUpdate?: (packs: TaskResultPack[], events: TaskEventPack[]) => Awaitable; + onTestRemoved?: (trigger?: string) => Awaitable; + onWatcherStart?: (files?: File[], errors?: unknown[]) => Awaitable; + onWatcherRerun?: (files: string[], trigger?: string) => Awaitable; + onServerRestart?: (reason?: string) => Awaitable; + onUserConsoleLog?: (log: UserConsoleLog) => Awaitable; + onProcessTimeout?: () => Awaitable; + /** + * Called when the new test run starts. + */ + onTestRunStart?: (specifications: ReadonlyArray) => Awaitable; + /** + * Called when the test run is finished. + */ + onTestRunEnd?: (testModules: ReadonlyArray, unhandledErrors: ReadonlyArray, reason: TestRunEndReason) => Awaitable; + /** + * Called when the module is enqueued for testing. The file itself is not loaded yet. + */ + onTestModuleQueued?: (testModule: TestModule) => Awaitable; + /** + * Called when the test file is loaded and the module is ready to run tests. + */ + onTestModuleCollected?: (testModule: TestModule) => Awaitable; + /** + * Called when starting to run tests of the test file + */ + onTestModuleStart?: (testModule: TestModule) => Awaitable; + /** + * Called when all tests of the test file have finished running. + */ + onTestModuleEnd?: (testModule: TestModule) => Awaitable; + /** + * Called when test case is ready to run. + * Called before the `beforeEach` hooks for the test are run. + */ + onTestCaseReady?: (testCase: TestCase) => Awaitable; + /** + * Called after the test and its hooks are finished running. + * The `result()` cannot be `pending`. + */ + onTestCaseResult?: (testCase: TestCase) => Awaitable; + /** + * Called when annotation is added via the `task.annotate` API. + */ + onTestCaseAnnotate?: (testCase: TestCase, annotation: TestAnnotation) => Awaitable; + /** + * Called when test suite is ready to run. + * Called before the `beforeAll` hooks for the test are run. + */ + onTestSuiteReady?: (testSuite: TestSuite) => Awaitable; + /** + * Called after the test suite and its hooks are finished running. + * The `state` cannot be `pending`. + */ + onTestSuiteResult?: (testSuite: TestSuite) => Awaitable; + /** + * Called before the hook starts to run. + */ + onHookStart?: (hook: ReportedHookContext) => Awaitable; + /** + * Called after the hook finished running. + */ + onHookEnd?: (hook: ReportedHookContext) => Awaitable; + onCoverage?: (coverage: unknown) => Awaitable; +} + +interface BaseOptions { + isTTY?: boolean; +} +declare abstract class BaseReporter implements Reporter { + start: number; + end: number; + watchFilters?: string[]; + failedUnwatchedFiles: TestModule[]; + isTTY: boolean; + ctx: Vitest; + renderSucceed: boolean; + protected verbose: boolean; + private _filesInWatchMode; + private _timeStart; + constructor(options?: BaseOptions); + onInit(ctx: Vitest): void; + log(...messages: any): void; + error(...messages: any): void; + relative(path: string): string; + onFinished(files?: File[], errors?: unknown[]): void; + onTestCaseResult(testCase: TestCase): void; + onTestSuiteResult(testSuite: TestSuite): void; + onTestModuleEnd(testModule: TestModule): void; + private logFailedTask; + protected printTestModule(testModule: TestModule): void; + protected printTestCase(moduleState: TestModuleState, test: TestCase): void; + private getModuleLog; + protected printTestSuite(_suite: TestSuite): void; + protected getTestName(test: Task, separator?: string): string; + protected getFullName(test: Task, separator?: string): string; + protected formatShortError(error: ErrorWithDiff): string; + protected getTestIndentation(_test: Task): string; + protected printAnnotations(test: TestCase, console: "log" | "error", padding?: number): void; + protected getDurationPrefix(task: Task): string; + onWatcherStart(files?: File[], errors?: unknown[]): void; + onWatcherRerun(files: string[], trigger?: string): void; + onUserConsoleLog(log: UserConsoleLog, taskState?: TestResult["state"]): void; + onTestRemoved(trigger?: string): void; + shouldLog(log: UserConsoleLog, taskState?: TestResult["state"]): boolean; + onServerRestart(reason?: string): void; + reportSummary(files: File[], errors: unknown[]): void; + reportTestSummary(files: File[], errors: unknown[]): void; + private printErrorsSummary; + reportBenchmarkSummary(files: File[]): void; + private printTaskErrors; +} + +interface BlobOptions { + outputFile?: string; +} +declare class BlobReporter implements Reporter { + start: number; + ctx: Vitest; + options: BlobOptions; + constructor(options: BlobOptions); + onInit(ctx: Vitest): void; + onFinished(files: File[] | undefined, errors: unknown[] | undefined, coverage: unknown): Promise; +} +interface MergedBlobs { + files: File[]; + errors: unknown[]; + coverages: unknown[]; + executionTimes: number[]; +} + +interface DefaultReporterOptions extends BaseOptions { + summary?: boolean; +} +declare class DefaultReporter extends BaseReporter { + private options; + private summary?; + constructor(options?: DefaultReporterOptions); + onTestRunStart(specifications: ReadonlyArray): void; + onTestModuleQueued(file: TestModule): void; + onTestModuleCollected(module: TestModule): void; + onTestModuleEnd(module: TestModule): void; + onTestCaseReady(test: TestCase): void; + onTestCaseResult(test: TestCase): void; + onHookStart(hook: ReportedHookContext): void; + onHookEnd(hook: ReportedHookContext): void; + onInit(ctx: Vitest): void; + onTestRunEnd(): void; +} + +interface HTMLOptions { + outputFile?: string; +} + +interface CoverageSummaryData { + lines: Totals; + statements: Totals; + branches: Totals; + functions: Totals; +} + +declare class CoverageSummary { + constructor(data: CoverageSummary | CoverageSummaryData); + merge(obj: CoverageSummary): CoverageSummary; + toJSON(): CoverageSummaryData; + isEmpty(): boolean; + data: CoverageSummaryData; + lines: Totals; + statements: Totals; + branches: Totals; + functions: Totals; +} + +interface CoverageMapData { + [key: string]: FileCoverage | FileCoverageData; +} + +declare class CoverageMap { + constructor(data: CoverageMapData | CoverageMap); + addFileCoverage(pathOrObject: string | FileCoverage | FileCoverageData): void; + files(): string[]; + fileCoverageFor(filename: string): FileCoverage; + filter(callback: (key: string) => boolean): void; + getCoverageSummary(): CoverageSummary; + merge(data: CoverageMapData | CoverageMap): void; + toJSON(): CoverageMapData; + data: CoverageMapData; +} + +interface Location { + line: number; + column: number; +} + +interface Range { + start: Location; + end: Location; +} + +interface BranchMapping { + loc: Range; + type: string; + locations: Range[]; + line: number; +} + +interface FunctionMapping { + name: string; + decl: Range; + loc: Range; + line: number; +} + +interface FileCoverageData { + path: string; + statementMap: { [key: string]: Range }; + fnMap: { [key: string]: FunctionMapping }; + branchMap: { [key: string]: BranchMapping }; + s: { [key: string]: number }; + f: { [key: string]: number }; + b: { [key: string]: number[] }; +} + +interface Totals { + total: number; + covered: number; + skipped: number; + pct: number; +} + +interface Coverage { + covered: number; + total: number; + coverage: number; +} + +declare class FileCoverage implements FileCoverageData { + constructor(data: string | FileCoverage | FileCoverageData); + merge(other: FileCoverageData): void; + getBranchCoverageByLine(): { [line: number]: Coverage }; + getLineCoverage(): { [line: number]: number }; + getUncoveredLines(): number[]; + resetHits(): void; + computeBranchTotals(): Totals; + computeSimpleTotals(): Totals; + toSummary(): CoverageSummary; + toJSON(): object; + + data: FileCoverageData; + path: string; + statementMap: { [key: string]: Range }; + fnMap: { [key: string]: FunctionMapping }; + branchMap: { [key: string]: BranchMapping }; + s: { [key: string]: number }; + f: { [key: string]: number }; + b: { [key: string]: number[] }; +} + +// for compatibility reasons, the reporter produces a JSON similar to the one produced by the Jest JSON reporter +// the following types are extracted from the Jest repository (and simplified) +// the commented-out fields are the missing ones +type Status = "passed" | "failed" | "skipped" | "pending" | "todo" | "disabled"; +type Milliseconds = number; +interface Callsite { + line: number; + column: number; +} +interface JsonAssertionResult { + ancestorTitles: Array; + fullName: string; + status: Status; + title: string; + meta: TaskMeta; + duration?: Milliseconds | null; + failureMessages: Array | null; + location?: Callsite | null; +} +interface JsonTestResult { + message: string; + name: string; + status: "failed" | "passed"; + startTime: number; + endTime: number; + assertionResults: Array; +} +interface JsonTestResults { + numFailedTests: number; + numFailedTestSuites: number; + numPassedTests: number; + numPassedTestSuites: number; + numPendingTests: number; + numPendingTestSuites: number; + numTodoTests: number; + numTotalTests: number; + numTotalTestSuites: number; + startTime: number; + success: boolean; + testResults: Array; + snapshot: SnapshotSummary; + coverageMap?: CoverageMap | null | undefined; +} +interface JsonOptions$1 { + outputFile?: string; +} +declare class JsonReporter implements Reporter { + start: number; + ctx: Vitest; + options: JsonOptions$1; + constructor(options: JsonOptions$1); + onInit(ctx: Vitest): void; + protected logTasks(files: File[], coverageMap?: CoverageMap | null): Promise; + onFinished(files?: File[], _errors?: unknown[], coverageMap?: unknown): Promise; + /** + * Writes the report to an output file if specified in the config, + * or logs it to the console otherwise. + * @param report + */ + writeReport(report: string): Promise; +} + +interface ClassnameTemplateVariables { + filename: string; + filepath: string; +} +interface JUnitOptions { + outputFile?: string; + /** @deprecated Use `classnameTemplate` instead. */ + classname?: string; + /** + * Template for the classname attribute. Can be either a string or a function. The string can contain placeholders {filename} and {filepath}. + */ + classnameTemplate?: string | ((classnameVariables: ClassnameTemplateVariables) => string); + suiteName?: string; + /** + * Write and for console output + * @default true + */ + includeConsoleOutput?: boolean; + /** + * Add attribute (validated on CIRCLE CI and GitLab CI) + * @default false + */ + addFileAttribute?: boolean; +} +declare class JUnitReporter implements Reporter { + private ctx; + private reportFile?; + private baseLog; + private logger; + private _timeStart; + private fileFd?; + private options; + constructor(options: JUnitOptions); + onInit(ctx: Vitest): Promise; + writeElement(name: string, attrs: Record, children: () => Promise): Promise; + writeLogs(task: Task, type: "err" | "out"): Promise; + writeTasks(tasks: Task[], filename: string): Promise; + onFinished(files?: File[]): Promise; +} + +declare class BasicReporter extends BaseReporter { + constructor(); + onInit(ctx: Vitest): void; + reportSummary(files: File[], errors: unknown[]): void; +} + +declare class DotReporter extends BaseReporter { + private renderer?; + private tests; + private finishedTests; + onInit(ctx: Vitest): void; + // Ignore default logging of base reporter + printTestModule(): void; + onWatcherRerun(files: string[], trigger?: string): void; + onFinished(files?: File[], errors?: unknown[]): void; + onTestModuleCollected(module: TestModule): void; + onTestCaseReady(test: TestCase): void; + onTestCaseResult(test: TestCase): void; + onTestModuleEnd(testModule: TestModule): void; + private createSummary; +} + +interface GithubActionsReporterOptions { + onWritePath?: (path: string) => string; +} +declare class GithubActionsReporter implements Reporter { + ctx: Vitest; + options: GithubActionsReporterOptions; + constructor(options?: GithubActionsReporterOptions); + onInit(ctx: Vitest): void; + onTestCaseAnnotate(testCase: TestCase, annotation: TestAnnotation): void; + onFinished(files?: File[], errors?: unknown[]): void; +} + +declare class HangingProcessReporter implements Reporter { + whyRunning: (() => void) | undefined; + onInit(): void; + onProcessTimeout(): void; +} + +declare class TapReporter implements Reporter { + protected ctx: Vitest; + private logger; + onInit(ctx: Vitest): void; + static getComment(task: Task): string; + private logErrorDetails; + protected logTasks(tasks: Task[]): void; + onFinished(files?: File[]): void; +} + +declare class TapFlatReporter extends TapReporter { + onInit(ctx: Vitest): void; + onFinished(files?: File[]): void; +} + +declare class VerboseReporter extends DefaultReporter { + protected verbose: boolean; + renderSucceed: boolean; + printTestModule(module: TestModule): void; + onTestCaseResult(test: TestCase): void; + protected printTestSuite(testSuite: TestSuite): void; + protected getTestName(test: Task): string; + protected getTestIndentation(test: Task): string; + protected formatShortError(): string; +} + +type FormattedBenchmarkResult = BenchmarkResult & { + id: string +}; + +declare function renderTable(options: { + tasks: Task[] + level: number + shallow?: boolean + showHeap: boolean + columns: number + slowTestThreshold: number + compare?: Record +}): string; + +declare class BenchmarkReporter extends DefaultReporter { + compare?: Parameters[0]["compare"]; + onInit(ctx: Vitest): Promise; + onTaskUpdate(packs: TaskResultPack[]): void; + onTestSuiteResult(testSuite: TestSuite): void; + protected printTestModule(testModule: TestModule): void; + private printSuiteTable; + onFinished(files?: File[], errors?: unknown[]): Promise; +} + +declare class VerboseBenchmarkReporter extends BenchmarkReporter { + protected verbose: boolean; +} + +declare const BenchmarkReportsMap: { + default: typeof BenchmarkReporter + verbose: typeof VerboseBenchmarkReporter +}; +type BenchmarkBuiltinReporters = keyof typeof BenchmarkReportsMap; + +declare const ReportersMap: { + default: typeof DefaultReporter + basic: typeof BasicReporter + blob: typeof BlobReporter + verbose: typeof VerboseReporter + dot: typeof DotReporter + json: typeof JsonReporter + tap: typeof TapReporter + "tap-flat": typeof TapFlatReporter + junit: typeof JUnitReporter + "hanging-process": typeof HangingProcessReporter + "github-actions": typeof GithubActionsReporter +}; +type BuiltinReporters = keyof typeof ReportersMap; +interface BuiltinReporterOptions { + "default": DefaultReporterOptions; + "basic": BaseOptions; + "verbose": DefaultReporterOptions; + "dot": BaseOptions; + "json": JsonOptions$1; + "blob": BlobOptions; + "tap": never; + "tap-flat": never; + "junit": JUnitOptions; + "hanging-process": never; + "html": HTMLOptions; +} + +interface BrowserTesterOptions { + method: TestExecutionMethod; + files: string[]; + providedContext: string; + startTime: number; +} + +type ChaiConfig = Omit, "useProxy" | "proxyExcludedKeys">; + +interface TestSequencer { + /** + * Slicing tests into shards. Will be run before `sort`. + * Only run, if `shard` is defined. + */ + shard: (files: TestSpecification[]) => Awaitable; + sort: (files: TestSpecification[]) => Awaitable; +} +interface TestSequencerConstructor { + new (ctx: Vitest): TestSequencer; +} + +interface WatcherTriggerPattern { + pattern: RegExp; + testsToRun: (file: string, match: RegExpMatchArray) => string[] | string | null | undefined | void; +} + +interface BenchmarkUserOptions { + /** + * Include globs for benchmark test files + * + * @default ['**\/*.{bench,benchmark}.?(c|m)[jt]s?(x)'] + */ + include?: string[]; + /** + * Exclude globs for benchmark test files + * @default ['**\/node_modules/**', '**\/dist/**', '**\/cypress/**', '**\/.{idea,git,cache,output,temp}/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'] + */ + exclude?: string[]; + /** + * Include globs for in-source benchmark test files + * + * @default [] + */ + includeSource?: string[]; + /** + * Custom reporter for output. Can contain one or more built-in report names, reporter instances, + * and/or paths to custom reporters + * + * @default ['default'] + */ + reporters?: Arrayable; + /** + * @deprecated Use `benchmark.outputJson` instead + */ + outputFile?: string | (Partial> & Record); + /** + * benchmark output file to compare against + */ + compare?: string; + /** + * benchmark output file + */ + outputJson?: string; + /** + * Include `samples` array of benchmark results for API or custom reporter usages. + * This is disabled by default to reduce memory usage. + * @default false + */ + includeSamples?: boolean; +} + +interface Node { + isRoot(): boolean; + visit(visitor: Visitor, state: any): void; +} + +interface Visitor { + onStart(root: N, state: any): void; + onSummary(root: N, state: any): void; + onDetail(root: N, state: any): void; + onSummaryEnd(root: N, state: any): void; + onEnd(root: N, state: any): void; +} + +interface FileOptions { + file: string; +} + +interface ProjectOptions { + projectRoot: string; +} + +interface ReportOptions { + clover: CloverOptions; + cobertura: CoberturaOptions; + "html-spa": HtmlSpaOptions; + html: HtmlOptions; + json: JsonOptions; + "json-summary": JsonSummaryOptions; + lcov: LcovOptions; + lcovonly: LcovOnlyOptions; + none: never; + teamcity: TeamcityOptions; + text: TextOptions; + "text-lcov": TextLcovOptions; + "text-summary": TextSummaryOptions; +} + +interface CloverOptions extends FileOptions, ProjectOptions {} + +interface CoberturaOptions extends FileOptions, ProjectOptions {} + +interface HtmlSpaOptions extends HtmlOptions { + metricsToShow: Array<"lines" | "branches" | "functions" | "statements">; +} +interface HtmlOptions { + verbose: boolean; + skipEmpty: boolean; + subdir: string; + linkMapper: LinkMapper; +} + +type JsonOptions = FileOptions; +type JsonSummaryOptions = FileOptions; + +interface LcovOptions extends FileOptions, ProjectOptions {} +interface LcovOnlyOptions extends FileOptions, ProjectOptions {} + +interface TeamcityOptions extends FileOptions { + blockName: string; +} + +interface TextOptions extends FileOptions { + maxCols: number; + skipEmpty: boolean; + skipFull: boolean; +} +type TextLcovOptions = ProjectOptions; +type TextSummaryOptions = FileOptions; + +interface LinkMapper { + getPath(node: string | Node): string; + relativePath(source: string | Node, target: string | Node): string; + assetPath(node: Node, name: string): string; +} + +type TransformResult = string | Partial | undefined | null | void; +type CoverageResults = unknown; +interface CoverageProvider { + name: string; + /** Called when provider is being initialized before tests run */ + initialize: (ctx: Vitest) => Promise | void; + /** Called when setting coverage options for Vitest context (`ctx.config.coverage`) */ + resolveOptions: () => ResolvedCoverageOptions; + /** Callback to clean previous reports */ + clean: (clean?: boolean) => void | Promise; + /** Called with coverage results after a single test file has been run */ + onAfterSuiteRun: (meta: AfterSuiteRunMeta) => void | Promise; + /** Callback called when test run fails */ + onTestFailure?: () => void | Promise; + /** Callback to generate final coverage results */ + generateCoverage: (reportContext: ReportContext) => CoverageResults | Promise; + /** Callback to convert coverage results to coverage reports. Called with results returned from `generateCoverage` */ + reportCoverage: (coverage: CoverageResults, reportContext: ReportContext) => void | Promise; + /** Callback for `--merge-reports` options. Called with multiple coverage results generated by `generateCoverage`. */ + mergeReports?: (coverages: CoverageResults[]) => void | Promise; + /** Callback called for instrumenting files with coverage counters. */ + onFileTransform?: (sourceCode: string, id: string, pluginCtx: any) => TransformResult | Promise; +} +interface ReportContext { + /** Indicates whether all tests were run. False when only specific tests were run. */ + allTestsRun?: boolean; +} +interface CoverageProviderModule extends RuntimeCoverageProviderModule { + /** + * Factory for creating a new coverage provider + */ + getProvider: () => CoverageProvider | Promise; +} +type CoverageReporter = keyof ReportOptions | (string & {}); +type CoverageReporterWithOptions = ReporterName extends keyof ReportOptions ? ReportOptions[ReporterName] extends never ? [ReporterName, object] : [ReporterName, Partial] : [ReporterName, Record]; +type CoverageProviderName = "v8" | "istanbul" | "custom" | undefined; +type CoverageOptions = T extends "istanbul" ? { + provider: T +} & CoverageIstanbulOptions : T extends "v8" ? { + /** + * Provider to use for coverage collection. + * + * @default 'v8' + */ + provider: T +} & CoverageV8Options : T extends "custom" ? { + provider: T +} & CustomProviderOptions : { + provider?: T +} & CoverageV8Options; +/** Fields that have default values. Internally these will always be defined. */ +type FieldsWithDefaultValues = "enabled" | "clean" | "cleanOnRerun" | "reportsDirectory" | "exclude" | "extension" | "reportOnFailure" | "allowExternal" | "processingConcurrency"; +type ResolvedCoverageOptions = CoverageOptions & Required, FieldsWithDefaultValues>> & { + reporter: CoverageReporterWithOptions[] +}; +interface BaseCoverageOptions { + /** + * Enables coverage collection. Can be overridden using `--coverage` CLI option. + * + * @default false + */ + enabled?: boolean; + /** + * List of files included in coverage as glob patterns + * + * @default ['**'] + */ + include?: string[]; + /** + * Extensions for files to be included in coverage + * + * @default ['.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx', '.vue', '.svelte', '.marko'] + */ + extension?: string | string[]; + /** + * List of files excluded from coverage as glob patterns + * + * @default ['coverage/**', 'dist/**', '**\/[.]**', 'packages/*\/test?(s)/**', '**\/*.d.ts', '**\/virtual:*', '**\/__x00__*', '**\/\x00*', 'cypress/**', 'test?(s)/**', 'test?(-*).?(c|m)[jt]s?(x)', '**\/*{.,-}{test,spec}?(-d).?(c|m)[jt]s?(x)', '**\/__tests__/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*', '**\/vitest.{workspace,projects}.[jt]s?(on)', '**\/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}'] + */ + exclude?: string[]; + /** + * Whether to include all files, including the untested ones into report + * + * @default true + */ + all?: boolean; + /** + * Clean coverage results before running tests + * + * @default true + */ + clean?: boolean; + /** + * Clean coverage report on watch rerun + * + * @default true + */ + cleanOnRerun?: boolean; + /** + * Directory to write coverage report to + * + * @default './coverage' + */ + reportsDirectory?: string; + /** + * Coverage reporters to use. + * See [istanbul documentation](https://istanbul.js.org/docs/advanced/alternative-reporters/) for detailed list of all reporters. + * + * @default ['text', 'html', 'clover', 'json'] + */ + reporter?: Arrayable$1 | (CoverageReporter | [CoverageReporter] | CoverageReporterWithOptions)[]; + /** + * Do not show files with 100% statement, branch, and function coverage + * + * @default false + */ + skipFull?: boolean; + /** + * Configurations for thresholds + * + * @example + * + * ```ts + * { + * // Thresholds for all files + * functions: 95, + * branches: 70, + * perFile: true, + * autoUpdate: true, + * + * // Thresholds for utilities + * 'src/utils/**.ts': { + * lines: 100, + * statements: 95, + * } + * } + * ``` + */ + thresholds?: Thresholds | ({ + [glob: string]: Pick + } & Thresholds); + /** + * Watermarks for statements, lines, branches and functions. + * + * Default value is `[50,80]` for each property. + */ + watermarks?: { + statements?: [number, number] + functions?: [number, number] + branches?: [number, number] + lines?: [number, number] + }; + /** + * Generate coverage report even when tests fail. + * + * @default false + */ + reportOnFailure?: boolean; + /** + * Collect coverage of files outside the project `root`. + * + * @default false + */ + allowExternal?: boolean; + /** + * Apply exclusions again after coverage has been remapped to original sources. + * This is useful when your source files are transpiled and may contain source maps + * of non-source files. + * + * Use this option when you are seeing files that show up in report even if they + * match your `coverage.exclude` patterns. + * + * @default false + */ + excludeAfterRemap?: boolean; + /** + * Concurrency limit used when processing the coverage results. + * Defaults to `Math.min(20, os.availableParallelism?.() ?? os.cpus().length)` + */ + processingConcurrency?: number; +} +interface CoverageIstanbulOptions extends BaseCoverageOptions { + /** + * Set to array of class method names to ignore for coverage + * + * @default [] + */ + ignoreClassMethods?: string[]; +} +interface CoverageV8Options extends BaseCoverageOptions { + /** + * Ignore empty lines, comments and other non-runtime code, e.g. Typescript types + * - Requires `experimentalAstAwareRemapping: false` + */ + ignoreEmptyLines?: boolean; + /** + * Remap coverage with experimental AST based analysis + * - Provides more accurate results compared to default mode + */ + experimentalAstAwareRemapping?: boolean; + /** + * Set to array of class method names to ignore for coverage. + * - Requires `experimentalAstAwareRemapping: true` + * + * @default [] + */ + ignoreClassMethods?: string[]; +} +interface CustomProviderOptions extends Pick { + /** Name of the module or path to a file to load the custom provider from */ + customProviderModule: string; +} +interface Thresholds { + /** Set global thresholds to `100` */ + 100?: boolean; + /** Check thresholds per file. */ + perFile?: boolean; + /** + * Update threshold values automatically when current coverage is higher than earlier thresholds + * + * @default false + */ + autoUpdate?: boolean; + /** Thresholds for statements */ + statements?: number; + /** Thresholds for functions */ + functions?: number; + /** Thresholds for branches */ + branches?: number; + /** Thresholds for lines */ + lines?: number; +} + +type BuiltinEnvironment = "node" | "jsdom" | "happy-dom" | "edge-runtime"; +// Record is used, so user can get intellisense for builtin environments, but still allow custom environments +type VitestEnvironment = BuiltinEnvironment | (string & Record); + +type CSSModuleScopeStrategy = "stable" | "scoped" | "non-scoped"; +type ApiConfig = Pick; + +type VitestRunMode = "test" | "benchmark"; +interface ProjectName { + label: string; + color?: LabelColor; +} +interface SequenceOptions { + /** + * Class that handles sorting and sharding algorithm. + * If you only need to change sorting, you can extend + * your custom sequencer from `BaseSequencer` from `vitest/node`. + * @default BaseSequencer + */ + sequencer?: TestSequencerConstructor; + /** + * Controls the order in which this project runs its tests when using multiple [projects](/guide/projects). + * + * - Projects with the same group order number will run together, and groups are run from lowest to highest. + * - If you don’t set this option, all projects run in parallel. + * - If several projects use the same group order, they will run at the same time. + * @default 0 + */ + groupOrder?: number; + /** + * Should files and tests run in random order. + * @default false + */ + shuffle?: boolean | { + /** + * Should files run in random order. Long running tests will not start + * earlier if you enable this option. + * @default false + */ + files?: boolean + /** + * Should tests run in random order. + * @default false + */ + tests?: boolean + }; + /** + * Should tests run in parallel. + * @default false + */ + concurrent?: boolean; + /** + * Defines how setup files should be ordered + * - 'parallel' will run all setup files in parallel + * - 'list' will run all setup files in the order they are defined in the config file + * @default 'parallel' + */ + setupFiles?: SequenceSetupFiles; + /** + * Seed for the random number generator. + * @default Date.now() + */ + seed?: number; + /** + * Defines how hooks should be ordered + * - `stack` will order "after" hooks in reverse order, "before" hooks will run sequentially + * - `list` will order hooks in the order they are defined + * - `parallel` will run hooks in a single group in parallel + * @default 'stack' + */ + hooks?: SequenceHooks; +} +type DepsOptimizationOptions = Omit & { + enabled?: boolean +}; +interface TransformModePatterns { + /** + * Use SSR transform pipeline for all modules inside specified tests. + * Vite plugins will receive `ssr: true` flag when processing those files. + * + * @default tests with node or edge environment + */ + ssr?: string[]; + /** + * First do a normal transform pipeline (targeting browser), + * then then do a SSR rewrite to run the code in Node. + * Vite plugins will receive `ssr: false` flag when processing those files. + * + * @default tests with jsdom or happy-dom environment + */ + web?: string[]; +} +interface DepsOptions { + /** + * Enable dependency optimization. This can improve the performance of your tests. + */ + optimizer?: { + web?: DepsOptimizationOptions + ssr?: DepsOptimizationOptions + }; + web?: { + /** + * Should Vitest process assets (.png, .svg, .jpg, etc) files and resolve them like Vite does in the browser. + * + * These module will have a default export equal to the path to the asset, if no query is specified. + * + * **At the moment, this option only works with `{ pool: 'vmThreads' }`.** + * + * @default true + */ + transformAssets?: boolean + /** + * Should Vitest process CSS (.css, .scss, .sass, etc) files and resolve them like Vite does in the browser. + * + * If CSS files are disabled with `css` options, this option will just silence UNKNOWN_EXTENSION errors. + * + * **At the moment, this option only works with `{ pool: 'vmThreads' }`.** + * + * @default true + */ + transformCss?: boolean + /** + * Regexp pattern to match external files that should be transformed. + * + * By default, files inside `node_modules` are externalized and not transformed. + * + * **At the moment, this option only works with `{ pool: 'vmThreads' }`.** + * + * @default [] + */ + transformGlobPattern?: RegExp | RegExp[] + }; + /** + * Externalize means that Vite will bypass the package to native Node. + * + * Externalized dependencies will not be applied Vite's transformers and resolvers. + * And does not support HMR on reload. + * + * Typically, packages under `node_modules` are externalized. + * + * @deprecated If you rely on vite-node directly, use `server.deps.external` instead. Otherwise, consider using `deps.optimizer.{web,ssr}.exclude`. + */ + external?: (string | RegExp)[]; + /** + * Vite will process inlined modules. + * + * This could be helpful to handle packages that ship `.js` in ESM format (that Node can't handle). + * + * If `true`, every dependency will be inlined + * + * @deprecated If you rely on vite-node directly, use `server.deps.inline` instead. Otherwise, consider using `deps.optimizer.{web,ssr}.include`. + */ + inline?: (string | RegExp)[] | true; + /** + * Interpret CJS module's default as named exports + * + * @default true + */ + interopDefault?: boolean; + /** + * When a dependency is a valid ESM package, try to guess the cjs version based on the path. + * This will significantly improve the performance in huge repo, but might potentially + * cause some misalignment if a package have different logic in ESM and CJS mode. + * + * @default false + * + * @deprecated Use `server.deps.fallbackCJS` instead. + */ + fallbackCJS?: boolean; + /** + * A list of directories relative to the config file that should be treated as module directories. + * + * @default ['node_modules'] + */ + moduleDirectories?: string[]; +} +type InlineReporter = Reporter; +type ReporterName = BuiltinReporters | "html" | (string & {}); +type ReporterWithOptions = Name extends keyof BuiltinReporterOptions ? BuiltinReporterOptions[Name] extends never ? [Name, object] : [Name, Partial] : [Name, Record]; +interface ResolveSnapshotPathHandlerContext { + config: SerializedConfig; +} +type ResolveSnapshotPathHandler = (testPath: string, snapExtension: string, context: ResolveSnapshotPathHandlerContext) => string; +interface InlineConfig { + /** + * Name of the project. Will be used to display in the reporter. + */ + name?: string | ProjectName; + /** + * Benchmark options. + * + * @default {} + */ + benchmark?: BenchmarkUserOptions; + /** + * Include globs for test files + * + * @default ['**\/*.{test,spec}.?(c|m)[jt]s?(x)'] + */ + include?: string[]; + /** + * Exclude globs for test files + * @default ['**\/node_modules/**', '**\/dist/**', '**\/cypress/**', '**\/.{idea,git,cache,output,temp}/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'] + */ + exclude?: string[]; + /** + * Include globs for in-source test files + * + * @default [] + */ + includeSource?: string[]; + /** + * Handling for dependencies inlining or externalizing + * + */ + deps?: DepsOptions; + /** + * Vite-node server options + */ + server?: Omit; + /** + * Base directory to scan for the test files + * + * @default `config.root` + */ + dir?: string; + /** + * Register apis globally + * + * @default false + */ + globals?: boolean; + /** + * Running environment + * + * Supports 'node', 'jsdom', 'happy-dom', 'edge-runtime' + * + * If used unsupported string, will try to load the package `vitest-environment-${env}` + * + * @default 'node' + */ + environment?: VitestEnvironment; + /** + * Environment options. + */ + environmentOptions?: EnvironmentOptions; + /** + * Automatically assign environment based on globs. The first match will be used. + * This has effect only when running tests inside Node.js. + * + * Format: [glob, environment-name] + * + * @deprecated use [`projects`](https://vitest.dev/config/#projects) instead + * @default [] + * @example [ + * // all tests in tests/dom will run in jsdom + * ['tests/dom/**', 'jsdom'], + * // all tests in tests/ with .edge.test.ts will run in edge-runtime + * ['**\/*.edge.test.ts', 'edge-runtime'], + * // ... + * ] + */ + environmentMatchGlobs?: [string, VitestEnvironment][]; + /** + * Run tests in an isolated environment. This option has no effect on vmThreads pool. + * + * Disabling this option might improve performance if your code doesn't rely on side effects. + * + * @default true + */ + isolate?: boolean; + /** + * Pool used to run tests in. + * + * Supports 'threads', 'forks', 'vmThreads' + * + * @default 'forks' + */ + pool?: Exclude; + /** + * Pool options + */ + poolOptions?: PoolOptions; + /** + * Maximum number or percentage of workers to run tests in. `poolOptions.{threads,vmThreads}.maxThreads`/`poolOptions.forks.maxForks` has higher priority. + */ + maxWorkers?: number | string; + /** + * Minimum number or percentage of workers to run tests in. `poolOptions.{threads,vmThreads}.minThreads`/`poolOptions.forks.minForks` has higher priority. + */ + minWorkers?: number | string; + /** + * Should all test files run in parallel. Doesn't affect tests running in the same file. + * Setting this to `false` will override `maxWorkers` and `minWorkers` options to `1`. + * + * @default true + */ + fileParallelism?: boolean; + /** + * Automatically assign pool based on globs. The first match will be used. + * + * Format: [glob, pool-name] + * + * @deprecated use [`projects`](https://vitest.dev/config/#projects) instead + * @default [] + * @example [ + * // all tests in "forks" directory will run using "poolOptions.forks" API + * ['tests/forks/**', 'forks'], + * // all other tests will run based on "poolOptions.threads" option, if you didn't specify other globs + * // ... + * ] + */ + poolMatchGlobs?: [string, Exclude][]; + /** + * Options for projects + */ + projects?: TestProjectConfiguration[]; + /** + * Path to a workspace configuration file + * @deprecated use `projects` instead + */ + workspace?: string | TestProjectConfiguration[]; + /** + * Update snapshot + * + * @default false + */ + update?: boolean; + /** + * Watch mode + * + * @default !process.env.CI + */ + watch?: boolean; + /** + * Project root + * + * @default process.cwd() + */ + root?: string; + /** + * Custom reporter for output. Can contain one or more built-in report names, reporter instances, + * and/or paths to custom reporters. + * + * @default [] + */ + reporters?: Arrayable$1 | ((ReporterName | InlineReporter) | [ReporterName] | ReporterWithOptions)[]; + /** + * Write test results to a file when the --reporter=json` or `--reporter=junit` option is also specified. + * Also definable individually per reporter by using an object instead. + */ + outputFile?: string | (Partial> & Record); + /** + * Default timeout of a test in milliseconds + * + * @default 5000 + */ + testTimeout?: number; + /** + * Default timeout of a hook in milliseconds + * + * @default 10000 + */ + hookTimeout?: number; + /** + * Default timeout to wait for close when Vitest shuts down, in milliseconds + * + * @default 10000 + */ + teardownTimeout?: number; + /** + * Silent mode + * + * Use `'passed-only'` to see logs from failing tests only. + * + * @default false + */ + silent?: boolean | "passed-only"; + /** + * Hide logs for skipped tests + * + * @default false + */ + hideSkippedTests?: boolean; + /** + * Path to setup files + */ + setupFiles?: string | string[]; + /** + * Path to global setup files + */ + globalSetup?: string | string[]; + /** + * Glob patter of file paths that will trigger the whole suite rerun + * + * Useful if you are testing calling CLI commands + * + * @default ['**\/package.json/**', '**\/{vitest,vite}.config.*\/**'] + */ + forceRerunTriggers?: string[]; + /** + * Pattern configuration to rerun only the tests that are affected + * by the changes of specific files in the repository. + */ + watchTriggerPatterns?: WatcherTriggerPattern[]; + /** + * Coverage options + */ + coverage?: CoverageOptions; + /** + * run test names with the specified pattern + */ + testNamePattern?: string | RegExp; + /** + * Will call `.mockClear()` on all spies before each test + * @default false + */ + clearMocks?: boolean; + /** + * Will call `.mockReset()` on all spies before each test + * @default false + */ + mockReset?: boolean; + /** + * Will call `.mockRestore()` on all spies before each test + * @default false + */ + restoreMocks?: boolean; + /** + * Will restore all global stubs to their original values before each test + * @default false + */ + unstubGlobals?: boolean; + /** + * Will restore all env stubs to their original values before each test + * @default false + */ + unstubEnvs?: boolean; + /** + * Serve API options. + * + * When set to true, the default port is 51204. + * + * @default false + */ + api?: boolean | number | ApiConfig; + /** + * Enable Vitest UI + * + * @default false + */ + ui?: boolean; + /** + * options for test in a browser environment + * @experimental + * + * @default false + */ + browser?: BrowserConfigOptions; + /** + * Open UI automatically. + * + * @default !process.env.CI + */ + open?: boolean; + /** + * Base url for the UI + * + * @default '/__vitest__/' + */ + uiBase?: string; + /** + * Determine the transform method for all modules imported inside a test that matches the glob pattern. + */ + testTransformMode?: TransformModePatterns; + /** + * Format options for snapshot testing. + */ + snapshotFormat?: Omit; + /** + * Path to a module which has a default export of diff config. + */ + diff?: string | SerializedDiffOptions; + /** + * Paths to snapshot serializer modules. + */ + snapshotSerializers?: string[]; + /** + * Resolve custom snapshot path + */ + resolveSnapshotPath?: ResolveSnapshotPathHandler; + /** + * Path to a custom snapshot environment module that has a default export of `SnapshotEnvironment` object. + */ + snapshotEnvironment?: string; + /** + * Pass with no tests + */ + passWithNoTests?: boolean; + /** + * Allow tests and suites that are marked as only + * + * @default !process.env.CI + */ + allowOnly?: boolean; + /** + * Show heap usage after each test. Useful for debugging memory leaks. + */ + logHeapUsage?: boolean; + /** + * Custom environment variables assigned to `process.env` before running tests. + */ + env?: Partial; + /** + * Options for @sinon/fake-timers + */ + fakeTimers?: FakeTimerInstallOpts; + /** + * Custom handler for console.log in tests. + * + * Return `false` to ignore the log. + */ + onConsoleLog?: (log: string, type: "stdout" | "stderr") => boolean | void; + /** + * Enable stack trace filtering. If absent, all stack trace frames + * will be shown. + * + * Return `false` to omit the frame. + */ + onStackTrace?: (error: ErrorWithDiff, frame: ParsedStack) => boolean | void; + /** + * Indicates if CSS files should be processed. + * + * When excluded, the CSS files will be replaced with empty strings to bypass the subsequent processing. + * + * @default { include: [], modules: { classNameStrategy: false } } + */ + css?: boolean | { + include?: RegExp | RegExp[] + exclude?: RegExp | RegExp[] + modules?: { + classNameStrategy?: CSSModuleScopeStrategy + } + }; + /** + * A number of tests that are allowed to run at the same time marked with `test.concurrent`. + * @default 5 + */ + maxConcurrency?: number; + /** + * Options for configuring cache policy. + * @default { dir: 'node_modules/.vite/vitest/{project-hash}' } + */ + cache?: false | { + /** + * @deprecated Use Vite's "cacheDir" instead if you want to change the cache director. Note caches will be written to "cacheDir\/vitest". + */ + dir: string + }; + /** + * Options for configuring the order of running tests. + */ + sequence?: SequenceOptions; + /** + * Specifies an `Object`, or an `Array` of `Object`, + * which defines aliases used to replace values in `import` or `require` statements. + * Will be merged with the default aliases inside `resolve.alias`. + */ + alias?: AliasOptions; + /** + * Ignore any unhandled errors that occur + * + * @default false + */ + dangerouslyIgnoreUnhandledErrors?: boolean; + /** + * Options for configuring typechecking test environment. + */ + typecheck?: Partial; + /** + * The number of milliseconds after which a test is considered slow and reported as such in the results. + * + * @default 300 + */ + slowTestThreshold?: number; + /** + * Path to a custom test runner. + */ + runner?: string; + /** + * Debug tests by opening `node:inspector` in worker / child process. + * Provides similar experience as `--inspect` Node CLI argument. + * + * Requires `poolOptions.threads.singleThread: true` OR `poolOptions.forks.singleFork: true`. + */ + inspect?: boolean | string; + /** + * Debug tests by opening `node:inspector` in worker / child process and wait for debugger to connect. + * Provides similar experience as `--inspect-brk` Node CLI argument. + * + * Requires `poolOptions.threads.singleThread: true` OR `poolOptions.forks.singleFork: true`. + */ + inspectBrk?: boolean | string; + /** + * Inspector options. If `--inspect` or `--inspect-brk` is enabled, these options will be passed to the inspector. + */ + inspector?: { + /** + * Enable inspector + */ + enabled?: boolean + /** + * Port to run inspector on + */ + port?: number + /** + * Host to run inspector on + */ + host?: string + /** + * Wait for debugger to connect before running tests + */ + waitForDebugger?: boolean + }; + /** + * Define variables that will be returned from `inject` in the test environment. + * @example + * ```ts + * // vitest.config.ts + * export default defineConfig({ + * test: { + * provide: { + * someKey: 'someValue' + * } + * } + * }) + * ``` + * ```ts + * // test file + * import { inject } from 'vitest' + * const value = inject('someKey') // 'someValue' + * ``` + */ + provide?: Partial; + /** + * Configuration options for expect() matches. + */ + expect?: { + /** + * Throw an error if tests don't have any expect() assertions. + */ + requireAssertions?: boolean + /** + * Default options for expect.poll() + */ + poll?: { + /** + * Timeout in milliseconds + * @default 1000 + */ + timeout?: number + /** + * Polling interval in milliseconds + * @default 50 + */ + interval?: number + } + }; + /** + * Modify default Chai config. Vitest uses Chai for `expect` and `assert` matches. + * https://github.com/chaijs/chai/blob/4.x.x/lib/chai/config.js + */ + chaiConfig?: ChaiConfig; + /** + * Stop test execution when given number of tests have failed. + */ + bail?: number; + /** + * Retry the test specific number of times if it fails. + * + * @default 0 + */ + retry?: number; + /** + * Show full diff when snapshot fails instead of a patch. + */ + expandSnapshotDiff?: boolean; + /** + * By default, Vitest automatically intercepts console logging during tests for extra formatting of test file, test title, etc... + * This is also required for console log preview on Vitest UI. + * However, disabling such interception might help when you want to debug a code with normal synchronous terminal console logging. + * + * This option has no effect on browser pool since Vitest preserves original logging on browser devtools. + * + * @default false + */ + disableConsoleIntercept?: boolean; + /** + * Always print console stack traces. + * + * @default false + */ + printConsoleTrace?: boolean; + /** + * Include "location" property inside the test definition + * + * @default false + */ + includeTaskLocation?: boolean; + /** + * Directory path for storing attachments created by `context.annotate` + * + * @default '.vitest-attachments' + */ + attachmentsDir?: string; +} +interface TypecheckConfig { + /** + * Run typechecking tests alongside regular tests. + */ + enabled?: boolean; + /** + * When typechecking is enabled, only run typechecking tests. + */ + only?: boolean; + /** + * What tools to use for type checking. + * + * @default 'tsc' + */ + checker: "tsc" | "vue-tsc" | (string & Record); + /** + * Pattern for files that should be treated as test files + * + * @default ['**\/*.{test,spec}-d.?(c|m)[jt]s?(x)'] + */ + include: string[]; + /** + * Pattern for files that should not be treated as test files + * + * @default ['**\/node_modules/**', '**\/dist/**', '**\/cypress/**', '**\/.{idea,git,cache,output,temp}/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'] + */ + exclude: string[]; + /** + * Check JS files that have `@ts-check` comment. + * If you have it enabled in tsconfig, this will not overwrite it. + */ + allowJs?: boolean; + /** + * Do not fail, if Vitest found errors outside the test files. + */ + ignoreSourceErrors?: boolean; + /** + * Path to tsconfig, relative to the project root. + */ + tsconfig?: string; + /** + * Minimum time in milliseconds it takes to spawn the typechecker. + * @default 10_000 + */ + spawnTimeout?: number; +} +interface UserConfig extends InlineConfig { + /** + * Path to the config file. + * + * Default resolving to `vitest.config.*`, `vite.config.*` + * + * Setting to `false` will disable config resolving. + */ + config?: string | false | undefined; + /** + * Do not run tests when Vitest starts. + * + * Vitest will only run tests if it's called programmatically or the test file changes. + * + * CLI file filters will be ignored. + */ + standalone?: boolean; + /** + * Use happy-dom + */ + dom?: boolean; + /** + * Run tests that cover a list of source files + */ + related?: string[] | string; + /** + * Overrides Vite mode + * @default 'test' + */ + mode?: string; + /** + * Runs tests that are affected by the changes in the repository, or between specified branch or commit hash + * Requires initialized git repository + * @default false + */ + changed?: boolean | string; + /** + * Test suite shard to execute in a format of /. + * Will divide tests into a `count` numbers, and run only the `indexed` part. + * Cannot be used with enabled watch. + * @example --shard=2/3 + */ + shard?: string; + /** + * Name of the project or projects to run. + */ + project?: string | string[]; + /** + * Additional exclude patterns + */ + cliExclude?: string[]; + /** + * Override vite config's clearScreen from cli + */ + clearScreen?: boolean; + /** + * benchmark.compare option exposed at the top level for cli + */ + compare?: string; + /** + * benchmark.outputJson option exposed at the top level for cli + */ + outputJson?: string; + /** + * Directory of blob reports to merge + * @default '.vitest-reports' + */ + mergeReports?: string; +} +interface ResolvedConfig extends Omit, "project" | "config" | "filters" | "browser" | "coverage" | "testNamePattern" | "related" | "api" | "reporters" | "resolveSnapshotPath" | "benchmark" | "shard" | "cache" | "sequence" | "typecheck" | "runner" | "poolOptions" | "pool" | "cliExclude" | "diff" | "setupFiles" | "snapshotEnvironment" | "bail" | "name"> { + mode: VitestRunMode; + name: ProjectName["label"]; + color?: ProjectName["color"]; + base?: string; + diff?: string | SerializedDiffOptions; + bail?: number; + setupFiles: string[]; + snapshotEnvironment?: string; + config?: string; + filters?: string[]; + testNamePattern?: RegExp; + related?: string[]; + coverage: ResolvedCoverageOptions; + snapshotOptions: SnapshotStateOptions; + browser: ResolvedBrowserOptions; + pool: Pool; + poolOptions?: ResolvedPoolOptions; + reporters: (InlineReporter | ReporterWithOptions)[]; + defines: Record; + api: ApiConfig & { + token: string + }; + cliExclude?: string[]; + project: string[]; + benchmark?: Required> & Pick; + shard?: { + index: number + count: number + }; + cache: { + /** + * @deprecated + */ + dir: string + } | false; + sequence: { + sequencer: TestSequencerConstructor + hooks: SequenceHooks + setupFiles: SequenceSetupFiles + shuffle?: boolean + concurrent?: boolean + seed: number + groupOrder: number + }; + typecheck: Omit & { + enabled: boolean + }; + runner?: string; + maxWorkers: number; + minWorkers: number; +} +type NonProjectOptions = "shard" | "watch" | "run" | "cache" | "update" | "reporters" | "outputFile" | "teardownTimeout" | "silent" | "forceRerunTriggers" | "testNamePattern" | "ui" | "open" | "uiBase" | "snapshotFormat" | "resolveSnapshotPath" | "passWithNoTests" | "onConsoleLog" | "onStackTrace" | "dangerouslyIgnoreUnhandledErrors" | "slowTestThreshold" | "inspect" | "inspectBrk" | "coverage" | "maxWorkers" | "minWorkers" | "fileParallelism" | "workspace" | "watchTriggerPatterns"; +type ProjectConfig = Omit & { + mode?: string + sequencer?: Omit + deps?: Omit + poolOptions?: { + threads?: Pick, "singleThread" | "isolate"> + vmThreads?: Pick, "singleThread"> + forks?: Pick, "singleFork" | "isolate"> + } +}; +type ResolvedProjectConfig = Omit>; +interface UserWorkspaceConfig extends UserConfig$1 { + test?: ProjectConfig; +} +type UserProjectConfigFn = (env: ConfigEnv) => UserWorkspaceConfig | Promise; +type UserProjectConfigExport = UserWorkspaceConfig | Promise | UserProjectConfigFn; +type TestProjectInlineConfiguration = (UserWorkspaceConfig & { + /** + * Relative path to the extendable config. All other options will be merged with this config. + * If `true`, the project will inherit all options from the root config. + * @example '../vite.config.ts' + */ + extends?: string | true +}); +type TestProjectConfiguration = string | TestProjectInlineConfiguration | Promise | UserProjectConfigFn; +/** @deprecated use `TestProjectConfiguration` instead */ +type WorkspaceProjectConfiguration = TestProjectConfiguration; + +interface BrowserProviderInitializationOptions { + browser: string; + options?: BrowserProviderOptions; +} +interface CDPSession { + send: (method: string, params?: Record) => Promise; + on: (event: string, listener: (...args: unknown[]) => void) => void; + once: (event: string, listener: (...args: unknown[]) => void) => void; + off: (event: string, listener: (...args: unknown[]) => void) => void; +} +interface BrowserModuleMocker { + register: (sessionId: string, module: MockedModule) => Promise; + delete: (sessionId: string, url: string) => Promise; + clear: (sessionId: string) => Promise; +} +interface BrowserProvider { + name: string; + mocker?: BrowserModuleMocker; + /** + * @experimental opt-in into file parallelisation + */ + supportsParallelism: boolean; + getSupportedBrowsers: () => readonly string[]; + getCommandsContext: (sessionId: string) => Record; + openPage: (sessionId: string, url: string, beforeNavigate?: () => Promise) => Promise; + getCDPSession?: (sessionId: string) => Promise; + close: () => Awaitable$1; + // eslint-disable-next-line ts/method-signature-style -- we want to allow extended options + initialize(ctx: TestProject, options: BrowserProviderInitializationOptions): Awaitable$1; +} +interface BrowserProviderModule { + new (): BrowserProvider; +} +interface BrowserProviderOptions {} +type BrowserBuiltinProvider = "webdriverio" | "playwright" | "preview"; +type UnsupportedProperties = "browser" | "typecheck" | "alias" | "sequence" | "root" | "pool" | "poolOptions" | "runner" | "api" | "deps" | "testTransformMode" | "poolMatchGlobs" | "environmentMatchGlobs" | "environment" | "environmentOptions" | "server" | "benchmark" | "name"; +interface BrowserInstanceOption extends BrowserProviderOptions, Omit, Pick { + /** + * Name of the browser + */ + browser: string; + name?: string; +} +interface BrowserConfigOptions { + /** + * if running tests in the browser should be the default + * + * @default false + */ + enabled?: boolean; + /** + * Name of the browser + * @deprecated use `instances` instead. if both are defined, this will filter `instances` by name. + */ + name?: string; + /** + * Configurations for different browser setups + */ + instances?: BrowserInstanceOption[]; + /** + * Browser provider + * + * @default 'preview' + */ + provider?: BrowserBuiltinProvider | (string & {}); + /** + * Options that are passed down to a browser provider. + * To support type hinting, add one of the types to your tsconfig.json "compilerOptions.types" field: + * + * - for webdriverio: `@vitest/browser/providers/webdriverio` + * - for playwright: `@vitest/browser/providers/playwright` + * + * @example + * { playwright: { launch: { devtools: true } } + * @deprecated use `instances` instead + */ + providerOptions?: BrowserProviderOptions; + /** + * enable headless mode + * + * @default process.env.CI + */ + headless?: boolean; + /** + * Serve API options. + * + * The default port is 63315. + */ + api?: ApiConfig | number; + /** + * Isolate test environment after each test + * + * @default true + */ + isolate?: boolean; + /** + * Run test files in parallel if provider supports this option + * This option only has effect in headless mode (enabled in CI by default) + * + * @default // Same as "test.fileParallelism" + */ + fileParallelism?: boolean; + /** + * Show Vitest UI + * + * @default !process.env.CI + */ + ui?: boolean; + /** + * Default viewport size + */ + viewport?: { + /** + * Width of the viewport + * @default 414 + */ + width: number + /** + * Height of the viewport + * @default 896 + */ + height: number + }; + /** + * Locator options + */ + locators?: { + /** + * Attribute used to locate elements by test id + * @default 'data-testid' + */ + testIdAttribute?: string + }; + /** + * Directory where screenshots will be saved when page.screenshot() is called + * If not set, all screenshots are saved to __screenshots__ directory in the same folder as the test file. + * If this is set, it will be resolved relative to the project root. + * @default __screenshots__ + */ + screenshotDirectory?: string; + /** + * Should Vitest take screenshots if the test fails + * @default !browser.ui + */ + screenshotFailures?: boolean; + /** + * Scripts injected into the tester iframe. + * @deprecated Will be removed in the future, use `testerHtmlPath` instead. + */ + testerScripts?: BrowserScript[]; + /** + * Path to the index.html file that will be used to run tests. + */ + testerHtmlPath?: string; + /** + * Scripts injected into the main window. + */ + orchestratorScripts?: BrowserScript[]; + /** + * Commands that will be executed on the server + * via the browser `import("@vitest/browser/context").commands` API. + * @see {@link https://vitest.dev/guide/browser/commands} + */ + commands?: Record>; + /** + * Timeout for connecting to the browser + * @default 30000 + */ + connectTimeout?: number; +} +interface BrowserCommandContext { + testPath: string | undefined; + provider: BrowserProvider; + project: TestProject; + /** @deprecated use `sessionId` instead */ + contextId: string; + sessionId: string; +} +interface BrowserServerStateSession { + project: TestProject; + connected: () => void; + fail: (v: Error) => void; +} +interface BrowserOrchestrator { + cleanupTesters: () => Promise; + createTesters: (options: BrowserTesterOptions) => Promise; + onCancel: (reason: CancelReason) => Promise; + $close: () => void; +} +interface BrowserServerState { + orchestrators: Map; +} +interface ParentProjectBrowser { + spawn: (project: TestProject) => ProjectBrowser; +} +interface ProjectBrowser { + vite: ViteDevServer; + state: BrowserServerState; + provider: BrowserProvider; + close: () => Promise; + initBrowserProvider: (project: TestProject) => Promise; + parseStacktrace: (stack: string) => ParsedStack[]; + parseErrorStacktrace: (error: ErrorWithDiff, options?: StackTraceParserOptions) => ParsedStack[]; +} +interface BrowserCommand { + (context: BrowserCommandContext, ...payload: Payload): Awaitable$1; +} +interface BrowserScript { + /** + * If "content" is provided and type is "module", this will be its identifier. + * + * If you are using TypeScript, you can add `.ts` extension here for example. + * @default `injected-${index}.js` + */ + id?: string; + /** + * JavaScript content to be injected. This string is processed by Vite plugins if type is "module". + * + * You can use `id` to give Vite a hint about the file extension. + */ + content?: string; + /** + * Path to the script. This value is resolved by Vite so it can be a node module or a file path. + */ + src?: string; + /** + * If the script should be loaded asynchronously. + */ + async?: boolean; + /** + * Script type. + * @default 'module' + */ + type?: string; +} +interface ResolvedBrowserOptions extends BrowserConfigOptions { + name: string; + providerOptions?: BrowserProviderOptions; + enabled: boolean; + headless: boolean; + isolate: boolean; + fileParallelism: boolean; + api: ApiConfig; + ui: boolean; + viewport: { + width: number + height: number + }; + screenshotFailures: boolean; + locators: { + testIdAttribute: string + }; +} + +declare class TestProject { + /** @deprecated */ + path: string | number; + options?: InitializeProjectOptions | undefined; + /** + * The global Vitest instance. + * @experimental The public Vitest API is experimental and does not follow semver. + */ + readonly vitest: Vitest; + /** + * Resolved global configuration. If there are no workspace projects, this will be the same as `config`. + */ + readonly globalConfig: ResolvedConfig; + /** + * Browser instance if the browser is enabled. This is initialized when the tests run for the first time. + */ + browser?: ProjectBrowser; + /** @deprecated use `vitest` instead */ + ctx: Vitest; + /** + * Temporary directory for the project. This is unique for each project. Vitest stores transformed content here. + */ + readonly tmpDir: string; + private runner; + private closingPromise; + private testFilesList; + private typecheckFilesList; + private _globalSetups?; + private _provided; + constructor(path: string | number, vitest: Vitest, options?: InitializeProjectOptions | undefined); + /** + * The unique hash of this project. This value is consistent between the reruns. + * + * It is based on the root of the project (not consistent between OS) and its name. + */ + get hash(): string; + // "provide" is a property, not a method to keep the context when destructed in the global setup, + // making it a method would be a breaking change, and can be done in Vitest 3 at minimum + /** + * Provide a value to the test context. This value will be available to all tests with `inject`. + */ + provide: (key: T, value: ProvidedContext[T]) => void; + /** + * Get the provided context. The project context is merged with the global context. + */ + getProvidedContext(): ProvidedContext; + /** + * Creates a new test specification. Specifications describe how to run tests. + * @param moduleId The file path + */ + createSpecification(moduleId: string, locations?: number[] | undefined, pool?: string): TestSpecification; + toJSON(): SerializedTestProject; + /** + * Vite's dev server instance. Every workspace project has its own server. + */ + get vite(): ViteDevServer; + /** + * Resolved project configuration. + */ + get config(): ResolvedConfig; + /** + * The name of the project or an empty string if not set. + */ + get name(): string; + /** + * The color used when reporting tasks of this project. + */ + get color(): ProjectName["color"]; + /** + * Serialized project configuration. This is the config that tests receive. + */ + get serializedConfig(): SerializedConfig; + /** @deprecated use `vite` instead */ + get server(): ViteDevServer; + /** + * Check if this is the root project. The root project is the one that has the root config. + */ + isRootProject(): boolean; + /** @deprecated use `isRootProject` instead */ + isCore(): boolean; + /** @deprecated use `createSpecification` instead */ + createSpec(moduleId: string, pool: string): WorkspaceSpec; + /** @deprecated */ + initializeGlobalSetup(): Promise; + onTestsRerun(cb: OnTestsRerunHandler): void; + /** @deprecated */ + teardownGlobalSetup(): Promise; + /** @deprecated use `vitest.logger` instead */ + get logger(): Logger; + // it's possible that file path was imported with different queries (?raw, ?url, etc) + /** @deprecated use `.vite` or `.browser.vite` directly */ + getModulesByFilepath(file: string): Set; + /** @deprecated use `.vite` or `.browser.vite` directly */ + getModuleById(id: string): ModuleNode | undefined; + /** @deprecated use `.vite` or `.browser.vite` directly */ + getSourceMapModuleById(id: string): TransformResult$1["map"] | undefined; + /** @deprecated use `vitest.reporters` instead */ + get reporters(): Reporter[]; + /** + * Get all files in the project that match the globs in the config and the filters. + * @param filters String filters to match the test files. + */ + globTestFiles(filters?: string[]): Promise<{ + /** + * Test files that match the filters. + */ + testFiles: string[] + /** + * Typecheck test files that match the filters. This will be empty unless `typecheck.enabled` is `true`. + */ + typecheckTestFiles: string[] + }>; + private globAllTestFiles; + isBrowserEnabled(): boolean; + private markTestFile; + /** @deprecated use `serializedConfig` instead */ + getSerializableConfig(): SerializedConfig; + /** + * Test if a file matches the test globs. This does the actual glob matching if the test is not cached, unlike `isCachedTestFile`. + */ + matchesTestGlob(moduleId: string, source?: () => string): boolean; + /** @deprecated use `matchesTestGlob` instead */ + isTargetFile(id: string, source?: string): Promise; + private isInSourceTestCode; + private filterFiles; + private _parentBrowser?; + /** + * Closes the project and all associated resources. This can only be called once; the closing promise is cached until the server restarts. + * If the resources are needed again, create a new project. + */ + close(): Promise; + /** + * Import a file using Vite module runner. + * @param moduleId The ID of the module in Vite module graph + */ + import(moduleId: string): Promise; + /** @deprecated use `name` instead */ + getName(): string; + /** @deprecated internal */ + setServer(options: UserConfig, server: ViteDevServer): Promise; + private _setHash; + private _serializeOverriddenConfig; + private clearTmpDir; + /** @deprecated */ + initBrowserProvider(): Promise; +} + +interface SerializedTestProject { + name: string; + serializedConfig: SerializedConfig; + context: ProvidedContext; +} +interface InitializeProjectOptions extends TestProjectInlineConfiguration { + configFile: string | false; +} + +/** +* @deprecated use TestSpecification instead +*/ +type WorkspaceSpec = TestSpecification & [project: TestProject, file: string, options: { + pool: Pool +}]; +type RunWithFiles = (files: TestSpecification[], invalidates?: string[]) => Awaitable$1; +interface ProcessPool { + name: string; + runTests: RunWithFiles; + collectTests: RunWithFiles; + close?: () => Awaitable$1; +} +declare function getFilePoolName(project: TestProject, file: string): Pool; + +interface TestRunResult { + testModules: TestModule[]; + unhandledErrors: unknown[]; +} + +interface SuiteResultCache { + failed: boolean; + duration: number; +} +declare class ResultsCache { + private cache; + private workspacesKeyMap; + private cachePath; + private version; + private root; + constructor(version: string); + getCachePath(): string | null; + setConfig(root: string, config: ResolvedConfig["cache"]): void; + getResults(key: string): SuiteResultCache | undefined; + readFromCache(): Promise; + updateResults(files: File[]): void; + removeFromCache(filepath: string): void; + writeToCache(): Promise; +} + +type FileStatsCache = Pick; +declare class FilesStatsCache { + cache: Map; + getStats(key: string): FileStatsCache | undefined; + populateStats(root: string, specs: TestSpecification[]): Promise; + updateStats(fsPath: string, key: string): Promise; + removeStats(fsPath: string): void; +} + +declare class VitestCache { + results: ResultsCache; + stats: FilesStatsCache; + constructor(version: string); + getFileTestResults(key: string): SuiteResultCache | undefined; + getFileStats(key: string): { + size: number + } | undefined; + static resolveCacheDir(root: string, dir?: string, projectName?: string): string; +} + +declare class VitestPackageInstaller { + isPackageExists(name: string, options?: { + paths?: string[] + }): boolean; + ensureInstalled(dependency: string, root: string, version?: string): Promise; +} + +declare class StateManager { + filesMap: Map; + pathsSet: Set; + idMap: Map; + taskFileMap: WeakMap; + errorsSet: Set; + processTimeoutCauses: Set; + reportedTasksMap: WeakMap; + blobs?: MergedBlobs; + catchError(err: unknown, type: string): void; + clearErrors(): void; + getUnhandledErrors(): unknown[]; + addProcessTimeoutCause(cause: string): void; + getProcessTimeoutCauses(): string[]; + getPaths(): string[]; + /** + * Return files that were running or collected. + */ + getFiles(keys?: string[]): File[]; + getTestModules(keys?: string[]): TestModule[]; + getFilepaths(): string[]; + getFailedFilepaths(): string[]; + collectPaths(paths?: string[]): void; + collectFiles(project: TestProject, files?: File[]): void; + clearFiles(project: TestProject, paths?: string[]): void; + updateId(task: Task, project: TestProject): void; + getReportedEntity(task: Task): TestModule | TestCase | TestSuite | undefined; + updateTasks(packs: TaskResultPack[]): void; + updateUserLog(log: UserConsoleLog): void; + getCountOfFailedTests(): number; + cancelFiles(files: string[], project: TestProject): void; +} + +interface VitestOptions { + packageInstaller?: VitestPackageInstaller; + stdin?: NodeJS.ReadStream; + stdout?: NodeJS.WriteStream | Writable; + stderr?: NodeJS.WriteStream | Writable; +} +declare class Vitest { + readonly mode: VitestRunMode; + /** + * Current Vitest version. + * @example '2.0.0' + */ + readonly version: string; + static readonly version: string; + /** + * The logger instance used to log messages. It's recommended to use this logger instead of `console`. + * It's possible to override stdout and stderr streams when initiating Vitest. + * @example + * new Vitest('test', { + * stdout: new Writable(), + * }) + */ + readonly logger: Logger; + /** + * The package installer instance used to install Vitest packages. + * @example + * await vitest.packageInstaller.ensureInstalled('@vitest/browser', process.cwd()) + */ + readonly packageInstaller: VitestPackageInstaller; + /** + * A path to the built Vitest directory. This is usually a folder in `node_modules`. + */ + readonly distPath: string; + /** + * A list of projects that are currently running. + * If projects were filtered with `--project` flag, they won't appear here. + */ + projects: TestProject[]; + private isFirstRun; + private restartsCount; + private readonly specifications; + private readonly watcher; + private pool; + private _config?; + private _vite?; + private _state?; + private _cache?; + private _snapshot?; + private _workspaceConfigPath?; + constructor(mode: VitestRunMode, cliOptions: UserConfig, options?: VitestOptions); + private _onRestartListeners; + private _onClose; + private _onSetServer; + private _onCancelListeners; + private _onUserTestsRerun; + private _onFilterWatchedSpecification; + /** @deprecated will be removed in 4.0, use `onFilterWatchedSpecification` instead */ + get invalidates(): Set; + /** @deprecated will be removed in 4.0, use `onFilterWatchedSpecification` instead */ + get changedTests(): Set; + /** + * The global config. + */ + get config(): ResolvedConfig; + /** @deprecated use `vitest.vite` instead */ + get server(): ViteDevServer; + /** + * Global Vite's dev server instance. + */ + get vite(): ViteDevServer; + /** + * The global test state manager. + * @experimental The State API is experimental and not subject to semver. + */ + get state(): StateManager; + /** + * The global snapshot manager. You can access the current state on `snapshot.summary`. + */ + get snapshot(): SnapshotManager; + /** + * Test results and test file stats cache. Primarily used by the sequencer to sort tests. + */ + get cache(): VitestCache; + /** @deprecated internal */ + setServer(options: UserConfig, server: ViteDevServer): Promise; + /** + * Inject new test projects into the workspace. + * @param config Glob, config path or a custom config options. + * @returns An array of new test projects. Can be empty if the name was filtered out. + */ + private injectTestProject; + /** + * Provide a value to the test context. This value will be available to all tests with `inject`. + */ + provide: (key: T, value: ProvidedContext[T]) => void; + /** + * Get global provided context. + */ + getProvidedContext(): ProvidedContext; + /** @deprecated use `getRootProject` instead */ + getCoreWorkspaceProject(): TestProject; + /** + * Return project that has the root (or "global") config. + */ + getRootProject(): TestProject; + /** + * @deprecated use Reported Task API instead + */ + getProjectByTaskId(taskId: string): TestProject; + getProjectByName(name: string): TestProject; + /** + * Import a file using Vite module runner. The file will be transformed by Vite and executed in a separate context. + * @param moduleId The ID of the module in Vite module graph + */ + import(moduleId: string): Promise; + private resolveWorkspaceConfigPath; + private resolveProjects; + /** + * Glob test files in every project and create a TestSpecification for each file and pool. + * @param filters String filters to match the test files. + */ + globTestSpecifications(filters?: string[]): Promise; + private initCoverageProvider; + /** + * Merge reports from multiple runs located in the specified directory (value from `--merge-reports` if not specified). + */ + mergeReports(directory?: string): Promise; + collect(filters?: string[]): Promise; + /** @deprecated use `getRelevantTestSpecifications` instead */ + listFiles(filters?: string[]): Promise; + /** + * Returns the list of test files that match the config and filters. + * @param filters String filters to match the test files + */ + getRelevantTestSpecifications(filters?: string[]): Promise; + /** + * Initialize reporters, the coverage provider, and run tests. + * This method can throw an error: + * - `FilesNotFoundError` if no tests are found + * - `GitNotFoundError` if `--related` flag is used, but git repository is not initialized + * - `Error` from the user reporters + * @param filters String filters to match the test files + */ + start(filters?: string[]): Promise; + /** + * Initialize reporters and the coverage provider. This method doesn't run any tests. + * If the `--watch` flag is provided, Vitest will still run changed tests even if this method was not called. + */ + init(): Promise; + /** + * @deprecated remove when vscode extension supports "getModuleSpecifications" + */ + getProjectsByTestFile(file: string): WorkspaceSpec[]; + /** @deprecated */ + getFileWorkspaceSpecs(file: string): WorkspaceSpec[]; + /** + * Get test specifications associated with the given module. If module is not a test file, an empty array is returned. + * + * **Note:** this method relies on a cache generated by `globTestSpecifications`. If the file was not processed yet, use `project.matchesGlobPattern` instead. + * @param moduleId The module ID to get test specifications for. + */ + getModuleSpecifications(moduleId: string): TestSpecification[]; + /** + * Vitest automatically caches test specifications for each file. This method clears the cache for the given file or the whole cache altogether. + */ + clearSpecificationsCache(moduleId?: string): void; + /** + * Run tests for the given test specifications. This does not trigger `onWatcher*` events. + * @param specifications A list of specifications to run. + * @param allTestsRun Indicates whether all tests were run. This only matters for coverage. + */ + runTestSpecifications(specifications: TestSpecification[], allTestsRun?: boolean): Promise; + /** + * Rerun files and trigger `onWatcherRerun`, `onWatcherStart` and `onTestsRerun` events. + * @param specifications A list of specifications to run. + * @param allTestsRun Indicates whether all tests were run. This only matters for coverage. + */ + rerunTestSpecifications(specifications: TestSpecification[], allTestsRun?: boolean): Promise; + private runFiles; + /** + * Collect tests in specified modules. Vitest will run the files to collect tests. + * @param specifications A list of specifications to run. + */ + collectTests(specifications: TestSpecification[]): Promise; + /** + * Gracefully cancel the current test run. Vitest will wait until all running tests are finished before cancelling. + */ + cancelCurrentRun(reason: CancelReason): Promise; + private initializeGlobalSetup; + /** + * Update snapshots in specified files. If no files are provided, it will update files with failed tests and obsolete snapshots. + * @param files The list of files on the file system + */ + updateSnapshot(files?: string[]): Promise; + /** + * Enable the mode that allows updating snapshots when running tests. + * This method doesn't run any tests. + * + * Every test that runs after this method is called will update snapshots. + * To disable the mode, call `resetSnapshotUpdate`. + */ + enableSnapshotUpdate(): void; + /** + * Disable the mode that allows updating snapshots when running tests. + */ + resetSnapshotUpdate(): void; + /** + * Set the global test name pattern to a regexp. + * This method doesn't run any tests. + */ + setGlobalTestNamePattern(pattern: string | RegExp): void; + /** + * Resets the global test name pattern. This method doesn't run any tests. + */ + resetGlobalTestNamePattern(): void; + private _rerunTimer; + // we can't use a single `triggerId` yet because vscode extension relies on this + private scheduleRerun; + /** + * Invalidate a file in all projects. + */ + invalidateFile(filepath: string): void; + /** @deprecated use `invalidateFile` */ + updateLastChanged(filepath: string): void; + private reportCoverage; + /** + * Closes all projects and their associated resources. + * This can only be called once; the closing promise is cached until the server restarts. + */ + close(): Promise; + /** + * Closes all projects and exit the process + * @param force If true, the process will exit immediately after closing the projects. + */ + exit(force?: boolean): Promise; + /** + * @deprecated use `globTestSpecifications` instead + */ + globTestSpecs(filters?: string[]): Promise; + /** + * @deprecated use `globTestSpecifications` instead + */ + globTestFiles(filters?: string[]): Promise; + /** @deprecated filter by `this.projects` yourself */ + getModuleProjects(filepath: string): TestProject[]; + /** + * Should the server be kept running after the tests are done. + */ + shouldKeepServer(): boolean; + /** + * Register a handler that will be called when the server is restarted due to a config change. + */ + onServerRestart(fn: OnServerRestartHandler): void; + /** + * Register a handler that will be called when the test run is cancelled with `vitest.cancelCurrentRun`. + */ + onCancel(fn: (reason: CancelReason) => Awaitable$1): void; + /** + * Register a handler that will be called when the server is closed. + */ + onClose(fn: () => Awaitable$1): void; + /** + * Register a handler that will be called when the tests are rerunning. + */ + onTestsRerun(fn: OnTestsRerunHandler): void; + /** + * Register a handler that will be called when a file is changed. + * This callback should return `true` of `false` indicating whether the test file needs to be rerun. + * @example + * const testsToRun = [resolve('./test.spec.ts')] + * vitest.onFilterWatchedSpecification(specification => testsToRun.includes(specification.moduleId)) + */ + onFilterWatchedSpecification(fn: (specification: TestSpecification) => boolean): void; + /** + * Check if the project with a given name should be included. + */ + matchesProjectFilter(name: string): boolean; +} +type OnServerRestartHandler = (reason?: string) => Promise | void; +type OnTestsRerunHandler = (testFiles: TestSpecification[]) => Promise | void; + +export { CoverageMap as C, TestSpecification as K, Logger as L, TestModule as M, TestProject as T, Vitest as V, VitestPackageInstaller as X, getFilePoolName as _, TestCase as a4, TestCollection as a5, BasicReporter as aC, BenchmarkReporter as aD, BenchmarkReportsMap as aE, DefaultReporter as aF, DotReporter as aG, GithubActionsReporter as aH, HangingProcessReporter as aI, JsonReporter as aJ, JUnitReporter as aK, ReportersMap as aL, TapFlatReporter as aM, TapReporter as aN, VerboseBenchmarkReporter as aO, VerboseReporter as aP, BaseReporter as aQ, TestSuite as ad }; +export type { SerializedTestProject as $, ApiConfig as A, BaseCoverageOptions as B, DepsOptimizationOptions as D, ProjectConfig as E, BenchmarkUserOptions as F, BrowserTesterOptions as G, VitestOptions as H, InlineConfig as I, TestSequencer as J, ModuleDiagnostic as N, OnServerRestartHandler as O, Pool as P, OnTestsRerunHandler as Q, ResolvedCoverageOptions as R, SerializedTestSpecification as S, UserWorkspaceConfig as U, WorkspaceProjectConfiguration as W, ProcessPool as Y, WorkspaceSpec as Z, ReportContext as a, HTMLOptions as a0, JsonOptions$1 as a1, JUnitOptions as a2, TaskOptions as a3, TestDiagnostic as a6, TestModuleState as a7, TestResult as a8, TestResultFailed as a9, ReportedHookContext as aA, TestRunEndReason as aB, BenchmarkBuiltinReporters as aR, BuiltinReporterOptions as aS, BuiltinReporters as aT, JsonAssertionResult as aU, JsonTestResult as aV, JsonTestResults as aW, TestResultPassed as aa, TestResultSkipped as ab, TestState as ac, TestSuiteState as ae, TestSequencerConstructor as af, BrowserBuiltinProvider as ag, BrowserCommand as ah, BrowserCommandContext as ai, BrowserInstanceOption as aj, BrowserModuleMocker as ak, BrowserOrchestrator as al, BrowserProvider as am, BrowserProviderInitializationOptions as an, BrowserProviderModule as ao, BrowserProviderOptions as ap, BrowserServerState as aq, BrowserServerStateSession as ar, CDPSession as as, ParentProjectBrowser as at, ProjectBrowser as au, ResolvedBrowserOptions as av, ResolvedProjectConfig as aw, ResolveSnapshotPathHandler as ax, ResolveSnapshotPathHandlerContext as ay, TestRunResult as az, TestProjectConfiguration as b, CoverageV8Options as c, UserProjectConfigFn as d, UserProjectConfigExport as e, TestProjectInlineConfiguration as f, WatcherTriggerPattern as g, CoverageProvider as h, CoverageProviderModule as i, CoverageReporter as j, CoverageProviderName as k, CoverageOptions as l, CoverageIstanbulOptions as m, CustomProviderOptions as n, Reporter as o, BrowserScript as p, BrowserConfigOptions as q, BuiltinEnvironment as r, VitestEnvironment as s, PoolOptions as t, CSSModuleScopeStrategy as u, VitestRunMode as v, TransformModePatterns as w, TypecheckConfig as x, UserConfig as y, ResolvedConfig as z }; diff --git a/node_modules/vitest/dist/chunks/rpc.-pEldfrD.js b/node_modules/vitest/dist/chunks/rpc.-pEldfrD.js new file mode 100644 index 0000000000..a48eb0174a --- /dev/null +++ b/node_modules/vitest/dist/chunks/rpc.-pEldfrD.js @@ -0,0 +1,83 @@ +import { getSafeTimers } from '@vitest/utils'; +import { c as createBirpc } from './index.B521nVV-.js'; +import { g as getWorkerState } from './utils.XdZDrNZV.js'; + +const { get } = Reflect; +function withSafeTimers(fn) { + const { setTimeout, clearTimeout, nextTick, setImmediate, clearImmediate } = getSafeTimers(); + const currentSetTimeout = globalThis.setTimeout; + const currentClearTimeout = globalThis.clearTimeout; + const currentSetImmediate = globalThis.setImmediate; + const currentClearImmediate = globalThis.clearImmediate; + const currentNextTick = globalThis.process?.nextTick; + try { + globalThis.setTimeout = setTimeout; + globalThis.clearTimeout = clearTimeout; + globalThis.setImmediate = setImmediate; + globalThis.clearImmediate = clearImmediate; + if (globalThis.process) globalThis.process.nextTick = nextTick; + const result = fn(); + return result; + } finally { + globalThis.setTimeout = currentSetTimeout; + globalThis.clearTimeout = currentClearTimeout; + globalThis.setImmediate = currentSetImmediate; + globalThis.clearImmediate = currentClearImmediate; + if (globalThis.process) nextTick(() => { + globalThis.process.nextTick = currentNextTick; + }); + } +} +const promises = /* @__PURE__ */ new Set(); +async function rpcDone() { + if (!promises.size) return; + const awaitable = Array.from(promises); + return Promise.all(awaitable); +} +function createRuntimeRpc(options) { + let setCancel = (_reason) => {}; + const onCancel = new Promise((resolve) => { + setCancel = resolve; + }); + const rpc = createSafeRpc(createBirpc({ onCancel: setCancel }, { + eventNames: [ + "onUserConsoleLog", + "onCollected", + "onCancel" + ], + onTimeoutError(functionName, args) { + let message = `[vitest-worker]: Timeout calling "${functionName}"`; + if (functionName === "fetch" || functionName === "transform" || functionName === "resolveId") message += ` with "${JSON.stringify(args)}"`; + // JSON.stringify cannot serialize Error instances + if (functionName === "onUnhandledError") message += ` with "${args[0]?.message || args[0]}"`; + throw new Error(message); + }, + ...options + })); + return { + rpc, + onCancel + }; +} +function createSafeRpc(rpc) { + return new Proxy(rpc, { get(target, p, handler) { + const sendCall = get(target, p, handler); + const safeSendCall = (...args) => withSafeTimers(async () => { + const result = sendCall(...args); + promises.add(result); + try { + return await result; + } finally { + promises.delete(result); + } + }); + safeSendCall.asEvent = sendCall.asEvent; + return safeSendCall; + } }); +} +function rpc() { + const { rpc } = getWorkerState(); + return rpc; +} + +export { rpcDone as a, createRuntimeRpc as c, rpc as r }; diff --git a/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js b/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js new file mode 100644 index 0000000000..9c62d6d1d5 --- /dev/null +++ b/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js @@ -0,0 +1,129 @@ +import { performance } from 'node:perf_hooks'; +import { startTests, collectTests } from '@vitest/runner'; +import { a as resolveSnapshotEnvironment, s as setupChaiConfig, r as resolveTestRunner } from './index.CwejwG0H.js'; +import { c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker } from './setup-common.Dd054P77.js'; +import { a as globalExpect, v as vi } from './vi.bdSIJ99Y.js'; +import { c as closeInspector } from './inspector.C914Efll.js'; +import { createRequire } from 'node:module'; +import timers from 'node:timers'; +import timersPromises from 'node:timers/promises'; +import util from 'node:util'; +import { getSafeTimers } from '@vitest/utils'; +import { KNOWN_ASSET_TYPES } from 'vite-node/constants'; +import { installSourcemapsSupport } from 'vite-node/source-map'; +import { V as VitestIndex } from './index.CdQS2e2Q.js'; +import { g as getWorkerState, r as resetModules } from './utils.XdZDrNZV.js'; +import 'chai'; +import 'node:path'; +import '../path.js'; +import 'node:url'; +import './rpc.-pEldfrD.js'; +import './index.B521nVV-.js'; +import './coverage.DVF1vEu8.js'; +import '@vitest/snapshot'; +import '@vitest/expect'; +import '@vitest/runner/utils'; +import './_commonjsHelpers.BFTU3MAI.js'; +import '@vitest/utils/error'; +import '@vitest/spy'; +import '@vitest/utils/source-map'; +import './date.Bq6ZW5rf.js'; +import './benchmark.CYdenmiT.js'; +import 'expect-type'; + +// this should only be used in Node +let globalSetup = false; +async function setupGlobalEnv(config, { environment }, executor) { + await setupCommonEnv(config); + Object.defineProperty(globalThis, "__vitest_index__", { + value: VitestIndex, + enumerable: false + }); + const state = getWorkerState(); + if (!state.config.snapshotOptions.snapshotEnvironment) state.config.snapshotOptions.snapshotEnvironment = await resolveSnapshotEnvironment(config, executor); + if (globalSetup) return; + globalSetup = true; + if (environment.transformMode === "web") { + const _require = createRequire(import.meta.url); + // always mock "required" `css` files, because we cannot process them + _require.extensions[".css"] = resolveCss; + _require.extensions[".scss"] = resolveCss; + _require.extensions[".sass"] = resolveCss; + _require.extensions[".less"] = resolveCss; + // since we are using Vite, we can assume how these will be resolved + KNOWN_ASSET_TYPES.forEach((type) => { + _require.extensions[`.${type}`] = resolveAsset; + }); + process.env.SSR = ""; + } else process.env.SSR = "1"; + // @ts-expect-error not typed global for patched timers + globalThis.__vitest_required__ = { + util, + timers, + timersPromises + }; + installSourcemapsSupport({ getSourceMap: (source) => state.moduleCache.getSourceMap(source) }); + if (!config.disableConsoleIntercept) await setupConsoleLogSpy(); +} +function resolveCss(mod) { + mod.exports = ""; +} +function resolveAsset(mod, url) { + mod.exports = url; +} +async function setupConsoleLogSpy() { + const { createCustomConsole } = await import('./console.CtFJOzRO.js'); + globalThis.console = createCustomConsole(); +} +async function withEnv({ environment }, options, fn) { + // @ts-expect-error untyped global + globalThis.__vitest_environment__ = environment.name; + globalExpect.setState({ environment: environment.name }); + const env = await environment.setup(globalThis, options); + try { + await fn(); + } finally { + // Run possible setTimeouts, e.g. the onces used by ConsoleLogSpy + const { setTimeout } = getSafeTimers(); + await new Promise((resolve) => setTimeout(resolve)); + await env.teardown(globalThis); + } +} + +// browser shouldn't call this! +async function run(method, files, config, environment, executor) { + const workerState = getWorkerState(); + const isIsolatedThreads = config.pool === "threads" && (config.poolOptions?.threads?.isolate ?? true); + const isIsolatedForks = config.pool === "forks" && (config.poolOptions?.forks?.isolate ?? true); + const isolate = isIsolatedThreads || isIsolatedForks; + await setupGlobalEnv(config, environment, executor); + await startCoverageInsideWorker(config.coverage, executor, { isolate }); + if (config.chaiConfig) setupChaiConfig(config.chaiConfig); + const runner = await resolveTestRunner(config, executor); + workerState.onCancel.then((reason) => { + closeInspector(config); + runner.cancel?.(reason); + }); + workerState.durations.prepare = performance.now() - workerState.durations.prepare; + workerState.durations.environment = performance.now(); + await withEnv(environment, environment.options || config.environmentOptions || {}, async () => { + workerState.durations.environment = performance.now() - workerState.durations.environment; + for (const file of files) { + if (isolate) { + executor.mocker.reset(); + resetModules(workerState.moduleCache, true); + } + workerState.filepath = file.filepath; + if (method === "run") await startTests([file], runner); + else await collectTests([file], runner); + // reset after tests, because user might call `vi.setConfig` in setupFile + vi.resetConfig(); + // mocks should not affect different files + vi.restoreAllMocks(); + } + await stopCoverageInsideWorker(config.coverage, executor, { isolate }); + }); + workerState.environmentTeardownRun = true; +} + +export { run }; diff --git a/node_modules/vitest/dist/chunks/setup-common.Dd054P77.js b/node_modules/vitest/dist/chunks/setup-common.Dd054P77.js new file mode 100644 index 0000000000..7287eac367 --- /dev/null +++ b/node_modules/vitest/dist/chunks/setup-common.Dd054P77.js @@ -0,0 +1,60 @@ +import { r as resolveCoverageProviderModule } from './coverage.DVF1vEu8.js'; +import { addSerializer } from '@vitest/snapshot'; +import { setSafeTimers } from '@vitest/utils'; + +async function startCoverageInsideWorker(options, loader, runtimeOptions) { + const coverageModule = await resolveCoverageProviderModule(options, loader); + if (coverageModule) return coverageModule.startCoverage?.(runtimeOptions); + return null; +} +async function takeCoverageInsideWorker(options, loader) { + const coverageModule = await resolveCoverageProviderModule(options, loader); + if (coverageModule) return coverageModule.takeCoverage?.({ moduleExecutionInfo: loader.moduleExecutionInfo }); + return null; +} +async function stopCoverageInsideWorker(options, loader, runtimeOptions) { + const coverageModule = await resolveCoverageProviderModule(options, loader); + if (coverageModule) return coverageModule.stopCoverage?.(runtimeOptions); + return null; +} + +let globalSetup = false; +async function setupCommonEnv(config) { + setupDefines(config.defines); + setupEnv(config.env); + if (globalSetup) return; + globalSetup = true; + setSafeTimers(); + if (config.globals) (await import('./globals.DEHgCU4V.js')).registerApiGlobally(); +} +function setupDefines(defines) { + for (const key in defines) globalThis[key] = defines[key]; +} +function setupEnv(env) { + if (typeof process === "undefined") return; + // same boolean-to-string assignment as VitestPlugin.configResolved + const { PROD, DEV,...restEnvs } = env; + process.env.PROD = PROD ? "1" : ""; + process.env.DEV = DEV ? "1" : ""; + for (const key in restEnvs) process.env[key] = env[key]; +} +async function loadDiffConfig(config, executor) { + if (typeof config.diff === "object") return config.diff; + if (typeof config.diff !== "string") return; + const diffModule = await executor.executeId(config.diff); + if (diffModule && typeof diffModule.default === "object" && diffModule.default != null) return diffModule.default; + else throw new Error(`invalid diff config file ${config.diff}. Must have a default export with config object`); +} +async function loadSnapshotSerializers(config, executor) { + const files = config.snapshotSerializers; + const snapshotSerializers = await Promise.all(files.map(async (file) => { + const mo = await executor.executeId(file); + if (!mo || typeof mo.default !== "object" || mo.default === null) throw new Error(`invalid snapshot serializer file ${file}. Must export a default object`); + const config = mo.default; + if (typeof config.test !== "function" || typeof config.serialize !== "function" && typeof config.print !== "function") throw new TypeError(`invalid snapshot serializer in ${file}. Must have a 'test' method along with either a 'serialize' or 'print' method.`); + return config; + })); + snapshotSerializers.forEach((serializer) => addSerializer(serializer)); +} + +export { stopCoverageInsideWorker as a, loadSnapshotSerializers as b, setupCommonEnv as c, loadDiffConfig as l, startCoverageInsideWorker as s, takeCoverageInsideWorker as t }; diff --git a/node_modules/vitest/dist/chunks/suite.d.FvehnV49.d.ts b/node_modules/vitest/dist/chunks/suite.d.FvehnV49.d.ts new file mode 100644 index 0000000000..02b5a10f68 --- /dev/null +++ b/node_modules/vitest/dist/chunks/suite.d.FvehnV49.d.ts @@ -0,0 +1,10 @@ +import { Test } from '@vitest/runner'; +import { c as BenchmarkAPI, a as BenchFunction } from './benchmark.d.BwvBVTda.js'; +import { Options } from 'tinybench'; +import '@vitest/runner/utils'; + +declare function getBenchOptions(key: Test): Options; +declare function getBenchFn(key: Test): BenchFunction; +declare const bench: BenchmarkAPI; + +export { getBenchOptions as a, bench as b, getBenchFn as g }; diff --git a/node_modules/vitest/dist/chunks/typechecker.DRKU1-1g.js b/node_modules/vitest/dist/chunks/typechecker.DRKU1-1g.js new file mode 100644 index 0000000000..d3a49f9aaf --- /dev/null +++ b/node_modules/vitest/dist/chunks/typechecker.DRKU1-1g.js @@ -0,0 +1,874 @@ +import nodeos__default from 'node:os'; +import { performance } from 'node:perf_hooks'; +import { TraceMap, generatedPositionFor, eachMapping } from '@vitest/utils/source-map'; +import { relative, basename, resolve, join } from 'pathe'; +import { x } from 'tinyexec'; +import { distDir } from '../path.js'; +import { getTests, generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes } from '@vitest/runner/utils'; +import '@vitest/utils'; +import { parseAstAsync } from 'vite'; + +function hasFailedSnapshot(suite) { + return getTests(suite).some((s) => { + return s.result?.errors?.some((e) => typeof e?.message === "string" && e.message.match(/Snapshot .* mismatched/)); + }); +} +function convertTasksToEvents(file, onTask) { + const packs = []; + const events = []; + function visit(suite) { + onTask?.(suite); + packs.push([ + suite.id, + suite.result, + suite.meta + ]); + events.push([ + suite.id, + "suite-prepare", + void 0 + ]); + suite.tasks.forEach((task) => { + if (task.type === "suite") visit(task); + else { + onTask?.(task); + if (suite.mode !== "skip" && suite.mode !== "todo") { + packs.push([ + task.id, + task.result, + task.meta + ]); + events.push([ + task.id, + "test-prepare", + void 0 + ]); + task.annotations.forEach((annotation) => { + events.push([ + task.id, + "test-annotation", + { annotation } + ]); + }); + events.push([ + task.id, + "test-finished", + void 0 + ]); + } + } + }); + events.push([ + suite.id, + "suite-finished", + void 0 + ]); + } + visit(file); + return { + packs, + events + }; +} + +const REGEXP_WRAP_PREFIX = "$$vitest:"; +function getOutputFile(config, reporter) { + if (!config?.outputFile) return; + if (typeof config.outputFile === "string") return config.outputFile; + return config.outputFile[reporter]; +} +/** +* Prepares `SerializedConfig` for serialization, e.g. `node:v8.serialize` +*/ +function wrapSerializableConfig(config) { + let testNamePattern = config.testNamePattern; + let defines = config.defines; + // v8 serialize does not support regex + if (testNamePattern && typeof testNamePattern !== "string") testNamePattern = `${REGEXP_WRAP_PREFIX}${testNamePattern.toString()}`; + // v8 serialize drops properties with undefined value + if (defines) defines = { + keys: Object.keys(defines), + original: defines + }; + return { + ...config, + testNamePattern, + defines + }; +} + +// AST walker module for ESTree compatible trees + + +// An ancestor walk keeps an array of ancestor nodes (including the +// current node) and passes them to the callback as third parameter +// (and also as state parameter when no other state is present). +function ancestor(node, visitors, baseVisitor, state, override) { + var ancestors = []; + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + baseVisitor[type](node, st, c); + if (visitors[type]) { visitors[type](node, st || ancestors, ancestors); } + if (isNew) { ancestors.pop(); } + })(node, state, override); +} + +function skipThrough(node, st, c) { c(node, st); } +function ignore(_node, _st, _c) {} + +// Node walkers. + +var base = {}; + +base.Program = base.BlockStatement = base.StaticBlock = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var stmt = list[i]; + + c(stmt, st, "Statement"); + } +}; +base.Statement = skipThrough; +base.EmptyStatement = ignore; +base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression = + function (node, st, c) { return c(node.expression, st, "Expression"); }; +base.IfStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Statement"); + if (node.alternate) { c(node.alternate, st, "Statement"); } +}; +base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); }; +base.BreakStatement = base.ContinueStatement = ignore; +base.WithStatement = function (node, st, c) { + c(node.object, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.SwitchStatement = function (node, st, c) { + c(node.discriminant, st, "Expression"); + for (var i = 0, list = node.cases; i < list.length; i += 1) { + var cs = list[i]; + + c(cs, st); + } +}; +base.SwitchCase = function (node, st, c) { + if (node.test) { c(node.test, st, "Expression"); } + for (var i = 0, list = node.consequent; i < list.length; i += 1) + { + var cons = list[i]; + + c(cons, st, "Statement"); + } +}; +base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) { + if (node.argument) { c(node.argument, st, "Expression"); } +}; +base.ThrowStatement = base.SpreadElement = + function (node, st, c) { return c(node.argument, st, "Expression"); }; +base.TryStatement = function (node, st, c) { + c(node.block, st, "Statement"); + if (node.handler) { c(node.handler, st); } + if (node.finalizer) { c(node.finalizer, st, "Statement"); } +}; +base.CatchClause = function (node, st, c) { + if (node.param) { c(node.param, st, "Pattern"); } + c(node.body, st, "Statement"); +}; +base.WhileStatement = base.DoWhileStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForStatement = function (node, st, c) { + if (node.init) { c(node.init, st, "ForInit"); } + if (node.test) { c(node.test, st, "Expression"); } + if (node.update) { c(node.update, st, "Expression"); } + c(node.body, st, "Statement"); +}; +base.ForInStatement = base.ForOfStatement = function (node, st, c) { + c(node.left, st, "ForInit"); + c(node.right, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForInit = function (node, st, c) { + if (node.type === "VariableDeclaration") { c(node, st); } + else { c(node, st, "Expression"); } +}; +base.DebuggerStatement = ignore; + +base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); }; +base.VariableDeclaration = function (node, st, c) { + for (var i = 0, list = node.declarations; i < list.length; i += 1) + { + var decl = list[i]; + + c(decl, st); + } +}; +base.VariableDeclarator = function (node, st, c) { + c(node.id, st, "Pattern"); + if (node.init) { c(node.init, st, "Expression"); } +}; + +base.Function = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + c(param, st, "Pattern"); + } + c(node.body, st, node.expression ? "Expression" : "Statement"); +}; + +base.Pattern = function (node, st, c) { + if (node.type === "Identifier") + { c(node, st, "VariablePattern"); } + else if (node.type === "MemberExpression") + { c(node, st, "MemberPattern"); } + else + { c(node, st); } +}; +base.VariablePattern = ignore; +base.MemberPattern = skipThrough; +base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); }; +base.ArrayPattern = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Pattern"); } + } +}; +base.ObjectPattern = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + if (prop.type === "Property") { + if (prop.computed) { c(prop.key, st, "Expression"); } + c(prop.value, st, "Pattern"); + } else if (prop.type === "RestElement") { + c(prop.argument, st, "Pattern"); + } + } +}; + +base.Expression = skipThrough; +base.ThisExpression = base.Super = base.MetaProperty = ignore; +base.ArrayExpression = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Expression"); } + } +}; +base.ObjectExpression = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) + { + var prop = list[i]; + + c(prop, st); + } +}; +base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration; +base.SequenceExpression = function (node, st, c) { + for (var i = 0, list = node.expressions; i < list.length; i += 1) + { + var expr = list[i]; + + c(expr, st, "Expression"); + } +}; +base.TemplateLiteral = function (node, st, c) { + for (var i = 0, list = node.quasis; i < list.length; i += 1) + { + var quasi = list[i]; + + c(quasi, st); + } + + for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1) + { + var expr = list$1[i$1]; + + c(expr, st, "Expression"); + } +}; +base.TemplateElement = ignore; +base.UnaryExpression = base.UpdateExpression = function (node, st, c) { + c(node.argument, st, "Expression"); +}; +base.BinaryExpression = base.LogicalExpression = function (node, st, c) { + c(node.left, st, "Expression"); + c(node.right, st, "Expression"); +}; +base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) { + c(node.left, st, "Pattern"); + c(node.right, st, "Expression"); +}; +base.ConditionalExpression = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Expression"); + c(node.alternate, st, "Expression"); +}; +base.NewExpression = base.CallExpression = function (node, st, c) { + c(node.callee, st, "Expression"); + if (node.arguments) + { for (var i = 0, list = node.arguments; i < list.length; i += 1) + { + var arg = list[i]; + + c(arg, st, "Expression"); + } } +}; +base.MemberExpression = function (node, st, c) { + c(node.object, st, "Expression"); + if (node.computed) { c(node.property, st, "Expression"); } +}; +base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) { + if (node.declaration) + { c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); } + if (node.source) { c(node.source, st, "Expression"); } +}; +base.ExportAllDeclaration = function (node, st, c) { + if (node.exported) + { c(node.exported, st); } + c(node.source, st, "Expression"); +}; +base.ImportDeclaration = function (node, st, c) { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) + { + var spec = list[i]; + + c(spec, st); + } + c(node.source, st, "Expression"); +}; +base.ImportExpression = function (node, st, c) { + c(node.source, st, "Expression"); +}; +base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore; + +base.TaggedTemplateExpression = function (node, st, c) { + c(node.tag, st, "Expression"); + c(node.quasi, st, "Expression"); +}; +base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); }; +base.Class = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + if (node.superClass) { c(node.superClass, st, "Expression"); } + c(node.body, st); +}; +base.ClassBody = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var elt = list[i]; + + c(elt, st); + } +}; +base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) { + if (node.computed) { c(node.key, st, "Expression"); } + if (node.value) { c(node.value, st, "Expression"); } +}; + +async function collectTests(ctx, filepath) { + const request = await ctx.vitenode.transformRequest(filepath, filepath); + if (!request) return null; + const ast = await parseAstAsync(request.code); + const testFilepath = relative(ctx.config.root, filepath); + const projectName = ctx.name; + const typecheckSubprojectName = projectName ? `${projectName}:__typecheck__` : "__typecheck__"; + const file = { + filepath, + type: "suite", + id: generateHash(`${testFilepath}${typecheckSubprojectName}`), + name: testFilepath, + mode: "run", + tasks: [], + start: ast.start, + end: ast.end, + projectName, + meta: { typecheck: true }, + file: null + }; + file.file = file; + const definitions = []; + const getName = (callee) => { + if (!callee) return null; + if (callee.type === "Identifier") return callee.name; + if (callee.type === "CallExpression") return getName(callee.callee); + if (callee.type === "TaggedTemplateExpression") return getName(callee.tag); + if (callee.type === "MemberExpression") { + if (callee.object?.type === "Identifier" && [ + "it", + "test", + "describe", + "suite" + ].includes(callee.object.name)) return callee.object?.name; + // direct call as `__vite_ssr_exports_0__.test()` + if (callee.object?.name?.startsWith("__vite_ssr_")) return getName(callee.property); + // call as `__vite_ssr__.test.skip()` + return getName(callee.object?.property); + } + // unwrap (0, ...) + if (callee.type === "SequenceExpression" && callee.expressions.length === 2) { + const [e0, e1] = callee.expressions; + if (e0.type === "Literal" && e0.value === 0) return getName(e1); + } + return null; + }; + ancestor(ast, { CallExpression(node) { + const { callee } = node; + const name = getName(callee); + if (!name) return; + if (![ + "it", + "test", + "describe", + "suite" + ].includes(name)) return; + const property = callee?.property?.name; + let mode = !property || property === name ? "run" : property; + // they will be picked up in the next iteration + if ([ + "each", + "for", + "skipIf", + "runIf" + ].includes(mode)) return; + let start; + const end = node.end; + // .each + if (callee.type === "CallExpression") start = callee.end; + else if (callee.type === "TaggedTemplateExpression") start = callee.end + 1; + else start = node.start; + const { arguments: [messageNode] } = node; + const isQuoted = messageNode?.type === "Literal" || messageNode?.type === "TemplateLiteral"; + const message = isQuoted ? request.code.slice(messageNode.start + 1, messageNode.end - 1) : request.code.slice(messageNode.start, messageNode.end); + // cannot statically analyze, so we always skip it + if (mode === "skipIf" || mode === "runIf") mode = "skip"; + definitions.push({ + start, + end, + name: message, + type: name === "it" || name === "test" ? "test" : "suite", + mode, + task: null + }); + } }); + let lastSuite = file; + const updateLatestSuite = (index) => { + while (lastSuite.suite && lastSuite.end < index) lastSuite = lastSuite.suite; + return lastSuite; + }; + definitions.sort((a, b) => a.start - b.start).forEach((definition) => { + const latestSuite = updateLatestSuite(definition.start); + let mode = definition.mode; + if (latestSuite.mode !== "run") + // inherit suite mode, if it's set + mode = latestSuite.mode; + if (definition.type === "suite") { + const task = { + type: definition.type, + id: "", + suite: latestSuite, + file, + tasks: [], + mode, + name: definition.name, + end: definition.end, + start: definition.start, + meta: { typecheck: true } + }; + definition.task = task; + latestSuite.tasks.push(task); + lastSuite = task; + return; + } + const task = { + type: definition.type, + id: "", + suite: latestSuite, + file, + mode, + timeout: 0, + context: {}, + name: definition.name, + end: definition.end, + start: definition.start, + annotations: [], + meta: { typecheck: true } + }; + definition.task = task; + latestSuite.tasks.push(task); + }); + calculateSuiteHash(file); + const hasOnly = someTasksAreOnly(file); + interpretTaskModes(file, ctx.config.testNamePattern, void 0, hasOnly, false, ctx.config.allowOnly); + return { + file, + parsed: request.code, + filepath, + map: request.map, + definitions + }; +} + +const newLineRegExp = /\r?\n/; +const errCodeRegExp = /error TS(?\d+)/; +async function makeTscErrorInfo(errInfo) { + const [errFilePathPos = "", ...errMsgRawArr] = errInfo.split(":"); + if (!errFilePathPos || errMsgRawArr.length === 0 || errMsgRawArr.join("").length === 0) return ["unknown filepath", null]; + const errMsgRaw = errMsgRawArr.join("").trim(); + // get filePath, line, col + const [errFilePath, errPos] = errFilePathPos.slice(0, -1).split("("); + if (!errFilePath || !errPos) return ["unknown filepath", null]; + const [errLine, errCol] = errPos.split(","); + if (!errLine || !errCol) return [errFilePath, null]; + // get errCode, errMsg + const execArr = errCodeRegExp.exec(errMsgRaw); + if (!execArr) return [errFilePath, null]; + const errCodeStr = execArr.groups?.errCode ?? ""; + if (!errCodeStr) return [errFilePath, null]; + const line = Number(errLine); + const col = Number(errCol); + const errCode = Number(errCodeStr); + return [errFilePath, { + filePath: errFilePath, + errCode, + line, + column: col, + errMsg: errMsgRaw.slice(`error TS${errCode} `.length) + }]; +} +async function getRawErrsMapFromTsCompile(tscErrorStdout) { + const rawErrsMap = /* @__PURE__ */ new Map(); + // Merge details line with main line (i.e. which contains file path) + const infos = await Promise.all(tscErrorStdout.split(newLineRegExp).reduce((prev, next) => { + if (!next) return prev; + else if (!next.startsWith(" ")) prev.push(next); + else prev[prev.length - 1] += `\n${next}`; + return prev; + }, []).map((errInfoLine) => makeTscErrorInfo(errInfoLine))); + infos.forEach(([errFilePath, errInfo]) => { + if (!errInfo) return; + if (!rawErrsMap.has(errFilePath)) rawErrsMap.set(errFilePath, [errInfo]); + else rawErrsMap.get(errFilePath)?.push(errInfo); + }); + return rawErrsMap; +} + +function createIndexMap(source) { + const map = /* @__PURE__ */ new Map(); + let index = 0; + let line = 1; + let column = 1; + for (const char of source) { + map.set(`${line}:${column}`, index++); + if (char === "\n" || char === "\r\n") { + line++; + column = 0; + } else column++; + } + return map; +} + +class TypeCheckError extends Error { + name = "TypeCheckError"; + constructor(message, stacks) { + super(message); + this.message = message; + this.stacks = stacks; + } +} +class Typechecker { + _onParseStart; + _onParseEnd; + _onWatcherRerun; + _result = { + files: [], + sourceErrors: [], + time: 0 + }; + _startTime = 0; + _output = ""; + _tests = {}; + process; + files = []; + constructor(project) { + this.project = project; + } + setFiles(files) { + this.files = files; + } + onParseStart(fn) { + this._onParseStart = fn; + } + onParseEnd(fn) { + this._onParseEnd = fn; + } + onWatcherRerun(fn) { + this._onWatcherRerun = fn; + } + async collectFileTests(filepath) { + return collectTests(this.project, filepath); + } + getFiles() { + return this.files; + } + async collectTests() { + const tests = (await Promise.all(this.getFiles().map((filepath) => this.collectFileTests(filepath)))).reduce((acc, data) => { + if (!data) return acc; + acc[data.filepath] = data; + return acc; + }, {}); + this._tests = tests; + return tests; + } + markPassed(file) { + if (!file.result?.state) file.result = { state: "pass" }; + const markTasks = (tasks) => { + for (const task of tasks) { + if ("tasks" in task) markTasks(task.tasks); + if (!task.result?.state && (task.mode === "run" || task.mode === "queued")) task.result = { state: "pass" }; + } + }; + markTasks(file.tasks); + } + async prepareResults(output) { + const typeErrors = await this.parseTscLikeOutput(output); + const testFiles = new Set(this.getFiles()); + if (!this._tests) this._tests = await this.collectTests(); + const sourceErrors = []; + const files = []; + testFiles.forEach((path) => { + const { file, definitions, map, parsed } = this._tests[path]; + const errors = typeErrors.get(path); + files.push(file); + if (!errors) { + this.markPassed(file); + return; + } + const sortedDefinitions = [...definitions.sort((a, b) => b.start - a.start)]; + // has no map for ".js" files that use // @ts-check + const traceMap = map && new TraceMap(map); + const indexMap = createIndexMap(parsed); + const markState = (task, state) => { + task.result = { state: task.mode === "run" || task.mode === "only" ? state : task.mode }; + if (task.suite) markState(task.suite, state); + else if (task.file && task !== task.file) markState(task.file, state); + }; + errors.forEach(({ error, originalError }) => { + const processedPos = traceMap ? findGeneratedPosition(traceMap, { + line: originalError.line, + column: originalError.column, + source: basename(path) + }) : originalError; + const line = processedPos.line ?? originalError.line; + const column = processedPos.column ?? originalError.column; + const index = indexMap.get(`${line}:${column}`); + const definition = index != null && sortedDefinitions.find((def) => def.start <= index && def.end >= index); + const suite = definition ? definition.task : file; + const state = suite.mode === "run" || suite.mode === "only" ? "fail" : suite.mode; + const errors = suite.result?.errors || []; + suite.result = { + state, + errors + }; + errors.push(error); + if (state === "fail") { + if (suite.suite) markState(suite.suite, "fail"); + else if (suite.file && suite !== suite.file) markState(suite.file, "fail"); + } + }); + this.markPassed(file); + }); + typeErrors.forEach((errors, path) => { + if (!testFiles.has(path)) sourceErrors.push(...errors.map(({ error }) => error)); + }); + return { + files, + sourceErrors, + time: performance.now() - this._startTime + }; + } + async parseTscLikeOutput(output) { + const errorsMap = await getRawErrsMapFromTsCompile(output); + const typesErrors = /* @__PURE__ */ new Map(); + errorsMap.forEach((errors, path) => { + const filepath = resolve(this.project.config.root, path); + const suiteErrors = errors.map((info) => { + const limit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + // Some expect-type errors have the most useful information on the second line e.g. `This expression is not callable.\n Type 'ExpectString' has no call signatures.` + const errMsg = info.errMsg.replace(/\r?\n\s*(Type .* has no call signatures)/g, " $1"); + const error = new TypeCheckError(errMsg, [{ + file: filepath, + line: info.line, + column: info.column, + method: "" + }]); + Error.stackTraceLimit = limit; + return { + originalError: info, + error: { + name: error.name, + message: errMsg, + stacks: error.stacks, + stack: "" + } + }; + }); + typesErrors.set(filepath, suiteErrors); + }); + return typesErrors; + } + async stop() { + this.process?.kill(); + this.process = void 0; + } + async ensurePackageInstalled(ctx, checker) { + if (checker !== "tsc" && checker !== "vue-tsc") return; + const packageName = checker === "tsc" ? "typescript" : "vue-tsc"; + await ctx.packageInstaller.ensureInstalled(packageName, ctx.config.root); + } + getExitCode() { + return this.process?.exitCode != null && this.process.exitCode; + } + getOutput() { + return this._output; + } + async spawn() { + const { root, watch, typecheck } = this.project.config; + const args = [ + "--noEmit", + "--pretty", + "false", + "--incremental", + "--tsBuildInfoFile", + join(process.versions.pnp ? join(nodeos__default.tmpdir(), this.project.hash) : distDir, "tsconfig.tmp.tsbuildinfo") + ]; + // use builtin watcher because it's faster + if (watch) args.push("--watch"); + if (typecheck.allowJs) args.push("--allowJs", "--checkJs"); + if (typecheck.tsconfig) args.push("-p", resolve(root, typecheck.tsconfig)); + this._output = ""; + this._startTime = performance.now(); + const child = x(typecheck.checker, args, { + nodeOptions: { + cwd: root, + stdio: "pipe" + }, + throwOnError: false + }); + this.process = child.process; + let rerunTriggered = false; + let dataReceived = false; + return new Promise((resolve, reject) => { + if (!child.process || !child.process.stdout) { + reject(new Error(`Failed to initialize ${typecheck.checker}. This is a bug in Vitest - please, open an issue with reproduction.`)); + return; + } + child.process.stdout.on("data", (chunk) => { + dataReceived = true; + this._output += chunk; + if (!watch) return; + if (this._output.includes("File change detected") && !rerunTriggered) { + this._onWatcherRerun?.(); + this._startTime = performance.now(); + this._result.sourceErrors = []; + this._result.files = []; + this._tests = null; + rerunTriggered = true; + } + if (/Found \w+ errors*. Watching for/.test(this._output)) { + rerunTriggered = false; + this.prepareResults(this._output).then((result) => { + this._result = result; + this._onParseEnd?.(result); + }); + this._output = ""; + } + }); + const timeout = setTimeout(() => reject(new Error(`${typecheck.checker} spawn timed out`)), this.project.config.typecheck.spawnTimeout); + function onError(cause) { + clearTimeout(timeout); + reject(new Error("Spawning typechecker failed - is typescript installed?", { cause })); + } + child.process.once("spawn", () => { + this._onParseStart?.(); + child.process?.off("error", onError); + clearTimeout(timeout); + if (process.platform === "win32") + // on Windows, the process might be spawned but fail to start + // we wait for a potential error here. if "close" event didn't trigger, + // we resolve the promise + setTimeout(() => { + resolve({ result: child }); + }, 200); + else resolve({ result: child }); + }); + if (process.platform === "win32") child.process.once("close", (code) => { + if (code != null && code !== 0 && !dataReceived) onError(new Error(`The ${typecheck.checker} command exited with code ${code}.`)); + }); + child.process.once("error", onError); + }); + } + async start() { + if (this.process) return; + const { watch } = this.project.config; + const { result: child } = await this.spawn(); + if (!watch) { + await child; + this._result = await this.prepareResults(this._output); + await this._onParseEnd?.(this._result); + } + } + getResult() { + return this._result; + } + getTestFiles() { + return Object.values(this._tests || {}).map((i) => i.file); + } + getTestPacksAndEvents() { + const packs = []; + const events = []; + for (const { file } of Object.values(this._tests || {})) { + const result = convertTasksToEvents(file); + packs.push(...result.packs); + events.push(...result.events); + } + return { + packs, + events + }; + } +} +function findGeneratedPosition(traceMap, { line, column, source }) { + const found = generatedPositionFor(traceMap, { + line, + column, + source + }); + if (found.line !== null) return found; + // find the next source token position when the exact error position doesn't exist in source map. + // this can happen, for example, when the type error is in the comment "// @ts-expect-error" + // and comments are stripped away in the generated code. + const mappings = []; + eachMapping(traceMap, (m) => { + if (m.source === source && m.originalLine !== null && m.originalColumn !== null && (line === m.originalLine ? column < m.originalColumn : line < m.originalLine)) mappings.push(m); + }); + const next = mappings.sort((a, b) => a.originalLine === b.originalLine ? a.originalColumn - b.originalColumn : a.originalLine - b.originalLine).at(0); + if (next) return { + line: next.generatedLine, + column: next.generatedColumn + }; + return { + line: null, + column: null + }; +} + +export { TypeCheckError as T, Typechecker as a, convertTasksToEvents as c, getOutputFile as g, hasFailedSnapshot as h, wrapSerializableConfig as w }; diff --git a/node_modules/vitest/dist/chunks/utils.CAioKnHs.js b/node_modules/vitest/dist/chunks/utils.CAioKnHs.js new file mode 100644 index 0000000000..70437e64eb --- /dev/null +++ b/node_modules/vitest/dist/chunks/utils.CAioKnHs.js @@ -0,0 +1,61 @@ +import { parseRegexp } from '@vitest/utils'; + +const REGEXP_WRAP_PREFIX = "$$vitest:"; +// Store global APIs in case process is overwritten by tests +const processSend = process.send?.bind(process); +const processOn = process.on?.bind(process); +const processOff = process.off?.bind(process); +const dispose = []; +function createThreadsRpcOptions({ port }) { + return { + post: (v) => { + port.postMessage(v); + }, + on: (fn) => { + port.addListener("message", fn); + } + }; +} +function disposeInternalListeners() { + for (const fn of dispose) try { + fn(); + } catch {} + dispose.length = 0; +} +function createForksRpcOptions(nodeV8) { + return { + serialize: nodeV8.serialize, + deserialize: (v) => nodeV8.deserialize(Buffer.from(v)), + post(v) { + processSend(v); + }, + on(fn) { + const handler = (message, ...extras) => { + // Do not react on Tinypool's internal messaging + if (message?.__tinypool_worker_message__) return; + return fn(message, ...extras); + }; + processOn("message", handler); + dispose.push(() => processOff("message", handler)); + } + }; +} +/** +* Reverts the wrapping done by `utils/config-helpers.ts`'s `wrapSerializableConfig` +*/ +function unwrapSerializableConfig(config) { + if (config.testNamePattern && typeof config.testNamePattern === "string") { + const testNamePattern = config.testNamePattern; + if (testNamePattern.startsWith(REGEXP_WRAP_PREFIX)) config.testNamePattern = parseRegexp(testNamePattern.slice(REGEXP_WRAP_PREFIX.length)); + } + if (config.defines && Array.isArray(config.defines.keys) && config.defines.original) { + const { keys, original } = config.defines; + const defines = {}; + // Apply all keys from the original. Entries which had undefined value are missing from original now + for (const key of keys) defines[key] = original[key]; + config.defines = defines; + } + return config; +} + +export { createThreadsRpcOptions as a, createForksRpcOptions as c, disposeInternalListeners as d, unwrapSerializableConfig as u }; diff --git a/node_modules/vitest/dist/chunks/utils.XdZDrNZV.js b/node_modules/vitest/dist/chunks/utils.XdZDrNZV.js new file mode 100644 index 0000000000..b71102f3e9 --- /dev/null +++ b/node_modules/vitest/dist/chunks/utils.XdZDrNZV.js @@ -0,0 +1,65 @@ +import { getSafeTimers } from '@vitest/utils'; + +const NAME_WORKER_STATE = "__vitest_worker__"; +function getWorkerState() { + // @ts-expect-error untyped global + const workerState = globalThis[NAME_WORKER_STATE]; + if (!workerState) { + const errorMsg = "Vitest failed to access its internal state.\n\nOne of the following is possible:\n- \"vitest\" is imported directly without running \"vitest\" command\n- \"vitest\" is imported inside \"globalSetup\" (to fix this, use \"setupFiles\" instead, because \"globalSetup\" runs in a different context)\n- \"vitest\" is imported inside Vite / Vitest config file\n- Otherwise, it might be a Vitest bug. Please report it to https://github.com/vitest-dev/vitest/issues\n"; + throw new Error(errorMsg); + } + return workerState; +} +function provideWorkerState(context, state) { + Object.defineProperty(context, NAME_WORKER_STATE, { + value: state, + configurable: true, + writable: true, + enumerable: false + }); + return state; +} +function getCurrentEnvironment() { + const state = getWorkerState(); + return state?.environment.name; +} +function isChildProcess() { + return typeof process !== "undefined" && !!process.send; +} +function setProcessTitle(title) { + try { + process.title = `node (${title})`; + } catch {} +} +function resetModules(modules, resetMocks = false) { + const skipPaths = [ + /\/vitest\/dist\//, + /\/vite-node\/dist\//, + /vitest-virtual-\w+\/dist/, + /@vitest\/dist/, + ...!resetMocks ? [/^mock:/] : [] + ]; + modules.forEach((mod, path) => { + if (skipPaths.some((re) => re.test(path))) return; + modules.invalidateModule(mod); + }); +} +function waitNextTick() { + const { setTimeout } = getSafeTimers(); + return new Promise((resolve) => setTimeout(resolve, 0)); +} +async function waitForImportsToResolve() { + await waitNextTick(); + const state = getWorkerState(); + const promises = []; + let resolvingCount = 0; + for (const mod of state.moduleCache.values()) { + if (mod.promise && !mod.evaluated) promises.push(mod.promise); + if (mod.resolving) resolvingCount++; + } + if (!promises.length && !resolvingCount) return; + await Promise.allSettled(promises); + await waitForImportsToResolve(); +} + +export { getCurrentEnvironment as a, getWorkerState as g, isChildProcess as i, provideWorkerState as p, resetModules as r, setProcessTitle as s, waitForImportsToResolve as w }; diff --git a/node_modules/vitest/dist/chunks/vi.bdSIJ99Y.js b/node_modules/vitest/dist/chunks/vi.bdSIJ99Y.js new file mode 100644 index 0000000000..a021d20886 --- /dev/null +++ b/node_modules/vitest/dist/chunks/vi.bdSIJ99Y.js @@ -0,0 +1,4015 @@ +import { equals, iterableEquality, subsetEquality, JestExtend, JestChaiExpect, JestAsymmetricMatchers, GLOBAL_EXPECT, ASYMMETRIC_MATCHERS_OBJECT, getState, setState, addCustomEqualityTesters, customMatchers } from '@vitest/expect'; +import { getCurrentTest } from '@vitest/runner'; +import { getNames, getTestName } from '@vitest/runner/utils'; +import * as chai$1 from 'chai'; +import { g as getWorkerState, a as getCurrentEnvironment, i as isChildProcess, w as waitForImportsToResolve, r as resetModules } from './utils.XdZDrNZV.js'; +import { getSafeTimers, assertTypes, createSimpleStackTrace } from '@vitest/utils'; +import { g as getDefaultExportFromCjs, c as commonjsGlobal } from './_commonjsHelpers.BFTU3MAI.js'; +import { stripSnapshotIndentation, addSerializer, SnapshotClient } from '@vitest/snapshot'; +import '@vitest/utils/error'; +import { fn, spyOn, mocks, isMockFunction } from '@vitest/spy'; +import { parseSingleStack } from '@vitest/utils/source-map'; +import { R as RealDate, r as resetDate, m as mockDate } from './date.Bq6ZW5rf.js'; + +// these matchers are not supported because they don't make sense with poll +const unsupported = [ + "matchSnapshot", + "toMatchSnapshot", + "toMatchInlineSnapshot", + "toThrowErrorMatchingSnapshot", + "toThrowErrorMatchingInlineSnapshot", + "throws", + "Throw", + "throw", + "toThrow", + "toThrowError" +]; +function createExpectPoll(expect) { + return function poll(fn, options = {}) { + const state = getWorkerState(); + const defaults = state.config.expect?.poll ?? {}; + const { interval = defaults.interval ?? 50, timeout = defaults.timeout ?? 1e3, message } = options; + // @ts-expect-error private poll access + const assertion = expect(null, message).withContext({ poll: true }); + fn = fn.bind(assertion); + const test = chai$1.util.flag(assertion, "vitest-test"); + if (!test) throw new Error("expect.poll() must be called inside a test"); + const proxy = new Proxy(assertion, { get(target, key, receiver) { + const assertionFunction = Reflect.get(target, key, receiver); + if (typeof assertionFunction !== "function") return assertionFunction instanceof chai$1.Assertion ? proxy : assertionFunction; + if (key === "assert") return assertionFunction; + if (typeof key === "string" && unsupported.includes(key)) throw new SyntaxError(`expect.poll() is not supported in combination with .${key}(). Use vi.waitFor() if your assertion condition is unstable.`); + return function(...args) { + const STACK_TRACE_ERROR = new Error("STACK_TRACE_ERROR"); + const promise = () => new Promise((resolve, reject) => { + let intervalId; + let timeoutId; + let lastError; + const { setTimeout, clearTimeout } = getSafeTimers(); + const check = async () => { + try { + chai$1.util.flag(assertion, "_name", key); + const obj = await fn(); + chai$1.util.flag(assertion, "object", obj); + resolve(await assertionFunction.call(assertion, ...args)); + clearTimeout(intervalId); + clearTimeout(timeoutId); + } catch (err) { + lastError = err; + if (!chai$1.util.flag(assertion, "_isLastPollAttempt")) intervalId = setTimeout(check, interval); + } + }; + timeoutId = setTimeout(() => { + clearTimeout(intervalId); + chai$1.util.flag(assertion, "_isLastPollAttempt", true); + const rejectWithCause = (cause) => { + reject(copyStackTrace$1(new Error("Matcher did not succeed in time.", { cause }), STACK_TRACE_ERROR)); + }; + check().then(() => rejectWithCause(lastError)).catch((e) => rejectWithCause(e)); + }, timeout); + check(); + }); + let awaited = false; + test.onFinished ??= []; + test.onFinished.push(() => { + if (!awaited) { + const negated = chai$1.util.flag(assertion, "negate") ? "not." : ""; + const name = chai$1.util.flag(assertion, "_poll.element") ? "element(locator)" : "poll(assertion)"; + const assertionString = `expect.${name}.${negated}${String(key)}()`; + const error = new Error(`${assertionString} was not awaited. This assertion is asynchronous and must be awaited; otherwise, it is not executed to avoid unhandled rejections:\n\nawait ${assertionString}\n`); + throw copyStackTrace$1(error, STACK_TRACE_ERROR); + } + }); + let resultPromise; + // only .then is enough to check awaited, but we type this as `Promise` in global types + // so let's follow it + return { + then(onFulfilled, onRejected) { + awaited = true; + return (resultPromise ||= promise()).then(onFulfilled, onRejected); + }, + catch(onRejected) { + return (resultPromise ||= promise()).catch(onRejected); + }, + finally(onFinally) { + return (resultPromise ||= promise()).finally(onFinally); + }, + [Symbol.toStringTag]: "Promise" + }; + }; + } }); + return proxy; + }; +} +function copyStackTrace$1(target, source) { + if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message); + return target; +} + +function commonjsRequire(path) { + throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); +} + +var chaiSubset$1 = {exports: {}}; + +var chaiSubset = chaiSubset$1.exports; + +var hasRequiredChaiSubset; + +function requireChaiSubset () { + if (hasRequiredChaiSubset) return chaiSubset$1.exports; + hasRequiredChaiSubset = 1; + (function (module, exports) { + (function() { + (function(chaiSubset) { + if (typeof commonjsRequire === 'function' && 'object' === 'object' && 'object' === 'object') { + return module.exports = chaiSubset; + } else { + return chai.use(chaiSubset); + } + })(function(chai, utils) { + var Assertion = chai.Assertion; + var assertionPrototype = Assertion.prototype; + + Assertion.addMethod('containSubset', function (expected) { + var actual = utils.flag(this, 'object'); + var showDiff = chai.config.showDiff; + + assertionPrototype.assert.call(this, + compare(expected, actual), + 'expected #{act} to contain subset #{exp}', + 'expected #{act} to not contain subset #{exp}', + expected, + actual, + showDiff + ); + }); + + chai.assert.containSubset = function(val, exp, msg) { + new chai.Assertion(val, msg).to.be.containSubset(exp); + }; + + function compare(expected, actual) { + if (expected === actual) { + return true; + } + if (typeof(actual) !== typeof(expected)) { + return false; + } + if (typeof(expected) !== 'object' || expected === null) { + return expected === actual; + } + if (!!expected && !actual) { + return false; + } + + if (Array.isArray(expected)) { + if (typeof(actual.length) !== 'number') { + return false; + } + var aa = Array.prototype.slice.call(actual); + return expected.every(function (exp) { + return aa.some(function (act) { + return compare(exp, act); + }); + }); + } + + if (expected instanceof Date) { + if (actual instanceof Date) { + return expected.getTime() === actual.getTime(); + } else { + return false; + } + } + + return Object.keys(expected).every(function (key) { + var eo = expected[key]; + var ao = actual[key]; + if (typeof(eo) === 'object' && eo !== null && ao !== null) { + return compare(eo, ao); + } + if (typeof(eo) === 'function') { + return eo(ao); + } + return ao === eo; + }); + } + }); + + }).call(chaiSubset); + } (chaiSubset$1)); + return chaiSubset$1.exports; +} + +var chaiSubsetExports = requireChaiSubset(); +var Subset = /*@__PURE__*/getDefaultExportFromCjs(chaiSubsetExports); + +function createAssertionMessage(util, assertion, hasArgs) { + const not = util.flag(assertion, "negate") ? "not." : ""; + const name = `${util.flag(assertion, "_name")}(${"expected" })`; + const promiseName = util.flag(assertion, "promise"); + const promise = promiseName ? `.${promiseName}` : ""; + return `expect(actual)${promise}.${not}${name}`; +} +function recordAsyncExpect(_test, promise, assertion, error) { + const test = _test; + // record promise for test, that resolves before test ends + if (test && promise instanceof Promise) { + // if promise is explicitly awaited, remove it from the list + promise = promise.finally(() => { + if (!test.promises) return; + const index = test.promises.indexOf(promise); + if (index !== -1) test.promises.splice(index, 1); + }); + // record promise + if (!test.promises) test.promises = []; + test.promises.push(promise); + let resolved = false; + test.onFinished ??= []; + test.onFinished.push(() => { + if (!resolved) { + const processor = globalThis.__vitest_worker__?.onFilterStackTrace || ((s) => s || ""); + const stack = processor(error.stack); + console.warn([ + `Promise returned by \`${assertion}\` was not awaited. `, + "Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in Vitest 3. ", + "Please remember to await the assertion.\n", + stack + ].join("")); + } + }); + return { + then(onFulfilled, onRejected) { + resolved = true; + return promise.then(onFulfilled, onRejected); + }, + catch(onRejected) { + return promise.catch(onRejected); + }, + finally(onFinally) { + return promise.finally(onFinally); + }, + [Symbol.toStringTag]: "Promise" + }; + } + return promise; +} + +let _client; +function getSnapshotClient() { + if (!_client) _client = new SnapshotClient({ isEqual: (received, expected) => { + return equals(received, expected, [iterableEquality, subsetEquality]); + } }); + return _client; +} +function getError(expected, promise) { + if (typeof expected !== "function") { + if (!promise) throw new Error(`expected must be a function, received ${typeof expected}`); + // when "promised", it receives thrown error + return expected; + } + try { + expected(); + } catch (e) { + return e; + } + throw new Error("snapshot function didn't throw"); +} +function getTestNames(test) { + return { + filepath: test.file.filepath, + name: getNames(test).slice(1).join(" > "), + testId: test.id + }; +} +const SnapshotPlugin = (chai, utils) => { + function getTest(assertionName, obj) { + const test = utils.flag(obj, "vitest-test"); + if (!test) throw new Error(`'${assertionName}' cannot be used without test context`); + return test; + } + for (const key of ["matchSnapshot", "toMatchSnapshot"]) utils.addMethod(chai.Assertion.prototype, key, function(properties, message) { + utils.flag(this, "_name", key); + const isNot = utils.flag(this, "negate"); + if (isNot) throw new Error(`${key} cannot be used with "not"`); + const expected = utils.flag(this, "object"); + const test = getTest(key, this); + if (typeof properties === "string" && typeof message === "undefined") { + message = properties; + properties = void 0; + } + const errorMessage = utils.flag(this, "message"); + getSnapshotClient().assert({ + received: expected, + message, + isInline: false, + properties, + errorMessage, + ...getTestNames(test) + }); + }); + utils.addMethod(chai.Assertion.prototype, "toMatchFileSnapshot", function(file, message) { + utils.flag(this, "_name", "toMatchFileSnapshot"); + const isNot = utils.flag(this, "negate"); + if (isNot) throw new Error("toMatchFileSnapshot cannot be used with \"not\""); + const error = new Error("resolves"); + const expected = utils.flag(this, "object"); + const test = getTest("toMatchFileSnapshot", this); + const errorMessage = utils.flag(this, "message"); + const promise = getSnapshotClient().assertRaw({ + received: expected, + message, + isInline: false, + rawSnapshot: { file }, + errorMessage, + ...getTestNames(test) + }); + return recordAsyncExpect(test, promise, createAssertionMessage(utils, this), error); + }); + utils.addMethod(chai.Assertion.prototype, "toMatchInlineSnapshot", function __INLINE_SNAPSHOT__(properties, inlineSnapshot, message) { + utils.flag(this, "_name", "toMatchInlineSnapshot"); + const isNot = utils.flag(this, "negate"); + if (isNot) throw new Error("toMatchInlineSnapshot cannot be used with \"not\""); + const test = getTest("toMatchInlineSnapshot", this); + const isInsideEach = test.each || test.suite?.each; + if (isInsideEach) throw new Error("InlineSnapshot cannot be used inside of test.each or describe.each"); + const expected = utils.flag(this, "object"); + const error = utils.flag(this, "error"); + if (typeof properties === "string") { + message = inlineSnapshot; + inlineSnapshot = properties; + properties = void 0; + } + if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot); + const errorMessage = utils.flag(this, "message"); + getSnapshotClient().assert({ + received: expected, + message, + isInline: true, + properties, + inlineSnapshot, + error, + errorMessage, + ...getTestNames(test) + }); + }); + utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingSnapshot", function(message) { + utils.flag(this, "_name", "toThrowErrorMatchingSnapshot"); + const isNot = utils.flag(this, "negate"); + if (isNot) throw new Error("toThrowErrorMatchingSnapshot cannot be used with \"not\""); + const expected = utils.flag(this, "object"); + const test = getTest("toThrowErrorMatchingSnapshot", this); + const promise = utils.flag(this, "promise"); + const errorMessage = utils.flag(this, "message"); + getSnapshotClient().assert({ + received: getError(expected, promise), + message, + errorMessage, + ...getTestNames(test) + }); + }); + utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingInlineSnapshot", function __INLINE_SNAPSHOT__(inlineSnapshot, message) { + const isNot = utils.flag(this, "negate"); + if (isNot) throw new Error("toThrowErrorMatchingInlineSnapshot cannot be used with \"not\""); + const test = getTest("toThrowErrorMatchingInlineSnapshot", this); + const isInsideEach = test.each || test.suite?.each; + if (isInsideEach) throw new Error("InlineSnapshot cannot be used inside of test.each or describe.each"); + const expected = utils.flag(this, "object"); + const error = utils.flag(this, "error"); + const promise = utils.flag(this, "promise"); + const errorMessage = utils.flag(this, "message"); + if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot); + getSnapshotClient().assert({ + received: getError(expected, promise), + message, + inlineSnapshot, + isInline: true, + error, + errorMessage, + ...getTestNames(test) + }); + }); + utils.addMethod(chai.expect, "addSnapshotSerializer", addSerializer); +}; + +chai$1.use(JestExtend); +chai$1.use(JestChaiExpect); +chai$1.use(Subset); +chai$1.use(SnapshotPlugin); +chai$1.use(JestAsymmetricMatchers); + +function createExpect(test) { + const expect = (value, message) => { + const { assertionCalls } = getState(expect); + setState({ assertionCalls: assertionCalls + 1 }, expect); + const assert = chai$1.expect(value, message); + const _test = test || getCurrentTest(); + if (_test) + // @ts-expect-error internal + return assert.withTest(_test); + else return assert; + }; + Object.assign(expect, chai$1.expect); + Object.assign(expect, globalThis[ASYMMETRIC_MATCHERS_OBJECT]); + expect.getState = () => getState(expect); + expect.setState = (state) => setState(state, expect); + // @ts-expect-error global is not typed + const globalState = getState(globalThis[GLOBAL_EXPECT]) || {}; + setState({ + ...globalState, + assertionCalls: 0, + isExpectingAssertions: false, + isExpectingAssertionsError: null, + expectedAssertionsNumber: null, + expectedAssertionsNumberErrorGen: null, + environment: getCurrentEnvironment(), + get testPath() { + return getWorkerState().filepath; + }, + currentTestName: test ? getTestName(test) : globalState.currentTestName + }, expect); + // @ts-expect-error untyped + expect.extend = (matchers) => chai$1.expect.extend(expect, matchers); + expect.addEqualityTesters = (customTesters) => addCustomEqualityTesters(customTesters); + expect.soft = (...args) => { + // @ts-expect-error private soft access + return expect(...args).withContext({ soft: true }); + }; + expect.poll = createExpectPoll(expect); + expect.unreachable = (message) => { + chai$1.assert.fail(`expected${message ? ` "${message}" ` : " "}not to be reached`); + }; + function assertions(expected) { + const errorGen = () => new Error(`expected number of assertions to be ${expected}, but got ${expect.getState().assertionCalls}`); + if (Error.captureStackTrace) Error.captureStackTrace(errorGen(), assertions); + expect.setState({ + expectedAssertionsNumber: expected, + expectedAssertionsNumberErrorGen: errorGen + }); + } + function hasAssertions() { + const error = new Error("expected any number of assertion, but got none"); + if (Error.captureStackTrace) Error.captureStackTrace(error, hasAssertions); + expect.setState({ + isExpectingAssertions: true, + isExpectingAssertionsError: error + }); + } + chai$1.util.addMethod(expect, "assertions", assertions); + chai$1.util.addMethod(expect, "hasAssertions", hasAssertions); + expect.extend(customMatchers); + return expect; +} +const globalExpect = createExpect(); +Object.defineProperty(globalThis, GLOBAL_EXPECT, { + value: globalExpect, + writable: true, + configurable: true +}); + +/** +* Gives access to injected context provided from the main thread. +* This usually returns a value provided by `globalSetup` or an external library. +*/ +function inject(key) { + const workerState = getWorkerState(); + return workerState.providedContext[key]; +} + +var fakeTimersSrc = {}; + +var global; +var hasRequiredGlobal; + +function requireGlobal () { + if (hasRequiredGlobal) return global; + hasRequiredGlobal = 1; + + /** + * A reference to the global object + * @type {object} globalObject + */ + var globalObject; + + /* istanbul ignore else */ + if (typeof commonjsGlobal !== "undefined") { + // Node + globalObject = commonjsGlobal; + } else if (typeof window !== "undefined") { + // Browser + globalObject = window; + } else { + // WebWorker + globalObject = self; + } + + global = globalObject; + return global; +} + +var throwsOnProto_1; +var hasRequiredThrowsOnProto; + +function requireThrowsOnProto () { + if (hasRequiredThrowsOnProto) return throwsOnProto_1; + hasRequiredThrowsOnProto = 1; + + /** + * Is true when the environment causes an error to be thrown for accessing the + * __proto__ property. + * This is necessary in order to support `node --disable-proto=throw`. + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto + * @type {boolean} + */ + let throwsOnProto; + try { + const object = {}; + // eslint-disable-next-line no-proto, no-unused-expressions + object.__proto__; + throwsOnProto = false; + } catch (_) { + // This branch is covered when tests are run with `--disable-proto=throw`, + // however we can test both branches at the same time, so this is ignored + /* istanbul ignore next */ + throwsOnProto = true; + } + + throwsOnProto_1 = throwsOnProto; + return throwsOnProto_1; +} + +var copyPrototypeMethods; +var hasRequiredCopyPrototypeMethods; + +function requireCopyPrototypeMethods () { + if (hasRequiredCopyPrototypeMethods) return copyPrototypeMethods; + hasRequiredCopyPrototypeMethods = 1; + + var call = Function.call; + var throwsOnProto = requireThrowsOnProto(); + + var disallowedProperties = [ + // ignore size because it throws from Map + "size", + "caller", + "callee", + "arguments", + ]; + + // This branch is covered when tests are run with `--disable-proto=throw`, + // however we can test both branches at the same time, so this is ignored + /* istanbul ignore next */ + if (throwsOnProto) { + disallowedProperties.push("__proto__"); + } + + copyPrototypeMethods = function copyPrototypeMethods(prototype) { + // eslint-disable-next-line @sinonjs/no-prototype-methods/no-prototype-methods + return Object.getOwnPropertyNames(prototype).reduce(function ( + result, + name + ) { + if (disallowedProperties.includes(name)) { + return result; + } + + if (typeof prototype[name] !== "function") { + return result; + } + + result[name] = call.bind(prototype[name]); + + return result; + }, + Object.create(null)); + }; + return copyPrototypeMethods; +} + +var array; +var hasRequiredArray; + +function requireArray () { + if (hasRequiredArray) return array; + hasRequiredArray = 1; + + var copyPrototype = requireCopyPrototypeMethods(); + + array = copyPrototype(Array.prototype); + return array; +} + +var calledInOrder_1; +var hasRequiredCalledInOrder; + +function requireCalledInOrder () { + if (hasRequiredCalledInOrder) return calledInOrder_1; + hasRequiredCalledInOrder = 1; + + var every = requireArray().every; + + /** + * @private + */ + function hasCallsLeft(callMap, spy) { + if (callMap[spy.id] === undefined) { + callMap[spy.id] = 0; + } + + return callMap[spy.id] < spy.callCount; + } + + /** + * @private + */ + function checkAdjacentCalls(callMap, spy, index, spies) { + var calledBeforeNext = true; + + if (index !== spies.length - 1) { + calledBeforeNext = spy.calledBefore(spies[index + 1]); + } + + if (hasCallsLeft(callMap, spy) && calledBeforeNext) { + callMap[spy.id] += 1; + return true; + } + + return false; + } + + /** + * A Sinon proxy object (fake, spy, stub) + * @typedef {object} SinonProxy + * @property {Function} calledBefore - A method that determines if this proxy was called before another one + * @property {string} id - Some id + * @property {number} callCount - Number of times this proxy has been called + */ + + /** + * Returns true when the spies have been called in the order they were supplied in + * @param {SinonProxy[] | SinonProxy} spies An array of proxies, or several proxies as arguments + * @returns {boolean} true when spies are called in order, false otherwise + */ + function calledInOrder(spies) { + var callMap = {}; + // eslint-disable-next-line no-underscore-dangle + var _spies = arguments.length > 1 ? arguments : spies; + + return every(_spies, checkAdjacentCalls.bind(null, callMap)); + } + + calledInOrder_1 = calledInOrder; + return calledInOrder_1; +} + +var className_1; +var hasRequiredClassName; + +function requireClassName () { + if (hasRequiredClassName) return className_1; + hasRequiredClassName = 1; + + /** + * Returns a display name for a value from a constructor + * @param {object} value A value to examine + * @returns {(string|null)} A string or null + */ + function className(value) { + const name = value.constructor && value.constructor.name; + return name || null; + } + + className_1 = className; + return className_1; +} + +var deprecated = {}; + +/* eslint-disable no-console */ + +var hasRequiredDeprecated; + +function requireDeprecated () { + if (hasRequiredDeprecated) return deprecated; + hasRequiredDeprecated = 1; + (function (exports) { + + /** + * Returns a function that will invoke the supplied function and print a + * deprecation warning to the console each time it is called. + * @param {Function} func + * @param {string} msg + * @returns {Function} + */ + exports.wrap = function (func, msg) { + var wrapped = function () { + exports.printWarning(msg); + return func.apply(this, arguments); + }; + if (func.prototype) { + wrapped.prototype = func.prototype; + } + return wrapped; + }; + + /** + * Returns a string which can be supplied to `wrap()` to notify the user that a + * particular part of the sinon API has been deprecated. + * @param {string} packageName + * @param {string} funcName + * @returns {string} + */ + exports.defaultMsg = function (packageName, funcName) { + return `${packageName}.${funcName} is deprecated and will be removed from the public API in a future version of ${packageName}.`; + }; + + /** + * Prints a warning on the console, when it exists + * @param {string} msg + * @returns {undefined} + */ + exports.printWarning = function (msg) { + /* istanbul ignore next */ + if (typeof process === "object" && process.emitWarning) { + // Emit Warnings in Node + process.emitWarning(msg); + } else if (console.info) { + console.info(msg); + } else { + console.log(msg); + } + }; + } (deprecated)); + return deprecated; +} + +var every; +var hasRequiredEvery; + +function requireEvery () { + if (hasRequiredEvery) return every; + hasRequiredEvery = 1; + + /** + * Returns true when fn returns true for all members of obj. + * This is an every implementation that works for all iterables + * @param {object} obj + * @param {Function} fn + * @returns {boolean} + */ + every = function every(obj, fn) { + var pass = true; + + try { + // eslint-disable-next-line @sinonjs/no-prototype-methods/no-prototype-methods + obj.forEach(function () { + if (!fn.apply(this, arguments)) { + // Throwing an error is the only way to break `forEach` + throw new Error(); + } + }); + } catch (e) { + pass = false; + } + + return pass; + }; + return every; +} + +var functionName; +var hasRequiredFunctionName; + +function requireFunctionName () { + if (hasRequiredFunctionName) return functionName; + hasRequiredFunctionName = 1; + + /** + * Returns a display name for a function + * @param {Function} func + * @returns {string} + */ + functionName = function functionName(func) { + if (!func) { + return ""; + } + + try { + return ( + func.displayName || + func.name || + // Use function decomposition as a last resort to get function + // name. Does not rely on function decomposition to work - if it + // doesn't debugging will be slightly less informative + // (i.e. toString will say 'spy' rather than 'myFunc'). + (String(func).match(/function ([^\s(]+)/) || [])[1] + ); + } catch (e) { + // Stringify may fail and we might get an exception, as a last-last + // resort fall back to empty string. + return ""; + } + }; + return functionName; +} + +var orderByFirstCall_1; +var hasRequiredOrderByFirstCall; + +function requireOrderByFirstCall () { + if (hasRequiredOrderByFirstCall) return orderByFirstCall_1; + hasRequiredOrderByFirstCall = 1; + + var sort = requireArray().sort; + var slice = requireArray().slice; + + /** + * @private + */ + function comparator(a, b) { + // uuid, won't ever be equal + var aCall = a.getCall(0); + var bCall = b.getCall(0); + var aId = (aCall && aCall.callId) || -1; + var bId = (bCall && bCall.callId) || -1; + + return aId < bId ? -1 : 1; + } + + /** + * A Sinon proxy object (fake, spy, stub) + * @typedef {object} SinonProxy + * @property {Function} getCall - A method that can return the first call + */ + + /** + * Sorts an array of SinonProxy instances (fake, spy, stub) by their first call + * @param {SinonProxy[] | SinonProxy} spies + * @returns {SinonProxy[]} + */ + function orderByFirstCall(spies) { + return sort(slice(spies), comparator); + } + + orderByFirstCall_1 = orderByFirstCall; + return orderByFirstCall_1; +} + +var _function; +var hasRequired_function; + +function require_function () { + if (hasRequired_function) return _function; + hasRequired_function = 1; + + var copyPrototype = requireCopyPrototypeMethods(); + + _function = copyPrototype(Function.prototype); + return _function; +} + +var map; +var hasRequiredMap; + +function requireMap () { + if (hasRequiredMap) return map; + hasRequiredMap = 1; + + var copyPrototype = requireCopyPrototypeMethods(); + + map = copyPrototype(Map.prototype); + return map; +} + +var object; +var hasRequiredObject; + +function requireObject () { + if (hasRequiredObject) return object; + hasRequiredObject = 1; + + var copyPrototype = requireCopyPrototypeMethods(); + + object = copyPrototype(Object.prototype); + return object; +} + +var set; +var hasRequiredSet; + +function requireSet () { + if (hasRequiredSet) return set; + hasRequiredSet = 1; + + var copyPrototype = requireCopyPrototypeMethods(); + + set = copyPrototype(Set.prototype); + return set; +} + +var string; +var hasRequiredString; + +function requireString () { + if (hasRequiredString) return string; + hasRequiredString = 1; + + var copyPrototype = requireCopyPrototypeMethods(); + + string = copyPrototype(String.prototype); + return string; +} + +var prototypes; +var hasRequiredPrototypes; + +function requirePrototypes () { + if (hasRequiredPrototypes) return prototypes; + hasRequiredPrototypes = 1; + + prototypes = { + array: requireArray(), + function: require_function(), + map: requireMap(), + object: requireObject(), + set: requireSet(), + string: requireString(), + }; + return prototypes; +} + +var typeDetect$1 = {exports: {}}; + +var typeDetect = typeDetect$1.exports; + +var hasRequiredTypeDetect; + +function requireTypeDetect () { + if (hasRequiredTypeDetect) return typeDetect$1.exports; + hasRequiredTypeDetect = 1; + (function (module, exports) { + (function (global, factory) { + module.exports = factory() ; + }(typeDetect, (function () { + /* ! + * type-detect + * Copyright(c) 2013 jake luer + * MIT Licensed + */ + var promiseExists = typeof Promise === 'function'; + + /* eslint-disable no-undef */ + var globalObject = typeof self === 'object' ? self : commonjsGlobal; // eslint-disable-line id-blacklist + + var symbolExists = typeof Symbol !== 'undefined'; + var mapExists = typeof Map !== 'undefined'; + var setExists = typeof Set !== 'undefined'; + var weakMapExists = typeof WeakMap !== 'undefined'; + var weakSetExists = typeof WeakSet !== 'undefined'; + var dataViewExists = typeof DataView !== 'undefined'; + var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined'; + var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined'; + var setEntriesExists = setExists && typeof Set.prototype.entries === 'function'; + var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function'; + var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries()); + var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries()); + var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function'; + var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); + var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function'; + var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]()); + var toStringLeftSliceLength = 8; + var toStringRightSliceLength = -1; + /** + * ### typeOf (obj) + * + * Uses `Object.prototype.toString` to determine the type of an object, + * normalising behaviour across engine versions & well optimised. + * + * @param {Mixed} object + * @return {String} object type + * @api public + */ + function typeDetect(obj) { + /* ! Speed optimisation + * Pre: + * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled) + * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled) + * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled) + * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled) + * function x 2,556,769 ops/sec ±1.73% (77 runs sampled) + * Post: + * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled) + * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled) + * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled) + * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled) + * function x 31,296,870 ops/sec ±0.96% (83 runs sampled) + */ + var typeofObj = typeof obj; + if (typeofObj !== 'object') { + return typeofObj; + } + + /* ! Speed optimisation + * Pre: + * null x 28,645,765 ops/sec ±1.17% (82 runs sampled) + * Post: + * null x 36,428,962 ops/sec ±1.37% (84 runs sampled) + */ + if (obj === null) { + return 'null'; + } + + /* ! Spec Conformance + * Test: `Object.prototype.toString.call(window)`` + * - Node === "[object global]" + * - Chrome === "[object global]" + * - Firefox === "[object Window]" + * - PhantomJS === "[object Window]" + * - Safari === "[object Window]" + * - IE 11 === "[object Window]" + * - IE Edge === "[object Window]" + * Test: `Object.prototype.toString.call(this)`` + * - Chrome Worker === "[object global]" + * - Firefox Worker === "[object DedicatedWorkerGlobalScope]" + * - Safari Worker === "[object DedicatedWorkerGlobalScope]" + * - IE 11 Worker === "[object WorkerGlobalScope]" + * - IE Edge Worker === "[object WorkerGlobalScope]" + */ + if (obj === globalObject) { + return 'global'; + } + + /* ! Speed optimisation + * Pre: + * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled) + * Post: + * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled) + */ + if ( + Array.isArray(obj) && + (symbolToStringTagExists === false || !(Symbol.toStringTag in obj)) + ) { + return 'Array'; + } + + // Not caching existence of `window` and related properties due to potential + // for `window` to be unset before tests in quasi-browser environments. + if (typeof window === 'object' && window !== null) { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/browsers.html#location) + * WhatWG HTML$7.7.3 - The `Location` interface + * Test: `Object.prototype.toString.call(window.location)`` + * - IE <=11 === "[object Object]" + * - IE Edge <=13 === "[object Object]" + */ + if (typeof window.location === 'object' && obj === window.location) { + return 'Location'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#document) + * WhatWG HTML$3.1.1 - The `Document` object + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * WhatWG HTML states: + * > For historical reasons, Window objects must also have a + * > writable, configurable, non-enumerable property named + * > HTMLDocument whose value is the Document interface object. + * Test: `Object.prototype.toString.call(document)`` + * - Chrome === "[object HTMLDocument]" + * - Firefox === "[object HTMLDocument]" + * - Safari === "[object HTMLDocument]" + * - IE <=10 === "[object Document]" + * - IE 11 === "[object HTMLDocument]" + * - IE Edge <=13 === "[object HTMLDocument]" + */ + if (typeof window.document === 'object' && obj === window.document) { + return 'Document'; + } + + if (typeof window.navigator === 'object') { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray) + * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray + * Test: `Object.prototype.toString.call(navigator.mimeTypes)`` + * - IE <=10 === "[object MSMimeTypesCollection]" + */ + if (typeof window.navigator.mimeTypes === 'object' && + obj === window.navigator.mimeTypes) { + return 'MimeTypeArray'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) + * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray + * Test: `Object.prototype.toString.call(navigator.plugins)`` + * - IE <=10 === "[object MSPluginsCollection]" + */ + if (typeof window.navigator.plugins === 'object' && + obj === window.navigator.plugins) { + return 'PluginArray'; + } + } + + if ((typeof window.HTMLElement === 'function' || + typeof window.HTMLElement === 'object') && + obj instanceof window.HTMLElement) { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) + * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement` + * Test: `Object.prototype.toString.call(document.createElement('blockquote'))`` + * - IE <=10 === "[object HTMLBlockElement]" + */ + if (obj.tagName === 'BLOCKQUOTE') { + return 'HTMLQuoteElement'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#htmltabledatacellelement) + * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement` + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * Test: Object.prototype.toString.call(document.createElement('td')) + * - Chrome === "[object HTMLTableCellElement]" + * - Firefox === "[object HTMLTableCellElement]" + * - Safari === "[object HTMLTableCellElement]" + */ + if (obj.tagName === 'TD') { + return 'HTMLTableDataCellElement'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#htmltableheadercellelement) + * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement` + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * Test: Object.prototype.toString.call(document.createElement('th')) + * - Chrome === "[object HTMLTableCellElement]" + * - Firefox === "[object HTMLTableCellElement]" + * - Safari === "[object HTMLTableCellElement]" + */ + if (obj.tagName === 'TH') { + return 'HTMLTableHeaderCellElement'; + } + } + } + + /* ! Speed optimisation + * Pre: + * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled) + * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled) + * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled) + * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled) + * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled) + * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled) + * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled) + * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled) + * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled) + * Post: + * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled) + * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled) + * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled) + * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled) + * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled) + * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled) + * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled) + * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled) + * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled) + */ + var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]); + if (typeof stringTag === 'string') { + return stringTag; + } + + var objPrototype = Object.getPrototypeOf(obj); + /* ! Speed optimisation + * Pre: + * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled) + * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled) + * Post: + * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled) + * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled) + */ + if (objPrototype === RegExp.prototype) { + return 'RegExp'; + } + + /* ! Speed optimisation + * Pre: + * date x 2,130,074 ops/sec ±4.42% (68 runs sampled) + * Post: + * date x 3,953,779 ops/sec ±1.35% (77 runs sampled) + */ + if (objPrototype === Date.prototype) { + return 'Date'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag) + * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise": + * Test: `Object.prototype.toString.call(Promise.resolve())`` + * - Chrome <=47 === "[object Object]" + * - Edge <=20 === "[object Object]" + * - Firefox 29-Latest === "[object Promise]" + * - Safari 7.1-Latest === "[object Promise]" + */ + if (promiseExists && objPrototype === Promise.prototype) { + return 'Promise'; + } + + /* ! Speed optimisation + * Pre: + * set x 2,222,186 ops/sec ±1.31% (82 runs sampled) + * Post: + * set x 4,545,879 ops/sec ±1.13% (83 runs sampled) + */ + if (setExists && objPrototype === Set.prototype) { + return 'Set'; + } + + /* ! Speed optimisation + * Pre: + * map x 2,396,842 ops/sec ±1.59% (81 runs sampled) + * Post: + * map x 4,183,945 ops/sec ±6.59% (82 runs sampled) + */ + if (mapExists && objPrototype === Map.prototype) { + return 'Map'; + } + + /* ! Speed optimisation + * Pre: + * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled) + * Post: + * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled) + */ + if (weakSetExists && objPrototype === WeakSet.prototype) { + return 'WeakSet'; + } + + /* ! Speed optimisation + * Pre: + * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled) + * Post: + * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled) + */ + if (weakMapExists && objPrototype === WeakMap.prototype) { + return 'WeakMap'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag) + * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView": + * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))`` + * - Edge <=13 === "[object Object]" + */ + if (dataViewExists && objPrototype === DataView.prototype) { + return 'DataView'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag) + * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator": + * Test: `Object.prototype.toString.call(new Map().entries())`` + * - Edge <=13 === "[object Object]" + */ + if (mapExists && objPrototype === mapIteratorPrototype) { + return 'Map Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag) + * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator": + * Test: `Object.prototype.toString.call(new Set().entries())`` + * - Edge <=13 === "[object Object]" + */ + if (setExists && objPrototype === setIteratorPrototype) { + return 'Set Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag) + * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator": + * Test: `Object.prototype.toString.call([][Symbol.iterator]())`` + * - Edge <=13 === "[object Object]" + */ + if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { + return 'Array Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag) + * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator": + * Test: `Object.prototype.toString.call(''[Symbol.iterator]())`` + * - Edge <=13 === "[object Object]" + */ + if (stringIteratorExists && objPrototype === stringIteratorPrototype) { + return 'String Iterator'; + } + + /* ! Speed optimisation + * Pre: + * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled) + * Post: + * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled) + */ + if (objPrototype === null) { + return 'Object'; + } + + return Object + .prototype + .toString + .call(obj) + .slice(toStringLeftSliceLength, toStringRightSliceLength); + } + + return typeDetect; + + }))); + } (typeDetect$1)); + return typeDetect$1.exports; +} + +var typeOf; +var hasRequiredTypeOf; + +function requireTypeOf () { + if (hasRequiredTypeOf) return typeOf; + hasRequiredTypeOf = 1; + + var type = requireTypeDetect(); + + /** + * Returns the lower-case result of running type from type-detect on the value + * @param {*} value + * @returns {string} + */ + typeOf = function typeOf(value) { + return type(value).toLowerCase(); + }; + return typeOf; +} + +var valueToString_1; +var hasRequiredValueToString; + +function requireValueToString () { + if (hasRequiredValueToString) return valueToString_1; + hasRequiredValueToString = 1; + + /** + * Returns a string representation of the value + * @param {*} value + * @returns {string} + */ + function valueToString(value) { + if (value && value.toString) { + // eslint-disable-next-line @sinonjs/no-prototype-methods/no-prototype-methods + return value.toString(); + } + return String(value); + } + + valueToString_1 = valueToString; + return valueToString_1; +} + +var lib; +var hasRequiredLib; + +function requireLib () { + if (hasRequiredLib) return lib; + hasRequiredLib = 1; + + lib = { + global: requireGlobal(), + calledInOrder: requireCalledInOrder(), + className: requireClassName(), + deprecated: requireDeprecated(), + every: requireEvery(), + functionName: requireFunctionName(), + orderByFirstCall: requireOrderByFirstCall(), + prototypes: requirePrototypes(), + typeOf: requireTypeOf(), + valueToString: requireValueToString(), + }; + return lib; +} + +var hasRequiredFakeTimersSrc; + +function requireFakeTimersSrc () { + if (hasRequiredFakeTimersSrc) return fakeTimersSrc; + hasRequiredFakeTimersSrc = 1; + + const globalObject = requireLib().global; + let timersModule, timersPromisesModule; + if (typeof __vitest_required__ !== 'undefined') { + try { + timersModule = __vitest_required__.timers; + } catch (e) { + // ignored + } + try { + timersPromisesModule = __vitest_required__.timersPromises; + } catch (e) { + // ignored + } + } + + /** + * @typedef {object} IdleDeadline + * @property {boolean} didTimeout - whether or not the callback was called before reaching the optional timeout + * @property {function():number} timeRemaining - a floating-point value providing an estimate of the number of milliseconds remaining in the current idle period + */ + + /** + * Queues a function to be called during a browser's idle periods + * @callback RequestIdleCallback + * @param {function(IdleDeadline)} callback + * @param {{timeout: number}} options - an options object + * @returns {number} the id + */ + + /** + * @callback NextTick + * @param {VoidVarArgsFunc} callback - the callback to run + * @param {...*} args - optional arguments to call the callback with + * @returns {void} + */ + + /** + * @callback SetImmediate + * @param {VoidVarArgsFunc} callback - the callback to run + * @param {...*} args - optional arguments to call the callback with + * @returns {NodeImmediate} + */ + + /** + * @callback VoidVarArgsFunc + * @param {...*} callback - the callback to run + * @returns {void} + */ + + /** + * @typedef RequestAnimationFrame + * @property {function(number):void} requestAnimationFrame + * @returns {number} - the id + */ + + /** + * @typedef Performance + * @property {function(): number} now + */ + + /* eslint-disable jsdoc/require-property-description */ + /** + * @typedef {object} Clock + * @property {number} now - the current time + * @property {Date} Date - the Date constructor + * @property {number} loopLimit - the maximum number of timers before assuming an infinite loop + * @property {RequestIdleCallback} requestIdleCallback + * @property {function(number):void} cancelIdleCallback + * @property {setTimeout} setTimeout + * @property {clearTimeout} clearTimeout + * @property {NextTick} nextTick + * @property {queueMicrotask} queueMicrotask + * @property {setInterval} setInterval + * @property {clearInterval} clearInterval + * @property {SetImmediate} setImmediate + * @property {function(NodeImmediate):void} clearImmediate + * @property {function():number} countTimers + * @property {RequestAnimationFrame} requestAnimationFrame + * @property {function(number):void} cancelAnimationFrame + * @property {function():void} runMicrotasks + * @property {function(string | number): number} tick + * @property {function(string | number): Promise} tickAsync + * @property {function(): number} next + * @property {function(): Promise} nextAsync + * @property {function(): number} runAll + * @property {function(): number} runToFrame + * @property {function(): Promise} runAllAsync + * @property {function(): number} runToLast + * @property {function(): Promise} runToLastAsync + * @property {function(): void} reset + * @property {function(number | Date): void} setSystemTime + * @property {function(number): void} jump + * @property {Performance} performance + * @property {function(number[]): number[]} hrtime - process.hrtime (legacy) + * @property {function(): void} uninstall Uninstall the clock. + * @property {Function[]} methods - the methods that are faked + * @property {boolean} [shouldClearNativeTimers] inherited from config + * @property {{methodName:string, original:any}[] | undefined} timersModuleMethods + * @property {{methodName:string, original:any}[] | undefined} timersPromisesModuleMethods + * @property {Map} abortListenerMap + */ + /* eslint-enable jsdoc/require-property-description */ + + /** + * Configuration object for the `install` method. + * @typedef {object} Config + * @property {number|Date} [now] a number (in milliseconds) or a Date object (default epoch) + * @property {string[]} [toFake] names of the methods that should be faked. + * @property {number} [loopLimit] the maximum number of timers that will be run when calling runAll() + * @property {boolean} [shouldAdvanceTime] tells FakeTimers to increment mocked time automatically (default false) + * @property {number} [advanceTimeDelta] increment mocked time every <> ms (default: 20ms) + * @property {boolean} [shouldClearNativeTimers] forwards clear timer calls to native functions if they are not fakes (default: false) + * @property {boolean} [ignoreMissingTimers] default is false, meaning asking to fake timers that are not present will throw an error + */ + + /* eslint-disable jsdoc/require-property-description */ + /** + * The internal structure to describe a scheduled fake timer + * @typedef {object} Timer + * @property {Function} func + * @property {*[]} args + * @property {number} delay + * @property {number} callAt + * @property {number} createdAt + * @property {boolean} immediate + * @property {number} id + * @property {Error} [error] + */ + + /** + * A Node timer + * @typedef {object} NodeImmediate + * @property {function(): boolean} hasRef + * @property {function(): NodeImmediate} ref + * @property {function(): NodeImmediate} unref + */ + /* eslint-enable jsdoc/require-property-description */ + + /* eslint-disable complexity */ + + /** + * Mocks available features in the specified global namespace. + * @param {*} _global Namespace to mock (e.g. `window`) + * @returns {FakeTimers} + */ + function withGlobal(_global) { + const maxTimeout = Math.pow(2, 31) - 1; //see https://heycam.github.io/webidl/#abstract-opdef-converttoint + const idCounterStart = 1e12; // arbitrarily large number to avoid collisions with native timer IDs + const NOOP = function () { + return undefined; + }; + const NOOP_ARRAY = function () { + return []; + }; + const isPresent = {}; + let timeoutResult, + addTimerReturnsObject = false; + + if (_global.setTimeout) { + isPresent.setTimeout = true; + timeoutResult = _global.setTimeout(NOOP, 0); + addTimerReturnsObject = typeof timeoutResult === "object"; + } + isPresent.clearTimeout = Boolean(_global.clearTimeout); + isPresent.setInterval = Boolean(_global.setInterval); + isPresent.clearInterval = Boolean(_global.clearInterval); + isPresent.hrtime = + _global.process && typeof _global.process.hrtime === "function"; + isPresent.hrtimeBigint = + isPresent.hrtime && typeof _global.process.hrtime.bigint === "function"; + isPresent.nextTick = + _global.process && typeof _global.process.nextTick === "function"; + const utilPromisify = _global.process && _global.__vitest_required__ && _global.__vitest_required__.util.promisify; + isPresent.performance = + _global.performance && typeof _global.performance.now === "function"; + const hasPerformancePrototype = + _global.Performance && + (typeof _global.Performance).match(/^(function|object)$/); + const hasPerformanceConstructorPrototype = + _global.performance && + _global.performance.constructor && + _global.performance.constructor.prototype; + isPresent.queueMicrotask = _global.hasOwnProperty("queueMicrotask"); + isPresent.requestAnimationFrame = + _global.requestAnimationFrame && + typeof _global.requestAnimationFrame === "function"; + isPresent.cancelAnimationFrame = + _global.cancelAnimationFrame && + typeof _global.cancelAnimationFrame === "function"; + isPresent.requestIdleCallback = + _global.requestIdleCallback && + typeof _global.requestIdleCallback === "function"; + isPresent.cancelIdleCallbackPresent = + _global.cancelIdleCallback && + typeof _global.cancelIdleCallback === "function"; + isPresent.setImmediate = + _global.setImmediate && typeof _global.setImmediate === "function"; + isPresent.clearImmediate = + _global.clearImmediate && typeof _global.clearImmediate === "function"; + isPresent.Intl = _global.Intl && typeof _global.Intl === "object"; + + if (_global.clearTimeout) { + _global.clearTimeout(timeoutResult); + } + + const NativeDate = _global.Date; + const NativeIntl = isPresent.Intl + ? Object.defineProperties( + Object.create(null), + Object.getOwnPropertyDescriptors(_global.Intl), + ) + : undefined; + let uniqueTimerId = idCounterStart; + + if (NativeDate === undefined) { + throw new Error( + "The global scope doesn't have a `Date` object" + + " (see https://github.com/sinonjs/sinon/issues/1852#issuecomment-419622780)", + ); + } + isPresent.Date = true; + + /** + * The PerformanceEntry object encapsulates a single performance metric + * that is part of the browser's performance timeline. + * + * This is an object returned by the `mark` and `measure` methods on the Performance prototype + */ + class FakePerformanceEntry { + constructor(name, entryType, startTime, duration) { + this.name = name; + this.entryType = entryType; + this.startTime = startTime; + this.duration = duration; + } + + toJSON() { + return JSON.stringify({ ...this }); + } + } + + /** + * @param {number} num + * @returns {boolean} + */ + function isNumberFinite(num) { + if (Number.isFinite) { + return Number.isFinite(num); + } + + return isFinite(num); + } + + let isNearInfiniteLimit = false; + + /** + * @param {Clock} clock + * @param {number} i + */ + function checkIsNearInfiniteLimit(clock, i) { + if (clock.loopLimit && i === clock.loopLimit - 1) { + isNearInfiniteLimit = true; + } + } + + /** + * + */ + function resetIsNearInfiniteLimit() { + isNearInfiniteLimit = false; + } + + /** + * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into + * number of milliseconds. This is used to support human-readable strings passed + * to clock.tick() + * @param {string} str + * @returns {number} + */ + function parseTime(str) { + if (!str) { + return 0; + } + + const strings = str.split(":"); + const l = strings.length; + let i = l; + let ms = 0; + let parsed; + + if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) { + throw new Error( + "tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits", + ); + } + + while (i--) { + parsed = parseInt(strings[i], 10); + + if (parsed >= 60) { + throw new Error(`Invalid time ${str}`); + } + + ms += parsed * Math.pow(60, l - i - 1); + } + + return ms * 1000; + } + + /** + * Get the decimal part of the millisecond value as nanoseconds + * @param {number} msFloat the number of milliseconds + * @returns {number} an integer number of nanoseconds in the range [0,1e6) + * + * Example: nanoRemainer(123.456789) -> 456789 + */ + function nanoRemainder(msFloat) { + const modulo = 1e6; + const remainder = (msFloat * 1e6) % modulo; + const positiveRemainder = + remainder < 0 ? remainder + modulo : remainder; + + return Math.floor(positiveRemainder); + } + + /** + * Used to grok the `now` parameter to createClock. + * @param {Date|number} epoch the system time + * @returns {number} + */ + function getEpoch(epoch) { + if (!epoch) { + return 0; + } + if (typeof epoch.getTime === "function") { + return epoch.getTime(); + } + if (typeof epoch === "number") { + return epoch; + } + throw new TypeError("now should be milliseconds since UNIX epoch"); + } + + /** + * @param {number} from + * @param {number} to + * @param {Timer} timer + * @returns {boolean} + */ + function inRange(from, to, timer) { + return timer && timer.callAt >= from && timer.callAt <= to; + } + + /** + * @param {Clock} clock + * @param {Timer} job + */ + function getInfiniteLoopError(clock, job) { + const infiniteLoopError = new Error( + `Aborting after running ${clock.loopLimit} timers, assuming an infinite loop!`, + ); + + if (!job.error) { + return infiniteLoopError; + } + + // pattern never matched in Node + const computedTargetPattern = /target\.*[<|(|[].*?[>|\]|)]\s*/; + let clockMethodPattern = new RegExp( + String(Object.keys(clock).join("|")), + ); + + if (addTimerReturnsObject) { + // node.js environment + clockMethodPattern = new RegExp( + `\\s+at (Object\\.)?(?:${Object.keys(clock).join("|")})\\s+`, + ); + } + + let matchedLineIndex = -1; + job.error.stack.split("\n").some(function (line, i) { + // If we've matched a computed target line (e.g. setTimeout) then we + // don't need to look any further. Return true to stop iterating. + const matchedComputedTarget = line.match(computedTargetPattern); + /* istanbul ignore if */ + if (matchedComputedTarget) { + matchedLineIndex = i; + return true; + } + + // If we've matched a clock method line, then there may still be + // others further down the trace. Return false to keep iterating. + const matchedClockMethod = line.match(clockMethodPattern); + if (matchedClockMethod) { + matchedLineIndex = i; + return false; + } + + // If we haven't matched anything on this line, but we matched + // previously and set the matched line index, then we can stop. + // If we haven't matched previously, then we should keep iterating. + return matchedLineIndex >= 0; + }); + + const stack = `${infiniteLoopError}\n${job.type || "Microtask"} - ${ + job.func.name || "anonymous" + }\n${job.error.stack + .split("\n") + .slice(matchedLineIndex + 1) + .join("\n")}`; + + try { + Object.defineProperty(infiniteLoopError, "stack", { + value: stack, + }); + } catch (e) { + // noop + } + + return infiniteLoopError; + } + + //eslint-disable-next-line jsdoc/require-jsdoc + function createDate() { + class ClockDate extends NativeDate { + /** + * @param {number} year + * @param {number} month + * @param {number} date + * @param {number} hour + * @param {number} minute + * @param {number} second + * @param {number} ms + * @returns void + */ + // eslint-disable-next-line no-unused-vars + constructor(year, month, date, hour, minute, second, ms) { + // Defensive and verbose to avoid potential harm in passing + // explicit undefined when user does not pass argument + if (arguments.length === 0) { + super(ClockDate.clock.now); + } else { + super(...arguments); + } + + // ensures identity checks using the constructor prop still works + // this should have no other functional effect + Object.defineProperty(this, "constructor", { + value: NativeDate, + enumerable: false, + }); + } + + static [Symbol.hasInstance](instance) { + return instance instanceof NativeDate; + } + } + + ClockDate.isFake = true; + + if (NativeDate.now) { + ClockDate.now = function now() { + return ClockDate.clock.now; + }; + } + + if (NativeDate.toSource) { + ClockDate.toSource = function toSource() { + return NativeDate.toSource(); + }; + } + + ClockDate.toString = function toString() { + return NativeDate.toString(); + }; + + // noinspection UnnecessaryLocalVariableJS + /** + * A normal Class constructor cannot be called without `new`, but Date can, so we need + * to wrap it in a Proxy in order to ensure this functionality of Date is kept intact + * @type {ClockDate} + */ + const ClockDateProxy = new Proxy(ClockDate, { + // handler for [[Call]] invocations (i.e. not using `new`) + apply() { + // the Date constructor called as a function, ref Ecma-262 Edition 5.1, section 15.9.2. + // This remains so in the 10th edition of 2019 as well. + if (this instanceof ClockDate) { + throw new TypeError( + "A Proxy should only capture `new` calls with the `construct` handler. This is not supposed to be possible, so check the logic.", + ); + } + + return new NativeDate(ClockDate.clock.now).toString(); + }, + }); + + return ClockDateProxy; + } + + /** + * Mirror Intl by default on our fake implementation + * + * Most of the properties are the original native ones, + * but we need to take control of those that have a + * dependency on the current clock. + * @returns {object} the partly fake Intl implementation + */ + function createIntl() { + const ClockIntl = {}; + /* + * All properties of Intl are non-enumerable, so we need + * to do a bit of work to get them out. + */ + Object.getOwnPropertyNames(NativeIntl).forEach( + (property) => (ClockIntl[property] = NativeIntl[property]), + ); + + ClockIntl.DateTimeFormat = function (...args) { + const realFormatter = new NativeIntl.DateTimeFormat(...args); + const formatter = {}; + + ["formatRange", "formatRangeToParts", "resolvedOptions"].forEach( + (method) => { + formatter[method] = + realFormatter[method].bind(realFormatter); + }, + ); + + ["format", "formatToParts"].forEach((method) => { + formatter[method] = function (date) { + return realFormatter[method](date || ClockIntl.clock.now); + }; + }); + + return formatter; + }; + + ClockIntl.DateTimeFormat.prototype = Object.create( + NativeIntl.DateTimeFormat.prototype, + ); + + ClockIntl.DateTimeFormat.supportedLocalesOf = + NativeIntl.DateTimeFormat.supportedLocalesOf; + + return ClockIntl; + } + + //eslint-disable-next-line jsdoc/require-jsdoc + function enqueueJob(clock, job) { + // enqueues a microtick-deferred task - ecma262/#sec-enqueuejob + if (!clock.jobs) { + clock.jobs = []; + } + clock.jobs.push(job); + } + + //eslint-disable-next-line jsdoc/require-jsdoc + function runJobs(clock) { + // runs all microtick-deferred tasks - ecma262/#sec-runjobs + if (!clock.jobs) { + return; + } + for (let i = 0; i < clock.jobs.length; i++) { + const job = clock.jobs[i]; + job.func.apply(null, job.args); + + checkIsNearInfiniteLimit(clock, i); + if (clock.loopLimit && i > clock.loopLimit) { + throw getInfiniteLoopError(clock, job); + } + } + resetIsNearInfiniteLimit(); + clock.jobs = []; + } + + /** + * @param {Clock} clock + * @param {Timer} timer + * @returns {number} id of the created timer + */ + function addTimer(clock, timer) { + if (timer.func === undefined) { + throw new Error("Callback must be provided to timer calls"); + } + + if (addTimerReturnsObject) { + // Node.js environment + if (typeof timer.func !== "function") { + throw new TypeError( + `[ERR_INVALID_CALLBACK]: Callback must be a function. Received ${ + timer.func + } of type ${typeof timer.func}`, + ); + } + } + + if (isNearInfiniteLimit) { + timer.error = new Error(); + } + + timer.type = timer.immediate ? "Immediate" : "Timeout"; + + if (timer.hasOwnProperty("delay")) { + if (typeof timer.delay !== "number") { + timer.delay = parseInt(timer.delay, 10); + } + + if (!isNumberFinite(timer.delay)) { + timer.delay = 0; + } + timer.delay = timer.delay > maxTimeout ? 1 : timer.delay; + timer.delay = Math.max(0, timer.delay); + } + + if (timer.hasOwnProperty("interval")) { + timer.type = "Interval"; + timer.interval = timer.interval > maxTimeout ? 1 : timer.interval; + } + + if (timer.hasOwnProperty("animation")) { + timer.type = "AnimationFrame"; + timer.animation = true; + } + + if (timer.hasOwnProperty("idleCallback")) { + timer.type = "IdleCallback"; + timer.idleCallback = true; + } + + if (!clock.timers) { + clock.timers = {}; + } + + timer.id = uniqueTimerId++; + timer.createdAt = clock.now; + timer.callAt = + clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0)); + + clock.timers[timer.id] = timer; + + if (addTimerReturnsObject) { + const res = { + refed: true, + ref: function () { + this.refed = true; + return res; + }, + unref: function () { + this.refed = false; + return res; + }, + hasRef: function () { + return this.refed; + }, + refresh: function () { + timer.callAt = + clock.now + + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0)); + + // it _might_ have been removed, but if not the assignment is perfectly fine + clock.timers[timer.id] = timer; + + return res; + }, + [Symbol.toPrimitive]: function () { + return timer.id; + }, + }; + return res; + } + + return timer.id; + } + + /* eslint consistent-return: "off" */ + /** + * Timer comparitor + * @param {Timer} a + * @param {Timer} b + * @returns {number} + */ + function compareTimers(a, b) { + // Sort first by absolute timing + if (a.callAt < b.callAt) { + return -1; + } + if (a.callAt > b.callAt) { + return 1; + } + + // Sort next by immediate, immediate timers take precedence + if (a.immediate && !b.immediate) { + return -1; + } + if (!a.immediate && b.immediate) { + return 1; + } + + // Sort next by creation time, earlier-created timers take precedence + if (a.createdAt < b.createdAt) { + return -1; + } + if (a.createdAt > b.createdAt) { + return 1; + } + + // Sort next by id, lower-id timers take precedence + if (a.id < b.id) { + return -1; + } + if (a.id > b.id) { + return 1; + } + + // As timer ids are unique, no fallback `0` is necessary + } + + /** + * @param {Clock} clock + * @param {number} from + * @param {number} to + * @returns {Timer} + */ + function firstTimerInRange(clock, from, to) { + const timers = clock.timers; + let timer = null; + let id, isInRange; + + for (id in timers) { + if (timers.hasOwnProperty(id)) { + isInRange = inRange(from, to, timers[id]); + + if ( + isInRange && + (!timer || compareTimers(timer, timers[id]) === 1) + ) { + timer = timers[id]; + } + } + } + + return timer; + } + + /** + * @param {Clock} clock + * @returns {Timer} + */ + function firstTimer(clock) { + const timers = clock.timers; + let timer = null; + let id; + + for (id in timers) { + if (timers.hasOwnProperty(id)) { + if (!timer || compareTimers(timer, timers[id]) === 1) { + timer = timers[id]; + } + } + } + + return timer; + } + + /** + * @param {Clock} clock + * @returns {Timer} + */ + function lastTimer(clock) { + const timers = clock.timers; + let timer = null; + let id; + + for (id in timers) { + if (timers.hasOwnProperty(id)) { + if (!timer || compareTimers(timer, timers[id]) === -1) { + timer = timers[id]; + } + } + } + + return timer; + } + + /** + * @param {Clock} clock + * @param {Timer} timer + */ + function callTimer(clock, timer) { + if (typeof timer.interval === "number") { + clock.timers[timer.id].callAt += timer.interval; + } else { + delete clock.timers[timer.id]; + } + + if (typeof timer.func === "function") { + timer.func.apply(null, timer.args); + } else { + /* eslint no-eval: "off" */ + const eval2 = eval; + (function () { + eval2(timer.func); + })(); + } + } + + /** + * Gets clear handler name for a given timer type + * @param {string} ttype + */ + function getClearHandler(ttype) { + if (ttype === "IdleCallback" || ttype === "AnimationFrame") { + return `cancel${ttype}`; + } + return `clear${ttype}`; + } + + /** + * Gets schedule handler name for a given timer type + * @param {string} ttype + */ + function getScheduleHandler(ttype) { + if (ttype === "IdleCallback" || ttype === "AnimationFrame") { + return `request${ttype}`; + } + return `set${ttype}`; + } + + /** + * Creates an anonymous function to warn only once + */ + function createWarnOnce() { + let calls = 0; + return function (msg) { + // eslint-disable-next-line + !calls++ && console.warn(msg); + }; + } + const warnOnce = createWarnOnce(); + + /** + * @param {Clock} clock + * @param {number} timerId + * @param {string} ttype + */ + function clearTimer(clock, timerId, ttype) { + if (!timerId) { + // null appears to be allowed in most browsers, and appears to be + // relied upon by some libraries, like Bootstrap carousel + return; + } + + if (!clock.timers) { + clock.timers = {}; + } + + // in Node, the ID is stored as the primitive value for `Timeout` objects + // for `Immediate` objects, no ID exists, so it gets coerced to NaN + const id = Number(timerId); + + if (Number.isNaN(id) || id < idCounterStart) { + const handlerName = getClearHandler(ttype); + + if (clock.shouldClearNativeTimers === true) { + const nativeHandler = clock[`_${handlerName}`]; + return typeof nativeHandler === "function" + ? nativeHandler(timerId) + : undefined; + } + warnOnce( + `FakeTimers: ${handlerName} was invoked to clear a native timer instead of one created by this library.` + + "\nTo automatically clean-up native timers, use `shouldClearNativeTimers`.", + ); + } + + if (clock.timers.hasOwnProperty(id)) { + // check that the ID matches a timer of the correct type + const timer = clock.timers[id]; + if ( + timer.type === ttype || + (timer.type === "Timeout" && ttype === "Interval") || + (timer.type === "Interval" && ttype === "Timeout") + ) { + delete clock.timers[id]; + } else { + const clear = getClearHandler(ttype); + const schedule = getScheduleHandler(timer.type); + throw new Error( + `Cannot clear timer: timer created with ${schedule}() but cleared with ${clear}()`, + ); + } + } + } + + /** + * @param {Clock} clock + * @param {Config} config + * @returns {Timer[]} + */ + function uninstall(clock, config) { + let method, i, l; + const installedHrTime = "_hrtime"; + const installedNextTick = "_nextTick"; + + for (i = 0, l = clock.methods.length; i < l; i++) { + method = clock.methods[i]; + if (method === "hrtime" && _global.process) { + _global.process.hrtime = clock[installedHrTime]; + } else if (method === "nextTick" && _global.process) { + _global.process.nextTick = clock[installedNextTick]; + } else if (method === "performance") { + const originalPerfDescriptor = Object.getOwnPropertyDescriptor( + clock, + `_${method}`, + ); + if ( + originalPerfDescriptor && + originalPerfDescriptor.get && + !originalPerfDescriptor.set + ) { + Object.defineProperty( + _global, + method, + originalPerfDescriptor, + ); + } else if (originalPerfDescriptor.configurable) { + _global[method] = clock[`_${method}`]; + } + } else { + if (_global[method] && _global[method].hadOwnProperty) { + _global[method] = clock[`_${method}`]; + } else { + try { + delete _global[method]; + } catch (ignore) { + /* eslint no-empty: "off" */ + } + } + } + if (clock.timersModuleMethods !== undefined) { + for (let j = 0; j < clock.timersModuleMethods.length; j++) { + const entry = clock.timersModuleMethods[j]; + timersModule[entry.methodName] = entry.original; + } + } + if (clock.timersPromisesModuleMethods !== undefined) { + for ( + let j = 0; + j < clock.timersPromisesModuleMethods.length; + j++ + ) { + const entry = clock.timersPromisesModuleMethods[j]; + timersPromisesModule[entry.methodName] = entry.original; + } + } + } + + if (config.shouldAdvanceTime === true) { + _global.clearInterval(clock.attachedInterval); + } + + // Prevent multiple executions which will completely remove these props + clock.methods = []; + + for (const [listener, signal] of clock.abortListenerMap.entries()) { + signal.removeEventListener("abort", listener); + clock.abortListenerMap.delete(listener); + } + + // return pending timers, to enable checking what timers remained on uninstall + if (!clock.timers) { + return []; + } + return Object.keys(clock.timers).map(function mapper(key) { + return clock.timers[key]; + }); + } + + /** + * @param {object} target the target containing the method to replace + * @param {string} method the keyname of the method on the target + * @param {Clock} clock + */ + function hijackMethod(target, method, clock) { + clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call( + target, + method, + ); + clock[`_${method}`] = target[method]; + + if (method === "Date") { + target[method] = clock[method]; + } else if (method === "Intl") { + target[method] = clock[method]; + } else if (method === "performance") { + const originalPerfDescriptor = Object.getOwnPropertyDescriptor( + target, + method, + ); + // JSDOM has a read only performance field so we have to save/copy it differently + if ( + originalPerfDescriptor && + originalPerfDescriptor.get && + !originalPerfDescriptor.set + ) { + Object.defineProperty( + clock, + `_${method}`, + originalPerfDescriptor, + ); + + const perfDescriptor = Object.getOwnPropertyDescriptor( + clock, + method, + ); + Object.defineProperty(target, method, perfDescriptor); + } else { + target[method] = clock[method]; + } + } else { + target[method] = function () { + return clock[method].apply(clock, arguments); + }; + + Object.defineProperties( + target[method], + Object.getOwnPropertyDescriptors(clock[method]), + ); + } + + target[method].clock = clock; + } + + /** + * @param {Clock} clock + * @param {number} advanceTimeDelta + */ + function doIntervalTick(clock, advanceTimeDelta) { + clock.tick(advanceTimeDelta); + } + + /** + * @typedef {object} Timers + * @property {setTimeout} setTimeout + * @property {clearTimeout} clearTimeout + * @property {setInterval} setInterval + * @property {clearInterval} clearInterval + * @property {Date} Date + * @property {Intl} Intl + * @property {SetImmediate=} setImmediate + * @property {function(NodeImmediate): void=} clearImmediate + * @property {function(number[]):number[]=} hrtime + * @property {NextTick=} nextTick + * @property {Performance=} performance + * @property {RequestAnimationFrame=} requestAnimationFrame + * @property {boolean=} queueMicrotask + * @property {function(number): void=} cancelAnimationFrame + * @property {RequestIdleCallback=} requestIdleCallback + * @property {function(number): void=} cancelIdleCallback + */ + + /** @type {Timers} */ + const timers = { + setTimeout: _global.setTimeout, + clearTimeout: _global.clearTimeout, + setInterval: _global.setInterval, + clearInterval: _global.clearInterval, + Date: _global.Date, + }; + + if (isPresent.setImmediate) { + timers.setImmediate = _global.setImmediate; + } + + if (isPresent.clearImmediate) { + timers.clearImmediate = _global.clearImmediate; + } + + if (isPresent.hrtime) { + timers.hrtime = _global.process.hrtime; + } + + if (isPresent.nextTick) { + timers.nextTick = _global.process.nextTick; + } + + if (isPresent.performance) { + timers.performance = _global.performance; + } + + if (isPresent.requestAnimationFrame) { + timers.requestAnimationFrame = _global.requestAnimationFrame; + } + + if (isPresent.queueMicrotask) { + timers.queueMicrotask = _global.queueMicrotask; + } + + if (isPresent.cancelAnimationFrame) { + timers.cancelAnimationFrame = _global.cancelAnimationFrame; + } + + if (isPresent.requestIdleCallback) { + timers.requestIdleCallback = _global.requestIdleCallback; + } + + if (isPresent.cancelIdleCallback) { + timers.cancelIdleCallback = _global.cancelIdleCallback; + } + + if (isPresent.Intl) { + timers.Intl = NativeIntl; + } + + const originalSetTimeout = _global.setImmediate || _global.setTimeout; + + /** + * @param {Date|number} [start] the system time - non-integer values are floored + * @param {number} [loopLimit] maximum number of timers that will be run when calling runAll() + * @returns {Clock} + */ + function createClock(start, loopLimit) { + // eslint-disable-next-line no-param-reassign + start = Math.floor(getEpoch(start)); + // eslint-disable-next-line no-param-reassign + loopLimit = loopLimit || 1000; + let nanos = 0; + const adjustedSystemTime = [0, 0]; // [millis, nanoremainder] + + const clock = { + now: start, + Date: createDate(), + loopLimit: loopLimit, + }; + + clock.Date.clock = clock; + + //eslint-disable-next-line jsdoc/require-jsdoc + function getTimeToNextFrame() { + return 16 - ((clock.now - start) % 16); + } + + //eslint-disable-next-line jsdoc/require-jsdoc + function hrtime(prev) { + const millisSinceStart = clock.now - adjustedSystemTime[0] - start; + const secsSinceStart = Math.floor(millisSinceStart / 1000); + const remainderInNanos = + (millisSinceStart - secsSinceStart * 1e3) * 1e6 + + nanos - + adjustedSystemTime[1]; + + if (Array.isArray(prev)) { + if (prev[1] > 1e9) { + throw new TypeError( + "Number of nanoseconds can't exceed a billion", + ); + } + + const oldSecs = prev[0]; + let nanoDiff = remainderInNanos - prev[1]; + let secDiff = secsSinceStart - oldSecs; + + if (nanoDiff < 0) { + nanoDiff += 1e9; + secDiff -= 1; + } + + return [secDiff, nanoDiff]; + } + return [secsSinceStart, remainderInNanos]; + } + + /** + * A high resolution timestamp in milliseconds. + * @typedef {number} DOMHighResTimeStamp + */ + + /** + * performance.now() + * @returns {DOMHighResTimeStamp} + */ + function fakePerformanceNow() { + const hrt = hrtime(); + const millis = hrt[0] * 1000 + hrt[1] / 1e6; + return millis; + } + + if (isPresent.hrtimeBigint) { + hrtime.bigint = function () { + const parts = hrtime(); + return BigInt(parts[0]) * BigInt(1e9) + BigInt(parts[1]); // eslint-disable-line + }; + } + + if (isPresent.Intl) { + clock.Intl = createIntl(); + clock.Intl.clock = clock; + } + + clock.requestIdleCallback = function requestIdleCallback( + func, + timeout, + ) { + let timeToNextIdlePeriod = 0; + + if (clock.countTimers() > 0) { + timeToNextIdlePeriod = 50; // const for now + } + + const result = addTimer(clock, { + func: func, + args: Array.prototype.slice.call(arguments, 2), + delay: + typeof timeout === "undefined" + ? timeToNextIdlePeriod + : Math.min(timeout, timeToNextIdlePeriod), + idleCallback: true, + }); + + return Number(result); + }; + + clock.cancelIdleCallback = function cancelIdleCallback(timerId) { + return clearTimer(clock, timerId, "IdleCallback"); + }; + + clock.setTimeout = function setTimeout(func, timeout) { + return addTimer(clock, { + func: func, + args: Array.prototype.slice.call(arguments, 2), + delay: timeout, + }); + }; + if (typeof _global.Promise !== "undefined" && utilPromisify) { + clock.setTimeout[utilPromisify.custom] = + function promisifiedSetTimeout(timeout, arg) { + return new _global.Promise(function setTimeoutExecutor( + resolve, + ) { + addTimer(clock, { + func: resolve, + args: [arg], + delay: timeout, + }); + }); + }; + } + + clock.clearTimeout = function clearTimeout(timerId) { + return clearTimer(clock, timerId, "Timeout"); + }; + + clock.nextTick = function nextTick(func) { + return enqueueJob(clock, { + func: func, + args: Array.prototype.slice.call(arguments, 1), + error: isNearInfiniteLimit ? new Error() : null, + }); + }; + + clock.queueMicrotask = function queueMicrotask(func) { + return clock.nextTick(func); // explicitly drop additional arguments + }; + + clock.setInterval = function setInterval(func, timeout) { + // eslint-disable-next-line no-param-reassign + timeout = parseInt(timeout, 10); + return addTimer(clock, { + func: func, + args: Array.prototype.slice.call(arguments, 2), + delay: timeout, + interval: timeout, + }); + }; + + clock.clearInterval = function clearInterval(timerId) { + return clearTimer(clock, timerId, "Interval"); + }; + + if (isPresent.setImmediate) { + clock.setImmediate = function setImmediate(func) { + return addTimer(clock, { + func: func, + args: Array.prototype.slice.call(arguments, 1), + immediate: true, + }); + }; + + if (typeof _global.Promise !== "undefined" && utilPromisify) { + clock.setImmediate[utilPromisify.custom] = + function promisifiedSetImmediate(arg) { + return new _global.Promise( + function setImmediateExecutor(resolve) { + addTimer(clock, { + func: resolve, + args: [arg], + immediate: true, + }); + }, + ); + }; + } + + clock.clearImmediate = function clearImmediate(timerId) { + return clearTimer(clock, timerId, "Immediate"); + }; + } + + clock.countTimers = function countTimers() { + return ( + Object.keys(clock.timers || {}).length + + (clock.jobs || []).length + ); + }; + + clock.requestAnimationFrame = function requestAnimationFrame(func) { + const result = addTimer(clock, { + func: func, + delay: getTimeToNextFrame(), + get args() { + return [fakePerformanceNow()]; + }, + animation: true, + }); + + return Number(result); + }; + + clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) { + return clearTimer(clock, timerId, "AnimationFrame"); + }; + + clock.runMicrotasks = function runMicrotasks() { + runJobs(clock); + }; + + /** + * @param {number|string} tickValue milliseconds or a string parseable by parseTime + * @param {boolean} isAsync + * @param {Function} resolve + * @param {Function} reject + * @returns {number|undefined} will return the new `now` value or nothing for async + */ + function doTick(tickValue, isAsync, resolve, reject) { + const msFloat = + typeof tickValue === "number" + ? tickValue + : parseTime(tickValue); + const ms = Math.floor(msFloat); + const remainder = nanoRemainder(msFloat); + let nanosTotal = nanos + remainder; + let tickTo = clock.now + ms; + + if (msFloat < 0) { + throw new TypeError("Negative ticks are not supported"); + } + + // adjust for positive overflow + if (nanosTotal >= 1e6) { + tickTo += 1; + nanosTotal -= 1e6; + } + + nanos = nanosTotal; + let tickFrom = clock.now; + let previous = clock.now; + // ESLint fails to detect this correctly + /* eslint-disable prefer-const */ + let timer, + firstException, + oldNow, + nextPromiseTick, + compensationCheck, + postTimerCall; + /* eslint-enable prefer-const */ + + clock.duringTick = true; + + // perform microtasks + oldNow = clock.now; + runJobs(clock); + if (oldNow !== clock.now) { + // compensate for any setSystemTime() call during microtask callback + tickFrom += clock.now - oldNow; + tickTo += clock.now - oldNow; + } + + //eslint-disable-next-line jsdoc/require-jsdoc + function doTickInner() { + // perform each timer in the requested range + timer = firstTimerInRange(clock, tickFrom, tickTo); + // eslint-disable-next-line no-unmodified-loop-condition + while (timer && tickFrom <= tickTo) { + if (clock.timers[timer.id]) { + tickFrom = timer.callAt; + clock.now = timer.callAt; + oldNow = clock.now; + try { + runJobs(clock); + callTimer(clock, timer); + } catch (e) { + firstException = firstException || e; + } + + if (isAsync) { + // finish up after native setImmediate callback to allow + // all native es6 promises to process their callbacks after + // each timer fires. + originalSetTimeout(nextPromiseTick); + return; + } + + compensationCheck(); + } + + postTimerCall(); + } + + // perform process.nextTick()s again + oldNow = clock.now; + runJobs(clock); + if (oldNow !== clock.now) { + // compensate for any setSystemTime() call during process.nextTick() callback + tickFrom += clock.now - oldNow; + tickTo += clock.now - oldNow; + } + clock.duringTick = false; + + // corner case: during runJobs new timers were scheduled which could be in the range [clock.now, tickTo] + timer = firstTimerInRange(clock, tickFrom, tickTo); + if (timer) { + try { + clock.tick(tickTo - clock.now); // do it all again - for the remainder of the requested range + } catch (e) { + firstException = firstException || e; + } + } else { + // no timers remaining in the requested range: move the clock all the way to the end + clock.now = tickTo; + + // update nanos + nanos = nanosTotal; + } + if (firstException) { + throw firstException; + } + + if (isAsync) { + resolve(clock.now); + } else { + return clock.now; + } + } + + nextPromiseTick = + isAsync && + function () { + try { + compensationCheck(); + postTimerCall(); + doTickInner(); + } catch (e) { + reject(e); + } + }; + + compensationCheck = function () { + // compensate for any setSystemTime() call during timer callback + if (oldNow !== clock.now) { + tickFrom += clock.now - oldNow; + tickTo += clock.now - oldNow; + previous += clock.now - oldNow; + } + }; + + postTimerCall = function () { + timer = firstTimerInRange(clock, previous, tickTo); + previous = tickFrom; + }; + + return doTickInner(); + } + + /** + * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15" + * @returns {number} will return the new `now` value + */ + clock.tick = function tick(tickValue) { + return doTick(tickValue, false); + }; + + if (typeof _global.Promise !== "undefined") { + /** + * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15" + * @returns {Promise} + */ + clock.tickAsync = function tickAsync(tickValue) { + return new _global.Promise(function (resolve, reject) { + originalSetTimeout(function () { + try { + doTick(tickValue, true, resolve, reject); + } catch (e) { + reject(e); + } + }); + }); + }; + } + + clock.next = function next() { + runJobs(clock); + const timer = firstTimer(clock); + if (!timer) { + return clock.now; + } + + clock.duringTick = true; + try { + clock.now = timer.callAt; + callTimer(clock, timer); + runJobs(clock); + return clock.now; + } finally { + clock.duringTick = false; + } + }; + + if (typeof _global.Promise !== "undefined") { + clock.nextAsync = function nextAsync() { + return new _global.Promise(function (resolve, reject) { + originalSetTimeout(function () { + try { + const timer = firstTimer(clock); + if (!timer) { + resolve(clock.now); + return; + } + + let err; + clock.duringTick = true; + clock.now = timer.callAt; + try { + callTimer(clock, timer); + } catch (e) { + err = e; + } + clock.duringTick = false; + + originalSetTimeout(function () { + if (err) { + reject(err); + } else { + resolve(clock.now); + } + }); + } catch (e) { + reject(e); + } + }); + }); + }; + } + + clock.runAll = function runAll() { + let numTimers, i; + runJobs(clock); + for (i = 0; i < clock.loopLimit; i++) { + if (!clock.timers) { + resetIsNearInfiniteLimit(); + return clock.now; + } + + numTimers = Object.keys(clock.timers).length; + if (numTimers === 0) { + resetIsNearInfiniteLimit(); + return clock.now; + } + + clock.next(); + checkIsNearInfiniteLimit(clock, i); + } + + const excessJob = firstTimer(clock); + throw getInfiniteLoopError(clock, excessJob); + }; + + clock.runToFrame = function runToFrame() { + return clock.tick(getTimeToNextFrame()); + }; + + if (typeof _global.Promise !== "undefined") { + clock.runAllAsync = function runAllAsync() { + return new _global.Promise(function (resolve, reject) { + let i = 0; + /** + * + */ + function doRun() { + originalSetTimeout(function () { + try { + runJobs(clock); + + let numTimers; + if (i < clock.loopLimit) { + if (!clock.timers) { + resetIsNearInfiniteLimit(); + resolve(clock.now); + return; + } + + numTimers = Object.keys( + clock.timers, + ).length; + if (numTimers === 0) { + resetIsNearInfiniteLimit(); + resolve(clock.now); + return; + } + + clock.next(); + + i++; + + doRun(); + checkIsNearInfiniteLimit(clock, i); + return; + } + + const excessJob = firstTimer(clock); + reject(getInfiniteLoopError(clock, excessJob)); + } catch (e) { + reject(e); + } + }); + } + doRun(); + }); + }; + } + + clock.runToLast = function runToLast() { + const timer = lastTimer(clock); + if (!timer) { + runJobs(clock); + return clock.now; + } + + return clock.tick(timer.callAt - clock.now); + }; + + if (typeof _global.Promise !== "undefined") { + clock.runToLastAsync = function runToLastAsync() { + return new _global.Promise(function (resolve, reject) { + originalSetTimeout(function () { + try { + const timer = lastTimer(clock); + if (!timer) { + runJobs(clock); + resolve(clock.now); + } + + resolve(clock.tickAsync(timer.callAt - clock.now)); + } catch (e) { + reject(e); + } + }); + }); + }; + } + + clock.reset = function reset() { + nanos = 0; + clock.timers = {}; + clock.jobs = []; + clock.now = start; + }; + + clock.setSystemTime = function setSystemTime(systemTime) { + // determine time difference + const newNow = getEpoch(systemTime); + const difference = newNow - clock.now; + let id, timer; + + adjustedSystemTime[0] = adjustedSystemTime[0] + difference; + adjustedSystemTime[1] = adjustedSystemTime[1] + nanos; + // update 'system clock' + clock.now = newNow; + nanos = 0; + + // update timers and intervals to keep them stable + for (id in clock.timers) { + if (clock.timers.hasOwnProperty(id)) { + timer = clock.timers[id]; + timer.createdAt += difference; + timer.callAt += difference; + } + } + }; + + /** + * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15" + * @returns {number} will return the new `now` value + */ + clock.jump = function jump(tickValue) { + const msFloat = + typeof tickValue === "number" + ? tickValue + : parseTime(tickValue); + const ms = Math.floor(msFloat); + + for (const timer of Object.values(clock.timers)) { + if (clock.now + ms > timer.callAt) { + timer.callAt = clock.now + ms; + } + } + clock.tick(ms); + }; + + if (isPresent.performance) { + clock.performance = Object.create(null); + clock.performance.now = fakePerformanceNow; + } + + if (isPresent.hrtime) { + clock.hrtime = hrtime; + } + + return clock; + } + + /* eslint-disable complexity */ + + /** + * @param {Config=} [config] Optional config + * @returns {Clock} + */ + function install(config) { + if ( + arguments.length > 1 || + config instanceof Date || + Array.isArray(config) || + typeof config === "number" + ) { + throw new TypeError( + `FakeTimers.install called with ${String( + config, + )} install requires an object parameter`, + ); + } + + if (_global.Date.isFake === true) { + // Timers are already faked; this is a problem. + // Make the user reset timers before continuing. + throw new TypeError( + "Can't install fake timers twice on the same global object.", + ); + } + + // eslint-disable-next-line no-param-reassign + config = typeof config !== "undefined" ? config : {}; + config.shouldAdvanceTime = config.shouldAdvanceTime || false; + config.advanceTimeDelta = config.advanceTimeDelta || 20; + config.shouldClearNativeTimers = + config.shouldClearNativeTimers || false; + + if (config.target) { + throw new TypeError( + "config.target is no longer supported. Use `withGlobal(target)` instead.", + ); + } + + /** + * @param {string} timer/object the name of the thing that is not present + * @param timer + */ + function handleMissingTimer(timer) { + if (config.ignoreMissingTimers) { + return; + } + + throw new ReferenceError( + `non-existent timers and/or objects cannot be faked: '${timer}'`, + ); + } + + let i, l; + const clock = createClock(config.now, config.loopLimit); + clock.shouldClearNativeTimers = config.shouldClearNativeTimers; + + clock.uninstall = function () { + return uninstall(clock, config); + }; + + clock.abortListenerMap = new Map(); + + clock.methods = config.toFake || []; + + if (clock.methods.length === 0) { + clock.methods = Object.keys(timers); + } + + if (config.shouldAdvanceTime === true) { + const intervalTick = doIntervalTick.bind( + null, + clock, + config.advanceTimeDelta, + ); + const intervalId = _global.setInterval( + intervalTick, + config.advanceTimeDelta, + ); + clock.attachedInterval = intervalId; + } + + if (clock.methods.includes("performance")) { + const proto = (() => { + if (hasPerformanceConstructorPrototype) { + return _global.performance.constructor.prototype; + } + if (hasPerformancePrototype) { + return _global.Performance.prototype; + } + })(); + if (proto) { + Object.getOwnPropertyNames(proto).forEach(function (name) { + if (name !== "now") { + clock.performance[name] = + name.indexOf("getEntries") === 0 + ? NOOP_ARRAY + : NOOP; + } + }); + // ensure `mark` returns a value that is valid + clock.performance.mark = (name) => + new FakePerformanceEntry(name, "mark", 0, 0); + clock.performance.measure = (name) => + new FakePerformanceEntry(name, "measure", 0, 100); + // `timeOrigin` should return the time of when the Window session started + // (or the Worker was installed) + clock.performance.timeOrigin = getEpoch(config.now); + } else if ((config.toFake || []).includes("performance")) { + return handleMissingTimer("performance"); + } + } + if (_global === globalObject && timersModule) { + clock.timersModuleMethods = []; + } + if (_global === globalObject && timersPromisesModule) { + clock.timersPromisesModuleMethods = []; + } + for (i = 0, l = clock.methods.length; i < l; i++) { + const nameOfMethodToReplace = clock.methods[i]; + + if (!isPresent[nameOfMethodToReplace]) { + handleMissingTimer(nameOfMethodToReplace); + // eslint-disable-next-line + continue; + } + + if (nameOfMethodToReplace === "hrtime") { + if ( + _global.process && + typeof _global.process.hrtime === "function" + ) { + hijackMethod(_global.process, nameOfMethodToReplace, clock); + } + } else if (nameOfMethodToReplace === "nextTick") { + if ( + _global.process && + typeof _global.process.nextTick === "function" + ) { + hijackMethod(_global.process, nameOfMethodToReplace, clock); + } + } else { + hijackMethod(_global, nameOfMethodToReplace, clock); + } + if ( + clock.timersModuleMethods !== undefined && + timersModule[nameOfMethodToReplace] + ) { + const original = timersModule[nameOfMethodToReplace]; + clock.timersModuleMethods.push({ + methodName: nameOfMethodToReplace, + original: original, + }); + timersModule[nameOfMethodToReplace] = + _global[nameOfMethodToReplace]; + } + if (clock.timersPromisesModuleMethods !== undefined) { + if (nameOfMethodToReplace === "setTimeout") { + clock.timersPromisesModuleMethods.push({ + methodName: "setTimeout", + original: timersPromisesModule.setTimeout, + }); + + timersPromisesModule.setTimeout = ( + delay, + value, + options = {}, + ) => + new Promise((resolve, reject) => { + const abort = () => { + options.signal.removeEventListener( + "abort", + abort, + ); + clock.abortListenerMap.delete(abort); + + // This is safe, there is no code path that leads to this function + // being invoked before handle has been assigned. + // eslint-disable-next-line no-use-before-define + clock.clearTimeout(handle); + reject(options.signal.reason); + }; + + const handle = clock.setTimeout(() => { + if (options.signal) { + options.signal.removeEventListener( + "abort", + abort, + ); + clock.abortListenerMap.delete(abort); + } + + resolve(value); + }, delay); + + if (options.signal) { + if (options.signal.aborted) { + abort(); + } else { + options.signal.addEventListener( + "abort", + abort, + ); + clock.abortListenerMap.set( + abort, + options.signal, + ); + } + } + }); + } else if (nameOfMethodToReplace === "setImmediate") { + clock.timersPromisesModuleMethods.push({ + methodName: "setImmediate", + original: timersPromisesModule.setImmediate, + }); + + timersPromisesModule.setImmediate = (value, options = {}) => + new Promise((resolve, reject) => { + const abort = () => { + options.signal.removeEventListener( + "abort", + abort, + ); + clock.abortListenerMap.delete(abort); + + // This is safe, there is no code path that leads to this function + // being invoked before handle has been assigned. + // eslint-disable-next-line no-use-before-define + clock.clearImmediate(handle); + reject(options.signal.reason); + }; + + const handle = clock.setImmediate(() => { + if (options.signal) { + options.signal.removeEventListener( + "abort", + abort, + ); + clock.abortListenerMap.delete(abort); + } + + resolve(value); + }); + + if (options.signal) { + if (options.signal.aborted) { + abort(); + } else { + options.signal.addEventListener( + "abort", + abort, + ); + clock.abortListenerMap.set( + abort, + options.signal, + ); + } + } + }); + } else if (nameOfMethodToReplace === "setInterval") { + clock.timersPromisesModuleMethods.push({ + methodName: "setInterval", + original: timersPromisesModule.setInterval, + }); + + timersPromisesModule.setInterval = ( + delay, + value, + options = {}, + ) => ({ + [Symbol.asyncIterator]: () => { + const createResolvable = () => { + let resolve, reject; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + promise.resolve = resolve; + promise.reject = reject; + return promise; + }; + + let done = false; + let hasThrown = false; + let returnCall; + let nextAvailable = 0; + const nextQueue = []; + + const handle = clock.setInterval(() => { + if (nextQueue.length > 0) { + nextQueue.shift().resolve(); + } else { + nextAvailable++; + } + }, delay); + + const abort = () => { + options.signal.removeEventListener( + "abort", + abort, + ); + clock.abortListenerMap.delete(abort); + + clock.clearInterval(handle); + done = true; + for (const resolvable of nextQueue) { + resolvable.resolve(); + } + }; + + if (options.signal) { + if (options.signal.aborted) { + done = true; + } else { + options.signal.addEventListener( + "abort", + abort, + ); + clock.abortListenerMap.set( + abort, + options.signal, + ); + } + } + + return { + next: async () => { + if (options.signal?.aborted && !hasThrown) { + hasThrown = true; + throw options.signal.reason; + } + + if (done) { + return { done: true, value: undefined }; + } + + if (nextAvailable > 0) { + nextAvailable--; + return { done: false, value: value }; + } + + const resolvable = createResolvable(); + nextQueue.push(resolvable); + + await resolvable; + + if (returnCall && nextQueue.length === 0) { + returnCall.resolve(); + } + + if (options.signal?.aborted && !hasThrown) { + hasThrown = true; + throw options.signal.reason; + } + + if (done) { + return { done: true, value: undefined }; + } + + return { done: false, value: value }; + }, + return: async () => { + if (done) { + return { done: true, value: undefined }; + } + + if (nextQueue.length > 0) { + returnCall = createResolvable(); + await returnCall; + } + + clock.clearInterval(handle); + done = true; + + if (options.signal) { + options.signal.removeEventListener( + "abort", + abort, + ); + clock.abortListenerMap.delete(abort); + } + + return { done: true, value: undefined }; + }, + }; + }, + }); + } + } + } + + return clock; + } + + /* eslint-enable complexity */ + + return { + timers: timers, + createClock: createClock, + install: install, + withGlobal: withGlobal, + }; + } + + /** + * @typedef {object} FakeTimers + * @property {Timers} timers + * @property {createClock} createClock + * @property {Function} install + * @property {withGlobal} withGlobal + */ + + /* eslint-enable complexity */ + + /** @type {FakeTimers} */ + const defaultImplementation = withGlobal(globalObject); + + fakeTimersSrc.timers = defaultImplementation.timers; + fakeTimersSrc.createClock = defaultImplementation.createClock; + fakeTimersSrc.install = defaultImplementation.install; + fakeTimersSrc.withGlobal = withGlobal; + return fakeTimersSrc; +} + +var fakeTimersSrcExports = requireFakeTimersSrc(); + +class FakeTimers { + _global; + _clock; + // | _fakingTime | _fakingDate | + // +-------------+-------------+ + // | false | falsy | initial + // | false | truthy | vi.setSystemTime called first (for mocking only Date without fake timers) + // | true | falsy | vi.useFakeTimers called first + // | true | truthy | unreachable + _fakingTime; + _fakingDate; + _fakeTimers; + _userConfig; + _now = RealDate.now; + constructor({ global, config }) { + this._userConfig = config; + this._fakingDate = null; + this._fakingTime = false; + this._fakeTimers = fakeTimersSrcExports.withGlobal(global); + this._global = global; + } + clearAllTimers() { + if (this._fakingTime) this._clock.reset(); + } + dispose() { + this.useRealTimers(); + } + runAllTimers() { + if (this._checkFakeTimers()) this._clock.runAll(); + } + async runAllTimersAsync() { + if (this._checkFakeTimers()) await this._clock.runAllAsync(); + } + runOnlyPendingTimers() { + if (this._checkFakeTimers()) this._clock.runToLast(); + } + async runOnlyPendingTimersAsync() { + if (this._checkFakeTimers()) await this._clock.runToLastAsync(); + } + advanceTimersToNextTimer(steps = 1) { + if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) { + this._clock.next(); + // Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250 + this._clock.tick(0); + if (this._clock.countTimers() === 0) break; + } + } + async advanceTimersToNextTimerAsync(steps = 1) { + if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) { + await this._clock.nextAsync(); + // Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250 + this._clock.tick(0); + if (this._clock.countTimers() === 0) break; + } + } + advanceTimersByTime(msToRun) { + if (this._checkFakeTimers()) this._clock.tick(msToRun); + } + async advanceTimersByTimeAsync(msToRun) { + if (this._checkFakeTimers()) await this._clock.tickAsync(msToRun); + } + advanceTimersToNextFrame() { + if (this._checkFakeTimers()) this._clock.runToFrame(); + } + runAllTicks() { + if (this._checkFakeTimers()) + // @ts-expect-error method not exposed + this._clock.runMicrotasks(); + } + useRealTimers() { + if (this._fakingDate) { + resetDate(); + this._fakingDate = null; + } + if (this._fakingTime) { + this._clock.uninstall(); + this._fakingTime = false; + } + } + useFakeTimers() { + if (this._fakingDate) throw new Error("\"setSystemTime\" was called already and date was mocked. Reset timers using `vi.useRealTimers()` if you want to use fake timers again."); + if (!this._fakingTime) { + const toFake = Object.keys(this._fakeTimers.timers).filter((timer) => timer !== "nextTick" && timer !== "queueMicrotask"); + if (this._userConfig?.toFake?.includes("nextTick") && isChildProcess()) throw new Error("process.nextTick cannot be mocked inside child_process"); + this._clock = this._fakeTimers.install({ + now: Date.now(), + ...this._userConfig, + toFake: this._userConfig?.toFake || toFake, + ignoreMissingTimers: true + }); + this._fakingTime = true; + } + } + reset() { + if (this._checkFakeTimers()) { + const { now } = this._clock; + this._clock.reset(); + this._clock.setSystemTime(now); + } + } + setSystemTime(now) { + const date = typeof now === "undefined" || now instanceof Date ? now : new Date(now); + if (this._fakingTime) this._clock.setSystemTime(date); + else { + this._fakingDate = date ?? new Date(this.getRealSystemTime()); + mockDate(this._fakingDate); + } + } + getMockedSystemTime() { + return this._fakingTime ? new Date(this._clock.now) : this._fakingDate; + } + getRealSystemTime() { + return this._now(); + } + getTimerCount() { + if (this._checkFakeTimers()) return this._clock.countTimers(); + return 0; + } + configure(config) { + this._userConfig = config; + } + isFakeTimers() { + return this._fakingTime; + } + _checkFakeTimers() { + if (!this._fakingTime) throw new Error("Timers are not mocked. Try calling \"vi.useFakeTimers()\" first."); + return this._fakingTime; + } +} + +function copyStackTrace(target, source) { + if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message); + return target; +} +function waitFor(callback, options = {}) { + const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers(); + const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options; + const STACK_TRACE_ERROR = new Error("STACK_TRACE_ERROR"); + return new Promise((resolve, reject) => { + let lastError; + let promiseStatus = "idle"; + let timeoutId; + let intervalId; + const onResolve = (result) => { + if (timeoutId) clearTimeout(timeoutId); + if (intervalId) clearInterval(intervalId); + resolve(result); + }; + const handleTimeout = () => { + if (intervalId) clearInterval(intervalId); + let error = lastError; + if (!error) error = copyStackTrace(new Error("Timed out in waitFor!"), STACK_TRACE_ERROR); + reject(error); + }; + const checkCallback = () => { + if (vi.isFakeTimers()) vi.advanceTimersByTime(interval); + if (promiseStatus === "pending") return; + try { + const result = callback(); + if (result !== null && typeof result === "object" && typeof result.then === "function") { + const thenable = result; + promiseStatus = "pending"; + thenable.then((resolvedValue) => { + promiseStatus = "resolved"; + onResolve(resolvedValue); + }, (rejectedValue) => { + promiseStatus = "rejected"; + lastError = rejectedValue; + }); + } else { + onResolve(result); + return true; + } + } catch (error) { + lastError = error; + } + }; + if (checkCallback() === true) return; + timeoutId = setTimeout(handleTimeout, timeout); + intervalId = setInterval(checkCallback, interval); + }); +} +function waitUntil(callback, options = {}) { + const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers(); + const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options; + const STACK_TRACE_ERROR = new Error("STACK_TRACE_ERROR"); + return new Promise((resolve, reject) => { + let promiseStatus = "idle"; + let timeoutId; + let intervalId; + const onReject = (error) => { + if (intervalId) clearInterval(intervalId); + if (!error) error = copyStackTrace(new Error("Timed out in waitUntil!"), STACK_TRACE_ERROR); + reject(error); + }; + const onResolve = (result) => { + if (!result) return; + if (timeoutId) clearTimeout(timeoutId); + if (intervalId) clearInterval(intervalId); + resolve(result); + return true; + }; + const checkCallback = () => { + if (vi.isFakeTimers()) vi.advanceTimersByTime(interval); + if (promiseStatus === "pending") return; + try { + const result = callback(); + if (result !== null && typeof result === "object" && typeof result.then === "function") { + const thenable = result; + promiseStatus = "pending"; + thenable.then((resolvedValue) => { + promiseStatus = "resolved"; + onResolve(resolvedValue); + }, (rejectedValue) => { + promiseStatus = "rejected"; + onReject(rejectedValue); + }); + } else return onResolve(result); + } catch (error) { + onReject(error); + } + }; + if (checkCallback() === true) return; + timeoutId = setTimeout(onReject, timeout); + intervalId = setInterval(checkCallback, interval); + }); +} + +function createVitest() { + let _config = null; + const workerState = getWorkerState(); + let _timers; + const timers = () => _timers ||= new FakeTimers({ + global: globalThis, + config: workerState.config.fakeTimers + }); + const _stubsGlobal = /* @__PURE__ */ new Map(); + const _stubsEnv = /* @__PURE__ */ new Map(); + const _envBooleans = [ + "PROD", + "DEV", + "SSR" + ]; + const utils = { + useFakeTimers(config) { + if (isChildProcess()) { + if (config?.toFake?.includes("nextTick") || workerState.config?.fakeTimers?.toFake?.includes("nextTick")) throw new Error("vi.useFakeTimers({ toFake: [\"nextTick\"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required."); + } + if (config) timers().configure({ + ...workerState.config.fakeTimers, + ...config + }); + else timers().configure(workerState.config.fakeTimers); + timers().useFakeTimers(); + return utils; + }, + isFakeTimers() { + return timers().isFakeTimers(); + }, + useRealTimers() { + timers().useRealTimers(); + return utils; + }, + runOnlyPendingTimers() { + timers().runOnlyPendingTimers(); + return utils; + }, + async runOnlyPendingTimersAsync() { + await timers().runOnlyPendingTimersAsync(); + return utils; + }, + runAllTimers() { + timers().runAllTimers(); + return utils; + }, + async runAllTimersAsync() { + await timers().runAllTimersAsync(); + return utils; + }, + runAllTicks() { + timers().runAllTicks(); + return utils; + }, + advanceTimersByTime(ms) { + timers().advanceTimersByTime(ms); + return utils; + }, + async advanceTimersByTimeAsync(ms) { + await timers().advanceTimersByTimeAsync(ms); + return utils; + }, + advanceTimersToNextTimer() { + timers().advanceTimersToNextTimer(); + return utils; + }, + async advanceTimersToNextTimerAsync() { + await timers().advanceTimersToNextTimerAsync(); + return utils; + }, + advanceTimersToNextFrame() { + timers().advanceTimersToNextFrame(); + return utils; + }, + getTimerCount() { + return timers().getTimerCount(); + }, + setSystemTime(time) { + timers().setSystemTime(time); + return utils; + }, + getMockedSystemTime() { + return timers().getMockedSystemTime(); + }, + getRealSystemTime() { + return timers().getRealSystemTime(); + }, + clearAllTimers() { + timers().clearAllTimers(); + return utils; + }, + spyOn, + fn, + waitFor, + waitUntil, + hoisted(factory) { + assertTypes(factory, "\"vi.hoisted\" factory", ["function"]); + return factory(); + }, + mock(path, factory) { + if (typeof path !== "string") throw new TypeError(`vi.mock() expects a string path, but received a ${typeof path}`); + const importer = getImporter("mock"); + _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory); + }, + unmock(path) { + if (typeof path !== "string") throw new TypeError(`vi.unmock() expects a string path, but received a ${typeof path}`); + _mocker().queueUnmock(path, getImporter("unmock")); + }, + doMock(path, factory) { + if (typeof path !== "string") throw new TypeError(`vi.doMock() expects a string path, but received a ${typeof path}`); + const importer = getImporter("doMock"); + _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory); + }, + doUnmock(path) { + if (typeof path !== "string") throw new TypeError(`vi.doUnmock() expects a string path, but received a ${typeof path}`); + _mocker().queueUnmock(path, getImporter("doUnmock")); + }, + async importActual(path) { + return _mocker().importActual(path, getImporter("importActual"), _mocker().getMockContext().callstack); + }, + async importMock(path) { + return _mocker().importMock(path, getImporter("importMock")); + }, + mockObject(value) { + return _mocker().mockObject({ value }).value; + }, + mocked(item, _options = {}) { + return item; + }, + isMockFunction(fn) { + return isMockFunction(fn); + }, + clearAllMocks() { + [...mocks].reverse().forEach((spy) => spy.mockClear()); + return utils; + }, + resetAllMocks() { + [...mocks].reverse().forEach((spy) => spy.mockReset()); + return utils; + }, + restoreAllMocks() { + [...mocks].reverse().forEach((spy) => spy.mockRestore()); + return utils; + }, + stubGlobal(name, value) { + if (!_stubsGlobal.has(name)) _stubsGlobal.set(name, Object.getOwnPropertyDescriptor(globalThis, name)); + Object.defineProperty(globalThis, name, { + value, + writable: true, + configurable: true, + enumerable: true + }); + return utils; + }, + stubEnv(name, value) { + if (!_stubsEnv.has(name)) _stubsEnv.set(name, process.env[name]); + if (_envBooleans.includes(name)) process.env[name] = value ? "1" : ""; + else if (value === void 0) delete process.env[name]; + else process.env[name] = String(value); + return utils; + }, + unstubAllGlobals() { + _stubsGlobal.forEach((original, name) => { + if (!original) Reflect.deleteProperty(globalThis, name); + else Object.defineProperty(globalThis, name, original); + }); + _stubsGlobal.clear(); + return utils; + }, + unstubAllEnvs() { + _stubsEnv.forEach((original, name) => { + if (original === void 0) delete process.env[name]; + else process.env[name] = original; + }); + _stubsEnv.clear(); + return utils; + }, + resetModules() { + resetModules(workerState.moduleCache); + return utils; + }, + async dynamicImportSettled() { + return waitForImportsToResolve(); + }, + setConfig(config) { + if (!_config) _config = { ...workerState.config }; + Object.assign(workerState.config, config); + }, + resetConfig() { + if (_config) Object.assign(workerState.config, _config); + } + }; + return utils; +} +const vitest = createVitest(); +const vi = vitest; +function _mocker() { + // @ts-expect-error injected by vite-nide + return typeof __vitest_mocker__ !== "undefined" ? __vitest_mocker__ : new Proxy({}, { get(_, name) { + throw new Error(`Vitest mocker was not initialized in this environment. vi.${String(name)}() is forbidden.`); + } }); +} +function getImporter(name) { + const stackTrace = createSimpleStackTrace({ stackTraceLimit: 5 }); + const stackArray = stackTrace.split("\n"); + // if there is no message in a stack trace, use the item - 1 + const importerStackIndex = stackArray.findIndex((stack) => { + return stack.includes(` at Object.${name}`) || stack.includes(`${name}@`); + }); + const stack = parseSingleStack(stackArray[importerStackIndex + 1]); + return stack?.file || ""; +} + +export { globalExpect as a, vitest as b, createExpect as c, getSnapshotClient as g, inject as i, vi as v }; diff --git a/node_modules/vitest/dist/chunks/vite.d.CMLlLIFP.d.ts b/node_modules/vitest/dist/chunks/vite.d.CMLlLIFP.d.ts new file mode 100644 index 0000000000..01b12242c2 --- /dev/null +++ b/node_modules/vitest/dist/chunks/vite.d.CMLlLIFP.d.ts @@ -0,0 +1,25 @@ +import { HookHandler } from 'vite'; +import { V as Vitest, T as TestProject, b as TestProjectConfiguration, I as InlineConfig } from './reporters.d.BFLkQcL6.js'; + +interface VitestPluginContext { + vitest: Vitest; + project: TestProject; + injectTestProjects: (config: TestProjectConfiguration | TestProjectConfiguration[]) => Promise; +} + +/* eslint-disable unused-imports/no-unused-vars */ + +type VitestInlineConfig = InlineConfig; +declare module "vite" { + interface UserConfig { + /** + * Options for Vitest + */ + test?: VitestInlineConfig; + } + interface Plugin { + configureVitest?: HookHandler<(context: VitestPluginContext) => void>; + } +} + +export type { VitestPluginContext as V }; diff --git a/node_modules/vitest/dist/chunks/vm.BThCzidc.js b/node_modules/vitest/dist/chunks/vm.BThCzidc.js new file mode 100644 index 0000000000..6a6e496b2c --- /dev/null +++ b/node_modules/vitest/dist/chunks/vm.BThCzidc.js @@ -0,0 +1,756 @@ +import { fileURLToPath, pathToFileURL } from 'node:url'; +import vm, { isContext } from 'node:vm'; +import { dirname, basename, extname, normalize, join, resolve } from 'pathe'; +import { distDir } from '../path.js'; +import { createCustomConsole } from './console.CtFJOzRO.js'; +import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.B7h3T_Hc.js'; +import fs from 'node:fs'; +import { dirname as dirname$1 } from 'node:path'; +import { isPrimitive, isNodeBuiltin, toArray, getCachedData, setCacheData, isBareImport } from 'vite-node/utils'; +import { createRequire, Module } from 'node:module'; +import { CSS_LANGS_RE, KNOWN_ASSET_RE } from 'vite-node/constants'; +import { p as provideWorkerState } from './utils.XdZDrNZV.js'; + +function interopCommonJsModule(interopDefault, mod) { + if (isPrimitive(mod) || Array.isArray(mod) || mod instanceof Promise) return { + keys: [], + moduleExports: {}, + defaultExport: mod + }; + if (interopDefault !== false && "__esModule" in mod && !isPrimitive(mod.default)) { + const defaultKets = Object.keys(mod.default); + const moduleKeys = Object.keys(mod); + const allKeys = new Set([...defaultKets, ...moduleKeys]); + allKeys.delete("default"); + return { + keys: Array.from(allKeys), + moduleExports: new Proxy(mod, { get(mod, prop) { + return mod[prop] ?? mod.default?.[prop]; + } }), + defaultExport: mod + }; + } + return { + keys: Object.keys(mod).filter((key) => key !== "default"), + moduleExports: mod, + defaultExport: mod + }; +} +const SyntheticModule = vm.SyntheticModule; +const SourceTextModule = vm.SourceTextModule; + +const _require = createRequire(import.meta.url); +const requiresCache = /* @__PURE__ */ new WeakMap(); +class CommonjsExecutor { + context; + requireCache = /* @__PURE__ */ new Map(); + publicRequireCache = this.createProxyCache(); + moduleCache = /* @__PURE__ */ new Map(); + builtinCache = Object.create(null); + extensions = Object.create(null); + fs; + Module; + interopDefault; + constructor(options) { + this.context = options.context; + this.fs = options.fileMap; + this.interopDefault = options.interopDefault; + const primitives = vm.runInContext("({ Object, Array, Error })", this.context); + // eslint-disable-next-line ts/no-this-alias + const executor = this; + this.Module = class Module$1 { + exports; + isPreloading = false; + id; + filename; + loaded; + parent; + children = []; + path; + paths = []; + constructor(id = "", parent) { + this.exports = primitives.Object.create(Object.prototype); + // in our case the path should always be resolved already + this.path = dirname(id); + this.id = id; + this.filename = id; + this.loaded = false; + this.parent = parent; + } + get require() { + const require = requiresCache.get(this); + if (require) return require; + const _require = Module$1.createRequire(this.id); + requiresCache.set(this, _require); + return _require; + } + static register = () => { + throw new Error(`[vitest] "register" is not available when running in Vitest.`); + }; + static registerHooks = () => { + throw new Error(`[vitest] "registerHooks" is not available when running in Vitest.`); + }; + _compile(code, filename) { + const cjsModule = Module$1.wrap(code); + const script = new vm.Script(cjsModule, { + filename, + importModuleDynamically: options.importModuleDynamically + }); + // @ts-expect-error mark script with current identifier + script.identifier = filename; + const fn = script.runInContext(executor.context); + const __dirname = dirname(filename); + executor.requireCache.set(filename, this); + try { + fn(this.exports, this.require, this, filename, __dirname); + return this.exports; + } finally { + this.loaded = true; + } + } + // exposed for external use, Node.js does the opposite + static _load = (request, parent, _isMain) => { + const require = Module$1.createRequire(parent?.filename ?? request); + return require(request); + }; + static wrap = (script) => { + return Module$1.wrapper[0] + script + Module$1.wrapper[1]; + }; + static wrapper = new primitives.Array("(function (exports, require, module, __filename, __dirname) { ", "\n});"); + static builtinModules = Module.builtinModules; + static findSourceMap = Module.findSourceMap; + static SourceMap = Module.SourceMap; + static syncBuiltinESMExports = Module.syncBuiltinESMExports; + static _cache = executor.publicRequireCache; + static _extensions = executor.extensions; + static createRequire = (filename) => { + return executor.createRequire(filename); + }; + static runMain = () => { + throw new primitives.Error("[vitest] \"runMain\" is not implemented."); + }; + // @ts-expect-error not typed + static _resolveFilename = Module._resolveFilename; + // @ts-expect-error not typed + static _findPath = Module._findPath; + // @ts-expect-error not typed + static _initPaths = Module._initPaths; + // @ts-expect-error not typed + static _preloadModules = Module._preloadModules; + // @ts-expect-error not typed + static _resolveLookupPaths = Module._resolveLookupPaths; + // @ts-expect-error not typed + static globalPaths = Module.globalPaths; + static isBuiltin = Module.isBuiltin; + static constants = Module.constants; + static enableCompileCache = Module.enableCompileCache; + static getCompileCacheDir = Module.getCompileCacheDir; + static flushCompileCache = Module.flushCompileCache; + static stripTypeScriptTypes = Module.stripTypeScriptTypes; + static findPackageJSON = Module.findPackageJSON; + static Module = Module$1; + }; + this.extensions[".js"] = this.requireJs; + this.extensions[".json"] = this.requireJson; + } + requireJs = (m, filename) => { + const content = this.fs.readFile(filename); + m._compile(content, filename); + }; + requireJson = (m, filename) => { + const code = this.fs.readFile(filename); + m.exports = JSON.parse(code); + }; + createRequire = (filename) => { + const _require = createRequire(filename); + const require = (id) => { + const resolved = _require.resolve(id); + const ext = extname(resolved); + if (ext === ".node" || isNodeBuiltin(resolved)) return this.requireCoreModule(resolved); + const module = new this.Module(resolved); + return this.loadCommonJSModule(module, resolved); + }; + require.resolve = _require.resolve; + Object.defineProperty(require, "extensions", { + get: () => this.extensions, + set: () => {}, + configurable: true + }); + require.main = void 0; + require.cache = this.publicRequireCache; + return require; + }; + createProxyCache() { + return new Proxy(Object.create(null), { + defineProperty: () => true, + deleteProperty: () => true, + set: () => true, + get: (_, key) => this.requireCache.get(key), + has: (_, key) => this.requireCache.has(key), + ownKeys: () => Array.from(this.requireCache.keys()), + getOwnPropertyDescriptor() { + return { + configurable: true, + enumerable: true + }; + } + }); + } + // very naive implementation for Node.js require + loadCommonJSModule(module, filename) { + const cached = this.requireCache.get(filename); + if (cached) return cached.exports; + const extension = this.findLongestRegisteredExtension(filename); + const loader = this.extensions[extension] || this.extensions[".js"]; + loader(module, filename); + return module.exports; + } + findLongestRegisteredExtension(filename) { + const name = basename(filename); + let currentExtension; + let index; + let startIndex = 0; + // eslint-disable-next-line no-cond-assign + while ((index = name.indexOf(".", startIndex)) !== -1) { + startIndex = index + 1; + if (index === 0) continue; + currentExtension = name.slice(index); + if (this.extensions[currentExtension]) return currentExtension; + } + return ".js"; + } + getCoreSyntheticModule(identifier) { + if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier); + const exports = this.require(identifier); + const keys = Object.keys(exports); + const module = new SyntheticModule([...keys, "default"], () => { + for (const key of keys) module.setExport(key, exports[key]); + module.setExport("default", exports); + }, { + context: this.context, + identifier + }); + this.moduleCache.set(identifier, module); + return module; + } + getCjsSyntheticModule(path, identifier) { + if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier); + const exports = this.require(path); + // TODO: technically module should be parsed to find static exports, implement for strict mode in #2854 + const { keys, moduleExports, defaultExport } = interopCommonJsModule(this.interopDefault, exports); + const module = new SyntheticModule([...keys, "default"], function() { + for (const key of keys) this.setExport(key, moduleExports[key]); + this.setExport("default", defaultExport); + }, { + context: this.context, + identifier + }); + this.moduleCache.set(identifier, module); + return module; + } + // TODO: use this in strict mode, when available in #2854 + // private _getNamedCjsExports(path: string): Set { + // const cachedNamedExports = this.cjsNamedExportsMap.get(path) + // if (cachedNamedExports) { + // return cachedNamedExports + // } + // if (extname(path) === '.node') { + // const moduleExports = this.require(path) + // const namedExports = new Set(Object.keys(moduleExports)) + // this.cjsNamedExportsMap.set(path, namedExports) + // return namedExports + // } + // const code = this.fs.readFile(path) + // const { exports, reexports } = parseCjs(code, path) + // const namedExports = new Set(exports) + // this.cjsNamedExportsMap.set(path, namedExports) + // for (const reexport of reexports) { + // if (isNodeBuiltin(reexport)) { + // const exports = this.require(reexport) + // if (exports !== null && typeof exports === 'object') { + // for (const e of Object.keys(exports)) { + // namedExports.add(e) + // } + // } + // } + // else { + // const require = this.createRequire(path) + // const resolved = require.resolve(reexport) + // const exports = this._getNamedCjsExports(resolved) + // for (const e of exports) { + // namedExports.add(e) + // } + // } + // } + // return namedExports + // } + require(identifier) { + const ext = extname(identifier); + if (ext === ".node" || isNodeBuiltin(identifier)) return this.requireCoreModule(identifier); + const module = new this.Module(identifier); + return this.loadCommonJSModule(module, identifier); + } + requireCoreModule(identifier) { + const normalized = identifier.replace(/^node:/, ""); + if (this.builtinCache[normalized]) return this.builtinCache[normalized].exports; + const moduleExports = _require(identifier); + if (identifier === "node:module" || identifier === "module") { + const module = new this.Module("/module.js"); + module.exports = this.Module; + this.builtinCache[normalized] = module; + return module.exports; + } + this.builtinCache[normalized] = _require.cache[normalized]; + // TODO: should we wrap module to rethrow context errors? + return moduleExports; + } +} + +const dataURIRegex = /^data:(?text\/javascript|application\/json|application\/wasm)(?:;(?charset=utf-8|base64))?,(?.*)$/; +class EsmExecutor { + moduleCache = /* @__PURE__ */ new Map(); + esmLinkMap = /* @__PURE__ */ new WeakMap(); + context; + #httpIp = IPnumber("127.0.0.0"); + constructor(executor, options) { + this.executor = executor; + this.context = options.context; + } + async evaluateModule(m) { + if (m.status === "unlinked") this.esmLinkMap.set(m, m.link((identifier, referencer) => this.executor.resolveModule(identifier, referencer.identifier))); + await this.esmLinkMap.get(m); + if (m.status === "linked") await m.evaluate(); + return m; + } + async createEsModule(fileURL, getCode) { + const cached = this.moduleCache.get(fileURL); + if (cached) return cached; + const promise = this.loadEsModule(fileURL, getCode); + this.moduleCache.set(fileURL, promise); + return promise; + } + async loadEsModule(fileURL, getCode) { + const code = await getCode(); + // TODO: should not be allowed in strict mode, implement in #2854 + if (fileURL.endsWith(".json")) { + const m = new SyntheticModule(["default"], function() { + const result = JSON.parse(code); + this.setExport("default", result); + }); + this.moduleCache.set(fileURL, m); + return m; + } + const m = new SourceTextModule(code, { + identifier: fileURL, + context: this.context, + importModuleDynamically: this.executor.importModuleDynamically, + initializeImportMeta: (meta, mod) => { + meta.url = mod.identifier; + if (mod.identifier.startsWith("file:")) { + const filename = fileURLToPath(mod.identifier); + meta.filename = filename; + meta.dirname = dirname$1(filename); + } + meta.resolve = (specifier, importer) => { + return this.executor.resolve(specifier, importer != null ? importer.toString() : mod.identifier); + }; + } + }); + this.moduleCache.set(fileURL, m); + return m; + } + async createWebAssemblyModule(fileUrl, getCode) { + const cached = this.moduleCache.get(fileUrl); + if (cached) return cached; + const m = this.loadWebAssemblyModule(getCode(), fileUrl); + this.moduleCache.set(fileUrl, m); + return m; + } + async createNetworkModule(fileUrl) { + // https://nodejs.org/api/esm.html#https-and-http-imports + if (fileUrl.startsWith("http:")) { + const url = new URL(fileUrl); + if (url.hostname !== "localhost" && url.hostname !== "::1" && (IPnumber(url.hostname) & IPmask(8)) !== this.#httpIp) throw new Error( + // we don't know the importer, so it's undefined (the same happens in --pool=threads) + `import of '${fileUrl}' by undefined is not supported: http can only be used to load local resources (use https instead).` + ); + } + return this.createEsModule(fileUrl, () => fetch(fileUrl).then((r) => r.text())); + } + async loadWebAssemblyModule(source, identifier) { + const cached = this.moduleCache.get(identifier); + if (cached) return cached; + const wasmModule = await WebAssembly.compile(source); + const exports = WebAssembly.Module.exports(wasmModule); + const imports = WebAssembly.Module.imports(wasmModule); + const moduleLookup = {}; + for (const { module } of imports) if (moduleLookup[module] === void 0) moduleLookup[module] = await this.executor.resolveModule(module, identifier); + const evaluateModule = (module) => this.evaluateModule(module); + const syntheticModule = new SyntheticModule(exports.map(({ name }) => name), async function() { + const importsObject = {}; + for (const { module, name } of imports) { + if (!importsObject[module]) importsObject[module] = {}; + await evaluateModule(moduleLookup[module]); + importsObject[module][name] = moduleLookup[module].namespace[name]; + } + const wasmInstance = new WebAssembly.Instance(wasmModule, importsObject); + for (const { name } of exports) this.setExport(name, wasmInstance.exports[name]); + }, { + context: this.context, + identifier + }); + return syntheticModule; + } + cacheModule(identifier, module) { + this.moduleCache.set(identifier, module); + } + resolveCachedModule(identifier) { + return this.moduleCache.get(identifier); + } + async createDataModule(identifier) { + const cached = this.moduleCache.get(identifier); + if (cached) return cached; + const match = identifier.match(dataURIRegex); + if (!match || !match.groups) throw new Error("Invalid data URI"); + const mime = match.groups.mime; + const encoding = match.groups.encoding; + if (mime === "application/wasm") { + if (!encoding) throw new Error("Missing data URI encoding"); + if (encoding !== "base64") throw new Error(`Invalid data URI encoding: ${encoding}`); + const module = this.loadWebAssemblyModule(Buffer.from(match.groups.code, "base64"), identifier); + this.moduleCache.set(identifier, module); + return module; + } + let code = match.groups.code; + if (!encoding || encoding === "charset=utf-8") code = decodeURIComponent(code); + else if (encoding === "base64") code = Buffer.from(code, "base64").toString(); + else throw new Error(`Invalid data URI encoding: ${encoding}`); + if (mime === "application/json") { + const module = new SyntheticModule(["default"], function() { + const obj = JSON.parse(code); + this.setExport("default", obj); + }, { + context: this.context, + identifier + }); + this.moduleCache.set(identifier, module); + return module; + } + return this.createEsModule(identifier, () => code); + } +} +function IPnumber(address) { + const ip = address.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/); + if (ip) return (+ip[1] << 24) + (+ip[2] << 16) + (+ip[3] << 8) + +ip[4]; + throw new Error(`Expected IP address, received ${address}`); +} +function IPmask(maskSize) { + return -1 << 32 - maskSize; +} + +const CLIENT_ID = "/@vite/client"; +const CLIENT_FILE = pathToFileURL(CLIENT_ID).href; +class ViteExecutor { + esm; + constructor(options) { + this.options = options; + this.esm = options.esmExecutor; + } + resolve = (identifier, parent) => { + if (identifier === CLIENT_ID) { + if (this.workerState.environment.transformMode === "web") return identifier; + const packageName = this.getPackageName(parent); + throw new Error(`[vitest] Vitest cannot handle ${CLIENT_ID} imported in ${parent} when running in SSR environment. Add "${packageName}" to "ssr.noExternal" if you are using Vite SSR, or to "server.deps.inline" if you are using Vite Node.`); + } + }; + get workerState() { + return this.options.context.__vitest_worker__; + } + getPackageName(modulePath) { + const path = normalize(modulePath); + let name = path.split("/node_modules/").pop() || ""; + if (name?.startsWith("@")) name = name.split("/").slice(0, 2).join("/"); + else name = name.split("/")[0]; + return name; + } + async createViteModule(fileUrl) { + if (fileUrl === CLIENT_FILE) return this.createViteClientModule(); + const cached = this.esm.resolveCachedModule(fileUrl); + if (cached) return cached; + return this.esm.createEsModule(fileUrl, async () => { + try { + const result = await this.options.transform(fileUrl, "web"); + if (result.code) return result.code; + } catch (cause) { + // rethrow vite error if it cannot load the module because it's not resolved + if (typeof cause === "object" && cause.code === "ERR_LOAD_URL" || typeof cause?.message === "string" && cause.message.includes("Failed to load url")) { + const error = new Error(`Cannot find module '${fileUrl}'`, { cause }); + error.code = "ERR_MODULE_NOT_FOUND"; + throw error; + } + } + throw new Error(`[vitest] Failed to transform ${fileUrl}. Does the file exist?`); + }); + } + createViteClientModule() { + const identifier = CLIENT_ID; + const cached = this.esm.resolveCachedModule(identifier); + if (cached) return cached; + const stub = this.options.viteClientModule; + const moduleKeys = Object.keys(stub); + const module = new SyntheticModule(moduleKeys, function() { + moduleKeys.forEach((key) => { + this.setExport(key, stub[key]); + }); + }, { + context: this.options.context, + identifier + }); + this.esm.cacheModule(identifier, module); + return module; + } + canResolve = (fileUrl) => { + const transformMode = this.workerState.environment.transformMode; + if (transformMode !== "web") return false; + if (fileUrl === CLIENT_FILE) return true; + const config = this.workerState.config.deps?.web || {}; + const [modulePath] = fileUrl.split("?"); + if (config.transformCss && CSS_LANGS_RE.test(modulePath)) return true; + if (config.transformAssets && KNOWN_ASSET_RE.test(modulePath)) return true; + if (toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath))) return true; + return false; + }; +} + +const { existsSync, statSync } = fs; +// always defined when we use vm pool +const nativeResolve = import.meta.resolve; +// TODO: improve Node.js strict mode support in #2854 +class ExternalModulesExecutor { + cjs; + esm; + vite; + context; + fs; + resolvers = []; + #networkSupported = null; + constructor(options) { + this.options = options; + this.context = options.context; + this.fs = options.fileMap; + this.esm = new EsmExecutor(this, { context: this.context }); + this.cjs = new CommonjsExecutor({ + context: this.context, + importModuleDynamically: this.importModuleDynamically, + fileMap: options.fileMap, + interopDefault: options.interopDefault + }); + this.vite = new ViteExecutor({ + esmExecutor: this.esm, + context: this.context, + transform: options.transform, + viteClientModule: options.viteClientModule + }); + this.resolvers = [this.vite.resolve]; + } + async import(identifier) { + const module = await this.createModule(identifier); + await this.esm.evaluateModule(module); + return module.namespace; + } + require(identifier) { + return this.cjs.require(identifier); + } + createRequire(identifier) { + return this.cjs.createRequire(identifier); + } + // dynamic import can be used in both ESM and CJS, so we have it in the executor + importModuleDynamically = async (specifier, referencer) => { + const module = await this.resolveModule(specifier, referencer.identifier); + return await this.esm.evaluateModule(module); + }; + resolveModule = async (specifier, referencer) => { + let identifier = this.resolve(specifier, referencer); + if (identifier instanceof Promise) identifier = await identifier; + return await this.createModule(identifier); + }; + resolve(specifier, parent) { + for (const resolver of this.resolvers) { + const id = resolver(specifier, parent); + if (id) return id; + } + // import.meta.resolve can be asynchronous in older +18 Node versions + return nativeResolve(specifier, parent); + } + findNearestPackageData(basedir) { + const originalBasedir = basedir; + const packageCache = this.options.packageCache; + while (basedir) { + const cached = getCachedData(packageCache, basedir, originalBasedir); + if (cached) return cached; + const pkgPath = join(basedir, "package.json"); + try { + if (statSync(pkgPath, { throwIfNoEntry: false })?.isFile()) { + const pkgData = JSON.parse(this.fs.readFile(pkgPath)); + if (packageCache) setCacheData(packageCache, pkgData, basedir, originalBasedir); + return pkgData; + } + } catch {} + const nextBasedir = dirname$1(basedir); + if (nextBasedir === basedir) break; + basedir = nextBasedir; + } + return {}; + } + getModuleInformation(identifier) { + if (identifier.startsWith("data:")) return { + type: "data", + url: identifier, + path: identifier + }; + const extension = extname(identifier); + if (extension === ".node" || isNodeBuiltin(identifier)) return { + type: "builtin", + url: identifier, + path: identifier + }; + if (this.isNetworkSupported && (identifier.startsWith("http:") || identifier.startsWith("https:"))) return { + type: "network", + url: identifier, + path: identifier + }; + const isFileUrl = identifier.startsWith("file://"); + const pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier; + const fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString(); + let type; + if (this.vite.canResolve(fileUrl)) type = "vite"; + else if (extension === ".mjs") type = "module"; + else if (extension === ".cjs") type = "commonjs"; + else if (extension === ".wasm") + // still experimental on NodeJS --experimental-wasm-modules + // cf. ESM_FILE_FORMAT(url) in https://nodejs.org/docs/latest-v20.x/api/esm.html#resolution-algorithm + type = "wasm"; + else { + const pkgData = this.findNearestPackageData(normalize(pathUrl)); + type = pkgData.type === "module" ? "module" : "commonjs"; + } + return { + type, + path: pathUrl, + url: fileUrl + }; + } + createModule(identifier) { + const { type, url, path } = this.getModuleInformation(identifier); + // create ERR_MODULE_NOT_FOUND on our own since latest NodeJS's import.meta.resolve doesn't throw on non-existing namespace or path + // https://github.com/nodejs/node/pull/49038 + if ((type === "module" || type === "commonjs" || type === "wasm") && !existsSync(path)) { + const error = new Error(`Cannot find ${isBareImport(path) ? "package" : "module"} '${path}'`); + error.code = "ERR_MODULE_NOT_FOUND"; + throw error; + } + switch (type) { + case "data": return this.esm.createDataModule(identifier); + case "builtin": return this.cjs.getCoreSyntheticModule(identifier); + case "vite": return this.vite.createViteModule(url); + case "wasm": return this.esm.createWebAssemblyModule(url, () => this.fs.readBuffer(path)); + case "module": return this.esm.createEsModule(url, () => this.fs.readFileAsync(path)); + case "commonjs": return this.cjs.getCjsSyntheticModule(path, identifier); + case "network": return this.esm.createNetworkModule(url); + default: { + const _deadend = type; + return _deadend; + } + } + } + get isNetworkSupported() { + if (this.#networkSupported == null) if (process.execArgv.includes("--experimental-network-imports")) this.#networkSupported = true; + else if (process.env.NODE_OPTIONS?.includes("--experimental-network-imports")) this.#networkSupported = true; + else this.#networkSupported = false; + return this.#networkSupported; + } +} + +const { promises, readFileSync } = fs; +class FileMap { + fsCache = /* @__PURE__ */ new Map(); + fsBufferCache = /* @__PURE__ */ new Map(); + async readFileAsync(path) { + const cached = this.fsCache.get(path); + if (cached != null) return cached; + const source = await promises.readFile(path, "utf-8"); + this.fsCache.set(path, source); + return source; + } + readFile(path) { + const cached = this.fsCache.get(path); + if (cached != null) return cached; + const source = readFileSync(path, "utf-8"); + this.fsCache.set(path, source); + return source; + } + readBuffer(path) { + const cached = this.fsBufferCache.get(path); + if (cached != null) return cached; + const buffer = readFileSync(path); + this.fsBufferCache.set(path, buffer); + return buffer; + } +} + +const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href; +const fileMap = new FileMap(); +const packageCache = /* @__PURE__ */ new Map(); +async function runVmTests(method, state) { + const { environment, ctx, rpc } = state; + if (!environment.setupVM) { + const envName = ctx.environment.name; + const packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`; + throw new TypeError(`Environment "${ctx.environment.name}" is not a valid environment. Path "${packageId}" doesn't support vm environment because it doesn't provide "setupVM" method.`); + } + const vm = await environment.setupVM(ctx.environment.options || ctx.config.environmentOptions || {}); + state.durations.environment = performance.now() - state.durations.environment; + process.env.VITEST_VM_POOL = "1"; + if (!vm.getVmContext) throw new TypeError(`Environment ${environment.name} doesn't provide "getVmContext" method. It should return a context created by "vm.createContext" method.`); + const context = vm.getVmContext(); + if (!isContext(context)) throw new TypeError(`Environment ${environment.name} doesn't provide a valid context. It should be created by "vm.createContext" method.`); + provideWorkerState(context, state); + // this is unfortunately needed for our own dependencies + // we need to find a way to not rely on this by default + // because browser doesn't provide these globals + context.process = process; + context.global = context; + context.console = state.config.disableConsoleIntercept ? console : createCustomConsole(state); + // TODO: don't hardcode setImmediate in fake timers defaults + context.setImmediate = setImmediate; + context.clearImmediate = clearImmediate; + const stubs = getDefaultRequestStubs(context); + const externalModulesExecutor = new ExternalModulesExecutor({ + context, + fileMap, + packageCache, + transform: rpc.transform, + viteClientModule: stubs["/@vite/client"] + }); + const executor = await startVitestExecutor({ + context, + moduleCache: state.moduleCache, + state, + externalModulesExecutor, + requestStubs: stubs + }); + context.__vitest_mocker__ = executor.mocker; + const { run } = await executor.importExternalModule(entryFile); + const fileSpecs = ctx.files.map((f) => typeof f === "string" ? { + filepath: f, + testLocations: void 0 + } : f); + try { + await run(method, fileSpecs, ctx.config, executor); + } finally { + await vm.teardown?.(); + state.environmentTeardownRun = true; + } +} + +export { runVmTests as r }; diff --git a/node_modules/vitest/dist/chunks/worker.d.1GmBbd7G.d.ts b/node_modules/vitest/dist/chunks/worker.d.1GmBbd7G.d.ts new file mode 100644 index 0000000000..51231abe8e --- /dev/null +++ b/node_modules/vitest/dist/chunks/worker.d.1GmBbd7G.d.ts @@ -0,0 +1,176 @@ +import { File, TestAnnotation, TaskResultPack, TaskEventPack, CancelReason, FileSpecification, Task } from '@vitest/runner'; +import { ViteNodeResolveId, ModuleCacheMap, ModuleExecutionInfo } from 'vite-node'; +import { a as SerializedConfig } from './config.d.D2ROskhv.js'; +import { T as TransformMode, U as UserConsoleLog, A as AfterSuiteRunMeta, E as Environment } from './environment.d.cL3nLXbE.js'; +import { SnapshotResult } from '@vitest/snapshot'; + +type ArgumentsType = T extends (...args: infer A) => any ? A : never; +type ReturnType = T extends (...args: any) => infer R ? R : never; +type PromisifyFn = ReturnType extends Promise ? T : (...args: ArgumentsType) => Promise>>; +type BirpcResolver = (name: string, resolved: (...args: unknown[]) => unknown) => ((...args: unknown[]) => unknown) | undefined; +interface ChannelOptions { + /** + * Function to post raw message + */ + post: (data: any, ...extras: any[]) => any | Promise; + /** + * Listener to receive raw message + */ + on: (fn: (data: any, ...extras: any[]) => void) => any | Promise; + /** + * Clear the listener when `$close` is called + */ + off?: (fn: (data: any, ...extras: any[]) => void) => any | Promise; + /** + * Custom function to serialize data + * + * by default it passes the data as-is + */ + serialize?: (data: any) => any; + /** + * Custom function to deserialize data + * + * by default it passes the data as-is + */ + deserialize?: (data: any) => any; + /** + * Call the methods with the RPC context or the original functions object + */ + bind?: 'rpc' | 'functions'; +} +interface EventOptions { + /** + * Names of remote functions that do not need response. + */ + eventNames?: (keyof Remote)[]; + /** + * Maximum timeout for waiting for response, in milliseconds. + * + * @default 60_000 + */ + timeout?: number; + /** + * Custom resolver to resolve function to be called + * + * For advanced use cases only + */ + resolver?: BirpcResolver; + /** + * Custom error handler + * + * @deprecated use `onFunctionError` and `onGeneralError` instead + */ + onError?: (error: Error, functionName: string, args: any[]) => boolean | void; + /** + * Custom error handler for errors occurred in local functions being called + * + * @returns `true` to prevent the error from being thrown + */ + onFunctionError?: (error: Error, functionName: string, args: any[]) => boolean | void; + /** + * Custom error handler for errors occurred during serialization or messsaging + * + * @returns `true` to prevent the error from being thrown + */ + onGeneralError?: (error: Error, functionName?: string, args?: any[]) => boolean | void; + /** + * Custom error handler for timeouts + * + * @returns `true` to prevent the error from being thrown + */ + onTimeoutError?: (functionName: string, args: any[]) => boolean | void; +} +type BirpcOptions = EventOptions & ChannelOptions; +type BirpcFn = PromisifyFn & { + /** + * Send event without asking for response + */ + asEvent: (...args: ArgumentsType) => void; +}; +type BirpcReturn> = { + [K in keyof RemoteFunctions]: BirpcFn; +} & { + $functions: LocalFunctions; + $close: (error?: Error) => void; + $closed: boolean; +}; + +interface RuntimeRPC { + fetch: (id: string, transformMode: TransformMode) => Promise<{ + externalize?: string + id?: string + }>; + transform: (id: string, transformMode: TransformMode) => Promise<{ + code?: string + }>; + resolveId: (id: string, importer: string | undefined, transformMode: TransformMode) => Promise<{ + external?: boolean | "absolute" | "relative" + id: string + /** @deprecated */ + meta?: Record | null + /** @deprecated */ + moduleSideEffects?: boolean | "no-treeshake" | null + /** @deprecated */ + syntheticNamedExports?: boolean | string | null + } | null>; + /** + * @deprecated unused + */ + getSourceMap: (id: string, force?: boolean) => Promise; + onUserConsoleLog: (log: UserConsoleLog) => void; + onUnhandledError: (err: unknown, type: string) => void; + onQueued: (file: File) => void; + onCollected: (files: File[]) => Promise; + onAfterSuiteRun: (meta: AfterSuiteRunMeta) => void; + onTaskAnnotate: (testId: string, annotation: TestAnnotation) => Promise; + onTaskUpdate: (pack: TaskResultPack[], events: TaskEventPack[]) => Promise; + onCancel: (reason: CancelReason) => void; + getCountOfFailedTests: () => number; + snapshotSaved: (snapshot: SnapshotResult) => void; + resolveSnapshotPath: (testPath: string) => string; +} +interface RunnerRPC { + onCancel: (reason: CancelReason) => void; +} + +/** @deprecated unused */ +type ResolveIdFunction = (id: string, importer?: string) => Promise; +type WorkerRPC = BirpcReturn; +interface ContextTestEnvironment { + name: string; + transformMode?: TransformMode; + options: Record | null; +} +type TestExecutionMethod = "run" | "collect"; +interface ContextRPC { + pool: string; + worker: string; + workerId: number; + config: SerializedConfig; + projectName: string; + files: string[] | FileSpecification[]; + environment: ContextTestEnvironment; + providedContext: Record; + invalidates?: string[]; +} +interface WorkerGlobalState { + ctx: ContextRPC; + config: SerializedConfig; + rpc: WorkerRPC; + current?: Task; + filepath?: string; + environment: Environment; + environmentTeardownRun?: boolean; + onCancel: Promise; + moduleCache: ModuleCacheMap; + moduleExecutionInfo?: ModuleExecutionInfo; + onCleanup: (listener: () => unknown) => void; + providedContext: Record; + durations: { + environment: number + prepare: number + }; + onFilterStackTrace?: (trace: string) => string; +} + +export type { BirpcOptions as B, ContextRPC as C, RuntimeRPC as R, TestExecutionMethod as T, WorkerGlobalState as W, BirpcReturn as a, WorkerRPC as b, RunnerRPC as c, ContextTestEnvironment as d, ResolveIdFunction as e }; diff --git a/node_modules/vitest/dist/chunks/worker.d.CKwWzBSj.d.ts b/node_modules/vitest/dist/chunks/worker.d.CKwWzBSj.d.ts new file mode 100644 index 0000000000..213ab3a6b0 --- /dev/null +++ b/node_modules/vitest/dist/chunks/worker.d.CKwWzBSj.d.ts @@ -0,0 +1,8 @@ +import { MessagePort } from 'node:worker_threads'; +import { C as ContextRPC } from './worker.d.1GmBbd7G.js'; + +interface WorkerContext extends ContextRPC { + port: MessagePort; +} + +export type { WorkerContext as W }; diff --git a/node_modules/vitest/dist/cli.js b/node_modules/vitest/dist/cli.js new file mode 100644 index 0000000000..fa7d5ac2dc --- /dev/null +++ b/node_modules/vitest/dist/cli.js @@ -0,0 +1,27 @@ +import { c as createCLI } from './chunks/cac.Cb-PYCCB.js'; +import '@vitest/utils'; +import 'events'; +import 'pathe'; +import 'tinyrainbow'; +import './chunks/constants.DnKduX2e.js'; +import './chunks/index.VByaPkjc.js'; +import 'node:perf_hooks'; +import '@vitest/runner/utils'; +import '@vitest/utils/source-map'; +import './chunks/env.D4Lgay0q.js'; +import 'std-env'; +import './chunks/typechecker.DRKU1-1g.js'; +import 'node:os'; +import 'tinyexec'; +import './path.js'; +import 'node:path'; +import 'node:url'; +import 'vite'; +import 'node:util'; +import 'node:fs'; +import 'node:fs/promises'; +import 'node:console'; +import 'node:stream'; +import 'node:module'; + +createCLI().parse(); diff --git a/node_modules/vitest/dist/config.cjs b/node_modules/vitest/dist/config.cjs new file mode 100644 index 0000000000..4b21e23b38 --- /dev/null +++ b/node_modules/vitest/dist/config.cjs @@ -0,0 +1,148 @@ +'use strict'; + +var os = require('node:os'); +var stdEnv = require('std-env'); +var vite = require('vite'); + +// if changed, update also jsdocs and docs +const defaultBrowserPort = 63315; +const extraInlineDeps = [ + /^(?!.*node_modules).*\.mjs$/, + /^(?!.*node_modules).*\.cjs\.js$/, + /vite\w*\/dist\/client\/env.mjs/ +]; + +const isNode = typeof process < "u" && typeof process.stdout < "u" && !process.versions?.deno && !globalThis.window; +const isDeno = typeof process < "u" && typeof process.stdout < "u" && process.versions?.deno !== void 0; +(isNode || isDeno) && process.platform === "win32"; +(isNode || isDeno) && process.stdout?.isTTY && !stdEnv.isCI; + +const defaultInclude = ["**/*.{test,spec}.?(c|m)[jt]s?(x)"]; +const defaultExclude = [ + "**/node_modules/**", + "**/dist/**", + "**/cypress/**", + "**/.{idea,git,cache,output,temp}/**", + "**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*" +]; +const defaultCoverageExcludes = [ + "coverage/**", + "dist/**", + "**/node_modules/**", + "**/[.]**", + "packages/*/test?(s)/**", + "**/*.d.ts", + "**/virtual:*", + "**/__x00__*", + "**/\0*", + "cypress/**", + "test?(s)/**", + "test?(-*).?(c|m)[jt]s?(x)", + "**/*{.,-}{test,spec,bench,benchmark}?(-d).?(c|m)[jt]s?(x)", + "**/__tests__/**", + "**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*", + "**/vitest.{workspace,projects}.[jt]s?(on)", + "**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}" +]; +// These are the generic defaults for coverage. Providers may also set some provider specific defaults. +const coverageConfigDefaults = { + provider: "v8", + enabled: false, + all: true, + clean: true, + cleanOnRerun: true, + reportsDirectory: "./coverage", + exclude: defaultCoverageExcludes, + reportOnFailure: false, + reporter: [ + ["text", {}], + ["html", {}], + ["clover", {}], + ["json", {}] + ], + extension: [ + ".js", + ".cjs", + ".mjs", + ".ts", + ".mts", + ".tsx", + ".jsx", + ".vue", + ".svelte", + ".marko", + ".astro" + ], + allowExternal: false, + excludeAfterRemap: false, + ignoreEmptyLines: true, + processingConcurrency: Math.min(20, os.availableParallelism?.() ?? os.cpus().length) +}; +const fakeTimersDefaults = { + loopLimit: 1e4, + shouldClearNativeTimers: true +}; +const configDefaults = Object.freeze({ + allowOnly: !stdEnv.isCI, + isolate: true, + watch: !stdEnv.isCI && process.stdin.isTTY, + globals: false, + environment: "node", + pool: "forks", + clearMocks: false, + restoreMocks: false, + mockReset: false, + unstubGlobals: false, + unstubEnvs: false, + include: defaultInclude, + exclude: defaultExclude, + teardownTimeout: 1e4, + forceRerunTriggers: ["**/package.json/**", "**/{vitest,vite}.config.*/**"], + update: false, + reporters: [], + silent: false, + hideSkippedTests: false, + api: false, + ui: false, + uiBase: "/__vitest__/", + open: !stdEnv.isCI, + css: { include: [] }, + coverage: coverageConfigDefaults, + fakeTimers: fakeTimersDefaults, + maxConcurrency: 5, + dangerouslyIgnoreUnhandledErrors: false, + typecheck: { + checker: "tsc", + include: ["**/*.{test,spec}-d.?(c|m)[jt]s?(x)"], + exclude: defaultExclude + }, + slowTestThreshold: 300, + disableConsoleIntercept: false +}); + +function defineConfig(config) { + return config; +} +function defineProject(config) { + return config; +} +/** +* @deprecated use the `projects` field in the root config instead +*/ +function defineWorkspace(config) { + return config; +} + +Object.defineProperty(exports, "mergeConfig", { + enumerable: true, + get: function () { return vite.mergeConfig; } +}); +exports.configDefaults = configDefaults; +exports.coverageConfigDefaults = coverageConfigDefaults; +exports.defaultBrowserPort = defaultBrowserPort; +exports.defaultExclude = defaultExclude; +exports.defaultInclude = defaultInclude; +exports.defineConfig = defineConfig; +exports.defineProject = defineProject; +exports.defineWorkspace = defineWorkspace; +exports.extraInlineDeps = extraInlineDeps; diff --git a/node_modules/vitest/dist/config.d.ts b/node_modules/vitest/dist/config.d.ts new file mode 100644 index 0000000000..0376d4c601 --- /dev/null +++ b/node_modules/vitest/dist/config.d.ts @@ -0,0 +1,100 @@ +import { UserConfig as UserConfig$1, ConfigEnv } from 'vite'; +export { ConfigEnv, Plugin, UserConfig as ViteUserConfig, mergeConfig } from 'vite'; +import { c as CoverageV8Options, R as ResolvedCoverageOptions, U as UserWorkspaceConfig, d as UserProjectConfigFn, e as UserProjectConfigExport, b as TestProjectConfiguration } from './chunks/reporters.d.BFLkQcL6.js'; +export { f as TestProjectInlineConfiguration, g as WatcherTriggerPattern, W as WorkspaceProjectConfiguration } from './chunks/reporters.d.BFLkQcL6.js'; +import './chunks/vite.d.CMLlLIFP.js'; +import { F as FakeTimerInstallOpts } from './chunks/config.d.D2ROskhv.js'; +import '@vitest/runner'; +import './chunks/environment.d.cL3nLXbE.js'; +import 'vitest/optional-types.js'; +import '@vitest/utils'; +import 'node:stream'; +import 'node:console'; +import '@vitest/mocker'; +import '@vitest/utils/source-map'; +import './chunks/worker.d.1GmBbd7G.js'; +import 'vite-node'; +import '@vitest/snapshot'; +import '@vitest/pretty-format'; +import '@vitest/utils/diff'; +import 'chai'; +import './chunks/benchmark.d.BwvBVTda.js'; +import '@vitest/runner/utils'; +import 'tinybench'; +import './chunks/coverage.d.S9RMNXIe.js'; +import 'vite-node/client'; +import '@vitest/snapshot/manager'; +import 'node:fs'; +import '@vitest/snapshot/environment'; + +declare const defaultBrowserPort = 63315; +declare const extraInlineDeps: RegExp[]; + +declare const defaultInclude: string[]; +declare const defaultExclude: string[]; +// These are the generic defaults for coverage. Providers may also set some provider specific defaults. +declare const coverageConfigDefaults: ResolvedCoverageOptions; +declare const configDefaults: Readonly<{ + allowOnly: boolean + isolate: boolean + watch: boolean + globals: boolean + environment: "node" + pool: "forks" + clearMocks: boolean + restoreMocks: boolean + mockReset: boolean + unstubGlobals: boolean + unstubEnvs: boolean + include: string[] + exclude: string[] + teardownTimeout: number + forceRerunTriggers: string[] + update: boolean + reporters: never[] + silent: boolean + hideSkippedTests: boolean + api: boolean + ui: boolean + uiBase: string + open: boolean + css: { + include: never[] + } + coverage: CoverageV8Options + fakeTimers: FakeTimerInstallOpts + maxConcurrency: number + dangerouslyIgnoreUnhandledErrors: boolean + typecheck: { + checker: "tsc" + include: string[] + exclude: string[] + } + slowTestThreshold: number + disableConsoleIntercept: boolean +}>; + +/** +* @deprecated Use `ViteUserConfig` instead +*/ +type UserConfig = UserConfig$1; + +type UserConfigFnObject = (env: ConfigEnv) => UserConfig$1; +type UserConfigFnPromise = (env: ConfigEnv) => Promise; +type UserConfigFn = (env: ConfigEnv) => UserConfig$1 | Promise; +type UserConfigExport = UserConfig$1 | Promise | UserConfigFnObject | UserConfigFnPromise | UserConfigFn; +declare function defineConfig(config: UserConfig$1): UserConfig$1; +declare function defineConfig(config: Promise): Promise; +declare function defineConfig(config: UserConfigFnObject): UserConfigFnObject; +declare function defineConfig(config: UserConfigExport): UserConfigExport; +declare function defineProject(config: UserWorkspaceConfig): UserWorkspaceConfig; +declare function defineProject(config: Promise): Promise; +declare function defineProject(config: UserProjectConfigFn): UserProjectConfigFn; +declare function defineProject(config: UserProjectConfigExport): UserProjectConfigExport; +/** +* @deprecated use the `projects` field in the root config instead +*/ +declare function defineWorkspace(config: TestProjectConfiguration[]): TestProjectConfiguration[]; + +export { TestProjectConfiguration, UserProjectConfigExport, UserProjectConfigFn, UserWorkspaceConfig, configDefaults, coverageConfigDefaults, defaultBrowserPort, defaultExclude, defaultInclude, defineConfig, defineProject, defineWorkspace, extraInlineDeps }; +export type { UserConfig, UserConfigExport, UserConfigFn, UserConfigFnObject, UserConfigFnPromise }; diff --git a/node_modules/vitest/dist/config.js b/node_modules/vitest/dist/config.js new file mode 100644 index 0000000000..7c7e774abf --- /dev/null +++ b/node_modules/vitest/dist/config.js @@ -0,0 +1,21 @@ +export { d as defaultBrowserPort, e as extraInlineDeps } from './chunks/constants.DnKduX2e.js'; +export { c as configDefaults, a as coverageConfigDefaults, d as defaultExclude, b as defaultInclude } from './chunks/defaults.B7q_naMc.js'; +export { mergeConfig } from 'vite'; +import 'node:os'; +import './chunks/env.D4Lgay0q.js'; +import 'std-env'; + +function defineConfig(config) { + return config; +} +function defineProject(config) { + return config; +} +/** +* @deprecated use the `projects` field in the root config instead +*/ +function defineWorkspace(config) { + return config; +} + +export { defineConfig, defineProject, defineWorkspace }; diff --git a/node_modules/vitest/dist/coverage.d.ts b/node_modules/vitest/dist/coverage.d.ts new file mode 100644 index 0000000000..dbcd5a6d5d --- /dev/null +++ b/node_modules/vitest/dist/coverage.d.ts @@ -0,0 +1,108 @@ +import { R as ResolvedCoverageOptions, V as Vitest, C as CoverageMap, a as ReportContext } from './chunks/reporters.d.BFLkQcL6.js'; +import { TransformResult } from 'vite'; +import { A as AfterSuiteRunMeta } from './chunks/environment.d.cL3nLXbE.js'; +import '@vitest/runner'; +import '@vitest/utils'; +import 'node:stream'; +import 'node:console'; +import '@vitest/mocker'; +import '@vitest/utils/source-map'; +import './chunks/worker.d.1GmBbd7G.js'; +import 'vite-node'; +import './chunks/config.d.D2ROskhv.js'; +import '@vitest/pretty-format'; +import '@vitest/snapshot'; +import '@vitest/snapshot/environment'; +import '@vitest/utils/diff'; +import 'chai'; +import './chunks/benchmark.d.BwvBVTda.js'; +import '@vitest/runner/utils'; +import 'tinybench'; +import './chunks/coverage.d.S9RMNXIe.js'; +import 'vite-node/client'; +import '@vitest/snapshot/manager'; +import 'node:fs'; +import 'vitest/optional-types.js'; + +type Threshold = "lines" | "functions" | "statements" | "branches"; +interface ResolvedThreshold { + coverageMap: CoverageMap; + name: string; + thresholds: Partial>; +} +/** +* Holds info about raw coverage results that are stored on file system: +* +* ```json +* "project-a": { +* "web": { +* "tests/math.test.ts": "coverage-1.json", +* "tests/utils.test.ts": "coverage-2.json", +* // ^^^^^^^^^^^^^^^ Raw coverage on file system +* }, +* "ssr": { ... }, +* "browser": { ... }, +* }, +* "project-b": ... +* ``` +*/ +type CoverageFiles = Map | symbol, Record>; +declare class BaseCoverageProvider> { + ctx: Vitest; + readonly name: "v8" | "istanbul"; + version: string; + options: Options; + coverageFiles: CoverageFiles; + pendingPromises: Promise[]; + coverageFilesDirectory: string; + _initialize(ctx: Vitest): void; + createCoverageMap(): CoverageMap; + generateReports(_: CoverageMap, __: boolean | undefined): Promise; + parseConfigModule(_: string): Promise<{ + generate: () => { + code: string + } + }>; + resolveOptions(): Options; + clean(clean?: boolean): Promise; + onAfterSuiteRun({ coverage, transformMode, projectName, testFiles }: AfterSuiteRunMeta): void; + readCoverageFiles({ onFileRead, onFinished, onDebug }: { + /** Callback invoked with a single coverage result */ + onFileRead: (data: CoverageType) => void + /** Callback invoked once all results of a project for specific transform mode are read */ + onFinished: (project: Vitest["projects"][number], transformMode: AfterSuiteRunMeta["transformMode"]) => Promise + onDebug: ((...logs: any[]) => void) & { + enabled: boolean + } + }): Promise; + cleanAfterRun(): Promise; + onTestFailure(): Promise; + reportCoverage(coverageMap: unknown, { allTestsRun }: ReportContext): Promise; + reportThresholds(coverageMap: CoverageMap, allTestsRun: boolean | undefined): Promise; + /** + * Constructs collected coverage and users' threshold options into separate sets + * where each threshold set holds their own coverage maps. Threshold set is either + * for specific files defined by glob pattern or global for all other files. + */ + private resolveThresholds; + /** + * Check collected coverage against configured thresholds. Sets exit code to 1 when thresholds not reached. + */ + private checkThresholds; + /** + * Check if current coverage is above configured thresholds and bump the thresholds if needed + */ + updateThresholds({ thresholds: allThresholds, onUpdate, configurationFile }: { + thresholds: ResolvedThreshold[] + configurationFile: unknown + onUpdate: () => void + }): Promise; + mergeReports(coverageMaps: unknown[]): Promise; + hasTerminalReporter(reporters: ResolvedCoverageOptions["reporter"]): boolean; + toSlices(array: T[], size: number): T[][]; + createUncoveredFileTransformer(ctx: Vitest): (filename: string) => Promise; +} + +export { BaseCoverageProvider }; diff --git a/node_modules/vitest/dist/coverage.js b/node_modules/vitest/dist/coverage.js new file mode 100644 index 0000000000..b3806af170 --- /dev/null +++ b/node_modules/vitest/dist/coverage.js @@ -0,0 +1,34 @@ +export { B as BaseCoverageProvider } from './chunks/coverage.DL5VHqXY.js'; +import 'node:fs'; +import 'pathe'; +import 'picomatch'; +import 'tinyrainbow'; +import './chunks/defaults.B7q_naMc.js'; +import 'node:os'; +import './chunks/env.D4Lgay0q.js'; +import 'std-env'; +import 'node:crypto'; +import '@vitest/utils'; +import 'node:module'; +import 'node:path'; +import 'node:process'; +import 'node:fs/promises'; +import 'node:url'; +import 'node:assert'; +import 'node:v8'; +import 'node:util'; +import 'vite'; +import './chunks/constants.DnKduX2e.js'; +import 'node:tty'; +import 'node:events'; +import './chunks/index.B521nVV-.js'; +import 'tinypool'; +import './chunks/typechecker.DRKU1-1g.js'; +import 'node:perf_hooks'; +import '@vitest/utils/source-map'; +import 'tinyexec'; +import './path.js'; +import '@vitest/runner/utils'; +import 'node:worker_threads'; +import 'vite-node/utils'; +import './chunks/coverage.DVF1vEu8.js'; diff --git a/node_modules/vitest/dist/environments.d.ts b/node_modules/vitest/dist/environments.d.ts new file mode 100644 index 0000000000..eb7af4ec70 --- /dev/null +++ b/node_modules/vitest/dist/environments.d.ts @@ -0,0 +1,26 @@ +import { E as Environment } from './chunks/environment.d.cL3nLXbE.js'; +export { a as EnvironmentReturn, V as VmEnvironmentReturn } from './chunks/environment.d.cL3nLXbE.js'; +import 'vitest/optional-types.js'; + +declare const environments: { + "node": Environment + "jsdom": Environment + "happy-dom": Environment + "edge-runtime": Environment +}; + +interface PopulateOptions { + // we bind functions such as addEventListener and others + // because they rely on `this` in happy-dom, and in jsdom it + // has a priority for getting implementation from symbols + // (global doesn't have these symbols, but window - does) + bindFunctions?: boolean; + additionalKeys?: string[]; +} +declare function populateGlobal(global: any, win: any, options?: PopulateOptions): { + keys: Set + skipKeys: string[] + originals: Map +}; + +export { Environment, environments as builtinEnvironments, populateGlobal }; diff --git a/node_modules/vitest/dist/environments.js b/node_modules/vitest/dist/environments.js new file mode 100644 index 0000000000..131e102178 --- /dev/null +++ b/node_modules/vitest/dist/environments.js @@ -0,0 +1,2 @@ +export { e as builtinEnvironments, p as populateGlobal } from './chunks/index.CmSc2RE5.js'; +import 'node:console'; diff --git a/node_modules/vitest/dist/execute.d.ts b/node_modules/vitest/dist/execute.d.ts new file mode 100644 index 0000000000..d6b0a4da87 --- /dev/null +++ b/node_modules/vitest/dist/execute.d.ts @@ -0,0 +1,150 @@ +import { ViteNodeRunnerOptions } from 'vite-node'; +import { ViteNodeRunner, ModuleExecutionInfo } from 'vite-node/client'; +import { R as RuntimeRPC, W as WorkerGlobalState } from './chunks/worker.d.1GmBbd7G.js'; +import vm from 'node:vm'; +import { MockedModule, MockedModuleType } from '@vitest/mocker'; +import { P as PendingSuiteMock, b as MockFactory, a as MockOptions } from './chunks/mocker.d.BE_2ls6u.js'; +import '@vitest/runner'; +import './chunks/config.d.D2ROskhv.js'; +import '@vitest/pretty-format'; +import '@vitest/snapshot'; +import '@vitest/snapshot/environment'; +import '@vitest/utils/diff'; +import './chunks/environment.d.cL3nLXbE.js'; +import 'vitest/optional-types.js'; + +declare class FileMap { + private fsCache; + private fsBufferCache; + readFileAsync(path: string): Promise; + readFile(path: string): string; + readBuffer(path: string): Buffer; +} + +// need to copy paste types for vm +// because they require latest @types/node which we don't bundle +interface ModuleEvaluateOptions { + timeout?: vm.RunningScriptOptions["timeout"] | undefined; + breakOnSigint?: vm.RunningScriptOptions["breakOnSigint"] | undefined; +} +type ModuleLinker = (specifier: string, referencingModule: VMModule, extra: { + assert: object +}) => VMModule | Promise; +type ModuleStatus = "unlinked" | "linking" | "linked" | "evaluating" | "evaluated" | "errored"; +declare class VMModule { + dependencySpecifiers: readonly string[]; + error: any; + identifier: string; + context: vm.Context; + namespace: object; + status: ModuleStatus; + evaluate(options?: ModuleEvaluateOptions): Promise; + link(linker: ModuleLinker): Promise; +} + +interface ExternalModulesExecutorOptions { + context: vm.Context; + fileMap: FileMap; + packageCache: Map; + transform: RuntimeRPC["transform"]; + interopDefault?: boolean; + viteClientModule: Record; +} +// TODO: improve Node.js strict mode support in #2854 +declare class ExternalModulesExecutor { + #private; + private options; + private cjs; + private esm; + private vite; + private context; + private fs; + private resolvers; + constructor(options: ExternalModulesExecutorOptions); + import(identifier: string): Promise; + require(identifier: string): any; + createRequire(identifier: string): NodeJS.Require; + // dynamic import can be used in both ESM and CJS, so we have it in the executor + importModuleDynamically: (specifier: string, referencer: VMModule) => Promise; + resolveModule: (specifier: string, referencer: string) => Promise; + resolve(specifier: string, parent: string): string; + private findNearestPackageData; + private getModuleInformation; + private createModule; + private get isNetworkSupported(); +} + +interface MockContext { + /** + * When mocking with a factory, this refers to the module that imported the mock. + */ + callstack: null | string[]; +} +declare class VitestMocker { + executor: VitestExecutor; + static pendingIds: PendingSuiteMock[]; + private spyModule?; + private primitives; + private filterPublicKeys; + private registries; + private mockContext; + constructor(executor: VitestExecutor); + private get root(); + private get moduleCache(); + private get moduleDirectories(); + initializeSpyModule(): Promise; + private getMockerRegistry; + reset(): void; + private deleteCachedItem; + private isModuleDirectory; + getSuiteFilepath(): string; + private createError; + private resolvePath; + resolveMocks(): Promise; + private callFunctionMock; + // public method to avoid circular dependency + getMockContext(): MockContext; + // path used to store mocked dependencies + getMockPath(dep: string): string; + getDependencyMock(id: string): MockedModule | undefined; + normalizePath(path: string): string; + resolveMockPath(mockPath: string, external: string | null): string | null; + mockObject(object: Record, mockExports?: Record, behavior?: MockedModuleType): Record; + unmockPath(path: string): void; + mockPath(originalId: string, path: string, external: string | null, mockType: MockedModuleType | undefined, factory: MockFactory | undefined): void; + importActual(rawId: string, importer: string, callstack?: string[] | null): Promise; + importMock(rawId: string, importee: string): Promise; + requestWithMock(url: string, callstack: string[]): Promise; + queueMock(id: string, importer: string, factoryOrOptions?: MockFactory | MockOptions): void; + queueUnmock(id: string, importer: string): void; +} + +interface ExecuteOptions extends ViteNodeRunnerOptions { + moduleDirectories?: string[]; + state: WorkerGlobalState; + context?: vm.Context; + externalModulesExecutor?: ExternalModulesExecutor; +} +declare class VitestExecutor extends ViteNodeRunner { + options: ExecuteOptions; + mocker: VitestMocker; + externalModules?: ExternalModulesExecutor; + private primitives; + constructor(options: ExecuteOptions); + protected getContextPrimitives(): { + Object: typeof Object + Reflect: typeof Reflect + Symbol: typeof Symbol + }; + get state(): WorkerGlobalState; + get moduleExecutionInfo(): ModuleExecutionInfo | undefined; + shouldResolveId(id: string, _importee?: string | undefined): boolean; + originalResolveUrl(id: string, importer?: string): Promise<[url: string, fsPath: string]>; + resolveUrl(id: string, importer?: string): Promise<[url: string, fsPath: string]>; + protected runModule(context: Record, transformed: string): Promise; + importExternalModule(path: string): Promise; + dependencyRequest(id: string, fsPath: string, callstack: string[]): Promise; + prepareContext(context: Record): Record; +} + +export { VitestExecutor }; diff --git a/node_modules/vitest/dist/execute.js b/node_modules/vitest/dist/execute.js new file mode 100644 index 0000000000..a7ffc2ca16 --- /dev/null +++ b/node_modules/vitest/dist/execute.js @@ -0,0 +1,13 @@ +export { V as VitestExecutor } from './chunks/execute.B7h3T_Hc.js'; +import 'node:fs'; +import 'node:url'; +import 'node:vm'; +import '@vitest/utils/error'; +import 'pathe'; +import 'vite-node/client'; +import 'vite-node/utils'; +import './path.js'; +import 'node:path'; +import '@vitest/mocker'; +import 'node:module'; +import '@vitest/utils'; diff --git a/node_modules/vitest/dist/index.d.ts b/node_modules/vitest/dist/index.d.ts new file mode 100644 index 0000000000..d8bc8c662f --- /dev/null +++ b/node_modules/vitest/dist/index.d.ts @@ -0,0 +1,651 @@ +import { File as File$1, TestAnnotation, TaskResultPack as TaskResultPack$1, TaskEventPack, TaskPopulated, Suite as Suite$1, Test as Test$1, Custom as Custom$1, Task as Task$1, TaskBase as TaskBase$1, TaskResult as TaskResult$1, DoneCallback as DoneCallback$1, RuntimeContext as RuntimeContext$1, SuiteHooks as SuiteHooks$1, SequenceHooks as SequenceHooks$1, SequenceSetupFiles as SequenceSetupFiles$1 } from '@vitest/runner'; +export { CancelReason, ExtendedContext, HookCleanupCallback, HookListener, ImportDuration, OnTestFailedHandler, OnTestFinishedHandler, RunMode, Custom as RunnerCustomCase, Task as RunnerTask, TaskBase as RunnerTaskBase, TaskEventPack as RunnerTaskEventPack, TaskResult as RunnerTaskResult, TaskResultPack as RunnerTaskResultPack, Test as RunnerTestCase, File as RunnerTestFile, Suite as RunnerTestSuite, SuiteAPI, SuiteCollector, SuiteFactory, TaskContext, TaskCustomOptions, TaskMeta, TaskState, TestAPI, TestAnnotation, TestContext, TestFunction, TestOptions, afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner'; +import { S as SerializedTestSpecification, h as CoverageProvider$1, a as ReportContext$1, i as CoverageProviderModule$1, j as CoverageReporter$1, k as CoverageProviderName, l as CoverageOptions$1, R as ResolvedCoverageOptions$1, B as BaseCoverageOptions$1, m as CoverageIstanbulOptions$1, c as CoverageV8Options$1, n as CustomProviderOptions$1, o as Reporter$1, V as Vitest$1, p as BrowserScript$1, q as BrowserConfigOptions$1, r as BuiltinEnvironment$1, s as VitestEnvironment$1, P as Pool$1, t as PoolOptions$1, u as CSSModuleScopeStrategy$1, A as ApiConfig$1, v as VitestRunMode$1, D as DepsOptimizationOptions$1, w as TransformModePatterns$1, I as InlineConfig$1, x as TypecheckConfig$1, y as UserConfig$1, z as ResolvedConfig$1, E as ProjectConfig$1, U as UserWorkspaceConfig$1, F as BenchmarkUserOptions$1 } from './chunks/reporters.d.BFLkQcL6.js'; +export { G as BrowserTesterOptions } from './chunks/reporters.d.BFLkQcL6.js'; +import { W as WorkerContext$1 } from './chunks/worker.d.CKwWzBSj.js'; +import { R as RawErrsMap$1, T as TscErrorInfo$1, C as CollectLineNumbers$1, a as CollectLines$1, b as RootAndTarget$1, c as Context$1 } from './chunks/global.d.MAmajcmJ.js'; +import { b as Awaitable$1, U as UserConsoleLog, L as LabelColor, M as ModuleGraphData, P as ProvidedContext, N as Nullable$1, c as Arrayable$1, d as ArgumentsType$1, e as MutableArray$1, C as Constructable$1, a as EnvironmentReturn$1, V as VmEnvironmentReturn$1, E as Environment$1, R as ResolvedTestEnvironment$1, J as JSDOMOptions$1, H as HappyDOMOptions$1, f as EnvironmentOptions$1 } from './chunks/environment.d.cL3nLXbE.js'; +export { A as AfterSuiteRunMeta, g as ModuleCache } from './chunks/environment.d.cL3nLXbE.js'; +import { a as BirpcReturn, b as WorkerRPC$1 } from './chunks/worker.d.1GmBbd7G.js'; +export { C as ContextRPC, d as ContextTestEnvironment, e as ResolveIdFunction, c as RunnerRPC, R as RuntimeRPC, T as TestExecutionMethod, W as WorkerGlobalState } from './chunks/worker.d.1GmBbd7G.js'; +import './chunks/vite.d.CMLlLIFP.js'; +import { a as SerializedConfig, F as FakeTimerInstallOpts, R as RuntimeOptions } from './chunks/config.d.D2ROskhv.js'; +export { b as RuntimeConfig, S as SerializedCoverageConfig } from './chunks/config.d.D2ROskhv.js'; +import { ExpectStatic } from '@vitest/expect'; +export { Assertion, AsymmetricMatchersContaining, DeeplyAllowMatchers, ExpectPollOptions, ExpectStatic, JestAssertion, Matchers } from '@vitest/expect'; +import { spyOn, fn, MaybeMockedDeep, MaybeMocked, MaybePartiallyMocked, MaybePartiallyMockedDeep, MockInstance } from '@vitest/spy'; +export { Mock, MockContext, MockInstance, Mocked, MockedClass, MockedFunction, MockedObject } from '@vitest/spy'; +import { M as MockFactoryWithHelper, a as MockOptions } from './chunks/mocker.d.BE_2ls6u.js'; +export { b as bench } from './chunks/suite.d.FvehnV49.js'; +export { a as BenchFunction, b as Benchmark, c as BenchmarkAPI, B as BenchmarkResult } from './chunks/benchmark.d.BwvBVTda.js'; +export { ExpectTypeOf, expectTypeOf } from 'expect-type'; +export { SnapshotData, SnapshotMatchOptions, SnapshotResult, SnapshotSerializer, SnapshotStateOptions, SnapshotSummary, SnapshotUpdateState, UncheckedSnapshot } from '@vitest/snapshot'; +export { ErrorWithDiff, ParsedStack, SerializedError, TestError } from '@vitest/utils'; +export { DiffOptions } from '@vitest/utils/diff'; +import * as chai from 'chai'; +export { chai }; +export { assert, should } from 'chai'; +export { Bench as BenchFactory, Options as BenchOptions, Task as BenchTask, TaskResult as BenchTaskResult } from 'tinybench'; +import 'node:stream'; +import 'vite'; +import 'node:console'; +import '@vitest/mocker'; +import '@vitest/utils/source-map'; +import '@vitest/pretty-format'; +import 'vite-node'; +import './chunks/coverage.d.S9RMNXIe.js'; +import 'vite-node/client'; +import '@vitest/snapshot/manager'; +import 'node:fs'; +import 'node:worker_threads'; +import 'vitest/optional-types.js'; +import '@vitest/snapshot/environment'; +import '@vitest/runner/utils'; + +interface SourceMap { + file: string; + mappings: string; + names: string[]; + sources: string[]; + sourcesContent?: string[]; + version: number; + toString: () => string; + toUrl: () => string; +} +interface TransformResultWithSource { + code: string; + map: SourceMap | { + mappings: "" + } | null; + etag?: string; + deps?: string[]; + dynamicDeps?: string[]; + source?: string; +} +interface WebSocketHandlers { + onTaskUpdate: (packs: TaskResultPack$1[], events: TaskEventPack[]) => void; + getFiles: () => File$1[]; + getTestFiles: () => Promise; + getPaths: () => string[]; + getConfig: () => SerializedConfig; + // TODO: Remove in v4 + /** @deprecated -- Use `getResolvedProjectLabels` instead */ + getResolvedProjectNames: () => string[]; + getResolvedProjectLabels: () => { + name: string + color?: LabelColor + }[]; + getModuleGraph: (projectName: string, id: string, browser?: boolean) => Promise; + getTransformResult: (projectName: string, id: string, browser?: boolean) => Promise; + readTestFile: (id: string) => Promise; + saveTestFile: (id: string, content: string) => Promise; + rerun: (files: string[], resetTestNamePattern?: boolean) => Promise; + rerunTask: (id: string) => Promise; + updateSnapshot: (file?: File$1) => Promise; + getUnhandledErrors: () => unknown[]; +} +interface WebSocketEvents { + onCollected?: (files?: File$1[]) => Awaitable$1; + onFinished?: (files: File$1[], errors: unknown[], coverage?: unknown) => Awaitable$1; + onTestAnnotate?: (testId: string, annotation: TestAnnotation) => Awaitable$1; + onTaskUpdate?: (packs: TaskResultPack$1[], events: TaskEventPack[]) => Awaitable$1; + onUserConsoleLog?: (log: UserConsoleLog) => Awaitable$1; + onPathsCollected?: (paths?: string[]) => Awaitable$1; + onSpecsCollected?: (specs?: SerializedTestSpecification[]) => Awaitable$1; + onFinishedReportCoverage: () => void; +} +type WebSocketRPC = BirpcReturn; + +// CI fails only for this file, but it works locally + +declare function createExpect(test?: TaskPopulated): ExpectStatic; +declare const globalExpect: ExpectStatic; + +/** +* Gives access to injected context provided from the main thread. +* This usually returns a value provided by `globalSetup` or an external library. +*/ +declare function inject(key: T): ProvidedContext[T]; + +// The waitFor function was inspired by https://github.com/testing-library/web-testing-library/pull/2 +type WaitForCallback = () => T | Promise; +interface WaitForOptions { + /** + * @description Time in ms between each check callback + * @default 50ms + */ + interval?: number; + /** + * @description Time in ms after which the throw a timeout error + * @default 1000ms + */ + timeout?: number; +} +declare function waitFor(callback: WaitForCallback, options?: number | WaitForOptions): Promise; +type WaitUntilCallback = () => T | Promise; +interface WaitUntilOptions extends Pick {} +type Truthy = T extends false | "" | 0 | null | undefined ? never : T; +declare function waitUntil(callback: WaitUntilCallback, options?: number | WaitUntilOptions): Promise>; + +type ESModuleExports = Record; +interface VitestUtils { + /** + * Checks if fake timers are enabled. + */ + isFakeTimers: () => boolean; + /** + * This method wraps all further calls to timers until [`vi.useRealTimers()`](https://vitest.dev/api/vi#vi-userealtimers) is called. + */ + useFakeTimers: (config?: FakeTimerInstallOpts) => VitestUtils; + /** + * Restores mocked timers to their original implementations. All timers that were scheduled before will be discarded. + */ + useRealTimers: () => VitestUtils; + /** + * This method will call every timer that was initiated after [`vi.useFakeTimers`](https://vitest.dev/api/vi#vi-usefaketimers) call. + * It will not fire any timer that was initiated during its call. + */ + runOnlyPendingTimers: () => VitestUtils; + /** + * This method will asynchronously call every timer that was initiated after [`vi.useFakeTimers`](https://vitest.dev/api/vi#vi-usefaketimers) call, even asynchronous ones. + * It will not fire any timer that was initiated during its call. + */ + runOnlyPendingTimersAsync: () => Promise; + /** + * This method will invoke every initiated timer until the timer queue is empty. It means that every timer called during `runAllTimers` will be fired. + * If you have an infinite interval, it will throw after 10,000 tries (can be configured with [`fakeTimers.loopLimit`](https://vitest.dev/config/#faketimers-looplimit)). + */ + runAllTimers: () => VitestUtils; + /** + * This method will asynchronously invoke every initiated timer until the timer queue is empty. It means that every timer called during `runAllTimersAsync` will be fired even asynchronous timers. + * If you have an infinite interval, it will throw after 10 000 tries (can be configured with [`fakeTimers.loopLimit`](https://vitest.dev/config/#faketimers-looplimit)). + */ + runAllTimersAsync: () => Promise; + /** + * Calls every microtask that was queued by `process.nextTick`. This will also run all microtasks scheduled by themselves. + */ + runAllTicks: () => VitestUtils; + /** + * This method will invoke every initiated timer until the specified number of milliseconds is passed or the queue is empty - whatever comes first. + */ + advanceTimersByTime: (ms: number) => VitestUtils; + /** + * This method will invoke every initiated timer until the specified number of milliseconds is passed or the queue is empty - whatever comes first. This will include and await asynchronously set timers. + */ + advanceTimersByTimeAsync: (ms: number) => Promise; + /** + * Will call next available timer. Useful to make assertions between each timer call. You can chain call it to manage timers by yourself. + */ + advanceTimersToNextTimer: () => VitestUtils; + /** + * Will call next available timer and wait until it's resolved if it was set asynchronously. Useful to make assertions between each timer call. + */ + advanceTimersToNextTimerAsync: () => Promise; + /** + * Similar to [`vi.advanceTimersByTime`](https://vitest.dev/api/vi#vi-advancetimersbytime), but will advance timers by the milliseconds needed to execute callbacks currently scheduled with `requestAnimationFrame`. + */ + advanceTimersToNextFrame: () => VitestUtils; + /** + * Get the number of waiting timers. + */ + getTimerCount: () => number; + /** + * If fake timers are enabled, this method simulates a user changing the system clock (will affect date related API like `hrtime`, `performance.now` or `new Date()`) - however, it will not fire any timers. + * If fake timers are not enabled, this method will only mock `Date.*` and `new Date()` calls. + */ + setSystemTime: (time: number | string | Date) => VitestUtils; + /** + * Returns mocked current date. If date is not mocked the method will return `null`. + */ + getMockedSystemTime: () => Date | null; + /** + * When using `vi.useFakeTimers`, `Date.now` calls are mocked. If you need to get real time in milliseconds, you can call this function. + */ + getRealSystemTime: () => number; + /** + * Removes all timers that are scheduled to run. These timers will never run in the future. + */ + clearAllTimers: () => VitestUtils; + /** + * Creates a spy on a method or getter/setter of an object similar to [`vi.fn()`](https://vitest.dev/api/vi#vi-fn). It returns a [mock function](https://vitest.dev/api/mock). + * @example + * ```ts + * const cart = { + * getApples: () => 42 + * } + * + * const spy = vi.spyOn(cart, 'getApples').mockReturnValue(10) + * + * expect(cart.getApples()).toBe(10) + * expect(spy).toHaveBeenCalled() + * expect(spy).toHaveReturnedWith(10) + * ``` + */ + spyOn: typeof spyOn; + /** + * Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](https://vitest.dev/api/mock). + * + * If no function is given, mock will return `undefined`, when invoked. + * @example + * ```ts + * const getApples = vi.fn(() => 0) + * + * getApples() + * + * expect(getApples).toHaveBeenCalled() + * expect(getApples).toHaveReturnedWith(0) + * + * getApples.mockReturnValueOnce(5) + * + * expect(getApples()).toBe(5) + * expect(getApples).toHaveNthReturnedWith(2, 5) + * ``` + */ + fn: typeof fn; + /** + * Wait for the callback to execute successfully. If the callback throws an error or returns a rejected promise it will continue to wait until it succeeds or times out. + * + * This is very useful when you need to wait for some asynchronous action to complete, for example, when you start a server and need to wait for it to start. + * @example + * ```ts + * const server = createServer() + * + * await vi.waitFor( + * () => { + * if (!server.isReady) + * throw new Error('Server not started') + * + * console.log('Server started') + * }, { + * timeout: 500, // default is 1000 + * interval: 20, // default is 50 + * } + * ) + * ``` + */ + waitFor: typeof waitFor; + /** + * This is similar to [`vi.waitFor`](https://vitest.dev/api/vi#vi-waitfor), but if the callback throws any errors, execution is immediately interrupted and an error message is received. + * + * If the callback returns a falsy value, the next check will continue until a truthy value is returned. This is useful when you need to wait for something to exist before taking the next step. + * @example + * ```ts + * const element = await vi.waitUntil( + * () => document.querySelector('.element'), + * { + * timeout: 500, // default is 1000 + * interval: 20, // default is 50 + * } + * ) + * + * // do something with the element + * expect(element.querySelector('.element-child')).toBeTruthy() + * ``` + */ + waitUntil: typeof waitUntil; + /** + * Run the factory before imports are evaluated. You can return a value from the factory + * to reuse it inside your [`vi.mock`](https://vitest.dev/api/vi#vi-mock) factory and tests. + * + * If used with [`vi.mock`](https://vitest.dev/api/vi#vi-mock), both will be hoisted in the order they are defined in. + */ + hoisted: (factory: () => T) => T; + /** + * Mocks every import call to the module even if it was already statically imported. + * + * The call to `vi.mock` is hoisted to the top of the file, so you don't have access to variables declared in the global file scope + * unless they are defined with [`vi.hoisted`](https://vitest.dev/api/vi#vi-hoisted) before this call. + * + * Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking#modules). + * @param path Path to the module. Can be aliased, if your Vitest config supports it + * @param factory Mocked module factory. The result of this function will be an exports object + */ + // eslint-disable-next-line ts/method-signature-style + mock(path: string, factory?: MockFactoryWithHelper | MockOptions): void; + // eslint-disable-next-line ts/method-signature-style + mock(module: Promise, factory?: MockFactoryWithHelper | MockOptions): void; + /** + * Removes module from mocked registry. All calls to import will return the original module even if it was mocked before. + * + * This call is hoisted to the top of the file, so it will only unmock modules that were defined in `setupFiles`, for example. + * @param path Path to the module. Can be aliased, if your Vitest config supports it + */ + // eslint-disable-next-line ts/method-signature-style + unmock(path: string): void; + // eslint-disable-next-line ts/method-signature-style + unmock(module: Promise): void; + /** + * Mocks every subsequent [dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) call. + * + * Unlike [`vi.mock`](https://vitest.dev/api/vi#vi-mock), this method will not mock statically imported modules because it is not hoisted to the top of the file. + * + * Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking#modules). + * @param path Path to the module. Can be aliased, if your Vitest config supports it + * @param factory Mocked module factory. The result of this function will be an exports object + */ + // eslint-disable-next-line ts/method-signature-style + doMock(path: string, factory?: MockFactoryWithHelper | MockOptions): void; + // eslint-disable-next-line ts/method-signature-style + doMock(module: Promise, factory?: MockFactoryWithHelper | MockOptions): void; + /** + * Removes module from mocked registry. All subsequent calls to import will return original module. + * + * Unlike [`vi.unmock`](https://vitest.dev/api/vi#vi-unmock), this method is not hoisted to the top of the file. + * @param path Path to the module. Can be aliased, if your Vitest config supports it + */ + // eslint-disable-next-line ts/method-signature-style + doUnmock(path: string): void; + // eslint-disable-next-line ts/method-signature-style + doUnmock(module: Promise): void; + /** + * Imports module, bypassing all checks if it should be mocked. + * Can be useful if you want to mock module partially. + * @example + * ```ts + * vi.mock('./example.js', async () => { + * const axios = await vi.importActual('./example.js') + * + * return { ...axios, get: vi.fn() } + * }) + * ``` + * @param path Path to the module. Can be aliased, if your config supports it + */ + importActual: (path: string) => Promise; + /** + * Imports a module with all of its properties and nested properties mocked. + * + * Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking#modules). + * @example + * ```ts + * const example = await vi.importMock('./example.js') + * example.calc.mockReturnValue(10) + * expect(example.calc()).toBe(10) + * ``` + * @param path Path to the module. Can be aliased, if your config supports it + * @returns Fully mocked module + */ + importMock: (path: string) => Promise>; + /** + * Deeply mocks properties and methods of a given object + * in the same way as `vi.mock()` mocks module exports. + * + * @example + * ```ts + * const original = { + * simple: () => 'value', + * nested: { + * method: () => 'real' + * }, + * prop: 'foo', + * } + * + * const mocked = vi.mockObject(original) + * expect(mocked.simple()).toBe(undefined) + * expect(mocked.nested.method()).toBe(undefined) + * expect(mocked.prop).toBe('foo') + * + * mocked.simple.mockReturnValue('mocked') + * mocked.nested.method.mockReturnValue('mocked nested') + * + * expect(mocked.simple()).toBe('mocked') + * expect(mocked.nested.method()).toBe('mocked nested') + * ``` + * + * @param value - The object to be mocked + * @returns A deeply mocked version of the input object + */ + mockObject: (value: T) => MaybeMockedDeep; + /** + * Type helper for TypeScript. Just returns the object that was passed. + * + * When `partial` is `true` it will expect a `Partial` as a return value. By default, this will only make TypeScript believe that + * the first level values are mocked. You can pass down `{ deep: true }` as a second argument to tell TypeScript that the whole object is mocked, if it actually is. + * @example + * ```ts + * import example from './example.js' + * vi.mock('./example.js') + * + * test('1 + 1 equals 10' async () => { + * vi.mocked(example.calc).mockReturnValue(10) + * expect(example.calc(1, '+', 1)).toBe(10) + * }) + * ``` + * @param item Anything that can be mocked + * @param deep If the object is deeply mocked + * @param options If the object is partially or deeply mocked + */ + mocked: ((item: T, deep?: false) => MaybeMocked) & ((item: T, deep: true) => MaybeMockedDeep) & ((item: T, options: { + partial?: false + deep?: false + }) => MaybeMocked) & ((item: T, options: { + partial?: false + deep: true + }) => MaybeMockedDeep) & ((item: T, options: { + partial: true + deep?: false + }) => MaybePartiallyMocked) & ((item: T, options: { + partial: true + deep: true + }) => MaybePartiallyMockedDeep) & ((item: T) => MaybeMocked); + /** + * Checks that a given parameter is a mock function. If you are using TypeScript, it will also narrow down its type. + */ + isMockFunction: (fn: any) => fn is MockInstance; + /** + * Calls [`.mockClear()`](https://vitest.dev/api/mock#mockclear) on every mocked function. + * + * This will only empty `.mock` state, it will not affect mock implementations. + * + * This is useful if you need to clean up mocks between different assertions within a test. + */ + clearAllMocks: () => VitestUtils; + /** + * Calls [`.mockReset()`](https://vitest.dev/api/mock#mockreset) on every mocked function. + * + * This will empty `.mock` state, reset "once" implementations, and reset each mock's base implementation to its original. + * + * This is useful when you want to reset all mocks to their original states. + */ + resetAllMocks: () => VitestUtils; + /** + * Calls [`.mockRestore()`](https://vitest.dev/api/mock#mockrestore) on every mocked function. + * + * This will empty `.mock` state, restore all original mock implementations, and restore original descriptors of spied-on objects. + * + * This is useful for inter-test cleanup and/or removing mocks created by [`vi.spyOn(...)`](https://vitest.dev/api/vi#vi-spyon). + */ + restoreAllMocks: () => VitestUtils; + /** + * Makes value available on global namespace. + * Useful, if you want to have global variables available, like `IntersectionObserver`. + * You can return it back to original value with `vi.unstubAllGlobals`, or by enabling `unstubGlobals` config option. + */ + stubGlobal: (name: string | symbol | number, value: unknown) => VitestUtils; + /** + * Changes the value of `import.meta.env` and `process.env`. + * You can return it back to original value with `vi.unstubAllEnvs`, or by enabling `unstubEnvs` config option. + */ + stubEnv: (name: T, value: T extends "PROD" | "DEV" | "SSR" ? boolean : string | undefined) => VitestUtils; + /** + * Reset the value to original value that was available before first `vi.stubGlobal` was called. + */ + unstubAllGlobals: () => VitestUtils; + /** + * Reset environmental variables to the ones that were available before first `vi.stubEnv` was called. + */ + unstubAllEnvs: () => VitestUtils; + /** + * Resets modules registry by clearing the cache of all modules. This allows modules to be reevaluated when reimported. + * Top-level imports cannot be re-evaluated. Might be useful to isolate modules where local state conflicts between tests. + * + * This method does not reset mocks registry. To clear mocks registry, use [`vi.unmock`](https://vitest.dev/api/vi#vi-unmock) or [`vi.doUnmock`](https://vitest.dev/api/vi#vi-dounmock). + */ + resetModules: () => VitestUtils; + /** + * Wait for all imports to load. Useful, if you have a synchronous call that starts + * importing a module that you cannot await otherwise. + * Will also wait for new imports, started during the wait. + */ + dynamicImportSettled: () => Promise; + /** + * Updates runtime config. You can only change values that are used when executing tests. + */ + setConfig: (config: RuntimeOptions) => void; + /** + * If config was changed with `vi.setConfig`, this will reset it to the original state. + */ + resetConfig: () => void; +} +declare const vitest: VitestUtils; +declare const vi: VitestUtils; + +interface AssertType { + (value: T): void; +} +declare const assertType: AssertType; + +interface BrowserUI { + setCurrentFileId: (fileId: string) => void; + setIframeViewport: (width: number, height: number) => Promise; +} + +/** @deprecated import `TypeCheckRawErrorsMap` from `vitest/node` instead */ +type RawErrsMap = RawErrsMap$1; +/** @deprecated import `TypeCheckErrorInfo` from `vitest/node` instead */ +type TscErrorInfo = TscErrorInfo$1; +/** @deprecated import `TypeCheckCollectLineNumbers` from `vitest/node` instead */ +type CollectLineNumbers = CollectLineNumbers$1; +/** @deprecated import `TypeCheckCollectLines` from `vitest/node` instead */ +type CollectLines = CollectLines$1; +/** @deprecated import `TypeCheckRootAndTarget` from `vitest/node` instead */ +type RootAndTarget = RootAndTarget$1; +/** @deprecated import `TypeCheckContext` from `vitest/node` instead */ +type Context = Context$1; +/** @deprecated use `RunnerTestSuite` instead */ +type Suite = Suite$1; +/** @deprecated use `RunnerTestFile` instead */ +type File = File$1; +/** @deprecated use `RunnerTestCase` instead */ +type Test = Test$1; +/** @deprecated do not use `Custom`, use `RunnerTestCase` instead */ +type Custom = Custom$1; +/** @deprecated use `RunnerTask` instead */ +type Task = Task$1; +/** @deprecated use `RunnerTaskBase` instead */ +type TaskBase = TaskBase$1; +/** @deprecated use `RunnerTaskResult` instead */ +type TaskResult = TaskResult$1; +/** @deprecated use `RunnerTaskResultPack` instead */ +type TaskResultPack = TaskResultPack$1; +/** @deprecated don't use `DoneCallback` since it's not supported */ +type DoneCallback = DoneCallback$1; +/** @deprecated internal type, don't use it */ +type RuntimeContext = RuntimeContext$1; +/** @deprecated internal type, don't use it */ +type SuiteHooks = SuiteHooks$1; + +/** @deprecated import from `vitest/node` instead */ +type WorkerContext = WorkerContext$1; +/** @deprecated import from `vitest/node` instead */ +type WorkerRPC = WorkerRPC$1; + +/** @deprecated do not use, internal helper */ +type Awaitable = Awaitable$1; +/** @deprecated do not use, internal helper */ +type Nullable = Nullable$1; +/** @deprecated do not use, internal helper */ +type Arrayable = Arrayable$1; +/** @deprecated do not use, internal helper */ +type ArgumentsType = ArgumentsType$1; +/** @deprecated do not use, internal helper */ +type MutableArray = MutableArray$1; +/** @deprecated do not use, internal helper */ +type Constructable = Constructable$1; + +/** @deprecated import from `vitest/environments` instead */ +type EnvironmentReturn = EnvironmentReturn$1; +/** @deprecated import from `vitest/environments` instead */ +type VmEnvironmentReturn = VmEnvironmentReturn$1; +/** @deprecated import from `vitest/environments` instead */ +type Environment = Environment$1; +/** @deprecated do not use it */ +type ResolvedTestEnvironment = ResolvedTestEnvironment$1; +/** @deprecated import from `vitest/node` instead */ +type CoverageProvider = CoverageProvider$1; +/** @deprecated import from `vitest/node` instead */ +type ReportContext = ReportContext$1; +/** @deprecated import from `vitest/node` instead */ +type CoverageProviderModule = CoverageProviderModule$1; +/** @deprecated import from `vitest/node` instead */ +type CoverageReporter = CoverageReporter$1; +/** @deprecated import from `vitest/node` instead */ +type CoverageOptions = CoverageOptions$1; +/** @deprecated import from `vitest/node` instead */ +type ResolvedCoverageOptions = ResolvedCoverageOptions$1; +/** @deprecated import from `vitest/node` instead */ +type BaseCoverageOptions = BaseCoverageOptions$1; +/** @deprecated import from `vitest/node` instead */ +type CoverageIstanbulOptions = CoverageIstanbulOptions$1; +/** @deprecated import from `vitest/node` instead */ +type CoverageV8Options = CoverageV8Options$1; +/** @deprecated import from `vitest/node` instead */ +type CustomProviderOptions = CustomProviderOptions$1; + +/** @deprecated import from `vitest/reporter` instead */ +type Reporter = Reporter$1; +/** @deprecated import from `vitest/node` instead */ +type Vitest = Vitest$1; + +/** @deprecated import from `vitest/node` instead */ +type BrowserScript = BrowserScript$1; +/** @deprecated import from `vitest/node` instead */ +type BrowserConfigOptions = BrowserConfigOptions$1; +/** @deprecated import from `vitest/node` instead */ +type SequenceHooks = SequenceHooks$1; +/** @deprecated import from `vitest/node` instead */ +type SequenceSetupFiles = SequenceSetupFiles$1; +/** @deprecated import from `vitest/node` instead */ +type BuiltinEnvironment = BuiltinEnvironment$1; +/** @deprecated import from `vitest/node` instead */ +type VitestEnvironment = VitestEnvironment$1; +/** @deprecated import from `vitest/node` instead */ +type Pool = Pool$1; +/** @deprecated import from `vitest/node` instead */ +type PoolOptions = PoolOptions$1; +/** @deprecated import from `vitest/node` instead */ +type CSSModuleScopeStrategy = CSSModuleScopeStrategy$1; +/** @deprecated import from `vitest/node` instead */ +type ApiConfig = ApiConfig$1; +/** @deprecated import from `vitest/node` instead */ +type JSDOMOptions = JSDOMOptions$1; +/** @deprecated import from `vitest/node` instead */ +type HappyDOMOptions = HappyDOMOptions$1; +/** @deprecated import from `vitest/node` instead */ +type EnvironmentOptions = EnvironmentOptions$1; +/** @deprecated import from `vitest/node` instead */ +type VitestRunMode = VitestRunMode$1; +/** @deprecated import from `vitest/node` instead */ +type DepsOptimizationOptions = DepsOptimizationOptions$1; +/** @deprecated import from `vitest/node` instead */ +type TransformModePatterns = TransformModePatterns$1; +/** @deprecated import from `vitest/node` instead */ +type InlineConfig = InlineConfig$1; +/** @deprecated import from `vitest/node` instead */ +type TypecheckConfig = TypecheckConfig$1; +/** @deprecated import from `vitest/node` instead */ +type UserConfig = UserConfig$1; +/** @deprecated import from `vitest/node` instead */ +type ResolvedConfig = ResolvedConfig$1; +/** @deprecated import from `vitest/node` instead */ +type ProjectConfig = ProjectConfig$1; +/** @deprecated import from `vitest/node` instead */ +type UserWorkspaceConfig = UserWorkspaceConfig$1; + +/** @deprecated use `SerializedTestSpecification` instead */ +type SerializableSpec = SerializedTestSpecification; + +/** @deprecated import from `vitest/node` instead */ +type BenchmarkUserOptions = BenchmarkUserOptions$1; + +export { LabelColor, ModuleGraphData, ProvidedContext, SerializedConfig, SerializedTestSpecification, UserConsoleLog, assertType, createExpect, globalExpect as expect, inject, vi, vitest }; +export type { ApiConfig, ArgumentsType, Arrayable, AssertType, Awaitable, BaseCoverageOptions, BenchmarkUserOptions, BrowserConfigOptions, BrowserScript, BrowserUI, BuiltinEnvironment, CSSModuleScopeStrategy, CollectLineNumbers, CollectLines, Constructable, Context, CoverageIstanbulOptions, CoverageOptions, CoverageProvider, CoverageProviderModule, CoverageReporter, CoverageV8Options, Custom, CustomProviderOptions, DepsOptimizationOptions, DoneCallback, Environment, EnvironmentOptions, EnvironmentReturn, File, HappyDOMOptions, InlineConfig, JSDOMOptions, MutableArray, Nullable, Pool, PoolOptions, ProjectConfig, RawErrsMap, ReportContext, Reporter, ResolvedConfig, ResolvedCoverageOptions, ResolvedTestEnvironment, RootAndTarget, RuntimeContext, SequenceHooks, SequenceSetupFiles, SerializableSpec, Suite, SuiteHooks, Task, TaskBase, TaskResult, TaskResultPack, Test, TransformModePatterns, TransformResultWithSource, TscErrorInfo, TypecheckConfig, UserConfig, UserWorkspaceConfig, Vitest, VitestEnvironment, VitestRunMode, VitestUtils, VmEnvironmentReturn, WebSocketEvents, WebSocketHandlers, WebSocketRPC, WorkerContext, WorkerRPC }; diff --git a/node_modules/vitest/dist/index.js b/node_modules/vitest/dist/index.js new file mode 100644 index 0000000000..3bdaf85f00 --- /dev/null +++ b/node_modules/vitest/dist/index.js @@ -0,0 +1,18 @@ +export { c as createExpect, a as expect, i as inject, v as vi, b as vitest } from './chunks/vi.bdSIJ99Y.js'; +export { b as bench } from './chunks/benchmark.CYdenmiT.js'; +export { a as assertType } from './chunks/index.CdQS2e2Q.js'; +export { expectTypeOf } from 'expect-type'; +export { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner'; +import * as chai from 'chai'; +export { chai }; +export { assert, should } from 'chai'; +import '@vitest/expect'; +import '@vitest/runner/utils'; +import './chunks/utils.XdZDrNZV.js'; +import '@vitest/utils'; +import './chunks/_commonjsHelpers.BFTU3MAI.js'; +import '@vitest/snapshot'; +import '@vitest/utils/error'; +import '@vitest/spy'; +import '@vitest/utils/source-map'; +import './chunks/date.Bq6ZW5rf.js'; diff --git a/node_modules/vitest/dist/mocker.d.ts b/node_modules/vitest/dist/mocker.d.ts new file mode 100644 index 0000000000..f7dc96a571 --- /dev/null +++ b/node_modules/vitest/dist/mocker.d.ts @@ -0,0 +1 @@ +export * from '@vitest/mocker'; diff --git a/node_modules/vitest/dist/mocker.js b/node_modules/vitest/dist/mocker.js new file mode 100644 index 0000000000..f7dc96a571 --- /dev/null +++ b/node_modules/vitest/dist/mocker.js @@ -0,0 +1 @@ +export * from '@vitest/mocker'; diff --git a/node_modules/vitest/dist/node.d.ts b/node_modules/vitest/dist/node.d.ts new file mode 100644 index 0000000000..269dd06366 --- /dev/null +++ b/node_modules/vitest/dist/node.d.ts @@ -0,0 +1,158 @@ +import { z as ResolvedConfig, y as UserConfig, v as VitestRunMode, H as VitestOptions, V as Vitest, A as ApiConfig, T as TestProject, J as TestSequencer, K as TestSpecification, L as Logger, M as TestModule, N as ModuleDiagnostic } from './chunks/reporters.d.BFLkQcL6.js'; +export { B as BaseCoverageOptions, F as BenchmarkUserOptions, ag as BrowserBuiltinProvider, ah as BrowserCommand, ai as BrowserCommandContext, q as BrowserConfigOptions, aj as BrowserInstanceOption, ak as BrowserModuleMocker, al as BrowserOrchestrator, am as BrowserProvider, an as BrowserProviderInitializationOptions, ao as BrowserProviderModule, ap as BrowserProviderOptions, p as BrowserScript, aq as BrowserServerState, ar as BrowserServerStateSession, r as BuiltinEnvironment, as as CDPSession, u as CSSModuleScopeStrategy, m as CoverageIstanbulOptions, l as CoverageOptions, h as CoverageProvider, i as CoverageProviderModule, j as CoverageReporter, c as CoverageV8Options, n as CustomProviderOptions, D as DepsOptimizationOptions, a0 as HTMLOptions, I as InlineConfig, a2 as JUnitOptions, a1 as JsonOptions, O as OnServerRestartHandler, Q as OnTestsRerunHandler, at as ParentProjectBrowser, P as Pool, t as PoolOptions, Y as ProcessPool, au as ProjectBrowser, E as ProjectConfig, a as ReportContext, aA as ReportedHookContext, o as Reporter, ax as ResolveSnapshotPathHandler, ay as ResolveSnapshotPathHandlerContext, av as ResolvedBrowserOptions, R as ResolvedCoverageOptions, aw as ResolvedProjectConfig, $ as SerializedTestProject, a3 as TaskOptions, a4 as TestCase, a5 as TestCollection, a6 as TestDiagnostic, a7 as TestModuleState, a8 as TestResult, a9 as TestResultFailed, aa as TestResultPassed, ab as TestResultSkipped, aB as TestRunEndReason, az as TestRunResult, af as TestSequencerConstructor, ac as TestState, ad as TestSuite, ae as TestSuiteState, w as TransformModePatterns, x as TypecheckConfig, U as UserWorkspaceConfig, s as VitestEnvironment, X as VitestPackageInstaller, g as WatcherTriggerPattern, Z as WorkspaceSpec, _ as getFilePoolName } from './chunks/reporters.d.BFLkQcL6.js'; +import * as vite from 'vite'; +import { InlineConfig, UserConfig as UserConfig$1, Plugin, ResolvedConfig as ResolvedConfig$1, LogLevel, LoggerOptions, Logger as Logger$1 } from 'vite'; +export { vite as Vite }; +export { esbuildVersion, isCSSRequest, isFileServingAllowed, parseAst, parseAstAsync, rollupVersion, version as viteVersion } from 'vite'; +import { IncomingMessage } from 'node:http'; +import { R as RuntimeRPC } from './chunks/worker.d.1GmBbd7G.js'; +export { T as TestExecutionType } from './chunks/worker.d.1GmBbd7G.js'; +import { Writable } from 'node:stream'; +export { V as VitestPluginContext } from './chunks/vite.d.CMLlLIFP.js'; +export { W as WorkerContext } from './chunks/worker.d.CKwWzBSj.js'; +export { C as TypeCheckCollectLineNumbers, a as TypeCheckCollectLines, c as TypeCheckContext, T as TypeCheckErrorInfo, R as TypeCheckRawErrorsMap, b as TypeCheckRootAndTarget } from './chunks/global.d.MAmajcmJ.js'; +import { Debugger } from 'debug'; +export { Task as RunnerTask, TaskResult as RunnerTaskResult, TaskResultPack as RunnerTaskResultPack, Test as RunnerTestCase, File as RunnerTestFile, Suite as RunnerTestSuite, SequenceHooks, SequenceSetupFiles } from '@vitest/runner'; +export { f as EnvironmentOptions, H as HappyDOMOptions, J as JSDOMOptions } from './chunks/environment.d.cL3nLXbE.js'; +export { SerializedError } from '@vitest/utils'; +export { b as RuntimeConfig } from './chunks/config.d.D2ROskhv.js'; +export { generateFileHash } from '@vitest/runner/utils'; +import 'node:console'; +import '@vitest/mocker'; +import '@vitest/utils/source-map'; +import '@vitest/pretty-format'; +import '@vitest/snapshot'; +import '@vitest/utils/diff'; +import 'vite-node'; +import 'chai'; +import './chunks/benchmark.d.BwvBVTda.js'; +import 'tinybench'; +import './chunks/coverage.d.S9RMNXIe.js'; +import 'vite-node/client'; +import '@vitest/snapshot/manager'; +import 'node:fs'; +import 'node:worker_threads'; +import '@vitest/expect'; +import 'vitest/optional-types.js'; +import '@vitest/snapshot/environment'; + +declare function isValidApiRequest(config: ResolvedConfig, req: IncomingMessage): boolean; + +interface CliOptions extends UserConfig { + /** + * Override the watch mode + */ + run?: boolean; + /** + * Removes colors from the console output + */ + color?: boolean; + /** + * Output collected tests as JSON or to a file + */ + json?: string | boolean; + /** + * Output collected test files only + */ + filesOnly?: boolean; + /** + * Override vite config's configLoader from cli. + * Use `bundle` to bundle the config with esbuild or `runner` (experimental) to process it on the fly (default: `bundle`). + * This is only available with **vite version 6.1.0** and above. + * @experimental + */ + configLoader?: InlineConfig extends { + configLoader?: infer T + } ? T : never; +} +/** +* Start Vitest programmatically +* +* Returns a Vitest instance if initialized successfully. +*/ +declare function startVitest(mode: VitestRunMode, cliFilters?: string[], options?: CliOptions, viteOverrides?: UserConfig$1, vitestOptions?: VitestOptions): Promise; + +interface CliParseOptions { + allowUnknownOptions?: boolean; +} +declare function parseCLI(argv: string | string[], config?: CliParseOptions): { + filter: string[] + options: CliOptions +}; + +declare function resolveApiServerConfig(options: Options, defaultPort: number): ApiConfig | undefined; + +declare function createVitest(mode: VitestRunMode, options: CliOptions, viteOverrides?: UserConfig$1, vitestOptions?: VitestOptions): Promise; + +declare class FilesNotFoundError extends Error { + code: string; + constructor(mode: "test" | "benchmark"); +} +declare class GitNotFoundError extends Error { + code: string; + constructor(); +} + +/** @deprecated use `TestProject` instead */ +type GlobalSetupContext = TestProject; + +declare function VitestPlugin(options?: UserConfig, vitest?: Vitest): Promise; + +// this is only exported as a public function and not used inside vitest +declare function resolveConfig(options?: UserConfig, viteOverrides?: UserConfig$1): Promise<{ + vitestConfig: ResolvedConfig + viteConfig: ResolvedConfig$1 +}>; + +declare function resolveFsAllow(projectRoot: string, rootConfigFile: string | false | undefined): string[]; + +interface MethodsOptions { + cacheFs?: boolean; + // do not report files + collect?: boolean; +} +declare function createMethodsRPC(project: TestProject, options?: MethodsOptions): RuntimeRPC; + +declare class BaseSequencer implements TestSequencer { + protected ctx: Vitest; + constructor(ctx: Vitest); + // async so it can be extended by other sequelizers + shard(files: TestSpecification[]): Promise; + // async so it can be extended by other sequelizers + sort(files: TestSpecification[]): Promise; +} + +declare function registerConsoleShortcuts(ctx: Vitest, stdin: NodeJS.ReadStream | undefined, stdout: NodeJS.WriteStream | Writable): () => void; + +// This is copy-pasted and needs to be synced from time to time. Ideally, Vite's `createLogger` should accept a custom `console` +// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/logger.ts?rgh-link-date=2024-10-16T23%3A29%3A19Z +// When Vitest supports only Vite 6 and above, we can use Vite's `createLogger({ console })` +// https://github.com/vitejs/vite/pull/18379 +declare function createViteLogger(console: Logger, level?: LogLevel, options?: LoggerOptions): Logger$1; + +declare const rootDir: string; +declare const distDir: string; + +declare function createDebugger(namespace: `vitest:${string}`): Debugger | undefined; + +declare const version: string; + +/** @deprecated use `createViteServer` instead */ +declare const createServer: typeof vite.createServer; +declare const createViteServer: typeof vite.createServer; + +/** +* @deprecated Use `TestModule` instead +*/ +declare const TestFile: typeof TestModule; + +/** +* @deprecated Use `ModuleDiagnostic` instead +*/ +type FileDiagnostic = ModuleDiagnostic; + +// rolldownVersion is exported only by rolldown-vite +declare const rolldownVersion: string | undefined; + +export { ApiConfig, BaseSequencer, GitNotFoundError, ModuleDiagnostic, ResolvedConfig, TestFile, TestModule, TestProject, TestSequencer, TestSpecification, FilesNotFoundError as TestsNotFoundError, UserConfig, Vitest, VitestOptions, VitestPlugin, VitestRunMode, TestProject as WorkspaceProject, createDebugger, createMethodsRPC, createServer, createViteLogger, createViteServer, createVitest, distDir, isValidApiRequest, parseCLI, registerConsoleShortcuts, resolveApiServerConfig, resolveConfig, resolveFsAllow, rolldownVersion, rootDir, startVitest, version }; +export type { CliParseOptions, FileDiagnostic, GlobalSetupContext }; diff --git a/node_modules/vitest/dist/node.js b/node_modules/vitest/dist/node.js new file mode 100644 index 0000000000..876d5f932d --- /dev/null +++ b/node_modules/vitest/dist/node.js @@ -0,0 +1,105 @@ +import * as vite from 'vite'; +import { resolveConfig as resolveConfig$1, mergeConfig } from 'vite'; +export { esbuildVersion, isCSSRequest, isFileServingAllowed, parseAst, parseAstAsync, rollupVersion, version as viteVersion } from 'vite'; +import { V as Vitest, a as VitestPlugin, T as TestModule } from './chunks/cli-api.BkDphVBG.js'; +export { G as GitNotFoundError, F as TestsNotFoundError, b as VitestPackageInstaller, e as createViteLogger, c as createVitest, i as isValidApiRequest, d as registerConsoleShortcuts, r as resolveFsAllow, s as startVitest } from './chunks/cli-api.BkDphVBG.js'; +export { p as parseCLI } from './chunks/cac.Cb-PYCCB.js'; +import { r as resolveConfig$2 } from './chunks/coverage.DL5VHqXY.js'; +export { b as BaseSequencer, c as createMethodsRPC, g as getFilePoolName, a as resolveApiServerConfig } from './chunks/coverage.DL5VHqXY.js'; +import { slash, deepClone } from '@vitest/utils'; +import { f as findUp } from './chunks/index.X0nbfr6-.js'; +import { resolve } from 'pathe'; +import { c as configFiles } from './chunks/constants.DnKduX2e.js'; +export { distDir, rootDir } from './path.js'; +import createDebug from 'debug'; +export { generateFileHash } from '@vitest/runner/utils'; +import 'node:fs'; +import './chunks/coverage.DVF1vEu8.js'; +import 'node:path'; +import '@vitest/snapshot/manager'; +import 'vite-node/client'; +import 'vite-node/server'; +import './chunks/index.B521nVV-.js'; +import './chunks/index.VByaPkjc.js'; +import 'node:perf_hooks'; +import '@vitest/utils/source-map'; +import 'tinyrainbow'; +import './chunks/env.D4Lgay0q.js'; +import 'std-env'; +import './chunks/typechecker.DRKU1-1g.js'; +import 'node:os'; +import 'tinyexec'; +import 'node:util'; +import 'node:fs/promises'; +import 'node:console'; +import 'node:stream'; +import 'node:module'; +import 'events'; +import 'https'; +import 'http'; +import 'net'; +import 'tls'; +import 'crypto'; +import 'stream'; +import 'url'; +import 'zlib'; +import 'buffer'; +import './chunks/_commonjsHelpers.BFTU3MAI.js'; +import 'node:crypto'; +import 'node:url'; +import 'picomatch'; +import 'tinyglobby'; +import 'vite-node/utils'; +import '@vitest/mocker/node'; +import './chunks/defaults.B7q_naMc.js'; +import 'magic-string'; +import './chunks/index.BCWujgDG.js'; +import 'node:assert'; +import '@vitest/utils/error'; +import 'node:readline'; +import 'node:process'; +import 'node:v8'; +import 'node:tty'; +import 'node:events'; +import 'tinypool'; +import 'node:worker_threads'; +import 'readline'; + +// this is only exported as a public function and not used inside vitest +async function resolveConfig(options = {}, viteOverrides = {}) { + const root = slash(resolve(options.root || process.cwd())); + const configPath = options.config === false ? false : options.config ? resolve(root, options.config) : await findUp(configFiles, { cwd: root }); + options.config = configPath; + const vitest = new Vitest("test", deepClone(options)); + const config = await resolveConfig$1(mergeConfig({ + configFile: configPath, + mode: options.mode || "test", + plugins: [await VitestPlugin(options, vitest)] + }, mergeConfig(viteOverrides, { root: options.root })), "serve"); + // Reflect just to avoid type error + const updatedOptions = Reflect.get(config, "_vitest"); + const vitestConfig = resolveConfig$2(vitest, updatedOptions, config); + await vitest.close(); + return { + viteConfig: config, + vitestConfig + }; +} + +function createDebugger(namespace) { + const debug = createDebug(namespace); + if (debug.enabled) return debug; +} + +const version = Vitest.version; +/** @deprecated use `createViteServer` instead */ +const createServer = vite.createServer; +const createViteServer = vite.createServer; +/** +* @deprecated Use `TestModule` instead +*/ +const TestFile = TestModule; +// rolldownVersion is exported only by rolldown-vite +const rolldownVersion = vite.rolldownVersion; + +export { TestFile, VitestPlugin, createDebugger, createServer, createViteServer, resolveConfig, rolldownVersion, version }; diff --git a/node_modules/vitest/dist/path.js b/node_modules/vitest/dist/path.js new file mode 100644 index 0000000000..0acf87b088 --- /dev/null +++ b/node_modules/vitest/dist/path.js @@ -0,0 +1,7 @@ +import { resolve } from 'node:path'; +import url from 'node:url'; + +const rootDir = resolve(url.fileURLToPath(import.meta.url), "../../"); +const distDir = resolve(url.fileURLToPath(import.meta.url), "../../dist"); + +export { distDir, rootDir }; diff --git a/node_modules/vitest/dist/reporters.d.ts b/node_modules/vitest/dist/reporters.d.ts new file mode 100644 index 0000000000..129ae97c47 --- /dev/null +++ b/node_modules/vitest/dist/reporters.d.ts @@ -0,0 +1,25 @@ +export { aQ as BaseReporter, aC as BasicReporter, aR as BenchmarkBuiltinReporters, aD as BenchmarkReporter, aE as BenchmarkReportsMap, aS as BuiltinReporterOptions, aT as BuiltinReporters, aF as DefaultReporter, aG as DotReporter, aH as GithubActionsReporter, aI as HangingProcessReporter, aK as JUnitReporter, aU as JsonAssertionResult, aJ as JsonReporter, aV as JsonTestResult, aW as JsonTestResults, aA as ReportedHookContext, o as Reporter, aL as ReportersMap, aM as TapFlatReporter, aN as TapReporter, aB as TestRunEndReason, aO as VerboseBenchmarkReporter, aP as VerboseReporter } from './chunks/reporters.d.BFLkQcL6.js'; +import '@vitest/runner'; +import './chunks/environment.d.cL3nLXbE.js'; +import 'vitest/optional-types.js'; +import '@vitest/utils'; +import 'node:stream'; +import 'vite'; +import 'node:console'; +import '@vitest/mocker'; +import '@vitest/utils/source-map'; +import './chunks/worker.d.1GmBbd7G.js'; +import 'vite-node'; +import './chunks/config.d.D2ROskhv.js'; +import '@vitest/pretty-format'; +import '@vitest/snapshot'; +import '@vitest/snapshot/environment'; +import '@vitest/utils/diff'; +import 'chai'; +import './chunks/benchmark.d.BwvBVTda.js'; +import '@vitest/runner/utils'; +import 'tinybench'; +import './chunks/coverage.d.S9RMNXIe.js'; +import 'vite-node/client'; +import '@vitest/snapshot/manager'; +import 'node:fs'; diff --git a/node_modules/vitest/dist/reporters.js b/node_modules/vitest/dist/reporters.js new file mode 100644 index 0000000000..9289321119 --- /dev/null +++ b/node_modules/vitest/dist/reporters.js @@ -0,0 +1,23 @@ +export { B as BasicReporter, D as DefaultReporter, a as DotReporter, G as GithubActionsReporter, H as HangingProcessReporter, b as JUnitReporter, J as JsonReporter, R as ReportersMap, T as TapFlatReporter, c as TapReporter, V as VerboseReporter } from './chunks/index.VByaPkjc.js'; +export { B as BenchmarkReporter, a as BenchmarkReportsMap, V as VerboseBenchmarkReporter } from './chunks/index.BCWujgDG.js'; +import 'node:perf_hooks'; +import '@vitest/runner/utils'; +import '@vitest/utils'; +import '@vitest/utils/source-map'; +import 'pathe'; +import 'tinyrainbow'; +import './chunks/env.D4Lgay0q.js'; +import 'std-env'; +import './chunks/typechecker.DRKU1-1g.js'; +import 'node:os'; +import 'tinyexec'; +import './path.js'; +import 'node:path'; +import 'node:url'; +import 'vite'; +import 'node:util'; +import 'node:fs'; +import 'node:fs/promises'; +import 'node:console'; +import 'node:stream'; +import 'node:module'; diff --git a/node_modules/vitest/dist/runners.d.ts b/node_modules/vitest/dist/runners.d.ts new file mode 100644 index 0000000000..a7409e087e --- /dev/null +++ b/node_modules/vitest/dist/runners.d.ts @@ -0,0 +1,46 @@ +import * as tinybench from 'tinybench'; +import { VitestRunner, VitestRunnerImportSource, Suite, File, Task, CancelReason, Test, TestContext, ImportDuration } from '@vitest/runner'; +export { VitestRunner } from '@vitest/runner'; +import { a as SerializedConfig } from './chunks/config.d.D2ROskhv.js'; +import '@vitest/pretty-format'; +import '@vitest/snapshot'; +import '@vitest/snapshot/environment'; +import '@vitest/utils/diff'; + +declare class NodeBenchmarkRunner implements VitestRunner { + config: SerializedConfig; + private __vitest_executor; + constructor(config: SerializedConfig); + importTinybench(): Promise; + importFile(filepath: string, source: VitestRunnerImportSource): unknown; + runSuite(suite: Suite): Promise; + runTask(): Promise; +} + +declare class VitestTestRunner implements VitestRunner { + config: SerializedConfig; + private snapshotClient; + private workerState; + private __vitest_executor; + private cancelRun; + private assertionsErrors; + pool: string; + constructor(config: SerializedConfig); + importFile(filepath: string, source: VitestRunnerImportSource): unknown; + onCollectStart(file: File): void; + onCleanupWorkerContext(listener: () => unknown): void; + onAfterRunFiles(): void; + getWorkerContext(): Record; + onAfterRunSuite(suite: Suite): Promise; + onAfterRunTask(test: Task): void; + cancel(_reason: CancelReason): void; + injectValue(key: string): any; + onBeforeRunTask(test: Task): Promise; + onBeforeRunSuite(suite: Suite): Promise; + onBeforeTryTask(test: Task): void; + onAfterTryTask(test: Test): void; + extendTaskContext(context: TestContext): TestContext; + getImportDurations(): Record; +} + +export { NodeBenchmarkRunner, VitestTestRunner }; diff --git a/node_modules/vitest/dist/runners.js b/node_modules/vitest/dist/runners.js new file mode 100644 index 0000000000..8918b257f2 --- /dev/null +++ b/node_modules/vitest/dist/runners.js @@ -0,0 +1,235 @@ +import { updateTask } from '@vitest/runner'; +import { createDefer, getSafeTimers } from '@vitest/utils'; +import { a as getBenchOptions, g as getBenchFn } from './chunks/benchmark.CYdenmiT.js'; +import { g as getWorkerState } from './chunks/utils.XdZDrNZV.js'; +import { setState, GLOBAL_EXPECT, getState } from '@vitest/expect'; +import { getTests, getNames, getTestName } from '@vitest/runner/utils'; +import { normalize } from 'pathe'; +import { g as getSnapshotClient, i as inject, c as createExpect, v as vi } from './chunks/vi.bdSIJ99Y.js'; +import { r as rpc } from './chunks/rpc.-pEldfrD.js'; +import 'chai'; +import './chunks/_commonjsHelpers.BFTU3MAI.js'; +import '@vitest/snapshot'; +import '@vitest/utils/error'; +import '@vitest/spy'; +import '@vitest/utils/source-map'; +import './chunks/date.Bq6ZW5rf.js'; +import './chunks/index.B521nVV-.js'; + +function createBenchmarkResult(name) { + return { + name, + rank: 0, + rme: 0, + samples: [] + }; +} +const benchmarkTasks = /* @__PURE__ */ new WeakMap(); +async function runBenchmarkSuite(suite, runner) { + const { Task, Bench } = await runner.importTinybench(); + const start = performance.now(); + const benchmarkGroup = []; + const benchmarkSuiteGroup = []; + for (const task of suite.tasks) { + if (task.mode !== "run" && task.mode !== "queued") continue; + if (task.meta?.benchmark) benchmarkGroup.push(task); + else if (task.type === "suite") benchmarkSuiteGroup.push(task); + } + // run sub suites sequentially + for (const subSuite of benchmarkSuiteGroup) await runBenchmarkSuite(subSuite, runner); + if (benchmarkGroup.length) { + const defer = createDefer(); + suite.result = { + state: "run", + startTime: start, + benchmark: createBenchmarkResult(suite.name) + }; + updateTask$1("suite-prepare", suite); + const addBenchTaskListener = (task, benchmark) => { + task.addEventListener("complete", (e) => { + const task = e.task; + const taskRes = task.result; + const result = benchmark.result.benchmark; + benchmark.result.state = "pass"; + Object.assign(result, taskRes); + // compute extra stats and free raw samples as early as possible + const samples = result.samples; + result.sampleCount = samples.length; + result.median = samples.length % 2 ? samples[Math.floor(samples.length / 2)] : (samples[samples.length / 2] + samples[samples.length / 2 - 1]) / 2; + if (!runner.config.benchmark?.includeSamples) result.samples.length = 0; + updateTask$1("test-finished", benchmark); + }, { once: true }); + task.addEventListener("error", (e) => { + const task = e.task; + defer.reject(benchmark ? task.result.error : e); + }, { once: true }); + }; + benchmarkGroup.forEach((benchmark) => { + const options = getBenchOptions(benchmark); + const benchmarkInstance = new Bench(options); + const benchmarkFn = getBenchFn(benchmark); + benchmark.result = { + state: "run", + startTime: start, + benchmark: createBenchmarkResult(benchmark.name) + }; + const task = new Task(benchmarkInstance, benchmark.name, benchmarkFn); + benchmarkTasks.set(benchmark, task); + addBenchTaskListener(task, benchmark); + }); + const { setTimeout } = getSafeTimers(); + const tasks = []; + for (const benchmark of benchmarkGroup) { + const task = benchmarkTasks.get(benchmark); + updateTask$1("test-prepare", benchmark); + await task.warmup(); + tasks.push([await new Promise((resolve) => setTimeout(async () => { + resolve(await task.run()); + })), benchmark]); + } + suite.result.duration = performance.now() - start; + suite.result.state = "pass"; + updateTask$1("suite-finished", suite); + defer.resolve(null); + await defer; + } + function updateTask$1(event, task) { + updateTask(event, task, runner); + } +} +class NodeBenchmarkRunner { + __vitest_executor; + constructor(config) { + this.config = config; + } + async importTinybench() { + return await import('tinybench'); + } + importFile(filepath, source) { + if (source === "setup") getWorkerState().moduleCache.delete(filepath); + return this.__vitest_executor.executeId(filepath); + } + async runSuite(suite) { + await runBenchmarkSuite(suite, this); + } + async runTask() { + throw new Error("`test()` and `it()` is only available in test mode."); + } +} + +// worker context is shared between all tests +const workerContext = Object.create(null); +class VitestTestRunner { + snapshotClient = getSnapshotClient(); + workerState = getWorkerState(); + __vitest_executor; + cancelRun = false; + assertionsErrors = /* @__PURE__ */ new WeakMap(); + pool = this.workerState.ctx.pool; + constructor(config) { + this.config = config; + } + importFile(filepath, source) { + if (source === "setup") this.workerState.moduleCache.delete(filepath); + return this.__vitest_executor.executeId(filepath); + } + onCollectStart(file) { + this.workerState.current = file; + } + onCleanupWorkerContext(listener) { + this.workerState.onCleanup(listener); + } + onAfterRunFiles() { + this.snapshotClient.clear(); + this.workerState.current = void 0; + } + getWorkerContext() { + return workerContext; + } + async onAfterRunSuite(suite) { + if (this.config.logHeapUsage && typeof process !== "undefined") suite.result.heap = process.memoryUsage().heapUsed; + if (suite.mode !== "skip" && "filepath" in suite) { + // mark snapshots in skipped tests as not obsolete + for (const test of getTests(suite)) if (test.mode === "skip") { + const name = getNames(test).slice(1).join(" > "); + this.snapshotClient.skipTest(suite.file.filepath, name); + } + const result = await this.snapshotClient.finish(suite.file.filepath); + await rpc().snapshotSaved(result); + } + this.workerState.current = suite.suite || suite.file; + } + onAfterRunTask(test) { + if (this.config.logHeapUsage && typeof process !== "undefined") test.result.heap = process.memoryUsage().heapUsed; + this.workerState.current = test.suite || test.file; + } + cancel(_reason) { + this.cancelRun = true; + } + injectValue(key) { + // inject has a very limiting type controlled by ProvidedContext + // some tests override it which causes the build to fail + return inject(key); + } + async onBeforeRunTask(test) { + if (this.cancelRun) test.mode = "skip"; + if (test.mode !== "run" && test.mode !== "queued") return; + this.workerState.current = test; + } + async onBeforeRunSuite(suite) { + if (this.cancelRun) suite.mode = "skip"; + // initialize snapshot state before running file suite + if (suite.mode !== "skip" && "filepath" in suite) await this.snapshotClient.setup(suite.file.filepath, this.workerState.config.snapshotOptions); + this.workerState.current = suite; + } + onBeforeTryTask(test) { + clearModuleMocks(this.config); + this.snapshotClient.clearTest(test.file.filepath, test.id); + setState({ + assertionCalls: 0, + isExpectingAssertions: false, + isExpectingAssertionsError: null, + expectedAssertionsNumber: null, + expectedAssertionsNumberErrorGen: null, + currentTestName: getTestName(test), + snapshotState: this.snapshotClient.getSnapshotState(test.file.filepath) + }, globalThis[GLOBAL_EXPECT]); + } + onAfterTryTask(test) { + const { assertionCalls, expectedAssertionsNumber, expectedAssertionsNumberErrorGen, isExpectingAssertions, isExpectingAssertionsError } = test.context._local ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]); + if (expectedAssertionsNumber !== null && assertionCalls !== expectedAssertionsNumber) throw expectedAssertionsNumberErrorGen(); + if (isExpectingAssertions === true && assertionCalls === 0) throw isExpectingAssertionsError; + if (this.config.expect.requireAssertions && assertionCalls === 0) throw this.assertionsErrors.get(test); + } + extendTaskContext(context) { + // create error during the test initialization so we have a nice stack trace + if (this.config.expect.requireAssertions) this.assertionsErrors.set(context.task, new Error("expected any number of assertion, but got none")); + let _expect; + Object.defineProperty(context, "expect", { get() { + if (!_expect) _expect = createExpect(context.task); + return _expect; + } }); + Object.defineProperty(context, "_local", { get() { + return _expect != null; + } }); + return context; + } + getImportDurations() { + const entries = [...this.workerState.moduleExecutionInfo?.entries() ?? []]; + return Object.fromEntries(entries.map(([filepath, { duration, selfTime }]) => [normalize(filepath), { + selfTime, + totalTime: duration + }])); + } +} +function clearModuleMocks(config) { + const { clearMocks, mockReset, restoreMocks, unstubEnvs, unstubGlobals } = config; + // since each function calls another, we can just call one + if (restoreMocks) vi.restoreAllMocks(); + else if (mockReset) vi.resetAllMocks(); + else if (clearMocks) vi.clearAllMocks(); + if (unstubEnvs) vi.unstubAllEnvs(); + if (unstubGlobals) vi.unstubAllGlobals(); +} + +export { NodeBenchmarkRunner, VitestTestRunner }; diff --git a/node_modules/vitest/dist/snapshot.d.ts b/node_modules/vitest/dist/snapshot.d.ts new file mode 100644 index 0000000000..966a627668 --- /dev/null +++ b/node_modules/vitest/dist/snapshot.d.ts @@ -0,0 +1,9 @@ +import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment'; +export { SnapshotEnvironment } from '@vitest/snapshot/environment'; + +declare class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment { + getHeader(): string; + resolvePath(filepath: string): Promise; +} + +export { VitestNodeSnapshotEnvironment as VitestSnapshotEnvironment }; diff --git a/node_modules/vitest/dist/snapshot.js b/node_modules/vitest/dist/snapshot.js new file mode 100644 index 0000000000..979896dbac --- /dev/null +++ b/node_modules/vitest/dist/snapshot.js @@ -0,0 +1,4 @@ +export { VitestNodeSnapshotEnvironment as VitestSnapshotEnvironment } from './chunks/node.fjCdwEIl.js'; +import '@vitest/snapshot/environment'; +import './chunks/utils.XdZDrNZV.js'; +import '@vitest/utils'; diff --git a/node_modules/vitest/dist/spy.js b/node_modules/vitest/dist/spy.js new file mode 100644 index 0000000000..d2b1e1d4de --- /dev/null +++ b/node_modules/vitest/dist/spy.js @@ -0,0 +1 @@ +export * from '@vitest/spy'; diff --git a/node_modules/vitest/dist/suite.d.ts b/node_modules/vitest/dist/suite.d.ts new file mode 100644 index 0000000000..74f358d7e1 --- /dev/null +++ b/node_modules/vitest/dist/suite.d.ts @@ -0,0 +1,5 @@ +export { g as getBenchFn, a as getBenchOptions } from './chunks/suite.d.FvehnV49.js'; +export { VitestRunner, VitestRunnerConfig, createTaskCollector, getCurrentSuite, getCurrentTest, getFn, getHooks, setFn, setHooks } from '@vitest/runner'; +export { createChainable } from '@vitest/runner/utils'; +import './chunks/benchmark.d.BwvBVTda.js'; +import 'tinybench'; diff --git a/node_modules/vitest/dist/suite.js b/node_modules/vitest/dist/suite.js new file mode 100644 index 0000000000..778940e42d --- /dev/null +++ b/node_modules/vitest/dist/suite.js @@ -0,0 +1,5 @@ +export { g as getBenchFn, a as getBenchOptions } from './chunks/benchmark.CYdenmiT.js'; +export { createTaskCollector, getCurrentSuite, getCurrentTest, getFn, getHooks, setFn, setHooks } from '@vitest/runner'; +export { createChainable } from '@vitest/runner/utils'; +import '@vitest/utils'; +import './chunks/utils.XdZDrNZV.js'; diff --git a/node_modules/vitest/dist/worker.js b/node_modules/vitest/dist/worker.js new file mode 100644 index 0000000000..91b87b2740 --- /dev/null +++ b/node_modules/vitest/dist/worker.js @@ -0,0 +1,124 @@ +import { pathToFileURL } from 'node:url'; +import { createStackString, parseStacktrace } from '@vitest/utils/source-map'; +import { workerId } from 'tinypool'; +import { ViteNodeRunner, ModuleCacheMap } from 'vite-node/client'; +import { readFileSync } from 'node:fs'; +import { resolve, normalize } from 'pathe'; +import { e as environments } from './chunks/index.CmSc2RE5.js'; +import { s as setupInspect } from './chunks/inspector.C914Efll.js'; +import { c as createRuntimeRpc, a as rpcDone } from './chunks/rpc.-pEldfrD.js'; +import { i as isChildProcess, s as setProcessTitle } from './chunks/utils.XdZDrNZV.js'; +import { d as disposeInternalListeners } from './chunks/utils.CAioKnHs.js'; +import 'node:console'; +import 'node:module'; +import '@vitest/utils'; +import './chunks/index.B521nVV-.js'; + +function isBuiltinEnvironment(env) { + return env in environments; +} +const _loaders = /* @__PURE__ */ new Map(); +async function createEnvironmentLoader(options) { + if (!_loaders.has(options.root)) { + const loader = new ViteNodeRunner(options); + await loader.executeId("/@vite/env"); + _loaders.set(options.root, loader); + } + return _loaders.get(options.root); +} +async function loadEnvironment(ctx, rpc) { + const name = ctx.environment.name; + if (isBuiltinEnvironment(name)) return environments[name]; + const loader = await createEnvironmentLoader({ + root: ctx.config.root, + fetchModule: async (id) => { + const result = await rpc.fetch(id, "ssr"); + if (result.id) return { code: readFileSync(result.id, "utf-8") }; + return result; + }, + resolveId: (id, importer) => rpc.resolveId(id, importer, "ssr") + }); + const root = loader.root; + const packageId = name[0] === "." || name[0] === "/" ? resolve(root, name) : (await rpc.resolveId(`vitest-environment-${name}`, void 0, "ssr"))?.id ?? resolve(root, name); + const pkg = await loader.executeId(normalize(packageId)); + if (!pkg || !pkg.default || typeof pkg.default !== "object") throw new TypeError(`Environment "${name}" is not a valid environment. Path "${packageId}" should export default object with a "setup" or/and "setupVM" method.`); + const environment = pkg.default; + if (environment.transformMode !== "web" && environment.transformMode !== "ssr") throw new TypeError(`Environment "${name}" is not a valid environment. Path "${packageId}" should export default object with a "transformMode" method equal to "ssr" or "web".`); + return environment; +} + +const listeners = /* @__PURE__ */ new Set(); +function addCleanupListener(listener) { + listeners.add(listener); +} +async function cleanup() { + const promises = [...listeners].map((l) => l()); + await Promise.all(promises); +} + +if (isChildProcess()) { + setProcessTitle(`vitest ${workerId}`); + const isProfiling = process.execArgv.some((execArg) => execArg.startsWith("--prof") || execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir")); + if (isProfiling) + // Work-around for nodejs/node#55094 + process.on("SIGTERM", () => { + process.exit(); + }); +} +// this is what every pool executes when running tests +async function execute(method, ctx) { + disposeInternalListeners(); + const prepareStart = performance.now(); + const inspectorCleanup = setupInspect(ctx); + process.env.VITEST_WORKER_ID = String(ctx.workerId); + process.env.VITEST_POOL_ID = String(workerId); + try { + // worker is a filepath or URL to a file that exposes a default export with "getRpcOptions" and "runTests" methods + if (ctx.worker[0] === ".") throw new Error(`Path to the test runner cannot be relative, received "${ctx.worker}"`); + const file = ctx.worker.startsWith("file:") ? ctx.worker : pathToFileURL(ctx.worker).toString(); + const testRunnerModule = await import(file); + if (!testRunnerModule.default || typeof testRunnerModule.default !== "object") throw new TypeError(`Test worker object should be exposed as a default export. Received "${typeof testRunnerModule.default}"`); + const worker = testRunnerModule.default; + if (!worker.getRpcOptions || typeof worker.getRpcOptions !== "function") throw new TypeError(`Test worker should expose "getRpcOptions" method. Received "${typeof worker.getRpcOptions}".`); + // RPC is used to communicate between worker (be it a thread worker or child process or a custom implementation) and the main thread + const { rpc, onCancel } = createRuntimeRpc(worker.getRpcOptions(ctx)); + const beforeEnvironmentTime = performance.now(); + const environment = await loadEnvironment(ctx, rpc); + if (ctx.environment.transformMode) environment.transformMode = ctx.environment.transformMode; + const state = { + ctx, + moduleCache: new ModuleCacheMap(), + moduleExecutionInfo: /* @__PURE__ */ new Map(), + config: ctx.config, + onCancel, + environment, + durations: { + environment: beforeEnvironmentTime, + prepare: prepareStart + }, + rpc, + onCleanup: (listener) => addCleanupListener(listener), + providedContext: ctx.providedContext, + onFilterStackTrace(stack) { + return createStackString(parseStacktrace(stack)); + } + }; + const methodName = method === "collect" ? "collectTests" : "runTests"; + if (!worker[methodName] || typeof worker[methodName] !== "function") throw new TypeError(`Test worker should expose "runTests" method. Received "${typeof worker.runTests}".`); + await worker[methodName](state); + } finally { + await rpcDone().catch(() => {}); + inspectorCleanup(); + } +} +function run(ctx) { + return execute("run", ctx); +} +function collect(ctx) { + return execute("collect", ctx); +} +async function teardown() { + return cleanup(); +} + +export { collect, run, teardown }; diff --git a/node_modules/vitest/dist/workers.d.ts b/node_modules/vitest/dist/workers.d.ts new file mode 100644 index 0000000000..b6f2957c85 --- /dev/null +++ b/node_modules/vitest/dist/workers.d.ts @@ -0,0 +1,40 @@ +import { W as WorkerGlobalState, C as ContextRPC, B as BirpcOptions, R as RuntimeRPC } from './chunks/worker.d.1GmBbd7G.js'; +import { Awaitable } from '@vitest/utils'; +import * as v8 from 'v8'; +import { a as SerializedConfig } from './chunks/config.d.D2ROskhv.js'; +import { W as WorkerContext } from './chunks/worker.d.CKwWzBSj.js'; +import '@vitest/runner'; +import 'vite-node'; +import './chunks/environment.d.cL3nLXbE.js'; +import 'vitest/optional-types.js'; +import '@vitest/snapshot'; +import '@vitest/pretty-format'; +import '@vitest/snapshot/environment'; +import '@vitest/utils/diff'; +import 'node:worker_threads'; + +declare function provideWorkerState(context: any, state: WorkerGlobalState): WorkerGlobalState; + +declare function run(ctx: ContextRPC): Promise; +declare function collect(ctx: ContextRPC): Promise; + +declare function runBaseTests(method: "run" | "collect", state: WorkerGlobalState): Promise; + +type WorkerRpcOptions = Pick, "on" | "post" | "serialize" | "deserialize">; +interface VitestWorker { + getRpcOptions: (ctx: ContextRPC) => WorkerRpcOptions; + runTests: (state: WorkerGlobalState) => Awaitable; + collectTests: (state: WorkerGlobalState) => Awaitable; +} + +declare function createThreadsRpcOptions({ port }: WorkerContext): WorkerRpcOptions; +declare function createForksRpcOptions(nodeV8: typeof v8): WorkerRpcOptions; +/** +* Reverts the wrapping done by `utils/config-helpers.ts`'s `wrapSerializableConfig` +*/ +declare function unwrapSerializableConfig(config: SerializedConfig): SerializedConfig; + +declare function runVmTests(method: "run" | "collect", state: WorkerGlobalState): Promise; + +export { collect as collectVitestWorkerTests, createForksRpcOptions, createThreadsRpcOptions, provideWorkerState, runBaseTests, run as runVitestWorker, runVmTests, unwrapSerializableConfig }; +export type { VitestWorker, WorkerRpcOptions }; diff --git a/node_modules/vitest/dist/workers.js b/node_modules/vitest/dist/workers.js new file mode 100644 index 0000000000..4a15f78f1e --- /dev/null +++ b/node_modules/vitest/dist/workers.js @@ -0,0 +1,30 @@ +export { p as provideWorkerState } from './chunks/utils.XdZDrNZV.js'; +export { collect as collectVitestWorkerTests, run as runVitestWorker } from './worker.js'; +export { r as runBaseTests } from './chunks/base.DfmxU-tU.js'; +export { c as createForksRpcOptions, a as createThreadsRpcOptions, u as unwrapSerializableConfig } from './chunks/utils.CAioKnHs.js'; +export { r as runVmTests } from './chunks/vm.BThCzidc.js'; +import '@vitest/utils'; +import 'node:url'; +import '@vitest/utils/source-map'; +import 'tinypool'; +import 'vite-node/client'; +import 'node:fs'; +import 'pathe'; +import './chunks/index.CmSc2RE5.js'; +import 'node:console'; +import './chunks/inspector.C914Efll.js'; +import 'node:module'; +import './chunks/rpc.-pEldfrD.js'; +import './chunks/index.B521nVV-.js'; +import './chunks/execute.B7h3T_Hc.js'; +import 'node:vm'; +import '@vitest/utils/error'; +import 'vite-node/utils'; +import './path.js'; +import 'node:path'; +import '@vitest/mocker'; +import './chunks/console.CtFJOzRO.js'; +import 'node:stream'; +import 'tinyrainbow'; +import './chunks/date.Bq6ZW5rf.js'; +import 'vite-node/constants'; diff --git a/node_modules/vitest/dist/workers/forks.js b/node_modules/vitest/dist/workers/forks.js new file mode 100644 index 0000000000..6fedd2fdb1 --- /dev/null +++ b/node_modules/vitest/dist/workers/forks.js @@ -0,0 +1,43 @@ +import v8 from 'node:v8'; +import { r as runBaseTests } from '../chunks/base.DfmxU-tU.js'; +import { c as createForksRpcOptions, u as unwrapSerializableConfig } from '../chunks/utils.CAioKnHs.js'; +import 'vite-node/client'; +import '../chunks/execute.B7h3T_Hc.js'; +import 'node:fs'; +import 'node:url'; +import 'node:vm'; +import '@vitest/utils/error'; +import 'pathe'; +import 'vite-node/utils'; +import '../path.js'; +import 'node:path'; +import '@vitest/mocker'; +import 'node:module'; +import '@vitest/utils'; +import '../chunks/utils.XdZDrNZV.js'; + +class ForksBaseWorker { + getRpcOptions() { + return createForksRpcOptions(v8); + } + async executeTests(method, state) { + // TODO: don't rely on reassigning process.exit + // https://github.com/vitest-dev/vitest/pull/4441#discussion_r1443771486 + const exit = process.exit; + state.ctx.config = unwrapSerializableConfig(state.ctx.config); + try { + await runBaseTests(method, state); + } finally { + process.exit = exit; + } + } + runTests(state) { + return this.executeTests("run", state); + } + collectTests(state) { + return this.executeTests("collect", state); + } +} +const worker = new ForksBaseWorker(); + +export { worker as default }; diff --git a/node_modules/vitest/dist/workers/runVmTests.js b/node_modules/vitest/dist/workers/runVmTests.js new file mode 100644 index 0000000000..6c89cd51f7 --- /dev/null +++ b/node_modules/vitest/dist/workers/runVmTests.js @@ -0,0 +1,90 @@ +import { createRequire } from 'node:module'; +import { performance } from 'node:perf_hooks'; +import timers from 'node:timers'; +import timersPromises from 'node:timers/promises'; +import util from 'node:util'; +import { startTests, collectTests } from '@vitest/runner'; +import { KNOWN_ASSET_TYPES } from 'vite-node/constants'; +import { installSourcemapsSupport } from 'vite-node/source-map'; +import { s as setupChaiConfig, r as resolveTestRunner, a as resolveSnapshotEnvironment } from '../chunks/index.CwejwG0H.js'; +import { c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker } from '../chunks/setup-common.Dd054P77.js'; +import { V as VitestIndex } from '../chunks/index.CdQS2e2Q.js'; +import { c as closeInspector } from '../chunks/inspector.C914Efll.js'; +import { g as getWorkerState } from '../chunks/utils.XdZDrNZV.js'; +import 'chai'; +import 'node:path'; +import '../path.js'; +import 'node:url'; +import '../chunks/rpc.-pEldfrD.js'; +import '@vitest/utils'; +import '../chunks/index.B521nVV-.js'; +import '../chunks/coverage.DVF1vEu8.js'; +import '@vitest/snapshot'; +import '../chunks/vi.bdSIJ99Y.js'; +import '@vitest/expect'; +import '@vitest/runner/utils'; +import '../chunks/_commonjsHelpers.BFTU3MAI.js'; +import '@vitest/utils/error'; +import '@vitest/spy'; +import '@vitest/utils/source-map'; +import '../chunks/date.Bq6ZW5rf.js'; +import '../chunks/benchmark.CYdenmiT.js'; +import 'expect-type'; + +async function run(method, files, config, executor) { + const workerState = getWorkerState(); + await setupCommonEnv(config); + Object.defineProperty(globalThis, "__vitest_index__", { + value: VitestIndex, + enumerable: false + }); + if (workerState.environment.transformMode === "web") { + const _require = createRequire(import.meta.url); + // always mock "required" `css` files, because we cannot process them + _require.extensions[".css"] = resolveCss; + _require.extensions[".scss"] = resolveCss; + _require.extensions[".sass"] = resolveCss; + _require.extensions[".less"] = resolveCss; + // since we are using Vite, we can assume how these will be resolved + KNOWN_ASSET_TYPES.forEach((type) => { + _require.extensions[`.${type}`] = resolveAsset; + }); + process.env.SSR = ""; + } else process.env.SSR = "1"; + // @ts-expect-error not typed global for patched timers + globalThis.__vitest_required__ = { + util, + timers, + timersPromises + }; + installSourcemapsSupport({ getSourceMap: (source) => workerState.moduleCache.getSourceMap(source) }); + await startCoverageInsideWorker(config.coverage, executor, { isolate: false }); + if (config.chaiConfig) setupChaiConfig(config.chaiConfig); + const [runner, snapshotEnvironment] = await Promise.all([resolveTestRunner(config, executor), resolveSnapshotEnvironment(config, executor)]); + config.snapshotOptions.snapshotEnvironment = snapshotEnvironment; + runner.getWorkerContext = void 0; + workerState.onCancel.then((reason) => { + closeInspector(config); + runner.cancel?.(reason); + }); + workerState.durations.prepare = performance.now() - workerState.durations.prepare; + const { vi } = VitestIndex; + for (const file of files) { + workerState.filepath = file.filepath; + if (method === "run") await startTests([file], runner); + else await collectTests([file], runner); + // reset after tests, because user might call `vi.setConfig` in setupFile + vi.resetConfig(); + // mocks should not affect different files + vi.restoreAllMocks(); + } + await stopCoverageInsideWorker(config.coverage, executor, { isolate: false }); +} +function resolveCss(mod) { + mod.exports = ""; +} +function resolveAsset(mod, url) { + mod.exports = url; +} + +export { run }; diff --git a/node_modules/vitest/dist/workers/threads.js b/node_modules/vitest/dist/workers/threads.js new file mode 100644 index 0000000000..c984ac4923 --- /dev/null +++ b/node_modules/vitest/dist/workers/threads.js @@ -0,0 +1,31 @@ +import { r as runBaseTests } from '../chunks/base.DfmxU-tU.js'; +import { a as createThreadsRpcOptions } from '../chunks/utils.CAioKnHs.js'; +import 'vite-node/client'; +import '../chunks/execute.B7h3T_Hc.js'; +import 'node:fs'; +import 'node:url'; +import 'node:vm'; +import '@vitest/utils/error'; +import 'pathe'; +import 'vite-node/utils'; +import '../path.js'; +import 'node:path'; +import '@vitest/mocker'; +import 'node:module'; +import '@vitest/utils'; +import '../chunks/utils.XdZDrNZV.js'; + +class ThreadsBaseWorker { + getRpcOptions(ctx) { + return createThreadsRpcOptions(ctx); + } + runTests(state) { + return runBaseTests("run", state); + } + collectTests(state) { + return runBaseTests("collect", state); + } +} +const worker = new ThreadsBaseWorker(); + +export { worker as default }; diff --git a/node_modules/vitest/dist/workers/vmForks.js b/node_modules/vitest/dist/workers/vmForks.js new file mode 100644 index 0000000000..3ea9afa197 --- /dev/null +++ b/node_modules/vitest/dist/workers/vmForks.js @@ -0,0 +1,47 @@ +import v8 from 'node:v8'; +import { c as createForksRpcOptions, u as unwrapSerializableConfig } from '../chunks/utils.CAioKnHs.js'; +import { r as runVmTests } from '../chunks/vm.BThCzidc.js'; +import '@vitest/utils'; +import 'node:url'; +import 'node:vm'; +import 'pathe'; +import '../path.js'; +import 'node:path'; +import '../chunks/console.CtFJOzRO.js'; +import 'node:console'; +import 'node:stream'; +import 'tinyrainbow'; +import '../chunks/date.Bq6ZW5rf.js'; +import '../chunks/utils.XdZDrNZV.js'; +import '../chunks/execute.B7h3T_Hc.js'; +import 'node:fs'; +import '@vitest/utils/error'; +import 'vite-node/client'; +import 'vite-node/utils'; +import '@vitest/mocker'; +import 'node:module'; +import 'vite-node/constants'; + +class ForksVmWorker { + getRpcOptions() { + return createForksRpcOptions(v8); + } + async executeTests(method, state) { + const exit = process.exit; + state.ctx.config = unwrapSerializableConfig(state.ctx.config); + try { + await runVmTests(method, state); + } finally { + process.exit = exit; + } + } + runTests(state) { + return this.executeTests("run", state); + } + collectTests(state) { + return this.executeTests("collect", state); + } +} +const worker = new ForksVmWorker(); + +export { worker as default }; diff --git a/node_modules/vitest/dist/workers/vmThreads.js b/node_modules/vitest/dist/workers/vmThreads.js new file mode 100644 index 0000000000..b7a89af21a --- /dev/null +++ b/node_modules/vitest/dist/workers/vmThreads.js @@ -0,0 +1,37 @@ +import { a as createThreadsRpcOptions } from '../chunks/utils.CAioKnHs.js'; +import { r as runVmTests } from '../chunks/vm.BThCzidc.js'; +import '@vitest/utils'; +import 'node:url'; +import 'node:vm'; +import 'pathe'; +import '../path.js'; +import 'node:path'; +import '../chunks/console.CtFJOzRO.js'; +import 'node:console'; +import 'node:stream'; +import 'tinyrainbow'; +import '../chunks/date.Bq6ZW5rf.js'; +import '../chunks/utils.XdZDrNZV.js'; +import '../chunks/execute.B7h3T_Hc.js'; +import 'node:fs'; +import '@vitest/utils/error'; +import 'vite-node/client'; +import 'vite-node/utils'; +import '@vitest/mocker'; +import 'node:module'; +import 'vite-node/constants'; + +class ThreadsVmWorker { + getRpcOptions(ctx) { + return createThreadsRpcOptions(ctx); + } + runTests(state) { + return runVmTests("run", state); + } + collectTests(state) { + return runVmTests("collect", state); + } +} +const worker = new ThreadsVmWorker(); + +export { worker as default }; diff --git a/node_modules/vitest/environments.d.ts b/node_modules/vitest/environments.d.ts new file mode 100644 index 0000000000..9758d6e8de --- /dev/null +++ b/node_modules/vitest/environments.d.ts @@ -0,0 +1 @@ +export * from './dist/environments' diff --git a/node_modules/vitest/execute.d.ts b/node_modules/vitest/execute.d.ts new file mode 100644 index 0000000000..9901479f9a --- /dev/null +++ b/node_modules/vitest/execute.d.ts @@ -0,0 +1 @@ +export * from './dist/execute.js' diff --git a/node_modules/vitest/globals.d.ts b/node_modules/vitest/globals.d.ts new file mode 100644 index 0000000000..828e85277f --- /dev/null +++ b/node_modules/vitest/globals.d.ts @@ -0,0 +1,20 @@ +declare global { + const suite: typeof import('vitest')['suite'] + const test: typeof import('vitest')['test'] + const chai: typeof import("vitest")["chai"] + const describe: typeof import('vitest')['describe'] + const it: typeof import('vitest')['it'] + const expectTypeOf: typeof import('vitest')['expectTypeOf'] + const assertType: typeof import('vitest')['assertType'] + const expect: typeof import('vitest')['expect'] + const assert: typeof import('vitest')['assert'] + const vitest: typeof import('vitest')['vitest'] + const vi: typeof import('vitest')['vitest'] + const beforeAll: typeof import('vitest')['beforeAll'] + const afterAll: typeof import('vitest')['afterAll'] + const beforeEach: typeof import('vitest')['beforeEach'] + const afterEach: typeof import('vitest')['afterEach'] + const onTestFailed: typeof import('vitest')['onTestFailed'] + const onTestFinished: typeof import('vitest')['onTestFinished'] +} +export {} diff --git a/node_modules/vitest/import-meta.d.ts b/node_modules/vitest/import-meta.d.ts new file mode 100644 index 0000000000..ee00ff5d04 --- /dev/null +++ b/node_modules/vitest/import-meta.d.ts @@ -0,0 +1,5 @@ +/// + +// https://github.com/microsoft/TypeScript/issues/45096 +// TypeScript has a bug that makes +// not possible in userland. This file provides a workaround for now. diff --git a/node_modules/vitest/importMeta.d.ts b/node_modules/vitest/importMeta.d.ts new file mode 100644 index 0000000000..6892126774 --- /dev/null +++ b/node_modules/vitest/importMeta.d.ts @@ -0,0 +1,4 @@ +interface ImportMeta { + url: string + readonly vitest?: typeof import('vitest') +} diff --git a/node_modules/vitest/index.cjs b/node_modules/vitest/index.cjs new file mode 100644 index 0000000000..85fc303f76 --- /dev/null +++ b/node_modules/vitest/index.cjs @@ -0,0 +1,5 @@ +throw new Error( + 'Vitest cannot be imported in a CommonJS module using require(). Please use "import" instead.' + + '\n\nIf you are using "import" in your source code, then it\'s possible it was bundled into require() automatically by your bundler. ' + + 'In that case, do not bundle CommonJS output since it will never work with Vitest, or use dynamic import() which is available in all CommonJS modules.', +) diff --git a/node_modules/vitest/index.d.cts b/node_modules/vitest/index.d.cts new file mode 100644 index 0000000000..09e9c9b2a2 --- /dev/null +++ b/node_modules/vitest/index.d.cts @@ -0,0 +1 @@ +export * from './dist/index.js' diff --git a/node_modules/vitest/jsdom.d.ts b/node_modules/vitest/jsdom.d.ts new file mode 100644 index 0000000000..723af9d426 --- /dev/null +++ b/node_modules/vitest/jsdom.d.ts @@ -0,0 +1,6 @@ +import type { JSDOM } from 'jsdom' + +declare global { + const jsdom: JSDOM +} +export {} diff --git a/node_modules/vitest/mocker.d.ts b/node_modules/vitest/mocker.d.ts new file mode 100644 index 0000000000..38df3da192 --- /dev/null +++ b/node_modules/vitest/mocker.d.ts @@ -0,0 +1 @@ +export * from './dist/mocker.js' diff --git a/node_modules/vitest/node.d.ts b/node_modules/vitest/node.d.ts new file mode 100644 index 0000000000..18975f6e88 --- /dev/null +++ b/node_modules/vitest/node.d.ts @@ -0,0 +1 @@ +export * from './dist/node.js' diff --git a/node_modules/vitest/optional-types.d.ts b/node_modules/vitest/optional-types.d.ts new file mode 100644 index 0000000000..49cdb4fae8 --- /dev/null +++ b/node_modules/vitest/optional-types.d.ts @@ -0,0 +1,7 @@ +/* eslint-disable ts/ban-ts-comment */ + +// @ts-ignore optional peer dep +export type * as jsdomTypes from 'jsdom' + +// @ts-ignore optional peer dep +export type * as happyDomTypes from 'happy-dom' diff --git a/node_modules/vitest/package.json b/node_modules/vitest/package.json new file mode 100644 index 0000000000..6990d4d57f --- /dev/null +++ b/node_modules/vitest/package.json @@ -0,0 +1,207 @@ +{ + "name": "vitest", + "type": "module", + "version": "3.2.4", + "description": "Next generation testing framework powered by Vite", + "author": "Anthony Fu ", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/vitest" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "keywords": [ + "vite", + "vitest", + "test", + "jest" + ], + "sideEffects": false, + "exports": { + ".": { + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "require": { + "types": "./index.d.cts", + "default": "./index.cjs" + } + }, + "./*": "./*", + "./globals": { + "types": "./globals.d.ts" + }, + "./jsdom": { + "types": "./jsdom.d.ts" + }, + "./importMeta": { + "types": "./importMeta.d.ts" + }, + "./import-meta": { + "types": "./import-meta.d.ts" + }, + "./node": { + "types": "./dist/node.d.ts", + "default": "./dist/node.js" + }, + "./execute": { + "types": "./dist/execute.d.ts", + "default": "./dist/execute.js" + }, + "./workers": { + "types": "./dist/workers.d.ts", + "import": "./dist/workers.js" + }, + "./internal/browser": { + "types": "./dist/browser.d.ts", + "default": "./dist/browser.js" + }, + "./runners": { + "types": "./dist/runners.d.ts", + "default": "./dist/runners.js" + }, + "./suite": { + "types": "./dist/suite.d.ts", + "default": "./dist/suite.js" + }, + "./environments": { + "types": "./dist/environments.d.ts", + "default": "./dist/environments.js" + }, + "./config": { + "types": "./config.d.ts", + "require": "./dist/config.cjs", + "default": "./dist/config.js" + }, + "./coverage": { + "types": "./coverage.d.ts", + "default": "./dist/coverage.js" + }, + "./reporters": { + "types": "./dist/reporters.d.ts", + "default": "./dist/reporters.js" + }, + "./snapshot": { + "types": "./dist/snapshot.d.ts", + "default": "./dist/snapshot.js" + }, + "./mocker": { + "types": "./dist/mocker.d.ts", + "default": "./dist/mocker.js" + } + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "bin": { + "vitest": "./vitest.mjs" + }, + "files": [ + "*.cjs", + "*.d.cts", + "*.d.ts", + "*.mjs", + "bin", + "dist" + ], + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "happy-dom": "*", + "jsdom": "*", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + }, + "dependencies": { + "@types/chai": "^5.2.2", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "why-is-node-running": "^2.3.0", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/spy": "3.2.4", + "vite-node": "3.2.4", + "@vitest/utils": "3.2.4" + }, + "devDependencies": { + "@ampproject/remapping": "^2.3.0", + "@antfu/install-pkg": "^1.1.0", + "@edge-runtime/vm": "^5.0.0", + "@sinonjs/fake-timers": "14.0.0", + "@types/debug": "^4.1.12", + "@types/estree": "^1.0.8", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/jsdom": "^21.1.7", + "@types/mime": "^4.0.0", + "@types/node": "^22.15.32", + "@types/picomatch": "^4.0.0", + "@types/prompts": "^2.4.9", + "@types/sinonjs__fake-timers": "^8.1.5", + "acorn-walk": "^8.3.4", + "birpc": "2.4.0", + "cac": "^6.7.14", + "chai-subset": "^1.6.0", + "find-up": "^6.3.0", + "flatted": "^3.3.3", + "happy-dom": "^17.6.3", + "jsdom": "^26.1.0", + "local-pkg": "^1.1.1", + "mime": "^4.0.7", + "pretty-format": "^29.7.0", + "prompts": "^2.4.2", + "strip-literal": "^3.0.0", + "ws": "^8.18.2" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "NODE_OPTIONS=\"--max-old-space-size=8192\" rollup -c --watch -m inline" + } +} \ No newline at end of file diff --git a/node_modules/vitest/reporters.d.ts b/node_modules/vitest/reporters.d.ts new file mode 100644 index 0000000000..5fe5fe7e27 --- /dev/null +++ b/node_modules/vitest/reporters.d.ts @@ -0,0 +1 @@ +export * from './dist/reporters.js' diff --git a/node_modules/vitest/runners.d.ts b/node_modules/vitest/runners.d.ts new file mode 100644 index 0000000000..0477c34a9a --- /dev/null +++ b/node_modules/vitest/runners.d.ts @@ -0,0 +1 @@ +export * from './dist/runners.js' diff --git a/node_modules/vitest/snapshot.d.ts b/node_modules/vitest/snapshot.d.ts new file mode 100644 index 0000000000..e032fa7897 --- /dev/null +++ b/node_modules/vitest/snapshot.d.ts @@ -0,0 +1 @@ +export * from './dist/snapshot.js' diff --git a/node_modules/vitest/suite.d.ts b/node_modules/vitest/suite.d.ts new file mode 100644 index 0000000000..9465dc5c11 --- /dev/null +++ b/node_modules/vitest/suite.d.ts @@ -0,0 +1 @@ +export * from './dist/suite.js' diff --git a/node_modules/vitest/suppress-warnings.cjs b/node_modules/vitest/suppress-warnings.cjs new file mode 100644 index 0000000000..65a3106e3c --- /dev/null +++ b/node_modules/vitest/suppress-warnings.cjs @@ -0,0 +1,21 @@ +// borrowed from tsx implementation: +// https://github.com/esbuild-kit/tsx + +const ignoreWarnings = new Set([ + '--experimental-loader is an experimental feature. This feature could change at any time', + 'Custom ESM Loaders is an experimental feature. This feature could change at any time', + 'Custom ESM Loaders is an experimental feature and might change at any time', + 'VM Modules is an experimental feature and might change at any time', + 'VM Modules is an experimental feature. This feature could change at any time', +]) + +const { emit } = process + +process.emit = function (event, warning) { + if (event === 'warning' && ignoreWarnings.has(warning.message)) { + return + } + + // eslint-disable-next-line prefer-rest-params + return Reflect.apply(emit, this, arguments) +} diff --git a/node_modules/vitest/utils.d.ts b/node_modules/vitest/utils.d.ts new file mode 100644 index 0000000000..e3f344e48a --- /dev/null +++ b/node_modules/vitest/utils.d.ts @@ -0,0 +1 @@ +export * from './dist/utils.js' diff --git a/node_modules/vitest/vitest.mjs b/node_modules/vitest/vitest.mjs new file mode 100755 index 0000000000..02dd4714b9 --- /dev/null +++ b/node_modules/vitest/vitest.mjs @@ -0,0 +1,2 @@ +#!/usr/bin/env node +import './dist/cli.js' diff --git a/node_modules/vitest/workers.d.ts b/node_modules/vitest/workers.d.ts new file mode 100644 index 0000000000..84e3490339 --- /dev/null +++ b/node_modules/vitest/workers.d.ts @@ -0,0 +1 @@ +export * from './dist/workers.js' diff --git a/node_modules/why-is-node-running/.github/FUNDING.yml b/node_modules/why-is-node-running/.github/FUNDING.yml new file mode 100644 index 0000000000..90f7f20b1a --- /dev/null +++ b/node_modules/why-is-node-running/.github/FUNDING.yml @@ -0,0 +1 @@ +github: mafintosh diff --git a/node_modules/why-is-node-running/LICENSE b/node_modules/why-is-node-running/LICENSE new file mode 100644 index 0000000000..bae9da7bfa --- /dev/null +++ b/node_modules/why-is-node-running/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Mathias Buus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/why-is-node-running/README.md b/node_modules/why-is-node-running/README.md new file mode 100644 index 0000000000..d5e4c54574 --- /dev/null +++ b/node_modules/why-is-node-running/README.md @@ -0,0 +1,104 @@ +# why-is-node-running + +Node is running but you don't know why? `why-is-node-running` is here to help you. + +## Installation + +Node 8 and above: + +```bash +npm i why-is-node-running -g +``` + +Earlier Node versions (no longer supported): + +```bash +npm i why-is-node-running@v1.x -g +``` + +## Usage + +```js +const log = require('why-is-node-running') // should be your first require +const net = require('net') + +function createServer () { + const server = net.createServer() + setInterval(function () {}, 1000) + server.listen(0) +} + +createServer() +createServer() + +setTimeout(function () { + log() // logs out active handles that are keeping node running +}, 100) +``` + +Save the file as `example.js`, then execute: + +```bash +node ./example.js +``` + +Here's the output: + +``` +There are 5 handle(s) keeping the process running + +# Timeout +/home/maf/dev/node_modules/why-is-node-running/example.js:6 - setInterval(function () {}, 1000) +/home/maf/dev/node_modules/why-is-node-running/example.js:10 - createServer() + +# TCPSERVERWRAP +/home/maf/dev/node_modules/why-is-node-running/example.js:7 - server.listen(0) +/home/maf/dev/node_modules/why-is-node-running/example.js:10 - createServer() + +# Timeout +/home/maf/dev/node_modules/why-is-node-running/example.js:6 - setInterval(function () {}, 1000) +/home/maf/dev/node_modules/why-is-node-running/example.js:11 - createServer() + +# TCPSERVERWRAP +/home/maf/dev/node_modules/why-is-node-running/example.js:7 - server.listen(0) +/home/maf/dev/node_modules/why-is-node-running/example.js:11 - createServer() + +# Timeout +/home/maf/dev/node_modules/why-is-node-running/example.js:13 - setTimeout(function () { +``` + +**Important Note!** +`unref`ed timers do not prevent the Node process from exiting. If you are running with Node v11.0.0 and above, `unref`ed timers will not be listed in the above list. Unfortunately, this is not supported in node versions below v11.0.0. + +## CLI + +You can also run `why-is-node-running` as a standalone if you don't want to include it inside your code. Sending `SIGUSR1`/`SIGINFO` signal to the process will produce the log. (`Ctrl + T` on macOS and BSD systems) + +```bash +why-is-node-running /path/to/some/file.js +``` + +``` +probing module /path/to/some/file.js +kill -SIGUSR1 31115 for logging +``` + +To trigger the log: + +``` +kill -SIGUSR1 31115 +``` + +## Require CLI Option + +You can also use the node `-r` option to include `why-is-node-running`: + +```bash +node -r why-is-node-running/include /path/to/some/file.js +``` + +The steps are otherwise the same as the above CLI section + +## License + +MIT diff --git a/node_modules/why-is-node-running/cli.js b/node_modules/why-is-node-running/cli.js new file mode 100755 index 0000000000..15cf2b9147 --- /dev/null +++ b/node_modules/why-is-node-running/cli.js @@ -0,0 +1,18 @@ +#!/usr/bin/env node + +var spawn = require('child_process').spawn +var path = require('path') + +var prog = path.resolve(process.argv[2]) +var progArgs = process.argv.slice(3) + +console.log('probing program', prog) + +var nodeArgs = [ + '-r', + path.join(__dirname, 'include.js') +] +var nodeOpts = { stdio: 'inherit' } +var child = spawn('node', nodeArgs.concat(prog).concat(progArgs), nodeOpts) + +console.log('kill -SIGUSR1', child.pid, 'for logging') diff --git a/node_modules/why-is-node-running/example.js b/node_modules/why-is-node-running/example.js new file mode 100644 index 0000000000..4584d4b778 --- /dev/null +++ b/node_modules/why-is-node-running/example.js @@ -0,0 +1,15 @@ +var log = require('./') +var net = require('net') + +function createServer () { + var server = net.createServer() + setInterval(function () {}, 1000) + server.listen(0) +} + +createServer() +createServer() + +setTimeout(function () { + log() +}, 100) diff --git a/node_modules/why-is-node-running/include.js b/node_modules/why-is-node-running/include.js new file mode 100644 index 0000000000..c7ffe28cb6 --- /dev/null +++ b/node_modules/why-is-node-running/include.js @@ -0,0 +1,3 @@ +var why = require('./') + +require('siginfo')(why, true) diff --git a/node_modules/why-is-node-running/index.js b/node_modules/why-is-node-running/index.js new file mode 100644 index 0000000000..70842c5609 --- /dev/null +++ b/node_modules/why-is-node-running/index.js @@ -0,0 +1,67 @@ +var asyncHooks = require('async_hooks') +var stackback = require('stackback') +var path = require('path') +var fs = require('fs') +var sep = path.sep + +var active = new Map() +var hook = asyncHooks.createHook({ + init (asyncId, type, triggerAsyncId, resource) { + if (type === 'TIMERWRAP' || type === 'PROMISE') return + if (type === 'PerformanceObserver' || type === 'RANDOMBYTESREQUEST') return + var err = new Error('whatevs') + var stacks = stackback(err) + active.set(asyncId, {type, stacks, resource}) + }, + destroy (asyncId) { + active.delete(asyncId) + } +}) + +hook.enable() +module.exports = whyIsNodeRunning + +function whyIsNodeRunning (logger) { + if (!logger) logger = console + + hook.disable() + var activeResources = [...active.values()].filter(function(r) { + if ( + typeof r.resource.hasRef === 'function' + && !r.resource.hasRef() + ) return false + return true + }) + + logger.error('There are %d handle(s) keeping the process running', activeResources.length) + for (const o of activeResources) printStacks(o) + + function printStacks (o) { + var stacks = o.stacks.slice(1).filter(function (s) { + var filename = s.getFileName() + return filename && filename.indexOf(sep) > -1 && filename.indexOf('internal' + sep) !== 0 && filename.indexOf('node:internal' + sep) !== 0 + }) + + logger.error('') + logger.error('# %s', o.type) + + if (!stacks[0]) { + logger.error('(unknown stack trace)') + } else { + var padding = '' + stacks.forEach(function (s) { + var pad = (s.getFileName() + ':' + s.getLineNumber()).replace(/./g, ' ') + if (pad.length > padding.length) padding = pad + }) + stacks.forEach(function (s) { + var prefix = s.getFileName() + ':' + s.getLineNumber() + try { + var src = fs.readFileSync(s.getFileName(), 'utf-8').split(/\n|\r\n/) + logger.error(prefix + padding.slice(prefix.length) + ' - ' + src[s.getLineNumber() - 1].trim()) + } catch (e) { + logger.error(prefix + padding.slice(prefix.length)) + } + }) + } + } +} diff --git a/node_modules/why-is-node-running/package.json b/node_modules/why-is-node-running/package.json new file mode 100644 index 0000000000..9bf6a6d651 --- /dev/null +++ b/node_modules/why-is-node-running/package.json @@ -0,0 +1,39 @@ +{ + "name": "why-is-node-running", + "version": "2.3.0", + "description": "Node is running but you don't know why? why-is-node-running is here to help you.", + "main": "index.js", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "repository": { + "type": "git", + "url": "https://github.com/mafintosh/why-is-node-running.git" + }, + "keywords": [ + "debug", + "devops", + "test", + "events", + "handles" + ], + "author": "Mathias Buus (@mafintosh)", + "contributors": [ + { + "name": "Jon Peck", + "email": "jpeck@fluxsauce.com" + } + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/mafintosh/why-is-node-running/issues" + }, + "homepage": "https://github.com/mafintosh/why-is-node-running" +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..17d0404967 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1506 @@ +{ + "name": "learn-cicd-starter", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "vitest": "^3.2.4" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", + "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", + "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", + "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", + "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", + "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", + "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", + "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", + "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", + "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", + "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", + "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", + "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", + "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", + "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", + "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", + "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", + "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", + "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", + "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", + "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", + "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", + "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", + "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", + "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", + "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.49.0.tgz", + "integrity": "sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.49.0.tgz", + "integrity": "sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.49.0.tgz", + "integrity": "sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.49.0.tgz", + "integrity": "sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.49.0.tgz", + "integrity": "sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.49.0.tgz", + "integrity": "sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.49.0.tgz", + "integrity": "sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.49.0.tgz", + "integrity": "sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.49.0.tgz", + "integrity": "sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.49.0.tgz", + "integrity": "sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.49.0.tgz", + "integrity": "sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.49.0.tgz", + "integrity": "sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.49.0.tgz", + "integrity": "sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.49.0.tgz", + "integrity": "sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.49.0.tgz", + "integrity": "sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.49.0.tgz", + "integrity": "sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.49.0.tgz", + "integrity": "sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.49.0.tgz", + "integrity": "sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.49.0.tgz", + "integrity": "sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.49.0.tgz", + "integrity": "sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.18", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz", + "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "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, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.49.0.tgz", + "integrity": "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.49.0", + "@rollup/rollup-android-arm64": "4.49.0", + "@rollup/rollup-darwin-arm64": "4.49.0", + "@rollup/rollup-darwin-x64": "4.49.0", + "@rollup/rollup-freebsd-arm64": "4.49.0", + "@rollup/rollup-freebsd-x64": "4.49.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.49.0", + "@rollup/rollup-linux-arm-musleabihf": "4.49.0", + "@rollup/rollup-linux-arm64-gnu": "4.49.0", + "@rollup/rollup-linux-arm64-musl": "4.49.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.49.0", + "@rollup/rollup-linux-ppc64-gnu": "4.49.0", + "@rollup/rollup-linux-riscv64-gnu": "4.49.0", + "@rollup/rollup-linux-riscv64-musl": "4.49.0", + "@rollup/rollup-linux-s390x-gnu": "4.49.0", + "@rollup/rollup-linux-x64-gnu": "4.49.0", + "@rollup/rollup-linux-x64-musl": "4.49.0", + "@rollup/rollup-win32-arm64-msvc": "4.49.0", + "@rollup/rollup-win32-ia32-msvc": "4.49.0", + "@rollup/rollup-win32-x64-msvc": "4.49.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", + "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vite": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.3.tgz", + "integrity": "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.14" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..0d12fb1ba9 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "devDependencies": { + "vitest": "^3.2.4" + }, + "scripts": { + "test": "vitest --run" + } +} diff --git a/src/tests/auth.test.ts b/src/tests/auth.test.ts new file mode 100644 index 0000000000..4bb8193406 --- /dev/null +++ b/src/tests/auth.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, test } from "vitest"; + +const person = { + isActive: true, + age: 32, +}; + +describe("person", () => { + test("person is defined", () => { + expect(person).toBeDefined(); + }); + + test("is active", () => { + expect(person.isActive).toBeTruthy(); + }); +});