diff --git a/.eslintrc.json b/.eslintrc.json index 5d192416..c8c67ee3 100755 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -34,11 +34,13 @@ "ignoreRegExpLiterals": true } ], + "prefer-regex-literals": "error", "eol-last": ["error", "always"], "import/no-default-export": "error", "eqeqeq": [2, "always"], "no-var": 2, "block-scoped-var": 2, + "curly": 2, "no-async-promise-executor": "off", "no-bitwise": [2, { "allow": ["~"] }], "no-duplicate-imports": [2, { "includeExports": true }], @@ -71,31 +73,11 @@ "files": ["*.ts"], "rules": { "@typescript-eslint/semi": ["error", "always"], - "@typescript-eslint/quotes": [ - "error", - "single", - { "avoidEscape": true, "allowTemplateLiterals": true } - ], "@typescript-eslint/no-empty-function": [ "error", { "allow": ["arrowFunctions"] } ] } - }, - { - "files": ["*.js"], - "parserOptions": { - "project": null - }, - "rules": { - "semi": ["error", "always"], - "quotes": [ - "error", - "single", - { "avoidEscape": true, "allowTemplateLiterals": true } - ], - "no-unused-vars": 2 - } } ], "settings": { diff --git a/.gitignore b/.gitignore index 725ebea1..35044a06 100755 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ node_modules /.temp /test-src /test-tests +/test-before-and-after-each.json diff --git a/benchmark/benchmark.js b/benchmark/benchmark.js index 20f27609..71a6ff6a 100644 --- a/benchmark/benchmark.js +++ b/benchmark/benchmark.js @@ -21,7 +21,9 @@ const test = () => { }; for (const [name, result] of results) { - if (name === 'Poku (Local)') continue; + if (name === 'Poku (Local)') { + continue; + } const expectedRatio = tolerancesPerTester[name]; const actualRatio = pokuResult.opsPerSec / result.opsPerSec; @@ -71,7 +73,9 @@ suite console.log(`\n🚀 Fastest is \x1b[1m${fatest}\x1b[0m\n`); - if (!/^Poku/.test(fatest)) process.exit(1); + if (!/^Poku/.test(fatest)) { + process.exit(1); + } test(); }) diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..59a2af71 --- /dev/null +++ b/biome.json @@ -0,0 +1,95 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.2/schema.json", + "files": { + "ignore": [ + "node_modules", + "lib", + "ci", + "coverage", + "website", + "fixtures", + "benchmark" + ] + }, + "organizeImports": { + "enabled": false + }, + "linter": { + "enabled": true, + "rules": { + "all": true, + "complexity": { + "all": true, + "noExcessiveCognitiveComplexity": "off" + }, + "a11y": { + "all": true + }, + "correctness": { + "all": true, + "noNodejsModules": "off" + }, + "nursery": { + "all": true, + "useImportRestrictions": "off", + "noConsole": "off", + "noMisplacedAssertion": "off" + }, + "performance": { + "all": true + }, + "security": { + "all": true + }, + "suspicious": { + "all": true, + "noAsyncPromiseExecutor": "off", + "noEmptyBlockStatements": "off", + "noConsoleLog": "off" + }, + "style": { + "all": true, + "noNonNullAssertion": "off", + "useNamingConvention": "off", + "useNodeAssertStrict": "off", + "noNamespaceImport": "off", + "useForOf": "off" + } + } + }, + "javascript": { + "globals": ["BufferEncoding"] + }, + "overrides": [ + { + "include": ["test", "tools"], + "linter": { + "rules": { + "nursery": { + "useTopLevelRegex": "off" + } + } + } + }, + { + "include": ["src/polyfills"], + "linter": { + "rules": { + "suspicious": { + "noExplicitAny": "off" + } + } + } + }, + { + "include": ["src/index.ts"], + "linter": { + "rules": { + "performance": { + "noBarrelFile": "off" + } + } + } + } + ] +} diff --git a/fixtures/before-after-each/integration.test.cjs b/fixtures/before-after-each/integration.test.cjs new file mode 100644 index 00000000..1c54f033 --- /dev/null +++ b/fixtures/before-after-each/integration.test.cjs @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ + +const fs = require('node:fs'); +const path = require('node:path'); + +const jsonFilePath = path.resolve('./test-before-and-after-each.json'); + +const data = fs.readFileSync(jsonFilePath, 'utf-8'); +const json = JSON.parse(data); + +json.value += 1; + +fs.writeFileSync(jsonFilePath, JSON.stringify(json)); diff --git a/fixtures/fail/exit.test.ts b/fixtures/fail/exit.test.ts index 226ecb1f..de44aaa9 100644 --- a/fixtures/fail/exit.test.ts +++ b/fixtures/fail/exit.test.ts @@ -1,4 +1,4 @@ import process from 'node:process'; -console.log(123); +console.log('Failure Fixture'); process.exit(1); diff --git a/fixtures/success/exit.test.ts b/fixtures/success/exit.test.ts index fa400b0b..e9a1a13d 100644 --- a/fixtures/success/exit.test.ts +++ b/fixtures/success/exit.test.ts @@ -1,4 +1,4 @@ import process from 'node:process'; -console.log(123); +console.log('Sucess Fixture'); process.exit(0); diff --git a/package-lock.json b/package-lock.json index 7dab83ae..202558c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "poku": "lib/bin/index.js" }, "devDependencies": { - "@types/node": "^20.14.8", + "@biomejs/biome": "1.8.2", + "@types/node": "^20.14.9", "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.14.1", "c8": "^10.1.2", @@ -22,6 +23,7 @@ "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-unicorn": "^54.0.0", "packages-update": "^2.0.0", "prettier": "^3.3.2", "shx": "^0.3.4", @@ -32,6 +34,124 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -39,6 +159,170 @@ "dev": true, "license": "MIT" }, + "node_modules/@biomejs/biome": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.8.2.tgz", + "integrity": "sha512-XafCzLgs0xbH0bCjYKxQ63ig2V86fZQMq1jiy5pyLToWk9aHxA8GAUxyBtklPHtPYZPGEPOYglQHj4jyfUp+Iw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.8.2", + "@biomejs/cli-darwin-x64": "1.8.2", + "@biomejs/cli-linux-arm64": "1.8.2", + "@biomejs/cli-linux-arm64-musl": "1.8.2", + "@biomejs/cli-linux-x64": "1.8.2", + "@biomejs/cli-linux-x64-musl": "1.8.2", + "@biomejs/cli-win32-arm64": "1.8.2", + "@biomejs/cli-win32-x64": "1.8.2" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.8.2.tgz", + "integrity": "sha512-l9msLsTcSIAPqMsPIhodQmb50sEfaXPLQ0YW4cdj6INmd8iaOh/V9NceQb2366vACTJgcWDQ2RzlvURek1T68g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.8.2.tgz", + "integrity": "sha512-Fc4y/FuIxRSiB3TJ+y27vFDE/HJt4QgBuymktsIKEcBZvnKfsRjxvzVDunccRn4xbKgepnp+fn6BoS+ZIg/I3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.8.2.tgz", + "integrity": "sha512-Q99qwP0qibkZxm2kfnt37OxeIlliDYf5ogi3zX9ij2DULzc+KtPA9Uj0wCljcJofOBsBYaHc7597Q+Bf/251ww==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.8.2.tgz", + "integrity": "sha512-WpT41QJJvkZa1eZq0WmD513zkC6AYaMI39HJKmKeiUeX2NZirG+bxv1YRDhqkns1NbBqo3+qrJqBkPmOW+xAVA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.8.2.tgz", + "integrity": "sha512-bjhhUVFchFid2gOjrvBe4fg8BShcpyFQTHuB/QQnfGxs1ddrGP30yq3fHfc6S6MoCcz9Tjd3Zzq1EfWfyy5iHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.8.2.tgz", + "integrity": "sha512-rk1Wj4d3LIlAlIAS1m2jlyfOjkNbuY1lfwKvWIAeZC51yDMzwhRD7cReE5PE+jqLDtq60PX38hDPeKd7nA1S6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.8.2.tgz", + "integrity": "sha512-EUbqmCmNWT5xhnxHrCAEBzJB1AnLqxTYoRjlxiCMzGvsy5jQzhCanJ8CT9kNsApW3pfPWBWkoTa7qrwWmwnEGA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.8.2.tgz", + "integrity": "sha512-n9H5oRUCk1uNezMgyJh9+hZdtfD8PXLLeq8DUzTycIhl0I1BulIoZ/uxWgRVDFDwAR1JHu1AykISCRFNGnc4iA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -794,15 +1078,22 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", - "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.14.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", @@ -1004,9 +1295,9 @@ "license": "ISC" }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", "dev": true, "license": "MIT", "bin": { @@ -1252,11 +1543,58 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/c8": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.2.tgz", "integrity": "sha512-Qr6rj76eSshu5CgRYvktW0uM0CFY0yi4Fd5D0duDXO6sYinyopmftUiJVuzBQxQcwQLor7JWDVRP+dUfCmzgJw==", "dev": true, + "license": "ISC", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@istanbuljs/schema": "^0.1.3", @@ -1315,6 +1653,27 @@ "node": ">=6" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001636", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", + "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1332,6 +1691,45 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -1381,6 +1779,20 @@ "dev": true, "license": "MIT" }, + "node_modules/core-js-compat": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1544,6 +1956,13 @@ "dev": true, "license": "MIT" }, + "node_modules/electron-to-chromium": { + "version": "1.4.812", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz", + "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==", + "dev": true, + "license": "ISC" + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1565,6 +1984,16 @@ "node": ">=10.13.0" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-abstract": { "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", @@ -2023,13 +2452,139 @@ "eslint-config-prettier": "*", "prettier": ">=3.0.0" }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-unicorn": { + "version": "54.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-54.0.0.tgz", + "integrity": "sha512-XxYLRiYtAWiAjPv6z4JREby1TAE2byBC7wlh0V4vWDCpccOSU1KovWV//jqPXF6bq3WKxqX9rdjoRQ1EhdmNdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.5", + "@eslint-community/eslint-utils": "^4.4.0", + "@eslint/eslintrc": "^3.0.2", + "ci-info": "^4.0.0", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.37.0", + "esquery": "^1.5.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.2.1", + "jsesc": "^3.0.2", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.10.0", + "semver": "^7.6.1", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=18.18" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=8.56.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, "node_modules/eslint-scope": { @@ -2294,9 +2849,9 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "dev": true, "license": "ISC", "dependencies": { @@ -2660,11 +3215,19 @@ "node": ">= 0.4" } }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ignore": { "version": "5.3.1", @@ -2703,6 +3266,16 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2764,6 +3337,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -2794,6 +3374,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -2808,13 +3404,16 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3047,6 +3646,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } @@ -3056,6 +3656,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -3070,6 +3671,7 @@ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -3097,6 +3699,13 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -3110,6 +3719,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -3117,6 +3739,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3168,6 +3797,13 @@ "node": ">= 0.8.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3206,6 +3842,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -3240,10 +3877,20 @@ "node": ">=8.6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -3290,12 +3937,45 @@ "dev": true, "license": "MIT" }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3441,6 +4121,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/packages-update": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/packages-update/-/packages-update-2.0.0.tgz", @@ -3468,6 +4165,25 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3532,6 +4248,13 @@ "node": ">=8" } }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -3545,6 +4268,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -3625,6 +4358,116 @@ ], "license": "MIT" }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", @@ -3637,6 +4480,16 @@ "node": ">= 0.10" } }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "license": "MIT", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -3656,6 +4509,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regjsparser": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -3940,6 +4815,42 @@ "node": ">=8" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -4060,6 +4971,19 @@ "node": ">=4" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4142,9 +5066,9 @@ } }, "node_modules/test-exclude/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dev": true, "license": "ISC", "dependencies": { @@ -4152,6 +5076,7 @@ "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { @@ -4377,6 +5302,37 @@ "dev": true, "license": "MIT" }, + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -4388,9 +5344,9 @@ } }, "node_modules/v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "license": "ISC", "dependencies": { @@ -4402,6 +5358,17 @@ "node": ">=10.12.0" } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index f0a8386e..1509df72 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,8 @@ "benchmark": "cd benchmark && npm ci && npm start" }, "devDependencies": { - "@types/node": "^20.14.8", + "@biomejs/biome": "1.8.2", + "@types/node": "^20.14.9", "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.14.1", "c8": "^10.1.2", @@ -68,6 +69,7 @@ "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-unicorn": "^54.0.0", "packages-update": "^2.0.0", "prettier": "^3.3.2", "shx": "^0.3.4", diff --git a/src/@types/background-process.ts b/src/@types/background-process.ts index 1207e2ff..2d962602 100644 --- a/src/@types/background-process.ts +++ b/src/@types/background-process.ts @@ -1,5 +1,5 @@ -import { Runner } from './runner.js'; -import { Configs } from './poku.js'; +import type { Runner } from './runner.js'; +import type { Configs } from './poku.js'; type BackgroundProcessOptions = { /** diff --git a/src/@types/describe.ts b/src/@types/describe.ts index ee4321ae..942c9ca2 100644 --- a/src/@types/describe.ts +++ b/src/@types/describe.ts @@ -1,4 +1,4 @@ -import { type backgroundColor } from '../helpers/format.js'; +import type { backgroundColor } from '../helpers/format.js'; export type DescribeOptions = { background?: keyof typeof backgroundColor | boolean; diff --git a/src/bin/index.ts b/src/bin/index.ts index 720e07c8..ee48af59 100644 --- a/src/bin/index.ts +++ b/src/bin/index.ts @@ -21,10 +21,14 @@ import type { Configs } from '../@types/poku.js'; const dirs = (() => { const includeArg = getArg('include'); - if (includeArg !== undefined) return includeArg.split(','); + if (includeArg !== undefined) { + return includeArg.split(','); + } const lastParam = getLastParam(); - if (lastParam !== undefined) return lastParam.split(','); + if (lastParam !== undefined) { + return lastParam.split(','); + } return ['.']; })(); @@ -119,17 +123,21 @@ Promise.all(tasks).then(() => { mapTests('.', dirs, options.filter, options.exclude).then( (mappedTests) => { - Array.from(mappedTests.keys()).forEach((mappedTest) => { + for (const mappedTest of Array.from(mappedTests.keys())) { watch(mappedTest, (file, event) => { if (event === 'change') { const filePath = normalizePath(file); - if (executing.has(filePath)) return; + if (executing.has(filePath)) { + return; + } executing.add(filePath); resultsClear(); const tests = mappedTests.get(filePath); - if (!tests) return; + if (!tests) { + return; + } poku(Array.from(tests), options).then(() => { setTimeout(() => { @@ -138,14 +146,16 @@ Promise.all(tasks).then(() => { }); } }); - }); + } } ); - dirs.forEach((dir) => { + for (const dir of dirs) { watch(dir, (file, event) => { if (event === 'change') { - if (executing.has(file)) return; + if (executing.has(file)) { + return; + } executing.add(file); resultsClear(); @@ -157,7 +167,7 @@ Promise.all(tasks).then(() => { }); } }); - }); + } hr(); write( diff --git a/src/helpers/find-file.ts b/src/helpers/find-file.ts index eece2729..f86b817b 100644 --- a/src/helpers/find-file.ts +++ b/src/helpers/find-file.ts @@ -1,4 +1,6 @@ /* c8 ignore start */ +const regex = /at\s(\/.+|file:.+)|^(\s+)at\smodule\scode\s\((\/.+|file:.+)\)/i; + export const findFile = (error: Error) => { const stackLines = error.stack?.split('\n') || []; @@ -8,18 +10,16 @@ export const findFile = (error: Error) => { for (const line of stackLines) { if (!line.includes(basePath)) { - const match = line.match( - /at\s(\/.+|file:.+)|^(\s+)at\smodule\scode\s\((\/.+|file:.+)\)/i - ); + const match = line.match(regex); // Node and Deno - if (match && match[1]) { + if (match?.[1]) { file = match[1]; break; } // Bun - if (match && match[3]) { + if (match?.[3]) { file = match[3]; break; } diff --git a/src/helpers/force-array.ts b/src/helpers/force-array.ts index 054d6e39..c5031f8c 100644 --- a/src/helpers/force-array.ts +++ b/src/helpers/force-array.ts @@ -1,6 +1,8 @@ /* c8 ignore start */ export const forceArray = (input: T | T[]): T[] => { - if (Array.isArray(input)) return input; + if (Array.isArray(input)) { + return input; + } return [input]; }; /* c8 ignore stop */ diff --git a/src/helpers/format.ts b/src/helpers/format.ts index 55bea24e..96328254 100644 --- a/src/helpers/format.ts +++ b/src/helpers/format.ts @@ -20,7 +20,7 @@ export const backgroundColor = { } as const; export class Formatter { - private parts: string = ''; + private parts = ''; private text: string; constructor(text: string) { diff --git a/src/helpers/get-arg.ts b/src/helpers/get-arg.ts index de212a63..5bf78742 100644 --- a/src/helpers/get-arg.ts +++ b/src/helpers/get-arg.ts @@ -2,6 +2,7 @@ import { argv } from 'node:process'; const [, , ...processArgs] = argv; +const regexQuotes = /''|""/; /** * Gets the value of an argument. @@ -20,9 +21,11 @@ export const getArg = (arg: string, prefix = '--'): string | undefined => { const argPattern = `${prefix}${arg}=`; const argValue = processArgs.find((a) => a.startsWith(argPattern)); - if (!argValue) return undefined; + if (!argValue) { + return undefined; + } - return argValue.slice(argPattern.length).replace(/''|""/, ''); + return argValue.slice(argPattern.length).replace(regexQuotes, ''); }; /** @@ -58,19 +61,28 @@ export const hasArg = (arg: string, prefix = '--'): boolean => { export const getLastParam = (prefix = '--'): string | undefined => { const lastArg = processArgs[processArgs.length - 1]; - if (!lastArg || lastArg.startsWith(prefix)) return undefined; + if (!lastArg || lastArg.startsWith(prefix)) { + return undefined; + } return lastArg; }; export const argToArray = (arg: string, prefix = '--') => { const hasArgument = hasArg(arg); - if (!hasArgument) return undefined; + if (!hasArgument) { + return undefined; + } const argValue = getArg(arg, prefix); - if (hasArgument && !argValue) return []; - if (!argValue) return undefined; + if (hasArgument && !argValue) { + return []; + } + + if (!argValue) { + return undefined; + } return argValue .split(',') diff --git a/src/helpers/get-runtime.ts b/src/helpers/get-runtime.ts index 1d529772..7cb70401 100644 --- a/src/helpers/get-runtime.ts +++ b/src/helpers/get-runtime.ts @@ -5,7 +5,7 @@ import type { Configs } from '../@types/poku.js'; declare const Deno: unknown; declare const Bun: unknown; -export const supportedPlatforms: ReadonlyArray = [ +export const supportedPlatforms: readonly Configs['platform'][] = [ 'node', 'bun', 'deno', @@ -19,19 +19,28 @@ export const platformIsValid = ( supportedPlatforms.some( (supportedPlatform) => supportedPlatform === platform ) - ) + ) { return true; + } + return false; }; export const getRuntime = ( configs?: Configs ): (typeof supportedPlatforms)[number] => { - if (configs?.platform && platformIsValid(configs.platform)) + if (configs?.platform && platformIsValid(configs.platform)) { return configs.platform; + } + + if (typeof Deno !== 'undefined') { + return 'deno'; + } + + if (typeof Bun !== 'undefined') { + return 'bun'; + } - if (typeof Deno !== 'undefined') return 'deno'; - if (typeof Bun !== 'undefined') return 'bun'; return 'node'; }; diff --git a/src/helpers/logs.ts b/src/helpers/logs.ts index fbd9cd37..ec8fe33d 100644 --- a/src/helpers/logs.ts +++ b/src/helpers/logs.ts @@ -3,6 +3,11 @@ import { stdout } from 'node:process'; import type { Configs } from '../@types/poku.js'; import type { Formatter } from './format.js'; +const regex = { + newLine: /\n/, + ansi: /u001b\[0m|\n/i, +} as const; + export const isQuiet = (configs?: Configs): boolean => typeof configs?.quiet === 'boolean' && Boolean(configs?.quiet); @@ -20,20 +25,22 @@ export const printOutput = (options: { const debug = isDebug(configs); const pad = configs?.parallel ? ' ' : ' '; - const splittedOutput = output.split(/\n/); + const splittedOutput = output.split(regex.newLine); const outputs = ( debug || !result ? splittedOutput : splittedOutput.filter((current) => { - if (current.includes('Exited with code')) return false; - return ( - /u001b\[0m|\n/i.test(JSON.stringify(current)) || current === '' - ); + if (current.includes('Exited with code')) { + return false; + } + return regex.ansi.test(JSON.stringify(current)) || current === ''; }) ).filter((line) => line?.trim().length > 0); - if (outputs.length === 0) return; + if (outputs.length === 0) { + return; + } const mappedOutputs = outputs.map((current) => `${pad}${current}`); diff --git a/src/helpers/parse-assertion.ts b/src/helpers/parse-assertion.ts index 91065cae..91113437 100644 --- a/src/helpers/parse-assertion.ts +++ b/src/helpers/parse-assertion.ts @@ -13,6 +13,7 @@ import { nodeVersion } from './get-runtime.js'; import { write } from './logs.js'; const cwd = processCWD(); +const regexFile = /file:(\/\/)?/; export const parseResultType = (type?: unknown): string => { const recurse = (value: unknown): unknown => { @@ -22,26 +23,33 @@ export const parseResultType = (type?: unknown): string => { typeof value === 'bigint' || typeof value === 'symbol' || value instanceof RegExp - ) + ) { return String(value); + } - if (Array.isArray(value)) return value.map(recurse); - if (value instanceof Set) return Array.from(value).map(recurse); + if (Array.isArray(value)) { + return value.map(recurse); + } + if (value instanceof Set) { + return Array.from(value).map(recurse); + } /* c8 ignore start */ - if (value instanceof Map) + if (value instanceof Map) { return recurse( !nodeVersion || nodeVersion >= 12 ? Object.fromEntries(value) : fromEntries(value) ); + } /* c8 ignore stop */ /* c8 ignore start */ if (value !== null && typeof value === 'object') { - if (!nodeVersion || nodeVersion >= 12) + if (!nodeVersion || nodeVersion >= 12) { return Object.fromEntries( Object.entries(value).map(([key, val]) => [key, recurse(val)]) ); + } return fromEntries( entries(value).map(([key, val]) => [key, recurse(val)]) @@ -65,25 +73,38 @@ export const parseAssertion = async ( const FILE = env.FILE; let preIdentation = ''; - if (indentation.hasDescribe || indentation.hasTest) preIdentation += ' '; - if (indentation.hasIt) preIdentation += ' '; + if (indentation.hasDescribe || indentation.hasTest) { + preIdentation += ' '; + } + + if (indentation.hasIt) { + preIdentation += ' '; + } try { if (typeof each.before.cb === 'function' && each.before.assert) { const beforeResult = each.before.cb(); - /* c8 ignore next */ - if (beforeResult instanceof Promise) await beforeResult; - /* c8 ignore next */ + + /* c8 ignore start */ + if (beforeResult instanceof Promise) { + await beforeResult; + } + /* c8 ignore stop */ } const cbResult = cb(); - if (cbResult instanceof Promise) await cbResult; + if (cbResult instanceof Promise) { + await cbResult; + } if (typeof each.after.cb === 'function' && each.after.assert) { const afterResult = each.after.cb(); - /* c8 ignore next */ - if (afterResult instanceof Promise) await afterResult; - /* c8 ignore next */ + + /* c8 ignore start */ + if (afterResult instanceof Promise) { + await afterResult; + } + /* c8 ignore stop */ } if (typeof options.message === 'string') { @@ -103,16 +124,18 @@ export const parseAssertion = async ( } catch (error) { if (error instanceof assert.AssertionError) { const { code, actual, expected, operator } = error; - const absoultePath = findFile(error).replace(/file:(\/\/)?/, ''); + const absoultePath = findFile(error).replace(regexFile, ''); const file = path.relative(path.resolve(cwd), absoultePath); - let message: string = ''; + let message = ''; - if (typeof options.message === 'string') message = options.message; - else if (options.message instanceof Error) + if (typeof options.message === 'string') { + message = options.message; + } else if (options.message instanceof Error) { message = options.message.message; - else if (typeof options.defaultMessage === 'string') + } else if (typeof options.defaultMessage === 'string') { message = options.defaultMessage; + } const finalMessage = message?.trim().length > 0 @@ -136,16 +159,18 @@ export const parseAssertion = async ( write( format(`${preIdentation} ${options?.actual || 'Actual'}:`).dim() ); - splitActual.forEach((line) => - write(`${preIdentation} ${format(line).fail().bold()}`) - ); + + for (const line of splitActual) { + write(`${preIdentation} ${format(line).fail().bold()}`); + } write( `\n${preIdentation} ${format(`${options?.expected || 'Expected'}:`).dim()}` ); - splitExpected.forEach((line) => - write(`${preIdentation} ${format(line).success().bold()}`) - ); + + for (const line of splitExpected) { + write(`${preIdentation} ${format(line).success().bold()}`); + } } if (options.throw) { diff --git a/src/helpers/runner.ts b/src/helpers/runner.ts index e65cc6ca..86812d23 100644 --- a/src/helpers/runner.ts +++ b/src/helpers/runner.ts @@ -11,7 +11,9 @@ export const runner = (filename: string, configs?: Configs): string[] => { const runtime = getRuntime(configs); // Bun - if (runtime === 'bun') return ['bun']; + if (runtime === 'bun') { + return ['bun']; + } // Deno if (runtime === 'deno') { @@ -45,16 +47,24 @@ export const runner = (filename: string, configs?: Configs): string[] => { export const scriptRunner = (runner: Runner): string[] => { // Bun - if (runner === 'bun') return ['bun', 'run']; + if (runner === 'bun') { + return ['bun', 'run']; + } // Deno - if (runner === 'deno') return ['deno', 'task']; + if (runner === 'deno') { + return ['deno', 'task']; + } // Yarn - if (runner === 'yarn') return ['yarn']; + if (runner === 'yarn') { + return ['yarn']; + } // PNPM - if (runner === 'pnpm') return ['pnpm', 'run']; + if (runner === 'pnpm') { + return ['pnpm', 'run']; + } // Node.js return [isWindows ? 'npm.cmd' : 'npm', 'run']; diff --git a/src/helpers/time.ts b/src/helpers/time.ts index be2e2884..edfeb794 100644 --- a/src/helpers/time.ts +++ b/src/helpers/time.ts @@ -10,7 +10,7 @@ export const setTime = (date: Date): string => { }; export const toSecs = (milliseconds: string): string => { - const ms = parseFloat(milliseconds); + const ms = Number.parseFloat(milliseconds); const seconds = (ms / 1000).toFixed(2); return seconds; diff --git a/src/modules/assert-promise.ts b/src/modules/assert-promise.ts index 7c7538b6..91040420 100644 --- a/src/modules/assert-promise.ts +++ b/src/modules/assert-promise.ts @@ -271,9 +271,11 @@ async function doesNotReject( typeof errorOrMessage === 'function' || errorOrMessage instanceof RegExp || typeof errorOrMessage === 'object' - ) + ) { await nodeAssert.doesNotReject(block, errorOrMessage, message); - else await nodeAssert.doesNotReject(block, message); + } else { + await nodeAssert.doesNotReject(block, message); + } }, { message: typeof errorOrMessage === 'string' ? errorOrMessage : message, diff --git a/src/modules/assert.ts b/src/modules/assert.ts index 19c652e9..e20845b6 100644 --- a/src/modules/assert.ts +++ b/src/modules/assert.ts @@ -263,9 +263,11 @@ async function doesNotReject( typeof errorOrMessage === 'function' || errorOrMessage instanceof RegExp || typeof errorOrMessage === 'object' - ) + ) { await nodeAssert.doesNotReject(block, errorOrMessage, message); - else await nodeAssert.doesNotReject(block, message); + } else { + await nodeAssert.doesNotReject(block, message); + } }, { message: typeof errorOrMessage === 'string' ? errorOrMessage : message, diff --git a/src/modules/container.ts b/src/modules/container.ts index 88505d84..1d91fde5 100644 --- a/src/modules/container.ts +++ b/src/modules/container.ts @@ -1,5 +1,5 @@ /* c8 ignore next */ -import { +import type { DockerComposeConfigs, DockerfileConfigs, } from '../@types/container.js'; diff --git a/src/modules/create-service.ts b/src/modules/create-service.ts index f4d6d869..49f0d424 100644 --- a/src/modules/create-service.ts +++ b/src/modules/create-service.ts @@ -67,7 +67,9 @@ const backgroundProcess = ( ['bun', 'deno'].includes(String(options?.runner)) ) { process.kill(PID); - } else process.kill(-PID, 'SIGKILL'); + } else { + process.kill(-PID, 'SIGKILL'); + } if (port && ['bun', 'deno'].includes(runtime)) { setTimeout(async () => { @@ -80,10 +82,8 @@ const backgroundProcess = ( return; } } catch { - { - resolve(undefined); - return; - } + resolve(undefined); + return; } }); @@ -141,7 +141,9 @@ const backgroundProcess = ( /* c8 ignore start */ service.on('close', (code) => { - if (code !== 0) reject(`Service exited with code ${code}`); + if (code !== 0) { + reject(`Service exited with code ${code}`); + } }); /* c8 ignore stop */ diff --git a/src/modules/describe.ts b/src/modules/describe.ts index d80f5b86..7040b92f 100644 --- a/src/modules/describe.ts +++ b/src/modules/describe.ts @@ -32,8 +32,11 @@ export async function describe( if (typeof arg1 === 'string') { title = arg1; - if (typeof arg2 === 'function') cb = arg2; - else options = arg2; + if (typeof arg2 === 'function') { + cb = arg2; + } else { + options = arg2; + } } else if (typeof arg1 === 'function') { cb = arg1; options = arg2 as DescribeOptions; @@ -46,8 +49,9 @@ export async function describe( const message = `${cb ? format('◌').dim() : icon || '☰'} ${cb ? format(isPoku ? `${title} › ${format(`${FILE}`).italic().gray()}` : /* c8 ignore next */ title).dim() : format(title).bold() || ''}`; const noBackground = !background; - if (noBackground) write(format(message).bold()); - else { + if (noBackground) { + write(format(message).bold()); + } else { write( format(` ${message} `).bg( typeof background === 'string' ? background : 'grey' @@ -56,13 +60,17 @@ export async function describe( } } - if (typeof cb !== 'function') return; + if (typeof cb !== 'function') { + return; + } const start = hrtime(); const resultCb = cb(); /* c8 ignore next */ - if (resultCb instanceof Promise) await resultCb; + if (resultCb instanceof Promise) { + await resultCb; + } const end = hrtime(start); if (title) { diff --git a/src/modules/each.ts b/src/modules/each.ts index d90a3854..9444011a 100644 --- a/src/modules/each.ts +++ b/src/modules/each.ts @@ -34,7 +34,9 @@ export const beforeEach = ( options?.immediate && callback(); each.before.cb = () => { - if (each.before.status) callback(); + if (each.before.status) { + callback(); + } }; const pause = () => { @@ -84,7 +86,9 @@ export const afterEach = ( typeof options?.assert === 'boolean' ? options.assert : false; each.after.cb = () => { - if (each.after.status) callback(); + if (each.after.status) { + callback(); + } }; const pause = () => { diff --git a/src/modules/it.ts b/src/modules/it.ts index fe3a13c1..dcda9285 100644 --- a/src/modules/it.ts +++ b/src/modules/it.ts @@ -29,14 +29,19 @@ export async function it( if (typeof each.before.cb === 'function' && each.before.test) { const beforeResult = each.before.cb(); - /* c8 ignore next */ - if (beforeResult instanceof Promise) await beforeResult; + /* c8 ignore start */ + if (beforeResult instanceof Promise) { + await beforeResult; + } + /* c8 ignore stop */ } if (typeof args[0] === 'string') { message = args[0]; cb = args[1] as () => unknown | Promise; - } else cb = args[0] as () => unknown | Promise; + } else { + cb = args[0] as () => unknown | Promise; + } if (message) { indentation.hasIt = true; @@ -52,13 +57,19 @@ export async function it( const resultCb = cb(); /* c8 ignore next */ - if (resultCb instanceof Promise) await resultCb; + if (resultCb instanceof Promise) { + await resultCb; + } const end = hrtime(start); if (typeof each.after.cb === 'function' && each.after.test) { const afterResult = each.after.cb(); - /* c8 ignore next */ - if (afterResult instanceof Promise) await afterResult; + + /* c8 ignore start */ + if (afterResult instanceof Promise) { + await afterResult; + } + /* c8 ignore stop */ } if (message) { diff --git a/src/modules/list-files-sync.ts b/src/modules/list-files-sync.ts index a58cafb3..275e88a5 100644 --- a/src/modules/list-files-sync.ts +++ b/src/modules/list-files-sync.ts @@ -11,6 +11,11 @@ import { escapeRegExp, sanitizePath } from './list-files.js'; const isDir = (fullPath: string) => statSync(fullPath).isDirectory(); +const regex = { + defaultFilter: /\.(test|spec)\./i, + staticExclude: /node_modules|^.git/, +}; + const envFilter = env.FILTER?.trim() ? new RegExp(escapeRegExp(env.FILTER), 'i') : null; @@ -21,13 +26,12 @@ const listFiles = ( configs?: Configs ) => { const currentFiles = readdirSync(sanitizePath(dirPath)); - const defaultRegExp = /\.(test|spec)\./i; const filter: RegExp = (envFilter ? envFilter : configs?.filter instanceof RegExp ? configs.filter - : defaultRegExp) || defaultRegExp; + : regex.defaultFilter) || regex.defaultFilter; const exclude: Configs['exclude'] = configs?.exclude ? Array.isArray(configs.exclude) @@ -38,11 +42,18 @@ const listFiles = ( for (const file of currentFiles) { const fullPath = sanitizePath(path.join(dirPath, file)); - if (/node_modules/.test(fullPath)) continue; - if (exclude && exclude.some((regex) => regex.test(fullPath))) continue; + if (regex.staticExclude.test(fullPath)) { + continue; + } + if (exclude?.some((regex) => regex.test(fullPath))) { + continue; + } - if (isDir(fullPath)) listFiles(fullPath, files, configs); - else if (filter.test(fullPath)) files.push(fullPath); + if (isDir(fullPath)) { + listFiles(fullPath, files, configs); + } else if (filter.test(fullPath)) { + files.push(fullPath); + } } return files; diff --git a/src/modules/list-files.ts b/src/modules/list-files.ts index b95fcc60..73935615 100644 --- a/src/modules/list-files.ts +++ b/src/modules/list-files.ts @@ -4,15 +4,24 @@ import { env } from 'node:process'; import { sep, join } from 'node:path'; import { readdir, stat as fsStat } from '../polyfills/fs.js'; +const regex = { + sep: /[/\\]+/g, + pathLevel: /(\.\.(\/|\\|$))+/g, + unusualChars: /[<>|^?*]+/g, + absolutePath: /^[/\\]/, + safeRegExp: /[.*{}[\]\\]/g, + defaultFilter: /\.(test|spec)\./i, +} as const; + export const sanitizePath = (input: string, ensureTarget?: boolean): string => { const sanitizedPath = input - .replace(/[/\\]+/g, sep) // adapting slashes according to OS - .replace(/(\.\.(\/|\\|$))+/g, '') // ensure the current path level - .replace(/[<>|^?*]+/g, ''); // removing unusual path characters + .replace(regex.sep, sep) // adapting slashes according to OS + .replace(regex.pathLevel, '') // ensure the current path level + .replace(regex.unusualChars, ''); // removing unusual path characters // Preventing absolute path access return ensureTarget - ? sanitizedPath.replace(/^[/\\]/, `.${sep}`) + ? sanitizedPath.replace(regex.absolutePath, `.${sep}`) : sanitizedPath; }; @@ -23,7 +32,7 @@ export const isFile = async (fullPath: string) => /* c8 ignore start */ export const escapeRegExp = (string: string) => - string.replace(/[.*{}[\]\\]/g, '\\$&'); + string.replace(regex.safeRegExp, '\\$&'); /* c8 ignore stop */ /* c8 ignore start */ @@ -38,14 +47,13 @@ export const getAllFiles = async ( configs?: Configs ): Promise> => { const currentFiles = await readdir(sanitizePath(dirPath)); - const defaultRegExp = /\.(test|spec)\./i; /* c8 ignore start */ const filter: RegExp = (envFilter ? envFilter : configs?.filter instanceof RegExp ? configs.filter - : defaultRegExp) || defaultRegExp; + : regex.defaultFilter) || regex.defaultFilter; const exclude: Configs['exclude'] = configs?.exclude ? Array.isArray(configs.exclude) @@ -63,19 +71,28 @@ export const getAllFiles = async ( if ( fullPath.indexOf('node_modules') !== -1 || fullPath.indexOf('.git') === 0 - ) + ) { return; + } /* c8 ignore stop */ if (exclude) { for (let i = 0; i < exclude.length; i++) { - /* c8 ignore next */ - if (exclude[i].test(fullPath)) return; + /* c8 ignore start */ + if (exclude[i].test(fullPath)) { + return; + } + /* c8 ignore stop */ } } - if (filter.test(fullPath)) return files.add(fullPath); - if (stat.isDirectory()) await getAllFiles(fullPath, files, configs); + if (filter.test(fullPath)) { + return files.add(fullPath); + } + + if (stat.isDirectory()) { + await getAllFiles(fullPath, files, configs); + } }) ); diff --git a/src/modules/poku.ts b/src/modules/poku.ts index aac2d891..846e20a1 100644 --- a/src/modules/poku.ts +++ b/src/modules/poku.ts @@ -26,11 +26,11 @@ export async function poku( export async function poku( targetPaths: string | string[], configs?: Configs -): Promise; +): Promise; export async function poku( targetPaths: string | string[], configs?: Configs -): Promise { +): Promise { let code: Code = 0; finalResults.started = new Date(); @@ -47,11 +47,15 @@ export async function poku( if (!result) { code = 1; - if (configs?.failFast) break; + if (configs?.failFast) { + break; + } } } - if (configs?.noExit) return code; + if (configs?.noExit) { + return code; + } const end = process.hrtime(start); const total = (end[0] * 1e3 + end[1] / 1e6).toFixed(6); @@ -72,14 +76,18 @@ export async function poku( const promises = dirs.map(async (dir) => { const result = await runTestsParallel(dir, configs); - if (!result && configs?.failFast) throw ''; + if (!result && configs?.failFast) { + throw new Error('quiet'); + } return result; }); const concurrency = await Promise.all(promises); - if (concurrency.some((result) => !result)) code = 1; + if (concurrency.some((result) => !result)) { + code = 1; + } } catch { } finally { const end = process.hrtime(start); @@ -112,7 +120,9 @@ export async function poku( ); } - if (configs?.noExit) return code; + if (configs?.noExit) { + return code; + } exit(code, configs?.quiet); } diff --git a/src/modules/processes.ts b/src/modules/processes.ts index 7a75ca80..995c6bd0 100644 --- a/src/modules/processes.ts +++ b/src/modules/processes.ts @@ -59,7 +59,9 @@ const killPort = async (port: number | number[]): Promise => { const PIDs = await getPIDs(port); for (const PID of PIDs) { - if (!PID) continue; + if (!PID) { + continue; + } await killPID(PID); } @@ -69,7 +71,9 @@ const killRange = async (startsAt: number, endsAt: number): Promise => { const PIDs = await getPIDs.range(startsAt, endsAt); for (const PID of PIDs) { - if (!PID) continue; + if (!PID) { + continue; + } await killPID(PID); } diff --git a/src/modules/test.ts b/src/modules/test.ts index 9e0cd7c3..e82d14ac 100644 --- a/src/modules/test.ts +++ b/src/modules/test.ts @@ -29,14 +29,19 @@ export async function test( if (typeof each.before.cb === 'function' && each.before.test) { const beforeResult = each.before.cb(); - /* c8 ignore next */ - if (beforeResult instanceof Promise) await beforeResult; + /* c8 ignore start */ + if (beforeResult instanceof Promise) { + await beforeResult; + } + /* c8 ignore stop */ } if (typeof args[0] === 'string') { message = args[0]; cb = args[1] as () => unknown | Promise; - } else cb = args[0] as () => unknown | Promise; + } else { + cb = args[0] as () => unknown | Promise; + } if (message) { indentation.hasTest = true; @@ -55,13 +60,19 @@ export async function test( const resultCb = cb(); /* c8 ignore next */ - if (resultCb instanceof Promise) await resultCb; + if (resultCb instanceof Promise) { + await resultCb; + } const end = hrtime(start); if (typeof each.after.cb === 'function' && each.after.test) { const afterResult = each.after.cb(); - /* c8 ignore next */ - if (afterResult instanceof Promise) await afterResult; + + /* c8 ignore start */ + if (afterResult instanceof Promise) { + await afterResult; + } + /* c8 ignore stop */ } /* c8 ignore start */ diff --git a/src/modules/wait-for.ts b/src/modules/wait-for.ts index 712e3d08..694196c3 100644 --- a/src/modules/wait-for.ts +++ b/src/modules/wait-for.ts @@ -26,7 +26,7 @@ const checkPort = (port: number, host: string): Promise => export const sleep = (milliseconds: number): Promise => { /* c8 ignore start */ if (!Number.isInteger(milliseconds)) { - throw new Error(`Milliseconds must be an integer.`); + throw new Error('Milliseconds must be an integer.'); } /* c8 ignore stop */ @@ -70,14 +70,16 @@ export const waitForExpectedResult = async ( const result = await callback(); if (typeof expectedResult === 'function') { - if (typeof result === 'function' && result.name === expectedResult.name) + if (typeof result === 'function' && result.name === expectedResult.name) { break; + } } else if (typeof expectedResult === 'symbol') { if ( typeof result === 'symbol' && String(result) === String(expectedResult) - ) + ) { break; + } } else { try { options?.strict @@ -90,7 +92,7 @@ export const waitForExpectedResult = async ( /* c8 ignore start */ if (Date.now() - startTime >= timeout) { - throw new Error(`Timeout`); + throw new Error('Timeout'); } /* c8 ignore stop */ diff --git a/src/polyfills/deno.mts b/src/polyfills/deno.mts index 1c807e73..802ff161 100644 --- a/src/polyfills/deno.mts +++ b/src/polyfills/deno.mts @@ -7,7 +7,9 @@ import process from 'node:process'; import { resolve, normalize } from 'node:path'; const file = process.env?.FILE; -if (!file) process.exit(1); +if (!file) { + process.exit(1); +} const cwd = process.cwd(); const targetPath = resolve(cwd, ''); diff --git a/src/polyfills/fs.ts b/src/polyfills/fs.ts index cb8a5628..009364cf 100644 --- a/src/polyfills/fs.ts +++ b/src/polyfills/fs.ts @@ -18,7 +18,10 @@ export function readdir( return new Promise((resolve, reject) => { if (options?.withFileTypes) { nodeReaddir(path, { withFileTypes: true }, (err, entries) => { - if (err) return reject(err); + if (err) { + return reject(err); + } + resolve(entries); }); @@ -26,7 +29,10 @@ export function readdir( } nodeReaddir(path, (err, files) => { - if (err) return reject(err); + if (err) { + return reject(err); + } + resolve(files); }); }); @@ -35,7 +41,10 @@ export function readdir( export const stat = (path: string): Promise => { return new Promise((resolve, reject) => { nodeStat(path, (err, stats) => { - if (err) return reject(err); + if (err) { + return reject(err); + } + resolve(stats); }); }); @@ -47,7 +56,10 @@ export const readFile = ( ): Promise => new Promise((resolve, reject) => { nodeReadFile(path, encoding, (err, data) => { - if (err) return reject(err); + if (err) { + return reject(err); + } + resolve(data); }); }); diff --git a/src/polyfills/object.ts b/src/polyfills/object.ts index ee8cdcef..9a39e3a6 100644 --- a/src/polyfills/object.ts +++ b/src/polyfills/object.ts @@ -5,7 +5,9 @@ export const entries = (obj: { [key: string]: any }): [string, unknown][] => { const resArray = new Array(i); // benchmark `while` outperformed `for` - while (i--) resArray[i] = [ownProps[i], obj[ownProps[i]]]; + while (i--) { + resArray[i] = [ownProps[i], obj[ownProps[i]]]; + } return resArray; }; diff --git a/src/polyfills/pad.ts b/src/polyfills/pad.ts index 4f534a84..e8826f1e 100644 --- a/src/polyfills/pad.ts +++ b/src/polyfills/pad.ts @@ -6,13 +6,15 @@ export const padStart = ( targetLength: number, padString: string ): string => { - padString = !padString ? ' ' : String(padString); + const defaultPad = padString ? String(padString) : ' '; - if (str.length >= targetLength) return str; + if (str.length >= targetLength) { + return str; + } const paddingLength = targetLength - str.length; - let fullPadString = padString.repeat( - Math.ceil(paddingLength / padString.length) + let fullPadString = defaultPad.repeat( + Math.ceil(paddingLength / defaultPad.length) ); fullPadString = fullPadString.slice(0, paddingLength); diff --git a/src/services/container.ts b/src/services/container.ts index 1b1d2a2f..4d9852d2 100644 --- a/src/services/container.ts +++ b/src/services/container.ts @@ -85,7 +85,9 @@ export class DockerContainer { public async build() { const args: string[] = ['build']; - if (this.cache === false) args.push('--no-cache'); + if (this.cache === false) { + args.push('--no-cache'); + } await runDockerCommand( 'docker', @@ -102,12 +104,17 @@ export class DockerContainer { args.push(this.detach !== false ? '-d' : '--init'); args.push(...['--name', this.containerName]); - this.ports.forEach((port) => args.push(...['-p', port])); - this.environments.forEach((environment) => - args.push(...['-e', environment]) - ); + for (const port of this.ports) { + args.push(...['-p', port]); + } - if (this.envFile) args.push(...['--env-file', this.envFile]); + for (const environment of this.environments) { + args.push(...['-e', environment]); + } + + if (this.envFile) { + args.push(...['--env-file', this.envFile]); + } return await runDockerCommand( 'docker', @@ -178,15 +185,23 @@ export class DockerCompose { public async up() { const args: string[] = ['-f', this.file]; - if (this.envFile) args.push(...['--env-file', this.envFile]); - if (this.projectName) args.push(...['-p', this.projectName]); + if (this.envFile) { + args.push(...['--env-file', this.envFile]); + } + if (this.projectName) { + args.push(...['-p', this.projectName]); + } args.push('up'); /* c8 ignore next */ args.push(this.detach !== false ? '-d' : '--abort-on-container-exit'); - if (this.build) args.push('--build'); - if (this.serviceName) args.push(this.serviceName); + if (this.build) { + args.push('--build'); + } + if (this.serviceName) { + args.push(this.serviceName); + } return await runDockerCommand( 'docker-compose', @@ -199,8 +214,12 @@ export class DockerCompose { public async down() { const args: string[] = ['-f', this.file]; - if (this.envFile) args.push(...['--env-file', this.envFile]); - if (this.projectName) args.push(...['-p', this.projectName]); + if (this.envFile) { + args.push(...['--env-file', this.envFile]); + } + if (this.projectName) { + args.push(...['-p', this.projectName]); + } return await runDockerCommand( 'docker-compose', diff --git a/src/services/each.ts b/src/services/each.ts index 32f7b89b..e12470a9 100644 --- a/src/services/each.ts +++ b/src/services/each.ts @@ -8,12 +8,21 @@ const eachCore = async ( fileRelative: string, configs?: Configs ): Promise => { - if (typeof configs?.[type] !== 'function') return true; + /* c8 ignore start */ + if (typeof configs?.[type] !== 'function') { + return true; + } + /* c8 ignore stop */ const cb = configs[type]; - /* c8 ignore next */ - if (typeof cb !== 'function') return true; + /* c8 ignore start */ + if (typeof cb !== 'function') { + return true; + } + /* c8 ignore stop */ + + /* c8 ignore start */ write( ` ${format('◯').dim().info()} ${format( `${cb}: ${cb.name || 'anonymous function'}` @@ -21,11 +30,17 @@ const eachCore = async ( .dim() .italic()}` ); + /* c8 ignore stop */ try { const resultCb = cb(); - /* c8 ignore next */ - if (resultCb instanceof Promise) await resultCb; + + /* c8 ignore start */ + if (resultCb instanceof Promise) { + await resultCb; + } + /* c8 ignore stop */ + return true; /* c8 ignore start */ } catch (error) { @@ -40,26 +55,28 @@ const eachCore = async ( ); if (error instanceof Error) { - write(format(` ├─ Message:`).fail()); + write(format(' ├─ Message:').fail()); write(format(` │ └─ ${error.message}`).fail()); } return false; } /* c8 ignore stop */ - /* c8 ignore next */ // c8 bug }; export const beforeEach = async (fileRelative: string, configs?: Configs) => { - if (configs?.beforeEach) + if (configs?.beforeEach) { return await eachCore('beforeEach', fileRelative, configs); + } return true; }; +/* c8 ignore next */ // c8 bug export const afterEach = async (fileRelative: string, configs?: Configs) => { - if (configs?.afterEach) + if (configs?.afterEach) { return await eachCore('afterEach', fileRelative, configs); + } return true; }; diff --git a/src/services/map-tests.ts b/src/services/map-tests.ts index d2229e73..b0be4b23 100644 --- a/src/services/map-tests.ts +++ b/src/services/map-tests.ts @@ -1,19 +1,24 @@ /* c8 ignore next */ // c8 bug -import { relative, dirname, sep } from 'node:path'; +import { relative, dirname } from 'node:path'; import { stat, readFile } from '../polyfills/fs.js'; import { listFiles } from '../modules/list-files.js'; const importMap = new Map>(); const processedFiles = new Set(); -const extFilter = /\.(js|cjs|mjs|ts|cts|mts|jsx|tsx)$/; +const regex = { + extFilter: /\.(js|cjs|mjs|ts|cts|mts|jsx|tsx)$/, + dependecy: /['"](\.{1,2}\/[^'"]+)['"]/, + dotBar: /(\.\/)/g, + sep: /[/\\]+/g, + dot: /^\.+/, +} as const; export const normalizePath = (filePath: string) => filePath - .replace(/(\.\/)/g, '') - .replace(/^\.+/, '') - .replace(/[/\\]+/g, sep) - .replace(/\\/g, '/'); + .replace(regex.dotBar, '') + .replace(regex.dot, '') + .replace(regex.sep, '/'); export const getDeepImports = (content: string): Set => { const paths: Set = new Set(); @@ -25,9 +30,11 @@ export const getDeepImports = (content: string): Set => { line.indexOf('require') !== -1 || line.indexOf(' from ') !== -1 ) { - const path = line.match(/['"](\.{1,2}\/[^'"]+)['"]/); + const path = line.match(regex.dependecy); - if (path) paths.add(normalizePath(path[1].replace(extFilter, ''))); + if (path) { + paths.add(normalizePath(path[1].replace(regex.extFilter, ''))); + } } } @@ -40,16 +47,17 @@ export const findMatchingFiles = ( ): Set => { const matchingFiles = new Set(); - srcFilesWithoutExt.forEach((srcFile) => { + for (const srcFile of srcFilesWithoutExt) { const normalizedSrcFile = normalizePath(srcFile); - srcFilesWithExt.forEach((fileWithExt) => { + for (const fileWithExt of srcFilesWithExt) { const normalizedFileWithExt = normalizePath(fileWithExt); - if (normalizedFileWithExt.includes(normalizedSrcFile)) + if (normalizedFileWithExt.includes(normalizedSrcFile)) { matchingFiles.add(fileWithExt); - }); - }); + } + } + } return matchingFiles; }; @@ -67,14 +75,17 @@ const collectTestFiles = async ( const listFilesPromises = stats.map((stat, index) => { const testPath = testPaths[index]; - if (stat.isDirectory()) + if (stat.isDirectory()) { return listFiles(testPath, { filter: testFilter, exclude, }); + } - if (stat.isFile() && extFilter.test(testPath)) return [testPath]; - else return []; + if (stat.isFile() && regex.extFilter.test(testPath)) { + return [testPath]; + } + return []; }); const nestedTestFiles = await Promise.all(listFilesPromises); @@ -89,7 +100,9 @@ const processDeepImports = async ( testFile: string, intersectedSrcFiles: Set ) => { - if (processedFiles.has(srcFile)) return; + if (processedFiles.has(srcFile)) { + return; + } processedFiles.add(srcFile); const srcContent = await readFile(srcFile, 'utf-8'); @@ -97,9 +110,11 @@ const processDeepImports = async ( const matchingFiles = findMatchingFiles(deepImports, intersectedSrcFiles); for (const deepImport of matchingFiles) { - if (!importMap.has(deepImport)) importMap.set(deepImport, new Set()); + if (!importMap.has(deepImport)) { + importMap.set(deepImport, new Set()); + } - importMap.get(deepImport)!.add(normalizePath(testFile)); + importMap.get(deepImport)?.add(normalizePath(testFile)); await processDeepImports(deepImport, testFile, intersectedSrcFiles); } @@ -126,12 +141,13 @@ const createImportMap = async ( /* c8 ignore start */ if ( - content.includes(relativePath.replace(extFilter, '')) || + content.includes(relativePath.replace(regex.extFilter, '')) || content.includes(normalizedSrcFile) ) { - if (!importMap.has(normalizedSrcFile)) + if (!importMap.has(normalizedSrcFile)) { importMap.set(normalizedSrcFile, new Set()); - importMap.get(normalizedSrcFile)!.add(normalizePath(testFile)); + } + importMap.get(normalizedSrcFile)?.add(normalizePath(testFile)); await processDeepImports(srcFile, testFile, intersectedSrcFiles); } @@ -151,7 +167,7 @@ export const mapTests = async ( const [allTestFiles, allSrcFiles] = await Promise.all([ collectTestFiles(testPaths, testFilter, exclude), listFiles(srcDir, { - filter: extFilter, + filter: regex.extFilter, exclude, }), ]); diff --git a/src/services/pid.ts b/src/services/pid.ts index 48f4eac1..3878ac95 100644 --- a/src/services/pid.ts +++ b/src/services/pid.ts @@ -2,10 +2,14 @@ import { spawn } from 'node:child_process'; import { forceArray } from '../helpers/force-array.js'; +const regex = { + sequentialSpaces: /\s+/, +} as const; + export const setPortsAndPIDs = (portOrPID: number | number[]) => forceArray(portOrPID) .map((p) => Number(p)) - .filter((p) => !isNaN(p)); + .filter((p) => !Number.isNaN(p)); export const populateRange = (startsAt: number, endsAt: number) => { const first = Number(startsAt); @@ -53,9 +57,11 @@ export const getPIDs = { service.stdout.on('data', (data: Buffer) => { const output = data.toString().trim().split('\n'); - output.forEach((pid) => { - if (pid) PIDs.add(Number(pid)); - }); + for (const pid of output) { + if (pid) { + PIDs.add(Number(pid)); + } + } }); service.on('close', () => { @@ -79,13 +85,15 @@ export const getPIDs = { * (Tested against ReDos Checker) */ lines.map((line) => { - const tokens = line.trim().split(/\s+/); + const tokens = line.trim().split(regex.sequentialSpaces); const stateIndex = tokens.indexOf('LISTENING'); if (stateIndex !== -1 && tokens[stateIndex + 1]) { const pid = Number(tokens[stateIndex + 1]); - if (!isNaN(pid)) PIDs.add(pid); + if (!Number.isNaN(pid)) { + PIDs.add(pid); + } } }); }); diff --git a/src/services/run-test-file.ts b/src/services/run-test-file.ts index 59be373a..a783d3c9 100644 --- a/src/services/run-test-file.ts +++ b/src/services/run-test-file.ts @@ -50,8 +50,11 @@ export const runTestFile = ( const start = hrtime(); let end: ReturnType; - /* c8 ignore next */ - if (!(await beforeEach(fileRelative, configs))) return false; + /* c8 ignore start */ + if (!(await beforeEach(fileRelative, configs))) { + return false; + } + /* c8 ignore stop */ // Export spawn helper is not an option const child = spawn(runtime, runtimeArguments, { @@ -73,20 +76,27 @@ export const runTestFile = ( const result = code === 0; - if (showLogs) + if (showLogs) { printOutput({ output, result, configs, }); + } - /* c8 ignore next */ - if (!(await afterEach(fileRelative, configs))) return false; + /* c8 ignore start */ + if (!(await afterEach(fileRelative, configs))) { + return false; + } + /* c8 ignore stop */ const total = (end[0] * 1e3 + end[1] / 1e6).toFixed(6); - if (result) fileResults.success.set(fileRelative, total); - else fileResults.fail.set(fileRelative, total); + if (result) { + fileResults.success.set(fileRelative, total); + } else { + fileResults.fail.set(fileRelative, total); + } resolve(result); }); diff --git a/src/services/run-tests.ts b/src/services/run-tests.ts index f84faf4c..fdc93966 100644 --- a/src/services/run-tests.ts +++ b/src/services/run-tests.ts @@ -1,4 +1,7 @@ -/* c8 ignore next */ +/* c8 ignore start */ // c8 bug (incompatibility) => +/** + * This service is strictly tested, but these tests use deep child process for it + */ import type { Configs } from '../@types/poku.js'; import { cwd as processCWD, hrtime } from 'node:process'; import { join, relative, sep } from 'node:path'; @@ -64,17 +67,14 @@ export const runTests = async ( } else { ++results.fail; - /* c8 ignore start */ if (showLogs) { write( `${indentation.test}${format('✘').fail()} ${log}${format(` › ${total}ms`).fail().dim()}${nextLine}` ); } - /* c8 ignore stop */ passed = false; - /* c8 ignore start */ if (configs?.failFast) { hr(); write( @@ -82,7 +82,6 @@ export const runTests = async ( ); break; } - /* c8 ignore stop */ } } @@ -101,29 +100,34 @@ export const runTestsParallel = async ( const concurrencyLimit = configs?.concurrency || 0; const concurrencyResults: (boolean | undefined)[][] = []; - if (concurrencyLimit > 0) + if (concurrencyLimit > 0) { for (let i = 0; i < files.length; i += concurrencyLimit) { filesByConcurrency.push(files.slice(i, i + concurrencyLimit)); } - else filesByConcurrency.push(files); + } else { + filesByConcurrency.push(files); + } try { for (const fileGroup of filesByConcurrency) { const promises = fileGroup.map(async (filePath) => { - if (configs?.failFast && results.fail > 0) return; + if (configs?.failFast && results.fail > 0) { + return; + } const testPassed = await runTestFile(filePath, configs); - /* c8 ignore start */ if (!testPassed) { ++results.fail; - if (configs?.failFast) - throw ` ${format('ℹ').fail()} ${format('fail-fast').bold()} is enabled`; + if (configs?.failFast) { + throw new Error( + ` ${format('ℹ').fail()} ${format('fail-fast').bold()} is enabled` + ); + } return false; } - /* c8 ignore stop */ ++results.success; return true; @@ -134,12 +138,10 @@ export const runTestsParallel = async ( } return concurrencyResults.every((group) => group.every((result) => result)); - /* c8 ignore start */ } catch (error) { hr(); - console.error(error); + error instanceof Error && console.error(error.message); return false; } - /* c8 ignore stop */ }; diff --git a/src/services/watch.ts b/src/services/watch.ts index 635622c2..5f850dea 100644 --- a/src/services/watch.ts +++ b/src/services/watch.ts @@ -18,8 +18,11 @@ class Watcher { } private watchFile(filePath: string) { - /* c8 ignore next */ - if (this.fileWatchers.has(filePath)) return; + /* c8 ignore start */ + if (this.fileWatchers.has(filePath)) { + return; + } + /* c8 ignore stop */ const watcher = nodeWatch(filePath, (eventType) => { this.callback(filePath, eventType); @@ -51,7 +54,9 @@ class Watcher { private async watchDirectory(dir: string) { /* c8 ignore next */ - if (this.dirWatchers.has(dir)) return; + if (this.dirWatchers.has(dir)) { + return; + } const watcher = nodeWatch(dir, async (_, filename) => { if (filename) { @@ -62,7 +67,9 @@ class Watcher { try { const stats = await stat(fullPath); - if (stats.isDirectory()) await this.watchDirectory(fullPath); + if (stats.isDirectory()) { + await this.watchDirectory(fullPath); + } /* c8 ignore start */ } catch {} /* c8 ignore stop */ @@ -96,7 +103,9 @@ class Watcher { this.watchFiles(this.files); await this.watchDirectory(this.rootDir); - } else this.watchFile(this.rootDir); + } else { + this.watchFile(this.rootDir); + } /* c8 ignore start */ } catch {} /* c8 ignore stop */ // c8 bug diff --git a/test/compatibility-by-dockerfile/bun-canary.test.ts b/test/compatibility-by-dockerfile/bun-canary.test.ts index 4625ebd4..7dca81eb 100644 --- a/test/compatibility-by-dockerfile/bun-canary.test.ts +++ b/test/compatibility-by-dockerfile/bun-canary.test.ts @@ -18,8 +18,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await dockerfile.start(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/bun-canary.test.ts b/test/compatibility/bun-canary.test.ts index 0d856995..93218518 100644 --- a/test/compatibility/bun-canary.test.ts +++ b/test/compatibility/bun-canary.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/bun-latest.test.ts b/test/compatibility/bun-latest.test.ts index 95634979..e8b59abf 100644 --- a/test/compatibility/bun-latest.test.ts +++ b/test/compatibility/bun-latest.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/deno-latest.test.ts b/test/compatibility/deno-latest.test.ts index ab3a5af0..5d172cb7 100644 --- a/test/compatibility/deno-latest.test.ts +++ b/test/compatibility/deno-latest.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-06.test.ts b/test/compatibility/node-06.test.ts index 13e055b4..08214e5f 100644 --- a/test/compatibility/node-06.test.ts +++ b/test/compatibility/node-06.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-07.test.ts b/test/compatibility/node-07.test.ts index 895fe841..c04c3a5a 100644 --- a/test/compatibility/node-07.test.ts +++ b/test/compatibility/node-07.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-08.test.ts b/test/compatibility/node-08.test.ts index ba2e15eb..1a1d976b 100644 --- a/test/compatibility/node-08.test.ts +++ b/test/compatibility/node-08.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-09.test.ts b/test/compatibility/node-09.test.ts index 4956e92c..6ffbff5c 100644 --- a/test/compatibility/node-09.test.ts +++ b/test/compatibility/node-09.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-10.test.ts b/test/compatibility/node-10.test.ts index f5717e24..c2a48f6b 100644 --- a/test/compatibility/node-10.test.ts +++ b/test/compatibility/node-10.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-11.test.ts b/test/compatibility/node-11.test.ts index 145b57e5..b808c0cd 100644 --- a/test/compatibility/node-11.test.ts +++ b/test/compatibility/node-11.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-12.test.ts b/test/compatibility/node-12.test.ts index 328de6d0..a0b63406 100644 --- a/test/compatibility/node-12.test.ts +++ b/test/compatibility/node-12.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-13.test.ts b/test/compatibility/node-13.test.ts index 52ea0686..fb11bf9e 100644 --- a/test/compatibility/node-13.test.ts +++ b/test/compatibility/node-13.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-14.test.ts b/test/compatibility/node-14.test.ts index c73b0212..cb50e892 100644 --- a/test/compatibility/node-14.test.ts +++ b/test/compatibility/node-14.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-15.test.ts b/test/compatibility/node-15.test.ts index b4422675..663d1989 100644 --- a/test/compatibility/node-15.test.ts +++ b/test/compatibility/node-15.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-16.test.ts b/test/compatibility/node-16.test.ts index dc966622..5b740c28 100644 --- a/test/compatibility/node-16.test.ts +++ b/test/compatibility/node-16.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-17.test.ts b/test/compatibility/node-17.test.ts index 26035c08..fbe3b009 100644 --- a/test/compatibility/node-17.test.ts +++ b/test/compatibility/node-17.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-18.test.ts b/test/compatibility/node-18.test.ts index 7d4581b8..54176e37 100644 --- a/test/compatibility/node-18.test.ts +++ b/test/compatibility/node-18.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-19.test.ts b/test/compatibility/node-19.test.ts index f12211c3..a7ae6df2 100644 --- a/test/compatibility/node-19.test.ts +++ b/test/compatibility/node-19.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-20.test.ts b/test/compatibility/node-20.test.ts index b9c645c9..7e54e3c0 100644 --- a/test/compatibility/node-20.test.ts +++ b/test/compatibility/node-20.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-21.test.ts b/test/compatibility/node-21.test.ts index cf5922cb..2bb062ca 100644 --- a/test/compatibility/node-21.test.ts +++ b/test/compatibility/node-21.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/compatibility/node-latest.test.ts b/test/compatibility/node-latest.test.ts index 4f3e15df..24169f42 100644 --- a/test/compatibility/node-latest.test.ts +++ b/test/compatibility/node-latest.test.ts @@ -24,8 +24,9 @@ test(`Compatibility Tests: ${serviceName}`, async () => { const result = await compose.up(); - if (!result) + if (!result) { assert.fail(`See the logs by running \`docker logs ${serviceName}\``); + } await dockerfile.remove(); }); diff --git a/test/e2e/before-and-after-each.test.ts b/test/e2e/before-and-after-each.test.ts new file mode 100644 index 00000000..c120f946 --- /dev/null +++ b/test/e2e/before-and-after-each.test.ts @@ -0,0 +1,163 @@ +import { test } from '../../src/modules/test.js'; +import { describe } from '../../src/modules/describe.js'; +import { it } from '../../src/modules/it.js'; +import { poku } from '../../src/modules/poku.js'; +import { assert } from '../../src/modules/assert.js'; + +test(async () => { + const prepareService = () => new Promise((resolve) => resolve(undefined)); + const resetService = () => new Promise((resolve) => resolve(undefined)); + // const crashIt = () => new Promise((_, reject) => reject("Let's crash it")); + + await describe('Before and After Each: direct methods', async () => { + await it(async () => { + const code = await poku('./fixtures/success', { + noExit: true, + quiet: true, + beforeEach: prepareService, + afterEach: resetService, + }); + + assert.equal( + code, + 0, + 'beforeEach and afterEach hooks with successful path' + ); + }); + + await it(async () => { + const code = await poku('./fixtures/fail', { + noExit: true, + quiet: true, + beforeEach: prepareService, + afterEach: resetService, + }); + + assert.equal(code, 1, 'beforeEach and afterEach hooks with failing path'); + }); + }); + + await describe('Before and After Each: called methods', async () => { + await it(async () => { + const code = await poku('./fixtures/success', { + noExit: true, + quiet: true, + beforeEach: () => prepareService(), + afterEach: () => resetService(), + }); + + assert.equal( + code, + 0, + 'beforeEach and afterEach hooks with successful path' + ); + }); + + await it(async () => { + const code = await poku('./fixtures/fail', { + noExit: true, + quiet: true, + beforeEach: () => prepareService(), + afterEach: () => resetService(), + }); + + assert.equal(code, 1, 'beforeEach and afterEach hooks with failing path'); + }); + }); + + await describe('Before and After Each: await called methods', async () => { + await it(async () => { + const code = await poku('./fixtures/success', { + noExit: true, + quiet: true, + beforeEach: async () => await prepareService(), + afterEach: async () => await resetService(), + }); + + assert.equal( + code, + 0, + 'beforeEach and afterEach hooks with successful path' + ); + }); + + await it(async () => { + const code = await poku('./fixtures/fail', { + noExit: true, + quiet: true, + beforeEach: async () => await prepareService(), + afterEach: async () => await resetService(), + }); + + assert.equal(code, 1, 'beforeEach and afterEach hooks with failing path'); + }); + }); + + await describe('Before and After Each: anonymous methods', async () => { + await it(async () => { + const code = await poku('./fixtures/success', { + noExit: true, + quiet: true, + beforeEach: () => true, + afterEach: () => true, + }); + + assert.equal( + code, + 0, + 'beforeEach and afterEach hooks with successful path' + ); + }); + + await it(async () => { + const code = await poku('./fixtures/fail', { + noExit: true, + quiet: true, + beforeEach: () => true, + afterEach: () => true, + }); + + assert.equal(code, 1, 'beforeEach and afterEach hooks with failing path'); + }); + }); + + await describe('Before and After Each: anonymous methods (function)', async () => { + await it(async () => { + const code = await poku('./fixtures/success', { + noExit: true, + quiet: true, + // biome-ignore lint/complexity/useArrowFunction: + beforeEach: function () { + return; + }, + // biome-ignore lint/complexity/useArrowFunction: + afterEach: function () { + return; + }, + }); + + assert.equal( + code, + 0, + 'beforeEach and afterEach hooks with successful path' + ); + }); + + await it(async () => { + const code = await poku('./fixtures/fail', { + noExit: true, + quiet: true, + // biome-ignore lint/complexity/useArrowFunction: + beforeEach: function () { + return; + }, + // biome-ignore lint/complexity/useArrowFunction: + afterEach: function () { + return; + }, + }); + + assert.equal(code, 1, 'beforeEach and afterEach hooks with failing path'); + }); + }); +}); diff --git a/test/e2e/cli.test.ts b/test/e2e/cli.test.ts index a46a4a6a..cab302c9 100644 --- a/test/e2e/cli.test.ts +++ b/test/e2e/cli.test.ts @@ -5,7 +5,9 @@ import { getRuntime } from '../../src/helpers/get-runtime.js'; const runtime = getRuntime(); -if (runtime === 'deno' && !isProduction) process.exit(0); +if (runtime === 'deno' && !isProduction) { + process.exit(0); +} test('Poku Test Runner: CLI', async () => { const output = await executeCLI([ diff --git a/test/helpers/capture-cli.test.ts b/test/helpers/capture-cli.test.ts index aec4a697..05e22340 100644 --- a/test/helpers/capture-cli.test.ts +++ b/test/helpers/capture-cli.test.ts @@ -19,7 +19,7 @@ export const executeCLI = (args: string[]): Promise => shell: isWindows, }); - let output: string = ''; + let output = ''; childProcess.stdout.on('data', (data: Buffer) => { output += data.toString(); diff --git a/test/integration/before-and-after-each/external-file-update.test.ts b/test/integration/before-and-after-each/external-file-update.test.ts new file mode 100644 index 00000000..48f6570d --- /dev/null +++ b/test/integration/before-and-after-each/external-file-update.test.ts @@ -0,0 +1,58 @@ +import process from 'node:process'; +import { nodeVersion, getRuntime } from '../../../src/helpers/get-runtime.js'; + +if (nodeVersion && nodeVersion < 16) { + process.exit(0); +} + +import fs from 'node:fs'; +import path from 'node:path'; +import { test } from '../../../src/modules/test.js'; +import { poku } from '../../../src/modules/poku.js'; +import { assert } from '../../../src/modules/assert.js'; + +const runtime = getRuntime(); + +if (runtime === 'deno') { + process.exit(0); +} + +const jsonFilePath = path.resolve('./test-before-and-after-each.json'); + +test('Before and After Each: updating an external file', async () => { + const prepareService = () => { + fs.writeFileSync(jsonFilePath, JSON.stringify({ value: 1 })); + }; + + const resetService = () => { + const data = fs.readFileSync(jsonFilePath, 'utf-8'); + const json = JSON.parse(data); + + json.value += 1; + + fs.writeFileSync(jsonFilePath, JSON.stringify(json)); + }; + + const exitCode = await poku( + './fixtures/before-after-each/integration.test.cjs', + { + noExit: true, + quiet: true, + beforeEach: () => prepareService(), + afterEach: () => resetService(), + } + ); + + const finalData = fs.readFileSync(jsonFilePath, 'utf-8'); + const finalJson = JSON.parse(finalData); + + fs.unlinkSync(jsonFilePath); + + assert.strictEqual(exitCode, 0, 'Fixture should be passed'); + + assert.deepStrictEqual( + finalJson.value, + 3, + 'Value should be incremented to 3' + ); +}); diff --git a/test/integration/containers/test-docker-compose.test.ts b/test/integration/containers/test-docker-compose.test.ts index b0607ba5..e9677bae 100644 --- a/test/integration/containers/test-docker-compose.test.ts +++ b/test/integration/containers/test-docker-compose.test.ts @@ -10,7 +10,9 @@ import { isWindows } from '../../../src/helpers/runner.js'; import { waitForPort } from '../../../src/modules/wait-for.js'; // External error: no matching manifest for windows/amd64 -if (isWindows) process.exit(0); +if (isWindows) { + process.exit(0); +} const hasDockerCompose = (() => { try { diff --git a/test/integration/containers/test-dockerfile.test.ts b/test/integration/containers/test-dockerfile.test.ts index 30e0c4a8..a62a675e 100644 --- a/test/integration/containers/test-dockerfile.test.ts +++ b/test/integration/containers/test-dockerfile.test.ts @@ -10,7 +10,9 @@ import { legacyFetch } from '../../helpers/legacy-fetch.test.js'; import { isWindows } from '../../../src/helpers/runner.js'; // External error: no matching manifest for windows/amd64 -if (isWindows) process.exit(0); +if (isWindows) { + process.exit(0); +} const hasDocker = (() => { try { diff --git a/test/integration/wait-for/wait-for-port.test.ts b/test/integration/wait-for/wait-for-port.test.ts index 2e511909..0b67ae23 100644 --- a/test/integration/wait-for/wait-for-port.test.ts +++ b/test/integration/wait-for/wait-for-port.test.ts @@ -1,4 +1,4 @@ -import { createServer, Server } from 'node:http'; +import { createServer, type Server } from 'node:http'; import { test } from '../../../src/modules/test.js'; import { it } from '../../../src/modules/it.js'; import { assert } from '../../../src/modules/assert.js'; @@ -31,7 +31,7 @@ test('Wait For Port', async () => { try { await waitForPort(port, { timeout: 5000 }); assert.ok(true, 'Port is active within timeout'); - } catch (error) { + } catch { assert.fail('Port was not active within the timeout period'); } finally { await stopServer(server); @@ -45,7 +45,7 @@ test('Wait For Port', async () => { try { await waitForPort(port, { delay: 100 }); assert.ok(true, 'Port is active within delay'); - } catch (error) { + } catch { assert.fail('Port was not active within the timeout period'); } finally { await stopServer(server); @@ -61,7 +61,7 @@ test('Wait For Port', async () => { } catch (error) { assert.strictEqual( (error as Error).message, - `Timeout`, + 'Timeout', 'Expected timeout for missing port' ); } @@ -74,7 +74,7 @@ test('Wait For Port', async () => { try { await waitForPort(port, { interval: 1000 }); assert.ok(true, 'Port is active within delay'); - } catch (error) { + } catch { assert.fail('Port was not active within the timeout period'); } finally { await stopServer(server); @@ -83,7 +83,7 @@ test('Wait For Port', async () => { it(async () => { try { - await waitForPort(NaN, { timeout: 2000 }); + await waitForPort(Number.NaN, { timeout: 2000 }); assert.fail('Expected error for invalid port, but none was thrown'); } catch (error) { assert.strictEqual( diff --git a/test/unit/assert-find-file.test.ts b/test/unit/assert-find-file.test.ts index 9635d705..45a46704 100644 --- a/test/unit/assert-find-file.test.ts +++ b/test/unit/assert-find-file.test.ts @@ -69,10 +69,10 @@ const testCases = [ ]; test('Assert: Find file from stack', () => { - testCases.forEach(({ description, stack, expected }) => { + for (const { description, stack, expected } of testCases) { const error = setStack(stack); const result = findFile(error); assert.deepStrictEqual(result, expected, description); - }); + } }); diff --git a/test/unit/assert-result-type.test.ts b/test/unit/assert-result-type.test.ts index 949abe54..bcab462b 100644 --- a/test/unit/assert-result-type.test.ts +++ b/test/unit/assert-result-type.test.ts @@ -54,6 +54,7 @@ test('Assert: Parse Result Type', async () => { assert( /function/.test( + // biome-ignore lint/complexity/useArrowFunction: parseResultType(function () { return; }) @@ -62,6 +63,7 @@ test('Assert: Parse Result Type', async () => { ); assert( /function/.test( + // biome-ignore lint/complexity/useArrowFunction: parseResultType(function (a: number) { return a; }) @@ -70,6 +72,7 @@ test('Assert: Parse Result Type', async () => { ); assert( /function/.test( + // biome-ignore lint/complexity/useArrowFunction: parseResultType(function (a: number, b: number) { return a + b; }) @@ -104,7 +107,7 @@ test('Assert: Parse Result Type', async () => { ]`, 'Array' ); - assert.deepStrictEqual(parseResultType([]), `[]`, 'Array (Empty)'); + assert.deepStrictEqual(parseResultType([]), '[]', 'Array (Empty)'); assert.deepStrictEqual( parseResultType([ 1, diff --git a/test/unit/deno/cjs.test.ts b/test/unit/deno/cjs.test.ts index 5d2efc83..695977aa 100644 --- a/test/unit/deno/cjs.test.ts +++ b/test/unit/deno/cjs.test.ts @@ -6,7 +6,9 @@ import { getRuntime } from '../../../src/helpers/get-runtime.js'; const runtime = getRuntime(); -if (runtime !== 'deno') process.exit(0); +if (runtime !== 'deno') { + process.exit(0); +} test('Deno Compatibility', async () => { const FILE = './fixtures/deno/require.cjs'; @@ -18,7 +20,7 @@ test('Deno Compatibility', async () => { const denoProcess = spawn(command, args, { env }); - let output: string = ''; + let output = ''; denoProcess.stdout.on('data', (data) => { output += String(data); diff --git a/test/unit/map-tests.test.ts b/test/unit/map-tests.test.ts index 974ef464..d10e5783 100644 --- a/test/unit/map-tests.test.ts +++ b/test/unit/map-tests.test.ts @@ -1,7 +1,9 @@ import process from 'node:process'; import { nodeVersion } from '../../src/helpers/get-runtime.js'; -if (nodeVersion && nodeVersion < 14) process.exit(0); +if (nodeVersion && nodeVersion < 14) { + process.exit(0); +} import { join } from 'node:path'; import { writeFileSync, mkdirSync, rmSync } from 'node:fs'; diff --git a/test/unit/wait-for/sleep.test.ts b/test/unit/wait-for/sleep.test.ts index 62c4df48..11ce83fc 100644 --- a/test/unit/wait-for/sleep.test.ts +++ b/test/unit/wait-for/sleep.test.ts @@ -7,10 +7,10 @@ test('Sleep "mini" helper', async () => { const delay = 500; await sleep(delay); const elapsedTime = Date.now() - startTime; - const margin = 250; + const margin = 500; assert.ok( elapsedTime >= delay - margin && elapsedTime <= delay + margin, - `Expected sleep time to be around ${delay}ms (±${margin}ms), but was ${elapsedTime}ms` + `Expected sleep time to be around ${delay}ms (±${margin}ms): Elapsed ${elapsedTime}ms` ); }); diff --git a/test/unit/wait-for/wait-for-expected-result.test.ts b/test/unit/wait-for/wait-for-expected-result.test.ts index e6f041da..d56ea536 100644 --- a/test/unit/wait-for/wait-for-expected-result.test.ts +++ b/test/unit/wait-for/wait-for-expected-result.test.ts @@ -144,7 +144,7 @@ test('Wait For Expected Result', async () => { assert.doesNotReject( () => - waitForExpectedResult(() => new Error(''), new Error(''), { + waitForExpectedResult(() => new Error('Some'), new Error('Some'), { timeout: 100, }), 'Error' diff --git a/test/unit/watch.test.ts b/test/unit/watch.test.ts index 9f9e02c9..bf317709 100644 --- a/test/unit/watch.test.ts +++ b/test/unit/watch.test.ts @@ -9,7 +9,9 @@ import { getRuntime, nodeVersion } from '../../src/helpers/get-runtime.js'; import { watch } from '../../src/services/watch.js'; import type { WatchCallback } from '../../src/@types/watch.js'; -if (nodeVersion && nodeVersion < 10) process.exit(0); +if (nodeVersion && nodeVersion < 10) { + process.exit(0); +} const runtime = getRuntime(); @@ -79,8 +81,12 @@ describe('Watcher Service', async () => { }); await it('should watch for new files in directory', async () => { - if (runtime === 'bun') return; - if (runtime === 'deno') return; + if (runtime === 'bun') { + return; + } + if (runtime === 'deno') { + return; + } callbackResults = []; @@ -135,8 +141,9 @@ describe('Watcher Service', async () => { }); await it('should watch for changes in subdirectories', async () => { - if (runtime === 'bun') return; - if (runtime === 'deno') return; + if (runtime === 'bun' || runtime === 'deno') { + return; + } callbackResults = []; const watcher = await watch(tmpDir, callback); @@ -173,8 +180,12 @@ describe('Watcher Service', async () => { }); await it('should watch for changes in nested subdirectories', async () => { - if (runtime === 'bun') return; - if (runtime === 'deno') return; + if (runtime === 'bun') { + return; + } + if (runtime === 'deno') { + return; + } callbackResults = []; const watcher = await watch(tmpDir, callback); @@ -212,7 +223,9 @@ describe('Watcher Service', async () => { }); await it('should watch a single file directly', async () => { - if (runtime === 'bun') return; + if (runtime === 'bun') { + return; + } callbackResults = []; const filePath = path.join(tmpDir, 'file1.test.js'); diff --git a/tsconfig.test.json b/tsconfig.test.json index 3908bcc3..f1257b73 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -5,6 +5,7 @@ "compilerOptions": { "outDir": "ci", "declaration": false, + "allowJs": true, "declarationDir": null } } diff --git a/website/package-lock.json b/website/package-lock.json index 4498c5ba..06d71480 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -30,7 +30,7 @@ "@docusaurus/tsconfig": "^3.4.0", "@docusaurus/types": "^3.4.0", "@types/bun": "^1.1.5", - "@types/node": "^20.14.8", + "@types/node": "^20.14.9", "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.14.1", "eslint": "^8.57.0", @@ -40,7 +40,7 @@ "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "packages-update": "^2.0.0", - "poku": "^1.19.0", + "poku": "^1.20.0", "prettier": "^3.3.2", "svps": "^2.3.0", "tsx": "^4.15.7", @@ -96,82 +96,82 @@ } }, "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.3.tgz", - "integrity": "sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", "license": "MIT", "dependencies": { - "@algolia/cache-common": "4.23.3" + "@algolia/cache-common": "4.24.0" } }, "node_modules/@algolia/cache-common": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.23.3.tgz", - "integrity": "sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==", "license": "MIT" }, "node_modules/@algolia/cache-in-memory": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.23.3.tgz", - "integrity": "sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", "license": "MIT", "dependencies": { - "@algolia/cache-common": "4.23.3" + "@algolia/cache-common": "4.24.0" } }, "node_modules/@algolia/client-account": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.23.3.tgz", - "integrity": "sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", "license": "MIT", "dependencies": { - "@algolia/client-common": "4.23.3", - "@algolia/client-search": "4.23.3", - "@algolia/transporter": "4.23.3" + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-analytics": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.23.3.tgz", - "integrity": "sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "4.23.3", - "@algolia/client-search": "4.23.3", - "@algolia/requester-common": "4.23.3", - "@algolia/transporter": "4.23.3" + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-common": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.23.3.tgz", - "integrity": "sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", "license": "MIT", "dependencies": { - "@algolia/requester-common": "4.23.3", - "@algolia/transporter": "4.23.3" + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-personalization": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.23.3.tgz", - "integrity": "sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", "license": "MIT", "dependencies": { - "@algolia/client-common": "4.23.3", - "@algolia/requester-common": "4.23.3", - "@algolia/transporter": "4.23.3" + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-search": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.23.3.tgz", - "integrity": "sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", "license": "MIT", "dependencies": { - "@algolia/client-common": "4.23.3", - "@algolia/requester-common": "4.23.3", - "@algolia/transporter": "4.23.3" + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/events": { @@ -181,72 +181,72 @@ "license": "MIT" }, "node_modules/@algolia/logger-common": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.23.3.tgz", - "integrity": "sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==", "license": "MIT" }, "node_modules/@algolia/logger-console": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.23.3.tgz", - "integrity": "sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", "license": "MIT", "dependencies": { - "@algolia/logger-common": "4.23.3" + "@algolia/logger-common": "4.24.0" } }, "node_modules/@algolia/recommend": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.23.3.tgz", - "integrity": "sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", "license": "MIT", "dependencies": { - "@algolia/cache-browser-local-storage": "4.23.3", - "@algolia/cache-common": "4.23.3", - "@algolia/cache-in-memory": "4.23.3", - "@algolia/client-common": "4.23.3", - "@algolia/client-search": "4.23.3", - "@algolia/logger-common": "4.23.3", - "@algolia/logger-console": "4.23.3", - "@algolia/requester-browser-xhr": "4.23.3", - "@algolia/requester-common": "4.23.3", - "@algolia/requester-node-http": "4.23.3", - "@algolia/transporter": "4.23.3" + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.3.tgz", - "integrity": "sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", "license": "MIT", "dependencies": { - "@algolia/requester-common": "4.23.3" + "@algolia/requester-common": "4.24.0" } }, "node_modules/@algolia/requester-common": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.23.3.tgz", - "integrity": "sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==", "license": "MIT" }, "node_modules/@algolia/requester-node-http": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.23.3.tgz", - "integrity": "sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", "license": "MIT", "dependencies": { - "@algolia/requester-common": "4.23.3" + "@algolia/requester-common": "4.24.0" } }, "node_modules/@algolia/transporter": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.23.3.tgz", - "integrity": "sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", "license": "MIT", "dependencies": { - "@algolia/cache-common": "4.23.3", - "@algolia/logger-common": "4.23.3", - "@algolia/requester-common": "4.23.3" + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" } }, "node_modules/@ampproject/remapping": { @@ -4118,6 +4118,7 @@ "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.1.5.tgz", "integrity": "sha512-7RprVDMF+1o+EWSo7F1+iJpkfNz+Ikw9K//vwambcY+D1QHXfb9l7jWY1hSBfuFEkW9yFAhkMzP2uTi1pQXoqw==", "dev": true, + "license": "MIT", "dependencies": { "bun-types": "1.1.14" } @@ -4198,9 +4199,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.3", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz", - "integrity": "sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==", + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -4322,9 +4323,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", - "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", "license": "MIT", "dependencies": { "undici-types": "~5.26.4" @@ -4483,9 +4484,9 @@ } }, "node_modules/@types/ssh2/node_modules/@types/node": { - "version": "18.19.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz", - "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==", + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5042,9 +5043,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -5072,10 +5073,13 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -5167,32 +5171,32 @@ } }, "node_modules/algoliasearch": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.23.3.tgz", - "integrity": "sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==", - "license": "MIT", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.23.3", - "@algolia/cache-common": "4.23.3", - "@algolia/cache-in-memory": "4.23.3", - "@algolia/client-account": "4.23.3", - "@algolia/client-analytics": "4.23.3", - "@algolia/client-common": "4.23.3", - "@algolia/client-personalization": "4.23.3", - "@algolia/client-search": "4.23.3", - "@algolia/logger-common": "4.23.3", - "@algolia/logger-console": "4.23.3", - "@algolia/recommend": "4.23.3", - "@algolia/requester-browser-xhr": "4.23.3", - "@algolia/requester-common": "4.23.3", - "@algolia/requester-node-http": "4.23.3", - "@algolia/transporter": "4.23.3" + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", + "license": "MIT", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/algoliasearch-helper": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.21.0.tgz", - "integrity": "sha512-hjVOrL15I3Y3K8xG0icwG1/tWE+MocqBrhW6uVBWpU+/kVEMK0BnM2xdssj6mZM61eJ4iRxHR0djEI3ENOpR8w==", + "version": "3.22.1", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.1.tgz", + "integrity": "sha512-fSxJ4YreH4kOME9CnKazbAn2tK/rvBoV37ETd6nTt4j7QfkcnW+c+F22WfuE9Q/sRpvOMnUwU/BXAVEiwW7p/w==", "license": "MIT", "dependencies": { "@algolia/events": "^4.0.1" @@ -5846,6 +5850,7 @@ "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.1.14.tgz", "integrity": "sha512-esfxOvECTkjEuUEHBOoOo590Qggf4b9cz5h29AOB2SKt3yZwG3LbAX4iIYwWZX7GnO7vaY5hIdcQygwN0xGdNw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" @@ -5856,6 +5861,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.14.tgz", "integrity": "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -5959,9 +5965,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001632", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001632.tgz", - "integrity": "sha512-udx3o7yHJfUxMLkGohMlVHCvFvWmirKh9JAH/d7WOLPetlH+LTL5cocMZ0t7oZx/mdlOWXti97xLZWc8uURRHg==", + "version": "1.0.30001636", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", + "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", "funding": [ { "type": "opencollective", @@ -7447,9 +7453,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.799", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.799.tgz", - "integrity": "sha512-3D3DwWkRTzrdEpntY0hMLYwj7SeBk1138CkPE8sBDSj3WzrzOiG2rHm3luw8jucpf+WiyLBCZyU9lMHyQI9M9Q==", + "version": "1.4.812", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz", + "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -7635,9 +7641,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", - "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", "license": "MIT" }, "node_modules/es-object-atoms": { @@ -8000,6 +8006,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", @@ -8353,13 +8360,12 @@ } }, "node_modules/estree-util-value-to-estree": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.1.tgz", - "integrity": "sha512-5mvUrF2suuv5f5cGDnDphIy4/gW86z82kl5qG6mM9z04SEQI4FB5Apmaw/TGEf3l55nLtMs5s51dmhUzvAHQCA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz", + "integrity": "sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag==", "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0", - "is-plain-obj": "^4.0.0" + "@types/estree": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/remcohaszing" @@ -9604,9 +9610,9 @@ } }, "node_modules/hast-util-raw": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.3.tgz", - "integrity": "sha512-ICWvVOF2fq4+7CMmtCPD5CM4QKjPbHpPotE6+8tDooV0ZuyJVUzHsrNX+O5NaRbieTf0F7FfeBOMAwi6Td0+yQ==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.4.tgz", + "integrity": "sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -10406,12 +10412,15 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10977,9 +10986,9 @@ } }, "node_modules/joi": { - "version": "17.13.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.1.tgz", - "integrity": "sha512-vaBlIKCyo4FCUtCm7Eu4QZd/q02bWcxfUO6YSXAZOWF6gzcLBeba8kwotUdYJjDLW8Cz8RywsSOqiNJZW0mNvg==", + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.3.0", @@ -11136,9 +11145,9 @@ } }, "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", + "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", "license": "MIT", "dependencies": { "picocolors": "^1.0.0", @@ -13654,9 +13663,9 @@ "license": "ISC" }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -13707,9 +13716,9 @@ } }, "node_modules/nan": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", - "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", "dev": true, "license": "MIT", "optional": true @@ -13864,10 +13873,13 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -14560,19 +14572,16 @@ } }, "node_modules/poku": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/poku/-/poku-1.19.0.tgz", - "integrity": "sha512-lzBftoieFZ6MS+XIIdyCjtpSIzKXZ+wr7cjjKcukd2F8YVJB4l0n4mFm+doWSHWr2oJO4CWKo+H3dJ8ws1pFfg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/poku/-/poku-1.20.0.tgz", + "integrity": "sha512-fUAcPrjYmu43IkC3UOuLNh2bAfoz5ygEJ4RJ7ecA6dQz9nmAlZKAhi/Sq4n+eAMbBJC9TCKiSF9092cIVEPk6g==", "dev": true, "license": "MIT", "bin": { "poku": "lib/bin/index.js" }, "engines": { - "bun": ">=0.5.3", - "deno": ">=1.17.0", - "node": ">=6.0.0", - "typescript": ">=5.0.2" + "node": ">=6.0.0" } }, "node_modules/possible-typed-array-names": { @@ -16391,6 +16400,7 @@ "version": "1.77.6", "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", + "license": "MIT", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -18001,9 +18011,9 @@ } }, "node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -18465,9 +18475,9 @@ } }, "node_modules/webpack": { - "version": "5.92.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.0.tgz", - "integrity": "sha512-Bsw2X39MYIgxouNATyVpCNVWBCuUwDgWtN78g6lSdPJRLaQ/PUVm/oXcaRAyY/sMFoKFQrsPeqvTizWtq7QPCA==", + "version": "5.92.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", + "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -18662,6 +18672,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -18995,6 +19006,7 @@ "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", "engines": { "node": ">=8.3.0" }, diff --git a/website/package.json b/website/package.json index 794093c4..2781cf5b 100644 --- a/website/package.json +++ b/website/package.json @@ -44,7 +44,7 @@ "@docusaurus/tsconfig": "^3.4.0", "@docusaurus/types": "^3.4.0", "@types/bun": "^1.1.5", - "@types/node": "^20.14.8", + "@types/node": "^20.14.9", "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.14.1", "eslint": "^8.57.0", @@ -54,7 +54,7 @@ "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "packages-update": "^2.0.0", - "poku": "^1.19.0", + "poku": "^1.20.0", "prettier": "^3.3.2", "svps": "^2.3.0", "tsx": "^4.15.7",