diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index ee0c04a618..eb85d0b5f1 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -365,15 +365,16 @@ } }, "node_modules/@ava/typescript": { - "version": "4.1.0", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ava/typescript/-/typescript-6.0.0.tgz", + "integrity": "sha512-+8oDYc4J5cCaWZh1VUbyc+cegGplJO9FqHpqR4LVAVx8fRLVRaYlC4yyA6cqHJ1vWP23Ff/ECS5U68Zz6OLZlg==", "dev": true, - "license": "MIT", "dependencies": { "escape-string-regexp": "^5.0.0", - "execa": "^7.1.1" + "execa": "^9.6.0" }, "engines": { - "node": "^14.19 || ^16.15 || ^18 || ^20" + "node": "^20.8 || ^22 || >=24" } }, "node_modules/@ava/typescript/node_modules/escape-string-regexp": { @@ -741,12 +742,20 @@ } }, "node_modules/@eslint/compat": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.1.1.tgz", - "integrity": "sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.3.1.tgz", + "integrity": "sha512-k8MHony59I5EPic6EQTCNOuPoVBnoYXkP+20xvwFjN7t0qI3ImyvyBgg+hIVPwC8JaxVjjUZld+cLfBLFDLucg==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^8.40 || 9" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/@eslint/eslintrc": { @@ -814,9 +823,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.28.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", - "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.0.tgz", + "integrity": "sha512-Wzw3wQwPvc9sHM+NjakWTcPx11mbZyiYHuwWa/QfZ7cIRX7WK54PSk7bdyXDaoaopUcMatv1zaQvOAAO8hCdww==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1749,6 +1758,24 @@ "version": "0.0.10", "license": "MIT" }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -1888,16 +1915,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", - "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz", + "integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/type-utils": "8.33.1", - "@typescript-eslint/utils": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/type-utils": "8.35.1", + "@typescript-eslint/utils": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -1911,19 +1938,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.33.1", + "@typescript-eslint/parser": "^8.35.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", - "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1934,9 +1961,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1947,15 +1974,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", - "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -1975,15 +2002,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", - "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz", + "integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1" + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1998,13 +2025,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", - "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2015,18 +2042,18 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2072,15 +2099,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", - "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz", + "integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4" }, "engines": { @@ -2096,13 +2123,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", - "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2113,9 +2140,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2126,15 +2153,15 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", - "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2154,13 +2181,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", - "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2171,18 +2198,18 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2219,13 +2246,13 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", - "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz", + "integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==", "dev": true, "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.33.1", - "@typescript-eslint/types": "^8.33.1", + "@typescript-eslint/tsconfig-utils": "^8.35.1", + "@typescript-eslint/types": "^8.35.1", "debug": "^4.3.4" }, "engines": { @@ -2240,9 +2267,9 @@ } }, "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2271,9 +2298,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", - "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz", + "integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2287,13 +2314,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", - "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz", + "integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.33.1", - "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/utils": "8.35.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -2310,13 +2337,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", - "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2327,9 +2354,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2340,15 +2367,15 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", - "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2368,15 +2395,15 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", - "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz", + "integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1" + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2391,13 +2418,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", - "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2408,18 +2435,18 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4312,24 +4339,6 @@ "eslint": "^8 || ^9" } }, - "node_modules/eslint-plugin-github/node_modules/@eslint/compat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.2.3.tgz", - "integrity": "sha512-wlZhwlDFxkxIZ571aH0FoK4h4Vwx7P3HJx62Gp8hTc10bfpwT2x0nULuAHmQSJBOWPgPeVf+9YtnD4j50zVHmA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": "^9.10.0" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, "node_modules/eslint-plugin-github/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -4826,27 +4835,85 @@ } }, "node_modules/execa": { - "version": "7.1.1", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", + "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", "dev": true, - "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" }, "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + "node": "^18.19.0 || >=20.5.0" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/execa/node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/pretty-ms": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", + "dev": true, + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fast-content-type-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", @@ -5061,18 +5128,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/form-data": { "version": "2.5.1", "license": "MIT", @@ -5200,11 +5255,16 @@ } }, "node_modules/get-stream": { - "version": "6.0.1", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "dev": true, - "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5458,11 +5518,12 @@ } }, "node_modules/human-signals": { - "version": "4.3.1", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", "dev": true, - "license": "Apache-2.0", "engines": { - "node": ">=14.18.0" + "node": ">=18.18.0" } }, "node_modules/ieee754": { @@ -5775,6 +5836,18 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-plain-object": { "version": "5.0.0", "license": "MIT", @@ -5818,11 +5891,12 @@ } }, "node_modules/is-stream": { - "version": "3.0.0", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, - "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6222,11 +6296,6 @@ "url": "https://github.com/sindresorhus/mem?sponsor=1" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/merge2": { "version": "1.4.1", "license": "MIT", @@ -6386,14 +6455,16 @@ } }, "node_modules/npm-run-path": { - "version": "5.1.0", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", "dev": true, - "license": "MIT", "dependencies": { - "path-key": "^4.0.0" + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6401,8 +6472,9 @@ }, "node_modules/npm-run-path/node_modules/path-key": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -6643,20 +6715,6 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.3", "dev": true, @@ -7364,14 +7422,20 @@ } }, "node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/sinon": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-20.0.0.tgz", - "integrity": "sha512-+FXOAbdnj94AQIxH0w1v8gzNxkawVvNqE3jUzRLptR71Oykeu2RrQXXl/VQjKay+Qnh73fDt/oDfMo6xMeDQbQ==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.0.tgz", + "integrity": "sha512-TOgRcwFPbfGtpqvZw+hyqJDvqfapr1qUlOizROIk4bBLjlsjlB00Pg6wMFXNtJRpu+eCZuVOaLatG7M8105kAw==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.1", @@ -7620,11 +7684,12 @@ } }, "node_modules/strip-final-newline": { - "version": "3.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", "dev": true, - "license": "MIT", "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8190,6 +8255,18 @@ "version": "5.26.5", "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universal-github-app-jwt": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-2.2.2.tgz", @@ -8426,17 +8503,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/write-file-atomic/node_modules/signal-exit": { - "version": "4.0.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/xml2js": { "version": "0.5.0", "license": "MIT", @@ -8499,6 +8565,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", + "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", diff --git a/node_modules/@ava/typescript/index.js b/node_modules/@ava/typescript/index.js index fb5b165062..dd1fc94ab3 100644 --- a/node_modules/@ava/typescript/index.js +++ b/node_modules/@ava/typescript/index.js @@ -4,8 +4,8 @@ import {pathToFileURL} from 'node:url'; import escapeStringRegexp from 'escape-string-regexp'; import {execa} from 'execa'; -const pkg = JSON.parse(fs.readFileSync(new URL('package.json', import.meta.url))); -const help = `See https://github.com/avajs/typescript/blob/v${pkg.version}/README.md`; +const package_ = JSON.parse(fs.readFileSync(new URL('package.json', import.meta.url))); +const help = `See https://github.com/avajs/typescript/blob/v${package_.version}/README.md`; function isPlainObject(x) { return x !== null && typeof x === 'object' && Reflect.getPrototypeOf(x) === Object.prototype; @@ -36,8 +36,8 @@ function validate(target, properties) { } } -async function compileTypeScript(projectDir) { - return execa('tsc', ['--incremental'], {preferLocal: true, cwd: projectDir}); +async function compileTypeScript(projectDirectory) { + return execa({preferLocal: true, cwd: projectDirectory})`tsc --incremental`; } const configProperties = { @@ -62,7 +62,7 @@ const configProperties = { isValid(extensions) { return Array.isArray(extensions) && extensions.length > 0 - && extensions.every(ext => typeof ext === 'string' && ext !== '') + && extensions.every(extension => typeof extension === 'string' && extension !== '') && new Set(extensions).size === extensions.length; }, }, @@ -75,7 +75,7 @@ const changeInterpretations = Object.freeze(Object.assign(Object.create(null), { })); export default function typescriptProvider({negotiateProtocol}) { - const protocol = negotiateProtocol(['ava-6', 'ava-3.2'], {version: pkg.version}); + const protocol = negotiateProtocol(['ava-6'], {version: package_.version}); if (protocol === null) { return; } @@ -98,143 +98,112 @@ export default function typescriptProvider({negotiateProtocol}) { path.join(protocol.projectDir, from), path.join(protocol.projectDir, to), ]); - const testFileExtension = new RegExp(`\\.(${extensions.map(ext => escapeStringRegexp(ext)).join('|')})$`); + const testFileExtension = new RegExp(`\\.(${extensions.map(extension => escapeStringRegexp(extension)).join('|')})$`); + + const watchMode = { + changeInterpretations, + interpretChange(filePath) { + if (config.compile === false) { + for (const [from] of rewritePaths) { + if (testFileExtension.test(filePath) && filePath.startsWith(from)) { + return changeInterpretations.waitForOutOfBandCompilation; + } + } + } - const watchMode = protocol.identifier === 'ava-3.2' - ? { - ignoreChange(filePath) { - if (!testFileExtension.test(filePath)) { - return false; + if (config.compile === 'tsc') { + for (const [, to] of rewritePaths) { + if (filePath.startsWith(to)) { + return changeInterpretations.ignoreCompiled; + } } + } - return rewritePaths.some(([from]) => filePath.startsWith(from)); - }, + return changeInterpretations.unspecified; + }, - resolveTestFile(testfile) { // Used under AVA 3.2 protocol by legacy watcher implementation. - if (!testFileExtension.test(testfile)) { - return testfile; - } + resolvePossibleOutOfBandCompilationSources(filePath) { + if (config.compile !== false) { + return null; + } - const rewrite = rewritePaths.find(([from]) => testfile.startsWith(from)); - if (rewrite === undefined) { - return testfile; - } + // Only recognize .cjs, .mjs and .js files. + if (!/\.(c|m)?js$/.test(filePath)) { + return null; + } - const [from, to] = rewrite; - let newExtension = '.js'; - if (testfile.endsWith('.cts')) { - newExtension = '.cjs'; - } else if (testfile.endsWith('.mts')) { - newExtension = '.mjs'; + for (const [from, to] of rewritePaths) { + if (!filePath.startsWith(to)) { + continue; } - return `${to}${testfile.slice(from.length)}`.replace(testFileExtension, newExtension); - }, - } - : { - changeInterpretations, - interpretChange(filePath) { - if (config.compile === false) { - for (const [from] of rewritePaths) { - if (testFileExtension.test(filePath) && filePath.startsWith(from)) { - return changeInterpretations.waitForOutOfBandCompilation; - } - } - } + const rewritten = `${from}${filePath.slice(to.length)}`; + const possibleExtensions = []; - if (config.compile === 'tsc') { - for (const [, to] of rewritePaths) { - if (filePath.startsWith(to)) { - return changeInterpretations.ignoreCompiled; - } + if (filePath.endsWith('.cjs')) { + if (extensions.includes('cjs')) { + possibleExtensions.push({replace: /\.cjs$/, extension: 'cjs'}); } - } - - return changeInterpretations.unspecified; - }, - resolvePossibleOutOfBandCompilationSources(filePath) { - if (config.compile !== false) { - return null; - } + if (extensions.includes('cts')) { + possibleExtensions.push({replace: /\.cjs$/, extension: 'cts'}); + } - // Only recognize .cjs, .mjs and .js files. - if (!/\.(c|m)?js$/.test(filePath)) { - return null; + if (possibleExtensions.length === 0) { + return null; + } } - for (const [from, to] of rewritePaths) { - if (!filePath.startsWith(to)) { - continue; + if (filePath.endsWith('.mjs')) { + if (extensions.includes('mjs')) { + possibleExtensions.push({replace: /\.mjs$/, extension: 'mjs'}); } - const rewritten = `${from}${filePath.slice(to.length)}`; - const possibleExtensions = []; - - if (filePath.endsWith('.cjs')) { - if (extensions.includes('cjs')) { - possibleExtensions.push({replace: /\.cjs$/, extension: 'cjs'}); - } - - if (extensions.includes('cts')) { - possibleExtensions.push({replace: /\.cjs$/, extension: 'cts'}); - } - - if (possibleExtensions.length === 0) { - return null; - } + if (extensions.includes('mts')) { + possibleExtensions.push({replace: /\.mjs$/, extension: 'mts'}); } - if (filePath.endsWith('.mjs')) { - if (extensions.includes('mjs')) { - possibleExtensions.push({replace: /\.mjs$/, extension: 'mjs'}); - } - - if (extensions.includes('mts')) { - possibleExtensions.push({replace: /\.mjs$/, extension: 'mts'}); - } - - if (possibleExtensions.length === 0) { - return null; - } + if (possibleExtensions.length === 0) { + return null; } + } - if (filePath.endsWith('.js')) { - if (extensions.includes('js')) { - possibleExtensions.push({replace: /\.js$/, extension: 'js'}); - } - - if (extensions.includes('ts')) { - possibleExtensions.push({replace: /\.js$/, extension: 'ts'}); - } + if (filePath.endsWith('.js')) { + if (extensions.includes('js')) { + possibleExtensions.push({replace: /\.js$/, extension: 'js'}); + } - if (extensions.includes('tsx')) { - possibleExtensions.push({replace: /\.js$/, extension: 'tsx'}); - } + if (extensions.includes('ts')) { + possibleExtensions.push({replace: /\.js$/, extension: 'ts'}); + } - if (possibleExtensions.length === 0) { - return null; - } + if (extensions.includes('tsx')) { + possibleExtensions.push({replace: /\.js$/, extension: 'tsx'}); } - const possibleDeletedFiles = []; - for (const {replace, extension} of possibleExtensions) { - const possibleFilePath = rewritten.replace(replace, `.${extension}`); + if (possibleExtensions.length === 0) { + return null; + } + } - // Pick the first file path that exists. - if (fs.existsSync(possibleFilePath)) { - return [possibleFilePath]; - } + const possibleDeletedFiles = []; + for (const {replace, extension} of possibleExtensions) { + const possibleFilePath = rewritten.replace(replace, `.${extension}`); - possibleDeletedFiles.push(possibleFilePath); + // Pick the first file path that exists. + if (fs.existsSync(possibleFilePath)) { + return [possibleFilePath]; } - return possibleDeletedFiles; + possibleDeletedFiles.push(possibleFilePath); } - return null; - }, - }; + return possibleDeletedFiles; + } + + return null; + }, + }; return { ...watchMode, @@ -276,21 +245,21 @@ export default function typescriptProvider({negotiateProtocol}) { worker({extensionsToLoadAsModules, state: {extensions, rewritePaths}}) { const importJs = extensionsToLoadAsModules.includes('js'); - const testFileExtension = new RegExp(`\\.(${extensions.map(ext => escapeStringRegexp(ext)).join('|')})$`); + const testFileExtension = new RegExp(`\\.(${extensions.map(extension => escapeStringRegexp(extension)).join('|')})$`); return { - canLoad(ref) { - return testFileExtension.test(ref) && rewritePaths.some(([from]) => ref.startsWith(from)); + canLoad(reference) { + return testFileExtension.test(reference) && rewritePaths.some(([from]) => reference.startsWith(from)); }, - async load(ref, {requireFn}) { - const [from, to] = rewritePaths.find(([from]) => ref.startsWith(from)); - let rewritten = `${to}${ref.slice(from.length)}`; + async load(reference, {requireFn}) { + const [from, to] = rewritePaths.find(([from]) => reference.startsWith(from)); + let rewritten = `${to}${reference.slice(from.length)}`; let useImport = true; - if (ref.endsWith('.cts')) { + if (reference.endsWith('.cts')) { rewritten = rewritten.replace(/\.cts$/, '.cjs'); useImport = false; - } else if (ref.endsWith('.mts')) { + } else if (reference.endsWith('.mts')) { rewritten = rewritten.replace(/\.mts$/, '.mjs'); } else { rewritten = rewritten.replace(testFileExtension, '.js'); diff --git a/node_modules/@ava/typescript/package.json b/node_modules/@ava/typescript/package.json index 3160f9a17d..127b75a474 100644 --- a/node_modules/@ava/typescript/package.json +++ b/node_modules/@ava/typescript/package.json @@ -1,9 +1,9 @@ { "name": "@ava/typescript", - "version": "4.1.0", + "version": "6.0.0", "description": "TypeScript provider for AVA", "engines": { - "node": "^14.19 || ^16.15 || ^18 || ^20" + "node": "^20.8 || ^22 || >=24" }, "files": [ "index.js" @@ -24,36 +24,17 @@ }, "dependencies": { "escape-string-regexp": "^5.0.0", - "execa": "^7.1.1" + "execa": "^9.6.0" }, "devDependencies": { - "ava": "^5.3.1", - "c8": "^8.0.0", - "del": "^7.0.0", - "typescript": "^5.1.3", - "xo": "^0.54.2" + "ava": "^6.4.0", + "c8": "^10.1.3", + "del": "^8.0.0", + "typescript": "^5.8.3", + "xo": "^1.1.0" }, - "c8": { - "reporter": [ - "html", - "lcov", - "text" - ] - }, - "ava": { - "files": [ - "!test/broken-fixtures/**" - ], - "ignoredByWatcher": [ - "test/fixtures/**", - "test/broken-fixtures/**" - ], - "timeout": "60s" - }, - "xo": { - "ignores": [ - "test/broken-fixtures", - "test/fixtures/**/compiled/**" - ] + "volta": { + "node": "22.16.0", + "npm": "11.4.2" } } diff --git a/node_modules/@eslint/compat/README.md b/node_modules/@eslint/compat/README.md index 15f5d17196..911bac9c58 100644 --- a/node_modules/@eslint/compat/README.md +++ b/node_modules/@eslint/compat/README.md @@ -17,7 +17,7 @@ yarn add @eslint/compat -D # or pnpm install @eslint/compat -D # or -bun install @eslint/compat -D +bun add @eslint/compat -D ``` For Deno: @@ -30,10 +30,10 @@ deno add @eslint/compat This package exports the following functions in both ESM and CommonJS format: -- `fixupRule(rule)` - wraps the given rule in a compatibility layer and returns the result -- `fixupPluginRules(plugin)` - wraps each rule in the given plugin using `fixupRule()` and returns a new object that represents the plugin with the fixed-up rules -- `fixupConfigRules(configs)` - wraps all plugins found in an array of config objects using `fixupPluginRules()` -- `includeIgnoreFile(path)` - reads an ignore file (like `.gitignore`) and converts the patterns into the correct format for the config file +- `fixupRule(rule)` - wraps the given rule in a compatibility layer and returns the result +- `fixupPluginRules(plugin)` - wraps each rule in the given plugin using `fixupRule()` and returns a new object that represents the plugin with the fixed-up rules +- `fixupConfigRules(configs)` - wraps all plugins found in an array of config objects using `fixupPluginRules()` +- `includeIgnoreFile(path)` - reads an ignore file (like `.gitignore`) and converts the patterns into the correct format for the config file ### Fixing Rules @@ -145,7 +145,9 @@ module.exports = [ ### Including Ignore Files -If you were using an alternate ignore file in ESLint v8.x, such as using `--ignore-path .gitignore` on the command line, you can include those patterns programmatically in your config file using the `includeIgnoreFile()` function. For example: +If you were using an alternate ignore file in ESLint v8.x, such as using `--ignore-path .gitignore` on the command line, you can include those patterns programmatically in your config file using the `includeIgnoreFile()` function. + +The `includeIgnoreFile()` function also accepts a second optional `name` parameter that allows you to set a custom name for this configuration object. If not specified, it defaults to `"Imported .gitignore patterns"`. For example: ```js // eslint.config.js - ESM example @@ -158,7 +160,7 @@ const __dirname = path.dirname(__filename); const gitignorePath = path.resolve(__dirname, ".gitignore"); export default [ - includeIgnoreFile(gitignorePath), + includeIgnoreFile(gitignorePath, "Imported .gitignore patterns"), // second argument is optional. { // your overrides }, @@ -174,7 +176,7 @@ const path = require("node:path"); const gitignorePath = path.resolve(__dirname, ".gitignore"); module.exports = [ - includeIgnoreFile(gitignorePath), + includeIgnoreFile(gitignorePath, "Imported .gitignore patterns"), // second argument is optional. { // your overrides }, @@ -187,21 +189,21 @@ module.exports = [ Apache 2.0 + + + ## Sponsors -The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate) to get your logo on our README and website. +The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate) +to get your logo on our READMEs and [website](https://eslint.org/sponsors). - - -

Platinum Sponsors

+

Diamond Sponsors

+

AG Grid

Platinum Sponsors

Automattic Airbnb

Gold Sponsors

-

Eli Schleifer Salesforce

Silver Sponsors

-

JetBrains Liftoff American Express Workleap

Bronze Sponsors

-

notion Anagram Solver Icons8 Discord Ignition Nx HeroCoders Nextbase Starter Kit

+

Qlty Software trunk.io Shopify

Silver Sponsors

+

Vite Liftoff American Express StackBlitz

Bronze Sponsors

+

Sentry Syntax Cybozu Anagram Solver Icons8 Discord GitBook Neko Nx Mercedes-Benz Group HeroCoders LambdaTest

+

Technology Sponsors

+Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work. +

Netlify Algolia 1Password

- - -

Technology Sponsors

-

Netlify Algolia 1Password -

- diff --git a/node_modules/@eslint/compat/dist/cjs/index.cjs b/node_modules/@eslint/compat/dist/cjs/index.cjs index f852b039db..f54755a70c 100644 --- a/node_modules/@eslint/compat/dist/cjs/index.cjs +++ b/node_modules/@eslint/compat/dist/cjs/index.cjs @@ -14,8 +14,8 @@ var path = require('node:path'); /** @typedef {import("eslint").ESLint.Plugin} FixupPluginDefinition */ /** @typedef {import("eslint").Rule.RuleModule} FixupRuleDefinition */ -/** @typedef {import("eslint").Rule.OldStyleRule} FixupLegacyRuleDefinition */ -/** @typedef {import("eslint").Linter.FlatConfig} FixupConfig */ +/** @typedef {FixupRuleDefinition["create"]} FixupLegacyRuleDefinition */ +/** @typedef {import("eslint").Linter.Config} FixupConfig */ /** @typedef {Array} FixupConfigArray */ //----------------------------------------------------------------------------- @@ -188,6 +188,21 @@ function fixupRule(ruleDefinition) { create: ruleCreate, }; + // copy `schema` property of function-style rule or top-level `schema` property of object-style rule into `meta` object + // @ts-ignore -- top-level `schema` property was not offically supported for object-style rules so it doesn't exist in types + const { schema } = ruleDefinition; + if (schema) { + if (!newRuleDefinition.meta) { + newRuleDefinition.meta = { schema }; + } else { + newRuleDefinition.meta = { + ...newRuleDefinition.meta, + // top-level `schema` had precedence over `meta.schema` so it's okay to overwrite `meta.schema` if it exists + schema, + }; + } + } + // cache the fixed up rule fixedUpRuleReplacements.set(ruleDefinition, newRuleDefinition); fixedUpRules.add(newRuleDefinition); @@ -270,7 +285,7 @@ function fixupConfigRules(config) { // Types //----------------------------------------------------------------------------- -/** @typedef {import("eslint").Linter.FlatConfig} FlatConfig */ +/** @typedef {import("eslint").Linter.Config} FlatConfig */ //----------------------------------------------------------------------------- // Exports @@ -324,10 +339,11 @@ function convertIgnorePatternToMinimatch(pattern) { /** * Reads an ignore file and returns an object with the ignore patterns. * @param {string} ignoreFilePath The absolute path to the ignore file. + * @param {string} [name] The name of the ignore file config. * @returns {FlatConfig} An object with an `ignores` property that is an array of ignore patterns. * @throws {Error} If the ignore file path is not an absolute path. */ -function includeIgnoreFile(ignoreFilePath) { +function includeIgnoreFile(ignoreFilePath, name) { if (!path.isAbsolute(ignoreFilePath)) { throw new Error("The ignore file location must be an absolute path."); } @@ -336,7 +352,7 @@ function includeIgnoreFile(ignoreFilePath) { const lines = ignoreFile.split(/\r?\n/u); return { - name: "Imported .gitignore patterns", + name: name || "Imported .gitignore patterns", ignores: lines .map(line => line.trim()) .filter(line => line && !line.startsWith("#")) diff --git a/node_modules/@eslint/compat/dist/cjs/index.d.cts b/node_modules/@eslint/compat/dist/cjs/index.d.cts index 5f24e71059..81580ba03f 100644 --- a/node_modules/@eslint/compat/dist/cjs/index.d.cts +++ b/node_modules/@eslint/compat/dist/cjs/index.d.cts @@ -1,14 +1,14 @@ -export type FlatConfig = import("eslint").Linter.FlatConfig; +export type FlatConfig = import("eslint").Linter.Config; export type FixupPluginDefinition = import("eslint").ESLint.Plugin; export type FixupRuleDefinition = import("eslint").Rule.RuleModule; -export type FixupLegacyRuleDefinition = import("eslint").Rule.OldStyleRule; -export type FixupConfig = import("eslint").Linter.FlatConfig; +export type FixupLegacyRuleDefinition = FixupRuleDefinition["create"]; +export type FixupConfig = import("eslint").Linter.Config; export type FixupConfigArray = Array; /** * @fileoverview Ignore file utilities for the compat package. * @author Nicholas C. Zakas */ -/** @typedef {import("eslint").Linter.FlatConfig} FlatConfig */ +/** @typedef {import("eslint").Linter.Config} FlatConfig */ /** * Converts an ESLint ignore pattern to a minimatch pattern. * @param {string} pattern The .eslintignore or .gitignore pattern to convert. @@ -39,7 +39,8 @@ export function fixupRule(ruleDefinition: FixupRuleDefinition | FixupLegacyRuleD /** * Reads an ignore file and returns an object with the ignore patterns. * @param {string} ignoreFilePath The absolute path to the ignore file. + * @param {string} [name] The name of the ignore file config. * @returns {FlatConfig} An object with an `ignores` property that is an array of ignore patterns. * @throws {Error} If the ignore file path is not an absolute path. */ -export function includeIgnoreFile(ignoreFilePath: string): FlatConfig; +export function includeIgnoreFile(ignoreFilePath: string, name?: string): FlatConfig; diff --git a/node_modules/@eslint/compat/dist/esm/index.d.ts b/node_modules/@eslint/compat/dist/esm/index.d.ts index 5f24e71059..81580ba03f 100644 --- a/node_modules/@eslint/compat/dist/esm/index.d.ts +++ b/node_modules/@eslint/compat/dist/esm/index.d.ts @@ -1,14 +1,14 @@ -export type FlatConfig = import("eslint").Linter.FlatConfig; +export type FlatConfig = import("eslint").Linter.Config; export type FixupPluginDefinition = import("eslint").ESLint.Plugin; export type FixupRuleDefinition = import("eslint").Rule.RuleModule; -export type FixupLegacyRuleDefinition = import("eslint").Rule.OldStyleRule; -export type FixupConfig = import("eslint").Linter.FlatConfig; +export type FixupLegacyRuleDefinition = FixupRuleDefinition["create"]; +export type FixupConfig = import("eslint").Linter.Config; export type FixupConfigArray = Array; /** * @fileoverview Ignore file utilities for the compat package. * @author Nicholas C. Zakas */ -/** @typedef {import("eslint").Linter.FlatConfig} FlatConfig */ +/** @typedef {import("eslint").Linter.Config} FlatConfig */ /** * Converts an ESLint ignore pattern to a minimatch pattern. * @param {string} pattern The .eslintignore or .gitignore pattern to convert. @@ -39,7 +39,8 @@ export function fixupRule(ruleDefinition: FixupRuleDefinition | FixupLegacyRuleD /** * Reads an ignore file and returns an object with the ignore patterns. * @param {string} ignoreFilePath The absolute path to the ignore file. + * @param {string} [name] The name of the ignore file config. * @returns {FlatConfig} An object with an `ignores` property that is an array of ignore patterns. * @throws {Error} If the ignore file path is not an absolute path. */ -export function includeIgnoreFile(ignoreFilePath: string): FlatConfig; +export function includeIgnoreFile(ignoreFilePath: string, name?: string): FlatConfig; diff --git a/node_modules/@eslint/compat/dist/esm/index.js b/node_modules/@eslint/compat/dist/esm/index.js index be1e322a3e..ef782e674b 100644 --- a/node_modules/@eslint/compat/dist/esm/index.js +++ b/node_modules/@eslint/compat/dist/esm/index.js @@ -13,8 +13,8 @@ import path from 'node:path'; /** @typedef {import("eslint").ESLint.Plugin} FixupPluginDefinition */ /** @typedef {import("eslint").Rule.RuleModule} FixupRuleDefinition */ -/** @typedef {import("eslint").Rule.OldStyleRule} FixupLegacyRuleDefinition */ -/** @typedef {import("eslint").Linter.FlatConfig} FixupConfig */ +/** @typedef {FixupRuleDefinition["create"]} FixupLegacyRuleDefinition */ +/** @typedef {import("eslint").Linter.Config} FixupConfig */ /** @typedef {Array} FixupConfigArray */ //----------------------------------------------------------------------------- @@ -187,6 +187,21 @@ function fixupRule(ruleDefinition) { create: ruleCreate, }; + // copy `schema` property of function-style rule or top-level `schema` property of object-style rule into `meta` object + // @ts-ignore -- top-level `schema` property was not offically supported for object-style rules so it doesn't exist in types + const { schema } = ruleDefinition; + if (schema) { + if (!newRuleDefinition.meta) { + newRuleDefinition.meta = { schema }; + } else { + newRuleDefinition.meta = { + ...newRuleDefinition.meta, + // top-level `schema` had precedence over `meta.schema` so it's okay to overwrite `meta.schema` if it exists + schema, + }; + } + } + // cache the fixed up rule fixedUpRuleReplacements.set(ruleDefinition, newRuleDefinition); fixedUpRules.add(newRuleDefinition); @@ -269,7 +284,7 @@ function fixupConfigRules(config) { // Types //----------------------------------------------------------------------------- -/** @typedef {import("eslint").Linter.FlatConfig} FlatConfig */ +/** @typedef {import("eslint").Linter.Config} FlatConfig */ //----------------------------------------------------------------------------- // Exports @@ -323,10 +338,11 @@ function convertIgnorePatternToMinimatch(pattern) { /** * Reads an ignore file and returns an object with the ignore patterns. * @param {string} ignoreFilePath The absolute path to the ignore file. + * @param {string} [name] The name of the ignore file config. * @returns {FlatConfig} An object with an `ignores` property that is an array of ignore patterns. * @throws {Error} If the ignore file path is not an absolute path. */ -function includeIgnoreFile(ignoreFilePath) { +function includeIgnoreFile(ignoreFilePath, name) { if (!path.isAbsolute(ignoreFilePath)) { throw new Error("The ignore file location must be an absolute path."); } @@ -335,7 +351,7 @@ function includeIgnoreFile(ignoreFilePath) { const lines = ignoreFile.split(/\r?\n/u); return { - name: "Imported .gitignore patterns", + name: name || "Imported .gitignore patterns", ignores: lines .map(line => line.trim()) .filter(line => line && !line.startsWith("#")) diff --git a/node_modules/@eslint/compat/package.json b/node_modules/@eslint/compat/package.json index 6cf7f491d0..1f0479bd0a 100644 --- a/node_modules/@eslint/compat/package.json +++ b/node_modules/@eslint/compat/package.json @@ -1,6 +1,6 @@ { "name": "@eslint/compat", - "version": "1.1.1", + "version": "1.3.1", "description": "Compatibility utilities for ESLint", "type": "module", "main": "dist/esm/index.js", @@ -25,7 +25,7 @@ "test": "tests" }, "scripts": { - "build:cts": "node -e \"fs.copyFileSync('dist/esm/index.d.ts', 'dist/cjs/index.d.cts')\"", + "build:cts": "node ../../tools/build-cts.js dist/esm/index.d.ts dist/cjs/index.d.cts", "build": "rollup -c && tsc -p tsconfig.esm.json && npm run build:cts", "test:jsr": "npx jsr@latest publish --dry-run", "test": "mocha tests/*.js", @@ -33,7 +33,8 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/eslint/rewrite.git" + "url": "git+https://github.com/eslint/rewrite.git", + "directory": "packages/compat" }, "keywords": [ "eslint", @@ -46,14 +47,18 @@ "bugs": { "url": "https://github.com/eslint/rewrite/issues" }, - "homepage": "https://github.com/eslint/rewrite#readme", + "homepage": "https://github.com/eslint/rewrite/tree/main/packages/compat#readme", "devDependencies": { - "@types/eslint": "^8.56.10", - "c8": "^9.1.0", - "eslint": "^9.0.0", - "mocha": "^10.4.0", - "rollup": "^4.16.2", - "typescript": "^5.4.5" + "@eslint/core": "^0.15.1", + "eslint": "^9.27.0" + }, + "peerDependencies": { + "eslint": "^8.40 || 9" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/node_modules/@eslint/js/package.json b/node_modules/@eslint/js/package.json index 4024e62c15..2c08e39d20 100644 --- a/node_modules/@eslint/js/package.json +++ b/node_modules/@eslint/js/package.json @@ -1,6 +1,6 @@ { "name": "@eslint/js", - "version": "9.28.0", + "version": "9.30.0", "description": "ESLint JavaScript language implementation", "funding": "https://eslint.org/donate", "main": "./src/index.js", diff --git a/node_modules/merge-stream/LICENSE b/node_modules/@sec-ant/readable-stream/LICENSE similarity index 83% rename from node_modules/merge-stream/LICENSE rename to node_modules/@sec-ant/readable-stream/LICENSE index 94a4c0a076..6c4c768669 100644 --- a/node_modules/merge-stream/LICENSE +++ b/node_modules/@sec-ant/readable-stream/LICENSE @@ -1,6 +1,6 @@ -The MIT License (MIT) +MIT License -Copyright (c) Stephen Sugden (stephensugden.com) +Copyright (c) 2022 Ze-Zheng Wu Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@sec-ant/readable-stream/README.md b/node_modules/@sec-ant/readable-stream/README.md new file mode 100644 index 0000000000..7fa7a2915d --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/README.md @@ -0,0 +1,230 @@ +# @sec-ant/readable-stream + +[![npm version](https://img.shields.io/npm/v/@sec-ant/readable-stream?cacheSeconds=300)](https://www.npmjs.com/package/@sec-ant/readable-stream/v/latest) [![npm downloads](https://img.shields.io/npm/dm/@sec-ant/readable-stream?cacheSeconds=300)](https://www.npmjs.com/package/@sec-ant/readable-stream/v/latest) [![](https://img.shields.io/jsdelivr/npm/hm/@sec-ant/readable-stream?cacheSeconds=300&color=ff5627)](https://www.jsdelivr.com/package/npm/@sec-ant/readable-stream) [![bundlephobia minzipped](https://img.shields.io/bundlephobia/minzip/@sec-ant/readable-stream?cacheSeconds=300)](https://bundlephobia.com/package/@sec-ant/readable-stream@latest) [![npm license](https://img.shields.io/npm/l/@sec-ant/readable-stream?cacheSeconds=300)](https://www.npmjs.com/package/@sec-ant/readable-stream/v/latest) + +A tiny, zero-dependency yet spec-compliant asynchronous iterator polyfill/ponyfill for [`ReadableStream`](https://developer.mozilla.org/docs/Web/API/ReadableStream)s. + +## Features + +### Asynchronously iterate a `ReadableStream` + +With this package, you can consume a `ReadableStream` as an `AsyncIterable`. + +- spec: https://streams.spec.whatwg.org/#rs-asynciterator +- tests: https://github.com/Sec-ant/readable-stream/blob/main/tests/asyncIterator.spec.ts (copied from [wpt](https://github.com/web-platform-tests/wpt/blob/309231a7f3e900d04914bc4963b016efd9989a00/streams/readable-streams/async-iterator.any.js)) + +### Convert an `AsyncIterable` or an `Iterable` into a `ReadableStream` + +With this package, you can construct a `ReadableStream` from an `AsyncIterable` or an `Iterable`. + +- spec: https://streams.spec.whatwg.org/#rs-from +- tests: https://github.com/Sec-ant/readable-stream/blob/main/tests/fromAnyIterable.spec.ts (copied from [wpt](https://github.com/web-platform-tests/wpt/blob/309231a7f3e900d04914bc4963b016efd9989a00/streams/readable-streams/from.any.js)) + +This package passes all the aforementioned tests. + +## Install + +```bash +npm i @sec-ant/readable-stream +``` + +## Usage + +### Ponyfill + +This package can be imported as a _ponyfill_ to avoid side effects: + +#### `asyncIterator` + +Path: + +``` +@sec-ant/readable-stream/ponyfill/asyncIterator +``` + +Example: + +```ts +import { + asyncIterator, + type ReadableStreamIteratorOptions, +} from "@sec-ant/readable-stream/ponyfill/asyncIterator"; + +const readableStream = (await fetch("https://www.example.org/")).body; + +let total = 0; +for await (const chunk of asyncIterator.call(readableStream)) { + total += chunk.length; +} + +console.log(total); +``` + +Check https://streams.spec.whatwg.org/#rs-class-definition and https://streams.spec.whatwg.org/#rs-asynciterator for further explanation on `ReadableStreamIteratorOptions`. + +#### `fromAnyIterable` + +Path: + +``` +@sec-ant/readable-stream/ponyfill/fromAnyIterable +``` + +Example: + +```ts +import { fromAnyIterable } from "@sec-ant/readable-stream/ponyfill/fromAnyIterable"; + +const readableStream = fromAnyIterable(["a", "b"]); +``` + +#### All-in-One + +Path: + +``` +@sec-ant/readable-stream/ponyfill +``` + +Example: + +```ts +import { + fromAnyIterable, + asyncIterator, + type ReadableStreamIteratorOptions, +} from "@sec-ant/readable-stream/ponyfill"; +``` + +### Polyfill + +This package can be imported as a drop-in _polyfill_ with side effects. + +#### `ReadableStream.prototype[Symbol.asyncIterator]` and `ReadableStream.prototype.values` + +Path: + +``` +@sec-ant/readable-stream/polyfill/asyncIterator +``` + +Example: + +```ts +import "@sec-ant/readable-stream/polyfill/asyncIterator"; + +const readableStream = (await fetch("https://www.example.org/")).body; + +let total = 0; +for await (const chunk of readableStream) { + total += chunk.length; +} + +console.log(total); +``` + +#### `ReadableStream.from` + +Path: + +``` +@sec-ant/readable-stream/polyfill/fromAnyIterable +``` + +Example: + +```js +import "@sec-ant/readable-stream/polyfill/fromAnyIterable"; + +const readableStream = ReadableStream.from(["a", "b"]); +``` + +Note that `ReadableStream.from` is not typed because [declared vars cannot be overridden](https://github.com/microsoft/TypeScript/issues/36146). + +#### All-in-One + +Path: + +``` +@sec-ant/readable-stream/polyfill +``` + +Example: + +```ts +import "@sec-ant/readable-stream/polyfill"; +``` + +### Ponyfill + Polyfill + +#### `asyncIterator` + +Path: + +``` +@sec-ant/readable-stream/asyncIterator +``` + +Example: + +```ts +import { + asyncIterator, + type ReadableStreamIteratorOptions, +} from "@sec-ant/readable-stream/asyncIterator"; +// also with side effects +``` + +#### `fromAnyIterable` + +Path: + +``` +@sec-ant/readable-stream/fromAnyIterable +``` + +Example: + +```ts +import { fromAnyIterable } from "@sec-ant/readable-stream/fromAnyIterable"; +// also with side effects +``` + +#### All-in-One + +Path: + +``` +@sec-ant/readable-stream +``` + +Example: + +```ts +import { + fromAnyIterable, + asyncIterator, + type ReadableStreamIteratorOptions, +} from "@sec-ant/readable-stream"; +// also with side effects +``` + +### Types + +You can also use this package to augment the `ReadableStream` type for async iteration if the runtime already supports it but the type system does not. + +Path: + +``` +@sec-ant/readable-stream/async-iterator +``` + +Example: + +```ts +/// +``` + +## License + +MIT diff --git a/node_modules/@sec-ant/readable-stream/dist/core/asyncIterablePrototype.d.ts b/node_modules/@sec-ant/readable-stream/dist/core/asyncIterablePrototype.d.ts new file mode 100644 index 0000000000..98d20c2506 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/core/asyncIterablePrototype.d.ts @@ -0,0 +1 @@ +export declare const AsyncIterablePrototype: object; diff --git a/node_modules/@sec-ant/readable-stream/dist/core/asyncIterator.d.ts b/node_modules/@sec-ant/readable-stream/dist/core/asyncIterator.d.ts new file mode 100644 index 0000000000..658d943c89 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/core/asyncIterator.d.ts @@ -0,0 +1,27 @@ +/** + * the implementer that does all the heavy works + */ +declare class ReadableStreamAsyncIterableIteratorImpl implements AsyncIterator { + #private; + constructor(reader: ReadableStreamDefaultReader, preventCancel: boolean); + next(): Promise>; + return(value?: TReturn): Promise>; +} +declare const implementSymbol: unique symbol; +/** + * declare `ReadableStreamAsyncIterableIterator` interaface + */ +interface ReadableStreamAsyncIterableIterator extends AsyncIterableIterator { + [implementSymbol]: ReadableStreamAsyncIterableIteratorImpl; +} +export interface ReadableStreamIteratorOptions { + preventCancel?: boolean; +} +/** + * Get an async iterable iterator from a readable stream + * @param this + * @param readableStreamIteratorOptions + * @returns + */ +export declare function asyncIterator(this: ReadableStream, { preventCancel }?: ReadableStreamIteratorOptions): ReadableStreamAsyncIterableIterator; +export {}; diff --git a/node_modules/@sec-ant/readable-stream/dist/core/fromAnyIterable.d.ts b/node_modules/@sec-ant/readable-stream/dist/core/fromAnyIterable.d.ts new file mode 100644 index 0000000000..1d5bafb84f --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/core/fromAnyIterable.d.ts @@ -0,0 +1,6 @@ +/** + * Create a new readable stream from an async iterable or a sync iterable + * @param iterable + * @returns a readable stream + */ +export declare function fromAnyIterable(iterable: Iterable | AsyncIterable): ReadableStream; diff --git a/node_modules/@sec-ant/readable-stream/dist/index/asyncIterator.d.ts b/node_modules/@sec-ant/readable-stream/dist/index/asyncIterator.d.ts new file mode 100644 index 0000000000..e10ed7984e --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/index/asyncIterator.d.ts @@ -0,0 +1,2 @@ +import "../polyfill/asyncIterator.js"; +export * from "../ponyfill/asyncIterator.js"; diff --git a/node_modules/@sec-ant/readable-stream/dist/index/asyncIterator.js b/node_modules/@sec-ant/readable-stream/dist/index/asyncIterator.js new file mode 100644 index 0000000000..240ad00646 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/index/asyncIterator.js @@ -0,0 +1,5 @@ +import "../polyfill/asyncIterator.js"; +import { asyncIterator as a } from "../ponyfill/asyncIterator.js"; +export { + a as asyncIterator +}; diff --git a/node_modules/@sec-ant/readable-stream/dist/index/fromAnyIterable.d.ts b/node_modules/@sec-ant/readable-stream/dist/index/fromAnyIterable.d.ts new file mode 100644 index 0000000000..35eb64b739 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/index/fromAnyIterable.d.ts @@ -0,0 +1,2 @@ +import "../polyfill/fromAnyIterable.js"; +export * from "../ponyfill/fromAnyIterable.js"; diff --git a/node_modules/@sec-ant/readable-stream/dist/index/fromAnyIterable.js b/node_modules/@sec-ant/readable-stream/dist/index/fromAnyIterable.js new file mode 100644 index 0000000000..a9080876a9 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/index/fromAnyIterable.js @@ -0,0 +1,5 @@ +import "../polyfill/fromAnyIterable.js"; +import { fromAnyIterable as m } from "../ponyfill/fromAnyIterable.js"; +export { + m as fromAnyIterable +}; diff --git a/node_modules/@sec-ant/readable-stream/dist/index/index.d.ts b/node_modules/@sec-ant/readable-stream/dist/index/index.d.ts new file mode 100644 index 0000000000..f7aa2353f2 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/index/index.d.ts @@ -0,0 +1,2 @@ +export * from "./asyncIterator.js"; +export * from "./fromAnyIterable.js"; diff --git a/node_modules/@sec-ant/readable-stream/dist/index/index.js b/node_modules/@sec-ant/readable-stream/dist/index/index.js new file mode 100644 index 0000000000..92a4b567fc --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/index/index.js @@ -0,0 +1,8 @@ +import "../polyfill/asyncIterator.js"; +import { asyncIterator as m } from "../ponyfill/asyncIterator.js"; +import "../polyfill/fromAnyIterable.js"; +import { fromAnyIterable as a } from "../ponyfill/fromAnyIterable.js"; +export { + m as asyncIterator, + a as fromAnyIterable +}; diff --git a/node_modules/@sec-ant/readable-stream/dist/polyfill/asyncIterator.d.ts b/node_modules/@sec-ant/readable-stream/dist/polyfill/asyncIterator.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/polyfill/asyncIterator.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@sec-ant/readable-stream/dist/polyfill/asyncIterator.js b/node_modules/@sec-ant/readable-stream/dist/polyfill/asyncIterator.js new file mode 100644 index 0000000000..32eeb3a29b --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/polyfill/asyncIterator.js @@ -0,0 +1,3 @@ +import { asyncIterator as e } from "../ponyfill/asyncIterator.js"; +ReadableStream.prototype.values ??= ReadableStream.prototype[Symbol.asyncIterator] ??= e; +ReadableStream.prototype[Symbol.asyncIterator] ??= ReadableStream.prototype.values; diff --git a/node_modules/@sec-ant/readable-stream/dist/polyfill/fromAnyIterable.d.ts b/node_modules/@sec-ant/readable-stream/dist/polyfill/fromAnyIterable.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/polyfill/fromAnyIterable.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@sec-ant/readable-stream/dist/polyfill/fromAnyIterable.js b/node_modules/@sec-ant/readable-stream/dist/polyfill/fromAnyIterable.js new file mode 100644 index 0000000000..b66554aadc --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/polyfill/fromAnyIterable.js @@ -0,0 +1,2 @@ +import { fromAnyIterable as r } from "../ponyfill/fromAnyIterable.js"; +ReadableStream.from ??= r; diff --git a/node_modules/@sec-ant/readable-stream/dist/polyfill/index.d.ts b/node_modules/@sec-ant/readable-stream/dist/polyfill/index.d.ts new file mode 100644 index 0000000000..2397cf8f41 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/polyfill/index.d.ts @@ -0,0 +1,2 @@ +import "./asyncIterator.js"; +import "./fromAnyIterable.js"; diff --git a/node_modules/@sec-ant/readable-stream/dist/polyfill/index.js b/node_modules/@sec-ant/readable-stream/dist/polyfill/index.js new file mode 100644 index 0000000000..115aff1050 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/polyfill/index.js @@ -0,0 +1,4 @@ +import "./asyncIterator.js"; +import "./fromAnyIterable.js"; +import "../ponyfill/asyncIterator.js"; +import "../ponyfill/fromAnyIterable.js"; diff --git a/node_modules/@sec-ant/readable-stream/dist/ponyfill/asyncIterator.d.ts b/node_modules/@sec-ant/readable-stream/dist/ponyfill/asyncIterator.d.ts new file mode 100644 index 0000000000..a7228ed881 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/ponyfill/asyncIterator.d.ts @@ -0,0 +1 @@ +export { asyncIterator, type ReadableStreamIteratorOptions, } from "../core/asyncIterator.js"; diff --git a/node_modules/@sec-ant/readable-stream/dist/ponyfill/asyncIterator.js b/node_modules/@sec-ant/readable-stream/dist/ponyfill/asyncIterator.js new file mode 100644 index 0000000000..374fb09ac3 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/ponyfill/asyncIterator.js @@ -0,0 +1,89 @@ +const a = Object.getPrototypeOf( + Object.getPrototypeOf( + /* istanbul ignore next */ + async function* () { + } + ).prototype +); +class c { + #t; + #n; + #r = !1; + #e = void 0; + constructor(e, t) { + this.#t = e, this.#n = t; + } + next() { + const e = () => this.#s(); + return this.#e = this.#e ? this.#e.then(e, e) : e(), this.#e; + } + return(e) { + const t = () => this.#i(e); + return this.#e ? this.#e.then(t, t) : t(); + } + async #s() { + if (this.#r) + return { + done: !0, + value: void 0 + }; + let e; + try { + e = await this.#t.read(); + } catch (t) { + throw this.#e = void 0, this.#r = !0, this.#t.releaseLock(), t; + } + return e.done && (this.#e = void 0, this.#r = !0, this.#t.releaseLock()), e; + } + async #i(e) { + if (this.#r) + return { + done: !0, + value: e + }; + if (this.#r = !0, !this.#n) { + const t = this.#t.cancel(e); + return this.#t.releaseLock(), await t, { + done: !0, + value: e + }; + } + return this.#t.releaseLock(), { + done: !0, + value: e + }; + } +} +const n = Symbol(); +function i() { + return this[n].next(); +} +Object.defineProperty(i, "name", { value: "next" }); +function o(r) { + return this[n].return(r); +} +Object.defineProperty(o, "name", { value: "return" }); +const u = Object.create(a, { + next: { + enumerable: !0, + configurable: !0, + writable: !0, + value: i + }, + return: { + enumerable: !0, + configurable: !0, + writable: !0, + value: o + } +}); +function h({ preventCancel: r = !1 } = {}) { + const e = this.getReader(), t = new c( + e, + r + ), s = Object.create(u); + return s[n] = t, s; +} +export { + h as asyncIterator +}; diff --git a/node_modules/@sec-ant/readable-stream/dist/ponyfill/fromAnyIterable.d.ts b/node_modules/@sec-ant/readable-stream/dist/ponyfill/fromAnyIterable.d.ts new file mode 100644 index 0000000000..6cc03328fe --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/ponyfill/fromAnyIterable.d.ts @@ -0,0 +1 @@ +export { fromAnyIterable } from "../core/fromAnyIterable.js"; diff --git a/node_modules/@sec-ant/readable-stream/dist/ponyfill/fromAnyIterable.js b/node_modules/@sec-ant/readable-stream/dist/ponyfill/fromAnyIterable.js new file mode 100644 index 0000000000..1d9e5d5093 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/ponyfill/fromAnyIterable.js @@ -0,0 +1,34 @@ +function c(n) { + const t = a(n); + return new ReadableStream( + { + async pull(e) { + const { value: r, done: o } = await t.next(); + o ? e.close() : e.enqueue(r); + }, + async cancel(e) { + if (typeof t.return == "function" && typeof await t.return(e) != "object") + throw new TypeError("return() fulfills with a non-object."); + return e; + } + }, + new CountQueuingStrategy({ + highWaterMark: 0 + }) + ); +} +function a(n) { + let t = n[Symbol.asyncIterator]?.bind(n); + if (t === void 0) { + const r = n[Symbol.iterator](), o = { + [Symbol.iterator]: () => r + }; + t = async function* () { + return yield* o; + }; + } + return t(); +} +export { + c as fromAnyIterable +}; diff --git a/node_modules/@sec-ant/readable-stream/dist/ponyfill/index.d.ts b/node_modules/@sec-ant/readable-stream/dist/ponyfill/index.d.ts new file mode 100644 index 0000000000..f7aa2353f2 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/ponyfill/index.d.ts @@ -0,0 +1,2 @@ +export * from "./asyncIterator.js"; +export * from "./fromAnyIterable.js"; diff --git a/node_modules/@sec-ant/readable-stream/dist/ponyfill/index.js b/node_modules/@sec-ant/readable-stream/dist/ponyfill/index.js new file mode 100644 index 0000000000..0d6779a505 --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/ponyfill/index.js @@ -0,0 +1,6 @@ +import { asyncIterator as e } from "./asyncIterator.js"; +import { fromAnyIterable as a } from "./fromAnyIterable.js"; +export { + e as asyncIterator, + a as fromAnyIterable +}; diff --git a/node_modules/@sec-ant/readable-stream/dist/types/async-iterator.d.ts b/node_modules/@sec-ant/readable-stream/dist/types/async-iterator.d.ts new file mode 100644 index 0000000000..0a92fc41ac --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/dist/types/async-iterator.d.ts @@ -0,0 +1,11 @@ +import type { ReadableStreamIteratorOptions } from "../core/asyncIterator.js"; +/** + * augment global readable stream interface + */ +declare global { + // biome-ignore lint/suspicious/noExplicitAny: to be compatible with lib.dom.d.ts + interface ReadableStream { + [Symbol.asyncIterator](): AsyncIterableIterator; + values(options?: ReadableStreamIteratorOptions): AsyncIterableIterator; + } +} diff --git a/node_modules/@sec-ant/readable-stream/package.json b/node_modules/@sec-ant/readable-stream/package.json new file mode 100644 index 0000000000..769613d51c --- /dev/null +++ b/node_modules/@sec-ant/readable-stream/package.json @@ -0,0 +1,98 @@ +{ + "name": "@sec-ant/readable-stream", + "description": "A tiny, zero-dependency yet spec-compliant asynchronous iterator polyfill/ponyfill for ReadableStreams.", + "private": false, + "version": "0.4.1", + "type": "module", + "files": [ + "./dist" + ], + "main": "./dist/index/index.js", + "module": "./dist/index/index.js", + "exports": { + ".": "./dist/index/index.js", + "./asyncIterator": "./dist/index/asyncIterator.js", + "./fromAnyIterable": "./dist/index/fromAnyIterable.js", + "./ponyfill": "./dist/ponyfill/index.js", + "./ponyfill/asyncIterator": "./dist/ponyfill/asyncIterator.js", + "./ponyfill/fromAnyIterable": "./dist/ponyfill/fromAnyIterable.js", + "./polyfill": "./dist/polyfill/index.js", + "./polyfill/asyncIterator": "./dist/polyfill/asyncIterator.js", + "./polyfill/fromAnyIterable": "./dist/polyfill/fromAnyIterable.js", + "./async-iterator": { + "types": "./dist/types/async-iterator.d.ts" + } + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Sec-ant/readable-stream.git" + }, + "homepage": "https://github.com/Sec-ant/readable-stream", + "bugs": { + "url": "https://github.com/Sec-ant/readable-stream/issues", + "email": "zezhengwu@proton.me" + }, + "keywords": [ + "stream", + "web-streams", + "readablestream", + "async", + "asynchronous", + "iterator", + "iteration", + "async-iterator", + "polyfill", + "esm", + "from-iterable" + ], + "author": { + "name": "Ze-Zheng Wu" + }, + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "scripts": { + "install:ci": "npm ci && npx playwright install --with-deps", + "install:codesandbox": "npm ci && ./scripts/prepare.sh", + "update-hooks": "simple-git-hooks", + "changeset": "changeset", + "bump": "changeset version 2>/dev/null | grep . && npm i; exit 0", + "type-check": "tsc --noEmit --emitDeclarationOnly false", + "format:prettier": "prettier . --write", + "format:biome": "biome format . --write", + "format": "conc \"npm:format:prettier\" \"npm:format:biome\"", + "check:biome": "biome check --apply .", + "check": "conc \"npm:format:prettier\" \"npm:check:biome\"", + "prebuild": "npm run check && npm run type-check", + "build": "vite build", + "copy": "copy-files-from-to", + "postbuild": "tsc && npm run copy", + "test:chromium": "vitest run --browser.name=chromium", + "test:firefox": "vitest run --browser.name=firefox", + "test": "npm run test:chromium && npm run test:firefox", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui --coverage", + "prepublishOnly": "npm run build", + "bump-biome:latest": "npm i -DE @biomejs/biome@latest", + "bump-biome:nightly": "npm i -DE @biomejs/biome@nightly" + }, + "devDependencies": { + "@biomejs/biome": "1.6.1", + "@changesets/cli": "^2.27.1", + "@commitlint/cli": "^19.1.0", + "@commitlint/config-conventional": "^19.1.0", + "@vitest/browser": "^1.3.1", + "@vitest/coverage-istanbul": "^1.3.1", + "@vitest/ui": "^1.3.1", + "concurrently": "^8.2.2", + "copy-files-from-to": "^3.9.1", + "lint-staged": "^15.2.2", + "playwright": "^1.42.1", + "prettier": "^3.2.5", + "simple-git-hooks": "^2.10.0", + "typescript": "^5.4.2", + "vite": "^5.1.6", + "vitest": "^1.3.1" + } +} diff --git a/node_modules/@sindresorhus/merge-streams/index.d.ts b/node_modules/@sindresorhus/merge-streams/index.d.ts new file mode 100644 index 0000000000..359623f61e --- /dev/null +++ b/node_modules/@sindresorhus/merge-streams/index.d.ts @@ -0,0 +1,44 @@ +import {type Readable} from 'node:stream'; + +/** +Merges an array of [readable streams](https://nodejs.org/api/stream.html#readable-streams) and returns a new readable stream that emits data from the individual streams as it arrives. + +If you provide an empty array, the stream remains open but can be [manually ended](https://nodejs.org/api/stream.html#writableendchunk-encoding-callback). + +@example +``` +import mergeStreams from '@sindresorhus/merge-streams'; + +const stream = mergeStreams([streamA, streamB]); + +for await (const chunk of stream) { + console.log(chunk); + //=> 'A1' + //=> 'B1' + //=> 'A2' + //=> 'B2' +} +``` +*/ +export default function mergeStreams(streams: Readable[]): MergedStream; + +/** +A single stream combining the output of multiple streams. +*/ +export class MergedStream extends Readable { + /** + Pipe a new readable stream. + + Throws if `MergedStream` has already ended. + */ + add(stream: Readable): void; + + /** + Unpipe a stream previously added using either `mergeStreams(streams)` or `MergedStream.add(stream)`. + + Returns `false` if the stream was not previously added, or if it was already removed by `MergedStream.remove(stream)`. + + The removed stream is not automatically ended. + */ + remove(stream: Readable): Promise; +} diff --git a/node_modules/@sindresorhus/merge-streams/index.js b/node_modules/@sindresorhus/merge-streams/index.js new file mode 100644 index 0000000000..5201922f60 --- /dev/null +++ b/node_modules/@sindresorhus/merge-streams/index.js @@ -0,0 +1,265 @@ +import {on, once} from 'node:events'; +import {PassThrough as PassThroughStream, getDefaultHighWaterMark} from 'node:stream'; +import {finished} from 'node:stream/promises'; + +export default function mergeStreams(streams) { + if (!Array.isArray(streams)) { + throw new TypeError(`Expected an array, got \`${typeof streams}\`.`); + } + + for (const stream of streams) { + validateStream(stream); + } + + const objectMode = streams.some(({readableObjectMode}) => readableObjectMode); + const highWaterMark = getHighWaterMark(streams, objectMode); + const passThroughStream = new MergedStream({ + objectMode, + writableHighWaterMark: highWaterMark, + readableHighWaterMark: highWaterMark, + }); + + for (const stream of streams) { + passThroughStream.add(stream); + } + + return passThroughStream; +} + +const getHighWaterMark = (streams, objectMode) => { + if (streams.length === 0) { + return getDefaultHighWaterMark(objectMode); + } + + const highWaterMarks = streams + .filter(({readableObjectMode}) => readableObjectMode === objectMode) + .map(({readableHighWaterMark}) => readableHighWaterMark); + return Math.max(...highWaterMarks); +}; + +class MergedStream extends PassThroughStream { + #streams = new Set([]); + #ended = new Set([]); + #aborted = new Set([]); + #onFinished; + #unpipeEvent = Symbol('unpipe'); + #streamPromises = new WeakMap(); + + add(stream) { + validateStream(stream); + + if (this.#streams.has(stream)) { + return; + } + + this.#streams.add(stream); + + this.#onFinished ??= onMergedStreamFinished(this, this.#streams, this.#unpipeEvent); + const streamPromise = endWhenStreamsDone({ + passThroughStream: this, + stream, + streams: this.#streams, + ended: this.#ended, + aborted: this.#aborted, + onFinished: this.#onFinished, + unpipeEvent: this.#unpipeEvent, + }); + this.#streamPromises.set(stream, streamPromise); + + stream.pipe(this, {end: false}); + } + + async remove(stream) { + validateStream(stream); + + if (!this.#streams.has(stream)) { + return false; + } + + const streamPromise = this.#streamPromises.get(stream); + if (streamPromise === undefined) { + return false; + } + + this.#streamPromises.delete(stream); + + stream.unpipe(this); + await streamPromise; + return true; + } +} + +const onMergedStreamFinished = async (passThroughStream, streams, unpipeEvent) => { + updateMaxListeners(passThroughStream, PASSTHROUGH_LISTENERS_COUNT); + const controller = new AbortController(); + + try { + await Promise.race([ + onMergedStreamEnd(passThroughStream, controller), + onInputStreamsUnpipe(passThroughStream, streams, unpipeEvent, controller), + ]); + } finally { + controller.abort(); + updateMaxListeners(passThroughStream, -PASSTHROUGH_LISTENERS_COUNT); + } +}; + +const onMergedStreamEnd = async (passThroughStream, {signal}) => { + try { + await finished(passThroughStream, {signal, cleanup: true}); + } catch (error) { + errorOrAbortStream(passThroughStream, error); + throw error; + } +}; + +const onInputStreamsUnpipe = async (passThroughStream, streams, unpipeEvent, {signal}) => { + for await (const [unpipedStream] of on(passThroughStream, 'unpipe', {signal})) { + if (streams.has(unpipedStream)) { + unpipedStream.emit(unpipeEvent); + } + } +}; + +const validateStream = stream => { + if (typeof stream?.pipe !== 'function') { + throw new TypeError(`Expected a readable stream, got: \`${typeof stream}\`.`); + } +}; + +const endWhenStreamsDone = async ({passThroughStream, stream, streams, ended, aborted, onFinished, unpipeEvent}) => { + updateMaxListeners(passThroughStream, PASSTHROUGH_LISTENERS_PER_STREAM); + const controller = new AbortController(); + + try { + await Promise.race([ + afterMergedStreamFinished(onFinished, stream, controller), + onInputStreamEnd({ + passThroughStream, + stream, + streams, + ended, + aborted, + controller, + }), + onInputStreamUnpipe({ + stream, + streams, + ended, + aborted, + unpipeEvent, + controller, + }), + ]); + } finally { + controller.abort(); + updateMaxListeners(passThroughStream, -PASSTHROUGH_LISTENERS_PER_STREAM); + } + + if (streams.size > 0 && streams.size === ended.size + aborted.size) { + if (ended.size === 0 && aborted.size > 0) { + abortStream(passThroughStream); + } else { + endStream(passThroughStream); + } + } +}; + +const afterMergedStreamFinished = async (onFinished, stream, {signal}) => { + try { + await onFinished; + if (!signal.aborted) { + abortStream(stream); + } + } catch (error) { + if (!signal.aborted) { + errorOrAbortStream(stream, error); + } + } +}; + +const onInputStreamEnd = async ({passThroughStream, stream, streams, ended, aborted, controller: {signal}}) => { + try { + await finished(stream, { + signal, + cleanup: true, + readable: true, + writable: false, + }); + if (streams.has(stream)) { + ended.add(stream); + } + } catch (error) { + if (signal.aborted || !streams.has(stream)) { + return; + } + + if (isAbortError(error)) { + aborted.add(stream); + } else { + errorStream(passThroughStream, error); + } + } +}; + +const onInputStreamUnpipe = async ({stream, streams, ended, aborted, unpipeEvent, controller: {signal}}) => { + await once(stream, unpipeEvent, {signal}); + + if (!stream.readable) { + return once(signal, 'abort', {signal}); + } + + streams.delete(stream); + ended.delete(stream); + aborted.delete(stream); +}; + +const endStream = stream => { + if (stream.writable) { + stream.end(); + } +}; + +const errorOrAbortStream = (stream, error) => { + if (isAbortError(error)) { + abortStream(stream); + } else { + errorStream(stream, error); + } +}; + +// This is the error thrown by `finished()` on `stream.destroy()` +const isAbortError = error => error?.code === 'ERR_STREAM_PREMATURE_CLOSE'; + +const abortStream = stream => { + if (stream.readable || stream.writable) { + stream.destroy(); + } +}; + +// `stream.destroy(error)` crashes the process with `uncaughtException` if no `error` event listener exists on `stream`. +// We take care of error handling on user behalf, so we do not want this to happen. +const errorStream = (stream, error) => { + if (!stream.destroyed) { + stream.once('error', noop); + stream.destroy(error); + } +}; + +const noop = () => {}; + +const updateMaxListeners = (passThroughStream, increment) => { + const maxListeners = passThroughStream.getMaxListeners(); + if (maxListeners !== 0 && maxListeners !== Number.POSITIVE_INFINITY) { + passThroughStream.setMaxListeners(maxListeners + increment); + } +}; + +// Number of times `passThroughStream.on()` is called regardless of streams: +// - once due to `finished(passThroughStream)` +// - once due to `on(passThroughStream)` +const PASSTHROUGH_LISTENERS_COUNT = 2; + +// Number of times `passThroughStream.on()` is called per stream: +// - once due to `stream.pipe(passThroughStream)` +const PASSTHROUGH_LISTENERS_PER_STREAM = 1; diff --git a/node_modules/onetime/license b/node_modules/@sindresorhus/merge-streams/license similarity index 100% rename from node_modules/onetime/license rename to node_modules/@sindresorhus/merge-streams/license diff --git a/node_modules/@sindresorhus/merge-streams/package.json b/node_modules/@sindresorhus/merge-streams/package.json new file mode 100644 index 0000000000..29c2ba1ea1 --- /dev/null +++ b/node_modules/@sindresorhus/merge-streams/package.json @@ -0,0 +1,49 @@ +{ + "name": "@sindresorhus/merge-streams", + "version": "4.0.0", + "description": "Merge multiple streams into a unified stream", + "license": "MIT", + "repository": "sindresorhus/merge-streams", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && c8 ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "merge", + "stream", + "streams", + "readable", + "passthrough", + "interleave", + "interleaved", + "unify", + "unified" + ], + "devDependencies": { + "@types/node": "^20.8.9", + "ava": "^6.1.0", + "c8": "^9.1.0", + "tempfile": "^5.0.0", + "tsd": "^0.31.0", + "typescript": "^5.2.2", + "xo": "^0.58.0" + } +} diff --git a/node_modules/@sindresorhus/merge-streams/readme.md b/node_modules/@sindresorhus/merge-streams/readme.md new file mode 100644 index 0000000000..d00e50cae2 --- /dev/null +++ b/node_modules/@sindresorhus/merge-streams/readme.md @@ -0,0 +1,53 @@ +# merge-streams + +> Merge multiple streams into a unified stream + +## Install + +```sh +npm install @sindresorhus/merge-streams +``` + +## Usage + +```js +import mergeStreams from '@sindresorhus/merge-streams'; + +const stream = mergeStreams([streamA, streamB]); + +for await (const chunk of stream) { + console.log(chunk); + //=> 'A1' + //=> 'B1' + //=> 'A2' + //=> 'B2' +} +``` + +## API + +### `mergeStreams(streams: stream.Readable[]): MergedStream` + +Merges an array of [readable streams](https://nodejs.org/api/stream.html#readable-streams) and returns a new readable stream that emits data from the individual streams as it arrives. + +If you provide an empty array, the stream remains open but can be [manually ended](https://nodejs.org/api/stream.html#writableendchunk-encoding-callback). + +#### `MergedStream` + +_Type_: `stream.Readable` + +A single stream combining the output of multiple streams. + +##### `MergedStream.add(stream: stream.Readable): void` + +Pipe a new readable stream. + +Throws if `MergedStream` has already ended. + +##### `MergedStream.remove(stream: stream.Readable): Promise` + +Unpipe a stream previously added using either [`mergeStreams(streams)`](#mergestreamsstreams-streamreadable-mergedstream) or [`MergedStream.add(stream)`](#mergedstreamaddstream-streamreadable-void). + +Returns `false` if the stream was not previously added, or if it was already removed by `MergedStream.remove(stream)`. + +The removed stream is not automatically ended. diff --git a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.d.ts b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.d.ts index 1b09044fd4..b902cfa97b 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.d.ts +++ b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.d.ts @@ -1,6 +1,7 @@ export type Options = [ { ignoredTypeNames?: string[]; + checkUnknown?: boolean; } ]; export type MessageIds = 'baseArrayJoin' | 'baseToString'; diff --git a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.d.ts.map b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.d.ts.map index 3abddfbf02..0d6c1ad407 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.d.ts.map +++ b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"no-base-to-string.d.ts","sourceRoot":"","sources":["../../src/rules/no-base-to-string.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC7B;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,cAAc,CAAC;;AAE1D,wBAwTG"} \ No newline at end of file +{"version":3,"file":"no-base-to-string.d.ts","sourceRoot":"","sources":["../../src/rules/no-base-to-string.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,cAAc,CAAC;;AAE1D,wBAmUG"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.js b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.js index 4e80892a1d..7e95b94be8 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.js +++ b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-base-to-string.js @@ -61,6 +61,10 @@ exports.default = (0, util_1.createRule)({ type: 'object', additionalProperties: false, properties: { + checkUnknown: { + type: 'boolean', + description: 'Whether to also check values of type `unknown`', + }, ignoredTypeNames: { type: 'array', description: 'Stringified regular expressions of type names to ignore.', @@ -74,6 +78,7 @@ exports.default = (0, util_1.createRule)({ }, defaultOptions: [ { + checkUnknown: false, ignoredTypeNames: ['Error', 'RegExp', 'URL', 'URLSearchParams'], }, ], @@ -172,7 +177,7 @@ exports.default = (0, util_1.createRule)({ return collectToStringCertainty(constraint, visited); } // unconstrained generic means `unknown` - return Usefulness.Always; + return option.checkUnknown ? Usefulness.Sometimes : Usefulness.Always; } // the Boolean type definition missing toString() if (type.flags & ts.TypeFlags.Boolean || @@ -197,7 +202,11 @@ exports.default = (0, util_1.createRule)({ const toString = checker.getPropertyOfType(type, 'toString') ?? checker.getPropertyOfType(type, 'toLocaleString'); if (!toString) { - // e.g. any/unknown + // unknown + if (option.checkUnknown && type.flags === ts.TypeFlags.Unknown) { + return Usefulness.Sometimes; + } + // e.g. any return Usefulness.Always; } const declarations = toString.getDeclarations(); diff --git a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/prefer-optional-chain.d.ts.map b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/prefer-optional-chain.d.ts.map index 08bdc84904..8fa9e94af0 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/prefer-optional-chain.d.ts.map +++ b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/prefer-optional-chain.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"prefer-optional-chain.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-optional-chain.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,6BAA6B,EAC7B,0BAA0B,EAC3B,MAAM,0DAA0D,CAAC;;AAelE,wBAiMG"} \ No newline at end of file +{"version":3,"file":"prefer-optional-chain.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-optional-chain.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,6BAA6B,EAC7B,0BAA0B,EAC3B,MAAM,0DAA0D,CAAC;;AAelE,wBAkMG"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/prefer-optional-chain.js b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/prefer-optional-chain.js index f0c0c58dd7..13c9c481f0 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/dist/rules/prefer-optional-chain.js +++ b/node_modules/@typescript-eslint/eslint-plugin/dist/rules/prefer-optional-chain.js @@ -77,7 +77,6 @@ exports.default = (0, util_1.createRule)({ const parserServices = (0, util_1.getParserServices)(context); const seenLogicals = new Set(); return { - // specific handling for `(foo ?? {}).bar` / `(foo || {}).bar` 'LogicalExpression[operator!="??"]'(node) { if (seenLogicals.has(node)) { return; @@ -101,6 +100,7 @@ exports.default = (0, util_1.createRule)({ (0, analyzeChain_1.analyzeChain)(context, parserServices, options, node, node.operator, currentChain); } }, + // specific handling for `(foo ?? {}).bar` / `(foo || {}).bar` 'LogicalExpression[operator="||"], LogicalExpression[operator="??"]'(node) { const leftNode = node.left; const rightNode = node.right; diff --git a/node_modules/@typescript-eslint/eslint-plugin/dist/util/astUtils.d.ts b/node_modules/@typescript-eslint/eslint-plugin/dist/util/astUtils.d.ts index bb1d8edcef..0f26d070df 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/dist/util/astUtils.d.ts +++ b/node_modules/@typescript-eslint/eslint-plugin/dist/util/astUtils.d.ts @@ -2,9 +2,9 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import * as ts from 'typescript'; export * from '@typescript-eslint/utils/ast-utils'; /** - * Get the `loc` object of a given name in a `/*globals` directive comment. + * Get the `loc` object of a given name in a `/*globals` comment directive. * @param sourceCode The source code to convert index to loc. - * @param comment The `/*globals` directive comment which include the name. + * @param comment The `/*globals` comment directive which include the name. * @param name The name to find. * @returns The `loc` object. */ diff --git a/node_modules/@typescript-eslint/eslint-plugin/dist/util/astUtils.js b/node_modules/@typescript-eslint/eslint-plugin/dist/util/astUtils.js index fc5e05cad2..c001d42db6 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/dist/util/astUtils.js +++ b/node_modules/@typescript-eslint/eslint-plugin/dist/util/astUtils.js @@ -46,9 +46,9 @@ __exportStar(require("@typescript-eslint/utils/ast-utils"), exports); // https://github.com/eslint/eslint/blob/145aec1ab9052fbca96a44d04927c595951b1536/lib/rules/utils/ast-utils.js#L1751-L1779 // Could be export { getNameLocationInGlobalDirectiveComment } from 'eslint/lib/rules/utils/ast-utils' /** - * Get the `loc` object of a given name in a `/*globals` directive comment. + * Get the `loc` object of a given name in a `/*globals` comment directive. * @param sourceCode The source code to convert index to loc. - * @param comment The `/*globals` directive comment which include the name. + * @param comment The `/*globals` comment directive which include the name. * @param name The name to find. * @returns The `loc` object. */ diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts index 059713cab8..5d230e2348 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts @@ -14,19 +14,19 @@ export declare class ESLintScopeVariable extends VariableBase { writeable?: boolean; /** * Written to by ESLint. - * This property is undefined if there are no globals directive comments. - * The array of globals directive comments which defined this global variable in the source code file. + * This property is undefined if there are no globals comment directives. + * The array of globals comment directives which defined this global variable in the source code file. */ eslintExplicitGlobal?: boolean; /** * Written to by ESLint. - * The configured value in config files. This can be different from `variable.writeable` if there are globals directive comments. + * The configured value in config files. This can be different from `variable.writeable` if there are globals comment directives. */ eslintImplicitGlobalSetting?: 'readonly' | 'writable'; /** * Written to by ESLint. * If this key exists, it is a global variable added by ESLint. - * If `true`, this global variable was defined by a globals directive comment in the source code file. + * If `true`, this global variable was defined by a globals comment directive in the source code file. */ eslintExplicitGlobalComments?: TSESTree.Comment[]; } diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js index 8aea84ed01..4450dad2b3 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js @@ -16,19 +16,19 @@ class ESLintScopeVariable extends VariableBase_1.VariableBase { writeable; // note that this isn't a typo - ESlint uses this spelling here /** * Written to by ESLint. - * This property is undefined if there are no globals directive comments. - * The array of globals directive comments which defined this global variable in the source code file. + * This property is undefined if there are no globals comment directives. + * The array of globals comment directives which defined this global variable in the source code file. */ eslintExplicitGlobal; /** * Written to by ESLint. - * The configured value in config files. This can be different from `variable.writeable` if there are globals directive comments. + * The configured value in config files. This can be different from `variable.writeable` if there are globals comment directives. */ eslintImplicitGlobalSetting; /** * Written to by ESLint. * If this key exists, it is a global variable added by ESLint. - * If `true`, this global variable was defined by a globals directive comment in the source code file. + * If `true`, this global variable was defined by a globals comment directive in the source code file. */ eslintExplicitGlobalComments; } diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/package.json b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/package.json index 233360f3d7..e84ae367d8 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/package.json +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "8.33.1", + "version": "8.35.1", "description": "TypeScript scope analyser for ESLint", "files": [ "dist", @@ -48,11 +48,11 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "devDependencies": { - "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/typescript-estree": "8.35.1", "@vitest/coverage-v8": "^3.1.3", "@vitest/pretty-format": "^3.1.3", "glob": "*", diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/dist/parser-options.d.ts b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/dist/parser-options.d.ts index 5923587f5d..d1d85c5735 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/dist/parser-options.d.ts +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/dist/parser-options.d.ts @@ -2,7 +2,7 @@ import type { Program } from 'typescript'; import type { Lib } from './lib'; export type DebugLevel = boolean | ('eslint' | 'typescript' | 'typescript-eslint')[]; export type CacheDurationSeconds = number | 'Infinity'; -export type EcmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 'latest' | undefined; +export type EcmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | 'latest' | undefined; export type SourceTypeClassic = 'module' | 'script'; export type SourceType = 'commonjs' | SourceTypeClassic; export type JSDocParsingMode = 'all' | 'none' | 'type-info'; diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map index 6c0fff12bc..40fc7fbe8a 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"parser-options.d.ts","sourceRoot":"","sources":["../src/parser-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,CAAC,QAAQ,GAAG,YAAY,GAAG,mBAAmB,CAAC,EAAE,CAAC;AACtD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEvD,MAAM,MAAM,WAAW,GACnB,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AACpD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,iBAAiB,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;;;OAMG;IACH,+DAA+D,CAAC,EAAE,MAAM,CAAC;CAC1E;AAGD,MAAM,WAAW,aAAa;IAC5B,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,aAAa,CAAC,EAAE;QACd,IAAI,CAAC,EAAE,oBAAoB,CAAC;KAC7B,CAAC;IAGF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,YAAY,CAAC,EACT;QACE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACnC,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KAC3B,GACD,SAAS,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,CAAC;IAG1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,2CAA2C,CAAC,EAAE,OAAO,CAAC;IAEtD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7C,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,cAAc,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAAC;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C"} \ No newline at end of file +{"version":3,"file":"parser-options.d.ts","sourceRoot":"","sources":["../src/parser-options.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/package.json b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/package.json index 5324be9fb4..e40eeded30 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/package.json +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "8.33.1", + "version": "8.35.1", "description": "Types for the TypeScript-ESTree AST spec", "files": [ "dist", diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map index 1607334a86..d1bfa348e2 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,EAAE,MAAM,aAAa,CAAC;AAmCtE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,GAAG,EAAE,CAAC,sBAAsB,GAC1D,OAAO,CAMT;AAED,MAAM,WAAW,OAAO;IACtB,qBAAqB,EAAE,2BAA2B,CAAC;IACnD,qBAAqB,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,qBAAa,SAAS;;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAEvD;;;;;OAKG;gBACS,GAAG,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAsZ1D,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,oCAAoC;IAe5C;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,sBAAsB;IA4C9B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;;;OAKG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;OAIG;IACH,OAAO,CAAC,kDAAkD;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,+BAA+B;IAgDvC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAiiFnB,OAAO,CAAC,UAAU;IAclB,cAAc,IAAI,QAAQ,CAAC,OAAO;IAIlC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA0FlB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAgFlB,UAAU,IAAI,OAAO;IAOrB;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAYhC"} \ No newline at end of file +{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,EAAE,MAAM,aAAa,CAAC;AAmCtE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,GAAG,EAAE,CAAC,sBAAsB,GAC1D,OAAO,CAMT;AAED,MAAM,WAAW,OAAO;IACtB,qBAAqB,EAAE,2BAA2B,CAAC;IACnD,qBAAqB,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC7D;AAqBD,qBAAa,SAAS;;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAEvD;;;;;OAKG;gBACS,GAAG,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAsZ1D,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,oCAAoC;IAe5C;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,sBAAsB;IA4C9B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;;;OAKG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;OAIG;IACH,OAAO,CAAC,kDAAkD;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,+BAA+B;IAgDvC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAyjFnB,OAAO,CAAC,UAAU;IAclB,cAAc,IAAI,QAAQ,CAAC,OAAO;IAIlC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA0FlB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAgFlB,UAAU,IAAI,OAAO;IAOrB;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAYhC"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/convert.js b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/convert.js index 1f8d85f999..382281b746 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/convert.js +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/convert.js @@ -50,6 +50,15 @@ const SyntaxKind = ts.SyntaxKind; function convertError(error) { return (0, node_utils_1.createError)(('message' in error && error.message) || error.messageText, error.file, error.start); } +function isPropertyAccessEntityNameExpression(node) { + return (ts.isPropertyAccessExpression(node) && + ts.isIdentifier(node.name) && + isEntityNameExpression(node.expression)); +} +function isEntityNameExpression(node) { + return (node.kind === SyntaxKind.Identifier || + isPropertyAccessEntityNameExpression(node)); +} class Converter { allowPattern = false; ast; @@ -1169,14 +1178,23 @@ class Converter { if (constructor.typeParameters) { this.fixParentLocation(constructor, constructor.typeParameters.range); } - const constructorKey = this.createNode(node, { - type: ts_estree_1.AST_NODE_TYPES.Identifier, - range: [constructorToken.getStart(this.ast), constructorToken.end], - decorators: [], - name: 'constructor', - optional: false, - typeAnnotation: undefined, - }); + const constructorKey = constructorToken.kind === SyntaxKind.StringLiteral + ? this.createNode(constructorToken, { + type: ts_estree_1.AST_NODE_TYPES.Literal, + raw: constructorToken.getText(), + value: 'constructor', + }) + : this.createNode(node, { + type: ts_estree_1.AST_NODE_TYPES.Identifier, + range: [ + constructorToken.getStart(this.ast), + constructorToken.end, + ], + decorators: [], + name: 'constructor', + optional: false, + typeAnnotation: undefined, + }); const isStatic = (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node); return this.createNode(node, { type: (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node) @@ -2185,13 +2203,22 @@ class Converter { case SyntaxKind.InterfaceDeclaration: { const interfaceHeritageClauses = node.heritageClauses ?? []; const interfaceExtends = []; + let seenExtendsClause = false; for (const heritageClause of interfaceHeritageClauses) { if (heritageClause.token !== SyntaxKind.ExtendsKeyword) { this.#throwError(heritageClause, heritageClause.token === SyntaxKind.ImplementsKeyword ? "Interface declaration cannot have 'implements' clause." : 'Unexpected token.'); } + if (seenExtendsClause) { + this.#throwError(heritageClause, "'extends' clause already seen."); + } + seenExtendsClause = true; for (const heritageType of heritageClause.types) { + if (!isEntityNameExpression(heritageType.expression) || + ts.isOptionalChain(heritageType.expression)) { + this.#throwError(heritageType, 'Interface declaration can only extend an identifier/qualified name with optional type arguments.'); + } interfaceExtends.push(this.convertChild(heritageType, node)); } } diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map index f4999949a8..5ab4c563d2 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"node-utils.d.ts","sourceRoot":"","sources":["../src/node-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"node-utils.d.ts","sourceRoot":"","sources":["../src/node-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js index d8adac997d..df5a7eed34 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js @@ -410,6 +410,9 @@ function isChildUnwrappableOptionalChain(node, child) { * Returns the type of a given ts.Token */ function getTokenType(token) { + if (token.kind === SyntaxKind.NullKeyword) { + return ts_estree_1.AST_TOKEN_TYPES.Null; + } let keywordKind; if (isAtLeast50 && token.kind === SyntaxKind.Identifier) { keywordKind = ts.identifierToKeywordKind(token); diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/package.json b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/package.json index 15556fdfd5..32c5f69879 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/package.json +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "8.33.1", + "version": "8.35.1", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "files": [ "dist", @@ -53,10 +53,10 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/dist/ts-eslint/Config.d.ts b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/dist/ts-eslint/Config.d.ts index fcc13ca58c..8ee3630263 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/dist/ts-eslint/Config.d.ts +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/dist/ts-eslint/Config.d.ts @@ -58,7 +58,7 @@ export declare namespace ClassicConfig { */ globals?: GlobalsConfig; /** - * The flag that disables directive comments. + * The flag that disables comment directives. */ noInlineConfig?: boolean; /** diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/dist/ts-eslint/eslint/ESLintShared.d.ts b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/dist/ts-eslint/eslint/ESLintShared.d.ts index f550f10e65..9df2ae9e7d 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/dist/ts-eslint/eslint/ESLintShared.d.ts +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/dist/ts-eslint/eslint/ESLintShared.d.ts @@ -87,7 +87,7 @@ export declare class ESLintBase { /** - * If false is present, ESLint suppresses directive comments in source code. + * If false is present, ESLint suppresses comment directives in source code. * If this option is false, it overrides the noInlineConfig setting in your configurations. * @default true */ diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/package.json b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/package.json index c5c543f6eb..d2aa43d309 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/package.json +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/utils", - "version": "8.33.1", + "version": "8.35.1", "description": "Utilities for working with TypeScript + ESLint together", "files": [ "dist", @@ -63,9 +63,9 @@ }, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1" + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js index b09fde6c8e..0e13f57bf0 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js @@ -137,8 +137,8 @@ const additionalKeys = { TSExternalModuleReference: ['expression'], TSFunctionType: SharedVisitorKeys.FunctionType, TSImportEqualsDeclaration: ['id', 'moduleReference'], - TSImportType: ['argument', 'qualifier', 'typeArguments', 'options'], - TSIndexedAccessType: ['indexType', 'objectType'], + TSImportType: ['argument', 'options', 'qualifier', 'typeArguments'], + TSIndexedAccessType: ['objectType', 'indexType'], TSIndexSignature: ['parameters', 'typeAnnotation'], TSInferType: ['typeParameter'], TSInstantiationExpression: ['expression', 'typeArguments'], @@ -149,7 +149,7 @@ const additionalKeys = { TSIntrinsicKeyword: [], TSLiteralType: ['literal'], TSMappedType: ['key', 'constraint', 'nameType', 'typeAnnotation'], - TSMethodSignature: ['typeParameters', 'key', 'params', 'returnType'], + TSMethodSignature: ['key', 'typeParameters', 'params', 'returnType'], TSModuleBlock: ['body'], TSModuleDeclaration: ['id', 'body'], TSNamedTupleMember: ['label', 'elementType'], @@ -162,7 +162,7 @@ const additionalKeys = { TSOptionalType: ['typeAnnotation'], TSParameterProperty: ['decorators', 'parameter'], TSPrivateKeyword: [], - TSPropertySignature: ['typeAnnotation', 'key'], + TSPropertySignature: ['key', 'typeAnnotation'], TSProtectedKeyword: [], TSPublicKeyword: [], TSQualifiedName: ['left', 'right'], @@ -183,7 +183,7 @@ const additionalKeys = { TSTypeParameter: ['name', 'constraint', 'default'], TSTypeParameterDeclaration: ['params'], TSTypeParameterInstantiation: ['params'], - TSTypePredicate: ['typeAnnotation', 'parameterName'], + TSTypePredicate: ['parameterName', 'typeAnnotation'], TSTypeQuery: ['exprName', 'typeArguments'], TSTypeReference: ['typeName', 'typeArguments'], TSUndefinedKeyword: [], diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/package.json b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/package.json index 89aafa93bf..3dc5f9672f 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/package.json +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "8.33.1", + "version": "8.35.1", "description": "Visitor keys used to help traverse the TypeScript-ESTree AST", "files": [ "dist", @@ -46,8 +46,8 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "devDependencies": { "@vitest/coverage-v8": "^3.1.3", diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion/index.js b/node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion/index.js index 4af9ddee46..a27f81ce04 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion/index.js +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion/index.js @@ -116,7 +116,7 @@ function expand(str, isTop) { var isOptions = m.body.indexOf(',') >= 0; if (!isSequence && !isOptions) { // {a},b} - if (m.post.match(/,.*\}/)) { + if (m.post.match(/,(?!,).*\}/)) { str = m.pre + '{' + m.body + escClose + m.post; return expand(str); } diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion/package.json b/node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion/package.json index 7097d41e39..c7eee34511 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion/package.json +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion/package.json @@ -1,7 +1,7 @@ { "name": "brace-expansion", "description": "Brace expansion as known from sh/bash", - "version": "2.0.1", + "version": "2.0.2", "repository": { "type": "git", "url": "git://github.com/juliangruber/brace-expansion.git" @@ -42,5 +42,8 @@ "iphone/6.0..latest", "android-browser/4.2..latest" ] + }, + "publishConfig": { + "tag": "2.x" } } diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/README.md b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/README.md index 3cbbdd39d0..aa860ba577 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/README.md +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/README.md @@ -109,11 +109,12 @@ Welcome. See [ESLint contribution guidelines](https://eslint.org/docs/developer- The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate) to get your logo on our READMEs and [website](https://eslint.org/sponsors). -

Platinum Sponsors

+

Diamond Sponsors

+

AG Grid

Platinum Sponsors

Automattic Airbnb

Gold Sponsors

-

trunk.io

Silver Sponsors

-

JetBrains Liftoff American Express Workleap

Bronze Sponsors

-

WordHint Anagram Solver Icons8 Discord GitBook Nx HeroCoders

+

Qlty Software trunk.io Shopify

Silver Sponsors

+

Vite Liftoff American Express StackBlitz

Bronze Sponsors

+

Sentry Syntax Cybozu Anagram Solver Icons8 Discord GitBook Neko Nx Mercedes-Benz Group HeroCoders LambdaTest

Technology Sponsors

Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.

Netlify Algolia 1Password

diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs index 7f58e49bcd..afc433c7cd 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs @@ -102,8 +102,8 @@ const KEYS = { "attributes" ], ExportSpecifier: [ - "exported", - "local" + "local", + "exported" ], ExpressionStatement: [ "expression" diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts index a8684341f1..34253c96c3 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts @@ -24,4 +24,5 @@ declare function unionWith(additionalKeys: VisitorKeys): VisitorKeys; type VisitorKeys = VisitorKeys$1; -export { KEYS, type VisitorKeys, getKeys, unionWith }; +export { KEYS, getKeys, unionWith }; +export type { VisitorKeys }; diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/lib/visitor-keys.js b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/lib/visitor-keys.js index 41feb4b2f8..c891e040af 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/lib/visitor-keys.js +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/lib/visitor-keys.js @@ -100,8 +100,8 @@ const KEYS = { "attributes" ], ExportSpecifier: [ - "exported", - "local" + "local", + "exported" ], ExpressionStatement: [ "expression" diff --git a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/package.json b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/package.json index 4dc2123dba..852e4ddb18 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/package.json +++ b/node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "eslint-visitor-keys", - "version": "4.2.0", + "version": "4.2.1", "description": "Constants and utilities about visitor keys to traverse AST.", "type": "module", "main": "dist/eslint-visitor-keys.cjs", @@ -29,12 +29,9 @@ "@types/estree": "^0.0.51", "@types/estree-jsx": "^0.0.1", "@typescript-eslint/parser": "^8.7.0", - "c8": "^7.11.0", - "chai": "^4.3.6", "eslint-release": "^3.2.0", "esquery": "^1.4.0", "json-diff": "^0.7.3", - "mocha": "^9.2.1", "opener": "^1.5.2", "rollup": "^4.22.4", "rollup-plugin-dts": "^6.1.1", @@ -55,9 +52,15 @@ "test:open-coverage": "c8 report --reporter lcov && opener coverage/lcov-report/index.html", "test:types": "tsd" }, - "repository": "eslint/js", + "repository": { + "type": "git", + "url": "https://github.com/eslint/js.git", + "directory": "packages/eslint-visitor-keys" + }, "funding": "https://opencollective.com/eslint", - "keywords": [], + "keywords": [ + "eslint" + ], "author": "Toru Nagashima (https://github.com/mysticatea)", "license": "Apache-2.0", "bugs": { diff --git a/node_modules/@typescript-eslint/eslint-plugin/package.json b/node_modules/@typescript-eslint/eslint-plugin/package.json index b48775e4d0..e6622edca6 100644 --- a/node_modules/@typescript-eslint/eslint-plugin/package.json +++ b/node_modules/@typescript-eslint/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "8.33.1", + "version": "8.35.1", "description": "TypeScript plugin for ESLint", "files": [ "dist", @@ -60,10 +60,10 @@ }, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/type-utils": "8.33.1", - "@typescript-eslint/utils": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/type-utils": "8.35.1", + "@typescript-eslint/utils": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -72,8 +72,8 @@ "devDependencies": { "@types/mdast": "^4.0.3", "@types/natural-compare": "*", - "@typescript-eslint/rule-schema-to-typescript-types": "8.33.1", - "@typescript-eslint/rule-tester": "8.33.1", + "@typescript-eslint/rule-schema-to-typescript-types": "8.35.1", + "@typescript-eslint/rule-tester": "8.35.1", "@vitest/coverage-v8": "^3.1.3", "ajv": "^6.12.6", "cross-fetch": "*", @@ -84,7 +84,6 @@ "mdast-util-from-markdown": "^2.0.0", "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0", - "prettier": "^3.5.3", "rimraf": "*", "title-case": "^4.0.0", "tsx": "*", @@ -93,7 +92,7 @@ "vitest": "^3.1.3" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.33.1", + "@typescript-eslint/parser": "^8.35.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" }, diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts index 059713cab8..5d230e2348 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts @@ -14,19 +14,19 @@ export declare class ESLintScopeVariable extends VariableBase { writeable?: boolean; /** * Written to by ESLint. - * This property is undefined if there are no globals directive comments. - * The array of globals directive comments which defined this global variable in the source code file. + * This property is undefined if there are no globals comment directives. + * The array of globals comment directives which defined this global variable in the source code file. */ eslintExplicitGlobal?: boolean; /** * Written to by ESLint. - * The configured value in config files. This can be different from `variable.writeable` if there are globals directive comments. + * The configured value in config files. This can be different from `variable.writeable` if there are globals comment directives. */ eslintImplicitGlobalSetting?: 'readonly' | 'writable'; /** * Written to by ESLint. * If this key exists, it is a global variable added by ESLint. - * If `true`, this global variable was defined by a globals directive comment in the source code file. + * If `true`, this global variable was defined by a globals comment directive in the source code file. */ eslintExplicitGlobalComments?: TSESTree.Comment[]; } diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js index 8aea84ed01..4450dad2b3 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js @@ -16,19 +16,19 @@ class ESLintScopeVariable extends VariableBase_1.VariableBase { writeable; // note that this isn't a typo - ESlint uses this spelling here /** * Written to by ESLint. - * This property is undefined if there are no globals directive comments. - * The array of globals directive comments which defined this global variable in the source code file. + * This property is undefined if there are no globals comment directives. + * The array of globals comment directives which defined this global variable in the source code file. */ eslintExplicitGlobal; /** * Written to by ESLint. - * The configured value in config files. This can be different from `variable.writeable` if there are globals directive comments. + * The configured value in config files. This can be different from `variable.writeable` if there are globals comment directives. */ eslintImplicitGlobalSetting; /** * Written to by ESLint. * If this key exists, it is a global variable added by ESLint. - * If `true`, this global variable was defined by a globals directive comment in the source code file. + * If `true`, this global variable was defined by a globals comment directive in the source code file. */ eslintExplicitGlobalComments; } diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/package.json b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/package.json index 233360f3d7..e84ae367d8 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/package.json +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "8.33.1", + "version": "8.35.1", "description": "TypeScript scope analyser for ESLint", "files": [ "dist", @@ -48,11 +48,11 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "devDependencies": { - "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/typescript-estree": "8.35.1", "@vitest/coverage-v8": "^3.1.3", "@vitest/pretty-format": "^3.1.3", "glob": "*", diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/dist/parser-options.d.ts b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/dist/parser-options.d.ts index 5923587f5d..d1d85c5735 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/dist/parser-options.d.ts +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/dist/parser-options.d.ts @@ -2,7 +2,7 @@ import type { Program } from 'typescript'; import type { Lib } from './lib'; export type DebugLevel = boolean | ('eslint' | 'typescript' | 'typescript-eslint')[]; export type CacheDurationSeconds = number | 'Infinity'; -export type EcmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 'latest' | undefined; +export type EcmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | 'latest' | undefined; export type SourceTypeClassic = 'module' | 'script'; export type SourceType = 'commonjs' | SourceTypeClassic; export type JSDocParsingMode = 'all' | 'none' | 'type-info'; diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map index 6c0fff12bc..40fc7fbe8a 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"parser-options.d.ts","sourceRoot":"","sources":["../src/parser-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,CAAC,QAAQ,GAAG,YAAY,GAAG,mBAAmB,CAAC,EAAE,CAAC;AACtD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEvD,MAAM,MAAM,WAAW,GACnB,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AACpD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,iBAAiB,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;;;OAMG;IACH,+DAA+D,CAAC,EAAE,MAAM,CAAC;CAC1E;AAGD,MAAM,WAAW,aAAa;IAC5B,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,aAAa,CAAC,EAAE;QACd,IAAI,CAAC,EAAE,oBAAoB,CAAC;KAC7B,CAAC;IAGF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,YAAY,CAAC,EACT;QACE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACnC,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KAC3B,GACD,SAAS,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,CAAC;IAG1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,2CAA2C,CAAC,EAAE,OAAO,CAAC;IAEtD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7C,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,cAAc,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAAC;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C"} \ No newline at end of file +{"version":3,"file":"parser-options.d.ts","sourceRoot":"","sources":["../src/parser-options.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/package.json b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/package.json index 5324be9fb4..e40eeded30 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/package.json +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "8.33.1", + "version": "8.35.1", "description": "Types for the TypeScript-ESTree AST spec", "files": [ "dist", diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map index 1607334a86..d1bfa348e2 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,EAAE,MAAM,aAAa,CAAC;AAmCtE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,GAAG,EAAE,CAAC,sBAAsB,GAC1D,OAAO,CAMT;AAED,MAAM,WAAW,OAAO;IACtB,qBAAqB,EAAE,2BAA2B,CAAC;IACnD,qBAAqB,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,qBAAa,SAAS;;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAEvD;;;;;OAKG;gBACS,GAAG,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAsZ1D,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,oCAAoC;IAe5C;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,sBAAsB;IA4C9B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;;;OAKG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;OAIG;IACH,OAAO,CAAC,kDAAkD;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,+BAA+B;IAgDvC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAiiFnB,OAAO,CAAC,UAAU;IAclB,cAAc,IAAI,QAAQ,CAAC,OAAO;IAIlC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA0FlB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAgFlB,UAAU,IAAI,OAAO;IAOrB;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAYhC"} \ No newline at end of file +{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,EAAE,MAAM,aAAa,CAAC;AAmCtE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,GAAG,EAAE,CAAC,sBAAsB,GAC1D,OAAO,CAMT;AAED,MAAM,WAAW,OAAO;IACtB,qBAAqB,EAAE,2BAA2B,CAAC;IACnD,qBAAqB,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC7D;AAqBD,qBAAa,SAAS;;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAEvD;;;;;OAKG;gBACS,GAAG,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAsZ1D,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,oCAAoC;IAe5C;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,sBAAsB;IA4C9B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;;;OAKG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;OAIG;IACH,OAAO,CAAC,kDAAkD;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,+BAA+B;IAgDvC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAyjFnB,OAAO,CAAC,UAAU;IAclB,cAAc,IAAI,QAAQ,CAAC,OAAO;IAIlC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA0FlB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAgFlB,UAAU,IAAI,OAAO;IAOrB;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAYhC"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/convert.js b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/convert.js index 1f8d85f999..382281b746 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/convert.js +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/convert.js @@ -50,6 +50,15 @@ const SyntaxKind = ts.SyntaxKind; function convertError(error) { return (0, node_utils_1.createError)(('message' in error && error.message) || error.messageText, error.file, error.start); } +function isPropertyAccessEntityNameExpression(node) { + return (ts.isPropertyAccessExpression(node) && + ts.isIdentifier(node.name) && + isEntityNameExpression(node.expression)); +} +function isEntityNameExpression(node) { + return (node.kind === SyntaxKind.Identifier || + isPropertyAccessEntityNameExpression(node)); +} class Converter { allowPattern = false; ast; @@ -1169,14 +1178,23 @@ class Converter { if (constructor.typeParameters) { this.fixParentLocation(constructor, constructor.typeParameters.range); } - const constructorKey = this.createNode(node, { - type: ts_estree_1.AST_NODE_TYPES.Identifier, - range: [constructorToken.getStart(this.ast), constructorToken.end], - decorators: [], - name: 'constructor', - optional: false, - typeAnnotation: undefined, - }); + const constructorKey = constructorToken.kind === SyntaxKind.StringLiteral + ? this.createNode(constructorToken, { + type: ts_estree_1.AST_NODE_TYPES.Literal, + raw: constructorToken.getText(), + value: 'constructor', + }) + : this.createNode(node, { + type: ts_estree_1.AST_NODE_TYPES.Identifier, + range: [ + constructorToken.getStart(this.ast), + constructorToken.end, + ], + decorators: [], + name: 'constructor', + optional: false, + typeAnnotation: undefined, + }); const isStatic = (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node); return this.createNode(node, { type: (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node) @@ -2185,13 +2203,22 @@ class Converter { case SyntaxKind.InterfaceDeclaration: { const interfaceHeritageClauses = node.heritageClauses ?? []; const interfaceExtends = []; + let seenExtendsClause = false; for (const heritageClause of interfaceHeritageClauses) { if (heritageClause.token !== SyntaxKind.ExtendsKeyword) { this.#throwError(heritageClause, heritageClause.token === SyntaxKind.ImplementsKeyword ? "Interface declaration cannot have 'implements' clause." : 'Unexpected token.'); } + if (seenExtendsClause) { + this.#throwError(heritageClause, "'extends' clause already seen."); + } + seenExtendsClause = true; for (const heritageType of heritageClause.types) { + if (!isEntityNameExpression(heritageType.expression) || + ts.isOptionalChain(heritageType.expression)) { + this.#throwError(heritageType, 'Interface declaration can only extend an identifier/qualified name with optional type arguments.'); + } interfaceExtends.push(this.convertChild(heritageType, node)); } } diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map index f4999949a8..5ab4c563d2 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"node-utils.d.ts","sourceRoot":"","sources":["../src/node-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"node-utils.d.ts","sourceRoot":"","sources":["../src/node-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js index d8adac997d..df5a7eed34 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js @@ -410,6 +410,9 @@ function isChildUnwrappableOptionalChain(node, child) { * Returns the type of a given ts.Token */ function getTokenType(token) { + if (token.kind === SyntaxKind.NullKeyword) { + return ts_estree_1.AST_TOKEN_TYPES.Null; + } let keywordKind; if (isAtLeast50 && token.kind === SyntaxKind.Identifier) { keywordKind = ts.identifierToKeywordKind(token); diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/package.json b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/package.json index 15556fdfd5..32c5f69879 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/package.json +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "8.33.1", + "version": "8.35.1", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "files": [ "dist", @@ -53,10 +53,10 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js index b09fde6c8e..0e13f57bf0 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js @@ -137,8 +137,8 @@ const additionalKeys = { TSExternalModuleReference: ['expression'], TSFunctionType: SharedVisitorKeys.FunctionType, TSImportEqualsDeclaration: ['id', 'moduleReference'], - TSImportType: ['argument', 'qualifier', 'typeArguments', 'options'], - TSIndexedAccessType: ['indexType', 'objectType'], + TSImportType: ['argument', 'options', 'qualifier', 'typeArguments'], + TSIndexedAccessType: ['objectType', 'indexType'], TSIndexSignature: ['parameters', 'typeAnnotation'], TSInferType: ['typeParameter'], TSInstantiationExpression: ['expression', 'typeArguments'], @@ -149,7 +149,7 @@ const additionalKeys = { TSIntrinsicKeyword: [], TSLiteralType: ['literal'], TSMappedType: ['key', 'constraint', 'nameType', 'typeAnnotation'], - TSMethodSignature: ['typeParameters', 'key', 'params', 'returnType'], + TSMethodSignature: ['key', 'typeParameters', 'params', 'returnType'], TSModuleBlock: ['body'], TSModuleDeclaration: ['id', 'body'], TSNamedTupleMember: ['label', 'elementType'], @@ -162,7 +162,7 @@ const additionalKeys = { TSOptionalType: ['typeAnnotation'], TSParameterProperty: ['decorators', 'parameter'], TSPrivateKeyword: [], - TSPropertySignature: ['typeAnnotation', 'key'], + TSPropertySignature: ['key', 'typeAnnotation'], TSProtectedKeyword: [], TSPublicKeyword: [], TSQualifiedName: ['left', 'right'], @@ -183,7 +183,7 @@ const additionalKeys = { TSTypeParameter: ['name', 'constraint', 'default'], TSTypeParameterDeclaration: ['params'], TSTypeParameterInstantiation: ['params'], - TSTypePredicate: ['typeAnnotation', 'parameterName'], + TSTypePredicate: ['parameterName', 'typeAnnotation'], TSTypeQuery: ['exprName', 'typeArguments'], TSTypeReference: ['typeName', 'typeArguments'], TSUndefinedKeyword: [], diff --git a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys/package.json b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys/package.json index 89aafa93bf..3dc5f9672f 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys/package.json +++ b/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "8.33.1", + "version": "8.35.1", "description": "Visitor keys used to help traverse the TypeScript-ESTree AST", "files": [ "dist", @@ -46,8 +46,8 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "devDependencies": { "@vitest/coverage-v8": "^3.1.3", diff --git a/node_modules/@typescript-eslint/parser/node_modules/brace-expansion/index.js b/node_modules/@typescript-eslint/parser/node_modules/brace-expansion/index.js index 4af9ddee46..a27f81ce04 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/brace-expansion/index.js +++ b/node_modules/@typescript-eslint/parser/node_modules/brace-expansion/index.js @@ -116,7 +116,7 @@ function expand(str, isTop) { var isOptions = m.body.indexOf(',') >= 0; if (!isSequence && !isOptions) { // {a},b} - if (m.post.match(/,.*\}/)) { + if (m.post.match(/,(?!,).*\}/)) { str = m.pre + '{' + m.body + escClose + m.post; return expand(str); } diff --git a/node_modules/@typescript-eslint/parser/node_modules/brace-expansion/package.json b/node_modules/@typescript-eslint/parser/node_modules/brace-expansion/package.json index 7097d41e39..c7eee34511 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/brace-expansion/package.json +++ b/node_modules/@typescript-eslint/parser/node_modules/brace-expansion/package.json @@ -1,7 +1,7 @@ { "name": "brace-expansion", "description": "Brace expansion as known from sh/bash", - "version": "2.0.1", + "version": "2.0.2", "repository": { "type": "git", "url": "git://github.com/juliangruber/brace-expansion.git" @@ -42,5 +42,8 @@ "iphone/6.0..latest", "android-browser/4.2..latest" ] + }, + "publishConfig": { + "tag": "2.x" } } diff --git a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/README.md b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/README.md index 3cbbdd39d0..aa860ba577 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/README.md +++ b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/README.md @@ -109,11 +109,12 @@ Welcome. See [ESLint contribution guidelines](https://eslint.org/docs/developer- The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate) to get your logo on our READMEs and [website](https://eslint.org/sponsors). -

Platinum Sponsors

+

Diamond Sponsors

+

AG Grid

Platinum Sponsors

Automattic Airbnb

Gold Sponsors

-

trunk.io

Silver Sponsors

-

JetBrains Liftoff American Express Workleap

Bronze Sponsors

-

WordHint Anagram Solver Icons8 Discord GitBook Nx HeroCoders

+

Qlty Software trunk.io Shopify

Silver Sponsors

+

Vite Liftoff American Express StackBlitz

Bronze Sponsors

+

Sentry Syntax Cybozu Anagram Solver Icons8 Discord GitBook Neko Nx Mercedes-Benz Group HeroCoders LambdaTest

Technology Sponsors

Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.

Netlify Algolia 1Password

diff --git a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs index 7f58e49bcd..afc433c7cd 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs +++ b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs @@ -102,8 +102,8 @@ const KEYS = { "attributes" ], ExportSpecifier: [ - "exported", - "local" + "local", + "exported" ], ExpressionStatement: [ "expression" diff --git a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts index a8684341f1..34253c96c3 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts +++ b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts @@ -24,4 +24,5 @@ declare function unionWith(additionalKeys: VisitorKeys): VisitorKeys; type VisitorKeys = VisitorKeys$1; -export { KEYS, type VisitorKeys, getKeys, unionWith }; +export { KEYS, getKeys, unionWith }; +export type { VisitorKeys }; diff --git a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/lib/visitor-keys.js b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/lib/visitor-keys.js index 41feb4b2f8..c891e040af 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/lib/visitor-keys.js +++ b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/lib/visitor-keys.js @@ -100,8 +100,8 @@ const KEYS = { "attributes" ], ExportSpecifier: [ - "exported", - "local" + "local", + "exported" ], ExpressionStatement: [ "expression" diff --git a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/package.json b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/package.json index 4dc2123dba..852e4ddb18 100644 --- a/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/package.json +++ b/node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "eslint-visitor-keys", - "version": "4.2.0", + "version": "4.2.1", "description": "Constants and utilities about visitor keys to traverse AST.", "type": "module", "main": "dist/eslint-visitor-keys.cjs", @@ -29,12 +29,9 @@ "@types/estree": "^0.0.51", "@types/estree-jsx": "^0.0.1", "@typescript-eslint/parser": "^8.7.0", - "c8": "^7.11.0", - "chai": "^4.3.6", "eslint-release": "^3.2.0", "esquery": "^1.4.0", "json-diff": "^0.7.3", - "mocha": "^9.2.1", "opener": "^1.5.2", "rollup": "^4.22.4", "rollup-plugin-dts": "^6.1.1", @@ -55,9 +52,15 @@ "test:open-coverage": "c8 report --reporter lcov && opener coverage/lcov-report/index.html", "test:types": "tsd" }, - "repository": "eslint/js", + "repository": { + "type": "git", + "url": "https://github.com/eslint/js.git", + "directory": "packages/eslint-visitor-keys" + }, "funding": "https://opencollective.com/eslint", - "keywords": [], + "keywords": [ + "eslint" + ], "author": "Toru Nagashima (https://github.com/mysticatea)", "license": "Apache-2.0", "bugs": { diff --git a/node_modules/@typescript-eslint/parser/package.json b/node_modules/@typescript-eslint/parser/package.json index a334a66540..9c9a932669 100644 --- a/node_modules/@typescript-eslint/parser/package.json +++ b/node_modules/@typescript-eslint/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "8.33.1", + "version": "8.35.1", "description": "An ESLint custom parser which leverages TypeScript ESTree", "files": [ "dist", @@ -52,10 +52,10 @@ "typescript": ">=4.8.4 <5.9.0" }, "dependencies": { - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4" }, "devDependencies": { diff --git a/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/dist/parser-options.d.ts b/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/dist/parser-options.d.ts index 5923587f5d..d1d85c5735 100644 --- a/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/dist/parser-options.d.ts +++ b/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/dist/parser-options.d.ts @@ -2,7 +2,7 @@ import type { Program } from 'typescript'; import type { Lib } from './lib'; export type DebugLevel = boolean | ('eslint' | 'typescript' | 'typescript-eslint')[]; export type CacheDurationSeconds = number | 'Infinity'; -export type EcmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 'latest' | undefined; +export type EcmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | 'latest' | undefined; export type SourceTypeClassic = 'module' | 'script'; export type SourceType = 'commonjs' | SourceTypeClassic; export type JSDocParsingMode = 'all' | 'none' | 'type-info'; diff --git a/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map b/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map index 6c0fff12bc..40fc7fbe8a 100644 --- a/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map +++ b/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"parser-options.d.ts","sourceRoot":"","sources":["../src/parser-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,CAAC,QAAQ,GAAG,YAAY,GAAG,mBAAmB,CAAC,EAAE,CAAC;AACtD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEvD,MAAM,MAAM,WAAW,GACnB,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AACpD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,iBAAiB,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;;;OAMG;IACH,+DAA+D,CAAC,EAAE,MAAM,CAAC;CAC1E;AAGD,MAAM,WAAW,aAAa;IAC5B,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,aAAa,CAAC,EAAE;QACd,IAAI,CAAC,EAAE,oBAAoB,CAAC;KAC7B,CAAC;IAGF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,YAAY,CAAC,EACT;QACE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACnC,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KAC3B,GACD,SAAS,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,CAAC;IAG1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,2CAA2C,CAAC,EAAE,OAAO,CAAC;IAEtD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7C,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,cAAc,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAAC;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C"} \ No newline at end of file +{"version":3,"file":"parser-options.d.ts","sourceRoot":"","sources":["../src/parser-options.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/package.json b/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/package.json index 5324be9fb4..e40eeded30 100644 --- a/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/package.json +++ b/node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "8.33.1", + "version": "8.35.1", "description": "Types for the TypeScript-ESTree AST spec", "files": [ "dist", diff --git a/node_modules/@typescript-eslint/project-service/package.json b/node_modules/@typescript-eslint/project-service/package.json index 2518a9b40b..084f4236b3 100644 --- a/node_modules/@typescript-eslint/project-service/package.json +++ b/node_modules/@typescript-eslint/project-service/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/project-service", - "version": "8.33.1", + "version": "8.35.1", "description": "Standalone TypeScript project service wrapper for linting.", "files": [ "dist", @@ -49,8 +49,8 @@ "typescript": ">=4.8.4 <5.9.0" }, "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.33.1", - "@typescript-eslint/types": "^8.33.1", + "@typescript-eslint/tsconfig-utils": "^8.35.1", + "@typescript-eslint/types": "^8.35.1", "debug": "^4.3.4" }, "funding": { diff --git a/node_modules/@typescript-eslint/tsconfig-utils/package.json b/node_modules/@typescript-eslint/tsconfig-utils/package.json index 42d3148562..a9746fdccf 100644 --- a/node_modules/@typescript-eslint/tsconfig-utils/package.json +++ b/node_modules/@typescript-eslint/tsconfig-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/tsconfig-utils", - "version": "8.33.1", + "version": "8.35.1", "description": "Utilities for collecting TSConfigs for linting scenarios.", "files": [ "dist", diff --git a/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.d.ts b/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.d.ts index 2eb4a7cfd2..7274e7b1b5 100644 --- a/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.d.ts +++ b/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.d.ts @@ -1,5 +1,6 @@ import * as ts from 'typescript'; /** + * @deprecated * Gets the source file for a given node */ export declare function getSourceFileOfNode(node: ts.Node): ts.SourceFile; diff --git a/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.d.ts.map b/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.d.ts.map index 4b992bd811..2558b1ea77 100644 --- a/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.d.ts.map +++ b/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"getSourceFileOfNode.d.ts","sourceRoot":"","sources":["../src/getSourceFileOfNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,UAAU,CAKhE"} \ No newline at end of file +{"version":3,"file":"getSourceFileOfNode.d.ts","sourceRoot":"","sources":["../src/getSourceFileOfNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,UAAU,CAKhE"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.js b/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.js index c27e044c71..3842a6bab2 100644 --- a/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.js +++ b/node_modules/@typescript-eslint/type-utils/dist/getSourceFileOfNode.js @@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.getSourceFileOfNode = getSourceFileOfNode; const ts = __importStar(require("typescript")); /** + * @deprecated * Gets the source file for a given node */ function getSourceFileOfNode(node) { diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts index 059713cab8..5d230e2348 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.d.ts @@ -14,19 +14,19 @@ export declare class ESLintScopeVariable extends VariableBase { writeable?: boolean; /** * Written to by ESLint. - * This property is undefined if there are no globals directive comments. - * The array of globals directive comments which defined this global variable in the source code file. + * This property is undefined if there are no globals comment directives. + * The array of globals comment directives which defined this global variable in the source code file. */ eslintExplicitGlobal?: boolean; /** * Written to by ESLint. - * The configured value in config files. This can be different from `variable.writeable` if there are globals directive comments. + * The configured value in config files. This can be different from `variable.writeable` if there are globals comment directives. */ eslintImplicitGlobalSetting?: 'readonly' | 'writable'; /** * Written to by ESLint. * If this key exists, it is a global variable added by ESLint. - * If `true`, this global variable was defined by a globals directive comment in the source code file. + * If `true`, this global variable was defined by a globals comment directive in the source code file. */ eslintExplicitGlobalComments?: TSESTree.Comment[]; } diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js index 8aea84ed01..4450dad2b3 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/dist/variable/ESLintScopeVariable.js @@ -16,19 +16,19 @@ class ESLintScopeVariable extends VariableBase_1.VariableBase { writeable; // note that this isn't a typo - ESlint uses this spelling here /** * Written to by ESLint. - * This property is undefined if there are no globals directive comments. - * The array of globals directive comments which defined this global variable in the source code file. + * This property is undefined if there are no globals comment directives. + * The array of globals comment directives which defined this global variable in the source code file. */ eslintExplicitGlobal; /** * Written to by ESLint. - * The configured value in config files. This can be different from `variable.writeable` if there are globals directive comments. + * The configured value in config files. This can be different from `variable.writeable` if there are globals comment directives. */ eslintImplicitGlobalSetting; /** * Written to by ESLint. * If this key exists, it is a global variable added by ESLint. - * If `true`, this global variable was defined by a globals directive comment in the source code file. + * If `true`, this global variable was defined by a globals comment directive in the source code file. */ eslintExplicitGlobalComments; } diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/package.json b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/package.json index 233360f3d7..e84ae367d8 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/package.json +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "8.33.1", + "version": "8.35.1", "description": "TypeScript scope analyser for ESLint", "files": [ "dist", @@ -48,11 +48,11 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "devDependencies": { - "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/typescript-estree": "8.35.1", "@vitest/coverage-v8": "^3.1.3", "@vitest/pretty-format": "^3.1.3", "glob": "*", diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/dist/parser-options.d.ts b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/dist/parser-options.d.ts index 5923587f5d..d1d85c5735 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/dist/parser-options.d.ts +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/dist/parser-options.d.ts @@ -2,7 +2,7 @@ import type { Program } from 'typescript'; import type { Lib } from './lib'; export type DebugLevel = boolean | ('eslint' | 'typescript' | 'typescript-eslint')[]; export type CacheDurationSeconds = number | 'Infinity'; -export type EcmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 'latest' | undefined; +export type EcmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | 'latest' | undefined; export type SourceTypeClassic = 'module' | 'script'; export type SourceType = 'commonjs' | SourceTypeClassic; export type JSDocParsingMode = 'all' | 'none' | 'type-info'; diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map index 6c0fff12bc..40fc7fbe8a 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/dist/parser-options.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"parser-options.d.ts","sourceRoot":"","sources":["../src/parser-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,CAAC,QAAQ,GAAG,YAAY,GAAG,mBAAmB,CAAC,EAAE,CAAC;AACtD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEvD,MAAM,MAAM,WAAW,GACnB,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AACpD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,iBAAiB,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;;;OAMG;IACH,+DAA+D,CAAC,EAAE,MAAM,CAAC;CAC1E;AAGD,MAAM,WAAW,aAAa;IAC5B,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,aAAa,CAAC,EAAE;QACd,IAAI,CAAC,EAAE,oBAAoB,CAAC;KAC7B,CAAC;IAGF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,YAAY,CAAC,EACT;QACE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACnC,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KAC3B,GACD,SAAS,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,CAAC;IAG1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,2CAA2C,CAAC,EAAE,OAAO,CAAC;IAEtD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7C,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,cAAc,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAAC;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C"} \ No newline at end of file +{"version":3,"file":"parser-options.d.ts","sourceRoot":"","sources":["../src/parser-options.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/package.json b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/package.json index 5324be9fb4..e40eeded30 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/package.json +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "8.33.1", + "version": "8.35.1", "description": "Types for the TypeScript-ESTree AST spec", "files": [ "dist", diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map index 1607334a86..d1bfa348e2 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/convert.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,EAAE,MAAM,aAAa,CAAC;AAmCtE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,GAAG,EAAE,CAAC,sBAAsB,GAC1D,OAAO,CAMT;AAED,MAAM,WAAW,OAAO;IACtB,qBAAqB,EAAE,2BAA2B,CAAC;IACnD,qBAAqB,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,qBAAa,SAAS;;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAEvD;;;;;OAKG;gBACS,GAAG,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAsZ1D,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,oCAAoC;IAe5C;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,sBAAsB;IA4C9B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;;;OAKG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;OAIG;IACH,OAAO,CAAC,kDAAkD;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,+BAA+B;IAgDvC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAiiFnB,OAAO,CAAC,UAAU;IAclB,cAAc,IAAI,QAAQ,CAAC,OAAO;IAIlC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA0FlB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAgFlB,UAAU,IAAI,OAAO;IAOrB;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAYhC"} \ No newline at end of file +{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,EAAE,MAAM,aAAa,CAAC;AAmCtE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,GAAG,EAAE,CAAC,sBAAsB,GAC1D,OAAO,CAMT;AAED,MAAM,WAAW,OAAO;IACtB,qBAAqB,EAAE,2BAA2B,CAAC;IACnD,qBAAqB,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC7D;AAqBD,qBAAa,SAAS;;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAEvD;;;;;OAKG;gBACS,GAAG,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAsZ1D,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,oCAAoC;IAe5C;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,sBAAsB;IA4C9B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;;;OAKG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;OAIG;IACH,OAAO,CAAC,kDAAkD;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,+BAA+B;IAgDvC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAyjFnB,OAAO,CAAC,UAAU;IAclB,cAAc,IAAI,QAAQ,CAAC,OAAO;IAIlC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA0FlB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAgFlB,UAAU,IAAI,OAAO;IAOrB;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAYhC"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/convert.js b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/convert.js index 1f8d85f999..382281b746 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/convert.js +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/convert.js @@ -50,6 +50,15 @@ const SyntaxKind = ts.SyntaxKind; function convertError(error) { return (0, node_utils_1.createError)(('message' in error && error.message) || error.messageText, error.file, error.start); } +function isPropertyAccessEntityNameExpression(node) { + return (ts.isPropertyAccessExpression(node) && + ts.isIdentifier(node.name) && + isEntityNameExpression(node.expression)); +} +function isEntityNameExpression(node) { + return (node.kind === SyntaxKind.Identifier || + isPropertyAccessEntityNameExpression(node)); +} class Converter { allowPattern = false; ast; @@ -1169,14 +1178,23 @@ class Converter { if (constructor.typeParameters) { this.fixParentLocation(constructor, constructor.typeParameters.range); } - const constructorKey = this.createNode(node, { - type: ts_estree_1.AST_NODE_TYPES.Identifier, - range: [constructorToken.getStart(this.ast), constructorToken.end], - decorators: [], - name: 'constructor', - optional: false, - typeAnnotation: undefined, - }); + const constructorKey = constructorToken.kind === SyntaxKind.StringLiteral + ? this.createNode(constructorToken, { + type: ts_estree_1.AST_NODE_TYPES.Literal, + raw: constructorToken.getText(), + value: 'constructor', + }) + : this.createNode(node, { + type: ts_estree_1.AST_NODE_TYPES.Identifier, + range: [ + constructorToken.getStart(this.ast), + constructorToken.end, + ], + decorators: [], + name: 'constructor', + optional: false, + typeAnnotation: undefined, + }); const isStatic = (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node); return this.createNode(node, { type: (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node) @@ -2185,13 +2203,22 @@ class Converter { case SyntaxKind.InterfaceDeclaration: { const interfaceHeritageClauses = node.heritageClauses ?? []; const interfaceExtends = []; + let seenExtendsClause = false; for (const heritageClause of interfaceHeritageClauses) { if (heritageClause.token !== SyntaxKind.ExtendsKeyword) { this.#throwError(heritageClause, heritageClause.token === SyntaxKind.ImplementsKeyword ? "Interface declaration cannot have 'implements' clause." : 'Unexpected token.'); } + if (seenExtendsClause) { + this.#throwError(heritageClause, "'extends' clause already seen."); + } + seenExtendsClause = true; for (const heritageType of heritageClause.types) { + if (!isEntityNameExpression(heritageType.expression) || + ts.isOptionalChain(heritageType.expression)) { + this.#throwError(heritageType, 'Interface declaration can only extend an identifier/qualified name with optional type arguments.'); + } interfaceExtends.push(this.convertChild(heritageType, node)); } } diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map index f4999949a8..5ab4c563d2 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"node-utils.d.ts","sourceRoot":"","sources":["../src/node-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"node-utils.d.ts","sourceRoot":"","sources":["../src/node-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js index d8adac997d..df5a7eed34 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/dist/node-utils.js @@ -410,6 +410,9 @@ function isChildUnwrappableOptionalChain(node, child) { * Returns the type of a given ts.Token */ function getTokenType(token) { + if (token.kind === SyntaxKind.NullKeyword) { + return ts_estree_1.AST_TOKEN_TYPES.Null; + } let keywordKind; if (isAtLeast50 && token.kind === SyntaxKind.Identifier) { keywordKind = ts.identifierToKeywordKind(token); diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/package.json b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/package.json index 15556fdfd5..32c5f69879 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/package.json +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "8.33.1", + "version": "8.35.1", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "files": [ "dist", @@ -53,10 +53,10 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/dist/ts-eslint/Config.d.ts b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/dist/ts-eslint/Config.d.ts index fcc13ca58c..8ee3630263 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/dist/ts-eslint/Config.d.ts +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/dist/ts-eslint/Config.d.ts @@ -58,7 +58,7 @@ export declare namespace ClassicConfig { */ globals?: GlobalsConfig; /** - * The flag that disables directive comments. + * The flag that disables comment directives. */ noInlineConfig?: boolean; /** diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/dist/ts-eslint/eslint/ESLintShared.d.ts b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/dist/ts-eslint/eslint/ESLintShared.d.ts index f550f10e65..9df2ae9e7d 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/dist/ts-eslint/eslint/ESLintShared.d.ts +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/dist/ts-eslint/eslint/ESLintShared.d.ts @@ -87,7 +87,7 @@ export declare class ESLintBase { /** - * If false is present, ESLint suppresses directive comments in source code. + * If false is present, ESLint suppresses comment directives in source code. * If this option is false, it overrides the noInlineConfig setting in your configurations. * @default true */ diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/package.json b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/package.json index c5c543f6eb..d2aa43d309 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/package.json +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/utils", - "version": "8.33.1", + "version": "8.35.1", "description": "Utilities for working with TypeScript + ESLint together", "files": [ "dist", @@ -63,9 +63,9 @@ }, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1" + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js index b09fde6c8e..0e13f57bf0 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys/dist/visitor-keys.js @@ -137,8 +137,8 @@ const additionalKeys = { TSExternalModuleReference: ['expression'], TSFunctionType: SharedVisitorKeys.FunctionType, TSImportEqualsDeclaration: ['id', 'moduleReference'], - TSImportType: ['argument', 'qualifier', 'typeArguments', 'options'], - TSIndexedAccessType: ['indexType', 'objectType'], + TSImportType: ['argument', 'options', 'qualifier', 'typeArguments'], + TSIndexedAccessType: ['objectType', 'indexType'], TSIndexSignature: ['parameters', 'typeAnnotation'], TSInferType: ['typeParameter'], TSInstantiationExpression: ['expression', 'typeArguments'], @@ -149,7 +149,7 @@ const additionalKeys = { TSIntrinsicKeyword: [], TSLiteralType: ['literal'], TSMappedType: ['key', 'constraint', 'nameType', 'typeAnnotation'], - TSMethodSignature: ['typeParameters', 'key', 'params', 'returnType'], + TSMethodSignature: ['key', 'typeParameters', 'params', 'returnType'], TSModuleBlock: ['body'], TSModuleDeclaration: ['id', 'body'], TSNamedTupleMember: ['label', 'elementType'], @@ -162,7 +162,7 @@ const additionalKeys = { TSOptionalType: ['typeAnnotation'], TSParameterProperty: ['decorators', 'parameter'], TSPrivateKeyword: [], - TSPropertySignature: ['typeAnnotation', 'key'], + TSPropertySignature: ['key', 'typeAnnotation'], TSProtectedKeyword: [], TSPublicKeyword: [], TSQualifiedName: ['left', 'right'], @@ -183,7 +183,7 @@ const additionalKeys = { TSTypeParameter: ['name', 'constraint', 'default'], TSTypeParameterDeclaration: ['params'], TSTypeParameterInstantiation: ['params'], - TSTypePredicate: ['typeAnnotation', 'parameterName'], + TSTypePredicate: ['parameterName', 'typeAnnotation'], TSTypeQuery: ['exprName', 'typeArguments'], TSTypeReference: ['typeName', 'typeArguments'], TSUndefinedKeyword: [], diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys/package.json b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys/package.json index 89aafa93bf..3dc5f9672f 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys/package.json +++ b/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "8.33.1", + "version": "8.35.1", "description": "Visitor keys used to help traverse the TypeScript-ESTree AST", "files": [ "dist", @@ -46,8 +46,8 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "devDependencies": { "@vitest/coverage-v8": "^3.1.3", diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion/index.js b/node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion/index.js index 4af9ddee46..a27f81ce04 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion/index.js +++ b/node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion/index.js @@ -116,7 +116,7 @@ function expand(str, isTop) { var isOptions = m.body.indexOf(',') >= 0; if (!isSequence && !isOptions) { // {a},b} - if (m.post.match(/,.*\}/)) { + if (m.post.match(/,(?!,).*\}/)) { str = m.pre + '{' + m.body + escClose + m.post; return expand(str); } diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion/package.json b/node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion/package.json index 7097d41e39..c7eee34511 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion/package.json +++ b/node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion/package.json @@ -1,7 +1,7 @@ { "name": "brace-expansion", "description": "Brace expansion as known from sh/bash", - "version": "2.0.1", + "version": "2.0.2", "repository": { "type": "git", "url": "git://github.com/juliangruber/brace-expansion.git" @@ -42,5 +42,8 @@ "iphone/6.0..latest", "android-browser/4.2..latest" ] + }, + "publishConfig": { + "tag": "2.x" } } diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/README.md b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/README.md index 3cbbdd39d0..aa860ba577 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/README.md +++ b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/README.md @@ -109,11 +109,12 @@ Welcome. See [ESLint contribution guidelines](https://eslint.org/docs/developer- The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate) to get your logo on our READMEs and [website](https://eslint.org/sponsors). -

Platinum Sponsors

+

Diamond Sponsors

+

AG Grid

Platinum Sponsors

Automattic Airbnb

Gold Sponsors

-

trunk.io

Silver Sponsors

-

JetBrains Liftoff American Express Workleap

Bronze Sponsors

-

WordHint Anagram Solver Icons8 Discord GitBook Nx HeroCoders

+

Qlty Software trunk.io Shopify

Silver Sponsors

+

Vite Liftoff American Express StackBlitz

Bronze Sponsors

+

Sentry Syntax Cybozu Anagram Solver Icons8 Discord GitBook Neko Nx Mercedes-Benz Group HeroCoders LambdaTest

Technology Sponsors

Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.

Netlify Algolia 1Password

diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs index 7f58e49bcd..afc433c7cd 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs +++ b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs @@ -102,8 +102,8 @@ const KEYS = { "attributes" ], ExportSpecifier: [ - "exported", - "local" + "local", + "exported" ], ExpressionStatement: [ "expression" diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts index a8684341f1..34253c96c3 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts +++ b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.d.cts @@ -24,4 +24,5 @@ declare function unionWith(additionalKeys: VisitorKeys): VisitorKeys; type VisitorKeys = VisitorKeys$1; -export { KEYS, type VisitorKeys, getKeys, unionWith }; +export { KEYS, getKeys, unionWith }; +export type { VisitorKeys }; diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/lib/visitor-keys.js b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/lib/visitor-keys.js index 41feb4b2f8..c891e040af 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/lib/visitor-keys.js +++ b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/lib/visitor-keys.js @@ -100,8 +100,8 @@ const KEYS = { "attributes" ], ExportSpecifier: [ - "exported", - "local" + "local", + "exported" ], ExpressionStatement: [ "expression" diff --git a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/package.json b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/package.json index 4dc2123dba..852e4ddb18 100644 --- a/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/package.json +++ b/node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "eslint-visitor-keys", - "version": "4.2.0", + "version": "4.2.1", "description": "Constants and utilities about visitor keys to traverse AST.", "type": "module", "main": "dist/eslint-visitor-keys.cjs", @@ -29,12 +29,9 @@ "@types/estree": "^0.0.51", "@types/estree-jsx": "^0.0.1", "@typescript-eslint/parser": "^8.7.0", - "c8": "^7.11.0", - "chai": "^4.3.6", "eslint-release": "^3.2.0", "esquery": "^1.4.0", "json-diff": "^0.7.3", - "mocha": "^9.2.1", "opener": "^1.5.2", "rollup": "^4.22.4", "rollup-plugin-dts": "^6.1.1", @@ -55,9 +52,15 @@ "test:open-coverage": "c8 report --reporter lcov && opener coverage/lcov-report/index.html", "test:types": "tsd" }, - "repository": "eslint/js", + "repository": { + "type": "git", + "url": "https://github.com/eslint/js.git", + "directory": "packages/eslint-visitor-keys" + }, "funding": "https://opencollective.com/eslint", - "keywords": [], + "keywords": [ + "eslint" + ], "author": "Toru Nagashima (https://github.com/mysticatea)", "license": "Apache-2.0", "bugs": { diff --git a/node_modules/@typescript-eslint/type-utils/package.json b/node_modules/@typescript-eslint/type-utils/package.json index 508fa36ae3..18b965950f 100644 --- a/node_modules/@typescript-eslint/type-utils/package.json +++ b/node_modules/@typescript-eslint/type-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/type-utils", - "version": "8.33.1", + "version": "8.35.1", "description": "Type utilities for working with TypeScript + ESLint together", "files": [ "dist", @@ -45,8 +45,8 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/typescript-estree": "8.33.1", - "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/utils": "8.35.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -55,7 +55,7 @@ "typescript": ">=4.8.4 <5.9.0" }, "devDependencies": { - "@typescript-eslint/parser": "8.33.1", + "@typescript-eslint/parser": "8.35.1", "@vitest/coverage-v8": "^3.1.3", "ajv": "^6.12.6", "eslint": "*", diff --git a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/LICENSE b/node_modules/eslint-plugin-github/node_modules/@eslint/compat/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/README.md b/node_modules/eslint-plugin-github/node_modules/@eslint/compat/README.md deleted file mode 100644 index 870e961300..0000000000 --- a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/README.md +++ /dev/null @@ -1,206 +0,0 @@ -# ESLint Compatibility Utilities - -## Overview - -This packages contains functions that allow you to wrap existing ESLint rules, plugins, and configurations that were intended for use with ESLint v8.x to allow them to work as-is in ESLint v9.x. - -**Note:** All plugins are not guaranteed to work in ESLint v9.x. This package fixes the most common issues but can't fix everything. - -## Installation - -For Node.js and compatible runtimes: - -```shell -npm install @eslint/compat -D -# or -yarn add @eslint/compat -D -# or -pnpm install @eslint/compat -D -# or -bun install @eslint/compat -D -``` - -For Deno: - -```shell -deno add @eslint/compat -``` - -## Usage - -This package exports the following functions in both ESM and CommonJS format: - -- `fixupRule(rule)` - wraps the given rule in a compatibility layer and returns the result -- `fixupPluginRules(plugin)` - wraps each rule in the given plugin using `fixupRule()` and returns a new object that represents the plugin with the fixed-up rules -- `fixupConfigRules(configs)` - wraps all plugins found in an array of config objects using `fixupPluginRules()` -- `includeIgnoreFile(path)` - reads an ignore file (like `.gitignore`) and converts the patterns into the correct format for the config file - -### Fixing Rules - -If you have a rule that you'd like to make compatible with ESLint v9.x, you can do so using the `fixupRule()` function: - -```js -// ESM example -import { fixupRule } from "@eslint/compat"; - -// Step 1: Import your rule -import myRule from "./local-rule.js"; - -// Step 2: Create backwards-compatible rule -const compatRule = fixupRule(myRule); - -// Step 3 (optional): Export fixed rule -export default compatRule; -``` - -Or in CommonJS: - -```js -// CommonJS example -const { fixupRule } = require("@eslint/compat"); - -// Step 1: Import your rule -const myRule = require("./local-rule.js"); - -// Step 2: Create backwards-compatible rule -const compatRule = fixupRule(myRule); - -// Step 3 (optional): Export fixed rule -module.exports = compatRule; -``` - -### Fixing Plugins - -If you are using a plugin in your `eslint.config.js` that is not yet compatible with ESLint 9.x, you can wrap it using the `fixupPluginRules()` function: - -```js -// eslint.config.js - ESM example -import { fixupPluginRules } from "@eslint/compat"; -import somePlugin from "eslint-plugin-some-plugin"; - -export default [ - { - plugins: { - // insert the fixed plugin instead of the original - somePlugin: fixupPluginRules(somePlugin), - }, - rules: { - "somePlugin/rule-name": "error", - }, - }, -]; -``` - -Or in CommonJS: - -```js -// eslint.config.js - CommonJS example -const { fixupPluginRules } = require("@eslint/compat"); -const somePlugin = require("eslint-plugin-some-plugin"); - -module.exports = [ - { - plugins: { - // insert the fixed plugin instead of the original - somePlugin: fixupPluginRules(somePlugin), - }, - rules: { - "somePlugin/rule-name": "error", - }, - }, -]; -``` - -### Fixing Configs - -If you are importing other configs into your `eslint.config.js` that use plugins that are not yet compatible with ESLint 9.x, you can wrap the entire array or a single object using the `fixupConfigRules()` function: - -```js -// eslint.config.js - ESM example -import { fixupConfigRules } from "@eslint/compat"; -import someConfig from "eslint-config-some-config"; - -export default [ - ...fixupConfigRules(someConfig), - { - // your overrides - }, -]; -``` - -Or in CommonJS: - -```js -// eslint.config.js - CommonJS example -const { fixupConfigRules } = require("@eslint/compat"); -const someConfig = require("eslint-config-some-config"); - -module.exports = [ - ...fixupConfigRules(someConfig), - { - // your overrides - }, -]; -``` - -### Including Ignore Files - -If you were using an alternate ignore file in ESLint v8.x, such as using `--ignore-path .gitignore` on the command line, you can include those patterns programmatically in your config file using the `includeIgnoreFile()` function. For example: - -```js -// eslint.config.js - ESM example -import { includeIgnoreFile } from "@eslint/compat"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -const gitignorePath = path.resolve(__dirname, ".gitignore"); - -export default [ - includeIgnoreFile(gitignorePath), - { - // your overrides - }, -]; -``` - -Or in CommonJS: - -```js -// eslint.config.js - CommonJS example -const { includeIgnoreFile } = require("@eslint/compat"); -const path = require("node:path"); -const gitignorePath = path.resolve(__dirname, ".gitignore"); - -module.exports = [ - includeIgnoreFile(gitignorePath), - { - // your overrides - }, -]; -``` - -**Limitation:** This works without modification when the ignore file is in the same directory as your config file. If the ignore file is in a different directory, you may need to modify the patterns manually. - -## License - -Apache 2.0 - - - - -## Sponsors - -The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate) -to get your logo on our READMEs and [website](https://eslint.org/sponsors). - -

Platinum Sponsors

-

Automattic Airbnb

Gold Sponsors

-

trunk.io

Silver Sponsors

-

SERP Triumph JetBrains Liftoff American Express Workleap

Bronze Sponsors

-

Cybozu Syntax WordHint Anagram Solver Icons8 Discord GitBook Nx HeroCoders

-

Technology Sponsors

-Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work. -

Netlify Algolia 1Password

- diff --git a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/cjs/index.cjs b/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/cjs/index.cjs deleted file mode 100644 index b0246262b6..0000000000 --- a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/cjs/index.cjs +++ /dev/null @@ -1,366 +0,0 @@ -'use strict'; - -var fs = require('node:fs'); -var path = require('node:path'); - -/** - * @filedescription Functions to fix up rules to provide missing methods on the `context` object. - * @author Nicholas C. Zakas - */ - -//----------------------------------------------------------------------------- -// Types -//----------------------------------------------------------------------------- - -/** @typedef {import("eslint").ESLint.Plugin} FixupPluginDefinition */ -/** @typedef {import("eslint").Rule.RuleModule} FixupRuleDefinition */ -/** @typedef {FixupRuleDefinition["create"]} FixupLegacyRuleDefinition */ -/** @typedef {import("eslint").Linter.Config} FixupConfig */ -/** @typedef {Array} FixupConfigArray */ - -//----------------------------------------------------------------------------- -// Data -//----------------------------------------------------------------------------- - -/** - * The removed methods from the `context` object that need to be added back. - * The keys are the name of the method on the `context` object and the values - * are the name of the method on the `sourceCode` object. - * @type {Map} - */ -const removedMethodNames = new Map([ - ["getSource", "getText"], - ["getSourceLines", "getLines"], - ["getAllComments", "getAllComments"], - ["getDeclaredVariables", "getDeclaredVariables"], - ["getNodeByRangeIndex", "getNodeByRangeIndex"], - ["getCommentsBefore", "getCommentsBefore"], - ["getCommentsAfter", "getCommentsAfter"], - ["getCommentsInside", "getCommentsInside"], - ["getJSDocComment", "getJSDocComment"], - ["getFirstToken", "getFirstToken"], - ["getFirstTokens", "getFirstTokens"], - ["getLastToken", "getLastToken"], - ["getLastTokens", "getLastTokens"], - ["getTokenAfter", "getTokenAfter"], - ["getTokenBefore", "getTokenBefore"], - ["getTokenByRangeStart", "getTokenByRangeStart"], - ["getTokens", "getTokens"], - ["getTokensAfter", "getTokensAfter"], - ["getTokensBefore", "getTokensBefore"], - ["getTokensBetween", "getTokensBetween"], -]); - -/** - * Tracks the original rule definition and the fixed-up rule definition. - * @type {WeakMap} - */ -const fixedUpRuleReplacements = new WeakMap(); - -/** - * Tracks all of the fixed up rule definitions so we don't duplicate effort. - * @type {WeakSet} - */ -const fixedUpRules = new WeakSet(); - -/** - * Tracks the original plugin definition and the fixed-up plugin definition. - * @type {WeakMap} - */ -const fixedUpPluginReplacements = new WeakMap(); - -/** - * Tracks all of the fixed up plugin definitions so we don't duplicate effort. - * @type {WeakSet} - */ -const fixedUpPlugins = new WeakSet(); - -//----------------------------------------------------------------------------- -// Exports -//----------------------------------------------------------------------------- - -/** - * Takes the given rule and creates a new rule with the `create()` method wrapped - * to provide the missing methods on the `context` object. - * @param {FixupRuleDefinition|FixupLegacyRuleDefinition} ruleDefinition The rule to fix up. - * @returns {FixupRuleDefinition} The fixed-up rule. - */ -function fixupRule(ruleDefinition) { - // first check if we've already fixed up this rule - if (fixedUpRuleReplacements.has(ruleDefinition)) { - return fixedUpRuleReplacements.get(ruleDefinition); - } - - const isLegacyRule = typeof ruleDefinition === "function"; - - // check to see if this rule definition has already been fixed up - if (!isLegacyRule && fixedUpRules.has(ruleDefinition)) { - return ruleDefinition; - } - - const originalCreate = isLegacyRule - ? ruleDefinition - : ruleDefinition.create.bind(ruleDefinition); - - function ruleCreate(context) { - // if getScope is already there then no need to create old methods - if ("getScope" in context) { - return originalCreate(context); - } - - const sourceCode = context.sourceCode; - let currentNode = sourceCode.ast; - - const newContext = Object.assign(Object.create(context), { - parserServices: sourceCode.parserServices, - - /* - * The following methods rely on the current node in the traversal, - * so we need to add them manually. - */ - getScope() { - return sourceCode.getScope(currentNode); - }, - - getAncestors() { - return sourceCode.getAncestors(currentNode); - }, - - markVariableAsUsed(variable) { - sourceCode.markVariableAsUsed(variable, currentNode); - }, - }); - - // add passthrough methods - for (const [ - contextMethodName, - sourceCodeMethodName, - ] of removedMethodNames) { - newContext[contextMethodName] = - sourceCode[sourceCodeMethodName].bind(sourceCode); - } - - // freeze just like the original context - Object.freeze(newContext); - - /* - * Create the visitor object using the original create() method. - * This is necessary to ensure that the visitor object is created - * with the correct context. - */ - const visitor = originalCreate(newContext); - - /* - * Wrap each method in the visitor object to update the currentNode - * before calling the original method. This is necessary because the - * methods like `getScope()` need to know the current node. - */ - for (const [methodName, method] of Object.entries(visitor)) { - /* - * Node is the second argument to most code path methods, - * and the third argument for onCodePathSegmentLoop. - */ - if (methodName.startsWith("on")) { - // eslint-disable-next-line no-loop-func -- intentionally updating shared `currentNode` variable - visitor[methodName] = (...args) => { - currentNode = - args[methodName === "onCodePathSegmentLoop" ? 2 : 1]; - - return method.call(visitor, ...args); - }; - - continue; - } - - // eslint-disable-next-line no-loop-func -- intentionally updating shared `currentNode` variable - visitor[methodName] = (...args) => { - currentNode = args[0]; - - return method.call(visitor, ...args); - }; - } - - return visitor; - } - - const newRuleDefinition = { - ...(isLegacyRule ? undefined : ruleDefinition), - create: ruleCreate, - }; - - // copy `schema` property of function-style rule or top-level `schema` property of object-style rule into `meta` object - // @ts-ignore -- top-level `schema` property was not offically supported for object-style rules so it doesn't exist in types - const { schema } = ruleDefinition; - if (schema) { - if (!newRuleDefinition.meta) { - newRuleDefinition.meta = { schema }; - } else { - newRuleDefinition.meta = { - ...newRuleDefinition.meta, - // top-level `schema` had precedence over `meta.schema` so it's okay to overwrite `meta.schema` if it exists - schema, - }; - } - } - - // cache the fixed up rule - fixedUpRuleReplacements.set(ruleDefinition, newRuleDefinition); - fixedUpRules.add(newRuleDefinition); - - return newRuleDefinition; -} - -/** - * Takes the given plugin and creates a new plugin with all of the rules wrapped - * to provide the missing methods on the `context` object. - * @param {FixupPluginDefinition} plugin The plugin to fix up. - * @returns {FixupPluginDefinition} The fixed-up plugin. - */ -function fixupPluginRules(plugin) { - // first check if we've already fixed up this plugin - if (fixedUpPluginReplacements.has(plugin)) { - return fixedUpPluginReplacements.get(plugin); - } - - /* - * If the plugin has already been fixed up, or if the plugin - * doesn't have any rules, we can just return it. - */ - if (fixedUpPlugins.has(plugin) || !plugin.rules) { - return plugin; - } - - const newPlugin = { - ...plugin, - rules: Object.fromEntries( - Object.entries(plugin.rules).map(([ruleId, ruleDefinition]) => [ - ruleId, - fixupRule(ruleDefinition), - ]), - ), - }; - - // cache the fixed up plugin - fixedUpPluginReplacements.set(plugin, newPlugin); - fixedUpPlugins.add(newPlugin); - - return newPlugin; -} - -/** - * Takes the given configuration and creates a new configuration with all of the - * rules wrapped to provide the missing methods on the `context` object. - * @param {FixupConfigArray|FixupConfig} config The configuration to fix up. - * @returns {FixupConfigArray} The fixed-up configuration. - */ -function fixupConfigRules(config) { - const configs = Array.isArray(config) ? config : [config]; - - return configs.map(configItem => { - if (!configItem.plugins) { - return configItem; - } - - const newPlugins = Object.fromEntries( - Object.entries(configItem.plugins).map(([pluginName, plugin]) => [ - pluginName, - fixupPluginRules(plugin), - ]), - ); - - return { - ...configItem, - plugins: newPlugins, - }; - }); -} - -/** - * @fileoverview Ignore file utilities for the compat package. - * @author Nicholas C. Zakas - */ - - -//----------------------------------------------------------------------------- -// Types -//----------------------------------------------------------------------------- - -/** @typedef {import("eslint").Linter.Config} FlatConfig */ - -//----------------------------------------------------------------------------- -// Exports -//----------------------------------------------------------------------------- - -/** - * Converts an ESLint ignore pattern to a minimatch pattern. - * @param {string} pattern The .eslintignore or .gitignore pattern to convert. - * @returns {string} The converted pattern. - */ -function convertIgnorePatternToMinimatch(pattern) { - const isNegated = pattern.startsWith("!"); - const negatedPrefix = isNegated ? "!" : ""; - const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd(); - - // special cases - if (["", "**", "/**", "**/"].includes(patternToTest)) { - return `${negatedPrefix}${patternToTest}`; - } - - const firstIndexOfSlash = patternToTest.indexOf("/"); - - const matchEverywherePrefix = - firstIndexOfSlash < 0 || firstIndexOfSlash === patternToTest.length - 1 - ? "**/" - : ""; - - const patternWithoutLeadingSlash = - firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest; - - /* - * Escape `{` and `(` because in gitignore patterns they are just - * literal characters without any specific syntactic meaning, - * while in minimatch patterns they can form brace expansion or extglob syntax. - * - * For example, gitignore pattern `src/{a,b}.js` ignores file `src/{a,b}.js`. - * But, the same minimatch pattern `src/{a,b}.js` ignores files `src/a.js` and `src/b.js`. - * Minimatch pattern `src/\{a,b}.js` is equivalent to gitignore pattern `src/{a,b}.js`. - */ - const escapedPatternWithoutLeadingSlash = - patternWithoutLeadingSlash.replaceAll( - /(?=((?:\\.|[^{(])*))\1([{(])/guy, - "$1\\$2", - ); - - const matchInsideSuffix = patternToTest.endsWith("/**") ? "/*" : ""; - - return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`; -} - -/** - * Reads an ignore file and returns an object with the ignore patterns. - * @param {string} ignoreFilePath The absolute path to the ignore file. - * @returns {FlatConfig} An object with an `ignores` property that is an array of ignore patterns. - * @throws {Error} If the ignore file path is not an absolute path. - */ -function includeIgnoreFile(ignoreFilePath) { - if (!path.isAbsolute(ignoreFilePath)) { - throw new Error("The ignore file location must be an absolute path."); - } - - const ignoreFile = fs.readFileSync(ignoreFilePath, "utf8"); - const lines = ignoreFile.split(/\r?\n/u); - - return { - name: "Imported .gitignore patterns", - ignores: lines - .map(line => line.trim()) - .filter(line => line && !line.startsWith("#")) - .map(convertIgnorePatternToMinimatch), - }; -} - -exports.convertIgnorePatternToMinimatch = convertIgnorePatternToMinimatch; -exports.fixupConfigRules = fixupConfigRules; -exports.fixupPluginRules = fixupPluginRules; -exports.fixupRule = fixupRule; -exports.includeIgnoreFile = includeIgnoreFile; diff --git a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/cjs/index.d.cts b/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/cjs/index.d.cts deleted file mode 100644 index d5284613cb..0000000000 --- a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/cjs/index.d.cts +++ /dev/null @@ -1,45 +0,0 @@ -export type FlatConfig = import("eslint").Linter.Config; -export type FixupPluginDefinition = import("eslint").ESLint.Plugin; -export type FixupRuleDefinition = import("eslint").Rule.RuleModule; -export type FixupLegacyRuleDefinition = FixupRuleDefinition["create"]; -export type FixupConfig = import("eslint").Linter.Config; -export type FixupConfigArray = Array; -/** - * @fileoverview Ignore file utilities for the compat package. - * @author Nicholas C. Zakas - */ -/** @typedef {import("eslint").Linter.Config} FlatConfig */ -/** - * Converts an ESLint ignore pattern to a minimatch pattern. - * @param {string} pattern The .eslintignore or .gitignore pattern to convert. - * @returns {string} The converted pattern. - */ -export function convertIgnorePatternToMinimatch(pattern: string): string; -/** - * Takes the given configuration and creates a new configuration with all of the - * rules wrapped to provide the missing methods on the `context` object. - * @param {FixupConfigArray|FixupConfig} config The configuration to fix up. - * @returns {FixupConfigArray} The fixed-up configuration. - */ -export function fixupConfigRules(config: FixupConfigArray | FixupConfig): FixupConfigArray; -/** - * Takes the given plugin and creates a new plugin with all of the rules wrapped - * to provide the missing methods on the `context` object. - * @param {FixupPluginDefinition} plugin The plugin to fix up. - * @returns {FixupPluginDefinition} The fixed-up plugin. - */ -export function fixupPluginRules(plugin: FixupPluginDefinition): FixupPluginDefinition; -/** - * Takes the given rule and creates a new rule with the `create()` method wrapped - * to provide the missing methods on the `context` object. - * @param {FixupRuleDefinition|FixupLegacyRuleDefinition} ruleDefinition The rule to fix up. - * @returns {FixupRuleDefinition} The fixed-up rule. - */ -export function fixupRule(ruleDefinition: FixupRuleDefinition | FixupLegacyRuleDefinition): FixupRuleDefinition; -/** - * Reads an ignore file and returns an object with the ignore patterns. - * @param {string} ignoreFilePath The absolute path to the ignore file. - * @returns {FlatConfig} An object with an `ignores` property that is an array of ignore patterns. - * @throws {Error} If the ignore file path is not an absolute path. - */ -export function includeIgnoreFile(ignoreFilePath: string): FlatConfig; diff --git a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/esm/index.d.ts b/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/esm/index.d.ts deleted file mode 100644 index d5284613cb..0000000000 --- a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/esm/index.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -export type FlatConfig = import("eslint").Linter.Config; -export type FixupPluginDefinition = import("eslint").ESLint.Plugin; -export type FixupRuleDefinition = import("eslint").Rule.RuleModule; -export type FixupLegacyRuleDefinition = FixupRuleDefinition["create"]; -export type FixupConfig = import("eslint").Linter.Config; -export type FixupConfigArray = Array; -/** - * @fileoverview Ignore file utilities for the compat package. - * @author Nicholas C. Zakas - */ -/** @typedef {import("eslint").Linter.Config} FlatConfig */ -/** - * Converts an ESLint ignore pattern to a minimatch pattern. - * @param {string} pattern The .eslintignore or .gitignore pattern to convert. - * @returns {string} The converted pattern. - */ -export function convertIgnorePatternToMinimatch(pattern: string): string; -/** - * Takes the given configuration and creates a new configuration with all of the - * rules wrapped to provide the missing methods on the `context` object. - * @param {FixupConfigArray|FixupConfig} config The configuration to fix up. - * @returns {FixupConfigArray} The fixed-up configuration. - */ -export function fixupConfigRules(config: FixupConfigArray | FixupConfig): FixupConfigArray; -/** - * Takes the given plugin and creates a new plugin with all of the rules wrapped - * to provide the missing methods on the `context` object. - * @param {FixupPluginDefinition} plugin The plugin to fix up. - * @returns {FixupPluginDefinition} The fixed-up plugin. - */ -export function fixupPluginRules(plugin: FixupPluginDefinition): FixupPluginDefinition; -/** - * Takes the given rule and creates a new rule with the `create()` method wrapped - * to provide the missing methods on the `context` object. - * @param {FixupRuleDefinition|FixupLegacyRuleDefinition} ruleDefinition The rule to fix up. - * @returns {FixupRuleDefinition} The fixed-up rule. - */ -export function fixupRule(ruleDefinition: FixupRuleDefinition | FixupLegacyRuleDefinition): FixupRuleDefinition; -/** - * Reads an ignore file and returns an object with the ignore patterns. - * @param {string} ignoreFilePath The absolute path to the ignore file. - * @returns {FlatConfig} An object with an `ignores` property that is an array of ignore patterns. - * @throws {Error} If the ignore file path is not an absolute path. - */ -export function includeIgnoreFile(ignoreFilePath: string): FlatConfig; diff --git a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/esm/index.js b/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/esm/index.js deleted file mode 100644 index 878f2fc6af..0000000000 --- a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/dist/esm/index.js +++ /dev/null @@ -1,361 +0,0 @@ -// @ts-self-types="./index.d.ts" -import fs from 'node:fs'; -import path from 'node:path'; - -/** - * @filedescription Functions to fix up rules to provide missing methods on the `context` object. - * @author Nicholas C. Zakas - */ - -//----------------------------------------------------------------------------- -// Types -//----------------------------------------------------------------------------- - -/** @typedef {import("eslint").ESLint.Plugin} FixupPluginDefinition */ -/** @typedef {import("eslint").Rule.RuleModule} FixupRuleDefinition */ -/** @typedef {FixupRuleDefinition["create"]} FixupLegacyRuleDefinition */ -/** @typedef {import("eslint").Linter.Config} FixupConfig */ -/** @typedef {Array} FixupConfigArray */ - -//----------------------------------------------------------------------------- -// Data -//----------------------------------------------------------------------------- - -/** - * The removed methods from the `context` object that need to be added back. - * The keys are the name of the method on the `context` object and the values - * are the name of the method on the `sourceCode` object. - * @type {Map} - */ -const removedMethodNames = new Map([ - ["getSource", "getText"], - ["getSourceLines", "getLines"], - ["getAllComments", "getAllComments"], - ["getDeclaredVariables", "getDeclaredVariables"], - ["getNodeByRangeIndex", "getNodeByRangeIndex"], - ["getCommentsBefore", "getCommentsBefore"], - ["getCommentsAfter", "getCommentsAfter"], - ["getCommentsInside", "getCommentsInside"], - ["getJSDocComment", "getJSDocComment"], - ["getFirstToken", "getFirstToken"], - ["getFirstTokens", "getFirstTokens"], - ["getLastToken", "getLastToken"], - ["getLastTokens", "getLastTokens"], - ["getTokenAfter", "getTokenAfter"], - ["getTokenBefore", "getTokenBefore"], - ["getTokenByRangeStart", "getTokenByRangeStart"], - ["getTokens", "getTokens"], - ["getTokensAfter", "getTokensAfter"], - ["getTokensBefore", "getTokensBefore"], - ["getTokensBetween", "getTokensBetween"], -]); - -/** - * Tracks the original rule definition and the fixed-up rule definition. - * @type {WeakMap} - */ -const fixedUpRuleReplacements = new WeakMap(); - -/** - * Tracks all of the fixed up rule definitions so we don't duplicate effort. - * @type {WeakSet} - */ -const fixedUpRules = new WeakSet(); - -/** - * Tracks the original plugin definition and the fixed-up plugin definition. - * @type {WeakMap} - */ -const fixedUpPluginReplacements = new WeakMap(); - -/** - * Tracks all of the fixed up plugin definitions so we don't duplicate effort. - * @type {WeakSet} - */ -const fixedUpPlugins = new WeakSet(); - -//----------------------------------------------------------------------------- -// Exports -//----------------------------------------------------------------------------- - -/** - * Takes the given rule and creates a new rule with the `create()` method wrapped - * to provide the missing methods on the `context` object. - * @param {FixupRuleDefinition|FixupLegacyRuleDefinition} ruleDefinition The rule to fix up. - * @returns {FixupRuleDefinition} The fixed-up rule. - */ -function fixupRule(ruleDefinition) { - // first check if we've already fixed up this rule - if (fixedUpRuleReplacements.has(ruleDefinition)) { - return fixedUpRuleReplacements.get(ruleDefinition); - } - - const isLegacyRule = typeof ruleDefinition === "function"; - - // check to see if this rule definition has already been fixed up - if (!isLegacyRule && fixedUpRules.has(ruleDefinition)) { - return ruleDefinition; - } - - const originalCreate = isLegacyRule - ? ruleDefinition - : ruleDefinition.create.bind(ruleDefinition); - - function ruleCreate(context) { - // if getScope is already there then no need to create old methods - if ("getScope" in context) { - return originalCreate(context); - } - - const sourceCode = context.sourceCode; - let currentNode = sourceCode.ast; - - const newContext = Object.assign(Object.create(context), { - parserServices: sourceCode.parserServices, - - /* - * The following methods rely on the current node in the traversal, - * so we need to add them manually. - */ - getScope() { - return sourceCode.getScope(currentNode); - }, - - getAncestors() { - return sourceCode.getAncestors(currentNode); - }, - - markVariableAsUsed(variable) { - sourceCode.markVariableAsUsed(variable, currentNode); - }, - }); - - // add passthrough methods - for (const [ - contextMethodName, - sourceCodeMethodName, - ] of removedMethodNames) { - newContext[contextMethodName] = - sourceCode[sourceCodeMethodName].bind(sourceCode); - } - - // freeze just like the original context - Object.freeze(newContext); - - /* - * Create the visitor object using the original create() method. - * This is necessary to ensure that the visitor object is created - * with the correct context. - */ - const visitor = originalCreate(newContext); - - /* - * Wrap each method in the visitor object to update the currentNode - * before calling the original method. This is necessary because the - * methods like `getScope()` need to know the current node. - */ - for (const [methodName, method] of Object.entries(visitor)) { - /* - * Node is the second argument to most code path methods, - * and the third argument for onCodePathSegmentLoop. - */ - if (methodName.startsWith("on")) { - // eslint-disable-next-line no-loop-func -- intentionally updating shared `currentNode` variable - visitor[methodName] = (...args) => { - currentNode = - args[methodName === "onCodePathSegmentLoop" ? 2 : 1]; - - return method.call(visitor, ...args); - }; - - continue; - } - - // eslint-disable-next-line no-loop-func -- intentionally updating shared `currentNode` variable - visitor[methodName] = (...args) => { - currentNode = args[0]; - - return method.call(visitor, ...args); - }; - } - - return visitor; - } - - const newRuleDefinition = { - ...(isLegacyRule ? undefined : ruleDefinition), - create: ruleCreate, - }; - - // copy `schema` property of function-style rule or top-level `schema` property of object-style rule into `meta` object - // @ts-ignore -- top-level `schema` property was not offically supported for object-style rules so it doesn't exist in types - const { schema } = ruleDefinition; - if (schema) { - if (!newRuleDefinition.meta) { - newRuleDefinition.meta = { schema }; - } else { - newRuleDefinition.meta = { - ...newRuleDefinition.meta, - // top-level `schema` had precedence over `meta.schema` so it's okay to overwrite `meta.schema` if it exists - schema, - }; - } - } - - // cache the fixed up rule - fixedUpRuleReplacements.set(ruleDefinition, newRuleDefinition); - fixedUpRules.add(newRuleDefinition); - - return newRuleDefinition; -} - -/** - * Takes the given plugin and creates a new plugin with all of the rules wrapped - * to provide the missing methods on the `context` object. - * @param {FixupPluginDefinition} plugin The plugin to fix up. - * @returns {FixupPluginDefinition} The fixed-up plugin. - */ -function fixupPluginRules(plugin) { - // first check if we've already fixed up this plugin - if (fixedUpPluginReplacements.has(plugin)) { - return fixedUpPluginReplacements.get(plugin); - } - - /* - * If the plugin has already been fixed up, or if the plugin - * doesn't have any rules, we can just return it. - */ - if (fixedUpPlugins.has(plugin) || !plugin.rules) { - return plugin; - } - - const newPlugin = { - ...plugin, - rules: Object.fromEntries( - Object.entries(plugin.rules).map(([ruleId, ruleDefinition]) => [ - ruleId, - fixupRule(ruleDefinition), - ]), - ), - }; - - // cache the fixed up plugin - fixedUpPluginReplacements.set(plugin, newPlugin); - fixedUpPlugins.add(newPlugin); - - return newPlugin; -} - -/** - * Takes the given configuration and creates a new configuration with all of the - * rules wrapped to provide the missing methods on the `context` object. - * @param {FixupConfigArray|FixupConfig} config The configuration to fix up. - * @returns {FixupConfigArray} The fixed-up configuration. - */ -function fixupConfigRules(config) { - const configs = Array.isArray(config) ? config : [config]; - - return configs.map(configItem => { - if (!configItem.plugins) { - return configItem; - } - - const newPlugins = Object.fromEntries( - Object.entries(configItem.plugins).map(([pluginName, plugin]) => [ - pluginName, - fixupPluginRules(plugin), - ]), - ); - - return { - ...configItem, - plugins: newPlugins, - }; - }); -} - -/** - * @fileoverview Ignore file utilities for the compat package. - * @author Nicholas C. Zakas - */ - - -//----------------------------------------------------------------------------- -// Types -//----------------------------------------------------------------------------- - -/** @typedef {import("eslint").Linter.Config} FlatConfig */ - -//----------------------------------------------------------------------------- -// Exports -//----------------------------------------------------------------------------- - -/** - * Converts an ESLint ignore pattern to a minimatch pattern. - * @param {string} pattern The .eslintignore or .gitignore pattern to convert. - * @returns {string} The converted pattern. - */ -function convertIgnorePatternToMinimatch(pattern) { - const isNegated = pattern.startsWith("!"); - const negatedPrefix = isNegated ? "!" : ""; - const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd(); - - // special cases - if (["", "**", "/**", "**/"].includes(patternToTest)) { - return `${negatedPrefix}${patternToTest}`; - } - - const firstIndexOfSlash = patternToTest.indexOf("/"); - - const matchEverywherePrefix = - firstIndexOfSlash < 0 || firstIndexOfSlash === patternToTest.length - 1 - ? "**/" - : ""; - - const patternWithoutLeadingSlash = - firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest; - - /* - * Escape `{` and `(` because in gitignore patterns they are just - * literal characters without any specific syntactic meaning, - * while in minimatch patterns they can form brace expansion or extglob syntax. - * - * For example, gitignore pattern `src/{a,b}.js` ignores file `src/{a,b}.js`. - * But, the same minimatch pattern `src/{a,b}.js` ignores files `src/a.js` and `src/b.js`. - * Minimatch pattern `src/\{a,b}.js` is equivalent to gitignore pattern `src/{a,b}.js`. - */ - const escapedPatternWithoutLeadingSlash = - patternWithoutLeadingSlash.replaceAll( - /(?=((?:\\.|[^{(])*))\1([{(])/guy, - "$1\\$2", - ); - - const matchInsideSuffix = patternToTest.endsWith("/**") ? "/*" : ""; - - return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`; -} - -/** - * Reads an ignore file and returns an object with the ignore patterns. - * @param {string} ignoreFilePath The absolute path to the ignore file. - * @returns {FlatConfig} An object with an `ignores` property that is an array of ignore patterns. - * @throws {Error} If the ignore file path is not an absolute path. - */ -function includeIgnoreFile(ignoreFilePath) { - if (!path.isAbsolute(ignoreFilePath)) { - throw new Error("The ignore file location must be an absolute path."); - } - - const ignoreFile = fs.readFileSync(ignoreFilePath, "utf8"); - const lines = ignoreFile.split(/\r?\n/u); - - return { - name: "Imported .gitignore patterns", - ignores: lines - .map(line => line.trim()) - .filter(line => line && !line.startsWith("#")) - .map(convertIgnorePatternToMinimatch), - }; -} - -export { convertIgnorePatternToMinimatch, fixupConfigRules, fixupPluginRules, fixupRule, includeIgnoreFile }; diff --git a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/package.json b/node_modules/eslint-plugin-github/node_modules/@eslint/compat/package.json deleted file mode 100644 index 31117e3462..0000000000 --- a/node_modules/eslint-plugin-github/node_modules/@eslint/compat/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "@eslint/compat", - "version": "1.2.3", - "description": "Compatibility utilities for ESLint", - "type": "module", - "main": "dist/esm/index.js", - "types": "dist/esm/index.d.ts", - "exports": { - "require": { - "types": "./dist/cjs/index.d.cts", - "default": "./dist/cjs/index.cjs" - }, - "import": { - "types": "./dist/esm/index.d.ts", - "default": "./dist/esm/index.js" - } - }, - "files": [ - "dist" - ], - "publishConfig": { - "access": "public" - }, - "directories": { - "test": "tests" - }, - "scripts": { - "build:cts": "node -e \"fs.copyFileSync('dist/esm/index.d.ts', 'dist/cjs/index.d.cts')\"", - "build": "rollup -c && tsc -p tsconfig.esm.json && npm run build:cts", - "test:jsr": "npx jsr@latest publish --dry-run", - "test": "mocha tests/*.js", - "test:coverage": "c8 npm test" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/eslint/rewrite.git" - }, - "keywords": [ - "eslint", - "compatibility", - "eslintplugin", - "eslint-plugin" - ], - "author": "Nicholas C. Zakas", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/eslint/rewrite/issues" - }, - "homepage": "https://github.com/eslint/rewrite#readme", - "devDependencies": { - "@eslint/core": "^0.9.0", - "c8": "^9.1.0", - "eslint": "^9.11.0", - "mocha": "^10.4.0", - "rollup": "^4.16.2", - "typescript": "^5.4.5" - }, - "peerDependencies": { - "eslint": "^9.10.0" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } -} diff --git a/node_modules/execa/index.d.ts b/node_modules/execa/index.d.ts index 576e7cffb9..a227299683 100644 --- a/node_modules/execa/index.d.ts +++ b/node_modules/execa/index.d.ts @@ -1,930 +1,27 @@ -import {type Buffer} from 'node:buffer'; -import {type ChildProcess} from 'node:child_process'; -import {type Stream, type Readable as ReadableStream, type Writable as WritableStream} from 'node:stream'; - -export type StdioOption = - | 'pipe' - | 'overlapped' - | 'ipc' - | 'ignore' - | 'inherit' - | Stream - | number - | undefined; - -export type CommonOptions = { - /** - Kill the spawned process when the parent process exits unless either: - - the spawned process is [`detached`](https://nodejs.org/api/child_process.html#child_process_options_detached) - - the parent process is terminated abruptly, for example, with `SIGKILL` as opposed to `SIGTERM` or a normal exit - - @default true - */ - readonly cleanup?: boolean; - - /** - Prefer locally installed binaries when looking for a binary to execute. - - If you `$ npm install foo`, you can then `execa('foo')`. - - @default `true` with `$`, `false` otherwise - */ - readonly preferLocal?: boolean; - - /** - Preferred path to find locally installed binaries in (use with `preferLocal`). - - @default process.cwd() - */ - readonly localDir?: string | URL; - - /** - Path to the Node.js executable to use in child processes. - - This can be either an absolute path or a path relative to the `cwd` option. - - Requires `preferLocal` to be `true`. - - For example, this can be used together with [`get-node`](https://github.com/ehmicky/get-node) to run a specific Node.js version in a child process. - - @default process.execPath - */ - readonly execPath?: string; - - /** - Buffer the output from the spawned process. When set to `false`, you must read the output of `stdout` and `stderr` (or `all` if the `all` option is `true`). Otherwise the returned promise will not be resolved/rejected. - - If the spawned process fails, `error.stdout`, `error.stderr`, and `error.all` will contain the buffered data. - - @default true - */ - readonly buffer?: boolean; - - /** - Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). - - @default `inherit` with `$`, `pipe` otherwise - */ - readonly stdin?: StdioOption; - - /** - Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). - - @default 'pipe' - */ - readonly stdout?: StdioOption; - - /** - Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). - - @default 'pipe' - */ - readonly stderr?: StdioOption; - - /** - Setting this to `false` resolves the promise with the error instead of rejecting it. - - @default true - */ - readonly reject?: boolean; - - /** - Add an `.all` property on the promise and the resolved value. The property contains the output of the process with `stdout` and `stderr` interleaved. - - @default false - */ - readonly all?: boolean; - - /** - Strip the final [newline character](https://en.wikipedia.org/wiki/Newline) from the output. - - @default true - */ - readonly stripFinalNewline?: boolean; - - /** - Set to `false` if you don't want to extend the environment variables when providing the `env` property. - - @default true - */ - readonly extendEnv?: boolean; - - /** - Current working directory of the child process. - - @default process.cwd() - */ - readonly cwd?: string | URL; - - /** - Environment key-value pairs. Extends automatically from `process.env`. Set `extendEnv` to `false` if you don't want this. - - @default process.env - */ - readonly env?: NodeJS.ProcessEnv; - - /** - Explicitly set the value of `argv[0]` sent to the child process. This will be set to `command` or `file` if not specified. - */ - readonly argv0?: string; - - /** - Child's [stdio](https://nodejs.org/api/child_process.html#child_process_options_stdio) configuration. - - @default 'pipe' - */ - readonly stdio?: 'pipe' | 'overlapped' | 'ignore' | 'inherit' | readonly StdioOption[]; - - /** - Specify the kind of serialization used for sending messages between processes when using the `stdio: 'ipc'` option or `execaNode()`: - - `json`: Uses `JSON.stringify()` and `JSON.parse()`. - - `advanced`: Uses [`v8.serialize()`](https://nodejs.org/api/v8.html#v8_v8_serialize_value) - - [More info.](https://nodejs.org/api/child_process.html#child_process_advanced_serialization) - - @default 'json' - */ - readonly serialization?: 'json' | 'advanced'; - - /** - Prepare child to run independently of its parent process. Specific behavior [depends on the platform](https://nodejs.org/api/child_process.html#child_process_options_detached). - - @default false - */ - readonly detached?: boolean; - - /** - Sets the user identity of the process. - */ - readonly uid?: number; - - /** - Sets the group identity of the process. - */ - readonly gid?: number; - - /** - If `true`, runs `command` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows. A different shell can be specified as a string. The shell should understand the `-c` switch on UNIX or `/d /s /c` on Windows. - - We recommend against using this option since it is: - - not cross-platform, encouraging shell-specific syntax. - - slower, because of the additional shell interpretation. - - unsafe, potentially allowing command injection. - - @default false - */ - readonly shell?: boolean | string; - - /** - Specify the character encoding used to decode the `stdout` and `stderr` output. If set to `null`, then `stdout` and `stderr` will be a `Buffer` instead of a string. - - @default 'utf8' - */ - readonly encoding?: EncodingType; - - /** - If `timeout` is greater than `0`, the parent will send the signal identified by the `killSignal` property (the default is `SIGTERM`) if the child runs longer than `timeout` milliseconds. - - @default 0 - */ - readonly timeout?: number; - - /** - Largest amount of data in bytes allowed on `stdout` or `stderr`. Default: 100 MB. - - @default 100_000_000 - */ - readonly maxBuffer?: number; - - /** - Signal value to be used when the spawned process will be killed. - - @default 'SIGTERM' - */ - readonly killSignal?: string | number; - - /** - You can abort the spawned process using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). - - When `AbortController.abort()` is called, [`.isCanceled`](https://github.com/sindresorhus/execa#iscanceled) becomes `false`. - - *Requires Node.js 16 or later.* - - @example - ``` - import {execa} from 'execa'; - - const abortController = new AbortController(); - const subprocess = execa('node', [], {signal: abortController.signal}); - - setTimeout(() => { - abortController.abort(); - }, 1000); - - try { - await subprocess; - } catch (error) { - console.log(subprocess.killed); // true - console.log(error.isCanceled); // true - } - ``` - */ - readonly signal?: AbortSignal; - - /** - If `true`, no quoting or escaping of arguments is done on Windows. Ignored on other platforms. This is set to `true` automatically when the `shell` option is `true`. - - @default false - */ - readonly windowsVerbatimArguments?: boolean; - - /** - On Windows, do not create a new console window. Please note this also prevents `CTRL-C` [from working](https://github.com/nodejs/node/issues/29837) on Windows. - - @default true - */ - readonly windowsHide?: boolean; - - /** - Print each command on `stderr` before executing it. - - This can also be enabled by setting the `NODE_DEBUG=execa` environment variable in the current process. - - @default false - */ - readonly verbose?: boolean; -}; - -export type Options = { - /** - Write some input to the `stdin` of your binary. - - If the input is a file, use the `inputFile` option instead. - */ - readonly input?: string | Buffer | ReadableStream; - - /** - Use a file as input to the the `stdin` of your binary. - - If the input is not a file, use the `input` option instead. - */ - readonly inputFile?: string; -} & CommonOptions; - -export type SyncOptions = { - /** - Write some input to the `stdin` of your binary. - - If the input is a file, use the `inputFile` option instead. - */ - readonly input?: string | Buffer; - - /** - Use a file as input to the the `stdin` of your binary. - - If the input is not a file, use the `input` option instead. - */ - readonly inputFile?: string; -} & CommonOptions; - -export type NodeOptions = { - /** - The Node.js executable to use. - - @default process.execPath - */ - readonly nodePath?: string; - - /** - List of [CLI options](https://nodejs.org/api/cli.html#cli_options) passed to the Node.js executable. - - @default process.execArgv - */ - readonly nodeOptions?: string[]; -} & Options; - -type StdoutStderrAll = string | Buffer | undefined; - -export type ExecaReturnBase = { - /** - The file and arguments that were run, for logging purposes. - - This is not escaped and should not be executed directly as a process, including using `execa()` or `execaCommand()`. - */ - command: string; - - /** - Same as `command` but escaped. - - This is meant to be copy and pasted into a shell, for debugging purposes. - Since the escaping is fairly basic, this should not be executed directly as a process, including using `execa()` or `execaCommand()`. - */ - escapedCommand: string; - - /** - The numeric exit code of the process that was run. - */ - exitCode: number; - - /** - The output of the process on stdout. - */ - stdout: StdoutStderrType; - - /** - The output of the process on stderr. - */ - stderr: StdoutStderrType; - - /** - Whether the process failed to run. - */ - failed: boolean; - - /** - Whether the process timed out. - */ - timedOut: boolean; - - /** - Whether the process was killed. - */ - killed: boolean; - - /** - The name of the signal that was used to terminate the process. For example, `SIGFPE`. - - If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`. - */ - signal?: string; - - /** - A human-friendly description of the signal that was used to terminate the process. For example, `Floating point arithmetic error`. - - If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`. It is also `undefined` when the signal is very uncommon which should seldomly happen. - */ - signalDescription?: string; -}; - -export type ExecaSyncReturnValue = { -} & ExecaReturnBase; - -/** -Result of a child process execution. On success this is a plain object. On failure this is also an `Error` instance. - -The child process fails when: -- its exit code is not `0` -- it was killed with a signal -- timing out -- being canceled -- there's not enough memory or there are already too many child processes -*/ -export type ExecaReturnValue = { - /** - The output of the process with `stdout` and `stderr` interleaved. - - This is `undefined` if either: - - the `all` option is `false` (default value) - - `execaSync()` was used - */ - all?: StdoutStderrType; - - /** - Whether the process was canceled. - - You can cancel the spawned process using the [`signal`](https://github.com/sindresorhus/execa#signal-1) option. - */ - isCanceled: boolean; -} & ExecaSyncReturnValue; - -export type ExecaSyncError = { - /** - Error message when the child process failed to run. In addition to the underlying error message, it also contains some information related to why the child process errored. - - The child process stderr then stdout are appended to the end, separated with newlines and not interleaved. - */ - message: string; - - /** - This is the same as the `message` property except it does not include the child process stdout/stderr. - */ - shortMessage: string; - - /** - Original error message. This is the same as the `message` property except it includes neither the child process stdout/stderr nor some additional information added by Execa. - - This is `undefined` unless the child process exited due to an `error` event or a timeout. - */ - originalMessage?: string; -} & Error & ExecaReturnBase; - -export type ExecaError = { - /** - The output of the process with `stdout` and `stderr` interleaved. - - This is `undefined` if either: - - the `all` option is `false` (default value) - - `execaSync()` was used - */ - all?: StdoutStderrType; - - /** - Whether the process was canceled. - */ - isCanceled: boolean; -} & ExecaSyncError; - -export type KillOptions = { - /** - Milliseconds to wait for the child process to terminate before sending `SIGKILL`. - - Can be disabled with `false`. - - @default 5000 - */ - forceKillAfterTimeout?: number | false; -}; - -export type ExecaChildPromise = { - /** - Stream combining/interleaving [`stdout`](https://nodejs.org/api/child_process.html#child_process_subprocess_stdout) and [`stderr`](https://nodejs.org/api/child_process.html#child_process_subprocess_stderr). - - This is `undefined` if either: - - the `all` option is `false` (the default value) - - both `stdout` and `stderr` options are set to [`'inherit'`, `'ipc'`, `Stream` or `integer`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio) - */ - all?: ReadableStream; - - catch( - onRejected?: (reason: ExecaError) => ResultType | PromiseLike - ): Promise | ResultType>; - - /** - Same as the original [`child_process#kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal), except if `signal` is `SIGTERM` (the default value) and the child process is not terminated after 5 seconds, force it by sending `SIGKILL`. - */ - kill(signal?: string, options?: KillOptions): void; - - /** - Similar to [`childProcess.kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal). This used to be preferred when cancelling the child process execution as the error is more descriptive and [`childProcessResult.isCanceled`](#iscanceled) is set to `true`. But now this is deprecated and you should either use `.kill()` or the `signal` option when creating the child process. - */ - cancel(): void; - - /** - [Pipe](https://nodejs.org/api/stream.html#readablepipedestination-options) the child process's `stdout` to `target`, which can be: - - Another `execa()` return value - - A writable stream - - A file path string - - If the `target` is another `execa()` return value, it is returned. Otherwise, the original `execa()` return value is returned. This allows chaining `pipeStdout()` then `await`ing the final result. - - The `stdout` option] must be kept as `pipe`, its default value. - */ - pipeStdout?>(target: Target): Target; - pipeStdout?(target: WritableStream | string): ExecaChildProcess; - - /** - Like `pipeStdout()` but piping the child process's `stderr` instead. - - The `stderr` option must be kept as `pipe`, its default value. - */ - pipeStderr?>(target: Target): Target; - pipeStderr?(target: WritableStream | string): ExecaChildProcess; - - /** - Combines both `pipeStdout()` and `pipeStderr()`. - - Either the `stdout` option or the `stderr` option must be kept as `pipe`, their default value. Also, the `all` option must be set to `true`. - */ - pipeAll?>(target: Target): Target; - pipeAll?(target: WritableStream | string): ExecaChildProcess; -}; - -export type ExecaChildProcess = ChildProcess & -ExecaChildPromise & -Promise>; - -/** -Executes a command using `file ...arguments`. `arguments` are specified as an array of strings. Returns a `childProcess`. - -Arguments are automatically escaped. They can contain any character, including spaces. - -This is the preferred method when executing single commands. - -@param file - The program/script to execute. -@param arguments - Arguments to pass to `file` on execution. -@returns An `ExecaChildProcess` that is both: - - a `Promise` resolving or rejecting with a `childProcessResult`. - - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties. -@throws A `childProcessResult` error - -@example Promise interface -``` -import {execa} from 'execa'; - -const {stdout} = await execa('echo', ['unicorns']); -console.log(stdout); -//=> 'unicorns' -``` - -@example Redirect output to a file -``` -import {execa} from 'execa'; - -// Similar to `echo unicorns > stdout.txt` in Bash -await execa('echo', ['unicorns']).pipeStdout('stdout.txt'); - -// Similar to `echo unicorns 2> stdout.txt` in Bash -await execa('echo', ['unicorns']).pipeStderr('stderr.txt'); - -// Similar to `echo unicorns &> stdout.txt` in Bash -await execa('echo', ['unicorns'], {all: true}).pipeAll('all.txt'); -``` - -@example Redirect input from a file -``` -import {execa} from 'execa'; - -// Similar to `cat < stdin.txt` in Bash -const {stdout} = await execa('cat', {inputFile: 'stdin.txt'}); -console.log(stdout); -//=> 'unicorns' -``` - -@example Save and pipe output from a child process -``` -import {execa} from 'execa'; - -const {stdout} = await execa('echo', ['unicorns']).pipeStdout(process.stdout); -// Prints `unicorns` -console.log(stdout); -// Also returns 'unicorns' -``` - -@example Pipe multiple processes -``` -import {execa} from 'execa'; - -// Similar to `echo unicorns | cat` in Bash -const {stdout} = await execa('echo', ['unicorns']).pipeStdout(execa('cat')); -console.log(stdout); -//=> 'unicorns' -``` - -@example Handling errors -``` -import {execa} from 'execa'; - -// Catching an error -try { - await execa('unknown', ['command']); -} catch (error) { - console.log(error); - /* - { - message: 'Command failed with ENOENT: unknown command spawn unknown ENOENT', - errno: -2, - code: 'ENOENT', - syscall: 'spawn unknown', - path: 'unknown', - spawnargs: ['command'], - originalMessage: 'spawn unknown ENOENT', - shortMessage: 'Command failed with ENOENT: unknown command spawn unknown ENOENT', - command: 'unknown command', - escapedCommand: 'unknown command', - stdout: '', - stderr: '', - failed: true, - timedOut: false, - isCanceled: false, - killed: false - } - \*\/ -} -``` - -@example Graceful termination -``` -const subprocess = execa('node'); - -setTimeout(() => { - subprocess.kill('SIGTERM', { - forceKillAfterTimeout: 2000 - }); -}, 1000); -``` -*/ -export function execa( - file: string, - arguments?: readonly string[], - options?: Options -): ExecaChildProcess; -export function execa( - file: string, - arguments?: readonly string[], - options?: Options -): ExecaChildProcess; -export function execa(file: string, options?: Options): ExecaChildProcess; -export function execa(file: string, options?: Options): ExecaChildProcess; - -/** -Same as `execa()` but synchronous. - -@param file - The program/script to execute. -@param arguments - Arguments to pass to `file` on execution. -@returns A `childProcessResult` object -@throws A `childProcessResult` error - -@example Promise interface -``` -import {execa} from 'execa'; - -const {stdout} = execaSync('echo', ['unicorns']); -console.log(stdout); -//=> 'unicorns' -``` - -@example Redirect input from a file -``` -import {execa} from 'execa'; - -// Similar to `cat < stdin.txt` in Bash -const {stdout} = execaSync('cat', {inputFile: 'stdin.txt'}); -console.log(stdout); -//=> 'unicorns' -``` - -@example Handling errors -``` -import {execa} from 'execa'; - -// Catching an error -try { - execaSync('unknown', ['command']); -} catch (error) { - console.log(error); - /* - { - message: 'Command failed with ENOENT: unknown command spawnSync unknown ENOENT', - errno: -2, - code: 'ENOENT', - syscall: 'spawnSync unknown', - path: 'unknown', - spawnargs: ['command'], - originalMessage: 'spawnSync unknown ENOENT', - shortMessage: 'Command failed with ENOENT: unknown command spawnSync unknown ENOENT', - command: 'unknown command', - escapedCommand: 'unknown command', - stdout: '', - stderr: '', - failed: true, - timedOut: false, - isCanceled: false, - killed: false - } - \*\/ -} -``` -*/ -export function execaSync( - file: string, - arguments?: readonly string[], - options?: SyncOptions -): ExecaSyncReturnValue; -export function execaSync( - file: string, - arguments?: readonly string[], - options?: SyncOptions -): ExecaSyncReturnValue; -export function execaSync(file: string, options?: SyncOptions): ExecaSyncReturnValue; -export function execaSync( - file: string, - options?: SyncOptions -): ExecaSyncReturnValue; - -/** -Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a `childProcess`. - -Arguments are automatically escaped. They can contain any character, but spaces must be escaped with a backslash like `execaCommand('echo has\\ space')`. - -This is the preferred method when executing a user-supplied `command` string, such as in a REPL. - -@param command - The program/script to execute and its arguments. -@returns An `ExecaChildProcess` that is both: - - a `Promise` resolving or rejecting with a `childProcessResult`. - - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties. -@throws A `childProcessResult` error - -@example -``` -import {execaCommand} from 'execa'; - -const {stdout} = await execaCommand('echo unicorns'); -console.log(stdout); -//=> 'unicorns' -``` -*/ -export function execaCommand(command: string, options?: Options): ExecaChildProcess; -export function execaCommand(command: string, options?: Options): ExecaChildProcess; - -/** -Same as `execaCommand()` but synchronous. - -@param command - The program/script to execute and its arguments. -@returns A `childProcessResult` object -@throws A `childProcessResult` error - -@example -``` -import {execaCommandSync} from 'execa'; - -const {stdout} = execaCommandSync('echo unicorns'); -console.log(stdout); -//=> 'unicorns' -``` -*/ -export function execaCommandSync(command: string, options?: SyncOptions): ExecaSyncReturnValue; -export function execaCommandSync(command: string, options?: SyncOptions): ExecaSyncReturnValue; - -type TemplateExpression = - | string - | number - | ExecaReturnValue - | ExecaSyncReturnValue - | Array | ExecaSyncReturnValue>; - -type Execa$ = { - /** - Returns a new instance of `$` but with different default `options`. Consecutive calls are merged to previous ones. - - This can be used to either: - - Set options for a specific command: `` $(options)`command` `` - - Share options for multiple commands: `` const $$ = $(options); $$`command`; $$`otherCommand` `` - - @param options - Options to set - @returns A new instance of `$` with those `options` set - - @example - ``` - import {$} from 'execa'; - - const $$ = $({stdio: 'inherit'}); - - await $$`echo unicorns`; - //=> 'unicorns' - - await $$`echo rainbows`; - //=> 'rainbows' - ``` - */ - (options: Options): Execa$; - (options: Options): Execa$; - (options: Options): Execa$; - ( - templates: TemplateStringsArray, - ...expressions: TemplateExpression[] - ): ExecaChildProcess; - - /** - Same as $\`command\` but synchronous. - - @returns A `childProcessResult` object - @throws A `childProcessResult` error - - @example Basic - ``` - import {$} from 'execa'; - - const branch = $.sync`git branch --show-current`; - $.sync`dep deploy --branch=${branch}`; - ``` - - @example Multiple arguments - ``` - import {$} from 'execa'; - - const args = ['unicorns', '&', 'rainbows!']; - const {stdout} = $.sync`echo ${args}`; - console.log(stdout); - //=> 'unicorns & rainbows!' - ``` - - @example With options - ``` - import {$} from 'execa'; - - $.sync({stdio: 'inherit'})`echo unicorns`; - //=> 'unicorns' - ``` - - @example Shared options - ``` - import {$} from 'execa'; - - const $$ = $({stdio: 'inherit'}); - - $$.sync`echo unicorns`; - //=> 'unicorns' - - $$.sync`echo rainbows`; - //=> 'rainbows' - ``` - */ - sync( - templates: TemplateStringsArray, - ...expressions: TemplateExpression[] - ): ExecaSyncReturnValue; -}; - -/** -Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a `childProcess`. - -Arguments are automatically escaped. They can contain any character, but spaces must use `${}` like `` $`echo ${'has space'}` ``. - -This is the preferred method when executing multiple commands in a script file. - -The `command` string can inject any `${value}` with the following types: string, number, `childProcess` or an array of those types. For example: `` $`echo one ${'two'} ${3} ${['four', 'five']}` ``. For `${childProcess}`, the process's `stdout` is used. - -@returns An `ExecaChildProcess` that is both: - - a `Promise` resolving or rejecting with a `childProcessResult`. - - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties. -@throws A `childProcessResult` error - -@example Basic -``` -import {$} from 'execa'; - -const branch = await $`git branch --show-current`; -await $`dep deploy --branch=${branch}`; -``` - -@example Multiple arguments -``` -import {$} from 'execa'; - -const args = ['unicorns', '&', 'rainbows!']; -const {stdout} = await $`echo ${args}`; -console.log(stdout); -//=> 'unicorns & rainbows!' -``` - -@example With options -``` -import {$} from 'execa'; - -await $({stdio: 'inherit'})`echo unicorns`; -//=> 'unicorns' -``` - -@example Shared options -``` -import {$} from 'execa'; - -const $$ = $({stdio: 'inherit'}); - -await $$`echo unicorns`; -//=> 'unicorns' - -await $$`echo rainbows`; -//=> 'rainbows' -``` -*/ -export const $: Execa$; - -/** -Execute a Node.js script as a child process. - -Arguments are automatically escaped. They can contain any character, including spaces. - -This is the preferred method when executing Node.js files. - -Like [`child_process#fork()`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options): - - the current Node version and options are used. This can be overridden using the `nodePath` and `nodeOptions` options. - - the `shell` option cannot be used - - an extra channel [`ipc`](https://nodejs.org/api/child_process.html#child_process_options_stdio) is passed to `stdio` - -@param scriptPath - Node.js script to execute. -@param arguments - Arguments to pass to `scriptPath` on execution. -@returns An `ExecaChildProcess` that is both: - - a `Promise` resolving or rejecting with a `childProcessResult`. - - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties. -@throws A `childProcessResult` error - -@example -``` -import {execa} from 'execa'; - -await execaNode('scriptPath', ['argument']); -``` -*/ -export function execaNode( - scriptPath: string, - arguments?: readonly string[], - options?: NodeOptions -): ExecaChildProcess; -export function execaNode( - scriptPath: string, - arguments?: readonly string[], - options?: NodeOptions -): ExecaChildProcess; -export function execaNode(scriptPath: string, options?: NodeOptions): ExecaChildProcess; -export function execaNode(scriptPath: string, options?: NodeOptions): ExecaChildProcess; +export type { + StdinOption, + StdinSyncOption, + StdoutStderrOption, + StdoutStderrSyncOption, +} from './types/stdio/type.js'; +export type {Options, SyncOptions} from './types/arguments/options.js'; +export type {TemplateExpression} from './types/methods/template.js'; + +export type {Result, SyncResult} from './types/return/result.js'; +export type {ResultPromise, Subprocess} from './types/subprocess/subprocess.js'; +export {ExecaError, ExecaSyncError} from './types/return/final-error.js'; + +export {execa, type ExecaMethod} from './types/methods/main-async.js'; +export {execaSync, type ExecaSyncMethod} from './types/methods/main-sync.js'; +export {execaCommand, execaCommandSync, parseCommandString} from './types/methods/command.js'; +export {$, type ExecaScriptMethod, type ExecaScriptSyncMethod} from './types/methods/script.js'; +export {execaNode, type ExecaNodeMethod} from './types/methods/node.js'; + +export { + sendMessage, + getOneMessage, + getEachMessage, + getCancelSignal, + type Message, +} from './types/ipc.js'; +export type {VerboseObject, SyncVerboseObject} from './types/verbose.js'; diff --git a/node_modules/execa/index.js b/node_modules/execa/index.js index fa417620f3..11285d9615 100644 --- a/node_modules/execa/index.js +++ b/node_modules/execa/index.js @@ -1,309 +1,28 @@ -import {Buffer} from 'node:buffer'; -import path from 'node:path'; -import childProcess from 'node:child_process'; -import process from 'node:process'; -import crossSpawn from 'cross-spawn'; -import stripFinalNewline from 'strip-final-newline'; -import {npmRunPathEnv} from 'npm-run-path'; -import onetime from 'onetime'; -import {makeError} from './lib/error.js'; -import {normalizeStdio, normalizeStdioNode} from './lib/stdio.js'; -import {spawnedKill, spawnedCancel, setupTimeout, validateTimeout, setExitHandler} from './lib/kill.js'; -import {addPipeMethods} from './lib/pipe.js'; -import {handleInput, getSpawnedResult, makeAllStream, handleInputSync} from './lib/stream.js'; -import {mergePromise, getSpawnedPromise} from './lib/promise.js'; -import {joinCommand, parseCommand, parseTemplates, getEscapedCommand} from './lib/command.js'; -import {logCommand, verboseDefault} from './lib/verbose.js'; - -const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; - -const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { - const env = extendEnv ? {...process.env, ...envOption} : envOption; - - if (preferLocal) { - return npmRunPathEnv({env, cwd: localDir, execPath}); - } - - return env; -}; - -const handleArguments = (file, args, options = {}) => { - const parsed = crossSpawn._parse(file, args, options); - file = parsed.command; - args = parsed.args; - options = parsed.options; - - options = { - maxBuffer: DEFAULT_MAX_BUFFER, - buffer: true, - stripFinalNewline: true, - extendEnv: true, - preferLocal: false, - localDir: options.cwd || process.cwd(), - execPath: process.execPath, - encoding: 'utf8', - reject: true, - cleanup: true, - all: false, - windowsHide: true, - verbose: verboseDefault, - ...options, - }; - - options.env = getEnv(options); - - options.stdio = normalizeStdio(options); - - if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { - // #116 - args.unshift('/q'); - } - - return {file, args, options, parsed}; -}; - -const handleOutput = (options, value, error) => { - if (typeof value !== 'string' && !Buffer.isBuffer(value)) { - // When `execaSync()` errors, we normalize it to '' to mimic `execa()` - return error === undefined ? undefined : ''; - } - - if (options.stripFinalNewline) { - return stripFinalNewline(value); - } - - return value; +import {createExeca} from './lib/methods/create.js'; +import {mapCommandAsync, mapCommandSync} from './lib/methods/command.js'; +import {mapNode} from './lib/methods/node.js'; +import {mapScriptAsync, setScriptSync, deepScriptOptions} from './lib/methods/script.js'; +import {getIpcExport} from './lib/ipc/methods.js'; + +export {parseCommandString} from './lib/methods/command.js'; +export {ExecaError, ExecaSyncError} from './lib/return/final-error.js'; + +export const execa = createExeca(() => ({})); +export const execaSync = createExeca(() => ({isSync: true})); +export const execaCommand = createExeca(mapCommandAsync); +export const execaCommandSync = createExeca(mapCommandSync); +export const execaNode = createExeca(mapNode); +export const $ = createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync); + +const { + sendMessage, + getOneMessage, + getEachMessage, + getCancelSignal, +} = getIpcExport(); +export { + sendMessage, + getOneMessage, + getEachMessage, + getCancelSignal, }; - -export function execa(file, args, options) { - const parsed = handleArguments(file, args, options); - const command = joinCommand(file, args); - const escapedCommand = getEscapedCommand(file, args); - logCommand(escapedCommand, parsed.options); - - validateTimeout(parsed.options); - - let spawned; - try { - spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options); - } catch (error) { - // Ensure the returned error is always both a promise and a child process - const dummySpawned = new childProcess.ChildProcess(); - const errorPromise = Promise.reject(makeError({ - error, - stdout: '', - stderr: '', - all: '', - command, - escapedCommand, - parsed, - timedOut: false, - isCanceled: false, - killed: false, - })); - mergePromise(dummySpawned, errorPromise); - return dummySpawned; - } - - const spawnedPromise = getSpawnedPromise(spawned); - const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); - const processDone = setExitHandler(spawned, parsed.options, timedPromise); - - const context = {isCanceled: false}; - - spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); - spawned.cancel = spawnedCancel.bind(null, spawned, context); - - const handlePromise = async () => { - const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone); - const stdout = handleOutput(parsed.options, stdoutResult); - const stderr = handleOutput(parsed.options, stderrResult); - const all = handleOutput(parsed.options, allResult); - - if (error || exitCode !== 0 || signal !== null) { - const returnedError = makeError({ - error, - exitCode, - signal, - stdout, - stderr, - all, - command, - escapedCommand, - parsed, - timedOut, - isCanceled: context.isCanceled || (parsed.options.signal ? parsed.options.signal.aborted : false), - killed: spawned.killed, - }); - - if (!parsed.options.reject) { - return returnedError; - } - - throw returnedError; - } - - return { - command, - escapedCommand, - exitCode: 0, - stdout, - stderr, - all, - failed: false, - timedOut: false, - isCanceled: false, - killed: false, - }; - }; - - const handlePromiseOnce = onetime(handlePromise); - - handleInput(spawned, parsed.options); - - spawned.all = makeAllStream(spawned, parsed.options); - - addPipeMethods(spawned); - mergePromise(spawned, handlePromiseOnce); - return spawned; -} - -export function execaSync(file, args, options) { - const parsed = handleArguments(file, args, options); - const command = joinCommand(file, args); - const escapedCommand = getEscapedCommand(file, args); - logCommand(escapedCommand, parsed.options); - - const input = handleInputSync(parsed.options); - - let result; - try { - result = childProcess.spawnSync(parsed.file, parsed.args, {...parsed.options, input}); - } catch (error) { - throw makeError({ - error, - stdout: '', - stderr: '', - all: '', - command, - escapedCommand, - parsed, - timedOut: false, - isCanceled: false, - killed: false, - }); - } - - const stdout = handleOutput(parsed.options, result.stdout, result.error); - const stderr = handleOutput(parsed.options, result.stderr, result.error); - - if (result.error || result.status !== 0 || result.signal !== null) { - const error = makeError({ - stdout, - stderr, - error: result.error, - signal: result.signal, - exitCode: result.status, - command, - escapedCommand, - parsed, - timedOut: result.error && result.error.code === 'ETIMEDOUT', - isCanceled: false, - killed: result.signal !== null, - }); - - if (!parsed.options.reject) { - return error; - } - - throw error; - } - - return { - command, - escapedCommand, - exitCode: 0, - stdout, - stderr, - failed: false, - timedOut: false, - isCanceled: false, - killed: false, - }; -} - -const normalizeScriptStdin = ({input, inputFile, stdio}) => input === undefined && inputFile === undefined && stdio === undefined - ? {stdin: 'inherit'} - : {}; - -const normalizeScriptOptions = (options = {}) => ({ - preferLocal: true, - ...normalizeScriptStdin(options), - ...options, -}); - -function create$(options) { - function $(templatesOrOptions, ...expressions) { - if (!Array.isArray(templatesOrOptions)) { - return create$({...options, ...templatesOrOptions}); - } - - const [file, ...args] = parseTemplates(templatesOrOptions, expressions); - return execa(file, args, normalizeScriptOptions(options)); - } - - $.sync = (templates, ...expressions) => { - if (!Array.isArray(templates)) { - throw new TypeError('Please use $(options).sync`command` instead of $.sync(options)`command`.'); - } - - const [file, ...args] = parseTemplates(templates, expressions); - return execaSync(file, args, normalizeScriptOptions(options)); - }; - - return $; -} - -export const $ = create$(); - -export function execaCommand(command, options) { - const [file, ...args] = parseCommand(command); - return execa(file, args, options); -} - -export function execaCommandSync(command, options) { - const [file, ...args] = parseCommand(command); - return execaSync(file, args, options); -} - -export function execaNode(scriptPath, args, options = {}) { - if (args && !Array.isArray(args) && typeof args === 'object') { - options = args; - args = []; - } - - const stdio = normalizeStdioNode(options); - const defaultExecArgv = process.execArgv.filter(arg => !arg.startsWith('--inspect')); - - const { - nodePath = process.execPath, - nodeOptions = defaultExecArgv, - } = options; - - return execa( - nodePath, - [ - ...nodeOptions, - scriptPath, - ...(Array.isArray(args) ? args : []), - ], - { - ...options, - stdin: undefined, - stdout: undefined, - stderr: undefined, - stdio, - shell: false, - }, - ); -} diff --git a/node_modules/execa/lib/arguments/command.js b/node_modules/execa/lib/arguments/command.js new file mode 100644 index 0000000000..d1f8e3602b --- /dev/null +++ b/node_modules/execa/lib/arguments/command.js @@ -0,0 +1,20 @@ +import {logCommand} from '../verbose/start.js'; +import {getVerboseInfo} from '../verbose/info.js'; +import {getStartTime} from '../return/duration.js'; +import {joinCommand} from './escape.js'; +import {normalizeFdSpecificOption} from './specific.js'; + +// Compute `result.command`, `result.escapedCommand` and `verbose`-related information +export const handleCommand = (filePath, rawArguments, rawOptions) => { + const startTime = getStartTime(); + const {command, escapedCommand} = joinCommand(filePath, rawArguments); + const verbose = normalizeFdSpecificOption(rawOptions, 'verbose'); + const verboseInfo = getVerboseInfo(verbose, escapedCommand, {...rawOptions}); + logCommand(escapedCommand, verboseInfo); + return { + command, + escapedCommand, + startTime, + verboseInfo, + }; +}; diff --git a/node_modules/execa/lib/arguments/cwd.js b/node_modules/execa/lib/arguments/cwd.js new file mode 100644 index 0000000000..6373eed2e2 --- /dev/null +++ b/node_modules/execa/lib/arguments/cwd.js @@ -0,0 +1,39 @@ +import {statSync} from 'node:fs'; +import path from 'node:path'; +import process from 'node:process'; +import {safeNormalizeFileUrl} from './file-url.js'; + +// Normalize `cwd` option +export const normalizeCwd = (cwd = getDefaultCwd()) => { + const cwdString = safeNormalizeFileUrl(cwd, 'The "cwd" option'); + return path.resolve(cwdString); +}; + +const getDefaultCwd = () => { + try { + return process.cwd(); + } catch (error) { + error.message = `The current directory does not exist.\n${error.message}`; + throw error; + } +}; + +// When `cwd` option has an invalid value, provide with a better error message +export const fixCwdError = (originalMessage, cwd) => { + if (cwd === getDefaultCwd()) { + return originalMessage; + } + + let cwdStat; + try { + cwdStat = statSync(cwd); + } catch (error) { + return `The "cwd" option is invalid: ${cwd}.\n${error.message}\n${originalMessage}`; + } + + if (!cwdStat.isDirectory()) { + return `The "cwd" option is not a directory: ${cwd}.\n${originalMessage}`; + } + + return originalMessage; +}; diff --git a/node_modules/execa/lib/arguments/encoding-option.js b/node_modules/execa/lib/arguments/encoding-option.js new file mode 100644 index 0000000000..c3ec6b8c0d --- /dev/null +++ b/node_modules/execa/lib/arguments/encoding-option.js @@ -0,0 +1,50 @@ +// Validate `encoding` option +export const validateEncoding = ({encoding}) => { + if (ENCODINGS.has(encoding)) { + return; + } + + const correctEncoding = getCorrectEncoding(encoding); + if (correctEncoding !== undefined) { + throw new TypeError(`Invalid option \`encoding: ${serializeEncoding(encoding)}\`. +Please rename it to ${serializeEncoding(correctEncoding)}.`); + } + + const correctEncodings = [...ENCODINGS].map(correctEncoding => serializeEncoding(correctEncoding)).join(', '); + throw new TypeError(`Invalid option \`encoding: ${serializeEncoding(encoding)}\`. +Please rename it to one of: ${correctEncodings}.`); +}; + +const TEXT_ENCODINGS = new Set(['utf8', 'utf16le']); +export const BINARY_ENCODINGS = new Set(['buffer', 'hex', 'base64', 'base64url', 'latin1', 'ascii']); +const ENCODINGS = new Set([...TEXT_ENCODINGS, ...BINARY_ENCODINGS]); + +const getCorrectEncoding = encoding => { + if (encoding === null) { + return 'buffer'; + } + + if (typeof encoding !== 'string') { + return; + } + + const lowerEncoding = encoding.toLowerCase(); + if (lowerEncoding in ENCODING_ALIASES) { + return ENCODING_ALIASES[lowerEncoding]; + } + + if (ENCODINGS.has(lowerEncoding)) { + return lowerEncoding; + } +}; + +const ENCODING_ALIASES = { + // eslint-disable-next-line unicorn/text-encoding-identifier-case + 'utf-8': 'utf8', + 'utf-16le': 'utf16le', + 'ucs-2': 'utf16le', + ucs2: 'utf16le', + binary: 'latin1', +}; + +const serializeEncoding = encoding => typeof encoding === 'string' ? `"${encoding}"` : String(encoding); diff --git a/node_modules/execa/lib/arguments/escape.js b/node_modules/execa/lib/arguments/escape.js new file mode 100644 index 0000000000..48ae3c244f --- /dev/null +++ b/node_modules/execa/lib/arguments/escape.js @@ -0,0 +1,88 @@ +import {platform} from 'node:process'; +import {stripVTControlCharacters} from 'node:util'; + +// Compute `result.command` and `result.escapedCommand` +export const joinCommand = (filePath, rawArguments) => { + const fileAndArguments = [filePath, ...rawArguments]; + const command = fileAndArguments.join(' '); + const escapedCommand = fileAndArguments + .map(fileAndArgument => quoteString(escapeControlCharacters(fileAndArgument))) + .join(' '); + return {command, escapedCommand}; +}; + +// Remove ANSI sequences and escape control characters and newlines +export const escapeLines = lines => stripVTControlCharacters(lines) + .split('\n') + .map(line => escapeControlCharacters(line)) + .join('\n'); + +const escapeControlCharacters = line => line.replaceAll(SPECIAL_CHAR_REGEXP, character => escapeControlCharacter(character)); + +const escapeControlCharacter = character => { + const commonEscape = COMMON_ESCAPES[character]; + if (commonEscape !== undefined) { + return commonEscape; + } + + const codepoint = character.codePointAt(0); + const codepointHex = codepoint.toString(16); + return codepoint <= ASTRAL_START + ? `\\u${codepointHex.padStart(4, '0')}` + : `\\U${codepointHex}`; +}; + +// Characters that would create issues when printed are escaped using the \u or \U notation. +// Those include control characters and newlines. +// The \u and \U notation is Bash specific, but there is no way to do this in a shell-agnostic way. +// Some shells do not even have a way to print those characters in an escaped fashion. +// Therefore, we prioritize printing those safely, instead of allowing those to be copy-pasted. +// List of Unicode character categories: https://www.fileformat.info/info/unicode/category/index.htm +const getSpecialCharRegExp = () => { + try { + // This throws when using Node.js without ICU support. + // When using a RegExp literal, this would throw at parsing-time, instead of runtime. + // eslint-disable-next-line prefer-regex-literals + return new RegExp('\\p{Separator}|\\p{Other}', 'gu'); + } catch { + // Similar to the above RegExp, but works even when Node.js has been built without ICU support. + // Unlike the above RegExp, it only covers whitespaces and C0/C1 control characters. + // It does not cover some edge cases, such as Unicode reserved characters. + // See https://github.com/sindresorhus/execa/issues/1143 + // eslint-disable-next-line no-control-regex + return /[\s\u0000-\u001F\u007F-\u009F\u00AD]/g; + } +}; + +const SPECIAL_CHAR_REGEXP = getSpecialCharRegExp(); + +// Accepted by $'...' in Bash. +// Exclude \a \e \v which are accepted in Bash but not in JavaScript (except \v) and JSON. +const COMMON_ESCAPES = { + ' ': ' ', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', +}; + +// Up until that codepoint, \u notation can be used instead of \U +const ASTRAL_START = 65_535; + +// Some characters are shell-specific, i.e. need to be escaped when the command is copy-pasted then run. +// Escaping is shell-specific. We cannot know which shell is used: `process.platform` detection is not enough. +// For example, Windows users could be using `cmd.exe`, Powershell or Bash for Windows which all use different escaping. +// We use '...' on Unix, which is POSIX shell compliant and escape all characters but ' so this is fairly safe. +// On Windows, we assume cmd.exe is used and escape with "...", which also works with Powershell. +const quoteString = escapedArgument => { + if (NO_ESCAPE_REGEXP.test(escapedArgument)) { + return escapedArgument; + } + + return platform === 'win32' + ? `"${escapedArgument.replaceAll('"', '""')}"` + : `'${escapedArgument.replaceAll('\'', '\'\\\'\'')}'`; +}; + +const NO_ESCAPE_REGEXP = /^[\w./-]+$/; diff --git a/node_modules/execa/lib/arguments/fd-options.js b/node_modules/execa/lib/arguments/fd-options.js new file mode 100644 index 0000000000..cd0e49d7fa --- /dev/null +++ b/node_modules/execa/lib/arguments/fd-options.js @@ -0,0 +1,108 @@ +import {parseFd} from './specific.js'; + +// Retrieve stream targeted by the `to` option +export const getToStream = (destination, to = 'stdin') => { + const isWritable = true; + const {options, fileDescriptors} = SUBPROCESS_OPTIONS.get(destination); + const fdNumber = getFdNumber(fileDescriptors, to, isWritable); + const destinationStream = destination.stdio[fdNumber]; + + if (destinationStream === null) { + throw new TypeError(getInvalidStdioOptionMessage(fdNumber, to, options, isWritable)); + } + + return destinationStream; +}; + +// Retrieve stream targeted by the `from` option +export const getFromStream = (source, from = 'stdout') => { + const isWritable = false; + const {options, fileDescriptors} = SUBPROCESS_OPTIONS.get(source); + const fdNumber = getFdNumber(fileDescriptors, from, isWritable); + const sourceStream = fdNumber === 'all' ? source.all : source.stdio[fdNumber]; + + if (sourceStream === null || sourceStream === undefined) { + throw new TypeError(getInvalidStdioOptionMessage(fdNumber, from, options, isWritable)); + } + + return sourceStream; +}; + +// Keeps track of the options passed to each Execa call +export const SUBPROCESS_OPTIONS = new WeakMap(); + +const getFdNumber = (fileDescriptors, fdName, isWritable) => { + const fdNumber = parseFdNumber(fdName, isWritable); + validateFdNumber(fdNumber, fdName, isWritable, fileDescriptors); + return fdNumber; +}; + +const parseFdNumber = (fdName, isWritable) => { + const fdNumber = parseFd(fdName); + if (fdNumber !== undefined) { + return fdNumber; + } + + const {validOptions, defaultValue} = isWritable + ? {validOptions: '"stdin"', defaultValue: 'stdin'} + : {validOptions: '"stdout", "stderr", "all"', defaultValue: 'stdout'}; + throw new TypeError(`"${getOptionName(isWritable)}" must not be "${fdName}". +It must be ${validOptions} or "fd3", "fd4" (and so on). +It is optional and defaults to "${defaultValue}".`); +}; + +const validateFdNumber = (fdNumber, fdName, isWritable, fileDescriptors) => { + const fileDescriptor = fileDescriptors[getUsedDescriptor(fdNumber)]; + if (fileDescriptor === undefined) { + throw new TypeError(`"${getOptionName(isWritable)}" must not be ${fdName}. That file descriptor does not exist. +Please set the "stdio" option to ensure that file descriptor exists.`); + } + + if (fileDescriptor.direction === 'input' && !isWritable) { + throw new TypeError(`"${getOptionName(isWritable)}" must not be ${fdName}. It must be a readable stream, not writable.`); + } + + if (fileDescriptor.direction !== 'input' && isWritable) { + throw new TypeError(`"${getOptionName(isWritable)}" must not be ${fdName}. It must be a writable stream, not readable.`); + } +}; + +const getInvalidStdioOptionMessage = (fdNumber, fdName, options, isWritable) => { + if (fdNumber === 'all' && !options.all) { + return 'The "all" option must be true to use "from: \'all\'".'; + } + + const {optionName, optionValue} = getInvalidStdioOption(fdNumber, options); + return `The "${optionName}: ${serializeOptionValue(optionValue)}" option is incompatible with using "${getOptionName(isWritable)}: ${serializeOptionValue(fdName)}". +Please set this option with "pipe" instead.`; +}; + +const getInvalidStdioOption = (fdNumber, {stdin, stdout, stderr, stdio}) => { + const usedDescriptor = getUsedDescriptor(fdNumber); + + if (usedDescriptor === 0 && stdin !== undefined) { + return {optionName: 'stdin', optionValue: stdin}; + } + + if (usedDescriptor === 1 && stdout !== undefined) { + return {optionName: 'stdout', optionValue: stdout}; + } + + if (usedDescriptor === 2 && stderr !== undefined) { + return {optionName: 'stderr', optionValue: stderr}; + } + + return {optionName: `stdio[${usedDescriptor}]`, optionValue: stdio[usedDescriptor]}; +}; + +const getUsedDescriptor = fdNumber => fdNumber === 'all' ? 1 : fdNumber; + +const getOptionName = isWritable => isWritable ? 'to' : 'from'; + +export const serializeOptionValue = value => { + if (typeof value === 'string') { + return `'${value}'`; + } + + return typeof value === 'number' ? `${value}` : 'Stream'; +}; diff --git a/node_modules/execa/lib/arguments/file-url.js b/node_modules/execa/lib/arguments/file-url.js new file mode 100644 index 0000000000..448f703717 --- /dev/null +++ b/node_modules/execa/lib/arguments/file-url.js @@ -0,0 +1,25 @@ +import {fileURLToPath} from 'node:url'; + +// Allow some arguments/options to be either a file path string or a file URL +export const safeNormalizeFileUrl = (file, name) => { + const fileString = normalizeFileUrl(normalizeDenoExecPath(file)); + + if (typeof fileString !== 'string') { + throw new TypeError(`${name} must be a string or a file URL: ${fileString}.`); + } + + return fileString; +}; + +// In Deno node:process execPath is a special object, not just a string: +// https://github.com/denoland/deno/blob/f460188e583f00144000aa0d8ade08218d47c3c1/ext/node/polyfills/process.ts#L344 +const normalizeDenoExecPath = file => isDenoExecPath(file) + ? file.toString() + : file; + +export const isDenoExecPath = file => typeof file !== 'string' + && file + && Object.getPrototypeOf(file) === String.prototype; + +// Same but also allows other values, e.g. `boolean` for the `shell` option +export const normalizeFileUrl = file => file instanceof URL ? fileURLToPath(file) : file; diff --git a/node_modules/execa/lib/arguments/options.js b/node_modules/execa/lib/arguments/options.js new file mode 100644 index 0000000000..5f591026a1 --- /dev/null +++ b/node_modules/execa/lib/arguments/options.js @@ -0,0 +1,96 @@ +import path from 'node:path'; +import process from 'node:process'; +import crossSpawn from 'cross-spawn'; +import {npmRunPathEnv} from 'npm-run-path'; +import {normalizeForceKillAfterDelay} from '../terminate/kill.js'; +import {normalizeKillSignal} from '../terminate/signal.js'; +import {validateCancelSignal} from '../terminate/cancel.js'; +import {validateGracefulCancel} from '../terminate/graceful.js'; +import {validateTimeout} from '../terminate/timeout.js'; +import {handleNodeOption} from '../methods/node.js'; +import {validateIpcInputOption} from '../ipc/ipc-input.js'; +import {validateEncoding, BINARY_ENCODINGS} from './encoding-option.js'; +import {normalizeCwd} from './cwd.js'; +import {normalizeFileUrl} from './file-url.js'; +import {normalizeFdSpecificOptions} from './specific.js'; + +// Normalize the options object, and sometimes also the file paths and arguments. +// Applies default values, validate allowed options, normalize them. +export const normalizeOptions = (filePath, rawArguments, rawOptions) => { + rawOptions.cwd = normalizeCwd(rawOptions.cwd); + const [processedFile, processedArguments, processedOptions] = handleNodeOption(filePath, rawArguments, rawOptions); + + const {command: file, args: commandArguments, options: initialOptions} = crossSpawn._parse(processedFile, processedArguments, processedOptions); + + const fdOptions = normalizeFdSpecificOptions(initialOptions); + const options = addDefaultOptions(fdOptions); + validateTimeout(options); + validateEncoding(options); + validateIpcInputOption(options); + validateCancelSignal(options); + validateGracefulCancel(options); + options.shell = normalizeFileUrl(options.shell); + options.env = getEnv(options); + options.killSignal = normalizeKillSignal(options.killSignal); + options.forceKillAfterDelay = normalizeForceKillAfterDelay(options.forceKillAfterDelay); + options.lines = options.lines.map((lines, fdNumber) => lines && !BINARY_ENCODINGS.has(options.encoding) && options.buffer[fdNumber]); + + if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { + // #116 + commandArguments.unshift('/q'); + } + + return {file, commandArguments, options}; +}; + +const addDefaultOptions = ({ + extendEnv = true, + preferLocal = false, + cwd, + localDir: localDirectory = cwd, + encoding = 'utf8', + reject = true, + cleanup = true, + all = false, + windowsHide = true, + killSignal = 'SIGTERM', + forceKillAfterDelay = true, + gracefulCancel = false, + ipcInput, + ipc = ipcInput !== undefined || gracefulCancel, + serialization = 'advanced', + ...options +}) => ({ + ...options, + extendEnv, + preferLocal, + cwd, + localDirectory, + encoding, + reject, + cleanup, + all, + windowsHide, + killSignal, + forceKillAfterDelay, + gracefulCancel, + ipcInput, + ipc, + serialization, +}); + +const getEnv = ({env: envOption, extendEnv, preferLocal, node, localDirectory, nodePath}) => { + const env = extendEnv ? {...process.env, ...envOption} : envOption; + + if (preferLocal || node) { + return npmRunPathEnv({ + env, + cwd: localDirectory, + execPath: nodePath, + preferLocal, + addExecPath: node, + }); + } + + return env; +}; diff --git a/node_modules/execa/lib/arguments/shell.js b/node_modules/execa/lib/arguments/shell.js new file mode 100644 index 0000000000..af99861570 --- /dev/null +++ b/node_modules/execa/lib/arguments/shell.js @@ -0,0 +1,11 @@ +// When the `shell` option is set, any command argument is concatenated as a single string by Node.js: +// https://github.com/nodejs/node/blob/e38ce27f3ca0a65f68a31cedd984cddb927d4002/lib/child_process.js#L614-L624 +// However, since Node 24, it also prints a deprecation warning. +// To avoid this warning, we perform that same operation before calling `node:child_process`. +// Shells only understand strings, which is why Node.js performs that concatenation. +// However, we rely on users splitting command arguments as an array. +// For example, this allows us to easily detect which arguments are passed. +// So we do want users to pass array of arguments even with `shell: true`, but we also want to avoid any warning. +export const concatenateShell = (file, commandArguments, options) => options.shell && commandArguments.length > 0 + ? [[file, ...commandArguments].join(' '), [], options] + : [file, commandArguments, options]; diff --git a/node_modules/execa/lib/arguments/specific.js b/node_modules/execa/lib/arguments/specific.js new file mode 100644 index 0000000000..1238c0df50 --- /dev/null +++ b/node_modules/execa/lib/arguments/specific.js @@ -0,0 +1,111 @@ +import {debuglog} from 'node:util'; +import isPlainObject from 'is-plain-obj'; +import {STANDARD_STREAMS_ALIASES} from '../utils/standard-stream.js'; + +// Some options can have different values for `stdout`/`stderr`/`fd3`. +// This normalizes those to array of values. +// For example, `{verbose: {stdout: 'none', stderr: 'full'}}` becomes `{verbose: ['none', 'none', 'full']}` +export const normalizeFdSpecificOptions = options => { + const optionsCopy = {...options}; + + for (const optionName of FD_SPECIFIC_OPTIONS) { + optionsCopy[optionName] = normalizeFdSpecificOption(options, optionName); + } + + return optionsCopy; +}; + +export const normalizeFdSpecificOption = (options, optionName) => { + const optionBaseArray = Array.from({length: getStdioLength(options) + 1}); + const optionArray = normalizeFdSpecificValue(options[optionName], optionBaseArray, optionName); + return addDefaultValue(optionArray, optionName); +}; + +const getStdioLength = ({stdio}) => Array.isArray(stdio) + ? Math.max(stdio.length, STANDARD_STREAMS_ALIASES.length) + : STANDARD_STREAMS_ALIASES.length; + +const normalizeFdSpecificValue = (optionValue, optionArray, optionName) => isPlainObject(optionValue) + ? normalizeOptionObject(optionValue, optionArray, optionName) + : optionArray.fill(optionValue); + +const normalizeOptionObject = (optionValue, optionArray, optionName) => { + for (const fdName of Object.keys(optionValue).sort(compareFdName)) { + for (const fdNumber of parseFdName(fdName, optionName, optionArray)) { + optionArray[fdNumber] = optionValue[fdName]; + } + } + + return optionArray; +}; + +// Ensure priority order when setting both `stdout`/`stderr`, `fd1`/`fd2`, and `all` +const compareFdName = (fdNameA, fdNameB) => getFdNameOrder(fdNameA) < getFdNameOrder(fdNameB) ? 1 : -1; + +const getFdNameOrder = fdName => { + if (fdName === 'stdout' || fdName === 'stderr') { + return 0; + } + + return fdName === 'all' ? 2 : 1; +}; + +const parseFdName = (fdName, optionName, optionArray) => { + if (fdName === 'ipc') { + return [optionArray.length - 1]; + } + + const fdNumber = parseFd(fdName); + if (fdNumber === undefined || fdNumber === 0) { + throw new TypeError(`"${optionName}.${fdName}" is invalid. +It must be "${optionName}.stdout", "${optionName}.stderr", "${optionName}.all", "${optionName}.ipc", or "${optionName}.fd3", "${optionName}.fd4" (and so on).`); + } + + if (fdNumber >= optionArray.length) { + throw new TypeError(`"${optionName}.${fdName}" is invalid: that file descriptor does not exist. +Please set the "stdio" option to ensure that file descriptor exists.`); + } + + return fdNumber === 'all' ? [1, 2] : [fdNumber]; +}; + +// Use the same syntax for fd-specific options and the `from`/`to` options +export const parseFd = fdName => { + if (fdName === 'all') { + return fdName; + } + + if (STANDARD_STREAMS_ALIASES.includes(fdName)) { + return STANDARD_STREAMS_ALIASES.indexOf(fdName); + } + + const regexpResult = FD_REGEXP.exec(fdName); + if (regexpResult !== null) { + return Number(regexpResult[1]); + } +}; + +const FD_REGEXP = /^fd(\d+)$/; + +const addDefaultValue = (optionArray, optionName) => optionArray.map(optionValue => optionValue === undefined + ? DEFAULT_OPTIONS[optionName] + : optionValue); + +// Default value for the `verbose` option +const verboseDefault = debuglog('execa').enabled ? 'full' : 'none'; + +const DEFAULT_OPTIONS = { + lines: false, + buffer: true, + maxBuffer: 1000 * 1000 * 100, + verbose: verboseDefault, + stripFinalNewline: true, +}; + +// List of options which can have different values for `stdout`/`stderr` +export const FD_SPECIFIC_OPTIONS = ['lines', 'buffer', 'maxBuffer', 'verbose', 'stripFinalNewline']; + +// Retrieve fd-specific option +export const getFdSpecificValue = (optionArray, fdNumber) => fdNumber === 'ipc' + ? optionArray.at(-1) + : optionArray[fdNumber]; diff --git a/node_modules/execa/lib/command.js b/node_modules/execa/lib/command.js deleted file mode 100644 index 7ae9c2bc73..0000000000 --- a/node_modules/execa/lib/command.js +++ /dev/null @@ -1,120 +0,0 @@ -import {Buffer} from 'node:buffer'; -import {ChildProcess} from 'node:child_process'; - -const normalizeArgs = (file, args = []) => { - if (!Array.isArray(args)) { - return [file]; - } - - return [file, ...args]; -}; - -const NO_ESCAPE_REGEXP = /^[\w.-]+$/; -const DOUBLE_QUOTES_REGEXP = /"/g; - -const escapeArg = arg => { - if (typeof arg !== 'string' || NO_ESCAPE_REGEXP.test(arg)) { - return arg; - } - - return `"${arg.replace(DOUBLE_QUOTES_REGEXP, '\\"')}"`; -}; - -export const joinCommand = (file, args) => normalizeArgs(file, args).join(' '); - -export const getEscapedCommand = (file, args) => normalizeArgs(file, args).map(arg => escapeArg(arg)).join(' '); - -const SPACES_REGEXP = / +/g; - -// Handle `execaCommand()` -export const parseCommand = command => { - const tokens = []; - for (const token of command.trim().split(SPACES_REGEXP)) { - // Allow spaces to be escaped by a backslash if not meant as a delimiter - const previousToken = tokens[tokens.length - 1]; - if (previousToken && previousToken.endsWith('\\')) { - // Merge previous token with current one - tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`; - } else { - tokens.push(token); - } - } - - return tokens; -}; - -const parseExpression = expression => { - const typeOfExpression = typeof expression; - - if (typeOfExpression === 'string') { - return expression; - } - - if (typeOfExpression === 'number') { - return String(expression); - } - - if ( - typeOfExpression === 'object' - && expression !== null - && !(expression instanceof ChildProcess) - && 'stdout' in expression - ) { - const typeOfStdout = typeof expression.stdout; - - if (typeOfStdout === 'string') { - return expression.stdout; - } - - if (Buffer.isBuffer(expression.stdout)) { - return expression.stdout.toString(); - } - - throw new TypeError(`Unexpected "${typeOfStdout}" stdout in template expression`); - } - - throw new TypeError(`Unexpected "${typeOfExpression}" in template expression`); -}; - -const concatTokens = (tokens, nextTokens, isNew) => isNew || tokens.length === 0 || nextTokens.length === 0 - ? [...tokens, ...nextTokens] - : [ - ...tokens.slice(0, -1), - `${tokens[tokens.length - 1]}${nextTokens[0]}`, - ...nextTokens.slice(1), - ]; - -const parseTemplate = ({templates, expressions, tokens, index, template}) => { - const templateString = template ?? templates.raw[index]; - const templateTokens = templateString.split(SPACES_REGEXP).filter(Boolean); - const newTokens = concatTokens( - tokens, - templateTokens, - templateString.startsWith(' '), - ); - - if (index === expressions.length) { - return newTokens; - } - - const expression = expressions[index]; - const expressionTokens = Array.isArray(expression) - ? expression.map(expression => parseExpression(expression)) - : [parseExpression(expression)]; - return concatTokens( - newTokens, - expressionTokens, - templateString.endsWith(' '), - ); -}; - -export const parseTemplates = (templates, expressions) => { - let tokens = []; - - for (const [index, template] of templates.entries()) { - tokens = parseTemplate({templates, expressions, tokens, index, template}); - } - - return tokens; -}; - diff --git a/node_modules/execa/lib/convert/add.js b/node_modules/execa/lib/convert/add.js new file mode 100644 index 0000000000..699aa2bacd --- /dev/null +++ b/node_modules/execa/lib/convert/add.js @@ -0,0 +1,15 @@ +import {initializeConcurrentStreams} from './concurrent.js'; +import {createReadable} from './readable.js'; +import {createWritable} from './writable.js'; +import {createDuplex} from './duplex.js'; +import {createIterable} from './iterable.js'; + +// Add methods to convert the subprocess to a stream or iterable +export const addConvertedStreams = (subprocess, {encoding}) => { + const concurrentStreams = initializeConcurrentStreams(); + subprocess.readable = createReadable.bind(undefined, {subprocess, concurrentStreams, encoding}); + subprocess.writable = createWritable.bind(undefined, {subprocess, concurrentStreams}); + subprocess.duplex = createDuplex.bind(undefined, {subprocess, concurrentStreams, encoding}); + subprocess.iterable = createIterable.bind(undefined, subprocess, encoding); + subprocess[Symbol.asyncIterator] = createIterable.bind(undefined, subprocess, encoding, {}); +}; diff --git a/node_modules/execa/lib/convert/concurrent.js b/node_modules/execa/lib/convert/concurrent.js new file mode 100644 index 0000000000..4d921e4d26 --- /dev/null +++ b/node_modules/execa/lib/convert/concurrent.js @@ -0,0 +1,33 @@ +import {createDeferred} from '../utils/deferred.js'; + +// When using multiple `.readable()`/`.writable()`/`.duplex()`, `final` and `destroy` should wait for other streams +export const initializeConcurrentStreams = () => ({ + readableDestroy: new WeakMap(), + writableFinal: new WeakMap(), + writableDestroy: new WeakMap(), +}); + +// Each file descriptor + `waitName` has its own array of promises. +// Each promise is a single `.readable()`/`.writable()`/`.duplex()` call. +export const addConcurrentStream = (concurrentStreams, stream, waitName) => { + const weakMap = concurrentStreams[waitName]; + if (!weakMap.has(stream)) { + weakMap.set(stream, []); + } + + const promises = weakMap.get(stream); + const promise = createDeferred(); + promises.push(promise); + const resolve = promise.resolve.bind(promise); + return {resolve, promises}; +}; + +// Wait for other streams, but stop waiting when subprocess ends +export const waitForConcurrentStreams = async ({resolve, promises}, subprocess) => { + resolve(); + const [isSubprocessExit] = await Promise.race([ + Promise.allSettled([true, subprocess]), + Promise.all([false, ...promises]), + ]); + return !isSubprocessExit; +}; diff --git a/node_modules/execa/lib/convert/duplex.js b/node_modules/execa/lib/convert/duplex.js new file mode 100644 index 0000000000..ecfcf9eefd --- /dev/null +++ b/node_modules/execa/lib/convert/duplex.js @@ -0,0 +1,69 @@ +import {Duplex} from 'node:stream'; +import {callbackify} from 'node:util'; +import {BINARY_ENCODINGS} from '../arguments/encoding-option.js'; +import { + getSubprocessStdout, + getReadableOptions, + getReadableMethods, + onStdoutFinished, + onReadableDestroy, +} from './readable.js'; +import { + getSubprocessStdin, + getWritableMethods, + onStdinFinished, + onWritableDestroy, +} from './writable.js'; + +// Create a `Duplex` stream combining both `subprocess.readable()` and `subprocess.writable()` +export const createDuplex = ({subprocess, concurrentStreams, encoding}, {from, to, binary: binaryOption = true, preserveNewlines = true} = {}) => { + const binary = binaryOption || BINARY_ENCODINGS.has(encoding); + const {subprocessStdout, waitReadableDestroy} = getSubprocessStdout(subprocess, from, concurrentStreams); + const {subprocessStdin, waitWritableFinal, waitWritableDestroy} = getSubprocessStdin(subprocess, to, concurrentStreams); + const {readableEncoding, readableObjectMode, readableHighWaterMark} = getReadableOptions(subprocessStdout, binary); + const {read, onStdoutDataDone} = getReadableMethods({ + subprocessStdout, + subprocess, + binary, + encoding, + preserveNewlines, + }); + const duplex = new Duplex({ + read, + ...getWritableMethods(subprocessStdin, subprocess, waitWritableFinal), + destroy: callbackify(onDuplexDestroy.bind(undefined, { + subprocessStdout, + subprocessStdin, + subprocess, + waitReadableDestroy, + waitWritableFinal, + waitWritableDestroy, + })), + readableHighWaterMark, + writableHighWaterMark: subprocessStdin.writableHighWaterMark, + readableObjectMode, + writableObjectMode: subprocessStdin.writableObjectMode, + encoding: readableEncoding, + }); + onStdoutFinished({ + subprocessStdout, + onStdoutDataDone, + readable: duplex, + subprocess, + subprocessStdin, + }); + onStdinFinished(subprocessStdin, duplex, subprocessStdout); + return duplex; +}; + +const onDuplexDestroy = async ({subprocessStdout, subprocessStdin, subprocess, waitReadableDestroy, waitWritableFinal, waitWritableDestroy}, error) => { + await Promise.all([ + onReadableDestroy({subprocessStdout, subprocess, waitReadableDestroy}, error), + onWritableDestroy({ + subprocessStdin, + subprocess, + waitWritableFinal, + waitWritableDestroy, + }, error), + ]); +}; diff --git a/node_modules/execa/lib/convert/iterable.js b/node_modules/execa/lib/convert/iterable.js new file mode 100644 index 0000000000..d332f2643c --- /dev/null +++ b/node_modules/execa/lib/convert/iterable.js @@ -0,0 +1,34 @@ +import {BINARY_ENCODINGS} from '../arguments/encoding-option.js'; +import {getFromStream} from '../arguments/fd-options.js'; +import {iterateOnSubprocessStream} from '../io/iterate.js'; + +// Convert the subprocess to an async iterable +export const createIterable = (subprocess, encoding, { + from, + binary: binaryOption = false, + preserveNewlines = false, +} = {}) => { + const binary = binaryOption || BINARY_ENCODINGS.has(encoding); + const subprocessStdout = getFromStream(subprocess, from); + const onStdoutData = iterateOnSubprocessStream({ + subprocessStdout, + subprocess, + binary, + shouldEncode: true, + encoding, + preserveNewlines, + }); + return iterateOnStdoutData(onStdoutData, subprocessStdout, subprocess); +}; + +const iterateOnStdoutData = async function * (onStdoutData, subprocessStdout, subprocess) { + try { + yield * onStdoutData; + } finally { + if (subprocessStdout.readable) { + subprocessStdout.destroy(); + } + + await subprocess; + } +}; diff --git a/node_modules/execa/lib/convert/readable.js b/node_modules/execa/lib/convert/readable.js new file mode 100644 index 0000000000..a63b0c0098 --- /dev/null +++ b/node_modules/execa/lib/convert/readable.js @@ -0,0 +1,113 @@ +import {Readable} from 'node:stream'; +import {callbackify} from 'node:util'; +import {BINARY_ENCODINGS} from '../arguments/encoding-option.js'; +import {getFromStream} from '../arguments/fd-options.js'; +import {iterateOnSubprocessStream, DEFAULT_OBJECT_HIGH_WATER_MARK} from '../io/iterate.js'; +import {createDeferred} from '../utils/deferred.js'; +import {addConcurrentStream, waitForConcurrentStreams} from './concurrent.js'; +import { + safeWaitForSubprocessStdin, + waitForSubprocessStdout, + waitForSubprocess, + destroyOtherStream, +} from './shared.js'; + +// Create a `Readable` stream that forwards from `stdout` and awaits the subprocess +export const createReadable = ({subprocess, concurrentStreams, encoding}, {from, binary: binaryOption = true, preserveNewlines = true} = {}) => { + const binary = binaryOption || BINARY_ENCODINGS.has(encoding); + const {subprocessStdout, waitReadableDestroy} = getSubprocessStdout(subprocess, from, concurrentStreams); + const {readableEncoding, readableObjectMode, readableHighWaterMark} = getReadableOptions(subprocessStdout, binary); + const {read, onStdoutDataDone} = getReadableMethods({ + subprocessStdout, + subprocess, + binary, + encoding, + preserveNewlines, + }); + const readable = new Readable({ + read, + destroy: callbackify(onReadableDestroy.bind(undefined, {subprocessStdout, subprocess, waitReadableDestroy})), + highWaterMark: readableHighWaterMark, + objectMode: readableObjectMode, + encoding: readableEncoding, + }); + onStdoutFinished({ + subprocessStdout, + onStdoutDataDone, + readable, + subprocess, + }); + return readable; +}; + +// Retrieve `stdout` (or other stream depending on `from`) +export const getSubprocessStdout = (subprocess, from, concurrentStreams) => { + const subprocessStdout = getFromStream(subprocess, from); + const waitReadableDestroy = addConcurrentStream(concurrentStreams, subprocessStdout, 'readableDestroy'); + return {subprocessStdout, waitReadableDestroy}; +}; + +export const getReadableOptions = ({readableEncoding, readableObjectMode, readableHighWaterMark}, binary) => binary + ? {readableEncoding, readableObjectMode, readableHighWaterMark} + : {readableEncoding, readableObjectMode: true, readableHighWaterMark: DEFAULT_OBJECT_HIGH_WATER_MARK}; + +export const getReadableMethods = ({subprocessStdout, subprocess, binary, encoding, preserveNewlines}) => { + const onStdoutDataDone = createDeferred(); + const onStdoutData = iterateOnSubprocessStream({ + subprocessStdout, + subprocess, + binary, + shouldEncode: !binary, + encoding, + preserveNewlines, + }); + + return { + read() { + onRead(this, onStdoutData, onStdoutDataDone); + }, + onStdoutDataDone, + }; +}; + +// Forwards data from `stdout` to `readable` +const onRead = async (readable, onStdoutData, onStdoutDataDone) => { + try { + const {value, done} = await onStdoutData.next(); + if (done) { + onStdoutDataDone.resolve(); + } else { + readable.push(value); + } + } catch {} +}; + +// When `subprocess.stdout` ends/aborts/errors, do the same on `readable`. +// Await the subprocess, for the same reason as above. +export const onStdoutFinished = async ({subprocessStdout, onStdoutDataDone, readable, subprocess, subprocessStdin}) => { + try { + await waitForSubprocessStdout(subprocessStdout); + await subprocess; + await safeWaitForSubprocessStdin(subprocessStdin); + await onStdoutDataDone; + + if (readable.readable) { + readable.push(null); + } + } catch (error) { + await safeWaitForSubprocessStdin(subprocessStdin); + destroyOtherReadable(readable, error); + } +}; + +// When `readable` aborts/errors, do the same on `subprocess.stdout` +export const onReadableDestroy = async ({subprocessStdout, subprocess, waitReadableDestroy}, error) => { + if (await waitForConcurrentStreams(waitReadableDestroy, subprocess)) { + destroyOtherReadable(subprocessStdout, error); + await waitForSubprocess(subprocess, error); + } +}; + +const destroyOtherReadable = (stream, error) => { + destroyOtherStream(stream, stream.readable, error); +}; diff --git a/node_modules/execa/lib/convert/shared.js b/node_modules/execa/lib/convert/shared.js new file mode 100644 index 0000000000..6e3d428348 --- /dev/null +++ b/node_modules/execa/lib/convert/shared.js @@ -0,0 +1,46 @@ +import {finished} from 'node:stream/promises'; +import {isStreamAbort} from '../resolve/wait-stream.js'; + +export const safeWaitForSubprocessStdin = async subprocessStdin => { + if (subprocessStdin === undefined) { + return; + } + + try { + await waitForSubprocessStdin(subprocessStdin); + } catch {} +}; + +export const safeWaitForSubprocessStdout = async subprocessStdout => { + if (subprocessStdout === undefined) { + return; + } + + try { + await waitForSubprocessStdout(subprocessStdout); + } catch {} +}; + +export const waitForSubprocessStdin = async subprocessStdin => { + await finished(subprocessStdin, {cleanup: true, readable: false, writable: true}); +}; + +export const waitForSubprocessStdout = async subprocessStdout => { + await finished(subprocessStdout, {cleanup: true, readable: true, writable: false}); +}; + +// When `readable` or `writable` aborts/errors, awaits the subprocess, for the reason mentioned above +export const waitForSubprocess = async (subprocess, error) => { + await subprocess; + if (error) { + throw error; + } +}; + +export const destroyOtherStream = (stream, isOpen, error) => { + if (error && !isStreamAbort(error)) { + stream.destroy(error); + } else if (isOpen) { + stream.destroy(); + } +}; diff --git a/node_modules/execa/lib/convert/writable.js b/node_modules/execa/lib/convert/writable.js new file mode 100644 index 0000000000..fd727e3ee3 --- /dev/null +++ b/node_modules/execa/lib/convert/writable.js @@ -0,0 +1,90 @@ +import {Writable} from 'node:stream'; +import {callbackify} from 'node:util'; +import {getToStream} from '../arguments/fd-options.js'; +import {addConcurrentStream, waitForConcurrentStreams} from './concurrent.js'; +import { + safeWaitForSubprocessStdout, + waitForSubprocessStdin, + waitForSubprocess, + destroyOtherStream, +} from './shared.js'; + +// Create a `Writable` stream that forwards to `stdin` and awaits the subprocess +export const createWritable = ({subprocess, concurrentStreams}, {to} = {}) => { + const {subprocessStdin, waitWritableFinal, waitWritableDestroy} = getSubprocessStdin(subprocess, to, concurrentStreams); + const writable = new Writable({ + ...getWritableMethods(subprocessStdin, subprocess, waitWritableFinal), + destroy: callbackify(onWritableDestroy.bind(undefined, { + subprocessStdin, + subprocess, + waitWritableFinal, + waitWritableDestroy, + })), + highWaterMark: subprocessStdin.writableHighWaterMark, + objectMode: subprocessStdin.writableObjectMode, + }); + onStdinFinished(subprocessStdin, writable); + return writable; +}; + +// Retrieve `stdin` (or other stream depending on `to`) +export const getSubprocessStdin = (subprocess, to, concurrentStreams) => { + const subprocessStdin = getToStream(subprocess, to); + const waitWritableFinal = addConcurrentStream(concurrentStreams, subprocessStdin, 'writableFinal'); + const waitWritableDestroy = addConcurrentStream(concurrentStreams, subprocessStdin, 'writableDestroy'); + return {subprocessStdin, waitWritableFinal, waitWritableDestroy}; +}; + +export const getWritableMethods = (subprocessStdin, subprocess, waitWritableFinal) => ({ + write: onWrite.bind(undefined, subprocessStdin), + final: callbackify(onWritableFinal.bind(undefined, subprocessStdin, subprocess, waitWritableFinal)), +}); + +// Forwards data from `writable` to `stdin` +const onWrite = (subprocessStdin, chunk, encoding, done) => { + if (subprocessStdin.write(chunk, encoding)) { + done(); + } else { + subprocessStdin.once('drain', done); + } +}; + +// Ensures that the writable `final` and readable `end` events awaits the subprocess. +// Like this, any subprocess failure is propagated as a stream `error` event, instead of being lost. +// The user does not need to `await` the subprocess anymore, but now needs to await the stream completion or error. +// When multiple writables are targeting the same stream, they wait for each other, unless the subprocess ends first. +const onWritableFinal = async (subprocessStdin, subprocess, waitWritableFinal) => { + if (await waitForConcurrentStreams(waitWritableFinal, subprocess)) { + if (subprocessStdin.writable) { + subprocessStdin.end(); + } + + await subprocess; + } +}; + +// When `subprocess.stdin` ends/aborts/errors, do the same on `writable`. +export const onStdinFinished = async (subprocessStdin, writable, subprocessStdout) => { + try { + await waitForSubprocessStdin(subprocessStdin); + if (writable.writable) { + writable.end(); + } + } catch (error) { + await safeWaitForSubprocessStdout(subprocessStdout); + destroyOtherWritable(writable, error); + } +}; + +// When `writable` aborts/errors, do the same on `subprocess.stdin` +export const onWritableDestroy = async ({subprocessStdin, subprocess, waitWritableFinal, waitWritableDestroy}, error) => { + await waitForConcurrentStreams(waitWritableFinal, subprocess); + if (await waitForConcurrentStreams(waitWritableDestroy, subprocess)) { + destroyOtherWritable(subprocessStdin, error); + await waitForSubprocess(subprocess, error); + } +}; + +const destroyOtherWritable = (stream, error) => { + destroyOtherStream(stream, stream.writable, error); +}; diff --git a/node_modules/execa/lib/error.js b/node_modules/execa/lib/error.js deleted file mode 100644 index b12c144428..0000000000 --- a/node_modules/execa/lib/error.js +++ /dev/null @@ -1,85 +0,0 @@ -import {signalsByName} from 'human-signals'; - -const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { - if (timedOut) { - return `timed out after ${timeout} milliseconds`; - } - - if (isCanceled) { - return 'was canceled'; - } - - if (errorCode !== undefined) { - return `failed with ${errorCode}`; - } - - if (signal !== undefined) { - return `was killed with ${signal} (${signalDescription})`; - } - - if (exitCode !== undefined) { - return `failed with exit code ${exitCode}`; - } - - return 'failed'; -}; - -export const makeError = ({ - stdout, - stderr, - all, - error, - signal, - exitCode, - command, - escapedCommand, - timedOut, - isCanceled, - killed, - parsed: {options: {timeout}}, -}) => { - // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`. - // We normalize them to `undefined` - exitCode = exitCode === null ? undefined : exitCode; - signal = signal === null ? undefined : signal; - const signalDescription = signal === undefined ? undefined : signalsByName[signal].description; - - const errorCode = error && error.code; - - const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}); - const execaMessage = `Command ${prefix}: ${command}`; - const isError = Object.prototype.toString.call(error) === '[object Error]'; - const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage; - const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n'); - - if (isError) { - error.originalMessage = error.message; - error.message = message; - } else { - error = new Error(message); - } - - error.shortMessage = shortMessage; - error.command = command; - error.escapedCommand = escapedCommand; - error.exitCode = exitCode; - error.signal = signal; - error.signalDescription = signalDescription; - error.stdout = stdout; - error.stderr = stderr; - - if (all !== undefined) { - error.all = all; - } - - if ('bufferedData' in error) { - delete error.bufferedData; - } - - error.failed = true; - error.timedOut = Boolean(timedOut); - error.isCanceled = isCanceled; - error.killed = killed && !timedOut; - - return error; -}; diff --git a/node_modules/execa/lib/io/contents.js b/node_modules/execa/lib/io/contents.js new file mode 100644 index 0000000000..a8c30768b0 --- /dev/null +++ b/node_modules/execa/lib/io/contents.js @@ -0,0 +1,116 @@ +import {setImmediate} from 'node:timers/promises'; +import getStream, {getStreamAsArrayBuffer, getStreamAsArray} from 'get-stream'; +import {isArrayBuffer} from '../utils/uint-array.js'; +import {shouldLogOutput, logLines} from '../verbose/output.js'; +import {iterateForResult} from './iterate.js'; +import {handleMaxBuffer} from './max-buffer.js'; +import {getStripFinalNewline} from './strip-newline.js'; + +// Retrieve `result.stdout|stderr|all|stdio[*]` +export const getStreamOutput = async ({stream, onStreamEnd, fdNumber, encoding, buffer, maxBuffer, lines, allMixed, stripFinalNewline, verboseInfo, streamInfo}) => { + const logPromise = logOutputAsync({ + stream, + onStreamEnd, + fdNumber, + encoding, + allMixed, + verboseInfo, + streamInfo, + }); + + if (!buffer) { + await Promise.all([resumeStream(stream), logPromise]); + return; + } + + const stripFinalNewlineValue = getStripFinalNewline(stripFinalNewline, fdNumber); + const iterable = iterateForResult({ + stream, + onStreamEnd, + lines, + encoding, + stripFinalNewline: stripFinalNewlineValue, + allMixed, + }); + const [output] = await Promise.all([ + getStreamContents({ + stream, + iterable, + fdNumber, + encoding, + maxBuffer, + lines, + }), + logPromise, + ]); + return output; +}; + +const logOutputAsync = async ({stream, onStreamEnd, fdNumber, encoding, allMixed, verboseInfo, streamInfo: {fileDescriptors}}) => { + if (!shouldLogOutput({ + stdioItems: fileDescriptors[fdNumber]?.stdioItems, + encoding, + verboseInfo, + fdNumber, + })) { + return; + } + + const linesIterable = iterateForResult({ + stream, + onStreamEnd, + lines: true, + encoding, + stripFinalNewline: true, + allMixed, + }); + await logLines(linesIterable, stream, fdNumber, verboseInfo); +}; + +// When using `buffer: false`, users need to read `subprocess.stdout|stderr|all` right away +// See https://github.com/sindresorhus/execa/issues/730 and https://github.com/sindresorhus/execa/pull/729#discussion_r1465496310 +const resumeStream = async stream => { + await setImmediate(); + if (stream.readableFlowing === null) { + stream.resume(); + } +}; + +const getStreamContents = async ({stream, stream: {readableObjectMode}, iterable, fdNumber, encoding, maxBuffer, lines}) => { + try { + if (readableObjectMode || lines) { + return await getStreamAsArray(iterable, {maxBuffer}); + } + + if (encoding === 'buffer') { + return new Uint8Array(await getStreamAsArrayBuffer(iterable, {maxBuffer})); + } + + return await getStream(iterable, {maxBuffer}); + } catch (error) { + return handleBufferedData(handleMaxBuffer({ + error, + stream, + readableObjectMode, + lines, + encoding, + fdNumber, + })); + } +}; + +// On failure, `result.stdout|stderr|all` should contain the currently buffered stream +// They are automatically closed and flushed by Node.js when the subprocess exits +// When `buffer` is `false`, `streamPromise` is `undefined` and there is no buffered data to retrieve +export const getBufferedData = async streamPromise => { + try { + return await streamPromise; + } catch (error) { + return handleBufferedData(error); + } +}; + +// Ensure we are returning Uint8Arrays when using `encoding: 'buffer'` +const handleBufferedData = ({bufferedData}) => isArrayBuffer(bufferedData) + ? new Uint8Array(bufferedData) + : bufferedData; diff --git a/node_modules/execa/lib/io/input-sync.js b/node_modules/execa/lib/io/input-sync.js new file mode 100644 index 0000000000..4b76757de6 --- /dev/null +++ b/node_modules/execa/lib/io/input-sync.js @@ -0,0 +1,44 @@ +import {runGeneratorsSync} from '../transform/generator.js'; +import {joinToUint8Array, isUint8Array} from '../utils/uint-array.js'; +import {TYPE_TO_MESSAGE} from '../stdio/type.js'; + +// Apply `stdin`/`input`/`inputFile` options, before spawning, in sync mode, by converting it to the `input` option +export const addInputOptionsSync = (fileDescriptors, options) => { + for (const fdNumber of getInputFdNumbers(fileDescriptors)) { + addInputOptionSync(fileDescriptors, fdNumber, options); + } +}; + +const getInputFdNumbers = fileDescriptors => new Set(Object.entries(fileDescriptors) + .filter(([, {direction}]) => direction === 'input') + .map(([fdNumber]) => Number(fdNumber))); + +const addInputOptionSync = (fileDescriptors, fdNumber, options) => { + const {stdioItems} = fileDescriptors[fdNumber]; + const allStdioItems = stdioItems.filter(({contents}) => contents !== undefined); + if (allStdioItems.length === 0) { + return; + } + + if (fdNumber !== 0) { + const [{type, optionName}] = allStdioItems; + throw new TypeError(`Only the \`stdin\` option, not \`${optionName}\`, can be ${TYPE_TO_MESSAGE[type]} with synchronous methods.`); + } + + const allContents = allStdioItems.map(({contents}) => contents); + const transformedContents = allContents.map(contents => applySingleInputGeneratorsSync(contents, stdioItems)); + options.input = joinToUint8Array(transformedContents); +}; + +const applySingleInputGeneratorsSync = (contents, stdioItems) => { + const newContents = runGeneratorsSync(contents, stdioItems, 'utf8', true); + validateSerializable(newContents); + return joinToUint8Array(newContents); +}; + +const validateSerializable = newContents => { + const invalidItem = newContents.find(item => typeof item !== 'string' && !isUint8Array(item)); + if (invalidItem !== undefined) { + throw new TypeError(`The \`stdin\` option is invalid: when passing objects as input, a transform must be used to serialize them to strings or Uint8Arrays: ${invalidItem}.`); + } +}; diff --git a/node_modules/execa/lib/io/iterate.js b/node_modules/execa/lib/io/iterate.js new file mode 100644 index 0000000000..1ded0c458a --- /dev/null +++ b/node_modules/execa/lib/io/iterate.js @@ -0,0 +1,110 @@ +import {on} from 'node:events'; +import {getDefaultHighWaterMark} from 'node:stream'; +import {getEncodingTransformGenerator} from '../transform/encoding-transform.js'; +import {getSplitLinesGenerator} from '../transform/split.js'; +import {transformChunkSync, finalChunksSync} from '../transform/run-sync.js'; + +// Iterate over lines of `subprocess.stdout`, used by `subprocess.readable|duplex|iterable()` +export const iterateOnSubprocessStream = ({subprocessStdout, subprocess, binary, shouldEncode, encoding, preserveNewlines}) => { + const controller = new AbortController(); + stopReadingOnExit(subprocess, controller); + return iterateOnStream({ + stream: subprocessStdout, + controller, + binary, + shouldEncode: !subprocessStdout.readableObjectMode && shouldEncode, + encoding, + shouldSplit: !subprocessStdout.readableObjectMode, + preserveNewlines, + }); +}; + +const stopReadingOnExit = async (subprocess, controller) => { + try { + await subprocess; + } catch {} finally { + controller.abort(); + } +}; + +// Iterate over lines of `subprocess.stdout`, used by `result.stdout` and the `verbose: 'full'` option. +// Applies the `lines` and `encoding` options. +export const iterateForResult = ({stream, onStreamEnd, lines, encoding, stripFinalNewline, allMixed}) => { + const controller = new AbortController(); + stopReadingOnStreamEnd(onStreamEnd, controller, stream); + const objectMode = stream.readableObjectMode && !allMixed; + return iterateOnStream({ + stream, + controller, + binary: encoding === 'buffer', + shouldEncode: !objectMode, + encoding, + shouldSplit: !objectMode && lines, + preserveNewlines: !stripFinalNewline, + }); +}; + +const stopReadingOnStreamEnd = async (onStreamEnd, controller, stream) => { + try { + await onStreamEnd; + } catch { + stream.destroy(); + } finally { + controller.abort(); + } +}; + +const iterateOnStream = ({stream, controller, binary, shouldEncode, encoding, shouldSplit, preserveNewlines}) => { + const onStdoutChunk = on(stream, 'data', { + signal: controller.signal, + highWaterMark: HIGH_WATER_MARK, + // Backward compatibility with older name for this option + // See https://github.com/nodejs/node/pull/52080#discussion_r1525227861 + // @todo Remove after removing support for Node 21 + highWatermark: HIGH_WATER_MARK, + }); + return iterateOnData({ + onStdoutChunk, + controller, + binary, + shouldEncode, + encoding, + shouldSplit, + preserveNewlines, + }); +}; + +export const DEFAULT_OBJECT_HIGH_WATER_MARK = getDefaultHighWaterMark(true); + +// The `highWaterMark` of `events.on()` is measured in number of events, not in bytes. +// Not knowing the average amount of bytes per `data` event, we use the same heuristic as streams in objectMode, since they have the same issue. +// Therefore, we use the value of `getDefaultHighWaterMark(true)`. +// Note: this option does not exist on Node 18, but this is ok since the logic works without it. It just consumes more memory. +const HIGH_WATER_MARK = DEFAULT_OBJECT_HIGH_WATER_MARK; + +const iterateOnData = async function * ({onStdoutChunk, controller, binary, shouldEncode, encoding, shouldSplit, preserveNewlines}) { + const generators = getGenerators({ + binary, + shouldEncode, + encoding, + shouldSplit, + preserveNewlines, + }); + + try { + for await (const [chunk] of onStdoutChunk) { + yield * transformChunkSync(chunk, generators, 0); + } + } catch (error) { + if (!controller.signal.aborted) { + throw error; + } + } finally { + yield * finalChunksSync(generators); + } +}; + +const getGenerators = ({binary, shouldEncode, encoding, shouldSplit, preserveNewlines}) => [ + getEncodingTransformGenerator(binary, encoding, !shouldEncode), + getSplitLinesGenerator(binary, preserveNewlines, !shouldSplit, {}), +].filter(Boolean); diff --git a/node_modules/execa/lib/io/max-buffer.js b/node_modules/execa/lib/io/max-buffer.js new file mode 100644 index 0000000000..1f4520a595 --- /dev/null +++ b/node_modules/execa/lib/io/max-buffer.js @@ -0,0 +1,89 @@ +import {MaxBufferError} from 'get-stream'; +import {getStreamName} from '../utils/standard-stream.js'; +import {getFdSpecificValue} from '../arguments/specific.js'; + +// When the `maxBuffer` option is hit, a MaxBufferError is thrown. +// The stream is aborted, then specific information is kept for the error message. +export const handleMaxBuffer = ({error, stream, readableObjectMode, lines, encoding, fdNumber}) => { + if (!(error instanceof MaxBufferError)) { + throw error; + } + + if (fdNumber === 'all') { + return error; + } + + const unit = getMaxBufferUnit(readableObjectMode, lines, encoding); + error.maxBufferInfo = {fdNumber, unit}; + stream.destroy(); + throw error; +}; + +const getMaxBufferUnit = (readableObjectMode, lines, encoding) => { + if (readableObjectMode) { + return 'objects'; + } + + if (lines) { + return 'lines'; + } + + if (encoding === 'buffer') { + return 'bytes'; + } + + return 'characters'; +}; + +// Check the `maxBuffer` option with `result.ipcOutput` +export const checkIpcMaxBuffer = (subprocess, ipcOutput, maxBuffer) => { + if (ipcOutput.length !== maxBuffer) { + return; + } + + const error = new MaxBufferError(); + error.maxBufferInfo = {fdNumber: 'ipc'}; + throw error; +}; + +// Error message when `maxBuffer` is hit +export const getMaxBufferMessage = (error, maxBuffer) => { + const {streamName, threshold, unit} = getMaxBufferInfo(error, maxBuffer); + return `Command's ${streamName} was larger than ${threshold} ${unit}`; +}; + +const getMaxBufferInfo = (error, maxBuffer) => { + if (error?.maxBufferInfo === undefined) { + return {streamName: 'output', threshold: maxBuffer[1], unit: 'bytes'}; + } + + const {maxBufferInfo: {fdNumber, unit}} = error; + delete error.maxBufferInfo; + + const threshold = getFdSpecificValue(maxBuffer, fdNumber); + if (fdNumber === 'ipc') { + return {streamName: 'IPC output', threshold, unit: 'messages'}; + } + + return {streamName: getStreamName(fdNumber), threshold, unit}; +}; + +// The only way to apply `maxBuffer` with `spawnSync()` is to use the native `maxBuffer` option Node.js provides. +// However, this has multiple limitations, and cannot behave the exact same way as the async behavior. +// When the `maxBuffer` is hit, a `ENOBUFS` error is thrown. +export const isMaxBufferSync = (resultError, output, maxBuffer) => resultError?.code === 'ENOBUFS' + && output !== null + && output.some(result => result !== null && result.length > getMaxBufferSync(maxBuffer)); + +// When `maxBuffer` is hit, ensure the result is truncated +export const truncateMaxBufferSync = (result, isMaxBuffer, maxBuffer) => { + if (!isMaxBuffer) { + return result; + } + + const maxBufferValue = getMaxBufferSync(maxBuffer); + return result.length > maxBufferValue ? result.slice(0, maxBufferValue) : result; +}; + +// `spawnSync()` does not allow differentiating `maxBuffer` per file descriptor, so we always use `stdout` +export const getMaxBufferSync = ([, stdoutMaxBuffer]) => stdoutMaxBuffer; diff --git a/node_modules/execa/lib/io/output-async.js b/node_modules/execa/lib/io/output-async.js new file mode 100644 index 0000000000..ededfa9b23 --- /dev/null +++ b/node_modules/execa/lib/io/output-async.js @@ -0,0 +1,80 @@ +import mergeStreams from '@sindresorhus/merge-streams'; +import {isStandardStream} from '../utils/standard-stream.js'; +import {incrementMaxListeners} from '../utils/max-listeners.js'; +import {TRANSFORM_TYPES} from '../stdio/type.js'; +import {pipeStreams} from './pipeline.js'; + +// Handle `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, after spawning, in async mode +// When multiple input streams are used, we merge them to ensure the output stream ends only once each input stream has ended +export const pipeOutputAsync = (subprocess, fileDescriptors, controller) => { + const pipeGroups = new Map(); + + for (const [fdNumber, {stdioItems, direction}] of Object.entries(fileDescriptors)) { + for (const {stream} of stdioItems.filter(({type}) => TRANSFORM_TYPES.has(type))) { + pipeTransform(subprocess, stream, direction, fdNumber); + } + + for (const {stream} of stdioItems.filter(({type}) => !TRANSFORM_TYPES.has(type))) { + pipeStdioItem({ + subprocess, + stream, + direction, + fdNumber, + pipeGroups, + controller, + }); + } + } + + for (const [outputStream, inputStreams] of pipeGroups.entries()) { + const inputStream = inputStreams.length === 1 ? inputStreams[0] : mergeStreams(inputStreams); + pipeStreams(inputStream, outputStream); + } +}; + +// When using transforms, `subprocess.stdin|stdout|stderr|stdio` is directly mutated +const pipeTransform = (subprocess, stream, direction, fdNumber) => { + if (direction === 'output') { + pipeStreams(subprocess.stdio[fdNumber], stream); + } else { + pipeStreams(stream, subprocess.stdio[fdNumber]); + } + + const streamProperty = SUBPROCESS_STREAM_PROPERTIES[fdNumber]; + if (streamProperty !== undefined) { + subprocess[streamProperty] = stream; + } + + subprocess.stdio[fdNumber] = stream; +}; + +const SUBPROCESS_STREAM_PROPERTIES = ['stdin', 'stdout', 'stderr']; + +// Most `std*` option values involve piping `subprocess.std*` to a stream. +// The stream is either passed by the user or created internally. +const pipeStdioItem = ({subprocess, stream, direction, fdNumber, pipeGroups, controller}) => { + if (stream === undefined) { + return; + } + + setStandardStreamMaxListeners(stream, controller); + + const [inputStream, outputStream] = direction === 'output' + ? [stream, subprocess.stdio[fdNumber]] + : [subprocess.stdio[fdNumber], stream]; + const outputStreams = pipeGroups.get(inputStream) ?? []; + pipeGroups.set(inputStream, [...outputStreams, outputStream]); +}; + +// Multiple subprocesses might be piping from/to `process.std*` at the same time. +// This is not necessarily an error and should not print a `maxListeners` warning. +const setStandardStreamMaxListeners = (stream, {signal}) => { + if (isStandardStream(stream)) { + incrementMaxListeners(stream, MAX_LISTENERS_INCREMENT, signal); + } +}; + +// `source.pipe(destination)` adds at most 1 listener for each event. +// If `stdin` option is an array, the values might be combined with `merge-streams`. +// That library also listens for `source` end, which adds 1 more listener. +const MAX_LISTENERS_INCREMENT = 2; diff --git a/node_modules/execa/lib/io/output-sync.js b/node_modules/execa/lib/io/output-sync.js new file mode 100644 index 0000000000..36c9a8af9f --- /dev/null +++ b/node_modules/execa/lib/io/output-sync.js @@ -0,0 +1,135 @@ +import {writeFileSync, appendFileSync} from 'node:fs'; +import {shouldLogOutput, logLinesSync} from '../verbose/output.js'; +import {runGeneratorsSync} from '../transform/generator.js'; +import {splitLinesSync} from '../transform/split.js'; +import {joinToString, joinToUint8Array, bufferToUint8Array} from '../utils/uint-array.js'; +import {FILE_TYPES} from '../stdio/type.js'; +import {truncateMaxBufferSync} from './max-buffer.js'; + +// Apply `stdout`/`stderr` options, after spawning, in sync mode +export const transformOutputSync = ({fileDescriptors, syncResult: {output}, options, isMaxBuffer, verboseInfo}) => { + if (output === null) { + return {output: Array.from({length: 3})}; + } + + const state = {}; + const outputFiles = new Set([]); + const transformedOutput = output.map((result, fdNumber) => + transformOutputResultSync({ + result, + fileDescriptors, + fdNumber, + state, + outputFiles, + isMaxBuffer, + verboseInfo, + }, options)); + return {output: transformedOutput, ...state}; +}; + +const transformOutputResultSync = ( + {result, fileDescriptors, fdNumber, state, outputFiles, isMaxBuffer, verboseInfo}, + {buffer, encoding, lines, stripFinalNewline, maxBuffer}, +) => { + if (result === null) { + return; + } + + const truncatedResult = truncateMaxBufferSync(result, isMaxBuffer, maxBuffer); + const uint8ArrayResult = bufferToUint8Array(truncatedResult); + const {stdioItems, objectMode} = fileDescriptors[fdNumber]; + const chunks = runOutputGeneratorsSync([uint8ArrayResult], stdioItems, encoding, state); + const {serializedResult, finalResult = serializedResult} = serializeChunks({ + chunks, + objectMode, + encoding, + lines, + stripFinalNewline, + fdNumber, + }); + + logOutputSync({ + serializedResult, + fdNumber, + state, + verboseInfo, + encoding, + stdioItems, + objectMode, + }); + + const returnedResult = buffer[fdNumber] ? finalResult : undefined; + + try { + if (state.error === undefined) { + writeToFiles(serializedResult, stdioItems, outputFiles); + } + + return returnedResult; + } catch (error) { + state.error = error; + return returnedResult; + } +}; + +// Applies transform generators to `stdout`/`stderr` +const runOutputGeneratorsSync = (chunks, stdioItems, encoding, state) => { + try { + return runGeneratorsSync(chunks, stdioItems, encoding, false); + } catch (error) { + state.error = error; + return chunks; + } +}; + +// The contents is converted to three stages: +// - serializedResult: used when the target is a file path/URL or a file descriptor (including 'inherit') +// - finalResult/returnedResult: returned as `result.std*` +const serializeChunks = ({chunks, objectMode, encoding, lines, stripFinalNewline, fdNumber}) => { + if (objectMode) { + return {serializedResult: chunks}; + } + + if (encoding === 'buffer') { + return {serializedResult: joinToUint8Array(chunks)}; + } + + const serializedResult = joinToString(chunks, encoding); + if (lines[fdNumber]) { + return {serializedResult, finalResult: splitLinesSync(serializedResult, !stripFinalNewline[fdNumber], objectMode)}; + } + + return {serializedResult}; +}; + +const logOutputSync = ({serializedResult, fdNumber, state, verboseInfo, encoding, stdioItems, objectMode}) => { + if (!shouldLogOutput({ + stdioItems, + encoding, + verboseInfo, + fdNumber, + })) { + return; + } + + const linesArray = splitLinesSync(serializedResult, false, objectMode); + + try { + logLinesSync(linesArray, fdNumber, verboseInfo); + } catch (error) { + state.error ??= error; + } +}; + +// When the `std*` target is a file path/URL or a file descriptor +const writeToFiles = (serializedResult, stdioItems, outputFiles) => { + for (const {path, append} of stdioItems.filter(({type}) => FILE_TYPES.has(type))) { + const pathString = typeof path === 'string' ? path : path.toString(); + if (append || outputFiles.has(pathString)) { + appendFileSync(path, serializedResult); + } else { + outputFiles.add(pathString); + writeFileSync(path, serializedResult); + } + } +}; diff --git a/node_modules/execa/lib/io/pipeline.js b/node_modules/execa/lib/io/pipeline.js new file mode 100644 index 0000000000..423639c08c --- /dev/null +++ b/node_modules/execa/lib/io/pipeline.js @@ -0,0 +1,48 @@ +import {finished} from 'node:stream/promises'; +import {isStandardStream} from '../utils/standard-stream.js'; + +// Similar to `Stream.pipeline(source, destination)`, but does not destroy standard streams +export const pipeStreams = (source, destination) => { + source.pipe(destination); + onSourceFinish(source, destination); + onDestinationFinish(source, destination); +}; + +// `source.pipe(destination)` makes `destination` end when `source` ends. +// But it does not propagate aborts or errors. This function does it. +const onSourceFinish = async (source, destination) => { + if (isStandardStream(source) || isStandardStream(destination)) { + return; + } + + try { + await finished(source, {cleanup: true, readable: true, writable: false}); + } catch {} + + endDestinationStream(destination); +}; + +export const endDestinationStream = destination => { + if (destination.writable) { + destination.end(); + } +}; + +// We do the same thing in the other direction as well. +const onDestinationFinish = async (source, destination) => { + if (isStandardStream(source) || isStandardStream(destination)) { + return; + } + + try { + await finished(destination, {cleanup: true, readable: false, writable: true}); + } catch {} + + abortSourceStream(source); +}; + +export const abortSourceStream = source => { + if (source.readable) { + source.destroy(); + } +}; diff --git a/node_modules/execa/lib/io/strip-newline.js b/node_modules/execa/lib/io/strip-newline.js new file mode 100644 index 0000000000..78d1401eb0 --- /dev/null +++ b/node_modules/execa/lib/io/strip-newline.js @@ -0,0 +1,12 @@ +import stripFinalNewlineFunction from 'strip-final-newline'; + +// Apply `stripFinalNewline` option, which applies to `result.stdout|stderr|all|stdio[*]`. +// If the `lines` option is used, it is applied on each line, but using a different function. +export const stripNewline = (value, {stripFinalNewline}, fdNumber) => getStripFinalNewline(stripFinalNewline, fdNumber) && value !== undefined && !Array.isArray(value) + ? stripFinalNewlineFunction(value) + : value; + +// Retrieve `stripFinalNewline` option value, including with `subprocess.all` +export const getStripFinalNewline = (stripFinalNewline, fdNumber) => fdNumber === 'all' + ? stripFinalNewline[1] || stripFinalNewline[2] + : stripFinalNewline[fdNumber]; diff --git a/node_modules/execa/lib/ipc/array.js b/node_modules/execa/lib/ipc/array.js new file mode 100644 index 0000000000..de9e219478 --- /dev/null +++ b/node_modules/execa/lib/ipc/array.js @@ -0,0 +1,4 @@ +// The `ipc` option adds an `ipc` item to the `stdio` option +export const normalizeIpcStdioArray = (stdioArray, ipc) => ipc && !stdioArray.includes('ipc') + ? [...stdioArray, 'ipc'] + : stdioArray; diff --git a/node_modules/execa/lib/ipc/buffer-messages.js b/node_modules/execa/lib/ipc/buffer-messages.js new file mode 100644 index 0000000000..c8ed3d583c --- /dev/null +++ b/node_modules/execa/lib/ipc/buffer-messages.js @@ -0,0 +1,47 @@ +import {checkIpcMaxBuffer} from '../io/max-buffer.js'; +import {shouldLogIpc, logIpcOutput} from '../verbose/ipc.js'; +import {getFdSpecificValue} from '../arguments/specific.js'; +import {loopOnMessages} from './get-each.js'; + +// Iterate through IPC messages sent by the subprocess +export const waitForIpcOutput = async ({ + subprocess, + buffer: bufferArray, + maxBuffer: maxBufferArray, + ipc, + ipcOutput, + verboseInfo, +}) => { + if (!ipc) { + return ipcOutput; + } + + const isVerbose = shouldLogIpc(verboseInfo); + const buffer = getFdSpecificValue(bufferArray, 'ipc'); + const maxBuffer = getFdSpecificValue(maxBufferArray, 'ipc'); + + for await (const message of loopOnMessages({ + anyProcess: subprocess, + channel: subprocess.channel, + isSubprocess: false, + ipc, + shouldAwait: false, + reference: true, + })) { + if (buffer) { + checkIpcMaxBuffer(subprocess, ipcOutput, maxBuffer); + ipcOutput.push(message); + } + + if (isVerbose) { + logIpcOutput(message, verboseInfo); + } + } + + return ipcOutput; +}; + +export const getBufferedIpcOutput = async (ipcOutputPromise, ipcOutput) => { + await Promise.allSettled([ipcOutputPromise]); + return ipcOutput; +}; diff --git a/node_modules/execa/lib/ipc/forward.js b/node_modules/execa/lib/ipc/forward.js new file mode 100644 index 0000000000..b380b44908 --- /dev/null +++ b/node_modules/execa/lib/ipc/forward.js @@ -0,0 +1,56 @@ +import {EventEmitter} from 'node:events'; +import {onMessage, onDisconnect} from './incoming.js'; +import {undoAddedReferences} from './reference.js'; + +// Forward the `message` and `disconnect` events from the process and subprocess to a proxy emitter. +// This prevents the `error` event from stopping IPC. +// This also allows debouncing the `message` event. +export const getIpcEmitter = (anyProcess, channel, isSubprocess) => { + if (IPC_EMITTERS.has(anyProcess)) { + return IPC_EMITTERS.get(anyProcess); + } + + // Use an `EventEmitter`, like the `process` that is being proxied + // eslint-disable-next-line unicorn/prefer-event-target + const ipcEmitter = new EventEmitter(); + ipcEmitter.connected = true; + IPC_EMITTERS.set(anyProcess, ipcEmitter); + forwardEvents({ + ipcEmitter, + anyProcess, + channel, + isSubprocess, + }); + return ipcEmitter; +}; + +const IPC_EMITTERS = new WeakMap(); + +// The `message` and `disconnect` events are buffered in the subprocess until the first listener is setup. +// However, unbuffering happens after one tick, so this give enough time for the caller to setup the listener on the proxy emitter first. +// See https://github.com/nodejs/node/blob/2aaeaa863c35befa2ebaa98fb7737ec84df4d8e9/lib/internal/child_process.js#L721 +const forwardEvents = ({ipcEmitter, anyProcess, channel, isSubprocess}) => { + const boundOnMessage = onMessage.bind(undefined, { + anyProcess, + channel, + isSubprocess, + ipcEmitter, + }); + anyProcess.on('message', boundOnMessage); + anyProcess.once('disconnect', onDisconnect.bind(undefined, { + anyProcess, + channel, + isSubprocess, + ipcEmitter, + boundOnMessage, + })); + undoAddedReferences(channel, isSubprocess); +}; + +// Check whether there might still be some `message` events to receive +export const isConnected = anyProcess => { + const ipcEmitter = IPC_EMITTERS.get(anyProcess); + return ipcEmitter === undefined + ? anyProcess.channel !== null + : ipcEmitter.connected; +}; diff --git a/node_modules/execa/lib/ipc/get-each.js b/node_modules/execa/lib/ipc/get-each.js new file mode 100644 index 0000000000..f134fc12cd --- /dev/null +++ b/node_modules/execa/lib/ipc/get-each.js @@ -0,0 +1,89 @@ +import {once, on} from 'node:events'; +import {validateIpcMethod, disconnect, getStrictResponseError} from './validation.js'; +import {getIpcEmitter, isConnected} from './forward.js'; +import {addReference, removeReference} from './reference.js'; + +// Like `[sub]process.on('message')` but promise-based +export const getEachMessage = ({anyProcess, channel, isSubprocess, ipc}, {reference = true} = {}) => loopOnMessages({ + anyProcess, + channel, + isSubprocess, + ipc, + shouldAwait: !isSubprocess, + reference, +}); + +// Same but used internally +export const loopOnMessages = ({anyProcess, channel, isSubprocess, ipc, shouldAwait, reference}) => { + validateIpcMethod({ + methodName: 'getEachMessage', + isSubprocess, + ipc, + isConnected: isConnected(anyProcess), + }); + + addReference(channel, reference); + const ipcEmitter = getIpcEmitter(anyProcess, channel, isSubprocess); + const controller = new AbortController(); + const state = {}; + stopOnDisconnect(anyProcess, ipcEmitter, controller); + abortOnStrictError({ + ipcEmitter, + isSubprocess, + controller, + state, + }); + return iterateOnMessages({ + anyProcess, + channel, + ipcEmitter, + isSubprocess, + shouldAwait, + controller, + state, + reference, + }); +}; + +const stopOnDisconnect = async (anyProcess, ipcEmitter, controller) => { + try { + await once(ipcEmitter, 'disconnect', {signal: controller.signal}); + controller.abort(); + } catch {} +}; + +const abortOnStrictError = async ({ipcEmitter, isSubprocess, controller, state}) => { + try { + const [error] = await once(ipcEmitter, 'strict:error', {signal: controller.signal}); + state.error = getStrictResponseError(error, isSubprocess); + controller.abort(); + } catch {} +}; + +const iterateOnMessages = async function * ({anyProcess, channel, ipcEmitter, isSubprocess, shouldAwait, controller, state, reference}) { + try { + for await (const [message] of on(ipcEmitter, 'message', {signal: controller.signal})) { + throwIfStrictError(state); + yield message; + } + } catch { + throwIfStrictError(state); + } finally { + controller.abort(); + removeReference(channel, reference); + + if (!isSubprocess) { + disconnect(anyProcess); + } + + if (shouldAwait) { + await anyProcess; + } + } +}; + +const throwIfStrictError = ({error}) => { + if (error) { + throw error; + } +}; diff --git a/node_modules/execa/lib/ipc/get-one.js b/node_modules/execa/lib/ipc/get-one.js new file mode 100644 index 0000000000..976a8fe191 --- /dev/null +++ b/node_modules/execa/lib/ipc/get-one.js @@ -0,0 +1,69 @@ +import {once, on} from 'node:events'; +import { + validateIpcMethod, + throwOnEarlyDisconnect, + disconnect, + getStrictResponseError, +} from './validation.js'; +import {getIpcEmitter, isConnected} from './forward.js'; +import {addReference, removeReference} from './reference.js'; + +// Like `[sub]process.once('message')` but promise-based +export const getOneMessage = ({anyProcess, channel, isSubprocess, ipc}, {reference = true, filter} = {}) => { + validateIpcMethod({ + methodName: 'getOneMessage', + isSubprocess, + ipc, + isConnected: isConnected(anyProcess), + }); + + return getOneMessageAsync({ + anyProcess, + channel, + isSubprocess, + filter, + reference, + }); +}; + +const getOneMessageAsync = async ({anyProcess, channel, isSubprocess, filter, reference}) => { + addReference(channel, reference); + const ipcEmitter = getIpcEmitter(anyProcess, channel, isSubprocess); + const controller = new AbortController(); + try { + return await Promise.race([ + getMessage(ipcEmitter, filter, controller), + throwOnDisconnect(ipcEmitter, isSubprocess, controller), + throwOnStrictError(ipcEmitter, isSubprocess, controller), + ]); + } catch (error) { + disconnect(anyProcess); + throw error; + } finally { + controller.abort(); + removeReference(channel, reference); + } +}; + +const getMessage = async (ipcEmitter, filter, {signal}) => { + if (filter === undefined) { + const [message] = await once(ipcEmitter, 'message', {signal}); + return message; + } + + for await (const [message] of on(ipcEmitter, 'message', {signal})) { + if (filter(message)) { + return message; + } + } +}; + +const throwOnDisconnect = async (ipcEmitter, isSubprocess, {signal}) => { + await once(ipcEmitter, 'disconnect', {signal}); + throwOnEarlyDisconnect(isSubprocess); +}; + +const throwOnStrictError = async (ipcEmitter, isSubprocess, {signal}) => { + const [error] = await once(ipcEmitter, 'strict:error', {signal}); + throw getStrictResponseError(error, isSubprocess); +}; diff --git a/node_modules/execa/lib/ipc/graceful.js b/node_modules/execa/lib/ipc/graceful.js new file mode 100644 index 0000000000..7931ecacaa --- /dev/null +++ b/node_modules/execa/lib/ipc/graceful.js @@ -0,0 +1,72 @@ +import {scheduler} from 'node:timers/promises'; +import {sendOneMessage} from './send.js'; +import {getIpcEmitter} from './forward.js'; +import {validateConnection, getAbortDisconnectError, throwOnMissingParent} from './validation.js'; + +// Send an IPC message so the subprocess performs a graceful termination +export const sendAbort = (subprocess, message) => { + const methodName = 'cancelSignal'; + validateConnection(methodName, false, subprocess.connected); + return sendOneMessage({ + anyProcess: subprocess, + methodName, + isSubprocess: false, + wrappedMessage: {type: GRACEFUL_CANCEL_TYPE, message}, + message, + }); +}; + +// When the signal is being used, start listening for incoming messages. +// Unbuffering messages takes one microtask to complete, so this must be async. +export const getCancelSignal = async ({anyProcess, channel, isSubprocess, ipc}) => { + await startIpc({ + anyProcess, + channel, + isSubprocess, + ipc, + }); + return cancelController.signal; +}; + +const startIpc = async ({anyProcess, channel, isSubprocess, ipc}) => { + if (cancelListening) { + return; + } + + cancelListening = true; + + if (!ipc) { + throwOnMissingParent(); + return; + } + + if (channel === null) { + abortOnDisconnect(); + return; + } + + getIpcEmitter(anyProcess, channel, isSubprocess); + await scheduler.yield(); +}; + +let cancelListening = false; + +// Reception of IPC message to perform a graceful termination +export const handleAbort = wrappedMessage => { + if (wrappedMessage?.type !== GRACEFUL_CANCEL_TYPE) { + return false; + } + + cancelController.abort(wrappedMessage.message); + return true; +}; + +const GRACEFUL_CANCEL_TYPE = 'execa:ipc:cancel'; + +// When the current process disconnects early, the subprocess `cancelSignal` is aborted. +// Otherwise, the signal would never be able to be aborted later on. +export const abortOnDisconnect = () => { + cancelController.abort(getAbortDisconnectError()); +}; + +const cancelController = new AbortController(); diff --git a/node_modules/execa/lib/ipc/incoming.js b/node_modules/execa/lib/ipc/incoming.js new file mode 100644 index 0000000000..56749f6483 --- /dev/null +++ b/node_modules/execa/lib/ipc/incoming.js @@ -0,0 +1,79 @@ +import {once} from 'node:events'; +import {scheduler} from 'node:timers/promises'; +import {waitForOutgoingMessages} from './outgoing.js'; +import {redoAddedReferences} from './reference.js'; +import {handleStrictRequest, handleStrictResponse} from './strict.js'; +import {handleAbort, abortOnDisconnect} from './graceful.js'; + +// By default, Node.js buffers `message` events. +// - Buffering happens when there is a `message` event is emitted but there is no handler. +// - As soon as a `message` event handler is set, all buffered `message` events are emitted, emptying the buffer. +// - This happens both in the current process and the subprocess. +// - See https://github.com/nodejs/node/blob/501546e8f37059cd577041e23941b640d0d4d406/lib/internal/child_process.js#L719 +// This is helpful. Notably, this allows sending messages to a subprocess that's still initializing. +// However, it has several problems. +// - This works with `events.on()` but not `events.once()` since all buffered messages are emitted at once. +// For example, users cannot call `await getOneMessage()`/`getEachMessage()` multiple times in a row. +// - When a user intentionally starts listening to `message` at a specific point in time, past `message` events are replayed, which might be unexpected. +// - Buffering is unlimited, which might lead to an out-of-memory crash. +// - This does not work well with multiple consumers. +// For example, Execa consumes events with both `result.ipcOutput` and manual IPC calls like `getOneMessage()`. +// Since `result.ipcOutput` reads all incoming messages, no buffering happens for manual IPC calls. +// - Forgetting to setup a `message` listener, or setting it up too late, is a programming mistake. +// The default behavior does not allow users to realize they made that mistake. +// To solve those problems, instead of buffering messages, we debounce them. +// The `message` event so it is emitted at most once per macrotask. +export const onMessage = async ({anyProcess, channel, isSubprocess, ipcEmitter}, wrappedMessage) => { + if (handleStrictResponse(wrappedMessage) || handleAbort(wrappedMessage)) { + return; + } + + if (!INCOMING_MESSAGES.has(anyProcess)) { + INCOMING_MESSAGES.set(anyProcess, []); + } + + const incomingMessages = INCOMING_MESSAGES.get(anyProcess); + incomingMessages.push(wrappedMessage); + + if (incomingMessages.length > 1) { + return; + } + + while (incomingMessages.length > 0) { + // eslint-disable-next-line no-await-in-loop + await waitForOutgoingMessages(anyProcess, ipcEmitter, wrappedMessage); + // eslint-disable-next-line no-await-in-loop + await scheduler.yield(); + + // eslint-disable-next-line no-await-in-loop + const message = await handleStrictRequest({ + wrappedMessage: incomingMessages[0], + anyProcess, + channel, + isSubprocess, + ipcEmitter, + }); + + incomingMessages.shift(); + ipcEmitter.emit('message', message); + ipcEmitter.emit('message:done'); + } +}; + +// If the `message` event is currently debounced, the `disconnect` event must wait for it +export const onDisconnect = async ({anyProcess, channel, isSubprocess, ipcEmitter, boundOnMessage}) => { + abortOnDisconnect(); + + const incomingMessages = INCOMING_MESSAGES.get(anyProcess); + while (incomingMessages?.length > 0) { + // eslint-disable-next-line no-await-in-loop + await once(ipcEmitter, 'message:done'); + } + + anyProcess.removeListener('message', boundOnMessage); + redoAddedReferences(channel, isSubprocess); + ipcEmitter.connected = false; + ipcEmitter.emit('disconnect'); +}; + +const INCOMING_MESSAGES = new WeakMap(); diff --git a/node_modules/execa/lib/ipc/ipc-input.js b/node_modules/execa/lib/ipc/ipc-input.js new file mode 100644 index 0000000000..908f2ace1c --- /dev/null +++ b/node_modules/execa/lib/ipc/ipc-input.js @@ -0,0 +1,44 @@ +import {serialize} from 'node:v8'; + +// Validate the `ipcInput` option +export const validateIpcInputOption = ({ipcInput, ipc, serialization}) => { + if (ipcInput === undefined) { + return; + } + + if (!ipc) { + throw new Error('The `ipcInput` option cannot be set unless the `ipc` option is `true`.'); + } + + validateIpcInput[serialization](ipcInput); +}; + +const validateAdvancedInput = ipcInput => { + try { + serialize(ipcInput); + } catch (error) { + throw new Error('The `ipcInput` option is not serializable with a structured clone.', {cause: error}); + } +}; + +const validateJsonInput = ipcInput => { + try { + JSON.stringify(ipcInput); + } catch (error) { + throw new Error('The `ipcInput` option is not serializable with JSON.', {cause: error}); + } +}; + +const validateIpcInput = { + advanced: validateAdvancedInput, + json: validateJsonInput, +}; + +// When the `ipcInput` option is set, it is sent as an initial IPC message to the subprocess +export const sendIpcInput = async (subprocess, ipcInput) => { + if (ipcInput === undefined) { + return; + } + + await subprocess.sendMessage(ipcInput); +}; diff --git a/node_modules/execa/lib/ipc/methods.js b/node_modules/execa/lib/ipc/methods.js new file mode 100644 index 0000000000..c1963bd864 --- /dev/null +++ b/node_modules/execa/lib/ipc/methods.js @@ -0,0 +1,49 @@ +import process from 'node:process'; +import {sendMessage} from './send.js'; +import {getOneMessage} from './get-one.js'; +import {getEachMessage} from './get-each.js'; +import {getCancelSignal} from './graceful.js'; + +// Add promise-based IPC methods in current process +export const addIpcMethods = (subprocess, {ipc}) => { + Object.assign(subprocess, getIpcMethods(subprocess, false, ipc)); +}; + +// Get promise-based IPC in the subprocess +export const getIpcExport = () => { + const anyProcess = process; + const isSubprocess = true; + const ipc = process.channel !== undefined; + + return { + ...getIpcMethods(anyProcess, isSubprocess, ipc), + getCancelSignal: getCancelSignal.bind(undefined, { + anyProcess, + channel: anyProcess.channel, + isSubprocess, + ipc, + }), + }; +}; + +// Retrieve the `ipc` shared by both the current process and the subprocess +const getIpcMethods = (anyProcess, isSubprocess, ipc) => ({ + sendMessage: sendMessage.bind(undefined, { + anyProcess, + channel: anyProcess.channel, + isSubprocess, + ipc, + }), + getOneMessage: getOneMessage.bind(undefined, { + anyProcess, + channel: anyProcess.channel, + isSubprocess, + ipc, + }), + getEachMessage: getEachMessage.bind(undefined, { + anyProcess, + channel: anyProcess.channel, + isSubprocess, + ipc, + }), +}); diff --git a/node_modules/execa/lib/ipc/outgoing.js b/node_modules/execa/lib/ipc/outgoing.js new file mode 100644 index 0000000000..904f67dd73 --- /dev/null +++ b/node_modules/execa/lib/ipc/outgoing.js @@ -0,0 +1,47 @@ +import {createDeferred} from '../utils/deferred.js'; +import {getFdSpecificValue} from '../arguments/specific.js'; +import {SUBPROCESS_OPTIONS} from '../arguments/fd-options.js'; +import {validateStrictDeadlock} from './strict.js'; + +// When `sendMessage()` is ongoing, any `message` being received waits before being emitted. +// This allows calling one or multiple `await sendMessage()` followed by `await getOneMessage()`/`await getEachMessage()`. +// Without running into a race condition when the other process sends a response too fast, before the current process set up a listener. +export const startSendMessage = (anyProcess, wrappedMessage, strict) => { + if (!OUTGOING_MESSAGES.has(anyProcess)) { + OUTGOING_MESSAGES.set(anyProcess, new Set()); + } + + const outgoingMessages = OUTGOING_MESSAGES.get(anyProcess); + const onMessageSent = createDeferred(); + const id = strict ? wrappedMessage.id : undefined; + const outgoingMessage = {onMessageSent, id}; + outgoingMessages.add(outgoingMessage); + return {outgoingMessages, outgoingMessage}; +}; + +export const endSendMessage = ({outgoingMessages, outgoingMessage}) => { + outgoingMessages.delete(outgoingMessage); + outgoingMessage.onMessageSent.resolve(); +}; + +// Await while `sendMessage()` is ongoing, unless there is already a `message` listener +export const waitForOutgoingMessages = async (anyProcess, ipcEmitter, wrappedMessage) => { + while (!hasMessageListeners(anyProcess, ipcEmitter) && OUTGOING_MESSAGES.get(anyProcess)?.size > 0) { + const outgoingMessages = [...OUTGOING_MESSAGES.get(anyProcess)]; + validateStrictDeadlock(outgoingMessages, wrappedMessage); + // eslint-disable-next-line no-await-in-loop + await Promise.all(outgoingMessages.map(({onMessageSent}) => onMessageSent)); + } +}; + +const OUTGOING_MESSAGES = new WeakMap(); + +// Whether any `message` listener is setup +export const hasMessageListeners = (anyProcess, ipcEmitter) => ipcEmitter.listenerCount('message') > getMinListenerCount(anyProcess); + +// When `buffer` is `false`, we set up a `message` listener that should be ignored. +// That listener is only meant to intercept `strict` acknowledgement responses. +const getMinListenerCount = anyProcess => SUBPROCESS_OPTIONS.has(anyProcess) + && !getFdSpecificValue(SUBPROCESS_OPTIONS.get(anyProcess).options.buffer, 'ipc') + ? 1 + : 0; diff --git a/node_modules/execa/lib/ipc/reference.js b/node_modules/execa/lib/ipc/reference.js new file mode 100644 index 0000000000..25eec52768 --- /dev/null +++ b/node_modules/execa/lib/ipc/reference.js @@ -0,0 +1,44 @@ +// By default, Node.js keeps the subprocess alive while it has a `message` or `disconnect` listener. +// We replicate the same logic for the events that we proxy. +// This ensures the subprocess is kept alive while `getOneMessage()` and `getEachMessage()` are ongoing. +// This is not a problem with `sendMessage()` since Node.js handles that method automatically. +// We do not use `anyProcess.channel.ref()` since this would prevent the automatic `.channel.refCounted()` Node.js is doing. +// We keep a reference to `anyProcess.channel` since it might be `null` while `getOneMessage()` or `getEachMessage()` is still processing debounced messages. +// See https://github.com/nodejs/node/blob/2aaeaa863c35befa2ebaa98fb7737ec84df4d8e9/lib/internal/child_process.js#L547 +export const addReference = (channel, reference) => { + if (reference) { + addReferenceCount(channel); + } +}; + +const addReferenceCount = channel => { + channel.refCounted(); +}; + +export const removeReference = (channel, reference) => { + if (reference) { + removeReferenceCount(channel); + } +}; + +const removeReferenceCount = channel => { + channel.unrefCounted(); +}; + +// To proxy events, we setup some global listeners on the `message` and `disconnect` events. +// Those should not keep the subprocess alive, so we remove the automatic counting that Node.js is doing. +// See https://github.com/nodejs/node/blob/1b965270a9c273d4cf70e8808e9d28b9ada7844f/lib/child_process.js#L180 +export const undoAddedReferences = (channel, isSubprocess) => { + if (isSubprocess) { + removeReferenceCount(channel); + removeReferenceCount(channel); + } +}; + +// Reverse it during `disconnect` +export const redoAddedReferences = (channel, isSubprocess) => { + if (isSubprocess) { + addReferenceCount(channel); + addReferenceCount(channel); + } +}; diff --git a/node_modules/execa/lib/ipc/send.js b/node_modules/execa/lib/ipc/send.js new file mode 100644 index 0000000000..2c885a14d6 --- /dev/null +++ b/node_modules/execa/lib/ipc/send.js @@ -0,0 +1,91 @@ +import {promisify} from 'node:util'; +import { + validateIpcMethod, + handleEpipeError, + handleSerializationError, + disconnect, +} from './validation.js'; +import {startSendMessage, endSendMessage} from './outgoing.js'; +import {handleSendStrict, waitForStrictResponse} from './strict.js'; + +// Like `[sub]process.send()` but promise-based. +// We do not `await subprocess` during `.sendMessage()` nor `.getOneMessage()` since those methods are transient. +// Users would still need to `await subprocess` after the method is done. +// Also, this would prevent `unhandledRejection` event from being emitted, making it silent. +export const sendMessage = ({anyProcess, channel, isSubprocess, ipc}, message, {strict = false} = {}) => { + const methodName = 'sendMessage'; + validateIpcMethod({ + methodName, + isSubprocess, + ipc, + isConnected: anyProcess.connected, + }); + + return sendMessageAsync({ + anyProcess, + channel, + methodName, + isSubprocess, + message, + strict, + }); +}; + +const sendMessageAsync = async ({anyProcess, channel, methodName, isSubprocess, message, strict}) => { + const wrappedMessage = handleSendStrict({ + anyProcess, + channel, + isSubprocess, + message, + strict, + }); + const outgoingMessagesState = startSendMessage(anyProcess, wrappedMessage, strict); + try { + await sendOneMessage({ + anyProcess, + methodName, + isSubprocess, + wrappedMessage, + message, + }); + } catch (error) { + disconnect(anyProcess); + throw error; + } finally { + endSendMessage(outgoingMessagesState); + } +}; + +// Used internally by `cancelSignal` +export const sendOneMessage = async ({anyProcess, methodName, isSubprocess, wrappedMessage, message}) => { + const sendMethod = getSendMethod(anyProcess); + + try { + await Promise.all([ + waitForStrictResponse(wrappedMessage, anyProcess, isSubprocess), + sendMethod(wrappedMessage), + ]); + } catch (error) { + handleEpipeError({error, methodName, isSubprocess}); + handleSerializationError({ + error, + methodName, + isSubprocess, + message, + }); + throw error; + } +}; + +// [sub]process.send() promisified, memoized +const getSendMethod = anyProcess => { + if (PROCESS_SEND_METHODS.has(anyProcess)) { + return PROCESS_SEND_METHODS.get(anyProcess); + } + + const sendMethod = promisify(anyProcess.send.bind(anyProcess)); + PROCESS_SEND_METHODS.set(anyProcess, sendMethod); + return sendMethod; +}; + +const PROCESS_SEND_METHODS = new WeakMap(); diff --git a/node_modules/execa/lib/ipc/strict.js b/node_modules/execa/lib/ipc/strict.js new file mode 100644 index 0000000000..6ff2be26d3 --- /dev/null +++ b/node_modules/execa/lib/ipc/strict.js @@ -0,0 +1,113 @@ +import {once} from 'node:events'; +import {createDeferred} from '../utils/deferred.js'; +import {incrementMaxListeners} from '../utils/max-listeners.js'; +import {sendMessage} from './send.js'; +import {throwOnMissingStrict, throwOnStrictDisconnect, throwOnStrictDeadlockError} from './validation.js'; +import {getIpcEmitter} from './forward.js'; +import {hasMessageListeners} from './outgoing.js'; + +// When using the `strict` option, wrap the message with metadata during `sendMessage()` +export const handleSendStrict = ({anyProcess, channel, isSubprocess, message, strict}) => { + if (!strict) { + return message; + } + + const ipcEmitter = getIpcEmitter(anyProcess, channel, isSubprocess); + const hasListeners = hasMessageListeners(anyProcess, ipcEmitter); + return { + id: count++, + type: REQUEST_TYPE, + message, + hasListeners, + }; +}; + +let count = 0n; + +// Handles when both processes are calling `sendMessage()` with `strict` at the same time. +// If neither process is listening, this would create a deadlock. We detect it and throw. +export const validateStrictDeadlock = (outgoingMessages, wrappedMessage) => { + if (wrappedMessage?.type !== REQUEST_TYPE || wrappedMessage.hasListeners) { + return; + } + + for (const {id} of outgoingMessages) { + if (id !== undefined) { + STRICT_RESPONSES[id].resolve({isDeadlock: true, hasListeners: false}); + } + } +}; + +// The other process then sends the acknowledgment back as a response +export const handleStrictRequest = async ({wrappedMessage, anyProcess, channel, isSubprocess, ipcEmitter}) => { + if (wrappedMessage?.type !== REQUEST_TYPE || !anyProcess.connected) { + return wrappedMessage; + } + + const {id, message} = wrappedMessage; + const response = {id, type: RESPONSE_TYPE, message: hasMessageListeners(anyProcess, ipcEmitter)}; + + try { + await sendMessage({ + anyProcess, + channel, + isSubprocess, + ipc: true, + }, response); + } catch (error) { + ipcEmitter.emit('strict:error', error); + } + + return message; +}; + +// Reception of the acknowledgment response +export const handleStrictResponse = wrappedMessage => { + if (wrappedMessage?.type !== RESPONSE_TYPE) { + return false; + } + + const {id, message: hasListeners} = wrappedMessage; + STRICT_RESPONSES[id]?.resolve({isDeadlock: false, hasListeners}); + return true; +}; + +// Wait for the other process to receive the message from `sendMessage()` +export const waitForStrictResponse = async (wrappedMessage, anyProcess, isSubprocess) => { + if (wrappedMessage?.type !== REQUEST_TYPE) { + return; + } + + const deferred = createDeferred(); + STRICT_RESPONSES[wrappedMessage.id] = deferred; + const controller = new AbortController(); + + try { + const {isDeadlock, hasListeners} = await Promise.race([ + deferred, + throwOnDisconnect(anyProcess, isSubprocess, controller), + ]); + + if (isDeadlock) { + throwOnStrictDeadlockError(isSubprocess); + } + + if (!hasListeners) { + throwOnMissingStrict(isSubprocess); + } + } finally { + controller.abort(); + delete STRICT_RESPONSES[wrappedMessage.id]; + } +}; + +const STRICT_RESPONSES = {}; + +const throwOnDisconnect = async (anyProcess, isSubprocess, {signal}) => { + incrementMaxListeners(anyProcess, 1, signal); + await once(anyProcess, 'disconnect', {signal}); + throwOnStrictDisconnect(isSubprocess); +}; + +const REQUEST_TYPE = 'execa:ipc:request'; +const RESPONSE_TYPE = 'execa:ipc:response'; diff --git a/node_modules/execa/lib/ipc/validation.js b/node_modules/execa/lib/ipc/validation.js new file mode 100644 index 0000000000..4b5d7605d6 --- /dev/null +++ b/node_modules/execa/lib/ipc/validation.js @@ -0,0 +1,111 @@ +// Validate the IPC channel is connected before receiving/sending messages +export const validateIpcMethod = ({methodName, isSubprocess, ipc, isConnected}) => { + validateIpcOption(methodName, isSubprocess, ipc); + validateConnection(methodName, isSubprocess, isConnected); +}; + +// Better error message when forgetting to set `ipc: true` and using the IPC methods +const validateIpcOption = (methodName, isSubprocess, ipc) => { + if (!ipc) { + throw new Error(`${getMethodName(methodName, isSubprocess)} can only be used if the \`ipc\` option is \`true\`.`); + } +}; + +// Better error message when one process does not send/receive messages once the other process has disconnected. +// This also makes it clear that any buffered messages are lost once either process has disconnected. +// Also when aborting `cancelSignal` after disconnecting the IPC. +export const validateConnection = (methodName, isSubprocess, isConnected) => { + if (!isConnected) { + throw new Error(`${getMethodName(methodName, isSubprocess)} cannot be used: the ${getOtherProcessName(isSubprocess)} has already exited or disconnected.`); + } +}; + +// When `getOneMessage()` could not complete due to an early disconnection +export const throwOnEarlyDisconnect = isSubprocess => { + throw new Error(`${getMethodName('getOneMessage', isSubprocess)} could not complete: the ${getOtherProcessName(isSubprocess)} exited or disconnected.`); +}; + +// When both processes use `sendMessage()` with `strict` at the same time +export const throwOnStrictDeadlockError = isSubprocess => { + throw new Error(`${getMethodName('sendMessage', isSubprocess)} failed: the ${getOtherProcessName(isSubprocess)} is sending a message too, instead of listening to incoming messages. +This can be fixed by both sending a message and listening to incoming messages at the same time: + +const [receivedMessage] = await Promise.all([ + ${getMethodName('getOneMessage', isSubprocess)}, + ${getMethodName('sendMessage', isSubprocess, 'message, {strict: true}')}, +]);`); +}; + +// When the other process used `strict` but the current process had I/O error calling `sendMessage()` for the response +export const getStrictResponseError = (error, isSubprocess) => new Error(`${getMethodName('sendMessage', isSubprocess)} failed when sending an acknowledgment response to the ${getOtherProcessName(isSubprocess)}.`, {cause: error}); + +// When using `strict` but the other process was not listening for messages +export const throwOnMissingStrict = isSubprocess => { + throw new Error(`${getMethodName('sendMessage', isSubprocess)} failed: the ${getOtherProcessName(isSubprocess)} is not listening to incoming messages.`); +}; + +// When using `strict` but the other process disconnected before receiving the message +export const throwOnStrictDisconnect = isSubprocess => { + throw new Error(`${getMethodName('sendMessage', isSubprocess)} failed: the ${getOtherProcessName(isSubprocess)} exited without listening to incoming messages.`); +}; + +// When the current process disconnects while the subprocess is listening to `cancelSignal` +export const getAbortDisconnectError = () => new Error(`\`cancelSignal\` aborted: the ${getOtherProcessName(true)} disconnected.`); + +// When the subprocess uses `cancelSignal` but not the current process +export const throwOnMissingParent = () => { + throw new Error('`getCancelSignal()` cannot be used without setting the `cancelSignal` subprocess option.'); +}; + +// EPIPE can happen when sending a message to a subprocess that is closing but has not disconnected yet +export const handleEpipeError = ({error, methodName, isSubprocess}) => { + if (error.code === 'EPIPE') { + throw new Error(`${getMethodName(methodName, isSubprocess)} cannot be used: the ${getOtherProcessName(isSubprocess)} is disconnecting.`, {cause: error}); + } +}; + +// Better error message when sending messages which cannot be serialized. +// Works with both `serialization: 'advanced'` and `serialization: 'json'`. +export const handleSerializationError = ({error, methodName, isSubprocess, message}) => { + if (isSerializationError(error)) { + throw new Error(`${getMethodName(methodName, isSubprocess)}'s argument type is invalid: the message cannot be serialized: ${String(message)}.`, {cause: error}); + } +}; + +const isSerializationError = ({code, message}) => SERIALIZATION_ERROR_CODES.has(code) + || SERIALIZATION_ERROR_MESSAGES.some(serializationErrorMessage => message.includes(serializationErrorMessage)); + +// `error.code` set by Node.js when it failed to serialize the message +const SERIALIZATION_ERROR_CODES = new Set([ + // Message is `undefined` + 'ERR_MISSING_ARGS', + // Message is a function, a bigint, a symbol + 'ERR_INVALID_ARG_TYPE', +]); + +// `error.message` set by Node.js when it failed to serialize the message +const SERIALIZATION_ERROR_MESSAGES = [ + // Message is a promise or a proxy, with `serialization: 'advanced'` + 'could not be cloned', + // Message has cycles, with `serialization: 'json'` + 'circular structure', + // Message has cycles inside toJSON(), with `serialization: 'json'` + 'call stack size exceeded', +]; + +const getMethodName = (methodName, isSubprocess, parameters = '') => methodName === 'cancelSignal' + ? '`cancelSignal`\'s `controller.abort()`' + : `${getNamespaceName(isSubprocess)}${methodName}(${parameters})`; + +const getNamespaceName = isSubprocess => isSubprocess ? '' : 'subprocess.'; + +const getOtherProcessName = isSubprocess => isSubprocess ? 'parent process' : 'subprocess'; + +// When any error arises, we disconnect the IPC. +// Otherwise, it is likely that one of the processes will stop sending/receiving messages. +// This would leave the other process hanging. +export const disconnect = anyProcess => { + if (anyProcess.connected) { + anyProcess.disconnect(); + } +}; diff --git a/node_modules/execa/lib/kill.js b/node_modules/execa/lib/kill.js deleted file mode 100644 index efc6b9ba41..0000000000 --- a/node_modules/execa/lib/kill.js +++ /dev/null @@ -1,102 +0,0 @@ -import os from 'node:os'; -import onExit from 'signal-exit'; - -const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; - -// Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior -export const spawnedKill = (kill, signal = 'SIGTERM', options = {}) => { - const killResult = kill(signal); - setKillTimeout(kill, signal, options, killResult); - return killResult; -}; - -const setKillTimeout = (kill, signal, options, killResult) => { - if (!shouldForceKill(signal, options, killResult)) { - return; - } - - const timeout = getForceKillAfterTimeout(options); - const t = setTimeout(() => { - kill('SIGKILL'); - }, timeout); - - // Guarded because there's no `.unref()` when `execa` is used in the renderer - // process in Electron. This cannot be tested since we don't run tests in - // Electron. - // istanbul ignore else - if (t.unref) { - t.unref(); - } -}; - -const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => isSigterm(signal) && forceKillAfterTimeout !== false && killResult; - -const isSigterm = signal => signal === os.constants.signals.SIGTERM - || (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM'); - -const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { - if (forceKillAfterTimeout === true) { - return DEFAULT_FORCE_KILL_TIMEOUT; - } - - if (!Number.isFinite(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { - throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); - } - - return forceKillAfterTimeout; -}; - -// `childProcess.cancel()` -export const spawnedCancel = (spawned, context) => { - const killResult = spawned.kill(); - - if (killResult) { - context.isCanceled = true; - } -}; - -const timeoutKill = (spawned, signal, reject) => { - spawned.kill(signal); - reject(Object.assign(new Error('Timed out'), {timedOut: true, signal})); -}; - -// `timeout` option handling -export const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => { - if (timeout === 0 || timeout === undefined) { - return spawnedPromise; - } - - let timeoutId; - const timeoutPromise = new Promise((resolve, reject) => { - timeoutId = setTimeout(() => { - timeoutKill(spawned, killSignal, reject); - }, timeout); - }); - - const safeSpawnedPromise = spawnedPromise.finally(() => { - clearTimeout(timeoutId); - }); - - return Promise.race([timeoutPromise, safeSpawnedPromise]); -}; - -export const validateTimeout = ({timeout}) => { - if (timeout !== undefined && (!Number.isFinite(timeout) || timeout < 0)) { - throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); - } -}; - -// `cleanup` option handling -export const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => { - if (!cleanup || detached) { - return timedPromise; - } - - const removeExitHandler = onExit(() => { - spawned.kill(); - }); - - return timedPromise.finally(() => { - removeExitHandler(); - }); -}; diff --git a/node_modules/execa/lib/methods/bind.js b/node_modules/execa/lib/methods/bind.js new file mode 100644 index 0000000000..d5fae18c20 --- /dev/null +++ b/node_modules/execa/lib/methods/bind.js @@ -0,0 +1,23 @@ +import isPlainObject from 'is-plain-obj'; +import {FD_SPECIFIC_OPTIONS} from '../arguments/specific.js'; + +// Deep merge specific options like `env`. Shallow merge the other ones. +export const mergeOptions = (boundOptions, options) => { + const newOptions = Object.fromEntries( + Object.entries(options).map(([optionName, optionValue]) => [ + optionName, + mergeOption(optionName, boundOptions[optionName], optionValue), + ]), + ); + return {...boundOptions, ...newOptions}; +}; + +const mergeOption = (optionName, boundOptionValue, optionValue) => { + if (DEEP_OPTIONS.has(optionName) && isPlainObject(boundOptionValue) && isPlainObject(optionValue)) { + return {...boundOptionValue, ...optionValue}; + } + + return optionValue; +}; + +const DEEP_OPTIONS = new Set(['env', ...FD_SPECIFIC_OPTIONS]); diff --git a/node_modules/execa/lib/methods/command.js b/node_modules/execa/lib/methods/command.js new file mode 100644 index 0000000000..add23b29dc --- /dev/null +++ b/node_modules/execa/lib/methods/command.js @@ -0,0 +1,43 @@ +// Main logic for `execaCommand()` +export const mapCommandAsync = ({file, commandArguments}) => parseCommand(file, commandArguments); + +// Main logic for `execaCommandSync()` +export const mapCommandSync = ({file, commandArguments}) => ({...parseCommand(file, commandArguments), isSync: true}); + +// Convert `execaCommand(command)` into `execa(file, ...commandArguments)` +const parseCommand = (command, unusedArguments) => { + if (unusedArguments.length > 0) { + throw new TypeError(`The command and its arguments must be passed as a single string: ${command} ${unusedArguments}.`); + } + + const [file, ...commandArguments] = parseCommandString(command); + return {file, commandArguments}; +}; + +// Convert `command` string into an array of file or arguments to pass to $`${...fileOrCommandArguments}` +export const parseCommandString = command => { + if (typeof command !== 'string') { + throw new TypeError(`The command must be a string: ${String(command)}.`); + } + + const trimmedCommand = command.trim(); + if (trimmedCommand === '') { + return []; + } + + const tokens = []; + for (const token of trimmedCommand.split(SPACES_REGEXP)) { + // Allow spaces to be escaped by a backslash if not meant as a delimiter + const previousToken = tokens.at(-1); + if (previousToken && previousToken.endsWith('\\')) { + // Merge previous token with current one + tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`; + } else { + tokens.push(token); + } + } + + return tokens; +}; + +const SPACES_REGEXP = / +/g; diff --git a/node_modules/execa/lib/methods/create.js b/node_modules/execa/lib/methods/create.js new file mode 100644 index 0000000000..d59fe0da22 --- /dev/null +++ b/node_modules/execa/lib/methods/create.js @@ -0,0 +1,65 @@ +import isPlainObject from 'is-plain-obj'; +import {normalizeParameters} from './parameters.js'; +import {isTemplateString, parseTemplates} from './template.js'; +import {execaCoreSync} from './main-sync.js'; +import {execaCoreAsync} from './main-async.js'; +import {mergeOptions} from './bind.js'; + +// Wraps every exported methods to provide the following features: +// - template string syntax: execa`command argument` +// - options binding: boundExeca = execa(options) +// - optional argument/options: execa(file), execa(file, args), execa(file, options), execa(file, args, options) +// `mapArguments()` and `setBoundExeca()` allows for method-specific logic. +export const createExeca = (mapArguments, boundOptions, deepOptions, setBoundExeca) => { + const createNested = (mapArguments, boundOptions, setBoundExeca) => createExeca(mapArguments, boundOptions, deepOptions, setBoundExeca); + const boundExeca = (...execaArguments) => callBoundExeca({ + mapArguments, + deepOptions, + boundOptions, + setBoundExeca, + createNested, + }, ...execaArguments); + + if (setBoundExeca !== undefined) { + setBoundExeca(boundExeca, createNested, boundOptions); + } + + return boundExeca; +}; + +const callBoundExeca = ({mapArguments, deepOptions = {}, boundOptions = {}, setBoundExeca, createNested}, firstArgument, ...nextArguments) => { + if (isPlainObject(firstArgument)) { + return createNested(mapArguments, mergeOptions(boundOptions, firstArgument), setBoundExeca); + } + + const {file, commandArguments, options, isSync} = parseArguments({ + mapArguments, + firstArgument, + nextArguments, + deepOptions, + boundOptions, + }); + return isSync + ? execaCoreSync(file, commandArguments, options) + : execaCoreAsync(file, commandArguments, options, createNested); +}; + +const parseArguments = ({mapArguments, firstArgument, nextArguments, deepOptions, boundOptions}) => { + const callArguments = isTemplateString(firstArgument) + ? parseTemplates(firstArgument, nextArguments) + : [firstArgument, ...nextArguments]; + const [initialFile, initialArguments, initialOptions] = normalizeParameters(...callArguments); + const mergedOptions = mergeOptions(mergeOptions(deepOptions, boundOptions), initialOptions); + const { + file = initialFile, + commandArguments = initialArguments, + options = mergedOptions, + isSync = false, + } = mapArguments({file: initialFile, commandArguments: initialArguments, options: mergedOptions}); + return { + file, + commandArguments, + options, + isSync, + }; +}; diff --git a/node_modules/execa/lib/methods/main-async.js b/node_modules/execa/lib/methods/main-async.js new file mode 100644 index 0000000000..47d092ce55 --- /dev/null +++ b/node_modules/execa/lib/methods/main-async.js @@ -0,0 +1,194 @@ +import {setMaxListeners} from 'node:events'; +import {spawn} from 'node:child_process'; +import {MaxBufferError} from 'get-stream'; +import {handleCommand} from '../arguments/command.js'; +import {normalizeOptions} from '../arguments/options.js'; +import {SUBPROCESS_OPTIONS} from '../arguments/fd-options.js'; +import {concatenateShell} from '../arguments/shell.js'; +import {addIpcMethods} from '../ipc/methods.js'; +import {makeError, makeSuccessResult} from '../return/result.js'; +import {handleResult} from '../return/reject.js'; +import {handleEarlyError} from '../return/early-error.js'; +import {handleStdioAsync} from '../stdio/handle-async.js'; +import {stripNewline} from '../io/strip-newline.js'; +import {pipeOutputAsync} from '../io/output-async.js'; +import {subprocessKill} from '../terminate/kill.js'; +import {cleanupOnExit} from '../terminate/cleanup.js'; +import {pipeToSubprocess} from '../pipe/setup.js'; +import {makeAllStream} from '../resolve/all-async.js'; +import {waitForSubprocessResult} from '../resolve/wait-subprocess.js'; +import {addConvertedStreams} from '../convert/add.js'; +import {createDeferred} from '../utils/deferred.js'; +import {mergePromise} from './promise.js'; + +// Main shared logic for all async methods: `execa()`, `$`, `execaNode()` +export const execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => { + const {file, commandArguments, command, escapedCommand, startTime, verboseInfo, options, fileDescriptors} = handleAsyncArguments(rawFile, rawArguments, rawOptions); + const {subprocess, promise} = spawnSubprocessAsync({ + file, + commandArguments, + options, + startTime, + verboseInfo, + command, + escapedCommand, + fileDescriptors, + }); + subprocess.pipe = pipeToSubprocess.bind(undefined, { + source: subprocess, + sourcePromise: promise, + boundOptions: {}, + createNested, + }); + mergePromise(subprocess, promise); + SUBPROCESS_OPTIONS.set(subprocess, {options, fileDescriptors}); + return subprocess; +}; + +// Compute arguments to pass to `child_process.spawn()` +const handleAsyncArguments = (rawFile, rawArguments, rawOptions) => { + const {command, escapedCommand, startTime, verboseInfo} = handleCommand(rawFile, rawArguments, rawOptions); + const {file, commandArguments, options: normalizedOptions} = normalizeOptions(rawFile, rawArguments, rawOptions); + const options = handleAsyncOptions(normalizedOptions); + const fileDescriptors = handleStdioAsync(options, verboseInfo); + return { + file, + commandArguments, + command, + escapedCommand, + startTime, + verboseInfo, + options, + fileDescriptors, + }; +}; + +// Options normalization logic specific to async methods. +// Prevent passing the `timeout` option directly to `child_process.spawn()`. +const handleAsyncOptions = ({timeout, signal, ...options}) => { + if (signal !== undefined) { + throw new TypeError('The "signal" option has been renamed to "cancelSignal" instead.'); + } + + return {...options, timeoutDuration: timeout}; +}; + +const spawnSubprocessAsync = ({file, commandArguments, options, startTime, verboseInfo, command, escapedCommand, fileDescriptors}) => { + let subprocess; + try { + subprocess = spawn(...concatenateShell(file, commandArguments, options)); + } catch (error) { + return handleEarlyError({ + error, + command, + escapedCommand, + fileDescriptors, + options, + startTime, + verboseInfo, + }); + } + + const controller = new AbortController(); + setMaxListeners(Number.POSITIVE_INFINITY, controller.signal); + + const originalStreams = [...subprocess.stdio]; + pipeOutputAsync(subprocess, fileDescriptors, controller); + cleanupOnExit(subprocess, options, controller); + + const context = {}; + const onInternalError = createDeferred(); + subprocess.kill = subprocessKill.bind(undefined, { + kill: subprocess.kill.bind(subprocess), + options, + onInternalError, + context, + controller, + }); + subprocess.all = makeAllStream(subprocess, options); + addConvertedStreams(subprocess, options); + addIpcMethods(subprocess, options); + + const promise = handlePromise({ + subprocess, + options, + startTime, + verboseInfo, + fileDescriptors, + originalStreams, + command, + escapedCommand, + context, + onInternalError, + controller, + }); + return {subprocess, promise}; +}; + +// Asynchronous logic, as opposed to the previous logic which can be run synchronously, i.e. can be returned to user right away +const handlePromise = async ({subprocess, options, startTime, verboseInfo, fileDescriptors, originalStreams, command, escapedCommand, context, onInternalError, controller}) => { + const [ + errorInfo, + [exitCode, signal], + stdioResults, + allResult, + ipcOutput, + ] = await waitForSubprocessResult({ + subprocess, + options, + context, + verboseInfo, + fileDescriptors, + originalStreams, + onInternalError, + controller, + }); + controller.abort(); + onInternalError.resolve(); + + const stdio = stdioResults.map((stdioResult, fdNumber) => stripNewline(stdioResult, options, fdNumber)); + const all = stripNewline(allResult, options, 'all'); + const result = getAsyncResult({ + errorInfo, + exitCode, + signal, + stdio, + all, + ipcOutput, + context, + options, + command, + escapedCommand, + startTime, + }); + return handleResult(result, verboseInfo, options); +}; + +const getAsyncResult = ({errorInfo, exitCode, signal, stdio, all, ipcOutput, context, options, command, escapedCommand, startTime}) => 'error' in errorInfo + ? makeError({ + error: errorInfo.error, + command, + escapedCommand, + timedOut: context.terminationReason === 'timeout', + isCanceled: context.terminationReason === 'cancel' || context.terminationReason === 'gracefulCancel', + isGracefullyCanceled: context.terminationReason === 'gracefulCancel', + isMaxBuffer: errorInfo.error instanceof MaxBufferError, + isForcefullyTerminated: context.isForcefullyTerminated, + exitCode, + signal, + stdio, + all, + ipcOutput, + options, + startTime, + isSync: false, + }) + : makeSuccessResult({ + command, + escapedCommand, + stdio, + all, + ipcOutput, + options, + startTime, + }); diff --git a/node_modules/execa/lib/methods/main-sync.js b/node_modules/execa/lib/methods/main-sync.js new file mode 100644 index 0000000000..f294e9f0bd --- /dev/null +++ b/node_modules/execa/lib/methods/main-sync.js @@ -0,0 +1,163 @@ +import {spawnSync} from 'node:child_process'; +import {handleCommand} from '../arguments/command.js'; +import {normalizeOptions} from '../arguments/options.js'; +import {concatenateShell} from '../arguments/shell.js'; +import {makeError, makeEarlyError, makeSuccessResult} from '../return/result.js'; +import {handleResult} from '../return/reject.js'; +import {handleStdioSync} from '../stdio/handle-sync.js'; +import {stripNewline} from '../io/strip-newline.js'; +import {addInputOptionsSync} from '../io/input-sync.js'; +import {transformOutputSync} from '../io/output-sync.js'; +import {getMaxBufferSync} from '../io/max-buffer.js'; +import {getAllSync} from '../resolve/all-sync.js'; +import {getExitResultSync} from '../resolve/exit-sync.js'; + +// Main shared logic for all sync methods: `execaSync()`, `$.sync()` +export const execaCoreSync = (rawFile, rawArguments, rawOptions) => { + const {file, commandArguments, command, escapedCommand, startTime, verboseInfo, options, fileDescriptors} = handleSyncArguments(rawFile, rawArguments, rawOptions); + const result = spawnSubprocessSync({ + file, + commandArguments, + options, + command, + escapedCommand, + verboseInfo, + fileDescriptors, + startTime, + }); + return handleResult(result, verboseInfo, options); +}; + +// Compute arguments to pass to `child_process.spawnSync()` +const handleSyncArguments = (rawFile, rawArguments, rawOptions) => { + const {command, escapedCommand, startTime, verboseInfo} = handleCommand(rawFile, rawArguments, rawOptions); + const syncOptions = normalizeSyncOptions(rawOptions); + const {file, commandArguments, options} = normalizeOptions(rawFile, rawArguments, syncOptions); + validateSyncOptions(options); + const fileDescriptors = handleStdioSync(options, verboseInfo); + return { + file, + commandArguments, + command, + escapedCommand, + startTime, + verboseInfo, + options, + fileDescriptors, + }; +}; + +// Options normalization logic specific to sync methods +const normalizeSyncOptions = options => options.node && !options.ipc ? {...options, ipc: false} : options; + +// Options validation logic specific to sync methods +const validateSyncOptions = ({ipc, ipcInput, detached, cancelSignal}) => { + if (ipcInput) { + throwInvalidSyncOption('ipcInput'); + } + + if (ipc) { + throwInvalidSyncOption('ipc: true'); + } + + if (detached) { + throwInvalidSyncOption('detached: true'); + } + + if (cancelSignal) { + throwInvalidSyncOption('cancelSignal'); + } +}; + +const throwInvalidSyncOption = value => { + throw new TypeError(`The "${value}" option cannot be used with synchronous methods.`); +}; + +const spawnSubprocessSync = ({file, commandArguments, options, command, escapedCommand, verboseInfo, fileDescriptors, startTime}) => { + const syncResult = runSubprocessSync({ + file, + commandArguments, + options, + command, + escapedCommand, + fileDescriptors, + startTime, + }); + if (syncResult.failed) { + return syncResult; + } + + const {resultError, exitCode, signal, timedOut, isMaxBuffer} = getExitResultSync(syncResult, options); + const {output, error = resultError} = transformOutputSync({ + fileDescriptors, + syncResult, + options, + isMaxBuffer, + verboseInfo, + }); + const stdio = output.map((stdioOutput, fdNumber) => stripNewline(stdioOutput, options, fdNumber)); + const all = stripNewline(getAllSync(output, options), options, 'all'); + return getSyncResult({ + error, + exitCode, + signal, + timedOut, + isMaxBuffer, + stdio, + all, + options, + command, + escapedCommand, + startTime, + }); +}; + +const runSubprocessSync = ({file, commandArguments, options, command, escapedCommand, fileDescriptors, startTime}) => { + try { + addInputOptionsSync(fileDescriptors, options); + const normalizedOptions = normalizeSpawnSyncOptions(options); + return spawnSync(...concatenateShell(file, commandArguments, normalizedOptions)); + } catch (error) { + return makeEarlyError({ + error, + command, + escapedCommand, + fileDescriptors, + options, + startTime, + isSync: true, + }); + } +}; + +// The `encoding` option is handled by Execa, not by `child_process.spawnSync()` +const normalizeSpawnSyncOptions = ({encoding, maxBuffer, ...options}) => ({...options, encoding: 'buffer', maxBuffer: getMaxBufferSync(maxBuffer)}); + +const getSyncResult = ({error, exitCode, signal, timedOut, isMaxBuffer, stdio, all, options, command, escapedCommand, startTime}) => error === undefined + ? makeSuccessResult({ + command, + escapedCommand, + stdio, + all, + ipcOutput: [], + options, + startTime, + }) + : makeError({ + error, + command, + escapedCommand, + timedOut, + isCanceled: false, + isGracefullyCanceled: false, + isMaxBuffer, + isForcefullyTerminated: false, + exitCode, + signal, + stdio, + all, + ipcOutput: [], + options, + startTime, + isSync: true, + }); diff --git a/node_modules/execa/lib/methods/node.js b/node_modules/execa/lib/methods/node.js new file mode 100644 index 0000000000..80d25d6d5f --- /dev/null +++ b/node_modules/execa/lib/methods/node.js @@ -0,0 +1,51 @@ +import {execPath, execArgv} from 'node:process'; +import path from 'node:path'; +import {safeNormalizeFileUrl} from '../arguments/file-url.js'; + +// `execaNode()` is a shortcut for `execa(..., {node: true})` +export const mapNode = ({options}) => { + if (options.node === false) { + throw new TypeError('The "node" option cannot be false with `execaNode()`.'); + } + + return {options: {...options, node: true}}; +}; + +// Applies the `node: true` option, and the related `nodePath`/`nodeOptions` options. +// Modifies the file commands/arguments to ensure the same Node binary and flags are re-used. +// Also adds `ipc: true` and `shell: false`. +export const handleNodeOption = (file, commandArguments, { + node: shouldHandleNode = false, + nodePath = execPath, + nodeOptions = execArgv.filter(nodeOption => !nodeOption.startsWith('--inspect')), + cwd, + execPath: formerNodePath, + ...options +}) => { + if (formerNodePath !== undefined) { + throw new TypeError('The "execPath" option has been removed. Please use the "nodePath" option instead.'); + } + + const normalizedNodePath = safeNormalizeFileUrl(nodePath, 'The "nodePath" option'); + const resolvedNodePath = path.resolve(cwd, normalizedNodePath); + const newOptions = { + ...options, + nodePath: resolvedNodePath, + node: shouldHandleNode, + cwd, + }; + + if (!shouldHandleNode) { + return [file, commandArguments, newOptions]; + } + + if (path.basename(file, '.exe') === 'node') { + throw new TypeError('When the "node" option is true, the first argument does not need to be "node".'); + } + + return [ + resolvedNodePath, + [...nodeOptions, file, ...commandArguments], + {ipc: true, ...newOptions, shell: false}, + ]; +}; diff --git a/node_modules/execa/lib/methods/parameters.js b/node_modules/execa/lib/methods/parameters.js new file mode 100644 index 0000000000..c4e526fa1c --- /dev/null +++ b/node_modules/execa/lib/methods/parameters.js @@ -0,0 +1,31 @@ +import isPlainObject from 'is-plain-obj'; +import {safeNormalizeFileUrl} from '../arguments/file-url.js'; + +// The command `arguments` and `options` are both optional. +// This also does basic validation on them and on the command file. +export const normalizeParameters = (rawFile, rawArguments = [], rawOptions = {}) => { + const filePath = safeNormalizeFileUrl(rawFile, 'First argument'); + const [commandArguments, options] = isPlainObject(rawArguments) + ? [[], rawArguments] + : [rawArguments, rawOptions]; + + if (!Array.isArray(commandArguments)) { + throw new TypeError(`Second argument must be either an array of arguments or an options object: ${commandArguments}`); + } + + if (commandArguments.some(commandArgument => typeof commandArgument === 'object' && commandArgument !== null)) { + throw new TypeError(`Second argument must be an array of strings: ${commandArguments}`); + } + + const normalizedArguments = commandArguments.map(String); + const nullByteArgument = normalizedArguments.find(normalizedArgument => normalizedArgument.includes('\0')); + if (nullByteArgument !== undefined) { + throw new TypeError(`Arguments cannot contain null bytes ("\\0"): ${nullByteArgument}`); + } + + if (!isPlainObject(options)) { + throw new TypeError(`Last argument must be an options object: ${options}`); + } + + return [filePath, normalizedArguments, options]; +}; diff --git a/node_modules/execa/lib/methods/promise.js b/node_modules/execa/lib/methods/promise.js new file mode 100644 index 0000000000..705692b4be --- /dev/null +++ b/node_modules/execa/lib/methods/promise.js @@ -0,0 +1,15 @@ +// The return value is a mixin of `subprocess` and `Promise` +export const mergePromise = (subprocess, promise) => { + for (const [property, descriptor] of descriptors) { + const value = descriptor.value.bind(promise); + Reflect.defineProperty(subprocess, property, {...descriptor, value}); + } +}; + +// eslint-disable-next-line unicorn/prefer-top-level-await +const nativePromisePrototype = (async () => {})().constructor.prototype; + +const descriptors = ['then', 'catch', 'finally'].map(property => [ + property, + Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property), +]); diff --git a/node_modules/execa/lib/methods/script.js b/node_modules/execa/lib/methods/script.js new file mode 100644 index 0000000000..a3f98b61a4 --- /dev/null +++ b/node_modules/execa/lib/methods/script.js @@ -0,0 +1,22 @@ +// Sets `$.sync` and `$.s` +export const setScriptSync = (boundExeca, createNested, boundOptions) => { + boundExeca.sync = createNested(mapScriptSync, boundOptions); + boundExeca.s = boundExeca.sync; +}; + +// Main logic for `$` +export const mapScriptAsync = ({options}) => getScriptOptions(options); + +// Main logic for `$.sync` +const mapScriptSync = ({options}) => ({...getScriptOptions(options), isSync: true}); + +// `$` is like `execa` but with script-friendly options: `{stdin: 'inherit', preferLocal: true}` +const getScriptOptions = options => ({options: {...getScriptStdinOption(options), ...options}}); + +const getScriptStdinOption = ({input, inputFile, stdio}) => input === undefined && inputFile === undefined && stdio === undefined + ? {stdin: 'inherit'} + : {}; + +// When using $(...).pipe(...), most script-friendly options should apply to both commands. +// However, some options (like `stdin: 'inherit'`) would create issues with piping, i.e. cannot be deep. +export const deepScriptOptions = {preferLocal: true}; diff --git a/node_modules/execa/lib/methods/template.js b/node_modules/execa/lib/methods/template.js new file mode 100644 index 0000000000..6b7745ea3a --- /dev/null +++ b/node_modules/execa/lib/methods/template.js @@ -0,0 +1,153 @@ +import {ChildProcess} from 'node:child_process'; +import isPlainObject from 'is-plain-obj'; +import {isUint8Array, uint8ArrayToString} from '../utils/uint-array.js'; + +// Check whether the template string syntax is being used +export const isTemplateString = templates => Array.isArray(templates) && Array.isArray(templates.raw); + +// Convert execa`file ...commandArguments` to execa(file, commandArguments) +export const parseTemplates = (templates, expressions) => { + let tokens = []; + + for (const [index, template] of templates.entries()) { + tokens = parseTemplate({ + templates, + expressions, + tokens, + index, + template, + }); + } + + if (tokens.length === 0) { + throw new TypeError('Template script must not be empty'); + } + + const [file, ...commandArguments] = tokens; + return [file, commandArguments, {}]; +}; + +const parseTemplate = ({templates, expressions, tokens, index, template}) => { + if (template === undefined) { + throw new TypeError(`Invalid backslash sequence: ${templates.raw[index]}`); + } + + const {nextTokens, leadingWhitespaces, trailingWhitespaces} = splitByWhitespaces(template, templates.raw[index]); + const newTokens = concatTokens(tokens, nextTokens, leadingWhitespaces); + + if (index === expressions.length) { + return newTokens; + } + + const expression = expressions[index]; + const expressionTokens = Array.isArray(expression) + ? expression.map(expression => parseExpression(expression)) + : [parseExpression(expression)]; + return concatTokens(newTokens, expressionTokens, trailingWhitespaces); +}; + +// Like `string.split(/[ \t\r\n]+/)` except newlines and tabs are: +// - ignored when input as a backslash sequence like: `echo foo\n bar` +// - not ignored when input directly +// The only way to distinguish those in JavaScript is to use a tagged template and compare: +// - the first array argument, which does not escape backslash sequences +// - its `raw` property, which escapes them +const splitByWhitespaces = (template, rawTemplate) => { + if (rawTemplate.length === 0) { + return {nextTokens: [], leadingWhitespaces: false, trailingWhitespaces: false}; + } + + const nextTokens = []; + let templateStart = 0; + const leadingWhitespaces = DELIMITERS.has(rawTemplate[0]); + + for ( + let templateIndex = 0, rawIndex = 0; + templateIndex < template.length; + templateIndex += 1, rawIndex += 1 + ) { + const rawCharacter = rawTemplate[rawIndex]; + if (DELIMITERS.has(rawCharacter)) { + if (templateStart !== templateIndex) { + nextTokens.push(template.slice(templateStart, templateIndex)); + } + + templateStart = templateIndex + 1; + } else if (rawCharacter === '\\') { + const nextRawCharacter = rawTemplate[rawIndex + 1]; + if (nextRawCharacter === '\n') { + // Handles escaped newlines in templates + templateIndex -= 1; + rawIndex += 1; + } else if (nextRawCharacter === 'u' && rawTemplate[rawIndex + 2] === '{') { + rawIndex = rawTemplate.indexOf('}', rawIndex + 3); + } else { + rawIndex += ESCAPE_LENGTH[nextRawCharacter] ?? 1; + } + } + } + + const trailingWhitespaces = templateStart === template.length; + if (!trailingWhitespaces) { + nextTokens.push(template.slice(templateStart)); + } + + return {nextTokens, leadingWhitespaces, trailingWhitespaces}; +}; + +const DELIMITERS = new Set([' ', '\t', '\r', '\n']); + +// Number of characters in backslash escape sequences: \0 \xXX or \uXXXX +// \cX is allowed in RegExps but not in strings +// Octal sequences are not allowed in strict mode +const ESCAPE_LENGTH = {x: 3, u: 5}; + +const concatTokens = (tokens, nextTokens, isSeparated) => isSeparated + || tokens.length === 0 + || nextTokens.length === 0 + ? [...tokens, ...nextTokens] + : [ + ...tokens.slice(0, -1), + `${tokens.at(-1)}${nextTokens[0]}`, + ...nextTokens.slice(1), + ]; + +// Handle `${expression}` inside the template string syntax +const parseExpression = expression => { + const typeOfExpression = typeof expression; + + if (typeOfExpression === 'string') { + return expression; + } + + if (typeOfExpression === 'number') { + return String(expression); + } + + if (isPlainObject(expression) && ('stdout' in expression || 'isMaxBuffer' in expression)) { + return getSubprocessResult(expression); + } + + if (expression instanceof ChildProcess || Object.prototype.toString.call(expression) === '[object Promise]') { + // eslint-disable-next-line no-template-curly-in-string + throw new TypeError('Unexpected subprocess in template expression. Please use ${await subprocess} instead of ${subprocess}.'); + } + + throw new TypeError(`Unexpected "${typeOfExpression}" in template expression`); +}; + +const getSubprocessResult = ({stdout}) => { + if (typeof stdout === 'string') { + return stdout; + } + + if (isUint8Array(stdout)) { + return uint8ArrayToString(stdout); + } + + if (stdout === undefined) { + throw new TypeError('Missing result.stdout in template expression. This is probably due to the previous subprocess\' "stdout" option.'); + } + + throw new TypeError(`Unexpected "${typeof stdout}" stdout in template expression`); +}; diff --git a/node_modules/execa/lib/pipe.js b/node_modules/execa/lib/pipe.js deleted file mode 100644 index e73ffcc989..0000000000 --- a/node_modules/execa/lib/pipe.js +++ /dev/null @@ -1,42 +0,0 @@ -import {createWriteStream} from 'node:fs'; -import {ChildProcess} from 'node:child_process'; -import {isWritableStream} from 'is-stream'; - -const isExecaChildProcess = target => target instanceof ChildProcess && typeof target.then === 'function'; - -const pipeToTarget = (spawned, streamName, target) => { - if (typeof target === 'string') { - spawned[streamName].pipe(createWriteStream(target)); - return spawned; - } - - if (isWritableStream(target)) { - spawned[streamName].pipe(target); - return spawned; - } - - if (!isExecaChildProcess(target)) { - throw new TypeError('The second argument must be a string, a stream or an Execa child process.'); - } - - if (!isWritableStream(target.stdin)) { - throw new TypeError('The target child process\'s stdin must be available.'); - } - - spawned[streamName].pipe(target.stdin); - return target; -}; - -export const addPipeMethods = spawned => { - if (spawned.stdout !== null) { - spawned.pipeStdout = pipeToTarget.bind(undefined, spawned, 'stdout'); - } - - if (spawned.stderr !== null) { - spawned.pipeStderr = pipeToTarget.bind(undefined, spawned, 'stderr'); - } - - if (spawned.all !== undefined) { - spawned.pipeAll = pipeToTarget.bind(undefined, spawned, 'all'); - } -}; diff --git a/node_modules/execa/lib/pipe/abort.js b/node_modules/execa/lib/pipe/abort.js new file mode 100644 index 0000000000..1d3caec588 --- /dev/null +++ b/node_modules/execa/lib/pipe/abort.js @@ -0,0 +1,20 @@ +import {aborted} from 'node:util'; +import {createNonCommandError} from './throw.js'; + +// When passing an `unpipeSignal` option, abort piping when the signal is aborted. +// However, do not terminate the subprocesses. +export const unpipeOnAbort = (unpipeSignal, unpipeContext) => unpipeSignal === undefined + ? [] + : [unpipeOnSignalAbort(unpipeSignal, unpipeContext)]; + +const unpipeOnSignalAbort = async (unpipeSignal, {sourceStream, mergedStream, fileDescriptors, sourceOptions, startTime}) => { + await aborted(unpipeSignal, sourceStream); + await mergedStream.remove(sourceStream); + const error = new Error('Pipe canceled by `unpipeSignal` option.'); + throw createNonCommandError({ + error, + fileDescriptors, + sourceOptions, + startTime, + }); +}; diff --git a/node_modules/execa/lib/pipe/pipe-arguments.js b/node_modules/execa/lib/pipe/pipe-arguments.js new file mode 100644 index 0000000000..9745a9e7a7 --- /dev/null +++ b/node_modules/execa/lib/pipe/pipe-arguments.js @@ -0,0 +1,91 @@ +import {normalizeParameters} from '../methods/parameters.js'; +import {getStartTime} from '../return/duration.js'; +import {SUBPROCESS_OPTIONS, getToStream, getFromStream} from '../arguments/fd-options.js'; +import {isDenoExecPath} from '../arguments/file-url.js'; + +// Normalize and validate arguments passed to `source.pipe(destination)` +export const normalizePipeArguments = ({source, sourcePromise, boundOptions, createNested}, ...pipeArguments) => { + const startTime = getStartTime(); + const { + destination, + destinationStream, + destinationError, + from, + unpipeSignal, + } = getDestinationStream(boundOptions, createNested, pipeArguments); + const {sourceStream, sourceError} = getSourceStream(source, from); + const {options: sourceOptions, fileDescriptors} = SUBPROCESS_OPTIONS.get(source); + return { + sourcePromise, + sourceStream, + sourceOptions, + sourceError, + destination, + destinationStream, + destinationError, + unpipeSignal, + fileDescriptors, + startTime, + }; +}; + +const getDestinationStream = (boundOptions, createNested, pipeArguments) => { + try { + const { + destination, + pipeOptions: {from, to, unpipeSignal} = {}, + } = getDestination(boundOptions, createNested, ...pipeArguments); + const destinationStream = getToStream(destination, to); + return { + destination, + destinationStream, + from, + unpipeSignal, + }; + } catch (error) { + return {destinationError: error}; + } +}; + +// Piping subprocesses can use three syntaxes: +// - source.pipe('command', commandArguments, pipeOptionsOrDestinationOptions) +// - source.pipe`command commandArgument` or source.pipe(pipeOptionsOrDestinationOptions)`command commandArgument` +// - source.pipe(execa(...), pipeOptions) +const getDestination = (boundOptions, createNested, firstArgument, ...pipeArguments) => { + if (Array.isArray(firstArgument)) { + const destination = createNested(mapDestinationArguments, boundOptions)(firstArgument, ...pipeArguments); + return {destination, pipeOptions: boundOptions}; + } + + if (typeof firstArgument === 'string' || firstArgument instanceof URL || isDenoExecPath(firstArgument)) { + if (Object.keys(boundOptions).length > 0) { + throw new TypeError('Please use .pipe("file", ..., options) or .pipe(execa("file", ..., options)) instead of .pipe(options)("file", ...).'); + } + + const [rawFile, rawArguments, rawOptions] = normalizeParameters(firstArgument, ...pipeArguments); + const destination = createNested(mapDestinationArguments)(rawFile, rawArguments, rawOptions); + return {destination, pipeOptions: rawOptions}; + } + + if (SUBPROCESS_OPTIONS.has(firstArgument)) { + if (Object.keys(boundOptions).length > 0) { + throw new TypeError('Please use .pipe(options)`command` or .pipe($(options)`command`) instead of .pipe(options)($`command`).'); + } + + return {destination: firstArgument, pipeOptions: pipeArguments[0]}; + } + + throw new TypeError(`The first argument must be a template string, an options object, or an Execa subprocess: ${firstArgument}`); +}; + +// Force `stdin: 'pipe'` with the destination subprocess +const mapDestinationArguments = ({options}) => ({options: {...options, stdin: 'pipe', piped: true}}); + +const getSourceStream = (source, from) => { + try { + const sourceStream = getFromStream(source, from); + return {sourceStream}; + } catch (error) { + return {sourceError: error}; + } +}; diff --git a/node_modules/execa/lib/pipe/sequence.js b/node_modules/execa/lib/pipe/sequence.js new file mode 100644 index 0000000000..b04c5a3452 --- /dev/null +++ b/node_modules/execa/lib/pipe/sequence.js @@ -0,0 +1,24 @@ +// Like Bash, we await both subprocesses. This is unlike some other shells which only await the destination subprocess. +// Like Bash with the `pipefail` option, if either subprocess fails, the whole pipe fails. +// Like Bash, if both subprocesses fail, we return the failure of the destination. +// This ensures both subprocesses' errors are present, using `error.pipedFrom`. +export const waitForBothSubprocesses = async subprocessPromises => { + const [ + {status: sourceStatus, reason: sourceReason, value: sourceResult = sourceReason}, + {status: destinationStatus, reason: destinationReason, value: destinationResult = destinationReason}, + ] = await subprocessPromises; + + if (!destinationResult.pipedFrom.includes(sourceResult)) { + destinationResult.pipedFrom.push(sourceResult); + } + + if (destinationStatus === 'rejected') { + throw destinationResult; + } + + if (sourceStatus === 'rejected') { + throw sourceResult; + } + + return destinationResult; +}; diff --git a/node_modules/execa/lib/pipe/setup.js b/node_modules/execa/lib/pipe/setup.js new file mode 100644 index 0000000000..bf1a87b503 --- /dev/null +++ b/node_modules/execa/lib/pipe/setup.js @@ -0,0 +1,72 @@ +import isPlainObject from 'is-plain-obj'; +import {normalizePipeArguments} from './pipe-arguments.js'; +import {handlePipeArgumentsError} from './throw.js'; +import {waitForBothSubprocesses} from './sequence.js'; +import {pipeSubprocessStream} from './streaming.js'; +import {unpipeOnAbort} from './abort.js'; + +// Pipe a subprocess' `stdout`/`stderr`/`stdio` into another subprocess' `stdin` +export const pipeToSubprocess = (sourceInfo, ...pipeArguments) => { + if (isPlainObject(pipeArguments[0])) { + return pipeToSubprocess.bind(undefined, { + ...sourceInfo, + boundOptions: {...sourceInfo.boundOptions, ...pipeArguments[0]}, + }); + } + + const {destination, ...normalizedInfo} = normalizePipeArguments(sourceInfo, ...pipeArguments); + const promise = handlePipePromise({...normalizedInfo, destination}); + promise.pipe = pipeToSubprocess.bind(undefined, { + ...sourceInfo, + source: destination, + sourcePromise: promise, + boundOptions: {}, + }); + return promise; +}; + +// Asynchronous logic when piping subprocesses +const handlePipePromise = async ({ + sourcePromise, + sourceStream, + sourceOptions, + sourceError, + destination, + destinationStream, + destinationError, + unpipeSignal, + fileDescriptors, + startTime, +}) => { + const subprocessPromises = getSubprocessPromises(sourcePromise, destination); + handlePipeArgumentsError({ + sourceStream, + sourceError, + destinationStream, + destinationError, + fileDescriptors, + sourceOptions, + startTime, + }); + const maxListenersController = new AbortController(); + try { + const mergedStream = pipeSubprocessStream(sourceStream, destinationStream, maxListenersController); + return await Promise.race([ + waitForBothSubprocesses(subprocessPromises), + ...unpipeOnAbort(unpipeSignal, { + sourceStream, + mergedStream, + sourceOptions, + fileDescriptors, + startTime, + }), + ]); + } finally { + maxListenersController.abort(); + } +}; + +// `.pipe()` awaits the subprocess promises. +// When invalid arguments are passed to `.pipe()`, we throw an error, which prevents awaiting them. +// We need to ensure this does not create unhandled rejections. +const getSubprocessPromises = (sourcePromise, destination) => Promise.allSettled([sourcePromise, destination]); diff --git a/node_modules/execa/lib/pipe/streaming.js b/node_modules/execa/lib/pipe/streaming.js new file mode 100644 index 0000000000..cae0cf2f83 --- /dev/null +++ b/node_modules/execa/lib/pipe/streaming.js @@ -0,0 +1,51 @@ +import {finished} from 'node:stream/promises'; +import mergeStreams from '@sindresorhus/merge-streams'; +import {incrementMaxListeners} from '../utils/max-listeners.js'; +import {pipeStreams} from '../io/pipeline.js'; + +// The piping behavior is like Bash. +// In particular, when one subprocess exits, the other is not terminated by a signal. +// Instead, its stdout (for the source) or stdin (for the destination) closes. +// If the subprocess uses it, it will make it error with SIGPIPE or EPIPE (for the source) or end (for the destination). +// If it does not use it, it will continue running. +// This allows for subprocesses to gracefully exit and lower the coupling between subprocesses. +export const pipeSubprocessStream = (sourceStream, destinationStream, maxListenersController) => { + const mergedStream = MERGED_STREAMS.has(destinationStream) + ? pipeMoreSubprocessStream(sourceStream, destinationStream) + : pipeFirstSubprocessStream(sourceStream, destinationStream); + incrementMaxListeners(sourceStream, SOURCE_LISTENERS_PER_PIPE, maxListenersController.signal); + incrementMaxListeners(destinationStream, DESTINATION_LISTENERS_PER_PIPE, maxListenersController.signal); + cleanupMergedStreamsMap(destinationStream); + return mergedStream; +}; + +// We use `merge-streams` to allow for multiple sources to pipe to the same destination. +const pipeFirstSubprocessStream = (sourceStream, destinationStream) => { + const mergedStream = mergeStreams([sourceStream]); + pipeStreams(mergedStream, destinationStream); + MERGED_STREAMS.set(destinationStream, mergedStream); + return mergedStream; +}; + +const pipeMoreSubprocessStream = (sourceStream, destinationStream) => { + const mergedStream = MERGED_STREAMS.get(destinationStream); + mergedStream.add(sourceStream); + return mergedStream; +}; + +const cleanupMergedStreamsMap = async destinationStream => { + try { + await finished(destinationStream, {cleanup: true, readable: false, writable: true}); + } catch {} + + MERGED_STREAMS.delete(destinationStream); +}; + +const MERGED_STREAMS = new WeakMap(); + +// Number of listeners set up on `sourceStream` by each `sourceStream.pipe(destinationStream)` +// Those are added by `merge-streams` +const SOURCE_LISTENERS_PER_PIPE = 2; +// Number of listeners set up on `destinationStream` by each `sourceStream.pipe(destinationStream)` +// Those are added by `finished()` in `cleanupMergedStreamsMap()` +const DESTINATION_LISTENERS_PER_PIPE = 1; diff --git a/node_modules/execa/lib/pipe/throw.js b/node_modules/execa/lib/pipe/throw.js new file mode 100644 index 0000000000..e13f749894 --- /dev/null +++ b/node_modules/execa/lib/pipe/throw.js @@ -0,0 +1,58 @@ +import {makeEarlyError} from '../return/result.js'; +import {abortSourceStream, endDestinationStream} from '../io/pipeline.js'; + +// When passing invalid arguments to `source.pipe()`, throw asynchronously. +// We also abort both subprocesses. +export const handlePipeArgumentsError = ({ + sourceStream, + sourceError, + destinationStream, + destinationError, + fileDescriptors, + sourceOptions, + startTime, +}) => { + const error = getPipeArgumentsError({ + sourceStream, + sourceError, + destinationStream, + destinationError, + }); + if (error !== undefined) { + throw createNonCommandError({ + error, + fileDescriptors, + sourceOptions, + startTime, + }); + } +}; + +const getPipeArgumentsError = ({sourceStream, sourceError, destinationStream, destinationError}) => { + if (sourceError !== undefined && destinationError !== undefined) { + return destinationError; + } + + if (destinationError !== undefined) { + abortSourceStream(sourceStream); + return destinationError; + } + + if (sourceError !== undefined) { + endDestinationStream(destinationStream); + return sourceError; + } +}; + +// Specific error return value when passing invalid arguments to `subprocess.pipe()` or when using `unpipeSignal` +export const createNonCommandError = ({error, fileDescriptors, sourceOptions, startTime}) => makeEarlyError({ + error, + command: PIPE_COMMAND_MESSAGE, + escapedCommand: PIPE_COMMAND_MESSAGE, + fileDescriptors, + options: sourceOptions, + startTime, + isSync: false, +}); + +const PIPE_COMMAND_MESSAGE = 'source.pipe(destination)'; diff --git a/node_modules/execa/lib/promise.js b/node_modules/execa/lib/promise.js deleted file mode 100644 index a4773f30b0..0000000000 --- a/node_modules/execa/lib/promise.js +++ /dev/null @@ -1,36 +0,0 @@ -// eslint-disable-next-line unicorn/prefer-top-level-await -const nativePromisePrototype = (async () => {})().constructor.prototype; - -const descriptors = ['then', 'catch', 'finally'].map(property => [ - property, - Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property), -]); - -// The return value is a mixin of `childProcess` and `Promise` -export const mergePromise = (spawned, promise) => { - for (const [property, descriptor] of descriptors) { - // Starting the main `promise` is deferred to avoid consuming streams - const value = typeof promise === 'function' - ? (...args) => Reflect.apply(descriptor.value, promise(), args) - : descriptor.value.bind(promise); - - Reflect.defineProperty(spawned, property, {...descriptor, value}); - } -}; - -// Use promises instead of `child_process` events -export const getSpawnedPromise = spawned => new Promise((resolve, reject) => { - spawned.on('exit', (exitCode, signal) => { - resolve({exitCode, signal}); - }); - - spawned.on('error', error => { - reject(error); - }); - - if (spawned.stdin) { - spawned.stdin.on('error', error => { - reject(error); - }); - } -}); diff --git a/node_modules/execa/lib/resolve/all-async.js b/node_modules/execa/lib/resolve/all-async.js new file mode 100644 index 0000000000..f0a5abcd3a --- /dev/null +++ b/node_modules/execa/lib/resolve/all-async.js @@ -0,0 +1,46 @@ +import mergeStreams from '@sindresorhus/merge-streams'; +import {waitForSubprocessStream} from './stdio.js'; + +// `all` interleaves `stdout` and `stderr` +export const makeAllStream = ({stdout, stderr}, {all}) => all && (stdout || stderr) + ? mergeStreams([stdout, stderr].filter(Boolean)) + : undefined; + +// Read the contents of `subprocess.all` and|or wait for its completion +export const waitForAllStream = ({subprocess, encoding, buffer, maxBuffer, lines, stripFinalNewline, verboseInfo, streamInfo}) => waitForSubprocessStream({ + ...getAllStream(subprocess, buffer), + fdNumber: 'all', + encoding, + maxBuffer: maxBuffer[1] + maxBuffer[2], + lines: lines[1] || lines[2], + allMixed: getAllMixed(subprocess), + stripFinalNewline, + verboseInfo, + streamInfo, +}); + +const getAllStream = ({stdout, stderr, all}, [, bufferStdout, bufferStderr]) => { + const buffer = bufferStdout || bufferStderr; + if (!buffer) { + return {stream: all, buffer}; + } + + if (!bufferStdout) { + return {stream: stderr, buffer}; + } + + if (!bufferStderr) { + return {stream: stdout, buffer}; + } + + return {stream: all, buffer}; +}; + +// When `subprocess.stdout` is in objectMode but not `subprocess.stderr` (or the opposite), we need to use both: +// - `getStreamAsArray()` for the chunks in objectMode, to return as an array without changing each chunk +// - `getStreamAsArrayBuffer()` or `getStream()` for the chunks not in objectMode, to convert them from Buffers to string or Uint8Array +// We do this by emulating the Buffer -> string|Uint8Array conversion performed by `get-stream` with our own, which is identical. +const getAllMixed = ({all, stdout, stderr}) => all + && stdout + && stderr + && stdout.readableObjectMode !== stderr.readableObjectMode; diff --git a/node_modules/execa/lib/resolve/all-sync.js b/node_modules/execa/lib/resolve/all-sync.js new file mode 100644 index 0000000000..bda3a3f1e5 --- /dev/null +++ b/node_modules/execa/lib/resolve/all-sync.js @@ -0,0 +1,33 @@ +import {isUint8Array, concatUint8Arrays} from '../utils/uint-array.js'; +import {stripNewline} from '../io/strip-newline.js'; + +// Retrieve `result.all` with synchronous methods +export const getAllSync = ([, stdout, stderr], options) => { + if (!options.all) { + return; + } + + if (stdout === undefined) { + return stderr; + } + + if (stderr === undefined) { + return stdout; + } + + if (Array.isArray(stdout)) { + return Array.isArray(stderr) + ? [...stdout, ...stderr] + : [...stdout, stripNewline(stderr, options, 'all')]; + } + + if (Array.isArray(stderr)) { + return [stripNewline(stdout, options, 'all'), ...stderr]; + } + + if (isUint8Array(stdout) && isUint8Array(stderr)) { + return concatUint8Arrays([stdout, stderr]); + } + + return `${stdout}${stderr}`; +}; diff --git a/node_modules/execa/lib/resolve/exit-async.js b/node_modules/execa/lib/resolve/exit-async.js new file mode 100644 index 0000000000..c89dc6d20e --- /dev/null +++ b/node_modules/execa/lib/resolve/exit-async.js @@ -0,0 +1,54 @@ +import {once} from 'node:events'; +import {DiscardedError} from '../return/final-error.js'; + +// If `error` is emitted before `spawn`, `exit` will never be emitted. +// However, `error` might be emitted after `spawn`. +// In that case, `exit` will still be emitted. +// Since the `exit` event contains the signal name, we want to make sure we are listening for it. +// This function also takes into account the following unlikely cases: +// - `exit` being emitted in the same microtask as `spawn` +// - `error` being emitted multiple times +export const waitForExit = async (subprocess, context) => { + const [exitCode, signal] = await waitForExitOrError(subprocess); + context.isForcefullyTerminated ??= false; + return [exitCode, signal]; +}; + +const waitForExitOrError = async subprocess => { + const [spawnPayload, exitPayload] = await Promise.allSettled([ + once(subprocess, 'spawn'), + once(subprocess, 'exit'), + ]); + + if (spawnPayload.status === 'rejected') { + return []; + } + + return exitPayload.status === 'rejected' + ? waitForSubprocessExit(subprocess) + : exitPayload.value; +}; + +const waitForSubprocessExit = async subprocess => { + try { + return await once(subprocess, 'exit'); + } catch { + return waitForSubprocessExit(subprocess); + } +}; + +// Retrieve the final exit code and|or signal name +export const waitForSuccessfulExit = async exitPromise => { + const [exitCode, signal] = await exitPromise; + + if (!isSubprocessErrorExit(exitCode, signal) && isFailedExit(exitCode, signal)) { + throw new DiscardedError(); + } + + return [exitCode, signal]; +}; + +// When the subprocess fails due to an `error` event +const isSubprocessErrorExit = (exitCode, signal) => exitCode === undefined && signal === undefined; +// When the subprocess fails due to a non-0 exit code or to a signal termination +export const isFailedExit = (exitCode, signal) => exitCode !== 0 || signal !== null; diff --git a/node_modules/execa/lib/resolve/exit-sync.js b/node_modules/execa/lib/resolve/exit-sync.js new file mode 100644 index 0000000000..2ab0b37427 --- /dev/null +++ b/node_modules/execa/lib/resolve/exit-sync.js @@ -0,0 +1,25 @@ +import {DiscardedError} from '../return/final-error.js'; +import {isMaxBufferSync} from '../io/max-buffer.js'; +import {isFailedExit} from './exit-async.js'; + +// Retrieve exit code, signal name and error information, with synchronous methods +export const getExitResultSync = ({error, status: exitCode, signal, output}, {maxBuffer}) => { + const resultError = getResultError(error, exitCode, signal); + const timedOut = resultError?.code === 'ETIMEDOUT'; + const isMaxBuffer = isMaxBufferSync(resultError, output, maxBuffer); + return { + resultError, + exitCode, + signal, + timedOut, + isMaxBuffer, + }; +}; + +const getResultError = (error, exitCode, signal) => { + if (error !== undefined) { + return error; + } + + return isFailedExit(exitCode, signal) ? new DiscardedError() : undefined; +}; diff --git a/node_modules/execa/lib/resolve/stdio.js b/node_modules/execa/lib/resolve/stdio.js new file mode 100644 index 0000000000..58abfd26cf --- /dev/null +++ b/node_modules/execa/lib/resolve/stdio.js @@ -0,0 +1,47 @@ +import {getStreamOutput} from '../io/contents.js'; +import {waitForStream, isInputFileDescriptor} from './wait-stream.js'; + +// Read the contents of `subprocess.std*` and|or wait for its completion +export const waitForStdioStreams = ({subprocess, encoding, buffer, maxBuffer, lines, stripFinalNewline, verboseInfo, streamInfo}) => subprocess.stdio.map((stream, fdNumber) => waitForSubprocessStream({ + stream, + fdNumber, + encoding, + buffer: buffer[fdNumber], + maxBuffer: maxBuffer[fdNumber], + lines: lines[fdNumber], + allMixed: false, + stripFinalNewline, + verboseInfo, + streamInfo, +})); + +// Read the contents of `subprocess.std*` or `subprocess.all` and|or wait for its completion +export const waitForSubprocessStream = async ({stream, fdNumber, encoding, buffer, maxBuffer, lines, allMixed, stripFinalNewline, verboseInfo, streamInfo}) => { + if (!stream) { + return; + } + + const onStreamEnd = waitForStream(stream, fdNumber, streamInfo); + if (isInputFileDescriptor(streamInfo, fdNumber)) { + await onStreamEnd; + return; + } + + const [output] = await Promise.all([ + getStreamOutput({ + stream, + onStreamEnd, + fdNumber, + encoding, + buffer, + maxBuffer, + lines, + allMixed, + stripFinalNewline, + verboseInfo, + streamInfo, + }), + onStreamEnd, + ]); + return output; +}; diff --git a/node_modules/execa/lib/resolve/wait-stream.js b/node_modules/execa/lib/resolve/wait-stream.js new file mode 100644 index 0000000000..8090888cfb --- /dev/null +++ b/node_modules/execa/lib/resolve/wait-stream.js @@ -0,0 +1,96 @@ +import {finished} from 'node:stream/promises'; + +// Wraps `finished(stream)` to handle the following case: +// - When the subprocess exits, Node.js automatically calls `subprocess.stdin.destroy()`, which we need to ignore. +// - However, we still need to throw if `subprocess.stdin.destroy()` is called before subprocess exit. +export const waitForStream = async (stream, fdNumber, streamInfo, {isSameDirection, stopOnExit = false} = {}) => { + const state = handleStdinDestroy(stream, streamInfo); + const abortController = new AbortController(); + try { + await Promise.race([ + ...(stopOnExit ? [streamInfo.exitPromise] : []), + finished(stream, {cleanup: true, signal: abortController.signal}), + ]); + } catch (error) { + if (!state.stdinCleanedUp) { + handleStreamError(error, fdNumber, streamInfo, isSameDirection); + } + } finally { + abortController.abort(); + } +}; + +// If `subprocess.stdin` is destroyed before being fully written to, it is considered aborted and should throw an error. +// This can happen for example when user called `subprocess.stdin.destroy()` before `subprocess.stdin.end()`. +// However, Node.js calls `subprocess.stdin.destroy()` on exit for cleanup purposes. +// https://github.com/nodejs/node/blob/0b4cdb4b42956cbd7019058e409e06700a199e11/lib/internal/child_process.js#L278 +// This is normal and should not throw an error. +// Therefore, we need to differentiate between both situations to know whether to throw an error. +// Unfortunately, events (`close`, `error`, `end`, `exit`) cannot be used because `.destroy()` can take an arbitrary amount of time. +// For example, `stdin: 'pipe'` is implemented as a TCP socket, and its `.destroy()` method waits for TCP disconnection. +// Therefore `.destroy()` might end before or after subprocess exit, based on OS speed and load. +// The only way to detect this is to spy on `subprocess.stdin._destroy()` by wrapping it. +// If `subprocess.exitCode` or `subprocess.signalCode` is set, it means `.destroy()` is being called by Node.js itself. +const handleStdinDestroy = (stream, {originalStreams: [originalStdin], subprocess}) => { + const state = {stdinCleanedUp: false}; + if (stream === originalStdin) { + spyOnStdinDestroy(stream, subprocess, state); + } + + return state; +}; + +const spyOnStdinDestroy = (subprocessStdin, subprocess, state) => { + const {_destroy} = subprocessStdin; + subprocessStdin._destroy = (...destroyArguments) => { + setStdinCleanedUp(subprocess, state); + _destroy.call(subprocessStdin, ...destroyArguments); + }; +}; + +const setStdinCleanedUp = ({exitCode, signalCode}, state) => { + if (exitCode !== null || signalCode !== null) { + state.stdinCleanedUp = true; + } +}; + +// We ignore EPIPEs on writable streams and aborts on readable streams since those can happen normally. +// When one stream errors, the error is propagated to the other streams on the same file descriptor. +// Those other streams might have a different direction due to the above. +// When this happens, the direction of both the initial stream and the others should then be taken into account. +// Therefore, we keep track of whether a stream error is currently propagating. +const handleStreamError = (error, fdNumber, streamInfo, isSameDirection) => { + if (!shouldIgnoreStreamError(error, fdNumber, streamInfo, isSameDirection)) { + throw error; + } +}; + +const shouldIgnoreStreamError = (error, fdNumber, streamInfo, isSameDirection = true) => { + if (streamInfo.propagating) { + return isStreamEpipe(error) || isStreamAbort(error); + } + + streamInfo.propagating = true; + return isInputFileDescriptor(streamInfo, fdNumber) === isSameDirection + ? isStreamEpipe(error) + : isStreamAbort(error); +}; + +// Unfortunately, we cannot use the stream's class or properties to know whether it is readable or writable. +// For example, `subprocess.stdin` is technically a Duplex, but can only be used as a writable. +// Therefore, we need to use the file descriptor's direction (`stdin` is input, `stdout` is output, etc.). +// However, while `subprocess.std*` and transforms follow that direction, any stream passed the `std*` option has the opposite direction. +// For example, `subprocess.stdin` is a writable, but the `stdin` option is a readable. +export const isInputFileDescriptor = ({fileDescriptors}, fdNumber) => fdNumber !== 'all' && fileDescriptors[fdNumber].direction === 'input'; + +// When `stream.destroy()` is called without an `error` argument, stream is aborted. +// This is the only way to abort a readable stream, which can be useful in some instances. +// Therefore, we ignore this error on readable streams. +export const isStreamAbort = error => error?.code === 'ERR_STREAM_PREMATURE_CLOSE'; + +// When `stream.write()` is called but the underlying source has been closed, `EPIPE` is emitted. +// When piping subprocesses, the source subprocess usually decides when to stop piping. +// However, there are some instances when the destination does instead, such as `... | head -n1`. +// It notifies the source by using `EPIPE`. +// Therefore, we ignore this error on writable streams. +const isStreamEpipe = error => error?.code === 'EPIPE'; diff --git a/node_modules/execa/lib/resolve/wait-subprocess.js b/node_modules/execa/lib/resolve/wait-subprocess.js new file mode 100644 index 0000000000..0c1c6ad97d --- /dev/null +++ b/node_modules/execa/lib/resolve/wait-subprocess.js @@ -0,0 +1,146 @@ +import {once} from 'node:events'; +import {isStream as isNodeStream} from 'is-stream'; +import {throwOnTimeout} from '../terminate/timeout.js'; +import {throwOnCancel} from '../terminate/cancel.js'; +import {throwOnGracefulCancel} from '../terminate/graceful.js'; +import {isStandardStream} from '../utils/standard-stream.js'; +import {TRANSFORM_TYPES} from '../stdio/type.js'; +import {getBufferedData} from '../io/contents.js'; +import {waitForIpcOutput, getBufferedIpcOutput} from '../ipc/buffer-messages.js'; +import {sendIpcInput} from '../ipc/ipc-input.js'; +import {waitForAllStream} from './all-async.js'; +import {waitForStdioStreams} from './stdio.js'; +import {waitForExit, waitForSuccessfulExit} from './exit-async.js'; +import {waitForStream} from './wait-stream.js'; + +// Retrieve result of subprocess: exit code, signal, error, streams (stdout/stderr/all) +export const waitForSubprocessResult = async ({ + subprocess, + options: { + encoding, + buffer, + maxBuffer, + lines, + timeoutDuration: timeout, + cancelSignal, + gracefulCancel, + forceKillAfterDelay, + stripFinalNewline, + ipc, + ipcInput, + }, + context, + verboseInfo, + fileDescriptors, + originalStreams, + onInternalError, + controller, +}) => { + const exitPromise = waitForExit(subprocess, context); + const streamInfo = { + originalStreams, + fileDescriptors, + subprocess, + exitPromise, + propagating: false, + }; + + const stdioPromises = waitForStdioStreams({ + subprocess, + encoding, + buffer, + maxBuffer, + lines, + stripFinalNewline, + verboseInfo, + streamInfo, + }); + const allPromise = waitForAllStream({ + subprocess, + encoding, + buffer, + maxBuffer, + lines, + stripFinalNewline, + verboseInfo, + streamInfo, + }); + const ipcOutput = []; + const ipcOutputPromise = waitForIpcOutput({ + subprocess, + buffer, + maxBuffer, + ipc, + ipcOutput, + verboseInfo, + }); + const originalPromises = waitForOriginalStreams(originalStreams, subprocess, streamInfo); + const customStreamsEndPromises = waitForCustomStreamsEnd(fileDescriptors, streamInfo); + + try { + return await Promise.race([ + Promise.all([ + {}, + waitForSuccessfulExit(exitPromise), + Promise.all(stdioPromises), + allPromise, + ipcOutputPromise, + sendIpcInput(subprocess, ipcInput), + ...originalPromises, + ...customStreamsEndPromises, + ]), + onInternalError, + throwOnSubprocessError(subprocess, controller), + ...throwOnTimeout(subprocess, timeout, context, controller), + ...throwOnCancel({ + subprocess, + cancelSignal, + gracefulCancel, + context, + controller, + }), + ...throwOnGracefulCancel({ + subprocess, + cancelSignal, + gracefulCancel, + forceKillAfterDelay, + context, + controller, + }), + ]); + } catch (error) { + context.terminationReason ??= 'other'; + return Promise.all([ + {error}, + exitPromise, + Promise.all(stdioPromises.map(stdioPromise => getBufferedData(stdioPromise))), + getBufferedData(allPromise), + getBufferedIpcOutput(ipcOutputPromise, ipcOutput), + Promise.allSettled(originalPromises), + Promise.allSettled(customStreamsEndPromises), + ]); + } +}; + +// Transforms replace `subprocess.std*`, which means they are not exposed to users. +// However, we still want to wait for their completion. +const waitForOriginalStreams = (originalStreams, subprocess, streamInfo) => + originalStreams.map((stream, fdNumber) => stream === subprocess.stdio[fdNumber] + ? undefined + : waitForStream(stream, fdNumber, streamInfo)); + +// Some `stdin`/`stdout`/`stderr` options create a stream, e.g. when passing a file path. +// The `.pipe()` method automatically ends that stream when `subprocess` ends. +// This makes sure we wait for the completion of those streams, in order to catch any error. +const waitForCustomStreamsEnd = (fileDescriptors, streamInfo) => fileDescriptors.flatMap(({stdioItems}, fdNumber) => stdioItems + .filter(({value, stream = value}) => isNodeStream(stream, {checkOpen: false}) && !isStandardStream(stream)) + .map(({type, value, stream = value}) => waitForStream(stream, fdNumber, streamInfo, { + isSameDirection: TRANSFORM_TYPES.has(type), + stopOnExit: type === 'native', + }))); + +// Fails when the subprocess emits an `error` event +const throwOnSubprocessError = async (subprocess, {signal}) => { + const [error] = await once(subprocess, 'error', {signal}); + throw error; +}; diff --git a/node_modules/execa/lib/return/duration.js b/node_modules/execa/lib/return/duration.js new file mode 100644 index 0000000000..bf431e1189 --- /dev/null +++ b/node_modules/execa/lib/return/duration.js @@ -0,0 +1,8 @@ +import {hrtime} from 'node:process'; + +// Start counting time before spawning the subprocess +export const getStartTime = () => hrtime.bigint(); + +// Compute duration after the subprocess ended. +// Printed by the `verbose` option. +export const getDurationMs = startTime => Number(hrtime.bigint() - startTime) / 1e6; diff --git a/node_modules/execa/lib/return/early-error.js b/node_modules/execa/lib/return/early-error.js new file mode 100644 index 0000000000..0c968b4cc4 --- /dev/null +++ b/node_modules/execa/lib/return/early-error.js @@ -0,0 +1,60 @@ +import {ChildProcess} from 'node:child_process'; +import { + PassThrough, + Readable, + Writable, + Duplex, +} from 'node:stream'; +import {cleanupCustomStreams} from '../stdio/handle.js'; +import {makeEarlyError} from './result.js'; +import {handleResult} from './reject.js'; + +// When the subprocess fails to spawn. +// We ensure the returned error is always both a promise and a subprocess. +export const handleEarlyError = ({error, command, escapedCommand, fileDescriptors, options, startTime, verboseInfo}) => { + cleanupCustomStreams(fileDescriptors); + + const subprocess = new ChildProcess(); + createDummyStreams(subprocess, fileDescriptors); + Object.assign(subprocess, {readable, writable, duplex}); + + const earlyError = makeEarlyError({ + error, + command, + escapedCommand, + fileDescriptors, + options, + startTime, + isSync: false, + }); + const promise = handleDummyPromise(earlyError, verboseInfo, options); + return {subprocess, promise}; +}; + +const createDummyStreams = (subprocess, fileDescriptors) => { + const stdin = createDummyStream(); + const stdout = createDummyStream(); + const stderr = createDummyStream(); + const extraStdio = Array.from({length: fileDescriptors.length - 3}, createDummyStream); + const all = createDummyStream(); + const stdio = [stdin, stdout, stderr, ...extraStdio]; + Object.assign(subprocess, { + stdin, + stdout, + stderr, + all, + stdio, + }); +}; + +const createDummyStream = () => { + const stream = new PassThrough(); + stream.end(); + return stream; +}; + +const readable = () => new Readable({read() {}}); +const writable = () => new Writable({write() {}}); +const duplex = () => new Duplex({read() {}, write() {}}); + +const handleDummyPromise = async (error, verboseInfo, options) => handleResult(error, verboseInfo, options); diff --git a/node_modules/execa/lib/return/final-error.js b/node_modules/execa/lib/return/final-error.js new file mode 100644 index 0000000000..045bb6e3ba --- /dev/null +++ b/node_modules/execa/lib/return/final-error.js @@ -0,0 +1,40 @@ +// When the subprocess fails, this is the error instance being returned. +// If another error instance is being thrown, it is kept as `error.cause`. +export const getFinalError = (originalError, message, isSync) => { + const ErrorClass = isSync ? ExecaSyncError : ExecaError; + const options = originalError instanceof DiscardedError ? {} : {cause: originalError}; + return new ErrorClass(message, options); +}; + +// Indicates that the error is used only to interrupt control flow, but not in the return value +export class DiscardedError extends Error {} + +// Proper way to set `error.name`: it should be inherited and non-enumerable +const setErrorName = (ErrorClass, value) => { + Object.defineProperty(ErrorClass.prototype, 'name', { + value, + writable: true, + enumerable: false, + configurable: true, + }); + Object.defineProperty(ErrorClass.prototype, execaErrorSymbol, { + value: true, + writable: false, + enumerable: false, + configurable: false, + }); +}; + +// Unlike `instanceof`, this works across realms +export const isExecaError = error => isErrorInstance(error) && execaErrorSymbol in error; + +const execaErrorSymbol = Symbol('isExecaError'); + +export const isErrorInstance = value => Object.prototype.toString.call(value) === '[object Error]'; + +// We use two different Error classes for async/sync methods since they have slightly different shape and types +export class ExecaError extends Error {} +setErrorName(ExecaError, ExecaError.name); + +export class ExecaSyncError extends Error {} +setErrorName(ExecaSyncError, ExecaSyncError.name); diff --git a/node_modules/execa/lib/return/message.js b/node_modules/execa/lib/return/message.js new file mode 100644 index 0000000000..9a7f22fbe6 --- /dev/null +++ b/node_modules/execa/lib/return/message.js @@ -0,0 +1,157 @@ +import {inspect} from 'node:util'; +import stripFinalNewline from 'strip-final-newline'; +import {isUint8Array, uint8ArrayToString} from '../utils/uint-array.js'; +import {fixCwdError} from '../arguments/cwd.js'; +import {escapeLines} from '../arguments/escape.js'; +import {getMaxBufferMessage} from '../io/max-buffer.js'; +import {getSignalDescription} from '../terminate/signal.js'; +import {DiscardedError, isExecaError} from './final-error.js'; + +// Computes `error.message`, `error.shortMessage` and `error.originalMessage` +export const createMessages = ({ + stdio, + all, + ipcOutput, + originalError, + signal, + signalDescription, + exitCode, + escapedCommand, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + forceKillAfterDelay, + killSignal, + maxBuffer, + timeout, + cwd, +}) => { + const errorCode = originalError?.code; + const prefix = getErrorPrefix({ + originalError, + timedOut, + timeout, + isMaxBuffer, + maxBuffer, + errorCode, + signal, + signalDescription, + exitCode, + isCanceled, + isGracefullyCanceled, + isForcefullyTerminated, + forceKillAfterDelay, + killSignal, + }); + const originalMessage = getOriginalMessage(originalError, cwd); + const suffix = originalMessage === undefined ? '' : `\n${originalMessage}`; + const shortMessage = `${prefix}: ${escapedCommand}${suffix}`; + const messageStdio = all === undefined ? [stdio[2], stdio[1]] : [all]; + const message = [ + shortMessage, + ...messageStdio, + ...stdio.slice(3), + ipcOutput.map(ipcMessage => serializeIpcMessage(ipcMessage)).join('\n'), + ] + .map(messagePart => escapeLines(stripFinalNewline(serializeMessagePart(messagePart)))) + .filter(Boolean) + .join('\n\n'); + return {originalMessage, shortMessage, message}; +}; + +const getErrorPrefix = ({ + originalError, + timedOut, + timeout, + isMaxBuffer, + maxBuffer, + errorCode, + signal, + signalDescription, + exitCode, + isCanceled, + isGracefullyCanceled, + isForcefullyTerminated, + forceKillAfterDelay, + killSignal, +}) => { + const forcefulSuffix = getForcefulSuffix(isForcefullyTerminated, forceKillAfterDelay); + + if (timedOut) { + return `Command timed out after ${timeout} milliseconds${forcefulSuffix}`; + } + + if (isGracefullyCanceled) { + if (signal === undefined) { + return `Command was gracefully canceled with exit code ${exitCode}`; + } + + return isForcefullyTerminated + ? `Command was gracefully canceled${forcefulSuffix}` + : `Command was gracefully canceled with ${signal} (${signalDescription})`; + } + + if (isCanceled) { + return `Command was canceled${forcefulSuffix}`; + } + + if (isMaxBuffer) { + return `${getMaxBufferMessage(originalError, maxBuffer)}${forcefulSuffix}`; + } + + if (errorCode !== undefined) { + return `Command failed with ${errorCode}${forcefulSuffix}`; + } + + if (isForcefullyTerminated) { + return `Command was killed with ${killSignal} (${getSignalDescription(killSignal)})${forcefulSuffix}`; + } + + if (signal !== undefined) { + return `Command was killed with ${signal} (${signalDescription})`; + } + + if (exitCode !== undefined) { + return `Command failed with exit code ${exitCode}`; + } + + return 'Command failed'; +}; + +const getForcefulSuffix = (isForcefullyTerminated, forceKillAfterDelay) => isForcefullyTerminated + ? ` and was forcefully terminated after ${forceKillAfterDelay} milliseconds` + : ''; + +const getOriginalMessage = (originalError, cwd) => { + if (originalError instanceof DiscardedError) { + return; + } + + const originalMessage = isExecaError(originalError) + ? originalError.originalMessage + : String(originalError?.message ?? originalError); + const escapedOriginalMessage = escapeLines(fixCwdError(originalMessage, cwd)); + return escapedOriginalMessage === '' ? undefined : escapedOriginalMessage; +}; + +const serializeIpcMessage = ipcMessage => typeof ipcMessage === 'string' + ? ipcMessage + : inspect(ipcMessage); + +const serializeMessagePart = messagePart => Array.isArray(messagePart) + ? messagePart.map(messageItem => stripFinalNewline(serializeMessageItem(messageItem))).filter(Boolean).join('\n') + : serializeMessageItem(messagePart); + +const serializeMessageItem = messageItem => { + if (typeof messageItem === 'string') { + return messageItem; + } + + if (isUint8Array(messageItem)) { + return uint8ArrayToString(messageItem); + } + + return ''; +}; diff --git a/node_modules/execa/lib/return/reject.js b/node_modules/execa/lib/return/reject.js new file mode 100644 index 0000000000..0f41d6823e --- /dev/null +++ b/node_modules/execa/lib/return/reject.js @@ -0,0 +1,13 @@ +import {logResult} from '../verbose/complete.js'; + +// Applies the `reject` option. +// Also print the final log line with `verbose`. +export const handleResult = (result, verboseInfo, {reject}) => { + logResult(result, verboseInfo); + + if (result.failed && reject) { + throw result; + } + + return result; +}; diff --git a/node_modules/execa/lib/return/result.js b/node_modules/execa/lib/return/result.js new file mode 100644 index 0000000000..daa73fd90f --- /dev/null +++ b/node_modules/execa/lib/return/result.js @@ -0,0 +1,186 @@ +import {getSignalDescription} from '../terminate/signal.js'; +import {getDurationMs} from './duration.js'; +import {getFinalError} from './final-error.js'; +import {createMessages} from './message.js'; + +// Object returned on subprocess success +export const makeSuccessResult = ({ + command, + escapedCommand, + stdio, + all, + ipcOutput, + options: {cwd}, + startTime, +}) => omitUndefinedProperties({ + command, + escapedCommand, + cwd, + durationMs: getDurationMs(startTime), + failed: false, + timedOut: false, + isCanceled: false, + isGracefullyCanceled: false, + isTerminated: false, + isMaxBuffer: false, + isForcefullyTerminated: false, + exitCode: 0, + stdout: stdio[1], + stderr: stdio[2], + all, + stdio, + ipcOutput, + pipedFrom: [], +}); + +// Object returned on subprocess failure before spawning +export const makeEarlyError = ({ + error, + command, + escapedCommand, + fileDescriptors, + options, + startTime, + isSync, +}) => makeError({ + error, + command, + escapedCommand, + startTime, + timedOut: false, + isCanceled: false, + isGracefullyCanceled: false, + isMaxBuffer: false, + isForcefullyTerminated: false, + stdio: Array.from({length: fileDescriptors.length}), + ipcOutput: [], + options, + isSync, +}); + +// Object returned on subprocess failure +export const makeError = ({ + error: originalError, + command, + escapedCommand, + startTime, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + exitCode: rawExitCode, + signal: rawSignal, + stdio, + all, + ipcOutput, + options: { + timeoutDuration, + timeout = timeoutDuration, + forceKillAfterDelay, + killSignal, + cwd, + maxBuffer, + }, + isSync, +}) => { + const {exitCode, signal, signalDescription} = normalizeExitPayload(rawExitCode, rawSignal); + const {originalMessage, shortMessage, message} = createMessages({ + stdio, + all, + ipcOutput, + originalError, + signal, + signalDescription, + exitCode, + escapedCommand, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + forceKillAfterDelay, + killSignal, + maxBuffer, + timeout, + cwd, + }); + const error = getFinalError(originalError, message, isSync); + Object.assign(error, getErrorProperties({ + error, + command, + escapedCommand, + startTime, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + exitCode, + signal, + signalDescription, + stdio, + all, + ipcOutput, + cwd, + originalMessage, + shortMessage, + })); + return error; +}; + +const getErrorProperties = ({ + error, + command, + escapedCommand, + startTime, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + exitCode, + signal, + signalDescription, + stdio, + all, + ipcOutput, + cwd, + originalMessage, + shortMessage, +}) => omitUndefinedProperties({ + shortMessage, + originalMessage, + command, + escapedCommand, + cwd, + durationMs: getDurationMs(startTime), + failed: true, + timedOut, + isCanceled, + isGracefullyCanceled, + isTerminated: signal !== undefined, + isMaxBuffer, + isForcefullyTerminated, + exitCode, + signal, + signalDescription, + code: error.cause?.code, + stdout: stdio[1], + stderr: stdio[2], + all, + stdio, + ipcOutput, + pipedFrom: [], +}); + +const omitUndefinedProperties = result => Object.fromEntries(Object.entries(result).filter(([, value]) => value !== undefined)); + +// `signal` and `exitCode` emitted on `subprocess.on('exit')` event can be `null`. +// We normalize them to `undefined` +const normalizeExitPayload = (rawExitCode, rawSignal) => { + const exitCode = rawExitCode === null ? undefined : rawExitCode; + const signal = rawSignal === null ? undefined : rawSignal; + const signalDescription = signal === undefined ? undefined : getSignalDescription(rawSignal); + return {exitCode, signal, signalDescription}; +}; diff --git a/node_modules/execa/lib/stdio.js b/node_modules/execa/lib/stdio.js deleted file mode 100644 index e8c1132dc1..0000000000 --- a/node_modules/execa/lib/stdio.js +++ /dev/null @@ -1,49 +0,0 @@ -const aliases = ['stdin', 'stdout', 'stderr']; - -const hasAlias = options => aliases.some(alias => options[alias] !== undefined); - -export const normalizeStdio = options => { - if (!options) { - return; - } - - const {stdio} = options; - - if (stdio === undefined) { - return aliases.map(alias => options[alias]); - } - - if (hasAlias(options)) { - throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`); - } - - if (typeof stdio === 'string') { - return stdio; - } - - if (!Array.isArray(stdio)) { - throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); - } - - const length = Math.max(stdio.length, aliases.length); - return Array.from({length}, (value, index) => stdio[index]); -}; - -// `ipc` is pushed unless it is already present -export const normalizeStdioNode = options => { - const stdio = normalizeStdio(options); - - if (stdio === 'ipc') { - return 'ipc'; - } - - if (stdio === undefined || typeof stdio === 'string') { - return [stdio, stdio, stdio, 'ipc']; - } - - if (stdio.includes('ipc')) { - return stdio; - } - - return [...stdio, 'ipc']; -}; diff --git a/node_modules/execa/lib/stdio/direction.js b/node_modules/execa/lib/stdio/direction.js new file mode 100644 index 0000000000..57c18c261d --- /dev/null +++ b/node_modules/execa/lib/stdio/direction.js @@ -0,0 +1,76 @@ +import process from 'node:process'; +import { + isStream as isNodeStream, + isReadableStream as isNodeReadableStream, + isWritableStream as isNodeWritableStream, +} from 'is-stream'; +import {isWritableStream} from './type.js'; + +// For `stdio[fdNumber]` beyond stdin/stdout/stderr, we need to guess whether the value passed is intended for inputs or outputs. +// This allows us to know whether to pipe _into_ or _from_ the stream. +// When `stdio[fdNumber]` is a single value, this guess is fairly straightforward. +// However, when it is an array instead, we also need to make sure the different values are not incompatible with each other. +export const getStreamDirection = (stdioItems, fdNumber, optionName) => { + const directions = stdioItems.map(stdioItem => getStdioItemDirection(stdioItem, fdNumber)); + + if (directions.includes('input') && directions.includes('output')) { + throw new TypeError(`The \`${optionName}\` option must not be an array of both readable and writable values.`); + } + + return directions.find(Boolean) ?? DEFAULT_DIRECTION; +}; + +const getStdioItemDirection = ({type, value}, fdNumber) => KNOWN_DIRECTIONS[fdNumber] ?? guessStreamDirection[type](value); + +// `stdin`/`stdout`/`stderr` have a known direction +const KNOWN_DIRECTIONS = ['input', 'output', 'output']; + +const anyDirection = () => undefined; +const alwaysInput = () => 'input'; + +// `string` can only be added through the `input` option, i.e. does not need to be handled here +const guessStreamDirection = { + generator: anyDirection, + asyncGenerator: anyDirection, + fileUrl: anyDirection, + filePath: anyDirection, + iterable: alwaysInput, + asyncIterable: alwaysInput, + uint8Array: alwaysInput, + webStream: value => isWritableStream(value) ? 'output' : 'input', + nodeStream(value) { + if (!isNodeReadableStream(value, {checkOpen: false})) { + return 'output'; + } + + return isNodeWritableStream(value, {checkOpen: false}) ? undefined : 'input'; + }, + webTransform: anyDirection, + duplex: anyDirection, + native(value) { + const standardStreamDirection = getStandardStreamDirection(value); + if (standardStreamDirection !== undefined) { + return standardStreamDirection; + } + + if (isNodeStream(value, {checkOpen: false})) { + return guessStreamDirection.nodeStream(value); + } + }, +}; + +const getStandardStreamDirection = value => { + if ([0, process.stdin].includes(value)) { + return 'input'; + } + + if ([1, 2, process.stdout, process.stderr].includes(value)) { + return 'output'; + } +}; + +// When ambiguous, we initially keep the direction as `undefined`. +// This allows arrays of `stdio` values to resolve the ambiguity. +// For example, `stdio[3]: DuplexStream` is ambiguous, but `stdio[3]: [DuplexStream, WritableStream]` is not. +// When the ambiguity remains, we default to `output` since it is the most common use case for additional file descriptors. +const DEFAULT_DIRECTION = 'output'; diff --git a/node_modules/execa/lib/stdio/duplicate.js b/node_modules/execa/lib/stdio/duplicate.js new file mode 100644 index 0000000000..7f5b9a45bd --- /dev/null +++ b/node_modules/execa/lib/stdio/duplicate.js @@ -0,0 +1,116 @@ +import { + SPECIAL_DUPLICATE_TYPES_SYNC, + SPECIAL_DUPLICATE_TYPES, + FORBID_DUPLICATE_TYPES, + TYPE_TO_MESSAGE, +} from './type.js'; + +// Duplicates in the same file descriptor is most likely an error. +// However, this can be useful with generators. +export const filterDuplicates = stdioItems => stdioItems.filter((stdioItemOne, indexOne) => + stdioItems.every((stdioItemTwo, indexTwo) => stdioItemOne.value !== stdioItemTwo.value + || indexOne >= indexTwo + || stdioItemOne.type === 'generator' + || stdioItemOne.type === 'asyncGenerator')); + +// Check if two file descriptors are sharing the same target. +// For example `{stdout: {file: './output.txt'}, stderr: {file: './output.txt'}}`. +export const getDuplicateStream = ({stdioItem: {type, value, optionName}, direction, fileDescriptors, isSync}) => { + const otherStdioItems = getOtherStdioItems(fileDescriptors, type); + if (otherStdioItems.length === 0) { + return; + } + + if (isSync) { + validateDuplicateStreamSync({ + otherStdioItems, + type, + value, + optionName, + direction, + }); + return; + } + + if (SPECIAL_DUPLICATE_TYPES.has(type)) { + return getDuplicateStreamInstance({ + otherStdioItems, + type, + value, + optionName, + direction, + }); + } + + if (FORBID_DUPLICATE_TYPES.has(type)) { + validateDuplicateTransform({ + otherStdioItems, + type, + value, + optionName, + }); + } +}; + +// Values shared by multiple file descriptors +const getOtherStdioItems = (fileDescriptors, type) => fileDescriptors + .flatMap(({direction, stdioItems}) => stdioItems + .filter(stdioItem => stdioItem.type === type) + .map((stdioItem => ({...stdioItem, direction})))); + +// With `execaSync()`, do not allow setting a file path both in input and output +const validateDuplicateStreamSync = ({otherStdioItems, type, value, optionName, direction}) => { + if (SPECIAL_DUPLICATE_TYPES_SYNC.has(type)) { + getDuplicateStreamInstance({ + otherStdioItems, + type, + value, + optionName, + direction, + }); + } +}; + +// When two file descriptors share the file or stream, we need to re-use the same underlying stream. +// Otherwise, the stream would be closed twice when piping ends. +// This is only an issue with output file descriptors. +// This is not a problem with generator functions since those create a new instance for each file descriptor. +// We also forbid input and output file descriptors sharing the same file or stream, since that does not make sense. +const getDuplicateStreamInstance = ({otherStdioItems, type, value, optionName, direction}) => { + const duplicateStdioItems = otherStdioItems.filter(stdioItem => hasSameValue(stdioItem, value)); + if (duplicateStdioItems.length === 0) { + return; + } + + const differentStdioItem = duplicateStdioItems.find(stdioItem => stdioItem.direction !== direction); + throwOnDuplicateStream(differentStdioItem, optionName, type); + + return direction === 'output' ? duplicateStdioItems[0].stream : undefined; +}; + +const hasSameValue = ({type, value}, secondValue) => { + if (type === 'filePath') { + return value.file === secondValue.file; + } + + if (type === 'fileUrl') { + return value.href === secondValue.href; + } + + return value === secondValue; +}; + +// We do not allow two file descriptors to share the same Duplex or TransformStream. +// This is because those are set directly to `subprocess.std*`. +// For example, this could result in `subprocess.stdout` and `subprocess.stderr` being the same value. +// This means reading from either would get data from both stdout and stderr. +const validateDuplicateTransform = ({otherStdioItems, type, value, optionName}) => { + const duplicateStdioItem = otherStdioItems.find(({value: {transform}}) => transform === value.transform); + throwOnDuplicateStream(duplicateStdioItem, optionName, type); +}; + +const throwOnDuplicateStream = (stdioItem, optionName, type) => { + if (stdioItem !== undefined) { + throw new TypeError(`The \`${stdioItem.optionName}\` and \`${optionName}\` options must not target ${TYPE_TO_MESSAGE[type]} that is the same.`); + } +}; diff --git a/node_modules/execa/lib/stdio/handle-async.js b/node_modules/execa/lib/stdio/handle-async.js new file mode 100644 index 0000000000..32fb352845 --- /dev/null +++ b/node_modules/execa/lib/stdio/handle-async.js @@ -0,0 +1,52 @@ +import {createReadStream, createWriteStream} from 'node:fs'; +import {Buffer} from 'node:buffer'; +import {Readable, Writable, Duplex} from 'node:stream'; +import {generatorToStream} from '../transform/generator.js'; +import {handleStdio} from './handle.js'; +import {TYPE_TO_MESSAGE} from './type.js'; + +// Handle `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, before spawning, in async mode +export const handleStdioAsync = (options, verboseInfo) => handleStdio(addPropertiesAsync, options, verboseInfo, false); + +const forbiddenIfAsync = ({type, optionName}) => { + throw new TypeError(`The \`${optionName}\` option cannot be ${TYPE_TO_MESSAGE[type]}.`); +}; + +// Create streams used internally for piping when using specific values for the `std*` options, in async mode. +// For example, `stdout: {file}` creates a file stream, which is piped from/to. +const addProperties = { + fileNumber: forbiddenIfAsync, + generator: generatorToStream, + asyncGenerator: generatorToStream, + nodeStream: ({value}) => ({stream: value}), + webTransform({value: {transform, writableObjectMode, readableObjectMode}}) { + const objectMode = writableObjectMode || readableObjectMode; + const stream = Duplex.fromWeb(transform, {objectMode}); + return {stream}; + }, + duplex: ({value: {transform}}) => ({stream: transform}), + native() {}, +}; + +const addPropertiesAsync = { + input: { + ...addProperties, + fileUrl: ({value}) => ({stream: createReadStream(value)}), + filePath: ({value: {file}}) => ({stream: createReadStream(file)}), + webStream: ({value}) => ({stream: Readable.fromWeb(value)}), + iterable: ({value}) => ({stream: Readable.from(value)}), + asyncIterable: ({value}) => ({stream: Readable.from(value)}), + string: ({value}) => ({stream: Readable.from(value)}), + uint8Array: ({value}) => ({stream: Readable.from(Buffer.from(value))}), + }, + output: { + ...addProperties, + fileUrl: ({value}) => ({stream: createWriteStream(value)}), + filePath: ({value: {file, append}}) => ({stream: createWriteStream(file, append ? {flags: 'a'} : {})}), + webStream: ({value}) => ({stream: Writable.fromWeb(value)}), + iterable: forbiddenIfAsync, + asyncIterable: forbiddenIfAsync, + string: forbiddenIfAsync, + uint8Array: forbiddenIfAsync, + }, +}; diff --git a/node_modules/execa/lib/stdio/handle-sync.js b/node_modules/execa/lib/stdio/handle-sync.js new file mode 100644 index 0000000000..07b8c2b752 --- /dev/null +++ b/node_modules/execa/lib/stdio/handle-sync.js @@ -0,0 +1,57 @@ +import {readFileSync} from 'node:fs'; +import {bufferToUint8Array} from '../utils/uint-array.js'; +import {handleStdio} from './handle.js'; +import {TYPE_TO_MESSAGE} from './type.js'; + +// Normalize `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, before spawning, in sync mode +export const handleStdioSync = (options, verboseInfo) => handleStdio(addPropertiesSync, options, verboseInfo, true); + +const forbiddenIfSync = ({type, optionName}) => { + throwInvalidSyncValue(optionName, TYPE_TO_MESSAGE[type]); +}; + +const forbiddenNativeIfSync = ({optionName, value}) => { + if (value === 'ipc' || value === 'overlapped') { + throwInvalidSyncValue(optionName, `"${value}"`); + } + + return {}; +}; + +const throwInvalidSyncValue = (optionName, value) => { + throw new TypeError(`The \`${optionName}\` option cannot be ${value} with synchronous methods.`); +}; + +// Create streams used internally for redirecting when using specific values for the `std*` options, in sync mode. +// For example, `stdin: {file}` reads the file synchronously, then passes it as the `input` option. +const addProperties = { + generator() {}, + asyncGenerator: forbiddenIfSync, + webStream: forbiddenIfSync, + nodeStream: forbiddenIfSync, + webTransform: forbiddenIfSync, + duplex: forbiddenIfSync, + asyncIterable: forbiddenIfSync, + native: forbiddenNativeIfSync, +}; + +const addPropertiesSync = { + input: { + ...addProperties, + fileUrl: ({value}) => ({contents: [bufferToUint8Array(readFileSync(value))]}), + filePath: ({value: {file}}) => ({contents: [bufferToUint8Array(readFileSync(file))]}), + fileNumber: forbiddenIfSync, + iterable: ({value}) => ({contents: [...value]}), + string: ({value}) => ({contents: [value]}), + uint8Array: ({value}) => ({contents: [value]}), + }, + output: { + ...addProperties, + fileUrl: ({value}) => ({path: value}), + filePath: ({value: {file, append}}) => ({path: file, append}), + fileNumber: ({value}) => ({path: value}), + iterable: forbiddenIfSync, + string: forbiddenIfSync, + uint8Array: forbiddenIfSync, + }, +}; diff --git a/node_modules/execa/lib/stdio/handle.js b/node_modules/execa/lib/stdio/handle.js new file mode 100644 index 0000000000..eeeb220b04 --- /dev/null +++ b/node_modules/execa/lib/stdio/handle.js @@ -0,0 +1,214 @@ +import {getStreamName, isStandardStream} from '../utils/standard-stream.js'; +import {normalizeTransforms} from '../transform/normalize.js'; +import {getFdObjectMode} from '../transform/object-mode.js'; +import { + getStdioItemType, + isRegularUrl, + isUnknownStdioString, + FILE_TYPES, +} from './type.js'; +import {getStreamDirection} from './direction.js'; +import {normalizeStdioOption} from './stdio-option.js'; +import {handleNativeStream} from './native.js'; +import {handleInputOptions} from './input-option.js'; +import {filterDuplicates, getDuplicateStream} from './duplicate.js'; + +// Handle `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, before spawning, in async/sync mode +// They are converted into an array of `fileDescriptors`. +// Each `fileDescriptor` is normalized, validated and contains all information necessary for further handling. +export const handleStdio = (addProperties, options, verboseInfo, isSync) => { + const stdio = normalizeStdioOption(options, verboseInfo, isSync); + const initialFileDescriptors = stdio.map((stdioOption, fdNumber) => getFileDescriptor({ + stdioOption, + fdNumber, + options, + isSync, + })); + const fileDescriptors = getFinalFileDescriptors({ + initialFileDescriptors, + addProperties, + options, + isSync, + }); + options.stdio = fileDescriptors.map(({stdioItems}) => forwardStdio(stdioItems)); + return fileDescriptors; +}; + +const getFileDescriptor = ({stdioOption, fdNumber, options, isSync}) => { + const optionName = getStreamName(fdNumber); + const {stdioItems: initialStdioItems, isStdioArray} = initializeStdioItems({ + stdioOption, + fdNumber, + options, + optionName, + }); + const direction = getStreamDirection(initialStdioItems, fdNumber, optionName); + const stdioItems = initialStdioItems.map(stdioItem => handleNativeStream({ + stdioItem, + isStdioArray, + fdNumber, + direction, + isSync, + })); + const normalizedStdioItems = normalizeTransforms(stdioItems, optionName, direction, options); + const objectMode = getFdObjectMode(normalizedStdioItems, direction); + validateFileObjectMode(normalizedStdioItems, objectMode); + return {direction, objectMode, stdioItems: normalizedStdioItems}; +}; + +// We make sure passing an array with a single item behaves the same as passing that item without an array. +// This is what users would expect. +// For example, `stdout: ['ignore']` behaves the same as `stdout: 'ignore'`. +const initializeStdioItems = ({stdioOption, fdNumber, options, optionName}) => { + const values = Array.isArray(stdioOption) ? stdioOption : [stdioOption]; + const initialStdioItems = [ + ...values.map(value => initializeStdioItem(value, optionName)), + ...handleInputOptions(options, fdNumber), + ]; + + const stdioItems = filterDuplicates(initialStdioItems); + const isStdioArray = stdioItems.length > 1; + validateStdioArray(stdioItems, isStdioArray, optionName); + validateStreams(stdioItems); + return {stdioItems, isStdioArray}; +}; + +const initializeStdioItem = (value, optionName) => ({ + type: getStdioItemType(value, optionName), + value, + optionName, +}); + +const validateStdioArray = (stdioItems, isStdioArray, optionName) => { + if (stdioItems.length === 0) { + throw new TypeError(`The \`${optionName}\` option must not be an empty array.`); + } + + if (!isStdioArray) { + return; + } + + for (const {value, optionName} of stdioItems) { + if (INVALID_STDIO_ARRAY_OPTIONS.has(value)) { + throw new Error(`The \`${optionName}\` option must not include \`${value}\`.`); + } + } +}; + +// Using those `stdio` values together with others for the same stream does not make sense, so we make it fail. +// However, we do allow it if the array has a single item. +const INVALID_STDIO_ARRAY_OPTIONS = new Set(['ignore', 'ipc']); + +const validateStreams = stdioItems => { + for (const stdioItem of stdioItems) { + validateFileStdio(stdioItem); + } +}; + +const validateFileStdio = ({type, value, optionName}) => { + if (isRegularUrl(value)) { + throw new TypeError(`The \`${optionName}: URL\` option must use the \`file:\` scheme. +For example, you can use the \`pathToFileURL()\` method of the \`url\` core module.`); + } + + if (isUnknownStdioString(type, value)) { + throw new TypeError(`The \`${optionName}: { file: '...' }\` option must be used instead of \`${optionName}: '...'\`.`); + } +}; + +const validateFileObjectMode = (stdioItems, objectMode) => { + if (!objectMode) { + return; + } + + const fileStdioItem = stdioItems.find(({type}) => FILE_TYPES.has(type)); + if (fileStdioItem !== undefined) { + throw new TypeError(`The \`${fileStdioItem.optionName}\` option cannot use both files and transforms in objectMode.`); + } +}; + +// Some `stdio` values require Execa to create streams. +// For example, file paths create file read/write streams. +// Those transformations are specified in `addProperties`, which is both direction-specific and type-specific. +const getFinalFileDescriptors = ({initialFileDescriptors, addProperties, options, isSync}) => { + const fileDescriptors = []; + + try { + for (const fileDescriptor of initialFileDescriptors) { + fileDescriptors.push(getFinalFileDescriptor({ + fileDescriptor, + fileDescriptors, + addProperties, + options, + isSync, + })); + } + + return fileDescriptors; + } catch (error) { + cleanupCustomStreams(fileDescriptors); + throw error; + } +}; + +const getFinalFileDescriptor = ({ + fileDescriptor: {direction, objectMode, stdioItems}, + fileDescriptors, + addProperties, + options, + isSync, +}) => { + const finalStdioItems = stdioItems.map(stdioItem => addStreamProperties({ + stdioItem, + addProperties, + direction, + options, + fileDescriptors, + isSync, + })); + return {direction, objectMode, stdioItems: finalStdioItems}; +}; + +const addStreamProperties = ({stdioItem, addProperties, direction, options, fileDescriptors, isSync}) => { + const duplicateStream = getDuplicateStream({ + stdioItem, + direction, + fileDescriptors, + isSync, + }); + + if (duplicateStream !== undefined) { + return {...stdioItem, stream: duplicateStream}; + } + + return { + ...stdioItem, + ...addProperties[direction][stdioItem.type](stdioItem, options), + }; +}; + +// The stream error handling is performed by the piping logic above, which cannot be performed before subprocess spawning. +// If the subprocess spawning fails (e.g. due to an invalid command), the streams need to be manually destroyed. +// We need to create those streams before subprocess spawning, in case their creation fails, e.g. when passing an invalid generator as argument. +// Like this, an exception would be thrown, which would prevent spawning a subprocess. +export const cleanupCustomStreams = fileDescriptors => { + for (const {stdioItems} of fileDescriptors) { + for (const {stream} of stdioItems) { + if (stream !== undefined && !isStandardStream(stream)) { + stream.destroy(); + } + } + } +}; + +// When the `std*: Iterable | WebStream | URL | filePath`, `input` or `inputFile` option is used, we pipe to `subprocess.std*`. +// When the `std*: Array` option is used, we emulate some of the native values ('inherit', Node.js stream and file descriptor integer). To do so, we also need to pipe to `subprocess.std*`. +// Therefore the `std*` options must be either `pipe` or `overlapped`. Other values do not set `subprocess.std*`. +const forwardStdio = stdioItems => { + if (stdioItems.length > 1) { + return stdioItems.some(({value}) => value === 'overlapped') ? 'overlapped' : 'pipe'; + } + + const [{type, value}] = stdioItems; + return type === 'native' ? value : 'pipe'; +}; diff --git a/node_modules/execa/lib/stdio/input-option.js b/node_modules/execa/lib/stdio/input-option.js new file mode 100644 index 0000000000..361538bf39 --- /dev/null +++ b/node_modules/execa/lib/stdio/input-option.js @@ -0,0 +1,50 @@ +import {isReadableStream} from 'is-stream'; +import {isUint8Array} from '../utils/uint-array.js'; +import {isUrl, isFilePathString} from './type.js'; + +// Append the `stdin` option with the `input` and `inputFile` options +export const handleInputOptions = ({input, inputFile}, fdNumber) => fdNumber === 0 + ? [ + ...handleInputOption(input), + ...handleInputFileOption(inputFile), + ] + : []; + +const handleInputOption = input => input === undefined ? [] : [{ + type: getInputType(input), + value: input, + optionName: 'input', +}]; + +const getInputType = input => { + if (isReadableStream(input, {checkOpen: false})) { + return 'nodeStream'; + } + + if (typeof input === 'string') { + return 'string'; + } + + if (isUint8Array(input)) { + return 'uint8Array'; + } + + throw new Error('The `input` option must be a string, a Uint8Array or a Node.js Readable stream.'); +}; + +const handleInputFileOption = inputFile => inputFile === undefined ? [] : [{ + ...getInputFileType(inputFile), + optionName: 'inputFile', +}]; + +const getInputFileType = inputFile => { + if (isUrl(inputFile)) { + return {type: 'fileUrl', value: inputFile}; + } + + if (isFilePathString(inputFile)) { + return {type: 'filePath', value: {file: inputFile}}; + } + + throw new Error('The `inputFile` option must be a file path string or a file URL.'); +}; diff --git a/node_modules/execa/lib/stdio/native.js b/node_modules/execa/lib/stdio/native.js new file mode 100644 index 0000000000..e967326a86 --- /dev/null +++ b/node_modules/execa/lib/stdio/native.js @@ -0,0 +1,106 @@ +import {readFileSync} from 'node:fs'; +import tty from 'node:tty'; +import {isStream as isNodeStream} from 'is-stream'; +import {STANDARD_STREAMS} from '../utils/standard-stream.js'; +import {bufferToUint8Array} from '../utils/uint-array.js'; +import {serializeOptionValue} from '../arguments/fd-options.js'; + +// When we use multiple `stdio` values for the same streams, we pass 'pipe' to `child_process.spawn()`. +// We then emulate the piping done by core Node.js. +// To do so, we transform the following values: +// - Node.js streams are marked as `type: nodeStream` +// - 'inherit' becomes `process.stdin|stdout|stderr` +// - any file descriptor integer becomes `process.stdio[fdNumber]` +// All of the above transformations tell Execa to perform manual piping. +export const handleNativeStream = ({stdioItem, stdioItem: {type}, isStdioArray, fdNumber, direction, isSync}) => { + if (!isStdioArray || type !== 'native') { + return stdioItem; + } + + return isSync + ? handleNativeStreamSync({stdioItem, fdNumber, direction}) + : handleNativeStreamAsync({stdioItem, fdNumber}); +}; + +// Synchronous methods use a different logic. +// 'inherit', file descriptors and process.std* are handled by readFileSync()/writeFileSync(). +const handleNativeStreamSync = ({stdioItem, stdioItem: {value, optionName}, fdNumber, direction}) => { + const targetFd = getTargetFd({ + value, + optionName, + fdNumber, + direction, + }); + if (targetFd !== undefined) { + return targetFd; + } + + if (isNodeStream(value, {checkOpen: false})) { + throw new TypeError(`The \`${optionName}: Stream\` option cannot both be an array and include a stream with synchronous methods.`); + } + + return stdioItem; +}; + +const getTargetFd = ({value, optionName, fdNumber, direction}) => { + const targetFdNumber = getTargetFdNumber(value, fdNumber); + if (targetFdNumber === undefined) { + return; + } + + if (direction === 'output') { + return {type: 'fileNumber', value: targetFdNumber, optionName}; + } + + if (tty.isatty(targetFdNumber)) { + throw new TypeError(`The \`${optionName}: ${serializeOptionValue(value)}\` option is invalid: it cannot be a TTY with synchronous methods.`); + } + + return {type: 'uint8Array', value: bufferToUint8Array(readFileSync(targetFdNumber)), optionName}; +}; + +const getTargetFdNumber = (value, fdNumber) => { + if (value === 'inherit') { + return fdNumber; + } + + if (typeof value === 'number') { + return value; + } + + const standardStreamIndex = STANDARD_STREAMS.indexOf(value); + if (standardStreamIndex !== -1) { + return standardStreamIndex; + } +}; + +const handleNativeStreamAsync = ({stdioItem, stdioItem: {value, optionName}, fdNumber}) => { + if (value === 'inherit') { + return {type: 'nodeStream', value: getStandardStream(fdNumber, value, optionName), optionName}; + } + + if (typeof value === 'number') { + return {type: 'nodeStream', value: getStandardStream(value, value, optionName), optionName}; + } + + if (isNodeStream(value, {checkOpen: false})) { + return {type: 'nodeStream', value, optionName}; + } + + return stdioItem; +}; + +// Node.js does not allow to easily retrieve file descriptors beyond stdin/stdout/stderr as streams. +// - `fs.createReadStream()`/`fs.createWriteStream()` with the `fd` option do not work with character devices that use blocking reads/writes (such as interactive TTYs). +// - Using a TCP `Socket` would work but be rather complex to implement. +// Since this is an edge case, we simply throw an error message. +// See https://github.com/sindresorhus/execa/pull/643#discussion_r1435905707 +const getStandardStream = (fdNumber, value, optionName) => { + const standardStream = STANDARD_STREAMS[fdNumber]; + + if (standardStream === undefined) { + throw new TypeError(`The \`${optionName}: ${value}\` option is invalid: no such standard stream.`); + } + + return standardStream; +}; diff --git a/node_modules/execa/lib/stdio/stdio-option.js b/node_modules/execa/lib/stdio/stdio-option.js new file mode 100644 index 0000000000..192cea5b4b --- /dev/null +++ b/node_modules/execa/lib/stdio/stdio-option.js @@ -0,0 +1,60 @@ +import {STANDARD_STREAMS_ALIASES} from '../utils/standard-stream.js'; +import {normalizeIpcStdioArray} from '../ipc/array.js'; +import {isFullVerbose} from '../verbose/values.js'; + +// Add support for `stdin`/`stdout`/`stderr` as an alias for `stdio`. +// Also normalize the `stdio` option. +export const normalizeStdioOption = ({stdio, ipc, buffer, ...options}, verboseInfo, isSync) => { + const stdioArray = getStdioArray(stdio, options).map((stdioOption, fdNumber) => addDefaultValue(stdioOption, fdNumber)); + return isSync + ? normalizeStdioSync(stdioArray, buffer, verboseInfo) + : normalizeIpcStdioArray(stdioArray, ipc); +}; + +const getStdioArray = (stdio, options) => { + if (stdio === undefined) { + return STANDARD_STREAMS_ALIASES.map(alias => options[alias]); + } + + if (hasAlias(options)) { + throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${STANDARD_STREAMS_ALIASES.map(alias => `\`${alias}\``).join(', ')}`); + } + + if (typeof stdio === 'string') { + return [stdio, stdio, stdio]; + } + + if (!Array.isArray(stdio)) { + throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); + } + + const length = Math.max(stdio.length, STANDARD_STREAMS_ALIASES.length); + return Array.from({length}, (_, fdNumber) => stdio[fdNumber]); +}; + +const hasAlias = options => STANDARD_STREAMS_ALIASES.some(alias => options[alias] !== undefined); + +const addDefaultValue = (stdioOption, fdNumber) => { + if (Array.isArray(stdioOption)) { + return stdioOption.map(item => addDefaultValue(item, fdNumber)); + } + + if (stdioOption === null || stdioOption === undefined) { + return fdNumber >= STANDARD_STREAMS_ALIASES.length ? 'ignore' : 'pipe'; + } + + return stdioOption; +}; + +// Using `buffer: false` with synchronous methods implies `stdout`/`stderr`: `ignore`. +// Unless the output is needed, e.g. due to `verbose: 'full'` or to redirecting to a file. +const normalizeStdioSync = (stdioArray, buffer, verboseInfo) => stdioArray.map((stdioOption, fdNumber) => + !buffer[fdNumber] + && fdNumber !== 0 + && !isFullVerbose(verboseInfo, fdNumber) + && isOutputPipeOnly(stdioOption) + ? 'ignore' + : stdioOption); + +const isOutputPipeOnly = stdioOption => stdioOption === 'pipe' + || (Array.isArray(stdioOption) && stdioOption.every(item => item === 'pipe')); diff --git a/node_modules/execa/lib/stdio/type.js b/node_modules/execa/lib/stdio/type.js new file mode 100644 index 0000000000..eb9dfcf146 --- /dev/null +++ b/node_modules/execa/lib/stdio/type.js @@ -0,0 +1,173 @@ +import {isStream as isNodeStream, isDuplexStream} from 'is-stream'; +import isPlainObj from 'is-plain-obj'; +import {isUint8Array} from '../utils/uint-array.js'; + +// The `stdin`/`stdout`/`stderr` option can be of many types. This detects it. +export const getStdioItemType = (value, optionName) => { + if (isAsyncGenerator(value)) { + return 'asyncGenerator'; + } + + if (isSyncGenerator(value)) { + return 'generator'; + } + + if (isUrl(value)) { + return 'fileUrl'; + } + + if (isFilePathObject(value)) { + return 'filePath'; + } + + if (isWebStream(value)) { + return 'webStream'; + } + + if (isNodeStream(value, {checkOpen: false})) { + return 'native'; + } + + if (isUint8Array(value)) { + return 'uint8Array'; + } + + if (isAsyncIterableObject(value)) { + return 'asyncIterable'; + } + + if (isIterableObject(value)) { + return 'iterable'; + } + + if (isTransformStream(value)) { + return getTransformStreamType({transform: value}, optionName); + } + + if (isTransformOptions(value)) { + return getTransformObjectType(value, optionName); + } + + return 'native'; +}; + +const getTransformObjectType = (value, optionName) => { + if (isDuplexStream(value.transform, {checkOpen: false})) { + return getDuplexType(value, optionName); + } + + if (isTransformStream(value.transform)) { + return getTransformStreamType(value, optionName); + } + + return getGeneratorObjectType(value, optionName); +}; + +const getDuplexType = (value, optionName) => { + validateNonGeneratorType(value, optionName, 'Duplex stream'); + return 'duplex'; +}; + +const getTransformStreamType = (value, optionName) => { + validateNonGeneratorType(value, optionName, 'web TransformStream'); + return 'webTransform'; +}; + +const validateNonGeneratorType = ({final, binary, objectMode}, optionName, typeName) => { + checkUndefinedOption(final, `${optionName}.final`, typeName); + checkUndefinedOption(binary, `${optionName}.binary`, typeName); + checkBooleanOption(objectMode, `${optionName}.objectMode`); +}; + +const checkUndefinedOption = (value, optionName, typeName) => { + if (value !== undefined) { + throw new TypeError(`The \`${optionName}\` option can only be defined when using a generator, not a ${typeName}.`); + } +}; + +const getGeneratorObjectType = ({transform, final, binary, objectMode}, optionName) => { + if (transform !== undefined && !isGenerator(transform)) { + throw new TypeError(`The \`${optionName}.transform\` option must be a generator, a Duplex stream or a web TransformStream.`); + } + + if (isDuplexStream(final, {checkOpen: false})) { + throw new TypeError(`The \`${optionName}.final\` option must not be a Duplex stream.`); + } + + if (isTransformStream(final)) { + throw new TypeError(`The \`${optionName}.final\` option must not be a web TransformStream.`); + } + + if (final !== undefined && !isGenerator(final)) { + throw new TypeError(`The \`${optionName}.final\` option must be a generator.`); + } + + checkBooleanOption(binary, `${optionName}.binary`); + checkBooleanOption(objectMode, `${optionName}.objectMode`); + + return isAsyncGenerator(transform) || isAsyncGenerator(final) ? 'asyncGenerator' : 'generator'; +}; + +const checkBooleanOption = (value, optionName) => { + if (value !== undefined && typeof value !== 'boolean') { + throw new TypeError(`The \`${optionName}\` option must use a boolean.`); + } +}; + +const isGenerator = value => isAsyncGenerator(value) || isSyncGenerator(value); +export const isAsyncGenerator = value => Object.prototype.toString.call(value) === '[object AsyncGeneratorFunction]'; +const isSyncGenerator = value => Object.prototype.toString.call(value) === '[object GeneratorFunction]'; +const isTransformOptions = value => isPlainObj(value) + && (value.transform !== undefined || value.final !== undefined); + +export const isUrl = value => Object.prototype.toString.call(value) === '[object URL]'; +export const isRegularUrl = value => isUrl(value) && value.protocol !== 'file:'; + +const isFilePathObject = value => isPlainObj(value) + && Object.keys(value).length > 0 + && Object.keys(value).every(key => FILE_PATH_KEYS.has(key)) + && isFilePathString(value.file); +const FILE_PATH_KEYS = new Set(['file', 'append']); +export const isFilePathString = file => typeof file === 'string'; + +export const isUnknownStdioString = (type, value) => type === 'native' + && typeof value === 'string' + && !KNOWN_STDIO_STRINGS.has(value); +const KNOWN_STDIO_STRINGS = new Set(['ipc', 'ignore', 'inherit', 'overlapped', 'pipe']); + +const isReadableStream = value => Object.prototype.toString.call(value) === '[object ReadableStream]'; +export const isWritableStream = value => Object.prototype.toString.call(value) === '[object WritableStream]'; +const isWebStream = value => isReadableStream(value) || isWritableStream(value); +const isTransformStream = value => isReadableStream(value?.readable) && isWritableStream(value?.writable); + +const isAsyncIterableObject = value => isObject(value) && typeof value[Symbol.asyncIterator] === 'function'; +const isIterableObject = value => isObject(value) && typeof value[Symbol.iterator] === 'function'; +const isObject = value => typeof value === 'object' && value !== null; + +// Types which modify `subprocess.std*` +export const TRANSFORM_TYPES = new Set(['generator', 'asyncGenerator', 'duplex', 'webTransform']); +// Types which write to a file or a file descriptor +export const FILE_TYPES = new Set(['fileUrl', 'filePath', 'fileNumber']); +// When two file descriptors of this type share the same target, we need to do some special logic +export const SPECIAL_DUPLICATE_TYPES_SYNC = new Set(['fileUrl', 'filePath']); +export const SPECIAL_DUPLICATE_TYPES = new Set([...SPECIAL_DUPLICATE_TYPES_SYNC, 'webStream', 'nodeStream']); +// Do not allow two file descriptors of this type sharing the same target +export const FORBID_DUPLICATE_TYPES = new Set(['webTransform', 'duplex']); + +// Convert types to human-friendly strings for error messages +export const TYPE_TO_MESSAGE = { + generator: 'a generator', + asyncGenerator: 'an async generator', + fileUrl: 'a file URL', + filePath: 'a file path string', + fileNumber: 'a file descriptor number', + webStream: 'a web stream', + nodeStream: 'a Node.js stream', + webTransform: 'a web TransformStream', + duplex: 'a Duplex stream', + native: 'any value', + iterable: 'an iterable', + asyncIterable: 'an async iterable', + string: 'a string', + uint8Array: 'a Uint8Array', +}; diff --git a/node_modules/execa/lib/stream.js b/node_modules/execa/lib/stream.js deleted file mode 100644 index 5f79b791d9..0000000000 --- a/node_modules/execa/lib/stream.js +++ /dev/null @@ -1,119 +0,0 @@ -import {createReadStream, readFileSync} from 'node:fs'; -import {isStream} from 'is-stream'; -import getStream from 'get-stream'; -import mergeStream from 'merge-stream'; - -const validateInputOptions = input => { - if (input !== undefined) { - throw new TypeError('The `input` and `inputFile` options cannot be both set.'); - } -}; - -const getInputSync = ({input, inputFile}) => { - if (typeof inputFile !== 'string') { - return input; - } - - validateInputOptions(input); - return readFileSync(inputFile); -}; - -// `input` and `inputFile` option in sync mode -export const handleInputSync = options => { - const input = getInputSync(options); - - if (isStream(input)) { - throw new TypeError('The `input` option cannot be a stream in sync mode'); - } - - return input; -}; - -const getInput = ({input, inputFile}) => { - if (typeof inputFile !== 'string') { - return input; - } - - validateInputOptions(input); - return createReadStream(inputFile); -}; - -// `input` and `inputFile` option in async mode -export const handleInput = (spawned, options) => { - const input = getInput(options); - - if (input === undefined) { - return; - } - - if (isStream(input)) { - input.pipe(spawned.stdin); - } else { - spawned.stdin.end(input); - } -}; - -// `all` interleaves `stdout` and `stderr` -export const makeAllStream = (spawned, {all}) => { - if (!all || (!spawned.stdout && !spawned.stderr)) { - return; - } - - const mixed = mergeStream(); - - if (spawned.stdout) { - mixed.add(spawned.stdout); - } - - if (spawned.stderr) { - mixed.add(spawned.stderr); - } - - return mixed; -}; - -// On failure, `result.stdout|stderr|all` should contain the currently buffered stream -const getBufferedData = async (stream, streamPromise) => { - // When `buffer` is `false`, `streamPromise` is `undefined` and there is no buffered data to retrieve - if (!stream || streamPromise === undefined) { - return; - } - - stream.destroy(); - - try { - return await streamPromise; - } catch (error) { - return error.bufferedData; - } -}; - -const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => { - if (!stream || !buffer) { - return; - } - - if (encoding) { - return getStream(stream, {encoding, maxBuffer}); - } - - return getStream.buffer(stream, {maxBuffer}); -}; - -// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all) -export const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => { - const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer}); - const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer}); - const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2}); - - try { - return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]); - } catch (error) { - return Promise.all([ - {error, signal: error.signal, timedOut: error.timedOut}, - getBufferedData(stdout, stdoutPromise), - getBufferedData(stderr, stderrPromise), - getBufferedData(all, allPromise), - ]); - } -}; diff --git a/node_modules/execa/lib/terminate/cancel.js b/node_modules/execa/lib/terminate/cancel.js new file mode 100644 index 0000000000..e951186f59 --- /dev/null +++ b/node_modules/execa/lib/terminate/cancel.js @@ -0,0 +1,20 @@ +import {onAbortedSignal} from '../utils/abort-signal.js'; + +// Validate the `cancelSignal` option +export const validateCancelSignal = ({cancelSignal}) => { + if (cancelSignal !== undefined && Object.prototype.toString.call(cancelSignal) !== '[object AbortSignal]') { + throw new Error(`The \`cancelSignal\` option must be an AbortSignal: ${String(cancelSignal)}`); + } +}; + +// Terminate the subprocess when aborting the `cancelSignal` option and `gracefulSignal` is `false` +export const throwOnCancel = ({subprocess, cancelSignal, gracefulCancel, context, controller}) => cancelSignal === undefined || gracefulCancel + ? [] + : [terminateOnCancel(subprocess, cancelSignal, context, controller)]; + +const terminateOnCancel = async (subprocess, cancelSignal, context, {signal}) => { + await onAbortedSignal(cancelSignal, signal); + context.terminationReason ??= 'cancel'; + subprocess.kill(); + throw cancelSignal.reason; +}; diff --git a/node_modules/execa/lib/terminate/cleanup.js b/node_modules/execa/lib/terminate/cleanup.js new file mode 100644 index 0000000000..5e98788d67 --- /dev/null +++ b/node_modules/execa/lib/terminate/cleanup.js @@ -0,0 +1,16 @@ +import {addAbortListener} from 'node:events'; +import {onExit} from 'signal-exit'; + +// If the `cleanup` option is used, call `subprocess.kill()` when the parent process exits +export const cleanupOnExit = (subprocess, {cleanup, detached}, {signal}) => { + if (!cleanup || detached) { + return; + } + + const removeExitHandler = onExit(() => { + subprocess.kill(); + }); + addAbortListener(signal, () => { + removeExitHandler(); + }); +}; diff --git a/node_modules/execa/lib/terminate/graceful.js b/node_modules/execa/lib/terminate/graceful.js new file mode 100644 index 0000000000..df360c5618 --- /dev/null +++ b/node_modules/execa/lib/terminate/graceful.js @@ -0,0 +1,71 @@ +import {onAbortedSignal} from '../utils/abort-signal.js'; +import {sendAbort} from '../ipc/graceful.js'; +import {killOnTimeout} from './kill.js'; + +// Validate the `gracefulCancel` option +export const validateGracefulCancel = ({gracefulCancel, cancelSignal, ipc, serialization}) => { + if (!gracefulCancel) { + return; + } + + if (cancelSignal === undefined) { + throw new Error('The `cancelSignal` option must be defined when setting the `gracefulCancel` option.'); + } + + if (!ipc) { + throw new Error('The `ipc` option cannot be false when setting the `gracefulCancel` option.'); + } + + if (serialization === 'json') { + throw new Error('The `serialization` option cannot be \'json\' when setting the `gracefulCancel` option.'); + } +}; + +// Send abort reason to the subprocess when aborting the `cancelSignal` option and `gracefulCancel` is `true` +export const throwOnGracefulCancel = ({ + subprocess, + cancelSignal, + gracefulCancel, + forceKillAfterDelay, + context, + controller, +}) => gracefulCancel + ? [sendOnAbort({ + subprocess, + cancelSignal, + forceKillAfterDelay, + context, + controller, + })] + : []; + +const sendOnAbort = async ({subprocess, cancelSignal, forceKillAfterDelay, context, controller: {signal}}) => { + await onAbortedSignal(cancelSignal, signal); + const reason = getReason(cancelSignal); + await sendAbort(subprocess, reason); + killOnTimeout({ + kill: subprocess.kill, + forceKillAfterDelay, + context, + controllerSignal: signal, + }); + context.terminationReason ??= 'gracefulCancel'; + throw cancelSignal.reason; +}; + +// The default `reason` is a DOMException, which is not serializable with V8 +// See https://github.com/nodejs/node/issues/53225 +const getReason = ({reason}) => { + if (!(reason instanceof DOMException)) { + return reason; + } + + const error = new Error(reason.message); + Object.defineProperty(error, 'stack', { + value: reason.stack, + enumerable: false, + configurable: true, + writable: true, + }); + return error; +}; diff --git a/node_modules/execa/lib/terminate/kill.js b/node_modules/execa/lib/terminate/kill.js new file mode 100644 index 0000000000..7b154367b6 --- /dev/null +++ b/node_modules/execa/lib/terminate/kill.js @@ -0,0 +1,93 @@ +import {setTimeout} from 'node:timers/promises'; +import {isErrorInstance} from '../return/final-error.js'; +import {normalizeSignalArgument} from './signal.js'; + +// Normalize the `forceKillAfterDelay` option +export const normalizeForceKillAfterDelay = forceKillAfterDelay => { + if (forceKillAfterDelay === false) { + return forceKillAfterDelay; + } + + if (forceKillAfterDelay === true) { + return DEFAULT_FORCE_KILL_TIMEOUT; + } + + if (!Number.isFinite(forceKillAfterDelay) || forceKillAfterDelay < 0) { + throw new TypeError(`Expected the \`forceKillAfterDelay\` option to be a non-negative integer, got \`${forceKillAfterDelay}\` (${typeof forceKillAfterDelay})`); + } + + return forceKillAfterDelay; +}; + +const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; + +// Monkey-patches `subprocess.kill()` to add `forceKillAfterDelay` behavior and `.kill(error)` +export const subprocessKill = ( + {kill, options: {forceKillAfterDelay, killSignal}, onInternalError, context, controller}, + signalOrError, + errorArgument, +) => { + const {signal, error} = parseKillArguments(signalOrError, errorArgument, killSignal); + emitKillError(error, onInternalError); + const killResult = kill(signal); + setKillTimeout({ + kill, + signal, + forceKillAfterDelay, + killSignal, + killResult, + context, + controller, + }); + return killResult; +}; + +const parseKillArguments = (signalOrError, errorArgument, killSignal) => { + const [signal = killSignal, error] = isErrorInstance(signalOrError) + ? [undefined, signalOrError] + : [signalOrError, errorArgument]; + + if (typeof signal !== 'string' && !Number.isInteger(signal)) { + throw new TypeError(`The first argument must be an error instance or a signal name string/integer: ${String(signal)}`); + } + + if (error !== undefined && !isErrorInstance(error)) { + throw new TypeError(`The second argument is optional. If specified, it must be an error instance: ${error}`); + } + + return {signal: normalizeSignalArgument(signal), error}; +}; + +// Fails right away when calling `subprocess.kill(error)`. +// Does not wait for actual signal termination. +// Uses a deferred promise instead of the `error` event on the subprocess, as this is less intrusive. +const emitKillError = (error, onInternalError) => { + if (error !== undefined) { + onInternalError.reject(error); + } +}; + +const setKillTimeout = async ({kill, signal, forceKillAfterDelay, killSignal, killResult, context, controller}) => { + if (signal === killSignal && killResult) { + killOnTimeout({ + kill, + forceKillAfterDelay, + context, + controllerSignal: controller.signal, + }); + } +}; + +// Forcefully terminate a subprocess after a timeout +export const killOnTimeout = async ({kill, forceKillAfterDelay, context, controllerSignal}) => { + if (forceKillAfterDelay === false) { + return; + } + + try { + await setTimeout(forceKillAfterDelay, undefined, {signal: controllerSignal}); + if (kill('SIGKILL')) { + context.isForcefullyTerminated ??= true; + } + } catch {} +}; diff --git a/node_modules/execa/lib/terminate/signal.js b/node_modules/execa/lib/terminate/signal.js new file mode 100644 index 0000000000..055bdf9e78 --- /dev/null +++ b/node_modules/execa/lib/terminate/signal.js @@ -0,0 +1,70 @@ +import {constants} from 'node:os'; +import {signalsByName} from 'human-signals'; + +// Normalize signals for comparison purpose. +// Also validate the signal exists. +export const normalizeKillSignal = killSignal => { + const optionName = 'option `killSignal`'; + if (killSignal === 0) { + throw new TypeError(`Invalid ${optionName}: 0 cannot be used.`); + } + + return normalizeSignal(killSignal, optionName); +}; + +export const normalizeSignalArgument = signal => signal === 0 + ? signal + : normalizeSignal(signal, '`subprocess.kill()`\'s argument'); + +const normalizeSignal = (signalNameOrInteger, optionName) => { + if (Number.isInteger(signalNameOrInteger)) { + return normalizeSignalInteger(signalNameOrInteger, optionName); + } + + if (typeof signalNameOrInteger === 'string') { + return normalizeSignalName(signalNameOrInteger, optionName); + } + + throw new TypeError(`Invalid ${optionName} ${String(signalNameOrInteger)}: it must be a string or an integer.\n${getAvailableSignals()}`); +}; + +const normalizeSignalInteger = (signalInteger, optionName) => { + if (signalsIntegerToName.has(signalInteger)) { + return signalsIntegerToName.get(signalInteger); + } + + throw new TypeError(`Invalid ${optionName} ${signalInteger}: this signal integer does not exist.\n${getAvailableSignals()}`); +}; + +const getSignalsIntegerToName = () => new Map(Object.entries(constants.signals) + .reverse() + .map(([signalName, signalInteger]) => [signalInteger, signalName])); + +const signalsIntegerToName = getSignalsIntegerToName(); + +const normalizeSignalName = (signalName, optionName) => { + if (signalName in constants.signals) { + return signalName; + } + + if (signalName.toUpperCase() in constants.signals) { + throw new TypeError(`Invalid ${optionName} '${signalName}': please rename it to '${signalName.toUpperCase()}'.`); + } + + throw new TypeError(`Invalid ${optionName} '${signalName}': this signal name does not exist.\n${getAvailableSignals()}`); +}; + +const getAvailableSignals = () => `Available signal names: ${getAvailableSignalNames()}. +Available signal numbers: ${getAvailableSignalIntegers()}.`; + +const getAvailableSignalNames = () => Object.keys(constants.signals) + .sort() + .map(signalName => `'${signalName}'`) + .join(', '); + +const getAvailableSignalIntegers = () => [...new Set(Object.values(constants.signals) + .sort((signalInteger, signalIntegerTwo) => signalInteger - signalIntegerTwo))] + .join(', '); + +// Human-friendly description of a signal +export const getSignalDescription = signal => signalsByName[signal].description; diff --git a/node_modules/execa/lib/terminate/timeout.js b/node_modules/execa/lib/terminate/timeout.js new file mode 100644 index 0000000000..d1c19d2439 --- /dev/null +++ b/node_modules/execa/lib/terminate/timeout.js @@ -0,0 +1,21 @@ +import {setTimeout} from 'node:timers/promises'; +import {DiscardedError} from '../return/final-error.js'; + +// Validate `timeout` option +export const validateTimeout = ({timeout}) => { + if (timeout !== undefined && (!Number.isFinite(timeout) || timeout < 0)) { + throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); + } +}; + +// Fails when the `timeout` option is exceeded +export const throwOnTimeout = (subprocess, timeout, context, controller) => timeout === 0 || timeout === undefined + ? [] + : [killAfterTimeout(subprocess, timeout, context, controller)]; + +const killAfterTimeout = async (subprocess, timeout, context, {signal}) => { + await setTimeout(timeout, undefined, {signal}); + context.terminationReason ??= 'timeout'; + subprocess.kill(); + throw new DiscardedError(); +}; diff --git a/node_modules/execa/lib/transform/encoding-transform.js b/node_modules/execa/lib/transform/encoding-transform.js new file mode 100644 index 0000000000..16bcedcead --- /dev/null +++ b/node_modules/execa/lib/transform/encoding-transform.js @@ -0,0 +1,51 @@ +import {Buffer} from 'node:buffer'; +import {StringDecoder} from 'node:string_decoder'; +import {isUint8Array, bufferToUint8Array} from '../utils/uint-array.js'; + +/* +When using binary encodings, add an internal generator that converts chunks from `Buffer` to `string` or `Uint8Array`. +Chunks might be Buffer, Uint8Array or strings since: +- `subprocess.stdout|stderr` emits Buffers +- `subprocess.stdin.write()` accepts Buffer, Uint8Array or string +- Previous generators might return Uint8Array or string + +However, those are converted to Buffer: +- on writes: `Duplex.writable` `decodeStrings: true` default option +- on reads: `Duplex.readable` `readableEncoding: null` default option +*/ +export const getEncodingTransformGenerator = (binary, encoding, skipped) => { + if (skipped) { + return; + } + + if (binary) { + return {transform: encodingUint8ArrayGenerator.bind(undefined, new TextEncoder())}; + } + + const stringDecoder = new StringDecoder(encoding); + return { + transform: encodingStringGenerator.bind(undefined, stringDecoder), + final: encodingStringFinal.bind(undefined, stringDecoder), + }; +}; + +const encodingUint8ArrayGenerator = function * (textEncoder, chunk) { + if (Buffer.isBuffer(chunk)) { + yield bufferToUint8Array(chunk); + } else if (typeof chunk === 'string') { + yield textEncoder.encode(chunk); + } else { + yield chunk; + } +}; + +const encodingStringGenerator = function * (stringDecoder, chunk) { + yield isUint8Array(chunk) ? stringDecoder.write(chunk) : chunk; +}; + +const encodingStringFinal = function * (stringDecoder) { + const lastChunk = stringDecoder.end(); + if (lastChunk !== '') { + yield lastChunk; + } +}; diff --git a/node_modules/execa/lib/transform/generator.js b/node_modules/execa/lib/transform/generator.js new file mode 100644 index 0000000000..a6b61faccb --- /dev/null +++ b/node_modules/execa/lib/transform/generator.js @@ -0,0 +1,107 @@ +import {Transform, getDefaultHighWaterMark} from 'node:stream'; +import {isAsyncGenerator} from '../stdio/type.js'; +import {getSplitLinesGenerator, getAppendNewlineGenerator} from './split.js'; +import {getValidateTransformInput, getValidateTransformReturn} from './validate.js'; +import {getEncodingTransformGenerator} from './encoding-transform.js'; +import { + pushChunks, + transformChunk, + finalChunks, + destroyTransform, +} from './run-async.js'; +import { + pushChunksSync, + transformChunkSync, + finalChunksSync, + runTransformSync, +} from './run-sync.js'; + +/* +Generators can be used to transform/filter standard streams. + +Generators have a simple syntax, yet allows all of the following: +- Sharing `state` between chunks +- Flushing logic, by using a `final` function +- Asynchronous logic +- Emitting multiple chunks from a single source chunk, even if spaced in time, by using multiple `yield` +- Filtering, by using no `yield` + +Therefore, there is no need to allow Node.js or web transform streams. + +The `highWaterMark` is kept as the default value, since this is what `subprocess.std*` uses. + +Chunks are currently processed serially. We could add a `concurrency` option to parallelize in the future. + +Transform an array of generator functions into a `Transform` stream. +`Duplex.from(generator)` cannot be used because it does not allow setting the `objectMode` and `highWaterMark`. +*/ +export const generatorToStream = ({ + value, + value: {transform, final, writableObjectMode, readableObjectMode}, + optionName, +}, {encoding}) => { + const state = {}; + const generators = addInternalGenerators(value, encoding, optionName); + + const transformAsync = isAsyncGenerator(transform); + const finalAsync = isAsyncGenerator(final); + const transformMethod = transformAsync + ? pushChunks.bind(undefined, transformChunk, state) + : pushChunksSync.bind(undefined, transformChunkSync); + const finalMethod = transformAsync || finalAsync + ? pushChunks.bind(undefined, finalChunks, state) + : pushChunksSync.bind(undefined, finalChunksSync); + const destroyMethod = transformAsync || finalAsync + ? destroyTransform.bind(undefined, state) + : undefined; + + const stream = new Transform({ + writableObjectMode, + writableHighWaterMark: getDefaultHighWaterMark(writableObjectMode), + readableObjectMode, + readableHighWaterMark: getDefaultHighWaterMark(readableObjectMode), + transform(chunk, encoding, done) { + transformMethod([chunk, generators, 0], this, done); + }, + flush(done) { + finalMethod([generators], this, done); + }, + destroy: destroyMethod, + }); + return {stream}; +}; + +// Applies transform generators in sync mode +export const runGeneratorsSync = (chunks, stdioItems, encoding, isInput) => { + const generators = stdioItems.filter(({type}) => type === 'generator'); + const reversedGenerators = isInput ? generators.reverse() : generators; + + for (const {value, optionName} of reversedGenerators) { + const generators = addInternalGenerators(value, encoding, optionName); + chunks = runTransformSync(generators, chunks); + } + + return chunks; +}; + +// Generators used internally to convert the chunk type, validate it, and split into lines +const addInternalGenerators = ( + {transform, final, binary, writableObjectMode, readableObjectMode, preserveNewlines}, + encoding, + optionName, +) => { + const state = {}; + return [ + {transform: getValidateTransformInput(writableObjectMode, optionName)}, + getEncodingTransformGenerator(binary, encoding, writableObjectMode), + getSplitLinesGenerator(binary, preserveNewlines, writableObjectMode, state), + {transform, final}, + {transform: getValidateTransformReturn(readableObjectMode, optionName)}, + getAppendNewlineGenerator({ + binary, + preserveNewlines, + readableObjectMode, + state, + }), + ].filter(Boolean); +}; diff --git a/node_modules/execa/lib/transform/normalize.js b/node_modules/execa/lib/transform/normalize.js new file mode 100644 index 0000000000..06d8e43215 --- /dev/null +++ b/node_modules/execa/lib/transform/normalize.js @@ -0,0 +1,111 @@ +import isPlainObj from 'is-plain-obj'; +import {BINARY_ENCODINGS} from '../arguments/encoding-option.js'; +import {TRANSFORM_TYPES} from '../stdio/type.js'; +import {getTransformObjectModes} from './object-mode.js'; + +// Transforms generators/duplex/TransformStream can have multiple shapes. +// This normalizes it and applies default values. +export const normalizeTransforms = (stdioItems, optionName, direction, options) => [ + ...stdioItems.filter(({type}) => !TRANSFORM_TYPES.has(type)), + ...getTransforms(stdioItems, optionName, direction, options), +]; + +const getTransforms = (stdioItems, optionName, direction, {encoding}) => { + const transforms = stdioItems.filter(({type}) => TRANSFORM_TYPES.has(type)); + const newTransforms = Array.from({length: transforms.length}); + + for (const [index, stdioItem] of Object.entries(transforms)) { + newTransforms[index] = normalizeTransform({ + stdioItem, + index: Number(index), + newTransforms, + optionName, + direction, + encoding, + }); + } + + return sortTransforms(newTransforms, direction); +}; + +const normalizeTransform = ({stdioItem, stdioItem: {type}, index, newTransforms, optionName, direction, encoding}) => { + if (type === 'duplex') { + return normalizeDuplex({stdioItem, optionName}); + } + + if (type === 'webTransform') { + return normalizeTransformStream({ + stdioItem, + index, + newTransforms, + direction, + }); + } + + return normalizeGenerator({ + stdioItem, + index, + newTransforms, + direction, + encoding, + }); +}; + +const normalizeDuplex = ({ + stdioItem, + stdioItem: { + value: { + transform, + transform: {writableObjectMode, readableObjectMode}, + objectMode = readableObjectMode, + }, + }, + optionName, +}) => { + if (objectMode && !readableObjectMode) { + throw new TypeError(`The \`${optionName}.objectMode\` option can only be \`true\` if \`new Duplex({objectMode: true})\` is used.`); + } + + if (!objectMode && readableObjectMode) { + throw new TypeError(`The \`${optionName}.objectMode\` option cannot be \`false\` if \`new Duplex({objectMode: true})\` is used.`); + } + + return { + ...stdioItem, + value: {transform, writableObjectMode, readableObjectMode}, + }; +}; + +const normalizeTransformStream = ({stdioItem, stdioItem: {value}, index, newTransforms, direction}) => { + const {transform, objectMode} = isPlainObj(value) ? value : {transform: value}; + const {writableObjectMode, readableObjectMode} = getTransformObjectModes(objectMode, index, newTransforms, direction); + return ({ + ...stdioItem, + value: {transform, writableObjectMode, readableObjectMode}, + }); +}; + +const normalizeGenerator = ({stdioItem, stdioItem: {value}, index, newTransforms, direction, encoding}) => { + const { + transform, + final, + binary: binaryOption = false, + preserveNewlines = false, + objectMode, + } = isPlainObj(value) ? value : {transform: value}; + const binary = binaryOption || BINARY_ENCODINGS.has(encoding); + const {writableObjectMode, readableObjectMode} = getTransformObjectModes(objectMode, index, newTransforms, direction); + return { + ...stdioItem, + value: { + transform, + final, + binary, + preserveNewlines, + writableObjectMode, + readableObjectMode, + }, + }; +}; + +const sortTransforms = (newTransforms, direction) => direction === 'input' ? newTransforms.reverse() : newTransforms; diff --git a/node_modules/execa/lib/transform/object-mode.js b/node_modules/execa/lib/transform/object-mode.js new file mode 100644 index 0000000000..d03f976bd4 --- /dev/null +++ b/node_modules/execa/lib/transform/object-mode.js @@ -0,0 +1,41 @@ +import {TRANSFORM_TYPES} from '../stdio/type.js'; + +/* +Retrieve the `objectMode`s of a single transform. +`objectMode` determines the return value's type, i.e. the `readableObjectMode`. +The chunk argument's type is based on the previous generator's return value, i.e. the `writableObjectMode` is based on the previous `readableObjectMode`. +The last input's generator is read by `subprocess.stdin` which: +- should not be in `objectMode` for performance reasons. +- can only be strings, Buffers and Uint8Arrays. +Therefore its `readableObjectMode` must be `false`. +The same applies to the first output's generator's `writableObjectMode`. +*/ +export const getTransformObjectModes = (objectMode, index, newTransforms, direction) => direction === 'output' + ? getOutputObjectModes(objectMode, index, newTransforms) + : getInputObjectModes(objectMode, index, newTransforms); + +const getOutputObjectModes = (objectMode, index, newTransforms) => { + const writableObjectMode = index !== 0 && newTransforms[index - 1].value.readableObjectMode; + const readableObjectMode = objectMode ?? writableObjectMode; + return {writableObjectMode, readableObjectMode}; +}; + +const getInputObjectModes = (objectMode, index, newTransforms) => { + const writableObjectMode = index === 0 + ? objectMode === true + : newTransforms[index - 1].value.readableObjectMode; + const readableObjectMode = index !== newTransforms.length - 1 && (objectMode ?? writableObjectMode); + return {writableObjectMode, readableObjectMode}; +}; + +// Retrieve the `objectMode` of a file descriptor, e.g. `stdout` or `stderr` +export const getFdObjectMode = (stdioItems, direction) => { + const lastTransform = stdioItems.findLast(({type}) => TRANSFORM_TYPES.has(type)); + if (lastTransform === undefined) { + return false; + } + + return direction === 'input' + ? lastTransform.value.writableObjectMode + : lastTransform.value.readableObjectMode; +}; diff --git a/node_modules/execa/lib/transform/run-async.js b/node_modules/execa/lib/transform/run-async.js new file mode 100644 index 0000000000..7cd1633c23 --- /dev/null +++ b/node_modules/execa/lib/transform/run-async.js @@ -0,0 +1,60 @@ +import {callbackify} from 'node:util'; + +// Applies a series of generator functions asynchronously +export const pushChunks = callbackify(async (getChunks, state, getChunksArguments, transformStream) => { + state.currentIterable = getChunks(...getChunksArguments); + + try { + for await (const chunk of state.currentIterable) { + transformStream.push(chunk); + } + } finally { + delete state.currentIterable; + } +}); + +// For each new chunk, apply each `transform()` method +export const transformChunk = async function * (chunk, generators, index) { + if (index === generators.length) { + yield chunk; + return; + } + + const {transform = identityGenerator} = generators[index]; + for await (const transformedChunk of transform(chunk)) { + yield * transformChunk(transformedChunk, generators, index + 1); + } +}; + +// At the end, apply each `final()` method, followed by the `transform()` method of the next transforms +export const finalChunks = async function * (generators) { + for (const [index, {final}] of Object.entries(generators)) { + yield * generatorFinalChunks(final, Number(index), generators); + } +}; + +const generatorFinalChunks = async function * (final, index, generators) { + if (final === undefined) { + return; + } + + for await (const finalChunk of final()) { + yield * transformChunk(finalChunk, generators, index + 1); + } +}; + +// Cancel any ongoing async generator when the Transform is destroyed, e.g. when the subprocess errors +export const destroyTransform = callbackify(async ({currentIterable}, error) => { + if (currentIterable !== undefined) { + await (error ? currentIterable.throw(error) : currentIterable.return()); + return; + } + + if (error) { + throw error; + } +}); + +const identityGenerator = function * (chunk) { + yield chunk; +}; diff --git a/node_modules/execa/lib/transform/run-sync.js b/node_modules/execa/lib/transform/run-sync.js new file mode 100644 index 0000000000..8e30b8cd00 --- /dev/null +++ b/node_modules/execa/lib/transform/run-sync.js @@ -0,0 +1,50 @@ +// Duplicate the code from `run-async.js` but as synchronous functions +export const pushChunksSync = (getChunksSync, getChunksArguments, transformStream, done) => { + try { + for (const chunk of getChunksSync(...getChunksArguments)) { + transformStream.push(chunk); + } + + done(); + } catch (error) { + done(error); + } +}; + +// Run synchronous generators with `execaSync()` +export const runTransformSync = (generators, chunks) => [ + ...chunks.flatMap(chunk => [...transformChunkSync(chunk, generators, 0)]), + ...finalChunksSync(generators), +]; + +export const transformChunkSync = function * (chunk, generators, index) { + if (index === generators.length) { + yield chunk; + return; + } + + const {transform = identityGenerator} = generators[index]; + for (const transformedChunk of transform(chunk)) { + yield * transformChunkSync(transformedChunk, generators, index + 1); + } +}; + +export const finalChunksSync = function * (generators) { + for (const [index, {final}] of Object.entries(generators)) { + yield * generatorFinalChunksSync(final, Number(index), generators); + } +}; + +const generatorFinalChunksSync = function * (final, index, generators) { + if (final === undefined) { + return; + } + + for (const finalChunk of final()) { + yield * transformChunkSync(finalChunk, generators, index + 1); + } +}; + +const identityGenerator = function * (chunk) { + yield chunk; +}; diff --git a/node_modules/execa/lib/transform/split.js b/node_modules/execa/lib/transform/split.js new file mode 100644 index 0000000000..47eb995b88 --- /dev/null +++ b/node_modules/execa/lib/transform/split.js @@ -0,0 +1,110 @@ +// Split chunks line-wise for generators passed to the `std*` options +export const getSplitLinesGenerator = (binary, preserveNewlines, skipped, state) => binary || skipped + ? undefined + : initializeSplitLines(preserveNewlines, state); + +// Same but for synchronous methods +export const splitLinesSync = (chunk, preserveNewlines, objectMode) => objectMode + ? chunk.flatMap(item => splitLinesItemSync(item, preserveNewlines)) + : splitLinesItemSync(chunk, preserveNewlines); + +const splitLinesItemSync = (chunk, preserveNewlines) => { + const {transform, final} = initializeSplitLines(preserveNewlines, {}); + return [...transform(chunk), ...final()]; +}; + +const initializeSplitLines = (preserveNewlines, state) => { + state.previousChunks = ''; + return { + transform: splitGenerator.bind(undefined, state, preserveNewlines), + final: linesFinal.bind(undefined, state), + }; +}; + +// This imperative logic is much faster than using `String.split()` and uses very low memory. +const splitGenerator = function * (state, preserveNewlines, chunk) { + if (typeof chunk !== 'string') { + yield chunk; + return; + } + + let {previousChunks} = state; + let start = -1; + + for (let end = 0; end < chunk.length; end += 1) { + if (chunk[end] === '\n') { + const newlineLength = getNewlineLength(chunk, end, preserveNewlines, state); + let line = chunk.slice(start + 1, end + 1 - newlineLength); + + if (previousChunks.length > 0) { + line = concatString(previousChunks, line); + previousChunks = ''; + } + + yield line; + start = end; + } + } + + if (start !== chunk.length - 1) { + previousChunks = concatString(previousChunks, chunk.slice(start + 1)); + } + + state.previousChunks = previousChunks; +}; + +const getNewlineLength = (chunk, end, preserveNewlines, state) => { + if (preserveNewlines) { + return 0; + } + + state.isWindowsNewline = end !== 0 && chunk[end - 1] === '\r'; + return state.isWindowsNewline ? 2 : 1; +}; + +const linesFinal = function * ({previousChunks}) { + if (previousChunks.length > 0) { + yield previousChunks; + } +}; + +// Unless `preserveNewlines: true` is used, we strip the newline of each line. +// This re-adds them after the user `transform` code has run. +export const getAppendNewlineGenerator = ({binary, preserveNewlines, readableObjectMode, state}) => binary || preserveNewlines || readableObjectMode + ? undefined + : {transform: appendNewlineGenerator.bind(undefined, state)}; + +const appendNewlineGenerator = function * ({isWindowsNewline = false}, chunk) { + const {unixNewline, windowsNewline, LF, concatBytes} = typeof chunk === 'string' ? linesStringInfo : linesUint8ArrayInfo; + + if (chunk.at(-1) === LF) { + yield chunk; + return; + } + + const newline = isWindowsNewline ? windowsNewline : unixNewline; + yield concatBytes(chunk, newline); +}; + +const concatString = (firstChunk, secondChunk) => `${firstChunk}${secondChunk}`; + +const linesStringInfo = { + windowsNewline: '\r\n', + unixNewline: '\n', + LF: '\n', + concatBytes: concatString, +}; + +const concatUint8Array = (firstChunk, secondChunk) => { + const chunk = new Uint8Array(firstChunk.length + secondChunk.length); + chunk.set(firstChunk, 0); + chunk.set(secondChunk, firstChunk.length); + return chunk; +}; + +const linesUint8ArrayInfo = { + windowsNewline: new Uint8Array([0x0D, 0x0A]), + unixNewline: new Uint8Array([0x0A]), + LF: 0x0A, + concatBytes: concatUint8Array, +}; diff --git a/node_modules/execa/lib/transform/validate.js b/node_modules/execa/lib/transform/validate.js new file mode 100644 index 0000000000..38a3ff0878 --- /dev/null +++ b/node_modules/execa/lib/transform/validate.js @@ -0,0 +1,43 @@ +import {Buffer} from 'node:buffer'; +import {isUint8Array} from '../utils/uint-array.js'; + +// Validate the type of chunk argument passed to transform generators +export const getValidateTransformInput = (writableObjectMode, optionName) => writableObjectMode + ? undefined + : validateStringTransformInput.bind(undefined, optionName); + +const validateStringTransformInput = function * (optionName, chunk) { + if (typeof chunk !== 'string' && !isUint8Array(chunk) && !Buffer.isBuffer(chunk)) { + throw new TypeError(`The \`${optionName}\` option's transform must use "objectMode: true" to receive as input: ${typeof chunk}.`); + } + + yield chunk; +}; + +// Validate the type of the value returned by transform generators +export const getValidateTransformReturn = (readableObjectMode, optionName) => readableObjectMode + ? validateObjectTransformReturn.bind(undefined, optionName) + : validateStringTransformReturn.bind(undefined, optionName); + +const validateObjectTransformReturn = function * (optionName, chunk) { + validateEmptyReturn(optionName, chunk); + yield chunk; +}; + +const validateStringTransformReturn = function * (optionName, chunk) { + validateEmptyReturn(optionName, chunk); + + if (typeof chunk !== 'string' && !isUint8Array(chunk)) { + throw new TypeError(`The \`${optionName}\` option's function must yield a string or an Uint8Array, not ${typeof chunk}.`); + } + + yield chunk; +}; + +const validateEmptyReturn = (optionName, chunk) => { + if (chunk === null || chunk === undefined) { + throw new TypeError(`The \`${optionName}\` option's function must not call \`yield ${chunk}\`. +Instead, \`yield\` should either be called with a value, or not be called at all. For example: + if (condition) { yield value; }`); + } +}; diff --git a/node_modules/execa/lib/utils/abort-signal.js b/node_modules/execa/lib/utils/abort-signal.js new file mode 100644 index 0000000000..e41dd4f4d4 --- /dev/null +++ b/node_modules/execa/lib/utils/abort-signal.js @@ -0,0 +1,8 @@ +import {once} from 'node:events'; + +// Combines `util.aborted()` and `events.addAbortListener()`: promise-based and cleaned up with a stop signal +export const onAbortedSignal = async (mainSignal, stopSignal) => { + if (!mainSignal.aborted) { + await once(mainSignal, 'abort', {signal: stopSignal}); + } +}; diff --git a/node_modules/execa/lib/utils/deferred.js b/node_modules/execa/lib/utils/deferred.js new file mode 100644 index 0000000000..6c0a9d2728 --- /dev/null +++ b/node_modules/execa/lib/utils/deferred.js @@ -0,0 +1,7 @@ +export const createDeferred = () => { + const methods = {}; + const promise = new Promise((resolve, reject) => { + Object.assign(methods, {resolve, reject}); + }); + return Object.assign(promise, methods); +}; diff --git a/node_modules/execa/lib/utils/max-listeners.js b/node_modules/execa/lib/utils/max-listeners.js new file mode 100644 index 0000000000..16856936ec --- /dev/null +++ b/node_modules/execa/lib/utils/max-listeners.js @@ -0,0 +1,14 @@ +import {addAbortListener} from 'node:events'; + +// Temporarily increase the maximum number of listeners on an eventEmitter +export const incrementMaxListeners = (eventEmitter, maxListenersIncrement, signal) => { + const maxListeners = eventEmitter.getMaxListeners(); + if (maxListeners === 0 || maxListeners === Number.POSITIVE_INFINITY) { + return; + } + + eventEmitter.setMaxListeners(maxListeners + maxListenersIncrement); + addAbortListener(signal, () => { + eventEmitter.setMaxListeners(eventEmitter.getMaxListeners() - maxListenersIncrement); + }); +}; diff --git a/node_modules/execa/lib/utils/standard-stream.js b/node_modules/execa/lib/utils/standard-stream.js new file mode 100644 index 0000000000..ed8a28de29 --- /dev/null +++ b/node_modules/execa/lib/utils/standard-stream.js @@ -0,0 +1,6 @@ +import process from 'node:process'; + +export const isStandardStream = stream => STANDARD_STREAMS.includes(stream); +export const STANDARD_STREAMS = [process.stdin, process.stdout, process.stderr]; +export const STANDARD_STREAMS_ALIASES = ['stdin', 'stdout', 'stderr']; +export const getStreamName = fdNumber => STANDARD_STREAMS_ALIASES[fdNumber] ?? `stdio[${fdNumber}]`; diff --git a/node_modules/execa/lib/utils/uint-array.js b/node_modules/execa/lib/utils/uint-array.js new file mode 100644 index 0000000000..4686080e75 --- /dev/null +++ b/node_modules/execa/lib/utils/uint-array.js @@ -0,0 +1,69 @@ +import {StringDecoder} from 'node:string_decoder'; + +const {toString: objectToString} = Object.prototype; + +export const isArrayBuffer = value => objectToString.call(value) === '[object ArrayBuffer]'; + +// Is either Uint8Array or Buffer +export const isUint8Array = value => objectToString.call(value) === '[object Uint8Array]'; + +export const bufferToUint8Array = buffer => new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); + +const textEncoder = new TextEncoder(); +const stringToUint8Array = string => textEncoder.encode(string); + +const textDecoder = new TextDecoder(); +export const uint8ArrayToString = uint8Array => textDecoder.decode(uint8Array); + +export const joinToString = (uint8ArraysOrStrings, encoding) => { + const strings = uint8ArraysToStrings(uint8ArraysOrStrings, encoding); + return strings.join(''); +}; + +const uint8ArraysToStrings = (uint8ArraysOrStrings, encoding) => { + if (encoding === 'utf8' && uint8ArraysOrStrings.every(uint8ArrayOrString => typeof uint8ArrayOrString === 'string')) { + return uint8ArraysOrStrings; + } + + const decoder = new StringDecoder(encoding); + const strings = uint8ArraysOrStrings + .map(uint8ArrayOrString => typeof uint8ArrayOrString === 'string' + ? stringToUint8Array(uint8ArrayOrString) + : uint8ArrayOrString) + .map(uint8Array => decoder.write(uint8Array)); + const finalString = decoder.end(); + return finalString === '' ? strings : [...strings, finalString]; +}; + +export const joinToUint8Array = uint8ArraysOrStrings => { + if (uint8ArraysOrStrings.length === 1 && isUint8Array(uint8ArraysOrStrings[0])) { + return uint8ArraysOrStrings[0]; + } + + return concatUint8Arrays(stringsToUint8Arrays(uint8ArraysOrStrings)); +}; + +const stringsToUint8Arrays = uint8ArraysOrStrings => uint8ArraysOrStrings.map(uint8ArrayOrString => typeof uint8ArrayOrString === 'string' + ? stringToUint8Array(uint8ArrayOrString) + : uint8ArrayOrString); + +export const concatUint8Arrays = uint8Arrays => { + const result = new Uint8Array(getJoinLength(uint8Arrays)); + + let index = 0; + for (const uint8Array of uint8Arrays) { + result.set(uint8Array, index); + index += uint8Array.length; + } + + return result; +}; + +const getJoinLength = uint8Arrays => { + let joinLength = 0; + for (const uint8Array of uint8Arrays) { + joinLength += uint8Array.length; + } + + return joinLength; +}; diff --git a/node_modules/execa/lib/verbose.js b/node_modules/execa/lib/verbose.js deleted file mode 100644 index 5f5490ed02..0000000000 --- a/node_modules/execa/lib/verbose.js +++ /dev/null @@ -1,19 +0,0 @@ -import {debuglog} from 'node:util'; -import process from 'node:process'; - -export const verboseDefault = debuglog('execa').enabled; - -const padField = (field, padding) => String(field).padStart(padding, '0'); - -const getTimestamp = () => { - const date = new Date(); - return `${padField(date.getHours(), 2)}:${padField(date.getMinutes(), 2)}:${padField(date.getSeconds(), 2)}.${padField(date.getMilliseconds(), 3)}`; -}; - -export const logCommand = (escapedCommand, {verbose}) => { - if (!verbose) { - return; - } - - process.stderr.write(`[${getTimestamp()}] ${escapedCommand}\n`); -}; diff --git a/node_modules/execa/lib/verbose/complete.js b/node_modules/execa/lib/verbose/complete.js new file mode 100644 index 0000000000..8f773fbe86 --- /dev/null +++ b/node_modules/execa/lib/verbose/complete.js @@ -0,0 +1,24 @@ +import prettyMs from 'pretty-ms'; +import {isVerbose} from './values.js'; +import {verboseLog} from './log.js'; +import {logError} from './error.js'; + +// When `verbose` is `short|full|custom`, print each command's completion, duration and error +export const logResult = (result, verboseInfo) => { + if (!isVerbose(verboseInfo)) { + return; + } + + logError(result, verboseInfo); + logDuration(result, verboseInfo); +}; + +const logDuration = (result, verboseInfo) => { + const verboseMessage = `(done in ${prettyMs(result.durationMs)})`; + verboseLog({ + type: 'duration', + verboseMessage, + verboseInfo, + result, + }); +}; diff --git a/node_modules/execa/lib/verbose/custom.js b/node_modules/execa/lib/verbose/custom.js new file mode 100644 index 0000000000..d55ab577ac --- /dev/null +++ b/node_modules/execa/lib/verbose/custom.js @@ -0,0 +1,26 @@ +import {getVerboseFunction} from './values.js'; + +// Apply the `verbose` function on each line +export const applyVerboseOnLines = (printedLines, verboseInfo, fdNumber) => { + const verboseFunction = getVerboseFunction(verboseInfo, fdNumber); + return printedLines + .map(({verboseLine, verboseObject}) => applyVerboseFunction(verboseLine, verboseObject, verboseFunction)) + .filter(printedLine => printedLine !== undefined) + .map(printedLine => appendNewline(printedLine)) + .join(''); +}; + +const applyVerboseFunction = (verboseLine, verboseObject, verboseFunction) => { + if (verboseFunction === undefined) { + return verboseLine; + } + + const printedLine = verboseFunction(verboseLine, verboseObject); + if (typeof printedLine === 'string') { + return printedLine; + } +}; + +const appendNewline = printedLine => printedLine.endsWith('\n') + ? printedLine + : `${printedLine}\n`; diff --git a/node_modules/execa/lib/verbose/default.js b/node_modules/execa/lib/verbose/default.js new file mode 100644 index 0000000000..090a367408 --- /dev/null +++ b/node_modules/execa/lib/verbose/default.js @@ -0,0 +1,54 @@ +import figures from 'figures'; +import { + gray, + bold, + redBright, + yellowBright, +} from 'yoctocolors'; + +// Default when `verbose` is not a function +export const defaultVerboseFunction = ({ + type, + message, + timestamp, + piped, + commandId, + result: {failed = false} = {}, + options: {reject = true}, +}) => { + const timestampString = serializeTimestamp(timestamp); + const icon = ICONS[type]({failed, reject, piped}); + const color = COLORS[type]({reject}); + return `${gray(`[${timestampString}]`)} ${gray(`[${commandId}]`)} ${color(icon)} ${color(message)}`; +}; + +// Prepending the timestamp allows debugging the slow paths of a subprocess +const serializeTimestamp = timestamp => `${padField(timestamp.getHours(), 2)}:${padField(timestamp.getMinutes(), 2)}:${padField(timestamp.getSeconds(), 2)}.${padField(timestamp.getMilliseconds(), 3)}`; + +const padField = (field, padding) => String(field).padStart(padding, '0'); + +const getFinalIcon = ({failed, reject}) => { + if (!failed) { + return figures.tick; + } + + return reject ? figures.cross : figures.warning; +}; + +const ICONS = { + command: ({piped}) => piped ? '|' : '$', + output: () => ' ', + ipc: () => '*', + error: getFinalIcon, + duration: getFinalIcon, +}; + +const identity = string => string; + +const COLORS = { + command: () => bold, + output: () => identity, + ipc: () => identity, + error: ({reject}) => reject ? redBright : yellowBright, + duration: () => gray, +}; diff --git a/node_modules/execa/lib/verbose/error.js b/node_modules/execa/lib/verbose/error.js new file mode 100644 index 0000000000..ed4c4b1ef2 --- /dev/null +++ b/node_modules/execa/lib/verbose/error.js @@ -0,0 +1,13 @@ +import {verboseLog} from './log.js'; + +// When `verbose` is `short|full|custom`, print each command's error when it fails +export const logError = (result, verboseInfo) => { + if (result.failed) { + verboseLog({ + type: 'error', + verboseMessage: result.shortMessage, + verboseInfo, + result, + }); + } +}; diff --git a/node_modules/execa/lib/verbose/info.js b/node_modules/execa/lib/verbose/info.js new file mode 100644 index 0000000000..0e1afa2930 --- /dev/null +++ b/node_modules/execa/lib/verbose/info.js @@ -0,0 +1,39 @@ +import {isVerbose, VERBOSE_VALUES, isVerboseFunction} from './values.js'; + +// Information computed before spawning, used by the `verbose` option +export const getVerboseInfo = (verbose, escapedCommand, rawOptions) => { + validateVerbose(verbose); + const commandId = getCommandId(verbose); + return { + verbose, + escapedCommand, + commandId, + rawOptions, + }; +}; + +const getCommandId = verbose => isVerbose({verbose}) ? COMMAND_ID++ : undefined; + +// Prepending the `pid` is useful when multiple commands print their output at the same time. +// However, we cannot use the real PID since this is not available with `child_process.spawnSync()`. +// Also, we cannot use the real PID if we want to print it before `child_process.spawn()` is run. +// As a pro, it is shorter than a normal PID and never re-uses the same id. +// As a con, it cannot be used to send signals. +let COMMAND_ID = 0n; + +const validateVerbose = verbose => { + for (const fdVerbose of verbose) { + if (fdVerbose === false) { + throw new TypeError('The "verbose: false" option was renamed to "verbose: \'none\'".'); + } + + if (fdVerbose === true) { + throw new TypeError('The "verbose: true" option was renamed to "verbose: \'short\'".'); + } + + if (!VERBOSE_VALUES.includes(fdVerbose) && !isVerboseFunction(fdVerbose)) { + const allowedValues = VERBOSE_VALUES.map(allowedValue => `'${allowedValue}'`).join(', '); + throw new TypeError(`The "verbose" option must not be ${fdVerbose}. Allowed values are: ${allowedValues} or a function.`); + } + } +}; diff --git a/node_modules/execa/lib/verbose/ipc.js b/node_modules/execa/lib/verbose/ipc.js new file mode 100644 index 0000000000..779052b7cb --- /dev/null +++ b/node_modules/execa/lib/verbose/ipc.js @@ -0,0 +1,15 @@ +import {verboseLog, serializeVerboseMessage} from './log.js'; +import {isFullVerbose} from './values.js'; + +// When `verbose` is `'full'`, print IPC messages from the subprocess +export const shouldLogIpc = verboseInfo => isFullVerbose(verboseInfo, 'ipc'); + +export const logIpcOutput = (message, verboseInfo) => { + const verboseMessage = serializeVerboseMessage(message); + verboseLog({ + type: 'ipc', + verboseMessage, + fdNumber: 'ipc', + verboseInfo, + }); +}; diff --git a/node_modules/execa/lib/verbose/log.js b/node_modules/execa/lib/verbose/log.js new file mode 100644 index 0000000000..52f46b7a7d --- /dev/null +++ b/node_modules/execa/lib/verbose/log.js @@ -0,0 +1,54 @@ +import {inspect} from 'node:util'; +import {escapeLines} from '../arguments/escape.js'; +import {defaultVerboseFunction} from './default.js'; +import {applyVerboseOnLines} from './custom.js'; + +// This prints on stderr. +// If the subprocess prints on stdout and is using `stdout: 'inherit'`, +// there is a chance both writes will compete (introducing a race condition). +// This means their respective order is not deterministic. +// In particular, this means the verbose command lines might be after the start of the subprocess output. +// Using synchronous I/O does not solve this problem. +// However, this only seems to happen when the stdout/stderr target +// (e.g. a terminal) is being written to by many subprocesses at once, which is unlikely in real scenarios. +export const verboseLog = ({type, verboseMessage, fdNumber, verboseInfo, result}) => { + const verboseObject = getVerboseObject({type, result, verboseInfo}); + const printedLines = getPrintedLines(verboseMessage, verboseObject); + const finalLines = applyVerboseOnLines(printedLines, verboseInfo, fdNumber); + if (finalLines !== '') { + console.warn(finalLines.slice(0, -1)); + } +}; + +const getVerboseObject = ({ + type, + result, + verboseInfo: {escapedCommand, commandId, rawOptions: {piped = false, ...options}}, +}) => ({ + type, + escapedCommand, + commandId: `${commandId}`, + timestamp: new Date(), + piped, + result, + options, +}); + +const getPrintedLines = (verboseMessage, verboseObject) => verboseMessage + .split('\n') + .map(message => getPrintedLine({...verboseObject, message})); + +const getPrintedLine = verboseObject => { + const verboseLine = defaultVerboseFunction(verboseObject); + return {verboseLine, verboseObject}; +}; + +// Serialize any type to a line string, for logging +export const serializeVerboseMessage = message => { + const messageString = typeof message === 'string' ? message : inspect(message); + const escapedMessage = escapeLines(messageString); + return escapedMessage.replaceAll('\t', ' '.repeat(TAB_SIZE)); +}; + +// Same as `util.inspect()` +const TAB_SIZE = 2; diff --git a/node_modules/execa/lib/verbose/output.js b/node_modules/execa/lib/verbose/output.js new file mode 100644 index 0000000000..c95b6274d9 --- /dev/null +++ b/node_modules/execa/lib/verbose/output.js @@ -0,0 +1,60 @@ +import {BINARY_ENCODINGS} from '../arguments/encoding-option.js'; +import {TRANSFORM_TYPES} from '../stdio/type.js'; +import {verboseLog, serializeVerboseMessage} from './log.js'; +import {isFullVerbose} from './values.js'; + +// `ignore` opts-out of `verbose` for a specific stream. +// `ipc` cannot use piping. +// `inherit` would result in double printing. +// They can also lead to double printing when passing file descriptor integers or `process.std*`. +// This only leaves with `pipe` and `overlapped`. +export const shouldLogOutput = ({stdioItems, encoding, verboseInfo, fdNumber}) => fdNumber !== 'all' + && isFullVerbose(verboseInfo, fdNumber) + && !BINARY_ENCODINGS.has(encoding) + && fdUsesVerbose(fdNumber) + && (stdioItems.some(({type, value}) => type === 'native' && PIPED_STDIO_VALUES.has(value)) + || stdioItems.every(({type}) => TRANSFORM_TYPES.has(type))); + +// Printing input streams would be confusing. +// Files and streams can produce big outputs, which we don't want to print. +// We could print `stdio[3+]` but it often is redirected to files and streams, with the same issue. +// So we only print stdout and stderr. +const fdUsesVerbose = fdNumber => fdNumber === 1 || fdNumber === 2; + +const PIPED_STDIO_VALUES = new Set(['pipe', 'overlapped']); + +// `verbose: 'full'` printing logic with async methods +export const logLines = async (linesIterable, stream, fdNumber, verboseInfo) => { + for await (const line of linesIterable) { + if (!isPipingStream(stream)) { + logLine(line, fdNumber, verboseInfo); + } + } +}; + +// `verbose: 'full'` printing logic with sync methods +export const logLinesSync = (linesArray, fdNumber, verboseInfo) => { + for (const line of linesArray) { + logLine(line, fdNumber, verboseInfo); + } +}; + +// When `subprocess.stdout|stderr.pipe()` is called, `verbose` becomes a noop. +// This prevents the following problems: +// - `.pipe()` achieves the same result as using `stdout: 'inherit'`, `stdout: stream`, etc. which also make `verbose` a noop. +// For example, `subprocess.stdout.pipe(process.stdin)` would print each line twice. +// - When chaining subprocesses with `subprocess.pipe(otherSubprocess)`, only the last one should print its output. +// Detecting whether `.pipe()` is impossible without monkey-patching it, so we use the following undocumented property. +// This is not a critical behavior since changes of the following property would only make `verbose` more verbose. +const isPipingStream = stream => stream._readableState.pipes.length > 0; + +// When `verbose` is `full`, print stdout|stderr +const logLine = (line, fdNumber, verboseInfo) => { + const verboseMessage = serializeVerboseMessage(line); + verboseLog({ + type: 'output', + verboseMessage, + fdNumber, + verboseInfo, + }); +}; diff --git a/node_modules/execa/lib/verbose/start.js b/node_modules/execa/lib/verbose/start.js new file mode 100644 index 0000000000..82fd516f21 --- /dev/null +++ b/node_modules/execa/lib/verbose/start.js @@ -0,0 +1,15 @@ +import {isVerbose} from './values.js'; +import {verboseLog} from './log.js'; + +// When `verbose` is `short|full|custom`, print each command +export const logCommand = (escapedCommand, verboseInfo) => { + if (!isVerbose(verboseInfo)) { + return; + } + + verboseLog({ + type: 'command', + verboseMessage: escapedCommand, + verboseInfo, + }); +}; diff --git a/node_modules/execa/lib/verbose/values.js b/node_modules/execa/lib/verbose/values.js new file mode 100644 index 0000000000..2ca75e7fe0 --- /dev/null +++ b/node_modules/execa/lib/verbose/values.js @@ -0,0 +1,33 @@ +import {getFdSpecificValue} from '../arguments/specific.js'; + +// The `verbose` option can have different values for `stdout`/`stderr` +export const isVerbose = ({verbose}, fdNumber) => getFdVerbose(verbose, fdNumber) !== 'none'; + +// Whether IPC and output and logged +export const isFullVerbose = ({verbose}, fdNumber) => !['none', 'short'].includes(getFdVerbose(verbose, fdNumber)); + +// The `verbose` option can be a function to customize logging +export const getVerboseFunction = ({verbose}, fdNumber) => { + const fdVerbose = getFdVerbose(verbose, fdNumber); + return isVerboseFunction(fdVerbose) ? fdVerbose : undefined; +}; + +// When using `verbose: {stdout, stderr, fd3, ipc}`: +// - `verbose.stdout|stderr|fd3` is used for 'output' +// - `verbose.ipc` is only used for 'ipc' +// - highest `verbose.*` value is used for 'command', 'error' and 'duration' +const getFdVerbose = (verbose, fdNumber) => fdNumber === undefined + ? getFdGenericVerbose(verbose) + : getFdSpecificValue(verbose, fdNumber); + +// When using `verbose: {stdout, stderr, fd3, ipc}` and logging is not specific to a file descriptor. +// We then use the highest `verbose.*` value, using the following order: +// - function > 'full' > 'short' > 'none' +// - if several functions are defined: stdout > stderr > fd3 > ipc +const getFdGenericVerbose = verbose => verbose.find(fdVerbose => isVerboseFunction(fdVerbose)) + ?? VERBOSE_VALUES.findLast(fdVerbose => verbose.includes(fdVerbose)); + +// Whether the `verbose` option is customized using a function +export const isVerboseFunction = fdVerbose => typeof fdVerbose === 'function'; + +export const VERBOSE_VALUES = ['none', 'short', 'full']; diff --git a/node_modules/execa/node_modules/figures/index.d.ts b/node_modules/execa/node_modules/figures/index.d.ts new file mode 100644 index 0000000000..5fc9dfd2bc --- /dev/null +++ b/node_modules/execa/node_modules/figures/index.d.ts @@ -0,0 +1,279 @@ +declare const figureSet: { + readonly tick: string; + readonly info: string; + readonly warning: string; + readonly cross: string; + readonly square: string; + readonly squareSmall: string; + readonly squareSmallFilled: string; + readonly squareDarkShade: string; + readonly squareMediumShade: string; + readonly squareLightShade: string; + readonly squareTop: string; + readonly squareBottom: string; + readonly squareLeft: string; + readonly squareRight: string; + readonly squareCenter: string; + readonly circle: string; + readonly circleFilled: string; + readonly circleDotted: string; + readonly circleDouble: string; + readonly circleCircle: string; + readonly circleCross: string; + readonly circlePipe: string; + readonly circleQuestionMark: string; + readonly radioOn: string; + readonly radioOff: string; + readonly checkboxOn: string; + readonly checkboxOff: string; + readonly checkboxCircleOn: string; + readonly checkboxCircleOff: string; + readonly questionMarkPrefix: string; + readonly bullet: string; + readonly dot: string; + readonly ellipsis: string; + readonly pointer: string; + readonly pointerSmall: string; + readonly triangleUp: string; + readonly triangleUpSmall: string; + readonly triangleUpOutline: string; + readonly triangleDown: string; + readonly triangleDownSmall: string; + readonly triangleLeft: string; + readonly triangleLeftSmall: string; + readonly triangleRight: string; + readonly triangleRightSmall: string; + readonly lozenge: string; + readonly lozengeOutline: string; + readonly home: string; + readonly hamburger: string; + readonly smiley: string; + readonly mustache: string; + readonly heart: string; + readonly star: string; + readonly play: string; + readonly musicNote: string; + readonly musicNoteBeamed: string; + readonly nodejs: string; + readonly arrowUp: string; + readonly arrowDown: string; + readonly arrowLeft: string; + readonly arrowRight: string; + readonly arrowLeftRight: string; + readonly arrowUpDown: string; + readonly almostEqual: string; + readonly notEqual: string; + readonly lessOrEqual: string; + readonly greaterOrEqual: string; + readonly identical: string; + readonly infinity: string; + readonly subscriptZero: string; + readonly subscriptOne: string; + readonly subscriptTwo: string; + readonly subscriptThree: string; + readonly subscriptFour: string; + readonly subscriptFive: string; + readonly subscriptSix: string; + readonly subscriptSeven: string; + readonly subscriptEight: string; + readonly subscriptNine: string; + readonly oneHalf: string; + readonly oneThird: string; + readonly oneQuarter: string; + readonly oneFifth: string; + readonly oneSixth: string; + readonly oneSeventh: string; + readonly oneEighth: string; + readonly oneNinth: string; + readonly oneTenth: string; + readonly twoThirds: string; + readonly twoFifths: string; + readonly threeQuarters: string; + readonly threeFifths: string; + readonly threeEighths: string; + readonly fourFifths: string; + readonly fiveSixths: string; + readonly fiveEighths: string; + readonly sevenEighth: string; + readonly line: string; + readonly lineBold: string; + readonly lineDouble: string; + readonly lineDashed0: string; + readonly lineDashed1: string; + readonly lineDashed2: string; + readonly lineDashed3: string; + readonly lineDashed4: string; + readonly lineDashed5: string; + readonly lineDashed6: string; + readonly lineDashed7: string; + readonly lineDashed8: string; + readonly lineDashed9: string; + readonly lineDashed10: string; + readonly lineDashed11: string; + readonly lineDashed12: string; + readonly lineDashed13: string; + readonly lineDashed14: string; + readonly lineDashed15: string; + readonly lineVertical: string; + readonly lineVerticalBold: string; + readonly lineVerticalDouble: string; + readonly lineVerticalDashed0: string; + readonly lineVerticalDashed1: string; + readonly lineVerticalDashed2: string; + readonly lineVerticalDashed3: string; + readonly lineVerticalDashed4: string; + readonly lineVerticalDashed5: string; + readonly lineVerticalDashed6: string; + readonly lineVerticalDashed7: string; + readonly lineVerticalDashed8: string; + readonly lineVerticalDashed9: string; + readonly lineVerticalDashed10: string; + readonly lineVerticalDashed11: string; + readonly lineDownLeft: string; + readonly lineDownLeftArc: string; + readonly lineDownBoldLeftBold: string; + readonly lineDownBoldLeft: string; + readonly lineDownLeftBold: string; + readonly lineDownDoubleLeftDouble: string; + readonly lineDownDoubleLeft: string; + readonly lineDownLeftDouble: string; + readonly lineDownRight: string; + readonly lineDownRightArc: string; + readonly lineDownBoldRightBold: string; + readonly lineDownBoldRight: string; + readonly lineDownRightBold: string; + readonly lineDownDoubleRightDouble: string; + readonly lineDownDoubleRight: string; + readonly lineDownRightDouble: string; + readonly lineUpLeft: string; + readonly lineUpLeftArc: string; + readonly lineUpBoldLeftBold: string; + readonly lineUpBoldLeft: string; + readonly lineUpLeftBold: string; + readonly lineUpDoubleLeftDouble: string; + readonly lineUpDoubleLeft: string; + readonly lineUpLeftDouble: string; + readonly lineUpRight: string; + readonly lineUpRightArc: string; + readonly lineUpBoldRightBold: string; + readonly lineUpBoldRight: string; + readonly lineUpRightBold: string; + readonly lineUpDoubleRightDouble: string; + readonly lineUpDoubleRight: string; + readonly lineUpRightDouble: string; + readonly lineUpDownLeft: string; + readonly lineUpBoldDownBoldLeftBold: string; + readonly lineUpBoldDownBoldLeft: string; + readonly lineUpDownLeftBold: string; + readonly lineUpBoldDownLeftBold: string; + readonly lineUpDownBoldLeftBold: string; + readonly lineUpDownBoldLeft: string; + readonly lineUpBoldDownLeft: string; + readonly lineUpDoubleDownDoubleLeftDouble: string; + readonly lineUpDoubleDownDoubleLeft: string; + readonly lineUpDownLeftDouble: string; + readonly lineUpDownRight: string; + readonly lineUpBoldDownBoldRightBold: string; + readonly lineUpBoldDownBoldRight: string; + readonly lineUpDownRightBold: string; + readonly lineUpBoldDownRightBold: string; + readonly lineUpDownBoldRightBold: string; + readonly lineUpDownBoldRight: string; + readonly lineUpBoldDownRight: string; + readonly lineUpDoubleDownDoubleRightDouble: string; + readonly lineUpDoubleDownDoubleRight: string; + readonly lineUpDownRightDouble: string; + readonly lineDownLeftRight: string; + readonly lineDownBoldLeftBoldRightBold: string; + readonly lineDownLeftBoldRightBold: string; + readonly lineDownBoldLeftRight: string; + readonly lineDownBoldLeftBoldRight: string; + readonly lineDownBoldLeftRightBold: string; + readonly lineDownLeftRightBold: string; + readonly lineDownLeftBoldRight: string; + readonly lineDownDoubleLeftDoubleRightDouble: string; + readonly lineDownDoubleLeftRight: string; + readonly lineDownLeftDoubleRightDouble: string; + readonly lineUpLeftRight: string; + readonly lineUpBoldLeftBoldRightBold: string; + readonly lineUpLeftBoldRightBold: string; + readonly lineUpBoldLeftRight: string; + readonly lineUpBoldLeftBoldRight: string; + readonly lineUpBoldLeftRightBold: string; + readonly lineUpLeftRightBold: string; + readonly lineUpLeftBoldRight: string; + readonly lineUpDoubleLeftDoubleRightDouble: string; + readonly lineUpDoubleLeftRight: string; + readonly lineUpLeftDoubleRightDouble: string; + readonly lineUpDownLeftRight: string; + readonly lineUpBoldDownBoldLeftBoldRightBold: string; + readonly lineUpDownBoldLeftBoldRightBold: string; + readonly lineUpBoldDownLeftBoldRightBold: string; + readonly lineUpBoldDownBoldLeftRightBold: string; + readonly lineUpBoldDownBoldLeftBoldRight: string; + readonly lineUpBoldDownLeftRight: string; + readonly lineUpDownBoldLeftRight: string; + readonly lineUpDownLeftBoldRight: string; + readonly lineUpDownLeftRightBold: string; + readonly lineUpBoldDownBoldLeftRight: string; + readonly lineUpDownLeftBoldRightBold: string; + readonly lineUpBoldDownLeftBoldRight: string; + readonly lineUpBoldDownLeftRightBold: string; + readonly lineUpDownBoldLeftBoldRight: string; + readonly lineUpDownBoldLeftRightBold: string; + readonly lineUpDoubleDownDoubleLeftDoubleRightDouble: string; + readonly lineUpDoubleDownDoubleLeftRight: string; + readonly lineUpDownLeftDoubleRightDouble: string; + readonly lineCross: string; + readonly lineBackslash: string; + readonly lineSlash: string; +}; + +type FigureSet = typeof figureSet; + +/** +Symbols to use when the terminal supports Unicode symbols. +*/ +export const mainSymbols: FigureSet; + +/** +Symbols to use when the terminal does not support Unicode symbols. +*/ +export const fallbackSymbols: FigureSet; + +/** +Symbols to use on any terminal. +*/ +export default figureSet; + +export type Options = { + /** + Whether to replace symbols with fallbacks. + + This can be set to `true` to always use fallback symbols, whether the terminal has poor Unicode support or not. + + @default `true` if the terminal has poor Unicode support + */ + readonly useFallback?: boolean; +}; + +/** +Returns the input with replaced fallback symbols if the terminal has poor Unicode support. + +@param string - String where the Unicode symbols will be replaced with fallback symbols depending on the terminal. +@returns The input with replaced fallback Unicode symbols. + +@example +``` +import figures, {replaceSymbols} from 'figures'; + +console.log(replaceSymbols('✔ check')); +// On terminals with Unicode symbols: ✔ check +// On other terminals: √ check + +console.log(replaceSymbols('✔ check', {useFallback: true})); +// On terminals with Unicode symbols: √ check +// On other terminals: √ check +``` +*/ +export function replaceSymbols(string: string, options?: Options): string; diff --git a/node_modules/execa/node_modules/figures/index.js b/node_modules/execa/node_modules/figures/index.js new file mode 100644 index 0000000000..642bce72c2 --- /dev/null +++ b/node_modules/execa/node_modules/figures/index.js @@ -0,0 +1,292 @@ +import isUnicodeSupported from 'is-unicode-supported'; + +const common = { + circleQuestionMark: '(?)', + questionMarkPrefix: '(?)', + square: '█', + squareDarkShade: '▓', + squareMediumShade: '▒', + squareLightShade: '░', + squareTop: '▀', + squareBottom: '▄', + squareLeft: '▌', + squareRight: '▐', + squareCenter: '■', + bullet: '●', + dot: '․', + ellipsis: '…', + pointerSmall: '›', + triangleUp: '▲', + triangleUpSmall: '▴', + triangleDown: '▼', + triangleDownSmall: '▾', + triangleLeftSmall: '◂', + triangleRightSmall: '▸', + home: '⌂', + heart: '♥', + musicNote: '♪', + musicNoteBeamed: '♫', + arrowUp: '↑', + arrowDown: '↓', + arrowLeft: '←', + arrowRight: '→', + arrowLeftRight: '↔', + arrowUpDown: '↕', + almostEqual: '≈', + notEqual: '≠', + lessOrEqual: '≤', + greaterOrEqual: '≥', + identical: '≡', + infinity: '∞', + subscriptZero: '₀', + subscriptOne: '₁', + subscriptTwo: '₂', + subscriptThree: '₃', + subscriptFour: '₄', + subscriptFive: '₅', + subscriptSix: '₆', + subscriptSeven: '₇', + subscriptEight: '₈', + subscriptNine: '₉', + oneHalf: '½', + oneThird: '⅓', + oneQuarter: '¼', + oneFifth: '⅕', + oneSixth: '⅙', + oneEighth: '⅛', + twoThirds: '⅔', + twoFifths: '⅖', + threeQuarters: '¾', + threeFifths: '⅗', + threeEighths: '⅜', + fourFifths: '⅘', + fiveSixths: '⅚', + fiveEighths: '⅝', + sevenEighths: '⅞', + line: '─', + lineBold: '━', + lineDouble: '═', + lineDashed0: '┄', + lineDashed1: '┅', + lineDashed2: '┈', + lineDashed3: '┉', + lineDashed4: '╌', + lineDashed5: '╍', + lineDashed6: '╴', + lineDashed7: '╶', + lineDashed8: '╸', + lineDashed9: '╺', + lineDashed10: '╼', + lineDashed11: '╾', + lineDashed12: '−', + lineDashed13: '–', + lineDashed14: '‐', + lineDashed15: '⁃', + lineVertical: '│', + lineVerticalBold: '┃', + lineVerticalDouble: '║', + lineVerticalDashed0: '┆', + lineVerticalDashed1: '┇', + lineVerticalDashed2: '┊', + lineVerticalDashed3: '┋', + lineVerticalDashed4: '╎', + lineVerticalDashed5: '╏', + lineVerticalDashed6: '╵', + lineVerticalDashed7: '╷', + lineVerticalDashed8: '╹', + lineVerticalDashed9: '╻', + lineVerticalDashed10: '╽', + lineVerticalDashed11: '╿', + lineDownLeft: '┐', + lineDownLeftArc: '╮', + lineDownBoldLeftBold: '┓', + lineDownBoldLeft: '┒', + lineDownLeftBold: '┑', + lineDownDoubleLeftDouble: '╗', + lineDownDoubleLeft: '╖', + lineDownLeftDouble: '╕', + lineDownRight: '┌', + lineDownRightArc: '╭', + lineDownBoldRightBold: '┏', + lineDownBoldRight: '┎', + lineDownRightBold: '┍', + lineDownDoubleRightDouble: '╔', + lineDownDoubleRight: '╓', + lineDownRightDouble: '╒', + lineUpLeft: '┘', + lineUpLeftArc: '╯', + lineUpBoldLeftBold: '┛', + lineUpBoldLeft: '┚', + lineUpLeftBold: '┙', + lineUpDoubleLeftDouble: '╝', + lineUpDoubleLeft: '╜', + lineUpLeftDouble: '╛', + lineUpRight: '└', + lineUpRightArc: '╰', + lineUpBoldRightBold: '┗', + lineUpBoldRight: '┖', + lineUpRightBold: '┕', + lineUpDoubleRightDouble: '╚', + lineUpDoubleRight: '╙', + lineUpRightDouble: '╘', + lineUpDownLeft: '┤', + lineUpBoldDownBoldLeftBold: '┫', + lineUpBoldDownBoldLeft: '┨', + lineUpDownLeftBold: '┥', + lineUpBoldDownLeftBold: '┩', + lineUpDownBoldLeftBold: '┪', + lineUpDownBoldLeft: '┧', + lineUpBoldDownLeft: '┦', + lineUpDoubleDownDoubleLeftDouble: '╣', + lineUpDoubleDownDoubleLeft: '╢', + lineUpDownLeftDouble: '╡', + lineUpDownRight: '├', + lineUpBoldDownBoldRightBold: '┣', + lineUpBoldDownBoldRight: '┠', + lineUpDownRightBold: '┝', + lineUpBoldDownRightBold: '┡', + lineUpDownBoldRightBold: '┢', + lineUpDownBoldRight: '┟', + lineUpBoldDownRight: '┞', + lineUpDoubleDownDoubleRightDouble: '╠', + lineUpDoubleDownDoubleRight: '╟', + lineUpDownRightDouble: '╞', + lineDownLeftRight: '┬', + lineDownBoldLeftBoldRightBold: '┳', + lineDownLeftBoldRightBold: '┯', + lineDownBoldLeftRight: '┰', + lineDownBoldLeftBoldRight: '┱', + lineDownBoldLeftRightBold: '┲', + lineDownLeftRightBold: '┮', + lineDownLeftBoldRight: '┭', + lineDownDoubleLeftDoubleRightDouble: '╦', + lineDownDoubleLeftRight: '╥', + lineDownLeftDoubleRightDouble: '╤', + lineUpLeftRight: '┴', + lineUpBoldLeftBoldRightBold: '┻', + lineUpLeftBoldRightBold: '┷', + lineUpBoldLeftRight: '┸', + lineUpBoldLeftBoldRight: '┹', + lineUpBoldLeftRightBold: '┺', + lineUpLeftRightBold: '┶', + lineUpLeftBoldRight: '┵', + lineUpDoubleLeftDoubleRightDouble: '╩', + lineUpDoubleLeftRight: '╨', + lineUpLeftDoubleRightDouble: '╧', + lineUpDownLeftRight: '┼', + lineUpBoldDownBoldLeftBoldRightBold: '╋', + lineUpDownBoldLeftBoldRightBold: '╈', + lineUpBoldDownLeftBoldRightBold: '╇', + lineUpBoldDownBoldLeftRightBold: '╊', + lineUpBoldDownBoldLeftBoldRight: '╉', + lineUpBoldDownLeftRight: '╀', + lineUpDownBoldLeftRight: '╁', + lineUpDownLeftBoldRight: '┽', + lineUpDownLeftRightBold: '┾', + lineUpBoldDownBoldLeftRight: '╂', + lineUpDownLeftBoldRightBold: '┿', + lineUpBoldDownLeftBoldRight: '╃', + lineUpBoldDownLeftRightBold: '╄', + lineUpDownBoldLeftBoldRight: '╅', + lineUpDownBoldLeftRightBold: '╆', + lineUpDoubleDownDoubleLeftDoubleRightDouble: '╬', + lineUpDoubleDownDoubleLeftRight: '╫', + lineUpDownLeftDoubleRightDouble: '╪', + lineCross: '╳', + lineBackslash: '╲', + lineSlash: '╱', +}; + +const specialMainSymbols = { + tick: '✔', + info: 'ℹ', + warning: '⚠', + cross: '✘', + squareSmall: '◻', + squareSmallFilled: '◼', + circle: '◯', + circleFilled: '◉', + circleDotted: '◌', + circleDouble: '◎', + circleCircle: 'ⓞ', + circleCross: 'ⓧ', + circlePipe: 'Ⓘ', + radioOn: '◉', + radioOff: '◯', + checkboxOn: '☒', + checkboxOff: '☐', + checkboxCircleOn: 'ⓧ', + checkboxCircleOff: 'Ⓘ', + pointer: '❯', + triangleUpOutline: '△', + triangleLeft: '◀', + triangleRight: '▶', + lozenge: '◆', + lozengeOutline: '◇', + hamburger: '☰', + smiley: '㋡', + mustache: '෴', + star: '★', + play: '▶', + nodejs: '⬢', + oneSeventh: '⅐', + oneNinth: '⅑', + oneTenth: '⅒', +}; + +const specialFallbackSymbols = { + tick: '√', + info: 'i', + warning: '‼', + cross: '×', + squareSmall: '□', + squareSmallFilled: '■', + circle: '( )', + circleFilled: '(*)', + circleDotted: '( )', + circleDouble: '( )', + circleCircle: '(○)', + circleCross: '(×)', + circlePipe: '(│)', + radioOn: '(*)', + radioOff: '( )', + checkboxOn: '[×]', + checkboxOff: '[ ]', + checkboxCircleOn: '(×)', + checkboxCircleOff: '( )', + pointer: '>', + triangleUpOutline: '∆', + triangleLeft: '◄', + triangleRight: '►', + lozenge: '♦', + lozengeOutline: '◊', + hamburger: '≡', + smiley: '☺', + mustache: '┌─┐', + star: '✶', + play: '►', + nodejs: '♦', + oneSeventh: '1/7', + oneNinth: '1/9', + oneTenth: '1/10', +}; + +export const mainSymbols = {...common, ...specialMainSymbols}; +export const fallbackSymbols = {...common, ...specialFallbackSymbols}; + +const shouldUseMain = isUnicodeSupported(); +const figures = shouldUseMain ? mainSymbols : fallbackSymbols; +export default figures; + +const replacements = Object.entries(specialMainSymbols); + +// On terminals which do not support Unicode symbols, substitute them to other symbols +export const replaceSymbols = (string, {useFallback = !shouldUseMain} = {}) => { + if (useFallback) { + for (const [key, mainSymbol] of replacements) { + string = string.replaceAll(mainSymbol, fallbackSymbols[key]); + } + } + + return string; +}; diff --git a/node_modules/execa/node_modules/figures/license b/node_modules/execa/node_modules/figures/license new file mode 100644 index 0000000000..fa7ceba3eb --- /dev/null +++ b/node_modules/execa/node_modules/figures/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/execa/node_modules/figures/package.json b/node_modules/execa/node_modules/figures/package.json new file mode 100644 index 0000000000..c592dd0440 --- /dev/null +++ b/node_modules/execa/node_modules/figures/package.json @@ -0,0 +1,49 @@ +{ + "name": "figures", + "version": "6.1.0", + "description": "Unicode symbols with fallbacks for older terminals", + "license": "MIT", + "repository": "sindresorhus/figures", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "unicode", + "cli", + "cmd", + "command-line", + "characters", + "symbol", + "symbols", + "figure", + "figures", + "fallback" + ], + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "devDependencies": { + "ava": "^5.3.1", + "tsd": "^0.29.0", + "xo": "^0.56.0" + } +} diff --git a/node_modules/execa/node_modules/figures/readme.md b/node_modules/execa/node_modules/figures/readme.md new file mode 100644 index 0000000000..950ca0575d --- /dev/null +++ b/node_modules/execa/node_modules/figures/readme.md @@ -0,0 +1,337 @@ +# figures + +> Unicode symbols with fallbacks for older terminals + +[![](screenshot.png)](index.js) + +[*and more...*](index.js) + +Terminals such as Windows Console Host (and CMD) only support a [limited character set](http://en.wikipedia.org/wiki/Code_page_437). + +## Install + +```sh +npm install figures +``` + +## Usage + +```js +import figures, {mainSymbols, fallbackSymbols, replaceSymbols} from 'figures'; + +console.log(figures.tick); +// On terminals with Unicode symbols: ✔ +// On other terminals: √ + +console.log(mainSymbols.tick); +// On all terminals: ✔ + +console.log(fallbackSymbols.tick); +// On all terminals: √ + +console.log(replaceSymbols('✔ check')); +// On terminals with Unicode symbols: ✔ check +// On other terminals: √ check +``` + +## API + +### figures (default export) + +Type: `object` + +Symbols to use on any terminal. + +### mainSymbols + +Symbols to use when the terminal supports Unicode symbols. + +### fallbackSymbols + +Symbols to use when the terminal does not support Unicode symbols. + +### replaceSymbols(string, options?) + +Returns the input with replaced fallback symbols if the terminal has poor Unicode support. + +All the below [figures](#figures) are attached to the default export as shown in the example above. + +#### string + +Type: `string` + +String where the Unicode symbols will be replaced with fallback symbols depending on the terminal. + +#### options + +Type: `object` + +##### useFallback + +Type: `boolean`\ +Default: `true` if the terminal has poor Unicode support + +Whether to replace symbols with fallbacks. + +This can be set to `true` to always use fallback symbols, whether the terminal has poor Unicode support or not. + +```js +import {replaceSymbols} from 'figures'; + +console.log(replaceSymbols('✔ check', {useFallback: true})); +// On terminals with Unicode symbols: √ check +// On other terminals: √ check +``` + +## Figures + +`Fallback` characters are only shown when they differ from the `Main` ones. + +| Name | Main | Fallback | +| ------------------------------------------- | :--: | :------: | +| tick | `✔` | `√` | +| info | `ℹ` | `i` | +| warning | `⚠` | `‼` | +| cross | `✘` | `×` | +| square | `█` | | +| squareSmall | `◻` | `□` | +| squareSmallFilled | `◼` | `■` | +| squareDarkShade | `▓` | | +| squareMediumShade | `▒` | | +| squareLightShade | `░` | | +| squareTop | `▀` | | +| squareBottom | `▄` | | +| squareLeft | `▌` | | +| squareRight | `▐` | | +| squareCenter | `■` | | +| circle | `◯` | `( )` | +| circleFilled | `◉` | `(*)` | +| circleDotted | `◌` | `( )` | +| circleDouble | `◎` | `( )` | +| circleCircle | `ⓞ` | `(○)` | +| circleCross | `ⓧ` | `(×)` | +| circlePipe | `Ⓘ` | `(│)` | +| circleQuestionMark | `?⃝ ` | `(?)` | +| radioOn | `◉` | `(*)` | +| radioOff | `◯` | `( )` | +| checkboxOn | `☒` | `[×]` | +| checkboxOff | `☐` | `[ ]` | +| checkboxCircleOn | `ⓧ` | `(×)` | +| checkboxCircleOff | `Ⓘ` | `( )` | +| questionMarkPrefix | `?⃝ ` | `?` | +| bullet | `●` | | +| dot | `․` | | +| ellipsis | `…` | | +| pointer | `❯` | `>` | +| pointerSmall | `›` | `›` | +| triangleUp | `▲` | | +| triangleUpSmall | `▴` | | +| triangleUpOutline | `△` | `∆` | +| triangleDown | `▼` | | +| triangleDownSmall | `▾` | | +| triangleLeft | `◀` | `◄` | +| triangleLeftSmall | `◂` | | +| triangleRight | `▶` | `►` | +| triangleRightSmall | `▸` | | +| lozenge | `◆` | `♦` | +| lozengeOutline | `◇` | `◊` | +| home | `⌂` | | +| hamburger | `☰` | `≡` | +| smiley | `㋡` | `☺` | +| mustache | `෴` | `┌─┐` | +| heart | `♥` | | +| star | `★` | `✶` | +| play | `▶` | `►` | +| musicNote | `♪` | | +| musicNoteBeamed | `♫` | | +| nodejs | `⬢` | `♦` | +| arrowUp | `↑` | | +| arrowDown | `↓` | | +| arrowLeft | `←` | | +| arrowRight | `→` | | +| arrowLeftRight | `↔` | | +| arrowUpDown | `↕` | | +| almostEqual | `≈` | | +| notEqual | `≠` | | +| lessOrEqual | `≤` | | +| greaterOrEqual | `≥` | | +| identical | `≡` | | +| infinity | `∞` | | +| subscriptZero | `₀` | | +| subscriptOne | `₁` | | +| subscriptTwo | `₂` | | +| subscriptThree | `₃` | | +| subscriptFour | `₄` | | +| subscriptFive | `₅` | | +| subscriptSix | `₆` | | +| subscriptSeven | `₇` | | +| subscriptEight | `₈` | | +| subscriptNine | `₉` | | +| oneHalf | `½` | | +| oneThird | `⅓` | | +| oneQuarter | `¼` | | +| oneFifth | `⅕` | | +| oneSixth | `⅙` | | +| oneSeventh | `⅐` | `1/7` | +| oneEighth | `⅛` | | +| oneNinth | `⅑` | `1/9` | +| oneTenth | `⅒` | `1/10` | +| twoThirds | `⅔` | | +| twoFifths | `⅖` | | +| threeQuarters | `¾` | | +| threeFifths | `⅗` | | +| threeEighths | `⅜` | | +| fourFifths | `⅘` | | +| fiveSixths | `⅚` | | +| fiveEighths | `⅝` | | +| sevenEighths | `⅞` | | +| line | `─` | | +| lineBold | `━` | | +| lineDouble | `═` | | +| lineDashed0 | `┄` | | +| lineDashed1 | `┅` | | +| lineDashed2 | `┈` | | +| lineDashed3 | `┉` | | +| lineDashed4 | `╌` | | +| lineDashed5 | `╍` | | +| lineDashed6 | `╴` | | +| lineDashed7 | `╶` | | +| lineDashed8 | `╸` | | +| lineDashed9 | `╺` | | +| lineDashed10 | `╼` | | +| lineDashed11 | `╾` | | +| lineDashed12 | `−` | | +| lineDashed13 | `–` | | +| lineDashed14 | `‐` | | +| lineDashed15 | `⁃` | | +| lineVertical | `│` | | +| lineVerticalBold | `┃` | | +| lineVerticalDouble | `║` | | +| lineVerticalDashed0 | `┆` | | +| lineVerticalDashed1 | `┇` | | +| lineVerticalDashed2 | `┊` | | +| lineVerticalDashed3 | `┋` | | +| lineVerticalDashed4 | `╎` | | +| lineVerticalDashed5 | `╏` | | +| lineVerticalDashed6 | `╵` | | +| lineVerticalDashed7 | `╷` | | +| lineVerticalDashed8 | `╹` | | +| lineVerticalDashed9 | `╻` | | +| lineVerticalDashed10 | `╽` | | +| lineVerticalDashed11 | `╿` | | +| lineDownLeft | `┐` | | +| lineDownLeftArc | `╮` | | +| lineDownBoldLeftBold | `┓` | | +| lineDownBoldLeft | `┒` | | +| lineDownLeftBold | `┑` | | +| lineDownDoubleLeftDouble | `╗` | | +| lineDownDoubleLeft | `╖` | | +| lineDownLeftDouble | `╕` | | +| lineDownRight | `┌` | | +| lineDownRightArc | `╭` | | +| lineDownBoldRightBold | `┏` | | +| lineDownBoldRight | `┎` | | +| lineDownRightBold | `┍` | | +| lineDownDoubleRightDouble | `╔` | | +| lineDownDoubleRight | `╓` | | +| lineDownRightDouble | `╒` | | +| lineUpLeft | `┘` | | +| lineUpLeftArc | `╯` | | +| lineUpBoldLeftBold | `┛` | | +| lineUpBoldLeft | `┚` | | +| lineUpLeftBold | `┙` | | +| lineUpDoubleLeftDouble | `╝` | | +| lineUpDoubleLeft | `╜` | | +| lineUpLeftDouble | `╛` | | +| lineUpRight | `└` | | +| lineUpRightArc | `╰` | | +| lineUpBoldRightBold | `┗` | | +| lineUpBoldRight | `┖` | | +| lineUpRightBold | `┕` | | +| lineUpDoubleRightDouble | `╚` | | +| lineUpDoubleRight | `╙` | | +| lineUpRightDouble | `╘` | | +| lineUpDownLeft | `┤` | | +| lineUpBoldDownBoldLeftBold | `┫` | | +| lineUpBoldDownBoldLeft | `┨` | | +| lineUpDownLeftBold | `┥` | | +| lineUpBoldDownLeftBold | `┩` | | +| lineUpDownBoldLeftBold | `┪` | | +| lineUpDownBoldLeft | `┧` | | +| lineUpBoldDownLeft | `┦` | | +| lineUpDoubleDownDoubleLeftDouble | `╣` | | +| lineUpDoubleDownDoubleLeft | `╢` | | +| lineUpDownLeftDouble | `╡` | | +| lineUpDownRight | `├` | | +| lineUpBoldDownBoldRightBold | `┣` | | +| lineUpBoldDownBoldRight | `┠` | | +| lineUpDownRightBold | `┝` | | +| lineUpBoldDownRightBold | `┡` | | +| lineUpDownBoldRightBold | `┢` | | +| lineUpDownBoldRight | `┟` | | +| lineUpBoldDownRight | `┞` | | +| lineUpDoubleDownDoubleRightDouble | `╠` | | +| lineUpDoubleDownDoubleRight | `╟` | | +| lineUpDownRightDouble | `╞` | | +| lineDownLeftRight | `┬` | | +| lineDownBoldLeftBoldRightBold | `┳` | | +| lineDownLeftBoldRightBold | `┯` | | +| lineDownBoldLeftRight | `┰` | | +| lineDownBoldLeftBoldRight | `┱` | | +| lineDownBoldLeftRightBold | `┲` | | +| lineDownLeftRightBold | `┮` | | +| lineDownLeftBoldRight | `┭` | | +| lineDownDoubleLeftDoubleRightDouble | `╦` | | +| lineDownDoubleLeftRight | `╥` | | +| lineDownLeftDoubleRightDouble | `╤` | | +| lineUpLeftRight | `┴` | | +| lineUpBoldLeftBoldRightBold | `┻` | | +| lineUpLeftBoldRightBold | `┷` | | +| lineUpBoldLeftRight | `┸` | | +| lineUpBoldLeftBoldRight | `┹` | | +| lineUpBoldLeftRightBold | `┺` | | +| lineUpLeftRightBold | `┶` | | +| lineUpLeftBoldRight | `┵` | | +| lineUpDoubleLeftDoubleRightDouble | `╩` | | +| lineUpDoubleLeftRight | `╨` | | +| lineUpLeftDoubleRightDouble | `╧` | | +| lineUpDownLeftRight | `┼` | | +| lineUpBoldDownBoldLeftBoldRightBold | `╋` | | +| lineUpDownBoldLeftBoldRightBold | `╈` | | +| lineUpBoldDownLeftBoldRightBold | `╇` | | +| lineUpBoldDownBoldLeftRightBold | `╊` | | +| lineUpBoldDownBoldLeftBoldRight | `╉` | | +| lineUpBoldDownLeftRight | `╀` | | +| lineUpDownBoldLeftRight | `╁` | | +| lineUpDownLeftBoldRight | `┽` | | +| lineUpDownLeftRightBold | `┾` | | +| lineUpBoldDownBoldLeftRight | `╂` | | +| lineUpDownLeftBoldRightBold | `┿` | | +| lineUpBoldDownLeftBoldRight | `╃` | | +| lineUpBoldDownLeftRightBold | `╄` | | +| lineUpDownBoldLeftBoldRight | `╅` | | +| lineUpDownBoldLeftRightBold | `╆` | | +| lineUpDoubleDownDoubleLeftDoubleRightDouble | `╬` | | +| lineUpDoubleDownDoubleLeftRight | `╫` | | +| lineUpDownLeftDoubleRightDouble | `╪` | | +| lineCross | `╳` | | +| lineBackslash | `╲` | | +| lineSlash | `╱` | | + +## Other characters + +If you cannot find the character you're looking for in the table above, please look at this full list of [cross-platform terminal characters](https://github.com/ehmicky/cross-platform-terminal-characters). + +## Unsupported terminals + +The following terminals are not officially supported: + +- xterm +- Linux Terminal (kernel) +- cmder + +They can display most but not all of the symbols listed above. + +## Related + +- [log-symbols](https://github.com/sindresorhus/log-symbols) - Colored symbols for various log levels diff --git a/node_modules/execa/node_modules/is-unicode-supported/index.d.ts b/node_modules/execa/node_modules/is-unicode-supported/index.d.ts new file mode 100644 index 0000000000..944a8783eb --- /dev/null +++ b/node_modules/execa/node_modules/is-unicode-supported/index.d.ts @@ -0,0 +1,12 @@ +/** +Detect whether the terminal supports Unicode. + +@example +``` +import isUnicodeSupported from 'is-unicode-supported'; + +isUnicodeSupported(); +//=> true +``` +*/ +export default function isUnicodeSupported(): boolean; diff --git a/node_modules/execa/node_modules/is-unicode-supported/index.js b/node_modules/execa/node_modules/is-unicode-supported/index.js new file mode 100644 index 0000000000..1e435ca90b --- /dev/null +++ b/node_modules/execa/node_modules/is-unicode-supported/index.js @@ -0,0 +1,21 @@ +import process from 'node:process'; + +export default function isUnicodeSupported() { + const {env} = process; + const {TERM, TERM_PROGRAM} = env; + + if (process.platform !== 'win32') { + return TERM !== 'linux'; // Linux console (kernel) + } + + return Boolean(env.WT_SESSION) // Windows Terminal + || Boolean(env.TERMINUS_SUBLIME) // Terminus (<0.2.27) + || env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder + || TERM_PROGRAM === 'Terminus-Sublime' + || TERM_PROGRAM === 'vscode' + || TERM === 'xterm-256color' + || TERM === 'alacritty' + || TERM === 'rxvt-unicode' + || TERM === 'rxvt-unicode-256color' + || env.TERMINAL_EMULATOR === 'JetBrains-JediTerm'; +} diff --git a/node_modules/execa/node_modules/is-unicode-supported/license b/node_modules/execa/node_modules/is-unicode-supported/license new file mode 100644 index 0000000000..fa7ceba3eb --- /dev/null +++ b/node_modules/execa/node_modules/is-unicode-supported/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/execa/node_modules/is-unicode-supported/package.json b/node_modules/execa/node_modules/is-unicode-supported/package.json new file mode 100644 index 0000000000..973e642901 --- /dev/null +++ b/node_modules/execa/node_modules/is-unicode-supported/package.json @@ -0,0 +1,47 @@ +{ + "name": "is-unicode-supported", + "version": "2.1.0", + "description": "Detect whether the terminal supports Unicode", + "license": "MIT", + "repository": "sindresorhus/is-unicode-supported", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "terminal", + "unicode", + "detect", + "utf8", + "console", + "shell", + "support", + "supports", + "supported", + "check", + "detection" + ], + "devDependencies": { + "ava": "^6.1.3", + "tsd": "^0.31.2", + "xo": "^0.59.3" + } +} diff --git a/node_modules/execa/node_modules/is-unicode-supported/readme.md b/node_modules/execa/node_modules/is-unicode-supported/readme.md new file mode 100644 index 0000000000..e1954ec37e --- /dev/null +++ b/node_modules/execa/node_modules/is-unicode-supported/readme.md @@ -0,0 +1,35 @@ +# is-unicode-supported + +> Detect whether the terminal supports Unicode + +This can be useful to decide whether to use Unicode characters or fallback ASCII characters in command-line output. + +Note that the check is quite naive. It just assumes all non-Windows terminals support Unicode and hard-codes which Windows terminals that do support Unicode. However, I have been using this logic in some popular packages for years without problems. + +## Install + +```sh +npm install is-unicode-supported +``` + +## Usage + +```js +import isUnicodeSupported from 'is-unicode-supported'; + +isUnicodeSupported(); +//=> true +``` + +## API + +### isUnicodeSupported() + +Returns a `boolean` for whether the terminal supports Unicode. + +## Related + +- [is-interactive](https://github.com/sindresorhus/is-interactive) - Check if stdout or stderr is interactive +- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color +- [figures](https://github.com/sindresorhus/figures) - Unicode symbols with Windows fallbacks +- [log-symbols](https://github.com/sindresorhus/log-symbols) - Colored symbols for various log levels diff --git a/node_modules/execa/node_modules/parse-ms/index.d.ts b/node_modules/execa/node_modules/parse-ms/index.d.ts new file mode 100644 index 0000000000..df9895cd75 --- /dev/null +++ b/node_modules/execa/node_modules/parse-ms/index.d.ts @@ -0,0 +1,30 @@ +export type TimeComponents = { + days: T; + hours: T; + minutes: T; + seconds: T; + milliseconds: T; + microseconds: T; + nanoseconds: T; +}; + +/** +Parse milliseconds into an object. + +@example +``` +import parseMilliseconds from 'parse-ms'; + +parseMilliseconds(1337000001); +// { +// days: 15, +// hours: 11, +// minutes: 23, +// seconds: 20, +// milliseconds: 1, +// microseconds: 0, +// nanoseconds: 0 +// } +``` +*/ +export default function parseMilliseconds(milliseconds: T): TimeComponents; diff --git a/node_modules/execa/node_modules/parse-ms/index.js b/node_modules/execa/node_modules/parse-ms/index.js new file mode 100644 index 0000000000..c62e670ed6 --- /dev/null +++ b/node_modules/execa/node_modules/parse-ms/index.js @@ -0,0 +1,45 @@ +const toZeroIfInfinity = value => Number.isFinite(value) ? value : 0; + +function parseNumber(milliseconds) { + return { + days: Math.trunc(milliseconds / 86_400_000), + hours: Math.trunc(milliseconds / 3_600_000 % 24), + minutes: Math.trunc(milliseconds / 60_000 % 60), + seconds: Math.trunc(milliseconds / 1000 % 60), + milliseconds: Math.trunc(milliseconds % 1000), + microseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1000) % 1000), + nanoseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e6) % 1000), + }; +} + +function parseBigint(milliseconds) { + return { + days: milliseconds / 86_400_000n, + hours: milliseconds / 3_600_000n % 24n, + minutes: milliseconds / 60_000n % 60n, + seconds: milliseconds / 1000n % 60n, + milliseconds: milliseconds % 1000n, + microseconds: 0n, + nanoseconds: 0n, + }; +} + +export default function parseMilliseconds(milliseconds) { + switch (typeof milliseconds) { + case 'number': { + if (Number.isFinite(milliseconds)) { + return parseNumber(milliseconds); + } + + break; + } + + case 'bigint': { + return parseBigint(milliseconds); + } + + // No default + } + + throw new TypeError('Expected a finite number or bigint'); +} diff --git a/node_modules/execa/node_modules/parse-ms/license b/node_modules/execa/node_modules/parse-ms/license new file mode 100644 index 0000000000..fa7ceba3eb --- /dev/null +++ b/node_modules/execa/node_modules/parse-ms/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/execa/node_modules/parse-ms/package.json b/node_modules/execa/node_modules/parse-ms/package.json new file mode 100644 index 0000000000..a54bf0f903 --- /dev/null +++ b/node_modules/execa/node_modules/parse-ms/package.json @@ -0,0 +1,47 @@ +{ + "name": "parse-ms", + "version": "4.0.0", + "description": "Parse milliseconds into an object", + "license": "MIT", + "repository": "sindresorhus/parse-ms", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "browser", + "parse", + "time", + "ms", + "milliseconds", + "microseconds", + "nanoseconds", + "duration", + "period", + "range", + "interval" + ], + "devDependencies": { + "ava": "^6.0.1", + "tsd": "^0.30.3", + "xo": "^0.56.0" + } +} diff --git a/node_modules/execa/node_modules/parse-ms/readme.md b/node_modules/execa/node_modules/parse-ms/readme.md new file mode 100644 index 0000000000..488cccd7b8 --- /dev/null +++ b/node_modules/execa/node_modules/parse-ms/readme.md @@ -0,0 +1,46 @@ +# parse-ms + +> Parse milliseconds into an object + +## Install + +```sh +npm install parse-ms +``` + +## Usage + +```js +import parseMilliseconds from 'parse-ms'; + +parseMilliseconds(1337000001); +/* +{ + days: 15, + hours: 11, + minutes: 23, + seconds: 20, + milliseconds: 1, + microseconds: 0, + nanoseconds: 0 +} +*/ + +parseMilliseconds(1337000001n); +/* +{ + days: 15n, + hours: 11n, + minutes: 23n, + seconds: 20n, + milliseconds: 1n, + microseconds: 0n, + nanoseconds: 0n +} +*/ +``` + +## Related + +- [to-milliseconds](https://github.com/sindresorhus/to-milliseconds) - The inverse of this module +- [pretty-ms](https://github.com/sindresorhus/pretty-ms) - Convert milliseconds to a human readable string diff --git a/node_modules/execa/node_modules/pretty-ms/index.d.ts b/node_modules/execa/node_modules/pretty-ms/index.d.ts new file mode 100644 index 0000000000..c513ad9954 --- /dev/null +++ b/node_modules/execa/node_modules/pretty-ms/index.d.ts @@ -0,0 +1,144 @@ +export type Options = { + /** + Number of digits to appear after the seconds decimal point. + + @default 1 + */ + readonly secondsDecimalDigits?: number; + + /** + Number of digits to appear after the milliseconds decimal point. + + Useful in combination with [`process.hrtime()`](https://nodejs.org/api/process.html#process_process_hrtime). + + @default 0 + */ + readonly millisecondsDecimalDigits?: number; + + /** + Keep milliseconds on whole seconds: `13s` → `13.0s`. + + Useful when you are showing a number of seconds spent on an operation and don't want the width of the output to change when hitting a whole number. + + @default false + */ + readonly keepDecimalsOnWholeSeconds?: boolean; + + /** + Only show the first unit: `1h 10m` → `1h`. + + Also ensures that `millisecondsDecimalDigits` and `secondsDecimalDigits` are both set to `0`. + + @default false + */ + readonly compact?: boolean; + + /** + Number of units to show. Setting `compact` to `true` overrides this option. + + @default Infinity + */ + readonly unitCount?: number; + + /** + Use full-length units: `5h 1m 45s` → `5 hours 1 minute 45 seconds`. + + @default false + */ + readonly verbose?: boolean; + + /** + Show milliseconds separately. This means they won't be included in the decimal part of the seconds. + + @default false + */ + readonly separateMilliseconds?: boolean; + + /** + Show microseconds and nanoseconds. + + @default false + */ + readonly formatSubMilliseconds?: boolean; + + /** + Display time using colon notation: `5h 1m 45s` → `5:01:45`. Always shows time in at least minutes: `1s` → `0:01` + + Useful when you want to display time without the time units, similar to a digital watch. + + Setting `colonNotation` to `true` overrides the following options to `false`: + - `compact` + - `formatSubMilliseconds` + - `separateMilliseconds` + - `verbose` + + @default false + */ + readonly colonNotation?: boolean; + + /** + Hides the year and shows the hidden year additionally as days (365 per year): `1y 3d 5h 1m 45s` → `368d 5h 1m 45s`. + + @default false + */ + readonly hideYear?: boolean; + + /** + Hides the year and days and shows the hidden values additionally as hours: `1y 3d 5h 1m 45s` → `8837h 1m 45s`. + + @default false + */ + readonly hideYearAndDays?: boolean; + + /** + Hides the seconds: `1y 3d 5h 1m 45s` → `1y 3d 5h 1m`. + + @default false + */ + readonly hideSeconds?: boolean; +}; + +/** +Convert milliseconds to a human readable string: `1337000000` → `15d 11h 23m 20s`. + +@param milliseconds - Milliseconds to humanize. + +@example +``` +import prettyMilliseconds from 'pretty-ms'; + +prettyMilliseconds(1337000000); +//=> '15d 11h 23m 20s' + +prettyMilliseconds(1337); +//=> '1.3s' + +prettyMilliseconds(133); +//=> '133ms' + +// `compact` option +prettyMilliseconds(1337, {compact: true}); +//=> '1s' + +// `verbose` option +prettyMilliseconds(1335669000, {verbose: true}); +//=> '15 days 11 hours 1 minute 9 seconds' + +// `colonNotation` option +prettyMilliseconds(95500, {colonNotation: true}); +//=> '1:35.5' + +// `formatSubMilliseconds` option +prettyMilliseconds(100.400080, {formatSubMilliseconds: true}) +//=> '100ms 400µs 80ns' + +// Can be useful for time durations +prettyMilliseconds(new Date(2014, 0, 1, 10, 40) - new Date(2014, 0, 1, 10, 5)) +//=> '35m' +``` +*/ +export default function prettyMilliseconds( + milliseconds: number | bigint, + options?: Options +): string; + diff --git a/node_modules/execa/node_modules/pretty-ms/index.js b/node_modules/execa/node_modules/pretty-ms/index.js new file mode 100644 index 0000000000..d8e0f0d557 --- /dev/null +++ b/node_modules/execa/node_modules/pretty-ms/index.js @@ -0,0 +1,149 @@ +import parseMilliseconds from 'parse-ms'; + +const isZero = value => value === 0 || value === 0n; +const pluralize = (word, count) => (count === 1 || count === 1n) ? word : `${word}s`; + +const SECOND_ROUNDING_EPSILON = 0.000_000_1; +const ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n; + +export default function prettyMilliseconds(milliseconds, options) { + const isBigInt = typeof milliseconds === 'bigint'; + if (!isBigInt && !Number.isFinite(milliseconds)) { + throw new TypeError('Expected a finite number or bigint'); + } + + options = {...options}; + + const sign = milliseconds < 0 ? '-' : ''; + milliseconds = milliseconds < 0 ? -milliseconds : milliseconds; // Cannot use `Math.abs()` because of BigInt support. + + if (options.colonNotation) { + options.compact = false; + options.formatSubMilliseconds = false; + options.separateMilliseconds = false; + options.verbose = false; + } + + if (options.compact) { + options.unitCount = 1; + options.secondsDecimalDigits = 0; + options.millisecondsDecimalDigits = 0; + } + + let result = []; + + const floorDecimals = (value, decimalDigits) => { + const flooredInterimValue = Math.floor((value * (10 ** decimalDigits)) + SECOND_ROUNDING_EPSILON); + const flooredValue = Math.round(flooredInterimValue) / (10 ** decimalDigits); + return flooredValue.toFixed(decimalDigits); + }; + + const add = (value, long, short, valueString) => { + if ( + (result.length === 0 || !options.colonNotation) + && isZero(value) + && !(options.colonNotation && short === 'm')) { + return; + } + + valueString ??= String(value); + if (options.colonNotation) { + const wholeDigits = valueString.includes('.') ? valueString.split('.')[0].length : valueString.length; + const minLength = result.length > 0 ? 2 : 1; + valueString = '0'.repeat(Math.max(0, minLength - wholeDigits)) + valueString; + } else { + valueString += options.verbose ? ' ' + pluralize(long, value) : short; + } + + result.push(valueString); + }; + + const parsed = parseMilliseconds(milliseconds); + const days = BigInt(parsed.days); + + if (options.hideYearAndDays) { + add((BigInt(days) * 24n) + BigInt(parsed.hours), 'hour', 'h'); + } else { + if (options.hideYear) { + add(days, 'day', 'd'); + } else { + add(days / 365n, 'year', 'y'); + add(days % 365n, 'day', 'd'); + } + + add(Number(parsed.hours), 'hour', 'h'); + } + + add(Number(parsed.minutes), 'minute', 'm'); + + if (!options.hideSeconds) { + if ( + options.separateMilliseconds + || options.formatSubMilliseconds + || (!options.colonNotation && milliseconds < 1000) + ) { + const seconds = Number(parsed.seconds); + const milliseconds = Number(parsed.milliseconds); + const microseconds = Number(parsed.microseconds); + const nanoseconds = Number(parsed.nanoseconds); + + add(seconds, 'second', 's'); + + if (options.formatSubMilliseconds) { + add(milliseconds, 'millisecond', 'ms'); + add(microseconds, 'microsecond', 'µs'); + add(nanoseconds, 'nanosecond', 'ns'); + } else { + const millisecondsAndBelow + = milliseconds + + (microseconds / 1000) + + (nanoseconds / 1e6); + + const millisecondsDecimalDigits + = typeof options.millisecondsDecimalDigits === 'number' + ? options.millisecondsDecimalDigits + : 0; + + const roundedMilliseconds = millisecondsAndBelow >= 1 + ? Math.round(millisecondsAndBelow) + : Math.ceil(millisecondsAndBelow); + + const millisecondsString = millisecondsDecimalDigits + ? millisecondsAndBelow.toFixed(millisecondsDecimalDigits) + : roundedMilliseconds; + + add( + Number.parseFloat(millisecondsString), + 'millisecond', + 'ms', + millisecondsString, + ); + } + } else { + const seconds = ( + (isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds) + / 1000 + ) % 60; + const secondsDecimalDigits + = typeof options.secondsDecimalDigits === 'number' + ? options.secondsDecimalDigits + : 1; + const secondsFixed = floorDecimals(seconds, secondsDecimalDigits); + const secondsString = options.keepDecimalsOnWholeSeconds + ? secondsFixed + : secondsFixed.replace(/\.0+$/, ''); + add(Number.parseFloat(secondsString), 'second', 's', secondsString); + } + } + + if (result.length === 0) { + return sign + '0' + (options.verbose ? ' milliseconds' : 'ms'); + } + + const separator = options.colonNotation ? ':' : ' '; + if (typeof options.unitCount === 'number') { + result = result.slice(0, Math.max(options.unitCount, 1)); + } + + return sign + result.join(separator); +} diff --git a/node_modules/execa/node_modules/pretty-ms/license b/node_modules/execa/node_modules/pretty-ms/license new file mode 100644 index 0000000000..fa7ceba3eb --- /dev/null +++ b/node_modules/execa/node_modules/pretty-ms/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/execa/node_modules/pretty-ms/package.json b/node_modules/execa/node_modules/pretty-ms/package.json new file mode 100644 index 0000000000..c88c93dcd0 --- /dev/null +++ b/node_modules/execa/node_modules/pretty-ms/package.json @@ -0,0 +1,55 @@ +{ + "name": "pretty-ms", + "version": "9.2.0", + "description": "Convert milliseconds to a human readable string: `1337000000` → `15d 11h 23m 20s`", + "license": "MIT", + "repository": "sindresorhus/pretty-ms", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "pretty", + "prettify", + "human", + "humanize", + "humanized", + "readable", + "time", + "ms", + "milliseconds", + "duration", + "period", + "range", + "text", + "string", + "number", + "hrtime" + ], + "dependencies": { + "parse-ms": "^4.0.0" + }, + "devDependencies": { + "ava": "^6.2.0", + "tsd": "^0.31.2", + "xo": "^0.59.3" + } +} diff --git a/node_modules/execa/node_modules/pretty-ms/readme.md b/node_modules/execa/node_modules/pretty-ms/readme.md new file mode 100644 index 0000000000..b80ed9e716 --- /dev/null +++ b/node_modules/execa/node_modules/pretty-ms/readme.md @@ -0,0 +1,166 @@ +# pretty-ms + +> Convert milliseconds to a human readable string: `1337000000` → `15d 11h 23m 20s` + +## Install + +```sh +npm install pretty-ms +``` + +## Usage + +```js +import prettyMilliseconds from 'pretty-ms'; + +prettyMilliseconds(1337000000); +//=> '15d 11h 23m 20s' + +prettyMilliseconds(1337000000n); +//=> '15d 11h 23m 20s' + +prettyMilliseconds(1337); +//=> '1.3s' + +prettyMilliseconds(133); +//=> '133ms' + +// `compact` option +prettyMilliseconds(1337, {compact: true}); +//=> '1s' + +// `verbose` option +prettyMilliseconds(1335669000, {verbose: true}); +//=> '15 days 11 hours 1 minute 9 seconds' + +// `colonNotation` option +prettyMilliseconds(95500, {colonNotation: true}); +//=> '1:35.5' + +// `formatSubMilliseconds` option +prettyMilliseconds(100.400080, {formatSubMilliseconds: true}) +//=> '100ms 400µs 80ns' + +// Can be useful for time durations +prettyMilliseconds(new Date(2014, 0, 1, 10, 40) - new Date(2014, 0, 1, 10, 5)) +//=> '35m' +``` + +## API + +### prettyMilliseconds(milliseconds, options?) + +#### milliseconds + +Type: `number | bigint` + +Milliseconds to humanize. + +#### options + +Type: `object` + +##### secondsDecimalDigits + +Type: `number`\ +Default: `1` + +Number of digits to appear after the seconds decimal point. + +##### millisecondsDecimalDigits + +Type: `number`\ +Default: `0` + +Number of digits to appear after the milliseconds decimal point. + +Useful in combination with [`process.hrtime()`](https://nodejs.org/api/process.html#process_process_hrtime_time). + +##### keepDecimalsOnWholeSeconds + +Type: `boolean`\ +Default: `false` + +Keep milliseconds on whole seconds: `13s` → `13.0s`. + +Useful when you are showing a number of seconds spent on an operation and don't want the width of the output to change when hitting a whole number. + +##### compact + +Type: `boolean`\ +Default: `false` + +Only show the first unit: `1h 10m` → `1h`. + +Also ensures that `millisecondsDecimalDigits` and `secondsDecimalDigits` are both set to `0`. + +##### unitCount + +Type: `number`\ +Default: `Infinity` + +Number of units to show. Setting `compact` to `true` overrides this option. + +##### verbose + +Type: `boolean`\ +Default: `false` + +Use full-length units: `5h 1m 45s` → `5 hours 1 minute 45 seconds` + +##### separateMilliseconds + +Type: `boolean`\ +Default: `false` + +Show milliseconds separately. This means they won't be included in the decimal part of the seconds. + +##### formatSubMilliseconds + +Type: `boolean`\ +Default: `false` + +Show microseconds and nanoseconds. + +##### colonNotation + +Type: `boolean`\ +Default: `false` + +Display time using colon notation: `5h 1m 45s` → `5:01:45`. Always shows time in at least minutes: `1s` → `0:01` + +Useful when you want to display time without the time units, similar to a digital watch. + +Setting `colonNotation` to `true` overrides the following options to `false`: +- `compact` +- `formatSubMilliseconds` +- `separateMilliseconds` +- `verbose` + +##### hideYear + +Type: `boolean`\ +Default: `false` + +Hides the year and shows the hidden year additionally as days (365 per year): `1y 3d 5h 1m 45s` → `368d 5h 1m 45s`. + +##### hideYearAndDays + +Type: `boolean`\ +Default: `false` + +Hides the year and days and shows the hidden values additionally as hours: `1y 3d 5h 1m 45s` → `8837h 1m 45s`. + +##### hideSeconds + +Type: `boolean`\ +Default: `false` + +Hides the seconds: `1y 3d 5h 1m 45s` → `1y 3d 5h 1m`. + +## Related + +- [pretty-ms-cli](https://github.com/sindresorhus/pretty-ms-cli) - CLI for this module +- [parse-ms](https://github.com/sindresorhus/parse-ms) - Parse milliseconds into an object +- [to-milliseconds](https://github.com/sindresorhus/to-milliseconds) - Convert an object of time properties to milliseconds +- [pretty-bytes](https://github.com/sindresorhus/pretty-bytes) - Convert bytes to a human readable string diff --git a/node_modules/execa/package.json b/node_modules/execa/package.json index 035400a472..fa8a0109dd 100644 --- a/node_modules/execa/package.json +++ b/node_modules/execa/package.json @@ -1,6 +1,6 @@ { "name": "execa", - "version": "7.1.1", + "version": "9.6.0", "description": "Process execution for humans", "license": "MIT", "repository": "sindresorhus/execa", @@ -11,22 +11,31 @@ "url": "https://sindresorhus.com" }, "type": "module", - "exports": "./index.js", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + "node": "^18.19.0 || >=20.5.0" }, "scripts": { - "test": "xo && c8 ava && tsd" + "test": "npm run lint && npm run unit && npm run type", + "lint": "xo", + "unit": "c8 --merge-async ava", + "type": "tsd && tsc && npx --yes tsd@0.29.0 && npx --yes --package typescript@5.1 tsc" }, "files": [ "index.js", "index.d.ts", - "lib" + "lib/**/*.js", + "types/**/*.ts" ], "keywords": [ "exec", "child", "process", + "subprocess", "execute", "fork", "execfile", @@ -38,30 +47,38 @@ "binaries", "npm", "path", - "local" + "local", + "zx" ], "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" }, "devDependencies": { - "@types/node": "^18.13.0", - "ava": "^5.2.0", - "c8": "^7.12.0", - "get-node": "^13.5.0", + "@types/node": "^22.15.21", + "ava": "^6.3.0", + "c8": "^10.1.3", + "get-node": "^15.0.3", + "is-in-ci": "^1.0.0", "is-running": "^2.1.0", - "p-event": "^5.0.1", + "log-process-errors": "^12.0.1", + "path-exists": "^5.0.0", "path-key": "^4.0.0", - "tempfile": "^4.0.0", - "tsd": "^0.25.0", - "xo": "^0.53.1" + "tempfile": "^5.0.0", + "tsd": "^0.32.0", + "typescript": "^5.8.3", + "which": "^5.0.0", + "xo": "^0.60.0" }, "c8": { "reporter": [ @@ -75,7 +92,9 @@ ] }, "ava": { - "workerThreads": false + "workerThreads": false, + "concurrency": 1, + "timeout": "240s" }, "xo": { "rules": { diff --git a/node_modules/execa/readme.md b/node_modules/execa/readme.md index 6b1f43eb7d..4bf527a53c 100644 --- a/node_modules/execa/readme.md +++ b/node_modules/execa/readme.md @@ -8,23 +8,53 @@ > Process execution for humans -## Why - -This package improves [`child_process`](https://nodejs.org/api/child_process.html) methods with: - -- [Promise interface](#execacommandcommand-options). -- [Scripts interface](#scripts-interface), like `zx`. -- Improved [Windows support](https://github.com/IndigoUnited/node-cross-spawn#why), including [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) binaries. -- Executes [locally installed binaries](#preferlocal) without `npx`. -- [Cleans up](#cleanup) child processes when the parent process ends. -- [Graceful termination](#optionsforcekillaftertimeout). -- Get [interleaved output](#all) from `stdout` and `stderr` similar to what is printed on the terminal. -- [Strips the final newline](#stripfinalnewline) from the output so you don't have to do `stdout.trim()`. -- Convenience methods to pipe processes' [input](#input) and [output](#redirect-output-to-a-file). -- Can specify file and arguments [as a single string](#execacommandcommand-options) without a shell. -- [Verbose mode](#verbose-mode) for debugging. -- More descriptive errors. -- Higher max buffer: 100 MB instead of 1 MB. +
+ +--- + +
+

+

+ + Sindre's open source work is supported by the community + +

+ Special thanks to: +
+
+ + CodeRabbit logo + +
+
+

+
+ +--- + +
+ +Execa runs commands in your script, application or library. Unlike shells, it is [optimized](docs/bash.md) for programmatic usage. Built on top of the [`child_process`](https://nodejs.org/api/child_process.html) core module. + +## Features + +- [Simple syntax](#simple-syntax): promises and [template strings](docs/execution.md#template-string-syntax), like [`zx`](docs/bash.md). +- [Script](#script) interface. +- [No escaping](docs/escaping.md) nor quoting needed. No risk of shell injection. +- Execute [locally installed binaries](#local-binaries) without `npx`. +- Improved [Windows support](docs/windows.md): [shebangs](docs/windows.md#shebang), [`PATHEXT`](https://ss64.com/nt/path.html#pathext), [graceful termination](#graceful-termination), [and more](https://github.com/moxystudio/node-cross-spawn?tab=readme-ov-file#why). +- [Detailed errors](#detailed-error), [verbose mode](#verbose-mode) and [custom logging](#custom-logging), for [debugging](docs/debugging.md). +- [Pipe multiple subprocesses](#pipe-multiple-subprocesses) better than in shells: retrieve [intermediate results](docs/pipe.md#result), use multiple [sources](docs/pipe.md#multiple-sources-1-destination)/[destinations](docs/pipe.md#1-source-multiple-destinations), [unpipe](docs/pipe.md#unpipe). +- [Split](#split-into-text-lines) the output into text lines, or [iterate](#iterate-over-text-lines) progressively over them. +- Strip [unnecessary newlines](docs/lines.md#newlines). +- Pass any [input](docs/input.md) to the subprocess: [files](#file-input), [strings](#simple-input), [`Uint8Array`s](docs/binary.md#binary-input), [iterables](docs/streams.md#iterables-as-input), [objects](docs/transform.md#object-mode) and almost any [other type](#any-input-type). +- Return [almost any type](#any-output-type) from the subprocess, or redirect it to [files](#file-output). +- Get [interleaved output](#interleaved-output) from `stdout` and `stderr` similar to what is printed on the terminal. +- Retrieve the output [programmatically and print it](#programmatic--terminal-output) on the console at the same time. +- [Transform or filter](#transformfilter-output) the input and output with [simple functions](docs/transform.md). +- Pass [Node.js streams](docs/streams.md#nodejs-streams) or [web streams](#web-streams) to subprocesses, or [convert](#convert-to-duplex-stream) subprocesses to [a stream](docs/streams.md#converting-a-subprocess-to-a-stream). +- [Exchange messages](#exchange-messages) with the subprocess. +- Ensure subprocesses exit even when they [intercept termination signals](docs/termination.md#forceful-termination), or when the current process [ends abruptly](docs/termination.md#current-process-exit). ## Install @@ -32,755 +62,375 @@ This package improves [`child_process`](https://nodejs.org/api/child_process.htm npm install execa ``` -## Usage - -### Promise interface +## Documentation + +Execution: +- ▶️ [Basic execution](docs/execution.md) +- 💬 [Escaping/quoting](docs/escaping.md) +- 💻 [Shell](docs/shell.md) +- 📜 [Scripts](docs/scripts.md) +- 🐢 [Node.js files](docs/node.md) +- 🌐 [Environment](docs/environment.md) +- ❌ [Errors](docs/errors.md) +- 🏁 [Termination](docs/termination.md) + +Input/output: +- 🎹 [Input](docs/input.md) +- 📢 [Output](docs/output.md) +- 📃 [Text lines](docs/lines.md) +- 🤖 [Binary data](docs/binary.md) +- 🧙 [Transforms](docs/transform.md) + +Advanced usage: +- 🔀 [Piping multiple subprocesses](docs/pipe.md) +- ⏳️ [Streams](docs/streams.md) +- 📞 [Inter-process communication](docs/ipc.md) +- 🐛 [Debugging](docs/debugging.md) +- 📎 [Windows](docs/windows.md) +- 🔍 [Difference with Bash and zx](docs/bash.md) +- 🐭 [Small packages](docs/small.md) +- 🤓 [TypeScript](docs/typescript.md) +- 📔 [API reference](docs/api.md) + +## Examples + +### Execution + +#### Simple syntax ```js import {execa} from 'execa'; -const {stdout} = await execa('echo', ['unicorns']); +const {stdout} = await execa`npm run build`; +// Print command's output console.log(stdout); -//=> 'unicorns' ``` -### Scripts interface - -For more information about Execa scripts, please see [this page](docs/scripts.md). - -#### Basic +#### Script ```js import {$} from 'execa'; +const {stdout: name} = await $`cat package.json`.pipe`grep name`; +console.log(name); + const branch = await $`git branch --show-current`; await $`dep deploy --branch=${branch}`; -``` -#### Multiple arguments +await Promise.all([ + $`sleep 1`, + $`sleep 2`, + $`sleep 3`, +]); -```js -import {$} from 'execa'; - -const args = ['unicorns', '&', 'rainbows!']; -const {stdout} = await $`echo ${args}`; -console.log(stdout); -//=> 'unicorns & rainbows!' +const directoryName = 'foo bar'; +await $`mkdir /tmp/${directoryName}`; ``` -#### With options +#### Local binaries -```js -import {$} from 'execa'; - -await $({stdio: 'inherit'})`echo unicorns`; -//=> 'unicorns' +```sh +$ npm install -D eslint ``` -#### Shared options - ```js -import {$} from 'execa'; - -const $$ = $({stdio: 'inherit'}); - -await $$`echo unicorns`; -//=> 'unicorns' - -await $$`echo rainbows`; -//=> 'rainbows' +await execa({preferLocal: true})`eslint`; ``` -#### Verbose mode +#### Pipe multiple subprocesses -```sh -> node file.js -unicorns -rainbows - -> NODE_DEBUG=execa node file.js -[16:50:03.305] echo unicorns -unicorns -[16:50:03.308] echo rainbows -rainbows +```js +const {stdout, pipedFrom} = await execa`npm run build` + .pipe`sort` + .pipe`head -n 2`; + +// Output of `npm run build | sort | head -n 2` +console.log(stdout); +// Output of `npm run build | sort` +console.log(pipedFrom[0].stdout); +// Output of `npm run build` +console.log(pipedFrom[0].pipedFrom[0].stdout); ``` ### Input/output -#### Redirect output to a file +#### Interleaved output ```js -import {execa} from 'execa'; - -// Similar to `echo unicorns > stdout.txt` in Bash -await execa('echo', ['unicorns']).pipeStdout('stdout.txt'); - -// Similar to `echo unicorns 2> stdout.txt` in Bash -await execa('echo', ['unicorns']).pipeStderr('stderr.txt'); - -// Similar to `echo unicorns &> stdout.txt` in Bash -await execa('echo', ['unicorns'], {all: true}).pipeAll('all.txt'); +const {all} = await execa({all: true})`npm run build`; +// stdout + stderr, interleaved +console.log(all); ``` -#### Redirect input from a file +#### Programmatic + terminal output ```js -import {execa} from 'execa'; - -// Similar to `cat < stdin.txt` in Bash -const {stdout} = await execa('cat', {inputFile: 'stdin.txt'}); +const {stdout} = await execa({stdout: ['pipe', 'inherit']})`npm run build`; +// stdout is also printed to the terminal console.log(stdout); -//=> 'unicorns' ``` -#### Save and pipe output from a child process +#### Simple input ```js -import {execa} from 'execa'; - -const {stdout} = await execa('echo', ['unicorns']).pipeStdout(process.stdout); -// Prints `unicorns` +const getInputString = () => { /* ... */ }; +const {stdout} = await execa({input: getInputString()})`sort`; console.log(stdout); -// Also returns 'unicorns' ``` -#### Pipe multiple processes +#### File input ```js -import {execa} from 'execa'; - -// Similar to `echo unicorns | cat` in Bash -const {stdout} = await execa('echo', ['unicorns']).pipeStdout(execa('cat')); -console.log(stdout); -//=> 'unicorns' +// Similar to: npm run build < input.txt +await execa({stdin: {file: 'input.txt'}})`npm run build`; ``` -### Handling Errors +#### File output ```js -import {execa} from 'execa'; - -// Catching an error -try { - await execa('unknown', ['command']); -} catch (error) { - console.log(error); - /* - { - message: 'Command failed with ENOENT: unknown command spawn unknown ENOENT', - errno: -2, - code: 'ENOENT', - syscall: 'spawn unknown', - path: 'unknown', - spawnargs: ['command'], - originalMessage: 'spawn unknown ENOENT', - shortMessage: 'Command failed with ENOENT: unknown command spawn unknown ENOENT', - command: 'unknown command', - escapedCommand: 'unknown command', - stdout: '', - stderr: '', - failed: true, - timedOut: false, - isCanceled: false, - killed: false - } - */ -} +// Similar to: npm run build > output.txt +await execa({stdout: {file: 'output.txt'}})`npm run build`; ``` -### Graceful termination - -Using SIGTERM, and after 2 seconds, kill it with SIGKILL. +#### Split into text lines ```js -const subprocess = execa('node'); - -setTimeout(() => { - subprocess.kill('SIGTERM', { - forceKillAfterTimeout: 2000 - }); -}, 1000); +const {stdout} = await execa({lines: true})`npm run build`; +// Print first 10 lines +console.log(stdout.slice(0, 10).join('\n')); ``` -## API - -### Methods - -#### execa(file, arguments?, options?) - -Executes a command using `file ...arguments`. `arguments` are specified as an array of strings. Returns a [`childProcess`](#childprocess). - -Arguments are [automatically escaped](#shell-syntax). They can contain any character, including spaces. - -This is the preferred method when executing single commands. - -#### execaNode(scriptPath, arguments?, options?) - -Executes a Node.js file using `node scriptPath ...arguments`. `arguments` are specified as an array of strings. Returns a [`childProcess`](#childprocess). - -Arguments are [automatically escaped](#shell-syntax). They can contain any character, including spaces. - -This is the preferred method when executing Node.js files. - -Like [`child_process#fork()`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options): - - the current Node version and options are used. This can be overridden using the [`nodePath`](#nodepath-for-node-only) and [`nodeOptions`](#nodeoptions-for-node-only) options. - - the [`shell`](#shell) option cannot be used - - an extra channel [`ipc`](https://nodejs.org/api/child_process.html#child_process_options_stdio) is passed to [`stdio`](#stdio) - -#### $\`command\` - -Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a [`childProcess`](#childprocess). - -Arguments are [automatically escaped](#shell-syntax). They can contain any character, but spaces must use `${}` like `` $`echo ${'has space'}` ``. - -This is the preferred method when executing multiple commands in a script file. - -The `command` string can inject any `${value}` with the following types: string, number, [`childProcess`](#childprocess) or an array of those types. For example: `` $`echo one ${'two'} ${3} ${['four', 'five']}` ``. For `${childProcess}`, the process's `stdout` is used. - -For more information, please see [this section](#scripts-interface) and [this page](docs/scripts.md). - -#### $(options) - -Returns a new instance of [`$`](#command) but with different default `options`. Consecutive calls are merged to previous ones. - -This can be used to either: - - Set options for a specific command: `` $(options)`command` `` - - Share options for multiple commands: `` const $$ = $(options); $$`command`; $$`otherCommand`; `` - -#### execaCommand(command, options?) - -Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a [`childProcess`](#childprocess). - -Arguments are [automatically escaped](#shell-syntax). They can contain any character, but spaces must be escaped with a backslash like `execaCommand('echo has\\ space')`. - -This is the preferred method when executing a user-supplied `command` string, such as in a REPL. - -### execaSync(file, arguments?, options?) - -Same as [`execa()`](#execacommandcommand-options) but synchronous. - -Returns or throws a [`childProcessResult`](#childProcessResult). - -### $.sync\`command\` - -Same as [$\`command\`](#command) but synchronous. - -Returns or throws a [`childProcessResult`](#childProcessResult). - -### execaCommandSync(command, options?) - -Same as [`execaCommand()`](#execacommand-command-options) but synchronous. - -Returns or throws a [`childProcessResult`](#childProcessResult). - -### Shell syntax - -For all the [methods above](#methods), no shell interpreter (Bash, cmd.exe, etc.) is used unless the [`shell` option](#shell) is set. This means shell-specific characters and expressions (`$variable`, `&&`, `||`, `;`, `|`, etc.) have no special meaning and do not need to be escaped. - -### childProcess - -The return value of all [asynchronous methods](#methods) is both: - - a `Promise` resolving or rejecting with a [`childProcessResult`](#childProcessResult). - - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with the following additional methods and properties. - -#### kill(signal?, options?) - -Same as the original [`child_process#kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal) except: if `signal` is `SIGTERM` (the default value) and the child process is not terminated after 5 seconds, force it by sending `SIGKILL`. - -##### options.forceKillAfterTimeout - -Type: `number | false`\ -Default: `5000` - -Milliseconds to wait for the child process to terminate before sending `SIGKILL`. - -Can be disabled with `false`. - -#### all - -Type: `ReadableStream | undefined` - -Stream combining/interleaving [`stdout`](https://nodejs.org/api/child_process.html#child_process_subprocess_stdout) and [`stderr`](https://nodejs.org/api/child_process.html#child_process_subprocess_stderr). - -This is `undefined` if either: - - the [`all` option](#all-2) is `false` (the default value) - - both [`stdout`](#stdout-1) and [`stderr`](#stderr-1) options are set to [`'inherit'`, `'ipc'`, `Stream` or `integer`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio) - -#### pipeStdout(target) - -[Pipe](https://nodejs.org/api/stream.html#readablepipedestination-options) the child process's `stdout` to `target`, which can be: - - Another [`execa()` return value](#pipe-multiple-processes) - - A [writable stream](#save-and-pipe-output-from-a-child-process) - - A [file path string](#redirect-output-to-a-file) - -If the `target` is another [`execa()` return value](#execacommandcommand-options), it is returned. Otherwise, the original `execa()` return value is returned. This allows chaining `pipeStdout()` then `await`ing the [final result](#childprocessresult). - -The [`stdout` option](#stdout-1) must be kept as `pipe`, its default value. - -#### pipeStderr(target) - -Like [`pipeStdout()`](#pipestdouttarget) but piping the child process's `stderr` instead. - -The [`stderr` option](#stderr-1) must be kept as `pipe`, its default value. - -#### pipeAll(target) - -Combines both [`pipeStdout()`](#pipestdouttarget) and [`pipeStderr()`](#pipestderrtarget). - -Either the [`stdout` option](#stdout-1) or the [`stderr` option](#stderr-1) must be kept as `pipe`, their default value. Also, the [`all` option](#all-2) must be set to `true`. - -### childProcessResult - -Type: `object` - -Result of a child process execution. On success this is a plain object. On failure this is also an `Error` instance. - -The child process [fails](#failed) when: -- its [exit code](#exitcode) is not `0` -- it was [killed](#killed) with a [signal](#signal) -- [timing out](#timedout) -- [being canceled](#iscanceled) -- there's not enough memory or there are already too many child processes - -#### command - -Type: `string` - -The file and arguments that were run, for logging purposes. - -This is not escaped and should not be executed directly as a process, including using [`execa()`](#execafile-arguments-options) or [`execaCommand()`](#execacommandcommand-options). - -#### escapedCommand - -Type: `string` - -Same as [`command`](#command-1) but escaped. - -This is meant to be copy and pasted into a shell, for debugging purposes. -Since the escaping is fairly basic, this should not be executed directly as a process, including using [`execa()`](#execafile-arguments-options) or [`execaCommand()`](#execacommandcommand-options). - -#### exitCode - -Type: `number` - -The numeric exit code of the process that was run. - -#### stdout - -Type: `string | Buffer` - -The output of the process on stdout. - -#### stderr - -Type: `string | Buffer` - -The output of the process on stderr. - -#### all - -Type: `string | Buffer | undefined` - -The output of the process with `stdout` and `stderr` interleaved. - -This is `undefined` if either: - - the [`all` option](#all-2) is `false` (the default value) - - `execaSync()` was used - -#### failed - -Type: `boolean` - -Whether the process failed to run. - -#### timedOut - -Type: `boolean` - -Whether the process timed out. - -#### isCanceled - -Type: `boolean` - -Whether the process was canceled. - -You can cancel the spawned process using the [`signal`](#signal-1) option. - -#### killed - -Type: `boolean` - -Whether the process was killed. - -#### signal - -Type: `string | undefined` - -The name of the signal that was used to terminate the process. For example, `SIGFPE`. - -If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`. - -#### signalDescription +### Streaming -Type: `string | undefined` +#### Iterate over text lines -A human-friendly description of the signal that was used to terminate the process. For example, `Floating point arithmetic error`. - -If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`. It is also `undefined` when the signal is very uncommon which should seldomly happen. - -#### message - -Type: `string` - -Error message when the child process failed to run. In addition to the [underlying error message](#originalMessage), it also contains some information related to why the child process errored. - -The child process [stderr](#stderr) then [stdout](#stdout) are appended to the end, separated with newlines and not interleaved. - -#### shortMessage - -Type: `string` - -This is the same as the [`message` property](#message) except it does not include the child process stdout/stderr. - -#### originalMessage - -Type: `string | undefined` - -Original error message. This is the same as the `message` property except it includes neither the child process stdout/stderr nor some additional information added by Execa. - -This is `undefined` unless the child process exited due to an `error` event or a timeout. - -### options - -Type: `object` - -#### cleanup - -Type: `boolean`\ -Default: `true` - -Kill the spawned process when the parent process exits unless either: - - the spawned process is [`detached`](https://nodejs.org/api/child_process.html#child_process_options_detached) - - the parent process is terminated abruptly, for example, with `SIGKILL` as opposed to `SIGTERM` or a normal exit - -#### preferLocal - -Type: `boolean`\ -Default: `true` with [`$`](#command), `false` otherwise - -Prefer locally installed binaries when looking for a binary to execute.\ -If you `$ npm install foo`, you can then `execa('foo')`. - -#### localDir - -Type: `string | URL`\ -Default: `process.cwd()` - -Preferred path to find locally installed binaries in (use with `preferLocal`). - -#### execPath - -Type: `string`\ -Default: `process.execPath` (Current Node.js executable) - -Path to the Node.js executable to use in child processes. - -This can be either an absolute path or a path relative to the [`cwd` option](#cwd). - -Requires [`preferLocal`](#preferlocal) to be `true`. - -For example, this can be used together with [`get-node`](https://github.com/ehmicky/get-node) to run a specific Node.js version in a child process. - -#### buffer - -Type: `boolean`\ -Default: `true` - -Buffer the output from the spawned process. When set to `false`, you must read the output of [`stdout`](#stdout-1) and [`stderr`](#stderr-1) (or [`all`](#all) if the [`all`](#all-2) option is `true`). Otherwise the returned promise will not be resolved/rejected. - -If the spawned process fails, [`error.stdout`](#stdout), [`error.stderr`](#stderr), and [`error.all`](#all) will contain the buffered data. - -#### input - -Type: `string | Buffer | stream.Readable` - -Write some input to the `stdin` of your binary.\ -Streams are not allowed when using the synchronous methods. - -If the input is a file, use the [`inputFile` option](#inputfile) instead. - -#### inputFile - -Type: `string` - -Use a file as input to the the `stdin` of your binary. - -If the input is not a file, use the [`input` option](#input) instead. - -#### stdin - -Type: `string | number | Stream | undefined`\ -Default: `inherit` with [`$`](#command), `pipe` otherwise - -Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). - -#### stdout - -Type: `string | number | Stream | undefined`\ -Default: `pipe` - -Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). - -#### stderr - -Type: `string | number | Stream | undefined`\ -Default: `pipe` - -Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). - -#### all - -Type: `boolean`\ -Default: `false` - -Add an `.all` property on the [promise](#all) and the [resolved value](#all-1). The property contains the output of the process with `stdout` and `stderr` interleaved. - -#### reject - -Type: `boolean`\ -Default: `true` - -Setting this to `false` resolves the promise with the error instead of rejecting it. - -#### stripFinalNewline - -Type: `boolean`\ -Default: `true` - -Strip the final [newline character](https://en.wikipedia.org/wiki/Newline) from the output. - -#### extendEnv - -Type: `boolean`\ -Default: `true` - -Set to `false` if you don't want to extend the environment variables when providing the `env` property. - ---- - -Execa also accepts the below options which are the same as the options for [`child_process#spawn()`](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options)/[`child_process#exec()`](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) - -#### cwd - -Type: `string | URL`\ -Default: `process.cwd()` - -Current working directory of the child process. - -#### env - -Type: `object`\ -Default: `process.env` - -Environment key-value pairs. Extends automatically from `process.env`. Set [`extendEnv`](#extendenv) to `false` if you don't want this. - -#### argv0 - -Type: `string` - -Explicitly set the value of `argv[0]` sent to the child process. This will be set to `file` if not specified. - -#### stdio - -Type: `string | string[]`\ -Default: `pipe` - -Child's [stdio](https://nodejs.org/api/child_process.html#child_process_options_stdio) configuration. - -#### serialization - -Type: `string`\ -Default: `'json'` - -Specify the kind of serialization used for sending messages between processes when using the [`stdio: 'ipc'`](#stdio) option or [`execaNode()`](#execanodescriptpath-arguments-options): - - `json`: Uses `JSON.stringify()` and `JSON.parse()`. - - `advanced`: Uses [`v8.serialize()`](https://nodejs.org/api/v8.html#v8_v8_serialize_value) - -[More info.](https://nodejs.org/api/child_process.html#child_process_advanced_serialization) - -#### detached - -Type: `boolean` - -Prepare child to run independently of its parent process. Specific behavior [depends on the platform](https://nodejs.org/api/child_process.html#child_process_options_detached). - -#### uid - -Type: `number` - -Sets the user identity of the process. - -#### gid - -Type: `number` - -Sets the group identity of the process. - -#### shell - -Type: `boolean | string`\ -Default: `false` - -If `true`, runs `file` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows. A different shell can be specified as a string. The shell should understand the `-c` switch on UNIX or `/d /s /c` on Windows. - -We recommend against using this option since it is: -- not cross-platform, encouraging shell-specific syntax. -- slower, because of the additional shell interpretation. -- unsafe, potentially allowing command injection. - -#### encoding - -Type: `string | null`\ -Default: `utf8` - -Specify the character encoding used to decode the `stdout` and `stderr` output. If set to `null`, then `stdout` and `stderr` will be a `Buffer` instead of a string. - -#### timeout - -Type: `number`\ -Default: `0` - -If timeout is greater than `0`, the parent will send the signal identified by the `killSignal` property (the default is `SIGTERM`) if the child runs longer than timeout milliseconds. - -#### maxBuffer - -Type: `number`\ -Default: `100_000_000` (100 MB) +```js +for await (const line of execa`npm run build`) { + if (line.includes('WARN')) { + console.warn(line); + } +} +``` -Largest amount of data in bytes allowed on `stdout` or `stderr`. +#### Transform/filter output -#### killSignal +```js +let count = 0; -Type: `string | number`\ -Default: `SIGTERM` +// Filter out secret lines, then prepend the line number +const transform = function * (line) { + if (!line.includes('secret')) { + yield `[${count++}] ${line}`; + } +}; -Signal value to be used when the spawned process will be killed. +await execa({stdout: transform})`npm run build`; +``` -#### signal +#### Web streams -Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) +```js +const response = await fetch('https://example.com'); +await execa({stdin: response.body})`sort`; +``` -You can abort the spawned process using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). +#### Convert to Duplex stream -When `AbortController.abort()` is called, [`.isCanceled`](#iscanceled) becomes `false`. +```js +import {execa} from 'execa'; +import {pipeline} from 'node:stream/promises'; +import {createReadStream, createWriteStream} from 'node:fs'; + +await pipeline( + createReadStream('./input.txt'), + execa`node ./transform.js`.duplex(), + createWriteStream('./output.txt'), +); +``` -*Requires Node.js 16 or later.* +### IPC -#### windowsVerbatimArguments +#### Exchange messages -Type: `boolean`\ -Default: `false` +```js +// parent.js +import {execaNode} from 'execa'; -If `true`, no quoting or escaping of arguments is done on Windows. Ignored on other platforms. This is set to `true` automatically when the `shell` option is `true`. +const subprocess = execaNode`child.js`; +await subprocess.sendMessage('Hello from parent'); +const message = await subprocess.getOneMessage(); +console.log(message); // 'Hello from child' +``` -#### windowsHide +```js +// child.js +import {getOneMessage, sendMessage} from 'execa'; -Type: `boolean`\ -Default: `true` +const message = await getOneMessage(); // 'Hello from parent' +const newMessage = message.replace('parent', 'child'); // 'Hello from child' +await sendMessage(newMessage); +``` -On Windows, do not create a new console window. Please note this also prevents `CTRL-C` [from working](https://github.com/nodejs/node/issues/29837) on Windows. +#### Any input type -#### verbose +```js +// main.js +import {execaNode} from 'execa'; + +const ipcInput = [ + {task: 'lint', ignore: /test\.js/}, + {task: 'copy', files: new Set(['main.js', 'index.js']), +}]; +await execaNode({ipcInput})`build.js`; +``` -Type: `boolean`\ -Default: `false` +```js +// build.js +import {getOneMessage} from 'execa'; -[Print each command](#verbose-mode) on `stderr` before executing it. +const ipcInput = await getOneMessage(); +``` -This can also be enabled by setting the `NODE_DEBUG=execa` environment variable in the current process. +#### Any output type -#### nodePath *(For `.node()` only)* +```js +// main.js +import {execaNode} from 'execa'; -Type: `string`\ -Default: [`process.execPath`](https://nodejs.org/api/process.html#process_process_execpath) +const {ipcOutput} = await execaNode`build.js`; +console.log(ipcOutput[0]); // {kind: 'start', timestamp: date} +console.log(ipcOutput[1]); // {kind: 'stop', timestamp: date} +``` -Node.js executable used to create the child process. +```js +// build.js +import {sendMessage} from 'execa'; -#### nodeOptions *(For `.node()` only)* +const runBuild = () => { /* ... */ }; -Type: `string[]`\ -Default: [`process.execArgv`](https://nodejs.org/api/process.html#process_process_execargv) +await sendMessage({kind: 'start', timestamp: new Date()}); +await runBuild(); +await sendMessage({kind: 'stop', timestamp: new Date()}); +``` -List of [CLI options](https://nodejs.org/api/cli.html#cli_options) passed to the Node.js executable. +#### Graceful termination -## Tips +```js +// main.js +import {execaNode} from 'execa'; -### Retry on error +const controller = new AbortController(); +setTimeout(() => { + controller.abort(); +}, 5000); -Gracefully handle failures by using automatic retries and exponential backoff with the [`p-retry`](https://github.com/sindresorhus/p-retry) package: +await execaNode({ + cancelSignal: controller.signal, + gracefulCancel: true, +})`build.js`; +``` ```js -import pRetry from 'p-retry'; - -const run = async () => { - const results = await execa('curl', ['-sSL', 'https://sindresorhus.com/unicorn']); - return results; -}; +// build.js +import {getCancelSignal} from 'execa'; -console.log(await pRetry(run, {retries: 5})); +const cancelSignal = await getCancelSignal(); +const url = 'https://example.com/build/info'; +const response = await fetch(url, {signal: cancelSignal}); ``` -### Cancelling a spawned process +### Debugging -```js -import {execa} from 'execa'; +#### Detailed error -const abortController = new AbortController(); -const subprocess = execa('node', [], {signal: abortController.signal}); - -setTimeout(() => { - abortController.abort(); -}, 1000); +```js +import {execa, ExecaError} from 'execa'; try { - await subprocess; + await execa`unknown command`; } catch (error) { - console.log(subprocess.killed); // true - console.log(error.isCanceled); // true + if (error instanceof ExecaError) { + console.log(error); + } + /* + ExecaError: Command failed with ENOENT: unknown command + spawn unknown ENOENT + at ... + at ... { + shortMessage: 'Command failed with ENOENT: unknown command\nspawn unknown ENOENT', + originalMessage: 'spawn unknown ENOENT', + command: 'unknown command', + escapedCommand: 'unknown command', + cwd: '/path/to/cwd', + durationMs: 28.217566, + failed: true, + timedOut: false, + isCanceled: false, + isTerminated: false, + isMaxBuffer: false, + code: 'ENOENT', + stdout: '', + stderr: '', + stdio: [undefined, '', ''], + pipedFrom: [] + [cause]: Error: spawn unknown ENOENT + at ... + at ... { + errno: -2, + code: 'ENOENT', + syscall: 'spawn unknown', + path: 'unknown', + spawnargs: [ 'command' ] + } + } + */ } ``` -### Execute the current package's binary +#### Verbose mode ```js -import {getBinPath} from 'get-bin-path'; - -const binPath = await getBinPath(); -await execa(binPath); +await execa`npm run build`; +await execa`npm run test`; ``` -`execa` can be combined with [`get-bin-path`](https://github.com/ehmicky/get-bin-path) to test the current package's binary. As opposed to hard-coding the path to the binary, this validates that the `package.json` `bin` field is correctly set up. +execa verbose output + +#### Custom logging + +```js +import {execa as execa_} from 'execa'; +import {createLogger, transports} from 'winston'; + +// Log to a file using Winston +const transport = new transports.File({filename: 'logs.txt'}); +const logger = createLogger({transports: [transport]}); +const LOG_LEVELS = { + command: 'info', + output: 'verbose', + ipc: 'verbose', + error: 'error', + duration: 'info', +}; + +const execa = execa_({ + verbose(verboseLine, {message, ...verboseObject}) { + const level = LOG_LEVELS[verboseObject.type]; + logger[level](message, verboseObject); + }, +}); + +await execa`npm run build`; +await execa`npm run test`; +``` ## Related -- [gulp-execa](https://github.com/ehmicky/gulp-execa) - Gulp plugin for `execa` -- [nvexeca](https://github.com/ehmicky/nvexeca) - Run `execa` using any Node.js version -- [sudo-prompt](https://github.com/jorangreef/sudo-prompt) - Run commands with elevated privileges. +- [nano-spawn](https://github.com/sindresorhus/nano-spawn) - Like Execa but [smaller](docs/small.md) +- [gulp-execa](https://github.com/ehmicky/gulp-execa) - Gulp plugin for Execa +- [nvexeca](https://github.com/ehmicky/nvexeca) - Run Execa using any Node.js version ## Maintainers - [Sindre Sorhus](https://github.com/sindresorhus) - [@ehmicky](https://github.com/ehmicky) - ---- - -
- - Get professional support for this package with a Tidelift subscription - -
- - Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. -
-
diff --git a/node_modules/execa/types/arguments/encoding-option.d.ts b/node_modules/execa/types/arguments/encoding-option.d.ts new file mode 100644 index 0000000000..a0a95748ac --- /dev/null +++ b/node_modules/execa/types/arguments/encoding-option.d.ts @@ -0,0 +1,19 @@ +type DefaultEncodingOption = 'utf8'; +type TextEncodingOption = + | DefaultEncodingOption + | 'utf16le'; + +export type BufferEncodingOption = 'buffer'; +export type BinaryEncodingOption = + | BufferEncodingOption + | 'hex' + | 'base64' + | 'base64url' + | 'latin1' + | 'ascii'; + +// `options.encoding` +export type EncodingOption = + | TextEncodingOption + | BinaryEncodingOption + | undefined; diff --git a/node_modules/execa/types/arguments/fd-options.d.ts b/node_modules/execa/types/arguments/fd-options.d.ts new file mode 100644 index 0000000000..195d92fdab --- /dev/null +++ b/node_modules/execa/types/arguments/fd-options.d.ts @@ -0,0 +1,8 @@ +type FileDescriptorOption = `fd${number}`; + +// `from` option of `subprocess.readable|duplex|iterable|pipe()` +// Also used by fd-specific options +export type FromOption = 'stdout' | 'stderr' | 'all' | FileDescriptorOption; + +// `to` option of `subprocess.writable|duplex|pipe()` +export type ToOption = 'stdin' | FileDescriptorOption; diff --git a/node_modules/execa/types/arguments/options.d.ts b/node_modules/execa/types/arguments/options.d.ts new file mode 100644 index 0000000000..fea7baad63 --- /dev/null +++ b/node_modules/execa/types/arguments/options.d.ts @@ -0,0 +1,400 @@ +import type {SignalConstants} from 'node:os'; +import type {Readable} from 'node:stream'; +import type {Unless} from '../utils.js'; +import type {Message} from '../ipc.js'; +import type {StdinOptionCommon, StdoutStderrOptionCommon, StdioOptionsProperty} from '../stdio/type.js'; +import type {VerboseOption} from '../verbose.js'; +import type {FdGenericOption} from './specific.js'; +import type {EncodingOption} from './encoding-option.js'; + +export type CommonOptions = { + /** + Prefer locally installed binaries when looking for a binary to execute. + + @default `true` with `$`, `false` otherwise + */ + readonly preferLocal?: boolean; + + /** + Preferred path to find locally installed binaries, when using the `preferLocal` option. + + @default `cwd` option + */ + readonly localDir?: string | URL; + + /** + If `true`, runs with Node.js. The first argument must be a Node.js file. + + The subprocess inherits the current Node.js [CLI flags](https://nodejs.org/api/cli.html#options) and version. This can be overridden using the `nodeOptions` and `nodePath` options. + + @default `true` with `execaNode()`, `false` otherwise + */ + readonly node?: boolean; + + /** + List of [CLI flags](https://nodejs.org/api/cli.html#cli_options) passed to the Node.js executable. + + Requires the `node` option to be `true`. + + @default [`process.execArgv`](https://nodejs.org/api/process.html#process_process_execargv) (current Node.js CLI flags) + */ + readonly nodeOptions?: readonly string[]; + + /** + Path to the Node.js executable. + + Requires the `node` option to be `true`. + + @default [`process.execPath`](https://nodejs.org/api/process.html#process_process_execpath) (current Node.js executable) + */ + readonly nodePath?: string | URL; + + /** + If `true`, runs the command inside of a [shell](https://en.wikipedia.org/wiki/Shell_(computing)). + + Uses [`/bin/sh`](https://en.wikipedia.org/wiki/Unix_shell) on UNIX and [`cmd.exe`](https://en.wikipedia.org/wiki/Cmd.exe) on Windows. A different shell can be specified as a string. The shell should understand the `-c` switch on UNIX or `/d /s /c` on Windows. + + We recommend against using this option. + + @default false + */ + readonly shell?: boolean | string | URL; + + /** + Current [working directory](https://en.wikipedia.org/wiki/Working_directory) of the subprocess. + + This is also used to resolve the `nodePath` option when it is a relative path. + + @default process.cwd() + */ + readonly cwd?: string | URL; + + /** + [Environment variables](https://en.wikipedia.org/wiki/Environment_variable). + + Unless the `extendEnv` option is `false`, the subprocess also uses the current process' environment variables ([`process.env`](https://nodejs.org/api/process.html#processenv)). + + @default [process.env](https://nodejs.org/api/process.html#processenv) + */ + readonly env?: Readonly>>; + + /** + If `true`, the subprocess uses both the `env` option and the current process' environment variables ([`process.env`](https://nodejs.org/api/process.html#processenv)). + If `false`, only the `env` option is used, not `process.env`. + + @default true + */ + readonly extendEnv?: boolean; + + /** + Write some input to the subprocess' [`stdin`](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)). + + See also the `inputFile` and `stdin` options. + */ + readonly input?: string | Uint8Array | Readable; + + /** + Use a file as input to the subprocess' [`stdin`](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)). + + See also the `input` and `stdin` options. + */ + readonly inputFile?: string | URL; + + /** + How to setup the subprocess' [standard input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)). This can be `'pipe'`, `'overlapped'`, `'ignore`, `'inherit'`, a file descriptor integer, a Node.js `Readable` stream, a web `ReadableStream`, a `{ file: 'path' }` object, a file URL, an `Iterable`, an `AsyncIterable`, an `Uint8Array`, a generator function, a `Duplex` or a web `TransformStream`. + + This can be an array of values such as `['inherit', 'pipe']` or `[fileUrl, 'pipe']`. + + @default `'inherit'` with `$`, `'pipe'` otherwise + */ + readonly stdin?: StdinOptionCommon; + + /** + How to setup the subprocess' [standard output](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)). This can be `'pipe'`, `'overlapped'`, `'ignore`, `'inherit'`, a file descriptor integer, a Node.js `Writable` stream, a web `WritableStream`, a `{ file: 'path' }` object, a file URL, a generator function, a `Duplex` or a web `TransformStream`. + + This can be an array of values such as `['inherit', 'pipe']` or `[fileUrl, 'pipe']`. + + @default 'pipe' + */ + readonly stdout?: StdoutStderrOptionCommon; + + /** + How to setup the subprocess' [standard error](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)). This can be `'pipe'`, `'overlapped'`, `'ignore`, `'inherit'`, a file descriptor integer, a Node.js `Writable` stream, a web `WritableStream`, a `{ file: 'path' }` object, a file URL, a generator function, a `Duplex` or a web `TransformStream`. + + This can be an array of values such as `['inherit', 'pipe']` or `[fileUrl, 'pipe']`. + + @default 'pipe' + */ + readonly stderr?: StdoutStderrOptionCommon; + + /** + Like the `stdin`, `stdout` and `stderr` options but for all [file descriptors](https://en.wikipedia.org/wiki/File_descriptor) at once. For example, `{stdio: ['ignore', 'pipe', 'pipe']}` is the same as `{stdin: 'ignore', stdout: 'pipe', stderr: 'pipe'}`. + + A single string can be used as a shortcut. + + The array can have more than 3 items, to create additional file descriptors beyond `stdin`/`stdout`/`stderr`. + + @default 'pipe' + */ + readonly stdio?: StdioOptionsProperty; + + /** + Add a `subprocess.all` stream and a `result.all` property. They contain the combined/interleaved output of the subprocess' `stdout` and `stderr`. + + @default false + */ + readonly all?: boolean; + + /** + If the subprocess outputs text, specifies its character encoding, either [`'utf8'`](https://en.wikipedia.org/wiki/UTF-8) or [`'utf16le'`](https://en.wikipedia.org/wiki/UTF-16). + + If it outputs binary data instead, this should be either: + - `'buffer'`: returns the binary output as an `Uint8Array`. + - [`'hex'`](https://en.wikipedia.org/wiki/Hexadecimal), [`'base64'`](https://en.wikipedia.org/wiki/Base64), [`'base64url'`](https://en.wikipedia.org/wiki/Base64#URL_applications), [`'latin1'`](https://nodejs.org/api/buffer.html#buffers-and-character-encodings) or [`'ascii'`](https://nodejs.org/api/buffer.html#buffers-and-character-encodings): encodes the binary output as a string. + + The output is available with `result.stdout`, `result.stderr` and `result.stdio`. + + @default 'utf8' + */ + readonly encoding?: EncodingOption; + + /** + Set `result.stdout`, `result.stderr`, `result.all` and `result.stdio` as arrays of strings, splitting the subprocess' output into lines. + + This cannot be used if the `encoding` option is binary. + + By default, this applies to both `stdout` and `stderr`, but different values can also be passed. + + @default false + */ + readonly lines?: FdGenericOption; + + /** + Strip the final [newline character](https://en.wikipedia.org/wiki/Newline) from the output. + + If the `lines` option is true, this applies to each output line instead. + + By default, this applies to both `stdout` and `stderr`, but different values can also be passed. + + @default true + */ + readonly stripFinalNewline?: FdGenericOption; + + /** + Largest amount of data allowed on `stdout`, `stderr` and `stdio`. + + By default, this applies to both `stdout` and `stderr`, but different values can also be passed. + + When reached, `error.isMaxBuffer` becomes `true`. + + @default 100_000_000 + */ + readonly maxBuffer?: FdGenericOption; + + /** + When `buffer` is `false`, the `result.stdout`, `result.stderr`, `result.all` and `result.stdio` properties are not set. + + By default, this applies to both `stdout` and `stderr`, but different values can also be passed. + + @default true + */ + readonly buffer?: FdGenericOption; + + /** + Enables exchanging messages with the subprocess using `subprocess.sendMessage(message)`, `subprocess.getOneMessage()` and `subprocess.getEachMessage()`. + + The subprocess must be a Node.js file. + + @default `true` if the `node`, `ipcInput` or `gracefulCancel` option is set, `false` otherwise + */ + readonly ipc?: Unless; + + /** + Specify the kind of serialization used for sending messages between subprocesses when using the `ipc` option. + + @default 'advanced' + */ + readonly serialization?: Unless; + + /** + Sends an IPC message when the subprocess starts. + + The subprocess must be a Node.js file. The value's type depends on the `serialization` option. + */ + readonly ipcInput?: Unless; + + /** + If `verbose` is `'short'`, prints the command on [`stderr`](https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)): its file, arguments, duration and (if it failed) error message. + + If `verbose` is `'full'` or a function, the command's [`stdout`](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout)), `stderr` and IPC messages are also printed. + + A function can be passed to customize logging. + + By default, this applies to both `stdout` and `stderr`, but different values can also be passed. + + @default 'none' + */ + readonly verbose?: VerboseOption; + + /** + Setting this to `false` resolves the result's promise with the error instead of rejecting it. + + @default true + */ + readonly reject?: boolean; + + /** + If `timeout` is greater than `0`, the subprocess will be terminated if it runs for longer than that amount of milliseconds. + + On timeout, `error.timedOut` becomes `true`. + + @default 0 + */ + readonly timeout?: number; + + /** + When the `cancelSignal` is [aborted](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort), terminate the subprocess using a `SIGTERM` signal. + + When aborted, `error.isCanceled` becomes `true`. + + @example + ``` + import {execaNode} from 'execa'; + + const controller = new AbortController(); + const cancelSignal = controller.signal; + + setTimeout(() => { + controller.abort(); + }, 5000); + + try { + await execaNode({cancelSignal})`build.js`; + } catch (error) { + if (error.isCanceled) { + console.error('Canceled by cancelSignal.'); + } + + throw error; + } + ``` + */ + readonly cancelSignal?: Unless; + + /** + When the `cancelSignal` option is [aborted](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort), do not send any `SIGTERM`. Instead, abort the [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) returned by `getCancelSignal()`. The subprocess should use it to terminate gracefully. + + The subprocess must be a Node.js file. + + When aborted, `error.isGracefullyCanceled` becomes `true`. + + @default false + */ + readonly gracefulCancel?: Unless; + + /** + If the subprocess is terminated but does not exit, forcefully exit it by sending [`SIGKILL`](https://en.wikipedia.org/wiki/Signal_(IPC)#SIGKILL). + + When this happens, `error.isForcefullyTerminated` becomes `true`. + + @default 5000 + */ + readonly forceKillAfterDelay?: Unless; + + /** + Default [signal](https://en.wikipedia.org/wiki/Signal_(IPC)) used to terminate the subprocess. + + This can be either a name (like `'SIGTERM'`) or a number (like `9`). + + @default 'SIGTERM' + */ + readonly killSignal?: keyof SignalConstants | number; + + /** + Run the subprocess independently from the current process. + + @default false + */ + readonly detached?: Unless; + + /** + Kill the subprocess when the current process exits. + + @default true + */ + readonly cleanup?: Unless; + + /** + Sets the [user identifier](https://en.wikipedia.org/wiki/User_identifier) of the subprocess. + + @default current user identifier + */ + readonly uid?: number; + + /** + Sets the [group identifier](https://en.wikipedia.org/wiki/Group_identifier) of the subprocess. + + @default current group identifier + */ + readonly gid?: number; + + /** + Value of [`argv[0]`](https://nodejs.org/api/process.html#processargv0) sent to the subprocess. + + @default file being executed + */ + readonly argv0?: string; + + /** + On Windows, do not create a new console window. + + @default true + */ + readonly windowsHide?: boolean; + + /** + If `false`, escapes the command arguments on Windows. + + @default `true` if the `shell` option is `true`, `false` otherwise + */ + readonly windowsVerbatimArguments?: boolean; +}; + +/** +Subprocess options. + +Some options are related to the subprocess output: `verbose`, `lines`, `stripFinalNewline`, `buffer`, `maxBuffer`. By default, those options apply to all file descriptors (`stdout`, `stderr`, etc.). A plain object can be passed instead to apply them to only `stdout`, `stderr`, `all` (both stdout and stderr), `ipc`, `fd3`, etc. + +@example + +``` +// Same value for stdout and stderr +await execa({verbose: 'full'})`npm run build`; + +// Different values for stdout and stderr +await execa({verbose: {stdout: 'none', stderr: 'full'}})`npm run build`; +``` +*/ +export type Options = CommonOptions; + +/** +Subprocess options, with synchronous methods. + +Some options are related to the subprocess output: `verbose`, `lines`, `stripFinalNewline`, `buffer`, `maxBuffer`. By default, those options apply to all file descriptors (`stdout`, `stderr`, etc.). A plain object can be passed instead to apply them to only `stdout`, `stderr`, `all` (both stdout and stderr), `ipc`, `fd3`, etc. + +@example + +``` +// Same value for stdout and stderr +execaSync({verbose: 'full'})`npm run build`; + +// Different values for stdout and stderr +execaSync({verbose: {stdout: 'none', stderr: 'full'}})`npm run build`; +``` +*/ +export type SyncOptions = CommonOptions; + +export type StricterOptions< + WideOptions extends CommonOptions, + StrictOptions extends CommonOptions, +> = WideOptions extends StrictOptions ? WideOptions : StrictOptions; diff --git a/node_modules/execa/types/arguments/specific.d.ts b/node_modules/execa/types/arguments/specific.d.ts new file mode 100644 index 0000000000..e2cbda141c --- /dev/null +++ b/node_modules/execa/types/arguments/specific.d.ts @@ -0,0 +1,52 @@ +import type {FromOption} from './fd-options.js'; + +// Options which can be fd-specific like `{verbose: {stdout: 'none', stderr: 'full'}}` +export type FdGenericOption = OptionType | GenericOptionObject; + +type GenericOptionObject = { + readonly [FdName in GenericFromOption]?: OptionType +}; + +type GenericFromOption = FromOption | 'ipc'; + +// Retrieve fd-specific option's value +export type FdSpecificOption< + GenericOption extends FdGenericOption, + FdNumber extends string, +> = GenericOption extends GenericOptionObject + ? FdSpecificObjectOption + : GenericOption; + +type FdSpecificObjectOption< + GenericOption extends GenericOptionObject, + FdNumber extends string, +> = keyof GenericOption extends GenericFromOption + ? FdNumberToFromOption extends never + ? undefined + : GenericOption[FdNumberToFromOption] + : GenericOption; + +type FdNumberToFromOption< + FdNumber extends string, + GenericOptionKeys extends GenericFromOption, +> = FdNumber extends '1' + ? 'stdout' extends GenericOptionKeys + ? 'stdout' + : 'fd1' extends GenericOptionKeys + ? 'fd1' + : 'all' extends GenericOptionKeys + ? 'all' + : never + : FdNumber extends '2' + ? 'stderr' extends GenericOptionKeys + ? 'stderr' + : 'fd2' extends GenericOptionKeys + ? 'fd2' + : 'all' extends GenericOptionKeys + ? 'all' + : never + : `fd${FdNumber}` extends GenericOptionKeys + ? `fd${FdNumber}` + : 'ipc' extends GenericOptionKeys + ? 'ipc' + : never; diff --git a/node_modules/execa/types/convert.d.ts b/node_modules/execa/types/convert.d.ts new file mode 100644 index 0000000000..3824a78501 --- /dev/null +++ b/node_modules/execa/types/convert.d.ts @@ -0,0 +1,58 @@ +import type {BinaryEncodingOption} from './arguments/encoding-option.js'; +import type {Options} from './arguments/options.js'; +import type {FromOption, ToOption} from './arguments/fd-options.js'; + +// `subprocess.readable|duplex|iterable()` options +export type ReadableOptions = { + /** + Which stream to read from the subprocess. A [file descriptor](https://en.wikipedia.org/wiki/File_descriptor) like `"fd3"` can also be passed. + + `"all"` reads both `stdout` and `stderr`. This requires the `all` option to be `true`. + + @default 'stdout' + */ + readonly from?: FromOption; + + /** + If `false`, iterates over lines. Each line is a string. + + If `true`, iterates over arbitrary chunks of data. Each line is an [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) (with `subprocess.iterable()`) or a [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) (with `subprocess.readable()`/`subprocess.duplex()`). + + This is always `true` when the `encoding` option is binary. + + @default `false` with `subprocess.iterable()`, `true` otherwise + */ + readonly binary?: boolean; + + /** + If both this option and the `binary` option is `false`, [newlines](https://en.wikipedia.org/wiki/Newline) are stripped from each line. + + @default `false` with `subprocess.iterable()`, `true` otherwise + */ + readonly preserveNewlines?: boolean; +}; + +// `subprocess.writable|duplex()` options +export type WritableOptions = { + /** + Which stream to write to the subprocess. A [file descriptor](https://en.wikipedia.org/wiki/File_descriptor) like `"fd3"` can also be passed. + + @default 'stdin' + */ + readonly to?: ToOption; +}; + +// `subprocess.duplex()` options +export type DuplexOptions = ReadableOptions & WritableOptions; + +// `subprocess.iterable()` return value +export type SubprocessAsyncIterable< + BinaryOption extends boolean | undefined, + EncodingOption extends Options['encoding'], +> = AsyncIterableIterator< +EncodingOption extends BinaryEncodingOption + ? Uint8Array + : BinaryOption extends true + ? Uint8Array + : string +>; diff --git a/node_modules/execa/types/ipc.d.ts b/node_modules/execa/types/ipc.d.ts new file mode 100644 index 0000000000..850684c981 --- /dev/null +++ b/node_modules/execa/types/ipc.d.ts @@ -0,0 +1,156 @@ +import type {Options} from './arguments/options.js'; + +// Message when the `serialization` option is `'advanced'` +type AdvancedMessage = + | string + | number + | boolean + | null + | object; + +// Message when the `serialization` option is `'json'` +type JsonMessage = + | string + | number + | boolean + | null + | readonly JsonMessage[] + | {readonly [key: string | number]: JsonMessage}; + +/** +Type of messages exchanged between a process and its subprocess using `sendMessage()`, `getOneMessage()` and `getEachMessage()`. + +This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option. +*/ +export type Message< + Serialization extends Options['serialization'] = Options['serialization'], +> = Serialization extends 'json' ? JsonMessage : AdvancedMessage; + +/** +Options to `sendMessage()` and `subprocess.sendMessage()` +*/ +type SendMessageOptions = { + /** + Throw when the other process is not receiving or listening to messages. + + @default false + */ + readonly strict?: boolean; +}; + +// IPC methods in subprocess +/** +Send a `message` to the parent process. + +This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option. +*/ +export function sendMessage(message: Message, sendMessageOptions?: SendMessageOptions): Promise; + +/** +Options to `getOneMessage()` and `subprocess.getOneMessage()` +*/ +type GetOneMessageOptions< + Serialization extends Options['serialization'], +> = { + /** + Ignore any `message` that returns `false`. + */ + readonly filter?: (message: Message) => boolean; + + /** + Keep the subprocess alive while `getOneMessage()` is waiting. + + @default true + */ + readonly reference?: boolean; +}; + +/** +Receive a single `message` from the parent process. + +This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option. +*/ +export function getOneMessage(getOneMessageOptions?: GetOneMessageOptions): Promise; + +/** +Options to `getEachMessage()` and `subprocess.getEachMessage()` +*/ +type GetEachMessageOptions = { + /** + Keep the subprocess alive while `getEachMessage()` is waiting. + + @default true + */ + readonly reference?: boolean; +}; + +/** +Iterate over each `message` from the parent process. + +This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option. +*/ +export function getEachMessage(getEachMessageOptions?: GetEachMessageOptions): AsyncIterableIterator; + +/** +Retrieves the [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) shared by the `cancelSignal` option. + +This can only be called inside a subprocess. This requires the `gracefulCancel` option to be `true`. +*/ +export function getCancelSignal(): Promise; + +// IPC methods in the subprocess +export type IpcMethods< + IpcEnabled extends boolean, + Serialization extends Options['serialization'], +> = IpcEnabled extends true + ? { + /** + Send a `message` to the subprocess. + + This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option. + */ + sendMessage(message: Message, sendMessageOptions?: SendMessageOptions): Promise; + + /** + Receive a single `message` from the subprocess. + + This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option. + */ + getOneMessage(getOneMessageOptions?: GetOneMessageOptions): Promise>; + + /** + Iterate over each `message` from the subprocess. + + This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option. + */ + getEachMessage(getEachMessageOptions?: GetEachMessageOptions): AsyncIterableIterator>; + } + // Those methods only work if the `ipc` option is `true`. + // At runtime, they are actually defined, in order to provide with a nice error message. + // At type check time, they are typed as `undefined` to prevent calling them. + : { + sendMessage: undefined; + getOneMessage: undefined; + getEachMessage: undefined; + }; + +// Whether IPC is enabled, based on the `ipc`, `ipcInput` and `gracefulCancel` options +export type HasIpc = HasIpcOption< +OptionsType['ipc'], +'ipcInput' extends keyof OptionsType ? OptionsType['ipcInput'] : undefined, +'gracefulCancel' extends keyof OptionsType ? OptionsType['gracefulCancel'] : undefined +>; + +type HasIpcOption< + IpcOption extends Options['ipc'], + IpcInputOption extends Options['ipcInput'], + GracefulCancelOption extends Options['gracefulCancel'], +> = IpcOption extends true + ? true + : IpcOption extends false + ? false + : IpcInputOption extends undefined + ? GracefulCancelOption extends true + ? true + : false + : true; diff --git a/node_modules/execa/types/methods/command.d.ts b/node_modules/execa/types/methods/command.d.ts new file mode 100644 index 0000000000..58fd0441d2 --- /dev/null +++ b/node_modules/execa/types/methods/command.d.ts @@ -0,0 +1,114 @@ +import type {Options, SyncOptions} from '../arguments/options.js'; +import type {SyncResult} from '../return/result.js'; +import type {ResultPromise} from '../subprocess/subprocess.js'; +import type {SimpleTemplateString} from './template.js'; + +/** +Executes a command. `command` is a string that includes both the `file` and its `arguments`. + +When `command` is a template string, it includes both the `file` and its `arguments`. + +`execaCommand(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. + +This is only intended for very specific cases, such as a REPL. This should be avoided otherwise. + +@param command - The program/script to execute and its arguments. +@returns A `ResultPromise` that is both: +- the subprocess. +- a `Promise` either resolving with its successful `result`, or rejecting with its `error`. +@throws `ExecaError` + +@example +``` +import {execaCommand} from 'execa'; + +for await (const commandAndArguments of getReplLine()) { + await execaCommand(commandAndArguments); +} +``` +*/ +export declare const execaCommand: ExecaCommandMethod<{}>; + +type ExecaCommandMethod = + & ExecaCommandBind + & ExecaCommandTemplate + & ExecaCommandArray; + +// `execaCommand(options)` binding +type ExecaCommandBind = + (options: NewOptionsType) + => ExecaCommandMethod; + +// `execaCommand`command`` template syntax +type ExecaCommandTemplate = + (...templateString: SimpleTemplateString) + => ResultPromise; + +// `execaCommand('command', {})` array syntax +type ExecaCommandArray = + (command: string, options?: NewOptionsType) + => ResultPromise; + +/** +Same as `execaCommand()` but synchronous. + +When `command` is a template string, it includes both the `file` and its `arguments`. + +`execaCommandSync(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. + +Returns a subprocess `result` or throws an `error`. The `subprocess` is not returned: its methods and properties are not available. + +@param command - The program/script to execute and its arguments. +@returns `SyncResult` +@throws `ExecaSyncError` + +@example +``` +import {execaCommandSync} from 'execa'; + +for (const commandAndArguments of getReplLine()) { + execaCommandSync(commandAndArguments); +} +``` +*/ +export declare const execaCommandSync: ExecaCommandSyncMethod<{}>; + +type ExecaCommandSyncMethod = + & ExecaCommandSyncBind + & ExecaCommandSyncTemplate + & ExecaCommandSyncArray; + +// `execaCommandSync(options)` binding +type ExecaCommandSyncBind = + (options: NewOptionsType) + => ExecaCommandSyncMethod; + +// `execaCommandSync`command`` template syntax +type ExecaCommandSyncTemplate = + (...templateString: SimpleTemplateString) + => SyncResult; + +// `execaCommandSync('command', {})` array syntax +type ExecaCommandSyncArray = + (command: string, options?: NewOptionsType) + => SyncResult; + +/** +Split a `command` string into an array. For example, `'npm run build'` returns `['npm', 'run', 'build']` and `'argument otherArgument'` returns `['argument', 'otherArgument']`. + +@param command - The file to execute and/or its arguments. +@returns fileOrArgument[] + +@example +``` +import {execa, parseCommandString} from 'execa'; + +const commandString = 'npm run task'; +const commandArray = parseCommandString(commandString); +await execa`${commandArray}`; + +const [file, ...commandArguments] = commandArray; +await execa(file, commandArguments); +``` +*/ +export function parseCommandString(command: string): string[]; diff --git a/node_modules/execa/types/methods/main-async.d.ts b/node_modules/execa/types/methods/main-async.d.ts new file mode 100644 index 0000000000..3805647f12 --- /dev/null +++ b/node_modules/execa/types/methods/main-async.d.ts @@ -0,0 +1,379 @@ +import type {Options} from '../arguments/options.js'; +import type {ResultPromise} from '../subprocess/subprocess.js'; +import type {TemplateString} from './template.js'; + +/** +Executes a command using `file ...arguments`. + +When `command` is a template string, it includes both the `file` and its `arguments`. + +`execa(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. + +@param file - The program/script to execute, as a string or file URL +@param arguments - Arguments to pass to `file` on execution. +@returns A `ResultPromise` that is both: +- the subprocess. +- a `Promise` either resolving with its successful `result`, or rejecting with its `error`. +@throws `ExecaError` + +@example Simple syntax + +``` +import {execa} from 'execa'; + +const {stdout} = await execa`npm run build`; +// Print command's output +console.log(stdout); +``` + +@example Script + +``` +import {$} from 'execa'; + +const {stdout: name} = await $`cat package.json`.pipe`grep name`; +console.log(name); + +const branch = await $`git branch --show-current`; +await $`dep deploy --branch=${branch}`; + +await Promise.all([ + $`sleep 1`, + $`sleep 2`, + $`sleep 3`, +]); + +const directoryName = 'foo bar'; +await $`mkdir /tmp/${directoryName}`; +``` + +@example Local binaries + +``` +$ npm install -D eslint +``` + +``` +await execa({preferLocal: true})`eslint`; +``` + +@example Pipe multiple subprocesses + +``` +const {stdout, pipedFrom} = await execa`npm run build` + .pipe`sort` + .pipe`head -n 2`; + +// Output of `npm run build | sort | head -n 2` +console.log(stdout); +// Output of `npm run build | sort` +console.log(pipedFrom[0].stdout); +// Output of `npm run build` +console.log(pipedFrom[0].pipedFrom[0].stdout); +``` + +@example Interleaved output + +``` +const {all} = await execa({all: true})`npm run build`; +// stdout + stderr, interleaved +console.log(all); +``` + +@example Programmatic + terminal output + +``` +const {stdout} = await execa({stdout: ['pipe', 'inherit']})`npm run build`; +// stdout is also printed to the terminal +console.log(stdout); +``` + +@example Simple input + +``` +const getInputString = () => { /* ... *\/ }; +const {stdout} = await execa({input: getInputString()})`sort`; +console.log(stdout); +``` + +@example File input + +``` +// Similar to: npm run build < input.txt +await execa({stdin: {file: 'input.txt'}})`npm run build`; +``` + +@example File output + +``` +// Similar to: npm run build > output.txt +await execa({stdout: {file: 'output.txt'}})`npm run build`; +``` + +@example Split into text lines + +``` +const {stdout} = await execa({lines: true})`npm run build`; +// Print first 10 lines +console.log(stdout.slice(0, 10).join('\n')); +``` + +@example Iterate over text lines + +``` +for await (const line of execa`npm run build`) { + if (line.includes('WARN')) { + console.warn(line); + } +} +``` + +@example Transform/filter output + +``` +let count = 0; + +// Filter out secret lines, then prepend the line number +const transform = function * (line) { + if (!line.includes('secret')) { + yield `[${count++}] ${line}`; + } +}; + +await execa({stdout: transform})`npm run build`; +``` + +@example Web streams + +``` +const response = await fetch('https://example.com'); +await execa({stdin: response.body})`sort`; +``` + +@example Convert to Duplex stream + +``` +import {execa} from 'execa'; +import {pipeline} from 'node:stream/promises'; +import {createReadStream, createWriteStream} from 'node:fs'; + +await pipeline( + createReadStream('./input.txt'), + execa`node ./transform.js`.duplex(), + createWriteStream('./output.txt'), +); +``` + +@example Exchange messages + +``` +// parent.js +import {execaNode} from 'execa'; + +const subprocess = execaNode`child.js`; +await subprocess.sendMessage('Hello from parent'); +const message = await subprocess.getOneMessage(); +console.log(message); // 'Hello from child' +``` + +``` +// child.js +import {getOneMessage, sendMessage} from 'execa'; + +const message = await getOneMessage(); // 'Hello from parent' +const newMessage = message.replace('parent', 'child'); // 'Hello from child' +await sendMessage(newMessage); +``` + +@example Any input type + +``` +// main.js +import {execaNode} from 'execa'; + +const ipcInput = [ + {task: 'lint', ignore: /test\.js/}, + {task: 'copy', files: new Set(['main.js', 'index.js']), +}]; +await execaNode({ipcInput})`build.js`; +``` + +``` +// build.js +import {getOneMessage} from 'execa'; + +const ipcInput = await getOneMessage(); +``` + +@example Any output type + +``` +// main.js +import {execaNode} from 'execa'; + +const {ipcOutput} = await execaNode`build.js`; +console.log(ipcOutput[0]); // {kind: 'start', timestamp: date} +console.log(ipcOutput[1]); // {kind: 'stop', timestamp: date} +``` + +``` +// build.js +import {sendMessage} from 'execa'; + +const runBuild = () => { /* ... *\/ }; + +await sendMessage({kind: 'start', timestamp: new Date()}); +await runBuild(); +await sendMessage({kind: 'stop', timestamp: new Date()}); +``` + +@example Graceful termination + +``` +// main.js +import {execaNode} from 'execa'; + +const controller = new AbortController(); +setTimeout(() => { + controller.abort(); +}, 5000); + +await execaNode({ + cancelSignal: controller.signal, + gracefulCancel: true, +})`build.js`; +``` + +``` +// build.js +import {getCancelSignal} from 'execa'; + +const cancelSignal = await getCancelSignal(); +const url = 'https://example.com/build/info'; +const response = await fetch(url, {signal: cancelSignal}); +``` + +@example Detailed error + +``` +import {execa, ExecaError} from 'execa'; + +try { + await execa`unknown command`; +} catch (error) { + if (error instanceof ExecaError) { + console.log(error); + } + /* + ExecaError: Command failed with ENOENT: unknown command + spawn unknown ENOENT + at ... + at ... { + shortMessage: 'Command failed with ENOENT: unknown command\nspawn unknown ENOENT', + originalMessage: 'spawn unknown ENOENT', + command: 'unknown command', + escapedCommand: 'unknown command', + cwd: '/path/to/cwd', + durationMs: 28.217566, + failed: true, + timedOut: false, + isCanceled: false, + isTerminated: false, + isMaxBuffer: false, + code: 'ENOENT', + stdout: '', + stderr: '', + stdio: [undefined, '', ''], + pipedFrom: [] + [cause]: Error: spawn unknown ENOENT + at ... + at ... { + errno: -2, + code: 'ENOENT', + syscall: 'spawn unknown', + path: 'unknown', + spawnargs: [ 'command' ] + } + } + *\/ +} +``` + +@example Verbose mode + +``` +await execa`npm run build`; +await execa`npm run test`; +``` + +``` +$ NODE_DEBUG=execa node build.js +[00:57:44.581] [0] $ npm run build +[00:57:44.653] [0] Building application... +[00:57:44.653] [0] Done building. +[00:57:44.658] [0] ✔ (done in 78ms) +[00:57:44.658] [1] $ npm run test +[00:57:44.740] [1] Running tests... +[00:57:44.740] [1] Error: the entrypoint is invalid. +[00:57:44.747] [1] ✘ Command failed with exit code 1: npm run test +[00:57:44.747] [1] ✘ (done in 89ms) +``` + +@example Custom logging + +``` +import {execa as execa_} from 'execa'; +import {createLogger, transports} from 'winston'; + +// Log to a file using Winston +const transport = new transports.File({filename: 'logs.txt'}); +const logger = createLogger({transports: [transport]}); +const LOG_LEVELS = { + command: 'info', + output: 'verbose', + ipc: 'verbose', + error: 'error', + duration: 'info', +}; + +const execa = execa_({ + verbose(verboseLine, {message, ...verboseObject}) { + const level = LOG_LEVELS[verboseObject.type]; + logger[level](message, verboseObject); + }, +}); + +await execa`npm run build`; +await execa`npm run test`; +``` +*/ +export declare const execa: ExecaMethod<{}>; + +/** +`execa()` method either exported by Execa, or bound using `execa(options)`. +*/ +export type ExecaMethod = + & ExecaBind + & ExecaTemplate + & ExecaArrayLong + & ExecaArrayShort; + +// `execa(options)` binding +type ExecaBind = + (options: NewOptionsType) + => ExecaMethod; + +// `execa`command`` template syntax +type ExecaTemplate = + (...templateString: TemplateString) + => ResultPromise; + +// `execa('file', ['argument'], {})` array syntax +type ExecaArrayLong = + (file: string | URL, arguments?: readonly string[], options?: NewOptionsType) + => ResultPromise; + +// `execa('file', {})` array syntax +type ExecaArrayShort = + (file: string | URL, options?: NewOptionsType) + => ResultPromise; diff --git a/node_modules/execa/types/methods/main-sync.d.ts b/node_modules/execa/types/methods/main-sync.d.ts new file mode 100644 index 0000000000..45fc35a8d6 --- /dev/null +++ b/node_modules/execa/types/methods/main-sync.d.ts @@ -0,0 +1,59 @@ +import type {SyncOptions} from '../arguments/options.js'; +import type {SyncResult} from '../return/result.js'; +import type {TemplateString} from './template.js'; + +/** +Same as `execa()` but synchronous. + +Returns a subprocess `result` or throws an `error`. The `subprocess` is not returned: its methods and properties are not available. + +When `command` is a template string, it includes both the `file` and its `arguments`. + +`execaSync(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. + +This method is discouraged as it holds the CPU and lacks multiple features. + +@param file - The program/script to execute, as a string or file URL +@param arguments - Arguments to pass to `file` on execution. +@returns `SyncResult` +@throws `ExecaSyncError` + +@example + +``` +import {execaSync} from 'execa'; + +const {stdout} = execaSync`npm run build`; +// Print command's output +console.log(stdout); +``` +*/ +export declare const execaSync: ExecaSyncMethod<{}>; + +// For the moment, we purposely do not export `ExecaSyncMethod` and `ExecaScriptSyncMethod`. +// This is because synchronous invocation is discouraged. +export type ExecaSyncMethod = + & ExecaSyncBind + & ExecaSyncTemplate + & ExecaSyncArrayLong + & ExecaSyncArrayShort; + +// `execaSync(options)` binding +type ExecaSyncBind = + (options: NewOptionsType) + => ExecaSyncMethod; + +// `execaSync`command`` template syntax +type ExecaSyncTemplate = + (...templateString: TemplateString) + => SyncResult; + +// `execaSync('file', ['argument'], {})` array syntax +type ExecaSyncArrayLong = + (file: string | URL, arguments?: readonly string[], options?: NewOptionsType) + => SyncResult; + +// `execaSync('file', {})` array syntax +type ExecaSyncArrayShort = + (file: string | URL, options?: NewOptionsType) + => SyncResult; diff --git a/node_modules/execa/types/methods/node.d.ts b/node_modules/execa/types/methods/node.d.ts new file mode 100644 index 0000000000..910109b0bf --- /dev/null +++ b/node_modules/execa/types/methods/node.d.ts @@ -0,0 +1,62 @@ +import type {Options} from '../arguments/options.js'; +import type {ResultPromise} from '../subprocess/subprocess.js'; +import type {TemplateString} from './template.js'; + +/** +Same as `execa()` but using the `node: true` option. +Executes a Node.js file using `node scriptPath ...arguments`. + +When `command` is a template string, it includes both the `file` and its `arguments`. + +`execaNode(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. + +This is the preferred method when executing Node.js files. + +@param scriptPath - Node.js script to execute, as a string or file URL +@param arguments - Arguments to pass to `scriptPath` on execution. +@returns A `ResultPromise` that is both: +- the subprocess. +- a `Promise` either resolving with its successful `result`, or rejecting with its `error`. +@throws `ExecaError` + +@example +``` +import {execaNode, execa} from 'execa'; + +await execaNode`file.js argument`; +// Is the same as: +await execa({node: true})`file.js argument`; +// Or: +await execa`node file.js argument`; +``` +*/ +export declare const execaNode: ExecaNodeMethod<{}>; + +/** +`execaNode()` method either exported by Execa, or bound using `execaNode(options)`. +*/ +export type ExecaNodeMethod = + & ExecaNodeBind + & ExecaNodeTemplate + & ExecaNodeArrayLong + & ExecaNodeArrayShort; + +// `execaNode(options)` binding +type ExecaNodeBind = + (options: NewOptionsType) + => ExecaNodeMethod; + +// `execaNode`command`` template syntax +type ExecaNodeTemplate = + (...templateString: TemplateString) + => ResultPromise; + +// `execaNode('script', ['argument'], {})` array syntax +type ExecaNodeArrayLong = + (scriptPath: string | URL, arguments?: readonly string[], options?: NewOptionsType) + => ResultPromise; + +// `execaNode('script', {})` array syntax +type ExecaNodeArrayShort = + (scriptPath: string | URL, options?: NewOptionsType) + => ResultPromise; diff --git a/node_modules/execa/types/methods/script.d.ts b/node_modules/execa/types/methods/script.d.ts new file mode 100644 index 0000000000..30cb8afa13 --- /dev/null +++ b/node_modules/execa/types/methods/script.d.ts @@ -0,0 +1,115 @@ +import type { + CommonOptions, + Options, + SyncOptions, + StricterOptions, +} from '../arguments/options.js'; +import type {SyncResult} from '../return/result.js'; +import type {ResultPromise} from '../subprocess/subprocess.js'; +import type {TemplateString} from './template.js'; + +/** +Same as `execa()` but using script-friendly default options. + +When `command` is a template string, it includes both the `file` and its `arguments`. + +`$(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. + +This is the preferred method when executing multiple commands in a script file. + +@returns A `ResultPromise` that is both: +- the subprocess. +- a `Promise` either resolving with its successful `result`, or rejecting with its `error`. +@throws `ExecaError` + +@example Basic +``` +import {$} from 'execa'; + +const branch = await $`git branch --show-current`; +await $`dep deploy --branch=${branch}`; +``` + +@example Verbose mode +``` +$ node build.js +Building application... +Done building. +Running tests... +Error: the entrypoint is invalid. + +$ NODE_DEBUG=execa node build.js +[00:57:44.581] [0] $ npm run build +[00:57:44.653] [0] Building application... +[00:57:44.653] [0] Done building. +[00:57:44.658] [0] ✔ (done in 78ms) +[00:57:44.658] [1] $ npm run test +[00:57:44.740] [1] Running tests... +[00:57:44.740] [1] Error: the entrypoint is invalid. +[00:57:44.747] [1] ✘ Command failed with exit code 1: npm run test +[00:57:44.747] [1] ✘ (done in 89ms) +``` +*/ +export const $: ExecaScriptMethod<{}>; + +/** +`$()` method either exported by Execa, or bound using `$(options)`. +*/ +export type ExecaScriptMethod = + & ExecaScriptBind + & ExecaScriptTemplate + & ExecaScriptArrayLong + & ExecaScriptArrayShort + & {sync: ExecaScriptSyncMethod} + & {s: ExecaScriptSyncMethod}; + +// `$(options)` binding +type ExecaScriptBind = + (options: NewOptionsType) + => ExecaScriptMethod; + +// `$`command`` template syntax +type ExecaScriptTemplate = + (...templateString: TemplateString) + => ResultPromise>; + +// `$('file', ['arg'], {})` array syntax +type ExecaScriptArrayLong = + (file: string | URL, arguments?: readonly string[], options?: NewOptionsType) + => ResultPromise>; + +// `$('file', {})` array syntax +type ExecaScriptArrayShort = + (file: string | URL, options?: NewOptionsType) + => ResultPromise>; + +// We must intersect the overloaded methods with & instead of using a simple object as a workaround for a TypeScript bug +// See https://github.com/microsoft/TypeScript/issues/58765 +/** +`$.sync()` method either exported by Execa, or bound using `$.sync(options)`. +*/ +export type ExecaScriptSyncMethod = + & ExecaScriptSyncBind + & ExecaScriptSyncTemplate + & ExecaScriptSyncArrayLong + & ExecaScriptSyncArrayShort; + +// `$.sync(options)` binding +type ExecaScriptSyncBind = + (options: NewOptionsType) + => ExecaScriptSyncMethod; + +// $.sync`command` template syntax +type ExecaScriptSyncTemplate = + (...templateString: TemplateString) + => SyncResult>; + +// `$.sync('file', ['arg'], {})` array syntax +type ExecaScriptSyncArrayLong = + (file: string | URL, arguments?: readonly string[], options?: NewOptionsType) + => SyncResult>; + +// `$.sync('file', {})` array syntax +type ExecaScriptSyncArrayShort = + (file: string | URL, options?: NewOptionsType) + => SyncResult>; diff --git a/node_modules/execa/types/methods/template.d.ts b/node_modules/execa/types/methods/template.d.ts new file mode 100644 index 0000000000..012d31990e --- /dev/null +++ b/node_modules/execa/types/methods/template.d.ts @@ -0,0 +1,18 @@ +import type {Result, SyncResult} from '../return/result.js'; + +type TemplateExpressionItem = + | string + | number + | Result + | SyncResult; + +/** +Value allowed inside `${...}` when using the template string syntax. +*/ +export type TemplateExpression = TemplateExpressionItem | readonly TemplateExpressionItem[]; + +// `...${...}...` template syntax +export type TemplateString = readonly [TemplateStringsArray, ...readonly TemplateExpression[]]; + +// `...${...}...` template syntax, but only allowing a single argument, for `execaCommand()` +export type SimpleTemplateString = readonly [TemplateStringsArray, string?]; diff --git a/node_modules/execa/types/pipe.d.ts b/node_modules/execa/types/pipe.d.ts new file mode 100644 index 0000000000..cc66dbeb5a --- /dev/null +++ b/node_modules/execa/types/pipe.d.ts @@ -0,0 +1,58 @@ +import type {Options} from './arguments/options.js'; +import type {Result} from './return/result.js'; +import type {FromOption, ToOption} from './arguments/fd-options.js'; +import type {ResultPromise} from './subprocess/subprocess.js'; +import type {TemplateExpression} from './methods/template.js'; + +// `subprocess.pipe()` options +type PipeOptions = { + /** + Which stream to pipe from the source subprocess. A [file descriptor](https://en.wikipedia.org/wiki/File_descriptor) like `"fd3"` can also be passed. + + `"all"` pipes both `stdout` and `stderr`. This requires the `all` option to be `true`. + */ + readonly from?: FromOption; + + /** + Which stream to pipe to the destination subprocess. A [file descriptor](https://en.wikipedia.org/wiki/File_descriptor) like `"fd3"` can also be passed. + */ + readonly to?: ToOption; + + /** + Unpipe the subprocess when the signal aborts. + */ + readonly unpipeSignal?: AbortSignal; +}; + +// `subprocess.pipe()` +export type PipableSubprocess = { + /** + [Pipe](https://nodejs.org/api/stream.html#readablepipedestination-options) the subprocess' `stdout` to a second Execa subprocess' `stdin`. This resolves with that second subprocess' result. If either subprocess is rejected, this is rejected with that subprocess' error instead. + + This follows the same syntax as `execa(file, arguments?, options?)` except both regular options and pipe-specific options can be specified. + */ + pipe( + file: string | URL, + arguments?: readonly string[], + options?: OptionsType, + ): Promise> & PipableSubprocess; + pipe( + file: string | URL, + options?: OptionsType, + ): Promise> & PipableSubprocess; + + /** + Like `subprocess.pipe(file, arguments?, options?)` but using a `command` template string instead. This follows the same syntax as `$`. + */ + pipe(templates: TemplateStringsArray, ...expressions: readonly TemplateExpression[]): + Promise> & PipableSubprocess; + pipe(options: OptionsType): + (templates: TemplateStringsArray, ...expressions: readonly TemplateExpression[]) + => Promise> & PipableSubprocess; + + /** + Like `subprocess.pipe(file, arguments?, options?)` but using the return value of another `execa()` call instead. + */ + pipe(destination: Destination, options?: PipeOptions): + Promise> & PipableSubprocess; +}; diff --git a/node_modules/execa/types/return/final-error.d.ts b/node_modules/execa/types/return/final-error.d.ts new file mode 100644 index 0000000000..f80b114f99 --- /dev/null +++ b/node_modules/execa/types/return/final-error.d.ts @@ -0,0 +1,51 @@ +import type {CommonOptions, Options, SyncOptions} from '../arguments/options.js'; +import {CommonResult} from './result.js'; + +declare abstract class CommonError< + IsSync extends boolean, + OptionsType extends CommonOptions, +> extends CommonResult { + message: CommonErrorProperty; + shortMessage: CommonErrorProperty; + originalMessage: CommonErrorProperty; + readonly name: CommonErrorProperty; + stack: CommonErrorProperty; +} + +type CommonErrorProperty< + IsSync extends boolean, + OptionsType extends CommonOptions, + PropertyName extends keyof CommonResult, +> = NonNullable[PropertyName]>; + +// `result.*` defined only on failure, i.e. on `error.*` +export type ErrorProperties = + | 'name' + | 'message' + | 'stack' + | 'cause' + | 'shortMessage' + | 'originalMessage' + | 'code'; + +/** +Result of a subprocess failed execution. + +This error is thrown as an exception. If the `reject` option is false, it is returned instead. + +This has the same shape as successful results, with a few additional properties. +*/ +export class ExecaError extends CommonError { + readonly name: 'ExecaError'; +} + +/** +Result of a subprocess failed execution. + +This error is thrown as an exception. If the `reject` option is false, it is returned instead. + +This has the same shape as successful results, with a few additional properties. +*/ +export class ExecaSyncError extends CommonError { + readonly name: 'ExecaSyncError'; +} diff --git a/node_modules/execa/types/return/ignore.d.ts b/node_modules/execa/types/return/ignore.d.ts new file mode 100644 index 0000000000..0df44aaf27 --- /dev/null +++ b/node_modules/execa/types/return/ignore.d.ts @@ -0,0 +1,26 @@ +import type {NoStreamStdioOption} from '../stdio/type.js'; +import type {IsInputFd} from '../stdio/direction.js'; +import type {FdStdioOption} from '../stdio/option.js'; +import type {FdSpecificOption} from '../arguments/specific.js'; +import type {CommonOptions} from '../arguments/options.js'; + +// Whether `result.stdin|stdout|stderr|all|stdio[*]` is `undefined` +export type IgnoresResultOutput< + FdNumber extends string, + OptionsType extends CommonOptions, +> = FdSpecificOption extends false + ? true + : IsInputFd extends true + ? true + : IgnoresSubprocessOutput; + +// Whether `subprocess.stdout|stderr|all` is `undefined|null` +export type IgnoresSubprocessOutput< + FdNumber extends string, + OptionsType extends CommonOptions, +> = IgnoresOutput>; + +type IgnoresOutput< + FdNumber extends string, + StdioOptionType, +> = StdioOptionType extends NoStreamStdioOption ? true : false; diff --git a/node_modules/execa/types/return/result-all.d.ts b/node_modules/execa/types/return/result-all.d.ts new file mode 100644 index 0000000000..74bab1966d --- /dev/null +++ b/node_modules/execa/types/return/result-all.d.ts @@ -0,0 +1,30 @@ +import type {IsObjectFd} from '../transform/object-mode.js'; +import type {CommonOptions} from '../arguments/options.js'; +import type {FdSpecificOption} from '../arguments/specific.js'; +import type {IgnoresResultOutput} from './ignore.js'; +import type {ResultStdio} from './result-stdout.js'; + +// `result.all` +export type ResultAll = + ResultAllProperty; + +type ResultAllProperty< + AllOption extends CommonOptions['all'], + OptionsType extends CommonOptions, +> = AllOption extends true + ? ResultStdio< + AllMainFd, + AllObjectFd, + AllLinesFd, + OptionsType + > + : undefined; + +type AllMainFd = + IgnoresResultOutput<'1', OptionsType> extends true ? '2' : '1'; + +type AllObjectFd = + IsObjectFd<'1', OptionsType> extends true ? '1' : '2'; + +type AllLinesFd = + FdSpecificOption extends true ? '1' : '2'; diff --git a/node_modules/execa/types/return/result-ipc.d.ts b/node_modules/execa/types/return/result-ipc.d.ts new file mode 100644 index 0000000000..f0b7df8e65 --- /dev/null +++ b/node_modules/execa/types/return/result-ipc.d.ts @@ -0,0 +1,27 @@ +import type {FdSpecificOption} from '../arguments/specific.js'; +import type {CommonOptions, Options, StricterOptions} from '../arguments/options.js'; +import type {Message, HasIpc} from '../ipc.js'; + +// `result.ipcOutput` +// This is empty unless the `ipc` option is `true`. +// Also, this is empty if the `buffer` option is `false`. +export type ResultIpcOutput< + IsSync, + OptionsType extends CommonOptions, +> = IsSync extends true + ? [] + : ResultIpcAsync< + FdSpecificOption, + HasIpc>, + OptionsType['serialization'] + >; + +type ResultIpcAsync< + BufferOption extends boolean | undefined, + IpcEnabled extends boolean, + SerializationOption extends CommonOptions['serialization'], +> = BufferOption extends false + ? [] + : IpcEnabled extends true + ? Array> + : []; diff --git a/node_modules/execa/types/return/result-stdio.d.ts b/node_modules/execa/types/return/result-stdio.d.ts new file mode 100644 index 0000000000..9540b20fe5 --- /dev/null +++ b/node_modules/execa/types/return/result-stdio.d.ts @@ -0,0 +1,17 @@ +import type {StdioOptionNormalizedArray} from '../stdio/array.js'; +import type {CommonOptions} from '../arguments/options.js'; +import type {ResultStdioNotAll} from './result-stdout.js'; + +// `result.stdio` +export type ResultStdioArray = + MapResultStdio, OptionsType>; + +type MapResultStdio< + StdioOptionsArrayType, + OptionsType extends CommonOptions, +> = { + -readonly [FdNumber in keyof StdioOptionsArrayType]: ResultStdioNotAll< + FdNumber extends string ? FdNumber : string, + OptionsType + > +}; diff --git a/node_modules/execa/types/return/result-stdout.d.ts b/node_modules/execa/types/return/result-stdout.d.ts new file mode 100644 index 0000000000..21732ad34f --- /dev/null +++ b/node_modules/execa/types/return/result-stdout.d.ts @@ -0,0 +1,50 @@ +import type {BufferEncodingOption, BinaryEncodingOption} from '../arguments/encoding-option.js'; +import type {IsObjectFd} from '../transform/object-mode.js'; +import type {FdSpecificOption} from '../arguments/specific.js'; +import type {CommonOptions} from '../arguments/options.js'; +import type {IgnoresResultOutput} from './ignore.js'; + +// `result.stdout|stderr|stdio` +export type ResultStdioNotAll< + FdNumber extends string, + OptionsType extends CommonOptions, +> = ResultStdio; + +// `result.stdout|stderr|stdio|all` +export type ResultStdio< + MainFdNumber extends string, + ObjectFdNumber extends string, + LinesFdNumber extends string, + OptionsType extends CommonOptions, +> = ResultStdioProperty< +ObjectFdNumber, +LinesFdNumber, +IgnoresResultOutput, +OptionsType +>; + +type ResultStdioProperty< + ObjectFdNumber extends string, + LinesFdNumber extends string, + StreamOutputIgnored, + OptionsType extends CommonOptions, +> = StreamOutputIgnored extends true + ? undefined + : ResultStdioItem< + IsObjectFd, + FdSpecificOption, + OptionsType['encoding'] + >; + +type ResultStdioItem< + IsObjectResult, + LinesOption extends boolean | undefined, + Encoding extends CommonOptions['encoding'], +> = IsObjectResult extends true ? unknown[] + : Encoding extends BufferEncodingOption + ? Uint8Array + : LinesOption extends true + ? Encoding extends BinaryEncodingOption + ? string + : string[] + : string; diff --git a/node_modules/execa/types/return/result.d.ts b/node_modules/execa/types/return/result.d.ts new file mode 100644 index 0000000000..4164f0915f --- /dev/null +++ b/node_modules/execa/types/return/result.d.ts @@ -0,0 +1,203 @@ +import type {SignalConstants} from 'node:os'; +import type {Unless} from '../utils.js'; +import type {CommonOptions, Options, SyncOptions} from '../arguments/options.js'; +import type {ErrorProperties} from './final-error.js'; +import type {ResultAll} from './result-all.js'; +import type {ResultStdioArray} from './result-stdio.js'; +import type {ResultStdioNotAll} from './result-stdout.js'; +import type {ResultIpcOutput} from './result-ipc.js'; + +export declare abstract class CommonResult< + IsSync extends boolean, + OptionsType extends CommonOptions, +> { + /** + The output of the subprocess on [`stdout`](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout)). + + This is `undefined` if the `stdout` option is set to only `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`. + + This is an array if the `lines` option is `true`, or if the `stdout` option is a transform in object mode. + */ + stdout: ResultStdioNotAll<'1', OptionsType>; + + /** + The output of the subprocess on [`stderr`](https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)). + + This is `undefined` if the `stderr` option is set to only `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`. + + This is an array if the `lines` option is `true`, or if the `stderr` option is a transform in object mode. + */ + stderr: ResultStdioNotAll<'2', OptionsType>; + + /** + The output of the subprocess with `result.stdout` and `result.stderr` interleaved. + + This requires the `all` option to be `true`. + + This is `undefined` if both `stdout` and `stderr` options are set to only `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`. + + This is an array if the `lines` option is `true`, or if either the `stdout` or `stderr` option is a transform in object mode. + */ + all: ResultAll; + + /** + The output of the subprocess on `stdin`, `stdout`, `stderr` and other file descriptors. + + Items are `undefined` when their corresponding `stdio` option is set to only `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`. + + Items are arrays when their corresponding `stdio` option is a transform in object mode. + */ + stdio: ResultStdioArray; + + /** + All the messages sent by the subprocess to the current process. + + This is empty unless the `ipc` option is `true`. Also, this is empty if the `buffer` option is `false`. + */ + ipcOutput: ResultIpcOutput; + + /** + Results of the other subprocesses that were piped into this subprocess. + + This array is initially empty and is populated each time the `subprocess.pipe()` method resolves. + */ + pipedFrom: Unless; + + /** + The file and arguments that were run. + */ + command: string; + + /** + Same as `command` but escaped. + */ + escapedCommand: string; + + /** + The current directory in which the command was run. + */ + cwd: string; + + /** + Duration of the subprocess, in milliseconds. + */ + durationMs: number; + + /** + Whether the subprocess failed to run. + + When this is `true`, the result is an `ExecaError` instance with additional error-related properties. + */ + failed: boolean; + + /** + Whether the subprocess timed out due to the `timeout` option. + */ + timedOut: boolean; + + /** + Whether the subprocess was canceled using the `cancelSignal` option. + */ + isCanceled: boolean; + + /** + Whether the subprocess was canceled using both the `cancelSignal` and the `gracefulCancel` options. + */ + isGracefullyCanceled: boolean; + + /** + Whether the subprocess failed because its output was larger than the `maxBuffer` option. + */ + isMaxBuffer: boolean; + + /** + Whether the subprocess was terminated by a signal (like `SIGTERM`) sent by either: + - The current process. + - Another process. This case is [not supported on Windows](https://nodejs.org/api/process.html#signal-events). + */ + isTerminated: boolean; + + /** + Whether the subprocess was terminated by the `SIGKILL` signal sent by the `forceKillAfterDelay` option. + */ + isForcefullyTerminated: boolean; + + /** + The numeric [exit code](https://en.wikipedia.org/wiki/Exit_status) of the subprocess that was run. + + This is `undefined` when the subprocess could not be spawned or was terminated by a signal. + */ + exitCode?: number; + + /** + The name of the signal (like `SIGTERM`) that terminated the subprocess, sent by either: + - The current process. + - Another process. This case is [not supported on Windows](https://nodejs.org/api/process.html#signal-events). + + If a signal terminated the subprocess, this property is defined and included in the error message. Otherwise it is `undefined`. + */ + signal?: keyof SignalConstants; + + /** + A human-friendly description of the signal that was used to terminate the subprocess. + + If a signal terminated the subprocess, this property is defined and included in the error message. Otherwise it is `undefined`. It is also `undefined` when the signal is very uncommon which should seldomly happen. + */ + signalDescription?: string; + + /** + Error message when the subprocess failed to run. + */ + message?: string; + + /** + This is the same as `error.message` except it does not include the subprocess output. + */ + shortMessage?: string; + + /** + Original error message. This is the same as `error.message` excluding the subprocess output and some additional information added by Execa. + + This exists only in specific instances, such as during a timeout. + */ + originalMessage?: string; + + /** + Underlying error, if there is one. For example, this is set by `subprocess.kill(error)`. + + This is usually an `Error` instance. + */ + cause?: unknown; + + /** + Node.js-specific [error code](https://nodejs.org/api/errors.html#errorcode), when available. + */ + code?: string; + + // We cannot `extend Error` because `message` must be optional. So we copy its types here. + readonly name?: Error['name']; + stack?: Error['stack']; +} + +export type SuccessResult< + IsSync extends boolean = boolean, + OptionsType extends CommonOptions = CommonOptions, +> = InstanceType> & OmitErrorIfReject; + +type OmitErrorIfReject = { + [ErrorProperty in ErrorProperties]: RejectOption extends false ? unknown : never +}; + +/** +Result of a subprocess successful execution. + +When the subprocess fails, it is rejected with an `ExecaError` instead. +*/ +export type Result = SuccessResult; + +/** +Result of a subprocess successful execution. + +When the subprocess fails, it is rejected with an `ExecaError` instead. +*/ +export type SyncResult = SuccessResult; diff --git a/node_modules/execa/types/stdio/array.d.ts b/node_modules/execa/types/stdio/array.d.ts new file mode 100644 index 0000000000..b3e08871bb --- /dev/null +++ b/node_modules/execa/types/stdio/array.d.ts @@ -0,0 +1,16 @@ +import type {CommonOptions} from '../arguments/options.js'; +import type {StdinOptionCommon, StdoutStderrOptionCommon, StdioOptionsArray} from './type.js'; + +// `options.stdio`, normalized as an array +export type StdioOptionNormalizedArray = StdioOptionNormalized; + +type StdioOptionNormalized = StdioOption extends StdioOptionsArray + ? StdioOption + : StdioOption extends StdinOptionCommon + ? StdioOption extends StdoutStderrOptionCommon + ? readonly [StdioOption, StdioOption, StdioOption] + : DefaultStdioOption + : DefaultStdioOption; + +// `options.stdio` default value +type DefaultStdioOption = readonly ['pipe', 'pipe', 'pipe']; diff --git a/node_modules/execa/types/stdio/direction.d.ts b/node_modules/execa/types/stdio/direction.d.ts new file mode 100644 index 0000000000..86eded65df --- /dev/null +++ b/node_modules/execa/types/stdio/direction.d.ts @@ -0,0 +1,12 @@ +import type {CommonOptions} from '../arguments/options.js'; +import type {Intersects} from '../utils.js'; +import type {StdioSingleOptionItems, InputStdioOption} from './type.js'; +import type {FdStdioArrayOption} from './option.js'; + +// Whether `result.stdio[FdNumber]` is an input stream +export type IsInputFd< + FdNumber extends string, + OptionsType extends CommonOptions, +> = FdNumber extends '0' + ? true + : Intersects>, InputStdioOption>; diff --git a/node_modules/execa/types/stdio/option.d.ts b/node_modules/execa/types/stdio/option.d.ts new file mode 100644 index 0000000000..0fbe989be6 --- /dev/null +++ b/node_modules/execa/types/stdio/option.d.ts @@ -0,0 +1,40 @@ +import type {CommonOptions} from '../arguments/options.js'; +import type {StdioOptionNormalizedArray} from './array.js'; +import type {StandardStreams, StdioOptionCommon, StdioOptionsArray} from './type.js'; + +// `options.stdin|stdout|stderr|stdio` for a given file descriptor +export type FdStdioOption< + FdNumber extends string, + OptionsType extends CommonOptions, +> = FdStdioOptionProperty; + +type FdStdioOptionProperty< + FdNumber extends string, + OptionsType extends CommonOptions, +> = string extends FdNumber ? StdioOptionCommon + : FdNumber extends keyof StandardStreams + ? StandardStreams[FdNumber] extends keyof OptionsType + ? OptionsType[StandardStreams[FdNumber]] extends undefined + ? FdStdioArrayOption + : OptionsType[StandardStreams[FdNumber]] + : FdStdioArrayOption + : FdStdioArrayOption; + +// `options.stdio[FdNumber]`, excluding `options.stdin|stdout|stderr` +export type FdStdioArrayOption< + FdNumber extends string, + OptionsType extends CommonOptions, +> = FdStdioArrayOptionProperty>; + +type FdStdioArrayOptionProperty< + FdNumber extends string, + StdioOptionsType, +> = string extends FdNumber + ? StdioOptionCommon | undefined + : StdioOptionsType extends StdioOptionsArray + ? FdNumber extends keyof StdioOptionsType + ? StdioOptionsType[FdNumber] + : StdioOptionNormalizedArray extends StdioOptionsType + ? StdioOptionsType[number] + : undefined + : undefined; diff --git a/node_modules/execa/types/stdio/type.d.ts b/node_modules/execa/types/stdio/type.d.ts new file mode 100644 index 0000000000..c823dffd54 --- /dev/null +++ b/node_modules/execa/types/stdio/type.d.ts @@ -0,0 +1,170 @@ +import type {Readable, Writable} from 'node:stream'; +import type {ReadableStream, WritableStream, TransformStream} from 'node:stream/web'; +import type { + Not, + And, + Or, + Unless, + AndUnless, +} from '../utils.js'; +import type { + GeneratorTransform, + GeneratorTransformFull, + DuplexTransform, + WebTransform, +} from '../transform/normalize.js'; + +type IsStandardStream = FdNumber extends keyof StandardStreams ? true : false; + +export type StandardStreams = readonly ['stdin', 'stdout', 'stderr']; + +// When `options.stdin|stdout|stderr|stdio` is set to one of those values, no stream is created +export type NoStreamStdioOption = + | 'ignore' + | 'inherit' + | 'ipc' + | number + | Readable + | Writable + | Unless, undefined> + | readonly [NoStreamStdioOption]; + +// `options.stdio` when it is not an array +type SimpleStdioOption< + IsSync extends boolean, + IsExtra extends boolean, + IsArray extends boolean, +> = + | undefined + | 'pipe' + | Unless, IsArray>, IsExtra>, 'inherit'> + | Unless + | Unless; + +// Values available in both `options.stdin|stdio` and `options.stdout|stderr|stdio` +type CommonStdioOption< + IsSync extends boolean, + IsExtra extends boolean, + IsArray extends boolean, +> = + | SimpleStdioOption + | URL + | {readonly file: string; readonly append?: boolean} + | GeneratorTransform + | GeneratorTransformFull + | Unless, IsArray>, 3 | 4 | 5 | 6 | 7 | 8 | 9> + | Unless, 'ipc'> + | Unless; + +// Synchronous iterables excluding strings, Uint8Arrays and Arrays +type IterableObject = Iterable +& object +& {readonly BYTES_PER_ELEMENT?: never} +& AndUnless; + +// `process.stdin|stdout|stderr` are `Duplex` with a `fd` property. +// This ensures they can only be passed to `stdin`/`stdout`/`stderr`, based on their direction. +type ProcessStdinFd = {readonly fd?: 0}; +type ProcessStdoutStderrFd = {readonly fd?: 1 | 2}; + +// Values available only in `options.stdin|stdio` +export type InputStdioOption< + IsSync extends boolean = boolean, + IsExtra extends boolean = boolean, + IsArray extends boolean = boolean, +> = + | 0 + | Unless, Uint8Array | IterableObject> + | Unless, Readable & ProcessStdinFd> + | Unless & ProcessStdinFd) | ReadableStream>; + +// Values available only in `options.stdout|stderr|stdio` +type OutputStdioOption< + IsSync extends boolean, + IsArray extends boolean, +> = + | 1 + | 2 + | Unless, Writable & ProcessStdoutStderrFd> + | Unless; + +// `options.stdin` array items +type StdinSingleOption< + IsSync extends boolean, + IsExtra extends boolean, + IsArray extends boolean, +> = + | CommonStdioOption + | InputStdioOption; + +// `options.stdin` +export type StdinOptionCommon< + IsSync extends boolean = boolean, + IsExtra extends boolean = boolean, +> = + | StdinSingleOption + | ReadonlyArray>; + +// `options.stdin`, async +export type StdinOption = StdinOptionCommon; +// `options.stdin`, sync +export type StdinSyncOption = StdinOptionCommon; + +// `options.stdout|stderr` array items +type StdoutStderrSingleOption< + IsSync extends boolean, + IsExtra extends boolean, + IsArray extends boolean, +> = + | CommonStdioOption + | OutputStdioOption; + +// `options.stdout|stderr` +export type StdoutStderrOptionCommon< + IsSync extends boolean = boolean, + IsExtra extends boolean = boolean, +> = + | StdoutStderrSingleOption + | ReadonlyArray>; + +// `options.stdout|stderr`, async +export type StdoutStderrOption = StdoutStderrOptionCommon; +// `options.stdout|stderr`, sync +export type StdoutStderrSyncOption = StdoutStderrOptionCommon; + +// `options.stdio[3+]` +type StdioExtraOptionCommon = + | StdinOptionCommon + | StdoutStderrOptionCommon; + +// `options.stdin|stdout|stderr|stdio` array items +type StdioSingleOption< + IsSync extends boolean = boolean, + IsExtra extends boolean = boolean, + IsArray extends boolean = boolean, +> = + | StdinSingleOption + | StdoutStderrSingleOption; + +// Get `options.stdin|stdout|stderr|stdio` items if it is an array, else keep as is +export type StdioSingleOptionItems = StdioOptionType extends readonly StdioSingleOption[] + ? StdioOptionType[number] + : StdioOptionType; + +// `options.stdin|stdout|stderr|stdio` +export type StdioOptionCommon = + | StdinOptionCommon + | StdoutStderrOptionCommon; + +// `options.stdio` when it is an array +export type StdioOptionsArray = readonly [ + StdinOptionCommon, + StdoutStderrOptionCommon, + StdoutStderrOptionCommon, + ...ReadonlyArray>, +]; + +// `options.stdio` +export type StdioOptionsProperty = + | SimpleStdioOption + | StdioOptionsArray; diff --git a/node_modules/execa/types/subprocess/all.d.ts b/node_modules/execa/types/subprocess/all.d.ts new file mode 100644 index 0000000000..2ef97f001a --- /dev/null +++ b/node_modules/execa/types/subprocess/all.d.ts @@ -0,0 +1,17 @@ +import type {Readable} from 'node:stream'; +import type {IgnoresSubprocessOutput} from '../return/ignore.js'; +import type {Options} from '../arguments/options.js'; + +// `subprocess.all` +export type SubprocessAll = AllStream>; + +type AllStream = IsIgnored extends true ? undefined : Readable; + +type AllIgnored< + AllOption, + OptionsType extends Options, +> = AllOption extends true + ? IgnoresSubprocessOutput<'1', OptionsType> extends true + ? IgnoresSubprocessOutput<'2', OptionsType> + : false + : true; diff --git a/node_modules/execa/types/subprocess/stdio.d.ts b/node_modules/execa/types/subprocess/stdio.d.ts new file mode 100644 index 0000000000..15b5f8eb02 --- /dev/null +++ b/node_modules/execa/types/subprocess/stdio.d.ts @@ -0,0 +1,18 @@ +import type {StdioOptionNormalizedArray} from '../stdio/array.js'; +import type {Options} from '../arguments/options.js'; +import type {SubprocessStdioStream} from './stdout.js'; + +// `subprocess.stdio` +export type SubprocessStdioArray = MapStdioStreams, OptionsType>; + +// We cannot use mapped types because it must be compatible with Node.js `ChildProcess["stdio"]` which uses a tuple with exactly 5 items +type MapStdioStreams< + StdioOptionsArrayType, + OptionsType extends Options, +> = [ + SubprocessStdioStream<'0', OptionsType>, + SubprocessStdioStream<'1', OptionsType>, + SubprocessStdioStream<'2', OptionsType>, + '3' extends keyof StdioOptionsArrayType ? SubprocessStdioStream<'3', OptionsType> : never, + '4' extends keyof StdioOptionsArrayType ? SubprocessStdioStream<'4', OptionsType> : never, +]; diff --git a/node_modules/execa/types/subprocess/stdout.d.ts b/node_modules/execa/types/subprocess/stdout.d.ts new file mode 100644 index 0000000000..41a781cb11 --- /dev/null +++ b/node_modules/execa/types/subprocess/stdout.d.ts @@ -0,0 +1,22 @@ +import type {Readable, Writable} from 'node:stream'; +import type {IsInputFd} from '../stdio/direction.js'; +import type {IgnoresSubprocessOutput} from '../return/ignore.js'; +import type {Options} from '../arguments/options.js'; + +// `subprocess.stdin|stdout|stderr|stdio` +export type SubprocessStdioStream< + FdNumber extends string, + OptionsType extends Options, +> = SubprocessStream, OptionsType>; + +type SubprocessStream< + FdNumber extends string, + StreamResultIgnored, + OptionsType extends Options, +> = StreamResultIgnored extends true + ? null + : InputOutputStream>; + +type InputOutputStream = IsInput extends true + ? Writable + : Readable; diff --git a/node_modules/execa/types/subprocess/subprocess.d.ts b/node_modules/execa/types/subprocess/subprocess.d.ts new file mode 100644 index 0000000000..aac0551d55 --- /dev/null +++ b/node_modules/execa/types/subprocess/subprocess.d.ts @@ -0,0 +1,117 @@ +import type {ChildProcess} from 'node:child_process'; +import type {SignalConstants} from 'node:os'; +import type {Readable, Writable, Duplex} from 'node:stream'; +import type {Options} from '../arguments/options.js'; +import type {Result} from '../return/result.js'; +import type {PipableSubprocess} from '../pipe.js'; +import type { + ReadableOptions, + WritableOptions, + DuplexOptions, + SubprocessAsyncIterable, +} from '../convert.js'; +import type {IpcMethods, HasIpc} from '../ipc.js'; +import type {SubprocessStdioStream} from './stdout.js'; +import type {SubprocessStdioArray} from './stdio.js'; +import type {SubprocessAll} from './all.js'; + +type ExecaCustomSubprocess = { + /** + Process identifier ([PID](https://en.wikipedia.org/wiki/Process_identifier)). + + This is `undefined` if the subprocess failed to spawn. + */ + pid?: number; + + /** + The subprocess [`stdin`](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)) as a stream. + + This is `null` if the `stdin` option is set to `'inherit'`, `'ignore'`, `Readable` or `integer`. + */ + stdin: SubprocessStdioStream<'0', OptionsType>; + + /** + The subprocess [`stdout`](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout)) as a stream. + + This is `null` if the `stdout` option is set to `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`. + */ + stdout: SubprocessStdioStream<'1', OptionsType>; + + /** + The subprocess [`stderr`](https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)) as a stream. + + This is `null` if the `stderr` option is set to `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`. + */ + stderr: SubprocessStdioStream<'2', OptionsType>; + + /** + Stream combining/interleaving `subprocess.stdout` and `subprocess.stderr`. + + This requires the `all` option to be `true`. + + This is `undefined` if `stdout` and `stderr` options are set to `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`. + */ + all: SubprocessAll; + + /** + The subprocess `stdin`, `stdout`, `stderr` and other files descriptors as an array of streams. + + Each array item is `null` if the corresponding `stdin`, `stdout`, `stderr` or `stdio` option is set to `'inherit'`, `'ignore'`, `Stream` or `integer`, or if the `buffer` option is `false`. + */ + stdio: SubprocessStdioArray; + + /** + Sends a [signal](https://nodejs.org/api/os.html#signal-constants) to the subprocess. The default signal is the `killSignal` option. `killSignal` defaults to `SIGTERM`, which terminates the subprocess. + + This returns `false` when the signal could not be sent, for example when the subprocess has already exited. + + When an error is passed as argument, it is set to the subprocess' `error.cause`. The subprocess is then terminated with the default signal. This does not emit the [`error` event](https://nodejs.org/api/child_process.html#event-error). + + [More info.](https://nodejs.org/api/child_process.html#subprocesskillsignal) + */ + kill(signal?: keyof SignalConstants | number, error?: Error): boolean; + kill(error?: Error): boolean; + + /** + Subprocesses are [async iterables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator). They iterate over each output line. + */ + [Symbol.asyncIterator](): SubprocessAsyncIterable; + + /** + Same as `subprocess[Symbol.asyncIterator]` except options can be provided. + */ + iterable(readableOptions?: IterableOptions): SubprocessAsyncIterable; + + /** + Converts the subprocess to a readable stream. + */ + readable(readableOptions?: ReadableOptions): Readable; + + /** + Converts the subprocess to a writable stream. + */ + writable(writableOptions?: WritableOptions): Writable; + + /** + Converts the subprocess to a duplex stream. + */ + duplex(duplexOptions?: DuplexOptions): Duplex; +} +& IpcMethods, OptionsType['serialization']> +& PipableSubprocess; + +/** +[`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with additional methods and properties. +*/ +export type Subprocess = + & Omit> + & ExecaCustomSubprocess; + +/** +The return value of all asynchronous methods is both: +- the subprocess. +- a `Promise` either resolving with its successful `result`, or rejecting with its `error`. +*/ +export type ResultPromise = + & Subprocess + & Promise>; diff --git a/node_modules/execa/types/transform/normalize.d.ts b/node_modules/execa/types/transform/normalize.d.ts new file mode 100644 index 0000000000..89a3348fae --- /dev/null +++ b/node_modules/execa/types/transform/normalize.d.ts @@ -0,0 +1,57 @@ +import type {TransformStream} from 'node:stream/web'; +import type {Duplex} from 'node:stream'; +import type {Unless} from '../utils.js'; + +// `options.std*: Generator` +// @todo Use `string`, `Uint8Array` or `unknown` for both the argument and the return type, based on whether `encoding: 'buffer'` and `objectMode: true` are used. +// See https://github.com/sindresorhus/execa/issues/694 +export type GeneratorTransform = (chunk: unknown) => +| Unless> +| Generator; +type GeneratorFinal = () => +| Unless> +| Generator; + +export type TransformCommon = { + /** + If `true`, allow `transformOptions.transform` and `transformOptions.final` to return any type, not just `string` or `Uint8Array`. + */ + readonly objectMode?: boolean; +}; + +/** +A transform or an array of transforms can be passed to the `stdin`, `stdout`, `stderr` or `stdio` option. + +A transform is either a generator function or a plain object with the following members. +*/ +export type GeneratorTransformFull = { + /** + Map or filter the input or output of the subprocess. + */ + readonly transform: GeneratorTransform; + + /** + Create additional lines after the last one. + */ + readonly final?: GeneratorFinal; + + /** + If `true`, iterate over arbitrary chunks of `Uint8Array`s instead of line `string`s. + */ + readonly binary?: boolean; + + /** + If `true`, keep newlines in each `line` argument. Also, this allows multiple `yield`s to produces a single line. + */ + readonly preserveNewlines?: boolean; +} & TransformCommon; + +// `options.std*: Duplex` +export type DuplexTransform = { + readonly transform: Duplex; +} & TransformCommon; + +// `options.std*: TransformStream` +export type WebTransform = { + readonly transform: TransformStream; +} & TransformCommon; diff --git a/node_modules/execa/types/transform/object-mode.d.ts b/node_modules/execa/types/transform/object-mode.d.ts new file mode 100644 index 0000000000..8c48e2cfd8 --- /dev/null +++ b/node_modules/execa/types/transform/object-mode.d.ts @@ -0,0 +1,21 @@ +import type {StdioSingleOptionItems} from '../stdio/type.js'; +import type {FdStdioOption} from '../stdio/option.js'; +import type {CommonOptions} from '../arguments/options.js'; +import type {DuplexTransform, TransformCommon} from './normalize.js'; + +// Whether a file descriptor is in object mode +// I.e. whether `result.stdout|stderr|stdio|all` is an array of `unknown` due to `objectMode: true` +export type IsObjectFd< + FdNumber extends string, + OptionsType extends CommonOptions, +> = IsObjectStdioOption>; + +type IsObjectStdioOption = IsObjectStdioSingleOption>; + +type IsObjectStdioSingleOption = StdioSingleOptionType extends TransformCommon + ? BooleanObjectMode + : StdioSingleOptionType extends DuplexTransform + ? StdioSingleOptionType['transform']['readableObjectMode'] + : false; + +type BooleanObjectMode = ObjectModeOption extends true ? true : false; diff --git a/node_modules/execa/types/utils.d.ts b/node_modules/execa/types/utils.d.ts new file mode 100644 index 0000000000..23871cf80e --- /dev/null +++ b/node_modules/execa/types/utils.d.ts @@ -0,0 +1,13 @@ +export type Not = Value extends true ? false : true; + +export type And = First extends true ? Second : false; + +export type Or = First extends true ? true : Second; + +export type Unless = Condition extends true ? ElseValue : ThenValue; + +export type AndUnless = Condition extends true ? ElseValue : ThenValue; + +// Whether any of T's union element is the same as one of U's union element. +// `&` does not work here. +export type Intersects = true extends (T extends U ? true : false) ? true : false; diff --git a/node_modules/execa/types/verbose.d.ts b/node_modules/execa/types/verbose.d.ts new file mode 100644 index 0000000000..28ad4bdf66 --- /dev/null +++ b/node_modules/execa/types/verbose.d.ts @@ -0,0 +1,98 @@ +import type {FdGenericOption} from './arguments/specific.js'; +import type {Options, SyncOptions} from './arguments/options.js'; +import type {Result, SyncResult} from './return/result.js'; + +type VerboseOption = FdGenericOption< +| 'none' +| 'short' +| 'full' +| VerboseFunction +>; + +type VerboseFunction = (verboseLine: string, verboseObject: MinimalVerboseObject) => string | void; + +type GenericVerboseObject = { + /** + Event type. This can be: + - `'command'`: subprocess start + - `'output'`: `stdout`/`stderr` output + - `'ipc'`: IPC output + - `'error'`: subprocess failure + - `'duration'`: subprocess success or failure + */ + type: 'command' | 'output' | 'ipc' | 'error' | 'duration'; + + /** + Depending on `verboseObject.type`, this is: + - `'command'`: the `result.escapedCommand` + - `'output'`: one line from `result.stdout` or `result.stderr` + - `'ipc'`: one IPC message from `result.ipcOutput` + - `'error'`: the `error.shortMessage` + - `'duration'`: the `result.durationMs` + */ + message: string; + + /** + The file and arguments that were run. This is the same as `result.escapedCommand`. + */ + escapedCommand: string; + + /** + Serial number identifying the subprocess within the current process. It is incremented from `'0'`. + + This is helpful when multiple subprocesses are running at the same time. + + This is similar to a [PID](https://en.wikipedia.org/wiki/Process_identifier) except it has no maximum limit, which means it never repeats. Also, it is usually shorter. + */ + commandId: string; + + /** + Event date/time. + */ + timestamp: Date; + + /** + Whether another subprocess is piped into this subprocess. This is `false` when `result.pipedFrom` is empty. + */ + piped: boolean; +}; + +type MinimalVerboseObject = GenericVerboseObject & { + // We cannot use the `CommonOptions` type because it would make this type recursive + options: object; + result?: never; +}; + +/** +Subprocess event object, for logging purpose, using the `verbose` option and `execa()`. +*/ +export type VerboseObject = GenericVerboseObject & { + /** + The options passed to the subprocess. + */ + options: Options; + + /** + Subprocess result. + + This is `undefined` if `verboseObject.type` is `'command'`, `'output'` or `'ipc'`. + */ + result?: Result; +}; + +/** +Subprocess event object, for logging purpose, using the `verbose` option and `execaSync()`. +*/ +export type SyncVerboseObject = GenericVerboseObject & { + /** + The options passed to the subprocess. + */ + options: SyncOptions; + + /** + Subprocess result. + + This is `undefined` if `verboseObject.type` is `'command'`, `'output'` or `'ipc'`. + */ + result?: SyncResult; +}; diff --git a/node_modules/foreground-child/node_modules/signal-exit/LICENSE.txt b/node_modules/foreground-child/node_modules/signal-exit/LICENSE.txt deleted file mode 100644 index 954f2fa823..0000000000 --- a/node_modules/foreground-child/node_modules/signal-exit/LICENSE.txt +++ /dev/null @@ -1,16 +0,0 @@ -The ISC License - -Copyright (c) 2015-2023 Benjamin Coe, Isaac Z. Schlueter, and Contributors - -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice -appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE -LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/foreground-child/node_modules/signal-exit/README.md b/node_modules/foreground-child/node_modules/signal-exit/README.md deleted file mode 100644 index c55cd45ee3..0000000000 --- a/node_modules/foreground-child/node_modules/signal-exit/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# signal-exit - -When you want to fire an event no matter how a process exits: - -- reaching the end of execution. -- explicitly having `process.exit(code)` called. -- having `process.kill(pid, sig)` called. -- receiving a fatal signal from outside the process - -Use `signal-exit`. - -```js -// Hybrid module, either works -import { onExit } from 'signal-exit' -// or: -// const { onExit } = require('signal-exit') - -onExit((code, signal) => { - console.log('process exited!', code, signal) -}) -``` - -## API - -`remove = onExit((code, signal) => {}, options)` - -The return value of the function is a function that will remove -the handler. - -Note that the function _only_ fires for signals if the signal -would cause the process to exit. That is, there are no other -listeners, and it is a fatal signal. - -If the global `process` object is not suitable for this purpose -(ie, it's unset, or doesn't have an `emit` method, etc.) then the -`onExit` function is a no-op that returns a no-op `remove` method. - -### Options - -- `alwaysLast`: Run this handler after any other signal or exit - handlers. This causes `process.emit` to be monkeypatched. - -### Capturing Signal Exits - -If the handler returns an exact boolean `true`, and the exit is a -due to signal, then the signal will be considered handled, and -will _not_ trigger a synthetic `process.kill(process.pid, -signal)` after firing the `onExit` handlers. - -In this case, it your responsibility as the caller to exit with a -signal (for example, by calling `process.kill()`) if you wish to -preserve the same exit status that would otherwise have occurred. -If you do not, then the process will likely exit gracefully with -status 0 at some point, assuming that no other terminating signal -or other exit trigger occurs. - -Prior to calling handlers, the `onExit` machinery is unloaded, so -any subsequent exits or signals will not be handled, even if the -signal is captured and the exit is thus prevented. - -Note that numeric code exits may indicate that the process is -already committed to exiting, for example due to a fatal -exception or unhandled promise rejection, and so there is no way to -prevent it safely. - -### Browser Fallback - -The `'signal-exit/browser'` module is the same fallback shim that -just doesn't do anything, but presents the same function -interface. - -Patches welcome to add something that hooks onto -`window.onbeforeunload` or similar, but it might just not be a -thing that makes sense there. diff --git a/node_modules/foreground-child/node_modules/signal-exit/package.json b/node_modules/foreground-child/node_modules/signal-exit/package.json deleted file mode 100644 index ac176cec74..0000000000 --- a/node_modules/foreground-child/node_modules/signal-exit/package.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "name": "signal-exit", - "version": "4.1.0", - "description": "when you want to fire an event no matter how a process exits.", - "main": "./dist/cjs/index.js", - "module": "./dist/mjs/index.js", - "browser": "./dist/mjs/browser.js", - "types": "./dist/mjs/index.d.ts", - "exports": { - ".": { - "import": { - "types": "./dist/mjs/index.d.ts", - "default": "./dist/mjs/index.js" - }, - "require": { - "types": "./dist/cjs/index.d.ts", - "default": "./dist/cjs/index.js" - } - }, - "./signals": { - "import": { - "types": "./dist/mjs/signals.d.ts", - "default": "./dist/mjs/signals.js" - }, - "require": { - "types": "./dist/cjs/signals.d.ts", - "default": "./dist/cjs/signals.js" - } - }, - "./browser": { - "import": { - "types": "./dist/mjs/browser.d.ts", - "default": "./dist/mjs/browser.js" - }, - "require": { - "types": "./dist/cjs/browser.d.ts", - "default": "./dist/cjs/browser.js" - } - } - }, - "files": [ - "dist" - ], - "engines": { - "node": ">=14" - }, - "repository": { - "type": "git", - "url": "https://github.com/tapjs/signal-exit.git" - }, - "keywords": [ - "signal", - "exit" - ], - "author": "Ben Coe ", - "license": "ISC", - "devDependencies": { - "@types/cross-spawn": "^6.0.2", - "@types/node": "^18.15.11", - "@types/signal-exit": "^3.0.1", - "@types/tap": "^15.0.8", - "c8": "^7.13.0", - "prettier": "^2.8.6", - "tap": "^16.3.4", - "ts-node": "^10.9.1", - "typedoc": "^0.23.28", - "typescript": "^5.0.2" - }, - "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "preprepare": "rm -rf dist", - "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh", - "pretest": "npm run prepare", - "presnap": "npm run prepare", - "test": "c8 tap", - "snap": "c8 tap", - "format": "prettier --write . --loglevel warn", - "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" - }, - "prettier": { - "semi": false, - "printWidth": 75, - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "jsxSingleQuote": false, - "bracketSameLine": true, - "arrowParens": "avoid", - "endOfLine": "lf" - }, - "tap": { - "coverage": false, - "jobs": 1, - "node-arg": [ - "--no-warnings", - "--loader", - "ts-node/esm" - ], - "ts": false - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } -} diff --git a/node_modules/get-stream/buffer-stream.js b/node_modules/get-stream/buffer-stream.js deleted file mode 100644 index 2dd75745df..0000000000 --- a/node_modules/get-stream/buffer-stream.js +++ /dev/null @@ -1,52 +0,0 @@ -'use strict'; -const {PassThrough: PassThroughStream} = require('stream'); - -module.exports = options => { - options = {...options}; - - const {array} = options; - let {encoding} = options; - const isBuffer = encoding === 'buffer'; - let objectMode = false; - - if (array) { - objectMode = !(encoding || isBuffer); - } else { - encoding = encoding || 'utf8'; - } - - if (isBuffer) { - encoding = null; - } - - const stream = new PassThroughStream({objectMode}); - - if (encoding) { - stream.setEncoding(encoding); - } - - let length = 0; - const chunks = []; - - stream.on('data', chunk => { - chunks.push(chunk); - - if (objectMode) { - length = chunks.length; - } else { - length += chunk.length; - } - }); - - stream.getBufferedValue = () => { - if (array) { - return chunks; - } - - return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); - }; - - stream.getBufferedLength = () => length; - - return stream; -}; diff --git a/node_modules/get-stream/index.d.ts b/node_modules/get-stream/index.d.ts deleted file mode 100644 index 9485b2b6d8..0000000000 --- a/node_modules/get-stream/index.d.ts +++ /dev/null @@ -1,105 +0,0 @@ -/// -import {Stream} from 'stream'; - -declare class MaxBufferErrorClass extends Error { - readonly name: 'MaxBufferError'; - constructor(); -} - -declare namespace getStream { - interface Options { - /** - Maximum length of the returned string. If it exceeds this value before the stream ends, the promise will be rejected with a `MaxBufferError` error. - - @default Infinity - */ - readonly maxBuffer?: number; - } - - interface OptionsWithEncoding extends Options { - /** - [Encoding](https://nodejs.org/api/buffer.html#buffer_buffer) of the incoming stream. - - @default 'utf8' - */ - readonly encoding?: EncodingType; - } - - type MaxBufferError = MaxBufferErrorClass; -} - -declare const getStream: { - /** - Get the `stream` as a string. - - @returns A promise that resolves when the end event fires on the stream, indicating that there is no more data to be read. The stream is switched to flowing mode. - - @example - ``` - import * as fs from 'fs'; - import getStream = require('get-stream'); - - (async () => { - const stream = fs.createReadStream('unicorn.txt'); - - console.log(await getStream(stream)); - // ,,))))))));, - // __)))))))))))))), - // \|/ -\(((((''''((((((((. - // -*-==//////(('' . `)))))), - // /|\ ))| o ;-. '((((( ,(, - // ( `| / ) ;))))' ,_))^;(~ - // | | | ,))((((_ _____------~~~-. %,;(;(>';'~ - // o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ - // ; ''''```` `: `:::|\,__,%% );`'; ~ - // | _ ) / `:|`----' `-' - // ______/\/~ | / / - // /~;;.____/;;' / ___--,-( `;;;/ - // / // _;______;'------~~~~~ /;;/\ / - // // | | / ; \;;,\ - // (<_ | ; /',/-----' _> - // \_| ||_ //~;~~~~~~~~~ - // `\_| (,~~ - // \~\ - // ~~ - })(); - ``` - */ - (stream: Stream, options?: getStream.OptionsWithEncoding): Promise; - - /** - Get the `stream` as a buffer. - - It honors the `maxBuffer` option as above, but it refers to byte length rather than string length. - */ - buffer( - stream: Stream, - options?: getStream.Options - ): Promise; - - /** - Get the `stream` as an array of values. - - It honors both the `maxBuffer` and `encoding` options. The behavior changes slightly based on the encoding chosen: - - - When `encoding` is unset, it assumes an [object mode stream](https://nodesource.com/blog/understanding-object-streams/) and collects values emitted from `stream` unmodified. In this case `maxBuffer` refers to the number of items in the array (not the sum of their sizes). - - When `encoding` is set to `buffer`, it collects an array of buffers. `maxBuffer` refers to the summed byte lengths of every buffer in the array. - - When `encoding` is set to anything else, it collects an array of strings. `maxBuffer` refers to the summed character lengths of every string in the array. - */ - array( - stream: Stream, - options?: getStream.Options - ): Promise; - array( - stream: Stream, - options: getStream.OptionsWithEncoding<'buffer'> - ): Promise; - array( - stream: Stream, - options: getStream.OptionsWithEncoding - ): Promise; - - MaxBufferError: typeof MaxBufferErrorClass; -}; - -export = getStream; diff --git a/node_modules/get-stream/index.js b/node_modules/get-stream/index.js deleted file mode 100644 index 1c5d028609..0000000000 --- a/node_modules/get-stream/index.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict'; -const {constants: BufferConstants} = require('buffer'); -const stream = require('stream'); -const {promisify} = require('util'); -const bufferStream = require('./buffer-stream'); - -const streamPipelinePromisified = promisify(stream.pipeline); - -class MaxBufferError extends Error { - constructor() { - super('maxBuffer exceeded'); - this.name = 'MaxBufferError'; - } -} - -async function getStream(inputStream, options) { - if (!inputStream) { - throw new Error('Expected a stream'); - } - - options = { - maxBuffer: Infinity, - ...options - }; - - const {maxBuffer} = options; - const stream = bufferStream(options); - - await new Promise((resolve, reject) => { - const rejectPromise = error => { - // Don't retrieve an oversized buffer. - if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) { - error.bufferedData = stream.getBufferedValue(); - } - - reject(error); - }; - - (async () => { - try { - await streamPipelinePromisified(inputStream, stream); - resolve(); - } catch (error) { - rejectPromise(error); - } - })(); - - stream.on('data', () => { - if (stream.getBufferedLength() > maxBuffer) { - rejectPromise(new MaxBufferError()); - } - }); - }); - - return stream.getBufferedValue(); -} - -module.exports = getStream; -module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'}); -module.exports.array = (stream, options) => getStream(stream, {...options, array: true}); -module.exports.MaxBufferError = MaxBufferError; diff --git a/node_modules/get-stream/package.json b/node_modules/get-stream/package.json index 0c084ac923..31ae171ed0 100644 --- a/node_modules/get-stream/package.json +++ b/node_modules/get-stream/package.json @@ -1,7 +1,7 @@ { "name": "get-stream", - "version": "6.0.1", - "description": "Get a stream as a string, buffer, or array", + "version": "9.0.1", + "description": "Get a stream as a string, Buffer, ArrayBuffer or array", "license": "MIT", "repository": "sindresorhus/get-stream", "funding": "https://github.com/sponsors/sindresorhus", @@ -10,16 +10,23 @@ "email": "sindresorhus@gmail.com", "url": "https://sindresorhus.com" }, + "type": "module", + "exports": { + "types": "./source/index.d.ts", + "browser": "./source/exports.js", + "default": "./source/index.js" + }, + "sideEffects": false, "engines": { - "node": ">=10" + "node": ">=18" }, "scripts": { - "test": "xo && ava && tsd" + "benchmark": "node benchmarks/index.js", + "test": "xo && ava && tsd --typings=source/index.d.ts --files=source/index.test-d.ts" }, "files": [ - "index.js", - "index.d.ts", - "buffer-stream.js" + "source", + "!*.test-d.ts" ], "keywords": [ "get", @@ -34,14 +41,20 @@ "consume", "readable", "readablestream", - "array", - "object" + "object", + "concat" ], + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, "devDependencies": { - "@types/node": "^14.0.27", - "ava": "^2.4.0", - "into-stream": "^5.0.0", - "tsd": "^0.13.1", - "xo": "^0.24.0" + "@types/node": "^20.8.9", + "ava": "^6.1.2", + "onetime": "^7.0.0", + "precise-now": "^3.0.0", + "stream-json": "^1.8.0", + "tsd": "^0.29.0", + "xo": "^0.58.0" } } diff --git a/node_modules/get-stream/readme.md b/node_modules/get-stream/readme.md index 70b01fd16c..cafb003ac3 100644 --- a/node_modules/get-stream/readme.md +++ b/node_modules/get-stream/readme.md @@ -1,124 +1,303 @@ # get-stream -> Get a stream as a string, buffer, or array +> Get a stream as a string, Buffer, ArrayBuffer or array + +## Features + +- Works in any JavaScript environment ([Node.js](#nodejs-streams), [browsers](#browser-support), etc.). +- Supports [text streams](#getstreamstream-options), [binary streams](#getstreamasbufferstream-options) and [object streams](#getstreamasarraystream-options). +- Supports [async iterables](#async-iterables). +- Can set a [maximum stream size](#maxbuffer). +- Returns [partially read data](#errors) when the stream errors. +- [Fast](#benchmarks). ## Install -``` -$ npm install get-stream +```sh +npm install get-stream ``` ## Usage +### Node.js streams + +```js +import fs from 'node:fs'; +import getStream from 'get-stream'; + +const stream = fs.createReadStream('unicorn.txt'); + +console.log(await getStream(stream)); +/* + ,,))))))));, + __)))))))))))))), +\|/ -\(((((''''((((((((. +-*-==//////(('' . `)))))), +/|\ ))| o ;-. '((((( ,(, + ( `| / ) ;))))' ,_))^;(~ + | | | ,))((((_ _____------~~~-. %,;(;(>';'~ + o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ + ; ''''```` `: `:::|\,__,%% );`'; ~ + | _ ) / `:|`----' `-' + ______/\/~ | / / + /~;;.____/;;' / ___--,-( `;;;/ + / // _;______;'------~~~~~ /;;/\ / + // | | / ; \;;,\ + (<_ | ; /',/-----' _> + \_| ||_ //~;~~~~~~~~~ + `\_| (,~~ + \~\ + ~~ +*/ +``` + +### Web streams + ```js -const fs = require('fs'); -const getStream = require('get-stream'); - -(async () => { - const stream = fs.createReadStream('unicorn.txt'); - - console.log(await getStream(stream)); - /* - ,,))))))));, - __)))))))))))))), - \|/ -\(((((''''((((((((. - -*-==//////(('' . `)))))), - /|\ ))| o ;-. '((((( ,(, - ( `| / ) ;))))' ,_))^;(~ - | | | ,))((((_ _____------~~~-. %,;(;(>';'~ - o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ - ; ''''```` `: `:::|\,__,%% );`'; ~ - | _ ) / `:|`----' `-' - ______/\/~ | / / - /~;;.____/;;' / ___--,-( `;;;/ - / // _;______;'------~~~~~ /;;/\ / - // | | / ; \;;,\ - (<_ | ; /',/-----' _> - \_| ||_ //~;~~~~~~~~~ - `\_| (,~~ - \~\ - ~~ - */ -})(); +import getStream from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStream(readableStream)); +``` + +This works in any browser, even [the ones](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#browser_compatibility) not supporting `ReadableStream.values()` yet. + +### Async iterables + +```js +import {opendir} from 'node:fs/promises'; +import {getStreamAsArray} from 'get-stream'; + +const asyncIterable = await opendir(directory); +console.log(await getStreamAsArray(asyncIterable)); ``` ## API -The methods returns a promise that resolves when the `end` event fires on the stream, indicating that there is no more data to be read. The stream is switched to flowing mode. +The following methods read the stream's contents and return it as a promise. ### getStream(stream, options?) -Get the `stream` as a string. +`stream`: [`stream.Readable`](https://nodejs.org/api/stream.html#class-streamreadable), [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream), or [`AsyncIterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols)\ +`options`: [`Options`](#options) -#### options +Get the given `stream` as a string. -Type: `object` +### getStreamAsBuffer(stream, options?) -##### encoding +Get the given `stream` as a Node.js [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer). -Type: `string`\ -Default: `'utf8'` +```js +import {getStreamAsBuffer} from 'get-stream'; -[Encoding](https://nodejs.org/api/buffer.html#buffer_buffer) of the incoming stream. +const stream = fs.createReadStream('unicorn.png'); +console.log(await getStreamAsBuffer(stream)); +``` + +### getStreamAsArrayBuffer(stream, options?) + +Get the given `stream` as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). + +```js +import {getStreamAsArrayBuffer} from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStreamAsArrayBuffer(readableStream)); +``` + +### getStreamAsArray(stream, options?) + +Get the given `stream` as an array. Unlike [other methods](#api), this supports [streams of objects](https://nodejs.org/api/stream.html#object-mode). + +```js +import {getStreamAsArray} from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStreamAsArray(readableStream)); +``` + +#### options + +Type: `object` ##### maxBuffer Type: `number`\ Default: `Infinity` -Maximum length of the returned string. If it exceeds this value before the stream ends, the promise will be rejected with a `getStream.MaxBufferError` error. +Maximum length of the stream. If exceeded, the promise will be rejected with a `MaxBufferError`. + +Depending on the [method](#api), the length is measured with [`string.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length), [`buffer.length`](https://nodejs.org/api/buffer.html#buflength), [`arrayBuffer.byteLength`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength) or [`array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length). -### getStream.buffer(stream, options?) +## Errors -Get the `stream` as a buffer. +If the stream errors, the returned promise will be rejected with the `error`. Any contents already read from the stream will be set to `error.bufferedData`, which is a `string`, a `Buffer`, an `ArrayBuffer` or an array depending on the [method used](#api). -It honors the `maxBuffer` option as above, but it refers to byte length rather than string length. +```js +import getStream from 'get-stream'; + +try { + await getStream(streamThatErrorsAtTheEnd('unicorn')); +} catch (error) { + console.log(error.bufferedData); + //=> 'unicorn' +} +``` -### getStream.array(stream, options?) +## Browser support -Get the `stream` as an array of values. +For this module to work in browsers, a bundler must be used that either: +- Supports the [`exports.browser`](https://nodejs.org/api/packages.html#community-conditions-definitions) field in `package.json` +- Strips or ignores `node:*` imports -It honors both the `maxBuffer` and `encoding` options. The behavior changes slightly based on the encoding chosen: +Most bundlers (such as [Webpack](https://webpack.js.org/guides/package-exports/#target-environment)) support either of these. -- When `encoding` is unset, it assumes an [object mode stream](https://nodesource.com/blog/understanding-object-streams/) and collects values emitted from `stream` unmodified. In this case `maxBuffer` refers to the number of items in the array (not the sum of their sizes). +Additionally, browsers support [web streams](#web-streams) and [async iterables](#async-iterables), but not [Node.js streams](#nodejs-streams). -- When `encoding` is set to `buffer`, it collects an array of buffers. `maxBuffer` refers to the summed byte lengths of every buffer in the array. +## Tips -- When `encoding` is set to anything else, it collects an array of strings. `maxBuffer` refers to the summed character lengths of every string in the array. +### Alternatives -## Errors +If you do not need the [`maxBuffer`](#maxbuffer) option, [`error.bufferedData`](#errors), nor browser support, you can use the following methods instead of this package. -If the input stream emits an `error` event, the promise will be rejected with the error. The buffered data will be attached to the `bufferedData` property of the error. +#### [`streamConsumers.text()`](https://nodejs.org/api/webstreams.html#streamconsumerstextstream) ```js -(async () => { - try { - await getStream(streamThatErrorsAtTheEnd('unicorn')); - } catch (error) { - console.log(error.bufferedData); - //=> 'unicorn' - } -})() +import fs from 'node:fs'; +import {text} from 'node:stream/consumers'; + +const stream = fs.createReadStream('unicorn.txt', {encoding: 'utf8'}); +console.log(await text(stream)) ``` +#### [`streamConsumers.buffer()`](https://nodejs.org/api/webstreams.html#streamconsumersbufferstream) + +```js +import {buffer} from 'node:stream/consumers'; + +console.log(await buffer(stream)) +``` + +#### [`streamConsumers.arrayBuffer()`](https://nodejs.org/api/webstreams.html#streamconsumersarraybufferstream) + +```js +import {arrayBuffer} from 'node:stream/consumers'; + +console.log(await arrayBuffer(stream)) +``` + +#### [`readable.toArray()`](https://nodejs.org/api/stream.html#readabletoarrayoptions) + +```js +console.log(await stream.toArray()) +``` + +#### [`Array.fromAsync()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync) + +If your [environment supports it](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync#browser_compatibility): + +```js +console.log(await Array.fromAsync(stream)) +``` + +### Non-UTF-8 encoding + +When all of the following conditions apply: + - [`getStream()`](#getstreamstream-options) is used (as opposed to [`getStreamAsBuffer()`](#getstreamasbufferstream-options) or [`getStreamAsArrayBuffer()`](#getstreamasarraybufferstream-options)) + - The stream is binary (not text) + - The stream's encoding is not UTF-8 (for example, it is UTF-16, hexadecimal, or Base64) + +Then the stream must be decoded using a transform stream like [`TextDecoderStream`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoderStream) or [`b64`](https://github.com/hapijs/b64). + +```js +import getStream from 'get-stream'; + +const textDecoderStream = new TextDecoderStream('utf-16le'); +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStream(readableStream.pipeThrough(textDecoderStream))); +``` + +### Blobs + +[`getStreamAsArrayBuffer()`](#getstreamasarraybufferstream-options) can be used to create [Blobs](https://developer.mozilla.org/en-US/docs/Web/API/Blob). + +```js +import {getStreamAsArrayBuffer} from 'get-stream'; + +const stream = fs.createReadStream('unicorn.txt'); +console.log(new Blob([await getStreamAsArrayBuffer(stream)])); +``` + +### JSON streaming + +[`getStreamAsArray()`](#getstreamasarraystream-options) can be combined with JSON streaming utilities to parse JSON incrementally. + +```js +import fs from 'node:fs'; +import {compose as composeStreams} from 'node:stream'; +import {getStreamAsArray} from 'get-stream'; +import streamJson from 'stream-json'; +import streamJsonArray from 'stream-json/streamers/StreamArray.js'; + +const stream = fs.createReadStream('big-array-of-objects.json'); +console.log(await getStreamAsArray( + composeStreams(stream, streamJson.parser(), streamJsonArray.streamArray()), +)); +``` + +## Benchmarks + +### Node.js stream (100 MB, binary) + +- `getStream()`: 142ms +- `text()`: 139ms +- `getStreamAsBuffer()`: 106ms +- `buffer()`: 83ms +- `getStreamAsArrayBuffer()`: 105ms +- `arrayBuffer()`: 81ms +- `getStreamAsArray()`: 24ms +- `stream.toArray()`: 21ms + +### Node.js stream (100 MB, text) + +- `getStream()`: 90ms +- `text()`: 89ms +- `getStreamAsBuffer()`: 127ms +- `buffer()`: 192ms +- `getStreamAsArrayBuffer()`: 129ms +- `arrayBuffer()`: 195ms +- `getStreamAsArray()`: 89ms +- `stream.toArray()`: 90ms + +### Web ReadableStream (100 MB, binary) + +- `getStream()`: 223ms +- `text()`: 221ms +- `getStreamAsBuffer()`: 182ms +- `buffer()`: 153ms +- `getStreamAsArrayBuffer()`: 171ms +- `arrayBuffer()`: 155ms +- `getStreamAsArray()`: 83ms + +### Web ReadableStream (100 MB, text) + +- `getStream()`: 141ms +- `text()`: 139ms +- `getStreamAsBuffer()`: 91ms +- `buffer()`: 80ms +- `getStreamAsArrayBuffer()`: 89ms +- `arrayBuffer()`: 81ms +- `getStreamAsArray()`: 21ms + +[Benchmarks' source file](benchmarks/index.js). + ## FAQ ### How is this different from [`concat-stream`](https://github.com/maxogden/concat-stream)? -This module accepts a stream instead of being one and returns a promise instead of using a callback. The API is simpler and it only supports returning a string, buffer, or array. It doesn't have a fragile type inference. You explicitly choose what you want. And it doesn't depend on the huge `readable-stream` package. +This module accepts a stream instead of being one and returns a promise instead of using a callback. The API is simpler and it only supports returning a string, `Buffer`, an `ArrayBuffer` or an array. It doesn't have a fragile type inference. You explicitly choose what you want. And it doesn't depend on the huge `readable-stream` package. ## Related - [get-stdin](https://github.com/sindresorhus/get-stdin) - Get stdin as a string or buffer - ---- - -
- - Get professional support for this package with a Tidelift subscription - -
- - Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. -
-
+- [into-stream](https://github.com/sindresorhus/into-stream) - The opposite of this package diff --git a/node_modules/get-stream/source/array-buffer.js b/node_modules/get-stream/source/array-buffer.js new file mode 100644 index 0000000000..fb90e93fd5 --- /dev/null +++ b/node_modules/get-stream/source/array-buffer.js @@ -0,0 +1,84 @@ +import {getStreamContents} from './contents.js'; +import {noop, throwObjectStream, getLengthProperty} from './utils.js'; + +export async function getStreamAsArrayBuffer(stream, options) { + return getStreamContents(stream, arrayBufferMethods, options); +} + +const initArrayBuffer = () => ({contents: new ArrayBuffer(0)}); + +const useTextEncoder = chunk => textEncoder.encode(chunk); +const textEncoder = new TextEncoder(); + +const useUint8Array = chunk => new Uint8Array(chunk); + +const useUint8ArrayWithOffset = chunk => new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength); + +const truncateArrayBufferChunk = (convertedChunk, chunkSize) => convertedChunk.slice(0, chunkSize); + +// `contents` is an increasingly growing `Uint8Array`. +const addArrayBufferChunk = (convertedChunk, {contents, length: previousLength}, length) => { + const newContents = hasArrayBufferResize() ? resizeArrayBuffer(contents, length) : resizeArrayBufferSlow(contents, length); + new Uint8Array(newContents).set(convertedChunk, previousLength); + return newContents; +}; + +// Without `ArrayBuffer.resize()`, `contents` size is always a power of 2. +// This means its last bytes are zeroes (not stream data), which need to be +// trimmed at the end with `ArrayBuffer.slice()`. +const resizeArrayBufferSlow = (contents, length) => { + if (length <= contents.byteLength) { + return contents; + } + + const arrayBuffer = new ArrayBuffer(getNewContentsLength(length)); + new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0); + return arrayBuffer; +}; + +// With `ArrayBuffer.resize()`, `contents` size matches exactly the size of +// the stream data. It does not include extraneous zeroes to trim at the end. +// The underlying `ArrayBuffer` does allocate a number of bytes that is a power +// of 2, but those bytes are only visible after calling `ArrayBuffer.resize()`. +const resizeArrayBuffer = (contents, length) => { + if (length <= contents.maxByteLength) { + contents.resize(length); + return contents; + } + + const arrayBuffer = new ArrayBuffer(length, {maxByteLength: getNewContentsLength(length)}); + new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0); + return arrayBuffer; +}; + +// Retrieve the closest `length` that is both >= and a power of 2 +const getNewContentsLength = length => SCALE_FACTOR ** Math.ceil(Math.log(length) / Math.log(SCALE_FACTOR)); + +const SCALE_FACTOR = 2; + +const finalizeArrayBuffer = ({contents, length}) => hasArrayBufferResize() ? contents : contents.slice(0, length); + +// `ArrayBuffer.slice()` is slow. When `ArrayBuffer.resize()` is available +// (Node >=20.0.0, Safari >=16.4 and Chrome), we can use it instead. +// eslint-disable-next-line no-warning-comments +// TODO: remove after dropping support for Node 20. +// eslint-disable-next-line no-warning-comments +// TODO: use `ArrayBuffer.transferToFixedLength()` instead once it is available +const hasArrayBufferResize = () => 'resize' in ArrayBuffer.prototype; + +const arrayBufferMethods = { + init: initArrayBuffer, + convertChunk: { + string: useTextEncoder, + buffer: useUint8Array, + arrayBuffer: useUint8Array, + dataView: useUint8ArrayWithOffset, + typedArray: useUint8ArrayWithOffset, + others: throwObjectStream, + }, + getSize: getLengthProperty, + truncateChunk: truncateArrayBufferChunk, + addChunk: addArrayBufferChunk, + getFinalChunk: noop, + finalize: finalizeArrayBuffer, +}; diff --git a/node_modules/get-stream/source/array.js b/node_modules/get-stream/source/array.js new file mode 100644 index 0000000000..6523a46103 --- /dev/null +++ b/node_modules/get-stream/source/array.js @@ -0,0 +1,32 @@ +import {getStreamContents} from './contents.js'; +import {identity, noop, getContentsProperty} from './utils.js'; + +export async function getStreamAsArray(stream, options) { + return getStreamContents(stream, arrayMethods, options); +} + +const initArray = () => ({contents: []}); + +const increment = () => 1; + +const addArrayChunk = (convertedChunk, {contents}) => { + contents.push(convertedChunk); + return contents; +}; + +const arrayMethods = { + init: initArray, + convertChunk: { + string: identity, + buffer: identity, + arrayBuffer: identity, + dataView: identity, + typedArray: identity, + others: identity, + }, + getSize: increment, + truncateChunk: noop, + addChunk: addArrayChunk, + getFinalChunk: noop, + finalize: getContentsProperty, +}; diff --git a/node_modules/get-stream/source/buffer.js b/node_modules/get-stream/source/buffer.js new file mode 100644 index 0000000000..875bd1b01f --- /dev/null +++ b/node_modules/get-stream/source/buffer.js @@ -0,0 +1,19 @@ +import {getStreamAsArrayBuffer} from './array-buffer.js'; + +export async function getStreamAsBuffer(stream, options) { + if (!('Buffer' in globalThis)) { + throw new Error('getStreamAsBuffer() is only supported in Node.js'); + } + + try { + return arrayBufferToNodeBuffer(await getStreamAsArrayBuffer(stream, options)); + } catch (error) { + if (error.bufferedData !== undefined) { + error.bufferedData = arrayBufferToNodeBuffer(error.bufferedData); + } + + throw error; + } +} + +const arrayBufferToNodeBuffer = arrayBuffer => globalThis.Buffer.from(arrayBuffer); diff --git a/node_modules/get-stream/source/contents.js b/node_modules/get-stream/source/contents.js new file mode 100644 index 0000000000..6825e15122 --- /dev/null +++ b/node_modules/get-stream/source/contents.js @@ -0,0 +1,121 @@ +import {getAsyncIterable} from './stream.js'; + +export const getStreamContents = async (stream, {init, convertChunk, getSize, truncateChunk, addChunk, getFinalChunk, finalize}, {maxBuffer = Number.POSITIVE_INFINITY} = {}) => { + const asyncIterable = getAsyncIterable(stream); + + const state = init(); + state.length = 0; + + try { + for await (const chunk of asyncIterable) { + const chunkType = getChunkType(chunk); + const convertedChunk = convertChunk[chunkType](chunk, state); + appendChunk({ + convertedChunk, + state, + getSize, + truncateChunk, + addChunk, + maxBuffer, + }); + } + + appendFinalChunk({ + state, + convertChunk, + getSize, + truncateChunk, + addChunk, + getFinalChunk, + maxBuffer, + }); + return finalize(state); + } catch (error) { + const normalizedError = typeof error === 'object' && error !== null ? error : new Error(error); + normalizedError.bufferedData = finalize(state); + throw normalizedError; + } +}; + +const appendFinalChunk = ({state, getSize, truncateChunk, addChunk, getFinalChunk, maxBuffer}) => { + const convertedChunk = getFinalChunk(state); + if (convertedChunk !== undefined) { + appendChunk({ + convertedChunk, + state, + getSize, + truncateChunk, + addChunk, + maxBuffer, + }); + } +}; + +const appendChunk = ({convertedChunk, state, getSize, truncateChunk, addChunk, maxBuffer}) => { + const chunkSize = getSize(convertedChunk); + const newLength = state.length + chunkSize; + + if (newLength <= maxBuffer) { + addNewChunk(convertedChunk, state, addChunk, newLength); + return; + } + + const truncatedChunk = truncateChunk(convertedChunk, maxBuffer - state.length); + + if (truncatedChunk !== undefined) { + addNewChunk(truncatedChunk, state, addChunk, maxBuffer); + } + + throw new MaxBufferError(); +}; + +const addNewChunk = (convertedChunk, state, addChunk, newLength) => { + state.contents = addChunk(convertedChunk, state, newLength); + state.length = newLength; +}; + +const getChunkType = chunk => { + const typeOfChunk = typeof chunk; + + if (typeOfChunk === 'string') { + return 'string'; + } + + if (typeOfChunk !== 'object' || chunk === null) { + return 'others'; + } + + if (globalThis.Buffer?.isBuffer(chunk)) { + return 'buffer'; + } + + const prototypeName = objectToString.call(chunk); + + if (prototypeName === '[object ArrayBuffer]') { + return 'arrayBuffer'; + } + + if (prototypeName === '[object DataView]') { + return 'dataView'; + } + + if ( + Number.isInteger(chunk.byteLength) + && Number.isInteger(chunk.byteOffset) + && objectToString.call(chunk.buffer) === '[object ArrayBuffer]' + ) { + return 'typedArray'; + } + + return 'others'; +}; + +const {toString: objectToString} = Object.prototype; + +export class MaxBufferError extends Error { + name = 'MaxBufferError'; + + constructor() { + super('maxBuffer exceeded'); + } +} diff --git a/node_modules/get-stream/source/exports.js b/node_modules/get-stream/source/exports.js new file mode 100644 index 0000000000..43c2dd4ba9 --- /dev/null +++ b/node_modules/get-stream/source/exports.js @@ -0,0 +1,5 @@ +export {getStreamAsArray} from './array.js'; +export {getStreamAsArrayBuffer} from './array-buffer.js'; +export {getStreamAsBuffer} from './buffer.js'; +export {getStreamAsString as default} from './string.js'; +export {MaxBufferError} from './contents.js'; diff --git a/node_modules/get-stream/source/index.d.ts b/node_modules/get-stream/source/index.d.ts new file mode 100644 index 0000000000..3f8ecff737 --- /dev/null +++ b/node_modules/get-stream/source/index.d.ts @@ -0,0 +1,121 @@ +import {type Readable} from 'node:stream'; +import {type Buffer} from 'node:buffer'; + +export class MaxBufferError extends Error { + readonly name: 'MaxBufferError'; + constructor(); +} + +// eslint-disable-next-line @typescript-eslint/ban-types +type TextStreamItem = string | Buffer | ArrayBuffer | ArrayBufferView; +export type AnyStream = Readable | ReadableStream | AsyncIterable; + +export type Options = { + /** + Maximum length of the stream. If exceeded, the promise will be rejected with a `MaxBufferError`. + + Depending on the [method](#api), the length is measured with [`string.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length), [`buffer.length`](https://nodejs.org/api/buffer.html#buflength), [`arrayBuffer.byteLength`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength) or [`array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length). + + @default Infinity + */ + readonly maxBuffer?: number; +}; + +/** +Get the given `stream` as a string. + +@returns The stream's contents as a promise. + +@example +``` +import fs from 'node:fs'; +import getStream from 'get-stream'; + +const stream = fs.createReadStream('unicorn.txt'); + +console.log(await getStream(stream)); +// ,,))))))));, +// __)))))))))))))), +// \|/ -\(((((''''((((((((. +// -*-==//////(('' . `)))))), +// /|\ ))| o ;-. '((((( ,(, +// ( `| / ) ;))))' ,_))^;(~ +// | | | ,))((((_ _____------~~~-. %,;(;(>';'~ +// o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ +// ; ''''```` `: `:::|\,__,%% );`'; ~ +// | _ ) / `:|`----' `-' +// ______/\/~ | / / +// /~;;.____/;;' / ___--,-( `;;;/ +// / // _;______;'------~~~~~ /;;/\ / +// // | | / ; \;;,\ +// (<_ | ; /',/-----' _> +// \_| ||_ //~;~~~~~~~~~ +// `\_| (,~~ +// \~\ +// ~~ +``` + +@example +``` +import getStream from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStream(readableStream)); +``` + +@example +``` +import {opendir} from 'node:fs/promises'; +import {getStreamAsArray} from 'get-stream'; + +const asyncIterable = await opendir(directory); +console.log(await getStreamAsArray(asyncIterable)); +``` +*/ +export default function getStream(stream: AnyStream, options?: Options): Promise; + +/** +Get the given `stream` as a Node.js [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer). + +@returns The stream's contents as a promise. + +@example +``` +import {getStreamAsBuffer} from 'get-stream'; + +const stream = fs.createReadStream('unicorn.png'); +console.log(await getStreamAsBuffer(stream)); +``` +*/ +// eslint-disable-next-line @typescript-eslint/ban-types +export function getStreamAsBuffer(stream: AnyStream, options?: Options): Promise; + +/** +Get the given `stream` as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). + +@returns The stream's contents as a promise. + +@example +``` +import {getStreamAsArrayBuffer} from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStreamAsArrayBuffer(readableStream)); +``` +*/ +export function getStreamAsArrayBuffer(stream: AnyStream, options?: Options): Promise; + +/** +Get the given `stream` as an array. Unlike [other methods](#api), this supports [streams of objects](https://nodejs.org/api/stream.html#object-mode). + +@returns The stream's contents as a promise. + +@example +``` +import {getStreamAsArray} from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStreamAsArray(readableStream)); +``` +*/ +export function getStreamAsArray(stream: AnyStream, options?: Options): Promise; diff --git a/node_modules/get-stream/source/index.js b/node_modules/get-stream/source/index.js new file mode 100644 index 0000000000..61f3ccb9f8 --- /dev/null +++ b/node_modules/get-stream/source/index.js @@ -0,0 +1,13 @@ +import {on} from 'node:events'; +import {finished} from 'node:stream/promises'; +import {nodeImports} from './stream.js'; + +Object.assign(nodeImports, {on, finished}); + +export { + default, + getStreamAsArray, + getStreamAsArrayBuffer, + getStreamAsBuffer, + MaxBufferError, +} from './exports.js'; diff --git a/node_modules/get-stream/source/stream.js b/node_modules/get-stream/source/stream.js new file mode 100644 index 0000000000..446925bc80 --- /dev/null +++ b/node_modules/get-stream/source/stream.js @@ -0,0 +1,65 @@ +import {isReadableStream} from 'is-stream'; +import {asyncIterator} from '@sec-ant/readable-stream/ponyfill'; + +export const getAsyncIterable = stream => { + if (isReadableStream(stream, {checkOpen: false}) && nodeImports.on !== undefined) { + return getStreamIterable(stream); + } + + if (typeof stream?.[Symbol.asyncIterator] === 'function') { + return stream; + } + + // `ReadableStream[Symbol.asyncIterator]` support is missing in multiple browsers, so we ponyfill it + if (toString.call(stream) === '[object ReadableStream]') { + return asyncIterator.call(stream); + } + + throw new TypeError('The first argument must be a Readable, a ReadableStream, or an async iterable.'); +}; + +const {toString} = Object.prototype; + +// The default iterable for Node.js streams does not allow for multiple readers at once, so we re-implement it +const getStreamIterable = async function * (stream) { + const controller = new AbortController(); + const state = {}; + handleStreamEnd(stream, controller, state); + + try { + for await (const [chunk] of nodeImports.on(stream, 'data', {signal: controller.signal})) { + yield chunk; + } + } catch (error) { + // Stream failure, for example due to `stream.destroy(error)` + if (state.error !== undefined) { + throw state.error; + // `error` event directly emitted on stream + } else if (!controller.signal.aborted) { + throw error; + // Otherwise, stream completed successfully + } + // The `finally` block also runs when the caller throws, for example due to the `maxBuffer` option + } finally { + stream.destroy(); + } +}; + +const handleStreamEnd = async (stream, controller, state) => { + try { + await nodeImports.finished(stream, { + cleanup: true, + readable: true, + writable: false, + error: false, + }); + } catch (error) { + state.error = error; + } finally { + controller.abort(); + } +}; + +// Loaded by the Node entrypoint, but not by the browser one. +// This prevents using dynamic imports. +export const nodeImports = {}; diff --git a/node_modules/get-stream/source/string.js b/node_modules/get-stream/source/string.js new file mode 100644 index 0000000000..1bdb3909b7 --- /dev/null +++ b/node_modules/get-stream/source/string.js @@ -0,0 +1,41 @@ +import {getStreamContents} from './contents.js'; +import { + identity, + getContentsProperty, + throwObjectStream, + getLengthProperty, +} from './utils.js'; + +export async function getStreamAsString(stream, options) { + return getStreamContents(stream, stringMethods, options); +} + +const initString = () => ({contents: '', textDecoder: new TextDecoder()}); + +const useTextDecoder = (chunk, {textDecoder}) => textDecoder.decode(chunk, {stream: true}); + +const addStringChunk = (convertedChunk, {contents}) => contents + convertedChunk; + +const truncateStringChunk = (convertedChunk, chunkSize) => convertedChunk.slice(0, chunkSize); + +const getFinalStringChunk = ({textDecoder}) => { + const finalChunk = textDecoder.decode(); + return finalChunk === '' ? undefined : finalChunk; +}; + +const stringMethods = { + init: initString, + convertChunk: { + string: identity, + buffer: useTextDecoder, + arrayBuffer: useTextDecoder, + dataView: useTextDecoder, + typedArray: useTextDecoder, + others: throwObjectStream, + }, + getSize: getLengthProperty, + truncateChunk: truncateStringChunk, + addChunk: addStringChunk, + getFinalChunk: getFinalStringChunk, + finalize: getContentsProperty, +}; diff --git a/node_modules/get-stream/source/utils.js b/node_modules/get-stream/source/utils.js new file mode 100644 index 0000000000..bbf94a80d5 --- /dev/null +++ b/node_modules/get-stream/source/utils.js @@ -0,0 +1,11 @@ +export const identity = value => value; + +export const noop = () => undefined; + +export const getContentsProperty = ({contents}) => contents; + +export const throwObjectStream = chunk => { + throw new Error(`Streams in object mode are not supported: ${String(chunk)}`); +}; + +export const getLengthProperty = convertedChunk => convertedChunk.length; diff --git a/node_modules/human-signals/LICENSE b/node_modules/human-signals/LICENSE index 642f59b66d..ba6ed1c259 100644 --- a/node_modules/human-signals/LICENSE +++ b/node_modules/human-signals/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2022 ehmicky + Copyright 2025 ehmicky Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/node_modules/human-signals/README.md b/node_modules/human-signals/README.md index 9526edaf59..ab79ecc832 100644 --- a/node_modules/human-signals/README.md +++ b/node_modules/human-signals/README.md @@ -16,16 +16,6 @@ this includes: - [default actions](#action), including whether they [can be prevented](#forced) - whether the signal is [supported](#supported) by the current OS -# Hire me - -Please -[reach out](https://www.linkedin.com/feed/update/urn:li:activity:7018596298127781890/) -if you're looking for a Node.js API or CLI engineer (10 years of experience). -Most recently I have been [Netlify Build](https://github.com/netlify/build)'s -and [Netlify Plugins](https://www.netlify.com/products/build/plugins/)' -technical lead for 2.5 years. I am available for full-time remote positions in -either US or EU time zones. - # Example ```js @@ -60,7 +50,7 @@ console.log(signalsByNumber[8]) npm install human-signals ``` -This package works in Node.js >=14.18.0. +This package works in Node.js >=18.18.0. This is an ES module. It must be loaded using [an `import` or `import()` statement](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c), @@ -166,13 +156,16 @@ Thanks go to our wonderful contributors: - - - - + + + + + + +

ehmicky

💻 🎨 🤔 📖

electrovir

💻
ehmicky
ehmicky

💻 🎨 🤔 📖
electrovir
electrovir

💻
Felix Zedén Yverås
Felix Zedén Yverås

💻 ⚠️
- + diff --git a/node_modules/human-signals/build/src/main.d.ts b/node_modules/human-signals/build/src/main.d.ts index 864d501ad8..8764b1af4b 100644 --- a/node_modules/human-signals/build/src/main.d.ts +++ b/node_modules/human-signals/build/src/main.d.ts @@ -11,14 +11,145 @@ export type SignalStandard = 'ansi' | 'posix' | 'bsd' | 'systemv' | 'other' /** * Standard name of the signal, for example 'SIGINT'. */ -export type SignalName = `SIG${string}` +export type SignalName = + | 'SIGHUP' + | 'SIGINT' + | 'SIGQUIT' + | 'SIGILL' + | 'SIGTRAP' + | 'SIGABRT' + | 'SIGIOT' + | 'SIGBUS' + | 'SIGEMT' + | 'SIGFPE' + | 'SIGKILL' + | 'SIGUSR1' + | 'SIGSEGV' + | 'SIGUSR2' + | 'SIGPIPE' + | 'SIGALRM' + | 'SIGTERM' + | 'SIGSTKFLT' + | 'SIGCHLD' + | 'SIGCLD' + | 'SIGCONT' + | 'SIGSTOP' + | 'SIGTSTP' + | 'SIGTTIN' + | 'SIGBREAK' + | 'SIGTTOU' + | 'SIGURG' + | 'SIGXCPU' + | 'SIGXFSZ' + | 'SIGVTALRM' + | 'SIGPROF' + | 'SIGWINCH' + | 'SIGIO' + | 'SIGPOLL' + | 'SIGINFO' + | 'SIGPWR' + | 'SIGSYS' + | 'SIGUNUSED' + | 'SIGRT1' + | 'SIGRT2' + | 'SIGRT3' + | 'SIGRT4' + | 'SIGRT5' + | 'SIGRT6' + | 'SIGRT7' + | 'SIGRT8' + | 'SIGRT9' + | 'SIGRT10' + | 'SIGRT11' + | 'SIGRT12' + | 'SIGRT13' + | 'SIGRT14' + | 'SIGRT15' + | 'SIGRT16' + | 'SIGRT17' + | 'SIGRT18' + | 'SIGRT19' + | 'SIGRT20' + | 'SIGRT21' + | 'SIGRT22' + | 'SIGRT23' + | 'SIGRT24' + | 'SIGRT25' + | 'SIGRT26' + | 'SIGRT27' + | 'SIGRT28' + | 'SIGRT29' + | 'SIGRT30' + | 'SIGRT31' /** * Code number of the signal, for example 2. * While most number are cross-platform, some are different between different * OS. */ -export type SignalNumber = number +export type SignalNumber = + | 1 + | 2 + | 3 + | 4 + | 5 + | 6 + | 7 + | 8 + | 9 + | 10 + | 11 + | 12 + | 13 + | 14 + | 15 + | 16 + | 17 + | 18 + | 19 + | 20 + | 21 + | 22 + | 23 + | 24 + | 25 + | 26 + | 27 + | 28 + | 29 + | 30 + | 31 + | 34 + | 35 + | 36 + | 37 + | 38 + | 39 + | 40 + | 41 + | 42 + | 43 + | 44 + | 45 + | 46 + | 47 + | 48 + | 49 + | 50 + | 51 + | 52 + | 53 + | 54 + | 55 + | 56 + | 57 + | 58 + | 59 + | 60 + | 61 + | 62 + | 63 + | 64 export interface Signal { /** @@ -65,9 +196,11 @@ export interface Signal { /** * Object whose keys are signal names and values are signal objects. */ -export declare const signalsByName: { [signalName: SignalName]: Signal } +export declare const signalsByName: { [SignalNameType in SignalName]: Signal } /** * Object whose keys are signal numbers and values are signal objects. */ -export declare const signalsByNumber: { [signalNumber: SignalNumber]: Signal } +export declare const signalsByNumber: { + [SignalNumberType in SignalNumber]: Signal +} diff --git a/node_modules/human-signals/build/src/main.js b/node_modules/human-signals/build/src/main.js index e17b7db85f..1c97801f92 100644 --- a/node_modules/human-signals/build/src/main.js +++ b/node_modules/human-signals/build/src/main.js @@ -7,7 +7,7 @@ import{getSignals}from"./signals.js"; const getSignalsByName=()=>{ const signals=getSignals(); -return Object.fromEntries(signals.map(getSignalByName)); +return Object.fromEntries(signals.map(getSignalByName)) }; const getSignalByName=({ @@ -29,16 +29,16 @@ const getSignalsByNumber=()=>{ const signals=getSignals(); const length=SIGRTMAX+1; const signalsA=Array.from({length},(value,number)=> -getSignalByNumber(number,signals)); - -return Object.assign({},...signalsA); +getSignalByNumber(number,signals) +); +return Object.assign({},...signalsA) }; const getSignalByNumber=(number,signals)=>{ const signal=findSignalByNumber(number,signals); if(signal===undefined){ -return{}; +return{} } const{name,description,supported,action,forced,standard}=signal; @@ -52,7 +52,7 @@ action, forced, standard } -}; +} }; @@ -61,10 +61,10 @@ const findSignalByNumber=(number,signals)=>{ const signal=signals.find(({name})=>constants.signals[name]===number); if(signal!==undefined){ -return signal; +return signal } -return signals.find((signalA)=>signalA.number===number); +return signals.find((signalA)=>signalA.number===number) }; export const signalsByNumber=getSignalsByNumber(); \ No newline at end of file diff --git a/node_modules/human-signals/build/src/realtime.js b/node_modules/human-signals/build/src/realtime.js index d049d81bec..76ab69dd2b 100644 --- a/node_modules/human-signals/build/src/realtime.js +++ b/node_modules/human-signals/build/src/realtime.js @@ -1,7 +1,7 @@ export const getRealtimeSignals=()=>{ const length=SIGRTMAX-SIGRTMIN+1; -return Array.from({length},getRealtimeSignal); +return Array.from({length},getRealtimeSignal) }; const getRealtimeSignal=(value,index)=>({ diff --git a/node_modules/human-signals/build/src/signals.js b/node_modules/human-signals/build/src/signals.js index a596503181..14e4c730b4 100644 --- a/node_modules/human-signals/build/src/signals.js +++ b/node_modules/human-signals/build/src/signals.js @@ -8,7 +8,7 @@ import{getRealtimeSignals}from"./realtime.js"; export const getSignals=()=>{ const realtimeSignals=getRealtimeSignals(); const signals=[...SIGNALS,...realtimeSignals].map(normalizeSignal); -return signals; +return signals }; @@ -30,5 +30,5 @@ signals:{[name]:constantSignal} }=constants; const supported=constantSignal!==undefined; const number=supported?constantSignal:defaultNumber; -return{name,number,description,supported,action,forced,standard}; +return{name,number,description,supported,action,forced,standard} }; \ No newline at end of file diff --git a/node_modules/human-signals/package.json b/node_modules/human-signals/package.json index e10e06b57d..86f35fb5be 100644 --- a/node_modules/human-signals/package.json +++ b/node_modules/human-signals/package.json @@ -1,6 +1,6 @@ { "name": "human-signals", - "version": "4.3.1", + "version": "8.0.1", "type": "module", "exports": { "types": "./build/src/main.d.ts", @@ -42,7 +42,10 @@ ], "license": "Apache-2.0", "homepage": "https://www.github.com/ehmicky/human-signals", - "repository": "ehmicky/human-signals", + "repository": { + "type": "git", + "url": "git+https://github.com/ehmicky/human-signals.git" + }, "bugs": { "url": "https://github.com/ehmicky/human-signals/issues" }, @@ -51,11 +54,13 @@ "lib": "src" }, "devDependencies": { - "@ehmicky/dev-tasks": "^2.0.71", - "ajv": "^8.12.0", - "test-each": "^5.7.1" + "@ehmicky/dev-tasks": "^3.0.33", + "@ehmicky/eslint-config": "^20.0.31", + "@ehmicky/prettier-config": "^1.0.6", + "ajv": "^8.17.1", + "test-each": "^7.0.1" }, "engines": { - "node": ">=14.18.0" + "node": ">=18.18.0" } } diff --git a/node_modules/is-plain-obj/index.d.ts b/node_modules/is-plain-obj/index.d.ts new file mode 100644 index 0000000000..3794c42e44 --- /dev/null +++ b/node_modules/is-plain-obj/index.d.ts @@ -0,0 +1,35 @@ +/** +Check if a value is a plain object. + +An object is plain if it's created by either `{}`, `new Object()`, or `Object.create(null)`. + +@example +``` +import isPlainObject from 'is-plain-obj'; +import {runInNewContext} from 'node:vm'; + +isPlainObject({foo: 'bar'}); +//=> true + +isPlainObject(new Object()); +//=> true + +isPlainObject(Object.create(null)); +//=> true + +// This works across realms +isPlainObject(runInNewContext('({})')); +//=> true + +isPlainObject([1, 2, 3]); +//=> false + +class Unicorn {} +isPlainObject(new Unicorn()); +//=> false + +isPlainObject(Math); +//=> false +``` +*/ +export default function isPlainObject(value: unknown): value is Record; diff --git a/node_modules/is-plain-obj/index.js b/node_modules/is-plain-obj/index.js new file mode 100644 index 0000000000..92555c3d39 --- /dev/null +++ b/node_modules/is-plain-obj/index.js @@ -0,0 +1,8 @@ +export default function isPlainObject(value) { + if (typeof value !== 'object' || value === null) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value); +} diff --git a/node_modules/is-plain-obj/license b/node_modules/is-plain-obj/license new file mode 100644 index 0000000000..fa7ceba3eb --- /dev/null +++ b/node_modules/is-plain-obj/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/onetime/package.json b/node_modules/is-plain-obj/package.json similarity index 61% rename from node_modules/onetime/package.json rename to node_modules/is-plain-obj/package.json index 367a963495..a92cf625a9 100644 --- a/node_modules/onetime/package.json +++ b/node_modules/is-plain-obj/package.json @@ -1,9 +1,9 @@ { - "name": "onetime", - "version": "6.0.0", - "description": "Ensure a function is only called once", + "name": "is-plain-obj", + "version": "4.1.0", + "description": "Check if a value is a plain object", "license": "MIT", - "repository": "sindresorhus/onetime", + "repository": "sindresorhus/is-plain-obj", "funding": "https://github.com/sponsors/sindresorhus", "author": { "name": "Sindre Sorhus", @@ -23,20 +23,16 @@ "index.d.ts" ], "keywords": [ - "once", - "function", - "one", - "onetime", - "func", - "fn", - "single", - "call", - "called", - "prevent" + "object", + "is", + "check", + "test", + "type", + "plain", + "vanilla", + "pure", + "simple" ], - "dependencies": { - "mimic-fn": "^4.0.0" - }, "devDependencies": { "ava": "^3.15.0", "tsd": "^0.14.0", diff --git a/node_modules/is-plain-obj/readme.md b/node_modules/is-plain-obj/readme.md new file mode 100644 index 0000000000..28de6fb55f --- /dev/null +++ b/node_modules/is-plain-obj/readme.md @@ -0,0 +1,58 @@ +# is-plain-obj + +> Check if a value is a plain object + +An object is plain if it's created by either `{}`, `new Object()`, or `Object.create(null)`. + +## Install + +``` +$ npm install is-plain-obj +``` + +## Usage + +```js +import isPlainObject from 'is-plain-obj'; +import {runInNewContext} from 'node:vm'; + +isPlainObject({foo: 'bar'}); +//=> true + +isPlainObject(new Object()); +//=> true + +isPlainObject(Object.create(null)); +//=> true + +// This works across realms +isPlainObject(runInNewContext('({})')); +//=> true + +isPlainObject([1, 2, 3]); +//=> false + +class Unicorn {} +isPlainObject(new Unicorn()); +//=> false + +isPlainObject(Math); +//=> false +``` + +## Related + +- [is-obj](https://github.com/sindresorhus/is-obj) - Check if a value is an object +- [is](https://github.com/sindresorhus/is) - Type check values + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
diff --git a/node_modules/is-stream/index.d.ts b/node_modules/is-stream/index.d.ts index df994e096a..7cdaf03c7b 100644 --- a/node_modules/is-stream/index.d.ts +++ b/node_modules/is-stream/index.d.ts @@ -1,11 +1,20 @@ import { - Stream, - Writable as WritableStream, - Readable as ReadableStream, - Duplex as DuplexStream, - Transform as TransformStream, + type Stream, + type Writable as WritableStream, + type Readable as ReadableStream, + type Duplex as DuplexStream, + type Transform as TransformStream, } from 'node:stream'; +export type Options = { + /** + When this option is `true`, the method returns `false` if the stream has already been closed. + + @default true + */ + checkOpen?: boolean; +}; + /** @returns Whether `stream` is a [`Stream`](https://nodejs.org/api/stream.html#stream_stream). @@ -21,10 +30,10 @@ isStream({}); //=> false ``` */ -export function isStream(stream: unknown): stream is Stream; +export function isStream(stream: unknown, options?: Options): stream is Stream; /** -@returns Whether `stream` is a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable). +@returns Whether `stream` is a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable), an [`http.OutgoingMessage`](https://nodejs.org/api/http.html#class-httpoutgoingmessage), an [`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse) or an [`http.ClientRequest`](https://nodejs.org/api/http.html#class-httpserverresponse). @example ``` @@ -35,10 +44,10 @@ isWritableStream(fs.createWriteStrem('unicorn.txt')); //=> true ``` */ -export function isWritableStream(stream: unknown): stream is WritableStream; +export function isWritableStream(stream: unknown, options?: Options): stream is WritableStream; /** -@returns Whether `stream` is a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable). +@returns Whether `stream` is a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable) or an [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage). @example ``` @@ -49,7 +58,7 @@ isReadableStream(fs.createReadStream('unicorn.png')); //=> true ``` */ -export function isReadableStream(stream: unknown): stream is ReadableStream; +export function isReadableStream(stream: unknown, options?: Options): stream is ReadableStream; /** @returns Whether `stream` is a [`stream.Duplex`](https://nodejs.org/api/stream.html#stream_class_stream_duplex). @@ -63,7 +72,7 @@ isDuplexStream(new DuplexStream()); //=> true ``` */ -export function isDuplexStream(stream: unknown): stream is DuplexStream; +export function isDuplexStream(stream: unknown, options?: Options): stream is DuplexStream; /** @returns Whether `stream` is a [`stream.Transform`](https://nodejs.org/api/stream.html#stream_class_stream_transform). @@ -78,4 +87,4 @@ isTransformStream(StringifyStream()); //=> true ``` */ -export function isTransformStream(stream: unknown): stream is TransformStream; +export function isTransformStream(stream: unknown, options?: Options): stream is TransformStream; diff --git a/node_modules/is-stream/index.js b/node_modules/is-stream/index.js index 887e601e02..d51dce24a5 100644 --- a/node_modules/is-stream/index.js +++ b/node_modules/is-stream/index.js @@ -1,29 +1,37 @@ -export function isStream(stream) { +export function isStream(stream, {checkOpen = true} = {}) { return stream !== null && typeof stream === 'object' + && (stream.writable || stream.readable || !checkOpen || (stream.writable === undefined && stream.readable === undefined)) && typeof stream.pipe === 'function'; } -export function isWritableStream(stream) { - return isStream(stream) - && stream.writable !== false - && typeof stream._write === 'function' - && typeof stream._writableState === 'object'; +export function isWritableStream(stream, {checkOpen = true} = {}) { + return isStream(stream, {checkOpen}) + && (stream.writable || !checkOpen) + && typeof stream.write === 'function' + && typeof stream.end === 'function' + && typeof stream.writable === 'boolean' + && typeof stream.writableObjectMode === 'boolean' + && typeof stream.destroy === 'function' + && typeof stream.destroyed === 'boolean'; } -export function isReadableStream(stream) { - return isStream(stream) - && stream.readable !== false - && typeof stream._read === 'function' - && typeof stream._readableState === 'object'; +export function isReadableStream(stream, {checkOpen = true} = {}) { + return isStream(stream, {checkOpen}) + && (stream.readable || !checkOpen) + && typeof stream.read === 'function' + && typeof stream.readable === 'boolean' + && typeof stream.readableObjectMode === 'boolean' + && typeof stream.destroy === 'function' + && typeof stream.destroyed === 'boolean'; } -export function isDuplexStream(stream) { - return isWritableStream(stream) - && isReadableStream(stream); +export function isDuplexStream(stream, options) { + return isWritableStream(stream, options) + && isReadableStream(stream, options); } -export function isTransformStream(stream) { - return isDuplexStream(stream) +export function isTransformStream(stream, options) { + return isDuplexStream(stream, options) && typeof stream._transform === 'function'; } diff --git a/node_modules/is-stream/package.json b/node_modules/is-stream/package.json index e970c7296e..8d5c427f25 100644 --- a/node_modules/is-stream/package.json +++ b/node_modules/is-stream/package.json @@ -1,6 +1,6 @@ { "name": "is-stream", - "version": "3.0.0", + "version": "4.0.1", "description": "Check if something is a Node.js stream", "license": "MIT", "repository": "sindresorhus/is-stream", @@ -11,9 +11,13 @@ "url": "https://sindresorhus.com" }, "type": "module", - "exports": "./index.js", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "scripts": { "test": "xo && ava && tsd" @@ -35,10 +39,10 @@ "is" ], "devDependencies": { - "@types/node": "^16.4.13", - "ava": "^3.15.0", - "tempy": "^1.0.1", - "tsd": "^0.17.0", - "xo": "^0.44.0" + "@types/node": "^20.11.19", + "ava": "^5.3.1", + "tempy": "^3.1.0", + "tsd": "^0.30.5", + "xo": "^0.57.0" } } diff --git a/node_modules/is-stream/readme.md b/node_modules/is-stream/readme.md index c6f8c1b2cb..c70a41c497 100644 --- a/node_modules/is-stream/readme.md +++ b/node_modules/is-stream/readme.md @@ -4,8 +4,8 @@ ## Install -``` -$ npm install is-stream +```sh +npm install is-stream ``` ## Usage @@ -23,38 +23,35 @@ isStream({}); ## API -### isStream(stream) +### isStream(stream, options?) Returns a `boolean` for whether it's a [`Stream`](https://nodejs.org/api/stream.html#stream_stream). -#### isWritableStream(stream) +### isWritableStream(stream, options?) -Returns a `boolean` for whether it's a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable). +Returns a `boolean` for whether it's a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable), an [`http.OutgoingMessage`](https://nodejs.org/api/http.html#class-httpoutgoingmessage), an [`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse) or an [`http.ClientRequest`](https://nodejs.org/api/http.html#class-httpserverresponse). -#### isReadableStream(stream) +### isReadableStream(stream, options?) -Returns a `boolean` for whether it's a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable). +Returns a `boolean` for whether it's a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable) or an [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage). -#### isDuplexStream(stream) +### isDuplexStream(stream, options?) Returns a `boolean` for whether it's a [`stream.Duplex`](https://nodejs.org/api/stream.html#stream_class_stream_duplex). -#### isTransformStream(stream) +### isTransformStream(stream, options?) Returns a `boolean` for whether it's a [`stream.Transform`](https://nodejs.org/api/stream.html#stream_class_stream_transform). +### Options + +#### checkOpen + +Type: `boolean`\ +Default: `true` + +When this option is `true`, the method returns `false` if the stream has already been closed. + ## Related - [is-file-stream](https://github.com/jamestalmage/is-file-stream) - Detect if a stream is a file stream - ---- - -
- - Get professional support for this package with a Tidelift subscription - -
- - Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. -
-
diff --git a/node_modules/merge-stream/README.md b/node_modules/merge-stream/README.md deleted file mode 100644 index 0d54841152..0000000000 --- a/node_modules/merge-stream/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# merge-stream - -Merge (interleave) a bunch of streams. - -[![build status](https://secure.travis-ci.org/grncdr/merge-stream.svg?branch=master)](http://travis-ci.org/grncdr/merge-stream) - -## Synopsis - -```javascript -var stream1 = new Stream(); -var stream2 = new Stream(); - -var merged = mergeStream(stream1, stream2); - -var stream3 = new Stream(); -merged.add(stream3); -merged.isEmpty(); -//=> false -``` - -## Description - -This is adapted from [event-stream](https://github.com/dominictarr/event-stream) separated into a new module, using Streams3. - -## API - -### `mergeStream` - -Type: `function` - -Merges an arbitrary number of streams. Returns a merged stream. - -#### `merged.add` - -A method to dynamically add more sources to the stream. The argument supplied to `add` can be either a source or an array of sources. - -#### `merged.isEmpty` - -A method that tells you if the merged stream is empty. - -When a stream is "empty" (aka. no sources were added), it could not be returned to a gulp task. - -So, we could do something like this: - -```js -stream = require('merge-stream')(); -// Something like a loop to add some streams to the merge stream -// stream.add(streamA); -// stream.add(streamB); -return stream.isEmpty() ? null : stream; -``` - -## Gulp example - -An example use case for **merge-stream** is to combine parts of a task in a project's **gulpfile.js** like this: - -```js -const gulp = require('gulp'); -const htmlValidator = require('gulp-w3c-html-validator'); -const jsHint = require('gulp-jshint'); -const mergeStream = require('merge-stream'); - -function lint() { - return mergeStream( - gulp.src('src/*.html') - .pipe(htmlValidator()) - .pipe(htmlValidator.reporter()), - gulp.src('src/*.js') - .pipe(jsHint()) - .pipe(jsHint.reporter()) - ); -} -gulp.task('lint', lint); -``` - -## License - -MIT diff --git a/node_modules/merge-stream/index.js b/node_modules/merge-stream/index.js deleted file mode 100644 index b1a9e1a02e..0000000000 --- a/node_modules/merge-stream/index.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - -const { PassThrough } = require('stream'); - -module.exports = function (/*streams...*/) { - var sources = [] - var output = new PassThrough({objectMode: true}) - - output.setMaxListeners(0) - - output.add = add - output.isEmpty = isEmpty - - output.on('unpipe', remove) - - Array.prototype.slice.call(arguments).forEach(add) - - return output - - function add (source) { - if (Array.isArray(source)) { - source.forEach(add) - return this - } - - sources.push(source); - source.once('end', remove.bind(null, source)) - source.once('error', output.emit.bind(output, 'error')) - source.pipe(output, {end: false}) - return this - } - - function isEmpty () { - return sources.length == 0; - } - - function remove (source) { - sources = sources.filter(function (it) { return it !== source }) - if (!sources.length && output.readable) { output.end() } - } -} diff --git a/node_modules/merge-stream/package.json b/node_modules/merge-stream/package.json deleted file mode 100644 index 1a4c54ca50..0000000000 --- a/node_modules/merge-stream/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "merge-stream", - "version": "2.0.0", - "description": "Create a stream that emits events from multiple other streams", - "files": [ - "index.js" - ], - "scripts": { - "test": "istanbul cover test.js && istanbul check-cover --statements 100 --branches 100" - }, - "repository": "grncdr/merge-stream", - "author": "Stephen Sugden ", - "license": "MIT", - "dependencies": {}, - "devDependencies": { - "from2": "^2.0.3", - "istanbul": "^0.4.5" - } -} diff --git a/node_modules/npm-run-path/index.d.ts b/node_modules/npm-run-path/index.d.ts index fad851b897..25eca12ace 100644 --- a/node_modules/npm-run-path/index.d.ts +++ b/node_modules/npm-run-path/index.d.ts @@ -1,4 +1,4 @@ -export interface RunPathOptions { +type CommonOptions = { /** Working directory. @@ -7,46 +7,50 @@ export interface RunPathOptions { readonly cwd?: string | URL; /** - PATH to be appended. Default: [`PATH`](https://github.com/sindresorhus/path-key). + The path to the current Node.js executable. - Set it to an empty string to exclude the default PATH. + This can be either an absolute path or a path relative to the `cwd` option. + + @default [process.execPath](https://nodejs.org/api/process.html#processexecpath) */ - readonly path?: string; + readonly execPath?: string | URL; /** - Path to the Node.js executable to use in child processes if that is different from the current one. Its directory is pushed to the front of PATH. - - This can be either an absolute path or a path relative to the `cwd` option. + Whether to push the current Node.js executable's directory (`execPath` option) to the front of PATH. - @default process.execPath + @default true */ - readonly execPath?: string; -} + readonly addExecPath?: boolean; -export type ProcessEnv = Record; - -export interface EnvOptions { /** - The working directory. + Whether to push the locally installed binaries' directory to the front of PATH. - @default process.cwd() + @default true */ - readonly cwd?: string | URL; + readonly preferLocal?: boolean; +}; +export type RunPathOptions = CommonOptions & { /** - Accepts an object of environment variables, like `process.env`, and modifies the PATH using the correct [PATH key](https://github.com/sindresorhus/path-key). Use this if you're modifying the PATH for use in the `child_process` options. + PATH to be appended. + + Set it to an empty string to exclude the default PATH. + + @default [`PATH`](https://github.com/sindresorhus/path-key) */ - readonly env?: ProcessEnv; + readonly path?: string; +}; - /** - The path to the current Node.js executable. Its directory is pushed to the front of PATH. +export type ProcessEnv = Record; - This can be either an absolute path or a path relative to the `cwd` option. +export type EnvOptions = CommonOptions & { + /** + Accepts an object of environment variables, like `process.env`, and modifies the PATH using the correct [PATH key](https://github.com/sindresorhus/path-key). Use this if you're modifying the PATH for use in the `child_process` options. - @default process.execPath + @default [process.env](https://nodejs.org/api/process.html#processenv) */ - readonly execPath?: string; -} + readonly env?: ProcessEnv; +}; /** Get your [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) prepended with locally installed binaries. @@ -68,6 +72,8 @@ console.log(npmRunPath()); export function npmRunPath(options?: RunPathOptions): string; /** +Get your [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) prepended with locally installed binaries. + @returns The augmented [`process.env`](https://nodejs.org/api/process.html#process_process_env) object. @example diff --git a/node_modules/npm-run-path/index.js b/node_modules/npm-run-path/index.js index 77dfae2177..4bb9716108 100644 --- a/node_modules/npm-run-path/index.js +++ b/node_modules/npm-run-path/index.js @@ -1,38 +1,55 @@ import process from 'node:process'; import path from 'node:path'; -import url from 'node:url'; import pathKey from 'path-key'; - -export function npmRunPath(options = {}) { - const { - cwd = process.cwd(), - path: path_ = process.env[pathKey()], - execPath = process.execPath, - } = options; - - let previous; - const cwdString = cwd instanceof URL ? url.fileURLToPath(cwd) : cwd; - let cwdPath = path.resolve(cwdString); +import {toPath, traversePathUp} from 'unicorn-magic'; + +export const npmRunPath = ({ + cwd = process.cwd(), + path: pathOption = process.env[pathKey()], + preferLocal = true, + execPath = process.execPath, + addExecPath = true, +} = {}) => { + const cwdPath = path.resolve(toPath(cwd)); const result = []; + const pathParts = pathOption.split(path.delimiter); + + if (preferLocal) { + applyPreferLocal(result, pathParts, cwdPath); + } - while (previous !== cwdPath) { - result.push(path.join(cwdPath, 'node_modules/.bin')); - previous = cwdPath; - cwdPath = path.resolve(cwdPath, '..'); + if (addExecPath) { + applyExecPath(result, pathParts, execPath, cwdPath); } - // Ensure the running `node` binary is used. - result.push(path.resolve(cwdString, execPath, '..')); + return pathOption === '' || pathOption === path.delimiter + ? `${result.join(path.delimiter)}${pathOption}` + : [...result, pathOption].join(path.delimiter); +}; + +const applyPreferLocal = (result, pathParts, cwdPath) => { + for (const directory of traversePathUp(cwdPath)) { + const pathPart = path.join(directory, 'node_modules/.bin'); + if (!pathParts.includes(pathPart)) { + result.push(pathPart); + } + } +}; - return [...result, path_].join(path.delimiter); -} +// Ensure the running `node` binary is used +const applyExecPath = (result, pathParts, execPath, cwdPath) => { + const pathPart = path.resolve(cwdPath, toPath(execPath), '..'); + if (!pathParts.includes(pathPart)) { + result.push(pathPart); + } +}; -export function npmRunPathEnv({env = process.env, ...options} = {}) { +export const npmRunPathEnv = ({env = process.env, ...options} = {}) => { env = {...env}; - const path = pathKey({env}); - options.path = env[path]; - env[path] = npmRunPath(options); + const pathName = pathKey({env}); + options.path = env[pathName]; + env[pathName] = npmRunPath(options); return env; -} +}; diff --git a/node_modules/npm-run-path/package.json b/node_modules/npm-run-path/package.json index df46566e33..80735ef548 100644 --- a/node_modules/npm-run-path/package.json +++ b/node_modules/npm-run-path/package.json @@ -1,6 +1,6 @@ { "name": "npm-run-path", - "version": "5.1.0", + "version": "6.0.0", "description": "Get your PATH prepended with locally installed binaries", "license": "MIT", "repository": "sindresorhus/npm-run-path", @@ -11,9 +11,13 @@ "url": "https://sindresorhus.com" }, "type": "module", - "exports": "./index.js", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "scripts": { "test": "xo && ava && tsd" @@ -37,11 +41,12 @@ "executable" ], "dependencies": { - "path-key": "^4.0.0" + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" }, "devDependencies": { - "ava": "^3.15.0", - "tsd": "^0.17.0", - "xo": "^0.45.0" + "ava": "^6.1.3", + "tsd": "^0.31.1", + "xo": "^0.59.3" } } diff --git a/node_modules/npm-run-path/readme.md b/node_modules/npm-run-path/readme.md index f2ab84b808..bec78f93a5 100644 --- a/node_modules/npm-run-path/readme.md +++ b/node_modules/npm-run-path/readme.md @@ -32,80 +32,73 @@ childProcess.execFileSync('foo', { ### npmRunPath(options?) +`options`: [`Options`](#options)\ +_Returns_: `string` + Returns the augmented PATH string. -#### options +### npmRunPathEnv(options?) + +`options`: [`Options`](#options)\ +_Returns_: `object` + +Returns the augmented [`process.env`](https://nodejs.org/api/process.html#process_process_env) object. + +### options Type: `object` -##### cwd +#### cwd Type: `string | URL`\ Default: `process.cwd()` The working directory. -##### path +#### execPath -Type: `string`\ -Default: [`PATH`](https://github.com/sindresorhus/path-key) +Type: `string | URL`\ +Default: [`process.execPath`](https://nodejs.org/api/process.html#processexecpath) -The PATH to be appended. +The path to the current Node.js executable. -Set it to an empty string to exclude the default PATH. +This can be either an absolute path or a path relative to the [`cwd` option](#cwd). -##### execPath +#### addExecPath -Type: `string`\ -Default: `process.execPath` +Type: `boolean`\ +Default: `true` -The path to the current Node.js executable. Its directory is pushed to the front of PATH. +Whether to push the current Node.js executable's directory ([`execPath`](#execpath) option) to the front of PATH. -This can be either an absolute path or a path relative to the [`cwd` option](#cwd). +#### preferLocal -### npmRunPathEnv(options?) +Type: `boolean`\ +Default: `true` -Returns the augmented [`process.env`](https://nodejs.org/api/process.html#process_process_env) object. +Whether to push the locally installed binaries' directory to the front of PATH. -#### options +#### path -Type: `object` +Type: `string`\ +Default: [`PATH`](https://github.com/sindresorhus/path-key) -##### cwd +The PATH to be appended. -Type: `string | URL`\ -Default: `process.cwd()` +Set it to an empty string to exclude the default PATH. -The working directory. +Only available with [`npmRunPath()`](#npmrunpathoptions), not [`npmRunPathEnv()`](#npmrunpathenvoptions). -##### env +#### env -Type: `object` +Type: `object`\ +Default: [`process.env`](https://nodejs.org/api/process.html#processenv) Accepts an object of environment variables, like `process.env`, and modifies the PATH using the correct [PATH key](https://github.com/sindresorhus/path-key). Use this if you're modifying the PATH for use in the `child_process` options. -##### execPath - -Type: `string`\ -Default: `process.execPath` - -The path to the Node.js executable to use in child processes if that is different from the current one. Its directory is pushed to the front of PATH. - -This can be either an absolute path or a path relative to the [`cwd` option](#cwd). +Only available with [`npmRunPathEnv()`](#npmrunpathenvoptions), not [`npmRunPath()`](#npmrunpathoptions). ## Related - [npm-run-path-cli](https://github.com/sindresorhus/npm-run-path-cli) - CLI for this module - [execa](https://github.com/sindresorhus/execa) - Execute a locally installed binary - ---- - -
- - Get professional support for this package with a Tidelift subscription - -
- - Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. -
-
diff --git a/node_modules/onetime/index.d.ts b/node_modules/onetime/index.d.ts deleted file mode 100644 index 3c80803f99..0000000000 --- a/node_modules/onetime/index.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -export interface Options { - /** - Throw an error when called more than once. - - @default false - */ - readonly throw?: boolean; -} - -declare const onetime: { - /** - Ensure a function is only called once. When called multiple times it will return the return value from the first call. - - @param fn - Function that should only be called once. - @returns A function that only calls `fn` once. - - @example - ``` - import onetime from 'onetime'; - - let index = 0; - - const foo = onetime(() => ++index); - - foo(); //=> 1 - foo(); //=> 1 - foo(); //=> 1 - - onetime.callCount(foo); //=> 3 - ``` - */ - ( - fn: (...arguments: ArgumentsType) => ReturnType, - options?: Options - ): (...arguments: ArgumentsType) => ReturnType; - - /** - Get the number of times `fn` has been called. - - @param fn - Function to get call count from. - @returns A number representing how many times `fn` has been called. - - @example - ``` - import onetime from 'onetime'; - - const foo = onetime(() => {}); - foo(); - foo(); - foo(); - - console.log(onetime.callCount(foo)); - //=> 3 - ``` - */ - callCount(fn: (...arguments: any[]) => unknown): number; -}; - -export default onetime; diff --git a/node_modules/onetime/index.js b/node_modules/onetime/index.js deleted file mode 100644 index eae4f33e4c..0000000000 --- a/node_modules/onetime/index.js +++ /dev/null @@ -1,41 +0,0 @@ -import mimicFunction from 'mimic-fn'; - -const calledFunctions = new WeakMap(); - -const onetime = (function_, options = {}) => { - if (typeof function_ !== 'function') { - throw new TypeError('Expected a function'); - } - - let returnValue; - let callCount = 0; - const functionName = function_.displayName || function_.name || ''; - - const onetime = function (...arguments_) { - calledFunctions.set(onetime, ++callCount); - - if (callCount === 1) { - returnValue = function_.apply(this, arguments_); - function_ = null; - } else if (options.throw === true) { - throw new Error(`Function \`${functionName}\` can only be called once`); - } - - return returnValue; - }; - - mimicFunction(onetime, function_); - calledFunctions.set(onetime, callCount); - - return onetime; -}; - -onetime.callCount = function_ => { - if (!calledFunctions.has(function_)) { - throw new Error(`The given function \`${function_.name}\` is not wrapped by the \`onetime\` package`); - } - - return calledFunctions.get(function_); -}; - -export default onetime; diff --git a/node_modules/onetime/readme.md b/node_modules/onetime/readme.md deleted file mode 100644 index e2b26fb3d3..0000000000 --- a/node_modules/onetime/readme.md +++ /dev/null @@ -1,94 +0,0 @@ -# onetime - -> Ensure a function is only called once - -When called multiple times it will return the return value from the first call. - -*Unlike the module [once](https://github.com/isaacs/once), this one isn't naughty and extending `Function.prototype`.* - -## Install - -``` -$ npm install onetime -``` - -## Usage - -```js -import onetime from 'onetime'; - -let index = 0; - -const foo = onetime(() => ++index); - -foo(); //=> 1 -foo(); //=> 1 -foo(); //=> 1 - -onetime.callCount(foo); //=> 3 -``` - -```js -import onetime from 'onetime'; - -const foo = onetime(() => {}, {throw: true}); - -foo(); - -foo(); -//=> Error: Function `foo` can only be called once -``` - -## API - -### onetime(fn, options?) - -Returns a function that only calls `fn` once. - -#### fn - -Type: `Function` - -Function that should only be called once. - -#### options - -Type: `object` - -##### throw - -Type: `boolean`\ -Default: `false` - -Throw an error when called more than once. - -### onetime.callCount(fn) - -Returns a number representing how many times `fn` has been called. - -Note: It throws an error if you pass in a function that is not wrapped by `onetime`. - -```js -import onetime from 'onetime'; - -const foo = onetime(() => {}); - -foo(); -foo(); -foo(); - -console.log(onetime.callCount(foo)); -//=> 3 -``` - -#### fn - -Type: `Function` - -Function to get call count from. - -## onetime for enterprise - -Available as part of the Tidelift Subscription. - -The maintainers of onetime and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-onetime?utm_source=npm-onetime&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) diff --git a/node_modules/signal-exit/LICENSE.txt b/node_modules/signal-exit/LICENSE.txt index eead04a121..954f2fa823 100644 --- a/node_modules/signal-exit/LICENSE.txt +++ b/node_modules/signal-exit/LICENSE.txt @@ -1,6 +1,6 @@ The ISC License -Copyright (c) 2015, Contributors +Copyright (c) 2015-2023 Benjamin Coe, Isaac Z. Schlueter, and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided diff --git a/node_modules/signal-exit/README.md b/node_modules/signal-exit/README.md index f9c7c007d5..c55cd45ee3 100644 --- a/node_modules/signal-exit/README.md +++ b/node_modules/signal-exit/README.md @@ -1,39 +1,74 @@ # signal-exit -[![Build Status](https://travis-ci.org/tapjs/signal-exit.png)](https://travis-ci.org/tapjs/signal-exit) -[![Coverage](https://coveralls.io/repos/tapjs/signal-exit/badge.svg?branch=master)](https://coveralls.io/r/tapjs/signal-exit?branch=master) -[![NPM version](https://img.shields.io/npm/v/signal-exit.svg)](https://www.npmjs.com/package/signal-exit) -[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version) - When you want to fire an event no matter how a process exits: -* reaching the end of execution. -* explicitly having `process.exit(code)` called. -* having `process.kill(pid, sig)` called. -* receiving a fatal signal from outside the process +- reaching the end of execution. +- explicitly having `process.exit(code)` called. +- having `process.kill(pid, sig)` called. +- receiving a fatal signal from outside the process Use `signal-exit`. ```js -var onExit = require('signal-exit') +// Hybrid module, either works +import { onExit } from 'signal-exit' +// or: +// const { onExit } = require('signal-exit') -onExit(function (code, signal) { - console.log('process exited!') +onExit((code, signal) => { + console.log('process exited!', code, signal) }) ``` ## API -`var remove = onExit(function (code, signal) {}, options)` +`remove = onExit((code, signal) => {}, options)` + +The return value of the function is a function that will remove +the handler. + +Note that the function _only_ fires for signals if the signal +would cause the process to exit. That is, there are no other +listeners, and it is a fatal signal. + +If the global `process` object is not suitable for this purpose +(ie, it's unset, or doesn't have an `emit` method, etc.) then the +`onExit` function is a no-op that returns a no-op `remove` method. + +### Options + +- `alwaysLast`: Run this handler after any other signal or exit + handlers. This causes `process.emit` to be monkeypatched. + +### Capturing Signal Exits + +If the handler returns an exact boolean `true`, and the exit is a +due to signal, then the signal will be considered handled, and +will _not_ trigger a synthetic `process.kill(process.pid, +signal)` after firing the `onExit` handlers. + +In this case, it your responsibility as the caller to exit with a +signal (for example, by calling `process.kill()`) if you wish to +preserve the same exit status that would otherwise have occurred. +If you do not, then the process will likely exit gracefully with +status 0 at some point, assuming that no other terminating signal +or other exit trigger occurs. + +Prior to calling handlers, the `onExit` machinery is unloaded, so +any subsequent exits or signals will not be handled, even if the +signal is captured and the exit is thus prevented. -The return value of the function is a function that will remove the -handler. +Note that numeric code exits may indicate that the process is +already committed to exiting, for example due to a fatal +exception or unhandled promise rejection, and so there is no way to +prevent it safely. -Note that the function *only* fires for signals if the signal would -cause the process to exit. That is, there are no other listeners, and -it is a fatal signal. +### Browser Fallback -## Options +The `'signal-exit/browser'` module is the same fallback shim that +just doesn't do anything, but presents the same function +interface. -* `alwaysLast`: Run this handler after any other signal or exit - handlers. This causes `process.emit` to be monkeypatched. +Patches welcome to add something that hooks onto +`window.onbeforeunload` or similar, but it might just not be a +thing that makes sense there. diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/browser.d.ts b/node_modules/signal-exit/dist/cjs/browser.d.ts similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/browser.d.ts rename to node_modules/signal-exit/dist/cjs/browser.d.ts diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/browser.d.ts.map b/node_modules/signal-exit/dist/cjs/browser.d.ts.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/browser.d.ts.map rename to node_modules/signal-exit/dist/cjs/browser.d.ts.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/browser.js b/node_modules/signal-exit/dist/cjs/browser.js similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/browser.js rename to node_modules/signal-exit/dist/cjs/browser.js diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/browser.js.map b/node_modules/signal-exit/dist/cjs/browser.js.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/browser.js.map rename to node_modules/signal-exit/dist/cjs/browser.js.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/index.d.ts b/node_modules/signal-exit/dist/cjs/index.d.ts similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/index.d.ts rename to node_modules/signal-exit/dist/cjs/index.d.ts diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/index.d.ts.map b/node_modules/signal-exit/dist/cjs/index.d.ts.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/index.d.ts.map rename to node_modules/signal-exit/dist/cjs/index.d.ts.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/index.js b/node_modules/signal-exit/dist/cjs/index.js similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/index.js rename to node_modules/signal-exit/dist/cjs/index.js diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/index.js.map b/node_modules/signal-exit/dist/cjs/index.js.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/index.js.map rename to node_modules/signal-exit/dist/cjs/index.js.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/package.json b/node_modules/signal-exit/dist/cjs/package.json similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/package.json rename to node_modules/signal-exit/dist/cjs/package.json diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/signals.d.ts b/node_modules/signal-exit/dist/cjs/signals.d.ts similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/signals.d.ts rename to node_modules/signal-exit/dist/cjs/signals.d.ts diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/signals.d.ts.map b/node_modules/signal-exit/dist/cjs/signals.d.ts.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/signals.d.ts.map rename to node_modules/signal-exit/dist/cjs/signals.d.ts.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/signals.js b/node_modules/signal-exit/dist/cjs/signals.js similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/signals.js rename to node_modules/signal-exit/dist/cjs/signals.js diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/cjs/signals.js.map b/node_modules/signal-exit/dist/cjs/signals.js.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/cjs/signals.js.map rename to node_modules/signal-exit/dist/cjs/signals.js.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/browser.d.ts b/node_modules/signal-exit/dist/mjs/browser.d.ts similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/browser.d.ts rename to node_modules/signal-exit/dist/mjs/browser.d.ts diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/browser.d.ts.map b/node_modules/signal-exit/dist/mjs/browser.d.ts.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/browser.d.ts.map rename to node_modules/signal-exit/dist/mjs/browser.d.ts.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/browser.js b/node_modules/signal-exit/dist/mjs/browser.js similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/browser.js rename to node_modules/signal-exit/dist/mjs/browser.js diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/browser.js.map b/node_modules/signal-exit/dist/mjs/browser.js.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/browser.js.map rename to node_modules/signal-exit/dist/mjs/browser.js.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/index.d.ts b/node_modules/signal-exit/dist/mjs/index.d.ts similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/index.d.ts rename to node_modules/signal-exit/dist/mjs/index.d.ts diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/index.d.ts.map b/node_modules/signal-exit/dist/mjs/index.d.ts.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/index.d.ts.map rename to node_modules/signal-exit/dist/mjs/index.d.ts.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/index.js b/node_modules/signal-exit/dist/mjs/index.js similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/index.js rename to node_modules/signal-exit/dist/mjs/index.js diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/index.js.map b/node_modules/signal-exit/dist/mjs/index.js.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/index.js.map rename to node_modules/signal-exit/dist/mjs/index.js.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/package.json b/node_modules/signal-exit/dist/mjs/package.json similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/package.json rename to node_modules/signal-exit/dist/mjs/package.json diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/signals.d.ts b/node_modules/signal-exit/dist/mjs/signals.d.ts similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/signals.d.ts rename to node_modules/signal-exit/dist/mjs/signals.d.ts diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/signals.d.ts.map b/node_modules/signal-exit/dist/mjs/signals.d.ts.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/signals.d.ts.map rename to node_modules/signal-exit/dist/mjs/signals.d.ts.map diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/signals.js b/node_modules/signal-exit/dist/mjs/signals.js similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/signals.js rename to node_modules/signal-exit/dist/mjs/signals.js diff --git a/node_modules/foreground-child/node_modules/signal-exit/dist/mjs/signals.js.map b/node_modules/signal-exit/dist/mjs/signals.js.map similarity index 100% rename from node_modules/foreground-child/node_modules/signal-exit/dist/mjs/signals.js.map rename to node_modules/signal-exit/dist/mjs/signals.js.map diff --git a/node_modules/signal-exit/index.js b/node_modules/signal-exit/index.js deleted file mode 100644 index 93703f3692..0000000000 --- a/node_modules/signal-exit/index.js +++ /dev/null @@ -1,202 +0,0 @@ -// Note: since nyc uses this module to output coverage, any lines -// that are in the direct sync flow of nyc's outputCoverage are -// ignored, since we can never get coverage for them. -// grab a reference to node's real process object right away -var process = global.process - -const processOk = function (process) { - return process && - typeof process === 'object' && - typeof process.removeListener === 'function' && - typeof process.emit === 'function' && - typeof process.reallyExit === 'function' && - typeof process.listeners === 'function' && - typeof process.kill === 'function' && - typeof process.pid === 'number' && - typeof process.on === 'function' -} - -// some kind of non-node environment, just no-op -/* istanbul ignore if */ -if (!processOk(process)) { - module.exports = function () { - return function () {} - } -} else { - var assert = require('assert') - var signals = require('./signals.js') - var isWin = /^win/i.test(process.platform) - - var EE = require('events') - /* istanbul ignore if */ - if (typeof EE !== 'function') { - EE = EE.EventEmitter - } - - var emitter - if (process.__signal_exit_emitter__) { - emitter = process.__signal_exit_emitter__ - } else { - emitter = process.__signal_exit_emitter__ = new EE() - emitter.count = 0 - emitter.emitted = {} - } - - // Because this emitter is a global, we have to check to see if a - // previous version of this library failed to enable infinite listeners. - // I know what you're about to say. But literally everything about - // signal-exit is a compromise with evil. Get used to it. - if (!emitter.infinite) { - emitter.setMaxListeners(Infinity) - emitter.infinite = true - } - - module.exports = function (cb, opts) { - /* istanbul ignore if */ - if (!processOk(global.process)) { - return function () {} - } - assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') - - if (loaded === false) { - load() - } - - var ev = 'exit' - if (opts && opts.alwaysLast) { - ev = 'afterexit' - } - - var remove = function () { - emitter.removeListener(ev, cb) - if (emitter.listeners('exit').length === 0 && - emitter.listeners('afterexit').length === 0) { - unload() - } - } - emitter.on(ev, cb) - - return remove - } - - var unload = function unload () { - if (!loaded || !processOk(global.process)) { - return - } - loaded = false - - signals.forEach(function (sig) { - try { - process.removeListener(sig, sigListeners[sig]) - } catch (er) {} - }) - process.emit = originalProcessEmit - process.reallyExit = originalProcessReallyExit - emitter.count -= 1 - } - module.exports.unload = unload - - var emit = function emit (event, code, signal) { - /* istanbul ignore if */ - if (emitter.emitted[event]) { - return - } - emitter.emitted[event] = true - emitter.emit(event, code, signal) - } - - // { : , ... } - var sigListeners = {} - signals.forEach(function (sig) { - sigListeners[sig] = function listener () { - /* istanbul ignore if */ - if (!processOk(global.process)) { - return - } - // If there are no other listeners, an exit is coming! - // Simplest way: remove us and then re-send the signal. - // We know that this will kill the process, so we can - // safely emit now. - var listeners = process.listeners(sig) - if (listeners.length === emitter.count) { - unload() - emit('exit', null, sig) - /* istanbul ignore next */ - emit('afterexit', null, sig) - /* istanbul ignore next */ - if (isWin && sig === 'SIGHUP') { - // "SIGHUP" throws an `ENOSYS` error on Windows, - // so use a supported signal instead - sig = 'SIGINT' - } - /* istanbul ignore next */ - process.kill(process.pid, sig) - } - } - }) - - module.exports.signals = function () { - return signals - } - - var loaded = false - - var load = function load () { - if (loaded || !processOk(global.process)) { - return - } - loaded = true - - // This is the number of onSignalExit's that are in play. - // It's important so that we can count the correct number of - // listeners on signals, and don't wait for the other one to - // handle it instead of us. - emitter.count += 1 - - signals = signals.filter(function (sig) { - try { - process.on(sig, sigListeners[sig]) - return true - } catch (er) { - return false - } - }) - - process.emit = processEmit - process.reallyExit = processReallyExit - } - module.exports.load = load - - var originalProcessReallyExit = process.reallyExit - var processReallyExit = function processReallyExit (code) { - /* istanbul ignore if */ - if (!processOk(global.process)) { - return - } - process.exitCode = code || /* istanbul ignore next */ 0 - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - /* istanbul ignore next */ - originalProcessReallyExit.call(process, process.exitCode) - } - - var originalProcessEmit = process.emit - var processEmit = function processEmit (ev, arg) { - if (ev === 'exit' && processOk(global.process)) { - /* istanbul ignore else */ - if (arg !== undefined) { - process.exitCode = arg - } - var ret = originalProcessEmit.apply(this, arguments) - /* istanbul ignore next */ - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - /* istanbul ignore next */ - return ret - } else { - return originalProcessEmit.apply(this, arguments) - } - } -} diff --git a/node_modules/signal-exit/package.json b/node_modules/signal-exit/package.json index e1a00311f9..ac176cec74 100644 --- a/node_modules/signal-exit/package.json +++ b/node_modules/signal-exit/package.json @@ -1,19 +1,49 @@ { "name": "signal-exit", - "version": "3.0.7", + "version": "4.1.0", "description": "when you want to fire an event no matter how a process exits.", - "main": "index.js", - "scripts": { - "test": "tap", - "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" + "main": "./dist/cjs/index.js", + "module": "./dist/mjs/index.js", + "browser": "./dist/mjs/browser.js", + "types": "./dist/mjs/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./signals": { + "import": { + "types": "./dist/mjs/signals.d.ts", + "default": "./dist/mjs/signals.js" + }, + "require": { + "types": "./dist/cjs/signals.d.ts", + "default": "./dist/cjs/signals.js" + } + }, + "./browser": { + "import": { + "types": "./dist/mjs/browser.d.ts", + "default": "./dist/mjs/browser.js" + }, + "require": { + "types": "./dist/cjs/browser.d.ts", + "default": "./dist/cjs/browser.js" + } + } }, "files": [ - "index.js", - "signals.js" + "dist" ], + "engines": { + "node": ">=14" + }, "repository": { "type": "git", "url": "https://github.com/tapjs/signal-exit.git" @@ -24,15 +54,53 @@ ], "author": "Ben Coe ", "license": "ISC", - "bugs": { - "url": "https://github.com/tapjs/signal-exit/issues" - }, - "homepage": "https://github.com/tapjs/signal-exit", "devDependencies": { - "chai": "^3.5.0", - "coveralls": "^3.1.1", - "nyc": "^15.1.0", - "standard-version": "^9.3.1", - "tap": "^15.1.1" + "@types/cross-spawn": "^6.0.2", + "@types/node": "^18.15.11", + "@types/signal-exit": "^3.0.1", + "@types/tap": "^15.0.8", + "c8": "^7.13.0", + "prettier": "^2.8.6", + "tap": "^16.3.4", + "ts-node": "^10.9.1", + "typedoc": "^0.23.28", + "typescript": "^5.0.2" + }, + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "preprepare": "rm -rf dist", + "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" + }, + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "tap": { + "coverage": false, + "jobs": 1, + "node-arg": [ + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } } diff --git a/node_modules/signal-exit/signals.js b/node_modules/signal-exit/signals.js deleted file mode 100644 index 3bd67a8a55..0000000000 --- a/node_modules/signal-exit/signals.js +++ /dev/null @@ -1,53 +0,0 @@ -// This is not the set of all possible signals. -// -// It IS, however, the set of all signals that trigger -// an exit on either Linux or BSD systems. Linux is a -// superset of the signal names supported on BSD, and -// the unknown signals just fail to register, so we can -// catch that easily enough. -// -// Don't bother with SIGKILL. It's uncatchable, which -// means that we can't fire any callbacks anyway. -// -// If a user does happen to register a handler on a non- -// fatal signal like SIGWINCH or something, and then -// exit, it'll end up firing `process.emit('exit')`, so -// the handler will be fired anyway. -// -// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised -// artificially, inherently leave the process in a -// state from which it is not safe to try and enter JS -// listeners. -module.exports = [ - 'SIGABRT', - 'SIGALRM', - 'SIGHUP', - 'SIGINT', - 'SIGTERM' -] - -if (process.platform !== 'win32') { - module.exports.push( - 'SIGVTALRM', - 'SIGXCPU', - 'SIGXFSZ', - 'SIGUSR2', - 'SIGTRAP', - 'SIGSYS', - 'SIGQUIT', - 'SIGIOT' - // should detect profiler and enable/disable accordingly. - // see #21 - // 'SIGPROF' - ) -} - -if (process.platform === 'linux') { - module.exports.push( - 'SIGIO', - 'SIGPOLL', - 'SIGPWR', - 'SIGSTKFLT', - 'SIGUNUSED' - ) -} diff --git a/node_modules/sinon/lib/sinon/assert.js b/node_modules/sinon/lib/sinon/assert.js index 43a555804a..374be4d8ba 100644 --- a/node_modules/sinon/lib/sinon/assert.js +++ b/node_modules/sinon/lib/sinon/assert.js @@ -47,8 +47,6 @@ function createAssertObject(opts) { }); const assert = { - failException: "AssertError", - fail: function fail(message) { let msg = message; if (cleanedAssertOptions.shouldLimitAssertionLogs) { @@ -58,7 +56,7 @@ function createAssertObject(opts) { ); } const error = new Error(msg); - error.name = this.failException || assert.failException; + error.name = "AssertError"; throw error; }, diff --git a/node_modules/sinon/package.json b/node_modules/sinon/package.json index 4ba6956c93..06013155f5 100644 --- a/node_modules/sinon/package.json +++ b/node_modules/sinon/package.json @@ -15,7 +15,7 @@ "xhr", "assert" ], - "version": "20.0.0", + "version": "21.0.0", "homepage": "https://sinonjs.org/", "author": "Christian Johansen", "repository": { @@ -99,7 +99,7 @@ "browserify": "^16.5.2", "debug": "^4.3.7", "dependency-check": "^4.1.0", - "esbuild": "^0.23.1", + "esbuild": "^0.25.1", "esbuild-plugin-istanbul": "^0.3.0", "get-stdin": "^9.0.0", "lint-staged": "^15.2.10", diff --git a/node_modules/sinon/pkg/sinon-esm.js b/node_modules/sinon/pkg/sinon-esm.js index 1bbf6d1f71..b9b6fcbe3e 100644 --- a/node_modules/sinon/pkg/sinon-esm.js +++ b/node_modules/sinon/pkg/sinon-esm.js @@ -1,4 +1,4 @@ -/* Sinon.JS 20.0.0, 2025-03-24, @license BSD-3 */let sinon;(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 'foo\nbar\n' + +const uint8Array = new TextEncoder().encode('foo\nbar\n\n') +new TextDecoder().decode(stripFinalNewline(uint8Array)); +//=> 'foo\nbar\n' +``` +*/ +export default function stripFinalNewline(input: T): T; diff --git a/node_modules/strip-final-newline/index.js b/node_modules/strip-final-newline/index.js index 034b56f865..a63ed26bbc 100644 --- a/node_modules/strip-final-newline/index.js +++ b/node_modules/strip-final-newline/index.js @@ -1,14 +1,26 @@ export default function stripFinalNewline(input) { - const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt(); - const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt(); - - if (input[input.length - 1] === LF) { - input = input.slice(0, -1); + if (typeof input === 'string') { + return stripFinalNewlineString(input); } - if (input[input.length - 1] === CR) { - input = input.slice(0, -1); + if (!(ArrayBuffer.isView(input) && input.BYTES_PER_ELEMENT === 1)) { + throw new Error('Input must be a string or a Uint8Array'); } - return input; + return stripFinalNewlineBinary(input); } + +const stripFinalNewlineString = input => + input.at(-1) === LF + ? input.slice(0, input.at(-2) === CR ? -2 : -1) + : input; + +const stripFinalNewlineBinary = input => + input.at(-1) === LF_BINARY + ? input.subarray(0, input.at(-2) === CR_BINARY ? -2 : -1) + : input; + +const LF = '\n'; +const LF_BINARY = LF.codePointAt(0); +const CR = '\r'; +const CR_BINARY = CR.codePointAt(0); diff --git a/node_modules/strip-final-newline/package.json b/node_modules/strip-final-newline/package.json index 23ac8622e4..cfeef7958e 100644 --- a/node_modules/strip-final-newline/package.json +++ b/node_modules/strip-final-newline/package.json @@ -1,7 +1,7 @@ { "name": "strip-final-newline", - "version": "3.0.0", - "description": "Strip the final newline character from a string/buffer", + "version": "4.0.0", + "description": "Strip the final newline character from a string or Uint8Array", "license": "MIT", "repository": "sindresorhus/strip-final-newline", "funding": "https://github.com/sponsors/sindresorhus", @@ -11,15 +11,20 @@ "url": "https://sindresorhus.com" }, "type": "module", - "exports": "./index.js", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, "engines": { - "node": ">=12" + "node": ">=18" }, "scripts": { - "test": "xo && ava" + "test": "xo && ava && tsd" }, "files": [ - "index.js" + "index.js", + "index.d.ts" ], "keywords": [ "strip", @@ -34,10 +39,11 @@ "linebreak", "character", "string", - "buffer" + "uint8array" ], "devDependencies": { - "ava": "^3.15.0", - "xo": "^0.39.1" + "ava": "^6.0.1", + "tsd": "^0.29.0", + "xo": "^0.56.0" } } diff --git a/node_modules/strip-final-newline/readme.md b/node_modules/strip-final-newline/readme.md index 8d9090b64f..f0454d5ac3 100644 --- a/node_modules/strip-final-newline/readme.md +++ b/node_modules/strip-final-newline/readme.md @@ -1,13 +1,13 @@ # strip-final-newline -> Strip the final [newline character](https://en.wikipedia.org/wiki/Newline) from a string/buffer +> Strip the final [newline character](https://en.wikipedia.org/wiki/Newline) from a string or Uint8Array. -Can be useful when parsing the output of, for example, `ChildProcess#execFile`, as [binaries usually output a newline at the end](https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newline). Normally, you would use `stdout.trim()`, but that would also remove newlines at the start and whitespace. +This can be useful when parsing the output of, for example, `ChildProcess#execFile()`, as [binaries usually output a newline at the end](https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newline). You cannot use `stdout.trimEnd()` for this as it removes all trailing newlines and whitespaces at the end. ## Install -``` -$ npm install strip-final-newline +```sh +npm install strip-final-newline ``` ## Usage @@ -18,18 +18,17 @@ import stripFinalNewline from 'strip-final-newline'; stripFinalNewline('foo\nbar\n\n'); //=> 'foo\nbar\n' -stripFinalNewline(Buffer.from('foo\nbar\n\n')).toString(); +const uint8Array = new TextEncoder().encode('foo\nbar\n\n') +new TextDecoder().decode(stripFinalNewline(uint8Array)); //=> 'foo\nbar\n' ``` ---- - -
- - Get professional support for this package with a Tidelift subscription - -
- - Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. -
-
+## Performance + +When using an `Uint8Array`, the original value is referenced, not copied. This is much more efficient, requires almost no memory, and remains milliseconds fast even on very large inputs. + +If you'd like to ensure that modifying the return value does not also modify the value passed as input, please use `.slice()`. + +```js +const value = new TextDecoder().decode(stripFinalNewline(uint8Array).slice()); +``` diff --git a/node_modules/unicorn-magic/default.d.ts b/node_modules/unicorn-magic/default.d.ts new file mode 100644 index 0000000000..c7916d8bcb --- /dev/null +++ b/node_modules/unicorn-magic/default.d.ts @@ -0,0 +1,13 @@ +/** +Delays the promise for the given duration. + +@example +``` +import {delay} from 'unicorn-magic'; + +await delay({seconds: 1}); + +console.log('1 second later'); +``` +*/ +export function delay(duration: {seconds: number} | {milliseconds: number}): Promise; diff --git a/node_modules/unicorn-magic/default.js b/node_modules/unicorn-magic/default.js new file mode 100644 index 0000000000..7bd408832c --- /dev/null +++ b/node_modules/unicorn-magic/default.js @@ -0,0 +1,14 @@ +export async function delay({seconds, milliseconds} = {}) { + let duration; + if (typeof seconds === 'number') { + duration = seconds * 1000; + } else if (typeof milliseconds === 'number') { + duration = milliseconds; + } else { + throw new TypeError('Expected an object with either `seconds` or `milliseconds`.'); + } + + return new Promise(resolve => { + setTimeout(resolve, duration); + }); +} diff --git a/node_modules/unicorn-magic/license b/node_modules/unicorn-magic/license new file mode 100644 index 0000000000..fa7ceba3eb --- /dev/null +++ b/node_modules/unicorn-magic/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/unicorn-magic/node.d.ts b/node_modules/unicorn-magic/node.d.ts new file mode 100644 index 0000000000..a411fa22ee --- /dev/null +++ b/node_modules/unicorn-magic/node.d.ts @@ -0,0 +1,125 @@ +import { + type ExecFileOptionsWithStringEncoding, + type ExecFileSyncOptionsWithStringEncoding, + type PromiseWithChild, +} from 'node:child_process'; + +/** +Converts a `URL` or path to a path. + +__Not available in browsers.__ + +@example +``` +import path from 'node:path'; +import {toPath} from 'unicorn-magic'; + +// `cwd` can be `URL` or a path string. +const getUnicornPath = cwd => path.join(toPath(cwd), 'unicorn'); +``` +*/ +export function toPath(urlOrPath: URL | string): string; + +/** +Finds the root directory of the given path. + +__Not available in browsers.__ + +On Unix-based systems, the root is always `'/'`. +On Windows, the root varies and includes the drive letter (e.g., `'C:\\'`). + +This function operates purely on paths and does not interact with the file system. + +@param path - The path or URL to check. +@returns The root directory of the path. + +@example +``` +import {rootDirectory} from 'unicorn-magic'; + +console.log(rootDirectory('/Users/x/y/z')); +//=> '/' + +console.log(rootDirectory('C:\\Users\\x\\y\\z')); +//=> 'C:\\' +``` +*/ +export function rootDirectory(path: string | URL): string; + +/** +Creates an iterable for traversing from a given start path up to the root directory. + +__Not available in browsers.__ + +This function operates purely on paths and does not interact with the file system. + +@param startPath - The starting path. Can be relative. +@returns An iterable that iterates over each parent directory up to the root. + +Tip: To stop iteration before reaching the root, use a `break` statement within a conditional check. + +@example +``` +import {traversePathUp} from 'unicorn-magic'; + +for (const directory of traversePathUp('/Users/x/y/z')) { + console.log(directory); + //=> '/Users/x/y/z' + //=> '/Users/x/y' + //=> '/Users/x' + //=> '/Users' + //=> '/' +} +``` +*/ +export function traversePathUp(startPath: string | URL): Iterable; + +/** +Executes a file. + +Same as the built-in `execFile` but with: +- Promise API +- 10 MB `maxBuffer` instead of 1 MB + +@example +``` +import {execFile} from 'unicorn-magic'; + +console.log(await execFile('ls', ['-l'])); +``` + +__Not available in browsers.__ +*/ +export function execFile( + file: string, + arguments_: readonly string[], + options?: ExecFileOptionsWithStringEncoding +): PromiseWithChild<{ + stdout: string; + stderr: string; +}>; + +/** +Executes a file synchronously. + +Same as the built-in `execFileSync` but with: +- String output instead of buffer (same as `execFile`) +- Does not output `stderr` to the terminal by default (same as `execFile`) +- 10 MB `maxBuffer` instead of 1 MB + +@example +``` +import {execFileSync} from 'unicorn-magic'; + +console.log(execFileSync('ls', ['-l'])); +``` + +__Not available in browsers.__ +*/ +export function execFileSync( + file: string, + arguments_?: readonly string[], + options?: ExecFileSyncOptionsWithStringEncoding +): string; + +export * from './default.js'; diff --git a/node_modules/unicorn-magic/node.js b/node_modules/unicorn-magic/node.js new file mode 100644 index 0000000000..748b8a62b2 --- /dev/null +++ b/node_modules/unicorn-magic/node.js @@ -0,0 +1,49 @@ +import {promisify} from 'node:util'; +import {execFile as execFileCallback, execFileSync as execFileSyncOriginal} from 'node:child_process'; +import path from 'node:path'; +import {fileURLToPath} from 'node:url'; + +const execFileOriginal = promisify(execFileCallback); + +export function toPath(urlOrPath) { + return urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath; +} + +export function rootDirectory(pathInput) { + return path.parse(toPath(pathInput)).root; +} + +export function traversePathUp(startPath) { + return { + * [Symbol.iterator]() { + let currentPath = path.resolve(toPath(startPath)); + let previousPath; + + while (previousPath !== currentPath) { + yield currentPath; + previousPath = currentPath; + currentPath = path.resolve(currentPath, '..'); + } + }, + }; +} + +const TEN_MEGABYTES_IN_BYTES = 10 * 1024 * 1024; + +export async function execFile(file, arguments_, options = {}) { + return execFileOriginal(file, arguments_, { + maxBuffer: TEN_MEGABYTES_IN_BYTES, + ...options, + }); +} + +export function execFileSync(file, arguments_ = [], options = {}) { + return execFileSyncOriginal(file, arguments_, { + maxBuffer: TEN_MEGABYTES_IN_BYTES, + encoding: 'utf8', + stdio: 'pipe', + ...options, + }); +} + +export * from './default.js'; diff --git a/node_modules/unicorn-magic/package.json b/node_modules/unicorn-magic/package.json new file mode 100644 index 0000000000..7d6b305d32 --- /dev/null +++ b/node_modules/unicorn-magic/package.json @@ -0,0 +1,62 @@ +{ + "name": "unicorn-magic", + "version": "0.3.0", + "description": "Some useful utilities I often need", + "license": "MIT", + "repository": "sindresorhus/unicorn-magic", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "node": { + "types": "./node.d.ts", + "import": "./node.js" + }, + "default": { + "types": "./default.d.ts", + "import": "./default.js" + } + }, + "sideEffects": false, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && ava && tsc node.d.ts" + }, + "files": [ + "node.js", + "node.d.ts", + "default.js", + "default.d.ts" + ], + "keywords": [ + "utilities", + "util", + "extras", + "url", + "path", + "delay", + "wait", + "settimeout", + "sleep", + "child_process", + "child", + "process", + "subprocess", + "exec", + "execfile", + "execfilesync" + ], + "devDependencies": { + "ava": "^6.1.3", + "in-range": "^3.0.0", + "time-span": "^5.1.0", + "typescript": "^5.5.4", + "xo": "^0.59.2" + } +} diff --git a/node_modules/unicorn-magic/readme.md b/node_modules/unicorn-magic/readme.md new file mode 100644 index 0000000000..633fc4015c --- /dev/null +++ b/node_modules/unicorn-magic/readme.md @@ -0,0 +1,25 @@ +# unicorn-magic + +> Some useful utilities I often need + +*I'm not accepting requests.* + +## Install + +```sh +npm install unicorn-magic +``` + +## Usage + +```js +import {delay} from 'unicorn-magic'; + +await delay({seconds: 1}); + +console.log('1 second later'); +``` + +## API + +See [the types](index.d.ts). diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/LICENSE.txt b/node_modules/write-file-atomic/node_modules/signal-exit/LICENSE.txt deleted file mode 100644 index 954f2fa823..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/LICENSE.txt +++ /dev/null @@ -1,16 +0,0 @@ -The ISC License - -Copyright (c) 2015-2023 Benjamin Coe, Isaac Z. Schlueter, and Contributors - -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice -appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE -LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/README.md b/node_modules/write-file-atomic/node_modules/signal-exit/README.md deleted file mode 100644 index f8e6d9d2b7..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# signal-exit - -When you want to fire an event no matter how a process exits: - -- reaching the end of execution. -- explicitly having `process.exit(code)` called. -- having `process.kill(pid, sig)` called. -- receiving a fatal signal from outside the process - -Use `signal-exit`. - -```js -// Hybrid module, either works -import { onExit } from 'signal-exit' -// or: -// const { onExit } = require('signal-exit') - -onExit((code, signal) => { - console.log('process exited!', code, signal) -}) -``` - -## API - -`remove = onExit((code, signal) => {}, options)` - -The return value of the function is a function that will remove -the handler. - -Note that the function _only_ fires for signals if the signal -would cause the process to exit. That is, there are no other -listeners, and it is a fatal signal. - -If the global `process` object is not suitable for this purpose -(ie, it's unset, or doesn't have an `emit` method, etc.) then the -`onExit` function is a no-op that returns a no-op `remove` method. - -### Options - -- `alwaysLast`: Run this handler after any other signal or exit - handlers. This causes `process.emit` to be monkeypatched. - -### Browser Fallback - -The `'signal-exit/browser'` module is the same fallback shim that -just doesn't do anything, but presents the same function -interface. - -Patches welcome to add something that hooks onto -`window.onbeforeunload` or similar, but it might just not be a -thing that makes sense there. diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.d.ts b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.d.ts deleted file mode 100644 index 90f2e3f112..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * This is a browser shim that provides the same functional interface - * as the main node export, but it does nothing. - * @module - */ -import type { Handler } from './index.js'; -export declare const onExit: (cb: Handler, opts: { - alwaysLast?: boolean; -}) => () => void; -export declare const load: () => void; -export declare const unload: () => void; -//# sourceMappingURL=browser.d.ts.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.d.ts.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.d.ts.map deleted file mode 100644 index aacc1d3b6d..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,eAAO,MAAM,MAAM,EAAE,CACnB,EAAE,EAAE,OAAO,EACX,IAAI,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,KAC3B,MAAM,IAAqB,CAAA;AAChC,eAAO,MAAM,IAAI,YAAW,CAAA;AAC5B,eAAO,MAAM,MAAM,YAAW,CAAA"} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.js b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.js deleted file mode 100644 index 614fbf0100..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.js +++ /dev/null @@ -1,10 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.unload = exports.load = exports.onExit = void 0; -const onExit = () => () => { }; -exports.onExit = onExit; -const load = () => { }; -exports.load = load; -const unload = () => { }; -exports.unload = unload; -//# sourceMappingURL=browser.js.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.js.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.js.map deleted file mode 100644 index 342cf2e20a..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/browser.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":";;;AAMO,MAAM,MAAM,GAGD,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC,CAAA;AAHnB,QAAA,MAAM,UAGa;AACzB,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAAf,QAAA,IAAI,QAAW;AACrB,MAAM,MAAM,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAAjB,QAAA,MAAM,UAAW","sourcesContent":["/**\n * This is a browser shim that provides the same functional interface\n * as the main node export, but it does nothing.\n * @module\n */\nimport type { Handler } from './index.js'\nexport const onExit: (\n cb: Handler,\n opts: { alwaysLast?: boolean }\n) => () => void = () => () => {}\nexport const load = () => {}\nexport const unload = () => {}\n"]} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.d.ts b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.d.ts deleted file mode 100644 index 18a4cc653b..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -/// -import { signals } from './signals.js'; -export { signals }; -/** - * A function that takes an exit code and signal as arguments - */ -export type Handler = (code: number | null | undefined, signal: NodeJS.Signals | null) => any; -export declare const -/** - * Called when the process is exiting, whether via signal, explicit - * exit, or running out of stuff to do. - * - * If the global process object is not suitable for instrumentation, - * then this will be a no-op. - * - * Returns a function that may be used to unload signal-exit. - */ -onExit: (cb: Handler, opts?: { - alwaysLast?: boolean | undefined; -} | undefined) => () => void, -/** - * Load the listeners. Likely you never need to call this, unless - * doing a rather deep integration with signal-exit functionality. - * Mostly exposed for the benefit of testing. - * - * @internal - */ -load: () => void, -/** - * Unload the listeners. Likely you never need to call this, unless - * doing a rather deep integration with signal-exit functionality. - * Mostly exposed for the benefit of testing. - * - * @internal - */ -unload: () => void; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.d.ts.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.d.ts.map deleted file mode 100644 index ee8640d9e6..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,CAAA;AAuBlB;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,CACpB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,KAC1B,GAAG,CAAA;AAmQR,eAAO;AACL;;;;;;;;GAQG;AACH,MAAM,OAnMO,OAAO;;wBAPiD,IAAI;AA4MzE;;;;;;GAMG;AACH,IAAI;AAEJ;;;;;;GAMG;AACH,MAAM,YAGP,CAAA"} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.js b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.js deleted file mode 100644 index 9312d0c96e..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.js +++ /dev/null @@ -1,272 +0,0 @@ -"use strict"; -var _a; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.unload = exports.load = exports.onExit = exports.signals = void 0; -// Note: since nyc uses this module to output coverage, any lines -// that are in the direct sync flow of nyc's outputCoverage are -// ignored, since we can never get coverage for them. -// grab a reference to node's real process object right away -const signals_js_1 = require("./signals.js"); -Object.defineProperty(exports, "signals", { enumerable: true, get: function () { return signals_js_1.signals; } }); -const processOk = (process) => !!process && - typeof process === 'object' && - typeof process.removeListener === 'function' && - typeof process.emit === 'function' && - typeof process.reallyExit === 'function' && - typeof process.listeners === 'function' && - typeof process.kill === 'function' && - typeof process.pid === 'number' && - typeof process.on === 'function'; -const kExitEmitter = Symbol.for('signal-exit emitter'); -const global = globalThis; -const ObjectDefineProperty = Object.defineProperty.bind(Object); -// teeny tiny ee -class Emitter { - emitted = { - afterExit: false, - exit: false, - }; - listeners = { - afterExit: [], - exit: [], - }; - count = 0; - id = Math.random(); - constructor() { - if (global[kExitEmitter]) { - return global[kExitEmitter]; - } - ObjectDefineProperty(global, kExitEmitter, { - value: this, - writable: false, - enumerable: false, - configurable: false, - }); - } - on(ev, fn) { - this.listeners[ev].push(fn); - } - removeListener(ev, fn) { - const list = this.listeners[ev]; - const i = list.indexOf(fn); - /* c8 ignore start */ - if (i === -1) { - return; - } - /* c8 ignore stop */ - if (i === 0 && list.length === 1) { - list.length = 0; - } - else { - list.splice(i, 1); - } - } - emit(ev, code, signal) { - if (this.emitted[ev]) { - return; - } - this.emitted[ev] = true; - for (const fn of this.listeners[ev]) { - fn(code, signal); - } - } -} -class SignalExitBase { -} -const signalExitWrap = (handler) => { - return { - onExit(cb, opts) { - return handler.onExit(cb, opts); - }, - load() { - return handler.load(); - }, - unload() { - return handler.unload(); - }, - }; -}; -class SignalExitFallback extends SignalExitBase { - onExit() { - return () => { }; - } - load() { } - unload() { } -} -class SignalExit extends SignalExitBase { - // "SIGHUP" throws an `ENOSYS` error on Windows, - // so use a supported signal instead - /* c8 ignore start */ - #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'; - /* c8 ignore stop */ - #emitter = new Emitter(); - #process; - #originalProcessEmit; - #originalProcessReallyExit; - #sigListeners = {}; - #loaded = false; - constructor(process) { - super(); - this.#process = process; - // { : , ... } - this.#sigListeners = {}; - for (const sig of signals_js_1.signals) { - this.#sigListeners[sig] = () => { - // If there are no other listeners, an exit is coming! - // Simplest way: remove us and then re-send the signal. - // We know that this will kill the process, so we can - // safely emit now. - const listeners = this.#process.listeners(sig); - let { count } = this.#emitter; - // This is a workaround for the fact that signal-exit v3 and signal - // exit v4 are not aware of each other, and each will attempt to let - // the other handle it, so neither of them do. To correct this, we - // detect if we're the only handler *except* for previous versions - // of signal-exit. - /* c8 ignore start */ - //@ts-ignore - if (typeof process.__signal_exit_emitter__ === 'object') - count++; - /* c8 ignore stop */ - if (listeners.length === count) { - this.unload(); - this.#emitter.emit('exit', null, sig); - this.#emitter.emit('afterExit', null, sig); - /* c8 ignore start */ - process.kill(process.pid, sig === 'SIGHUP' ? this.#hupSig : sig); - /* c8 ignore stop */ - } - }; - } - this.#originalProcessReallyExit = process.reallyExit; - this.#originalProcessEmit = process.emit; - } - onExit(cb, opts) { - /* c8 ignore start */ - if (!processOk(this.#process)) { - return () => { }; - } - /* c8 ignore stop */ - if (this.#loaded === false) { - this.load(); - } - const ev = opts?.alwaysLast ? 'afterExit' : 'exit'; - this.#emitter.on(ev, cb); - return () => { - this.#emitter.removeListener(ev, cb); - if (this.#emitter.listeners['exit'].length === 0 && - this.#emitter.listeners['afterExit'].length === 0) { - this.unload(); - } - }; - } - load() { - if (this.#loaded) { - return; - } - this.#loaded = true; - // This is the number of onSignalExit's that are in play. - // It's important so that we can count the correct number of - // listeners on signals, and don't wait for the other one to - // handle it instead of us. - this.#emitter.count += 1; - for (const sig of signals_js_1.signals) { - try { - const fn = this.#sigListeners[sig]; - if (fn) - this.#process.on(sig, fn); - } - catch (_) { } - } - this.#process.emit = (ev, ...a) => { - return this.#processEmit(ev, ...a); - }; - this.#process.reallyExit = (code) => { - return this.#processReallyExit(code); - }; - } - unload() { - if (!this.#loaded) { - return; - } - this.#loaded = false; - signals_js_1.signals.forEach(sig => { - const listener = this.#sigListeners[sig]; - /* c8 ignore start */ - if (!listener) { - throw new Error('Listener not defined for signal: ' + sig); - } - /* c8 ignore stop */ - try { - this.#process.removeListener(sig, listener); - /* c8 ignore start */ - } - catch (_) { } - /* c8 ignore stop */ - }); - this.#process.emit = this.#originalProcessEmit; - this.#process.reallyExit = this.#originalProcessReallyExit; - this.#emitter.count -= 1; - } - #processReallyExit(code) { - /* c8 ignore start */ - if (!processOk(this.#process)) { - return 0; - } - this.#process.exitCode = code || 0; - /* c8 ignore stop */ - this.#emitter.emit('exit', this.#process.exitCode, null); - this.#emitter.emit('afterExit', this.#process.exitCode, null); - return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode); - } - #processEmit(ev, ...args) { - const og = this.#originalProcessEmit; - if (ev === 'exit' && processOk(this.#process)) { - if (typeof args[0] === 'number') { - this.#process.exitCode = args[0]; - /* c8 ignore start */ - } - /* c8 ignore start */ - const ret = og.call(this.#process, ev, ...args); - /* c8 ignore start */ - this.#emitter.emit('exit', this.#process.exitCode, null); - this.#emitter.emit('afterExit', this.#process.exitCode, null); - /* c8 ignore stop */ - return ret; - } - else { - return og.call(this.#process, ev, ...args); - } - } -} -const process = globalThis.process; -// wrap so that we call the method on the actual handler, without -// exporting it directly. -_a = signalExitWrap(processOk(process) ? new SignalExit(process) : new SignalExitFallback()), -/** - * Called when the process is exiting, whether via signal, explicit - * exit, or running out of stuff to do. - * - * If the global process object is not suitable for instrumentation, - * then this will be a no-op. - * - * Returns a function that may be used to unload signal-exit. - */ -exports.onExit = _a.onExit, -/** - * Load the listeners. Likely you never need to call this, unless - * doing a rather deep integration with signal-exit functionality. - * Mostly exposed for the benefit of testing. - * - * @internal - */ -exports.load = _a.load, -/** - * Unload the listeners. Likely you never need to call this, unless - * doing a rather deep integration with signal-exit functionality. - * Mostly exposed for the benefit of testing. - * - * @internal - */ -exports.unload = _a.unload; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.js.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.js.map deleted file mode 100644 index ebaf7c6872..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Note: since nyc uses this module to output coverage, any lines\n// that are in the direct sync flow of nyc's outputCoverage are\n// ignored, since we can never get coverage for them.\n// grab a reference to node's real process object right away\nimport { signals } from './signals.js'\nexport { signals }\n\n// just a loosened process type so we can do some evil things\ntype ProcessRE = NodeJS.Process & {\n reallyExit: (code?: number | undefined | null) => any\n emit: (ev: string, ...a: any[]) => any\n}\n\nconst processOk = (process: any): process is ProcessRE =>\n !!process &&\n typeof process === 'object' &&\n typeof process.removeListener === 'function' &&\n typeof process.emit === 'function' &&\n typeof process.reallyExit === 'function' &&\n typeof process.listeners === 'function' &&\n typeof process.kill === 'function' &&\n typeof process.pid === 'number' &&\n typeof process.on === 'function'\n\nconst kExitEmitter = Symbol.for('signal-exit emitter')\nconst global: typeof globalThis & { [kExitEmitter]?: Emitter } = globalThis\nconst ObjectDefineProperty = Object.defineProperty.bind(Object)\n\n/**\n * A function that takes an exit code and signal as arguments\n */\nexport type Handler = (\n code: number | null | undefined,\n signal: NodeJS.Signals | null\n) => any\ntype ExitEvent = 'afterExit' | 'exit'\ntype Emitted = { [k in ExitEvent]: boolean }\ntype Listeners = { [k in ExitEvent]: Handler[] }\n\n// teeny tiny ee\nclass Emitter {\n emitted: Emitted = {\n afterExit: false,\n exit: false,\n }\n\n listeners: Listeners = {\n afterExit: [],\n exit: [],\n }\n\n count: number = 0\n id: number = Math.random()\n\n constructor() {\n if (global[kExitEmitter]) {\n return global[kExitEmitter]\n }\n ObjectDefineProperty(global, kExitEmitter, {\n value: this,\n writable: false,\n enumerable: false,\n configurable: false,\n })\n }\n\n on(ev: ExitEvent, fn: Handler) {\n this.listeners[ev].push(fn)\n }\n\n removeListener(ev: ExitEvent, fn: Handler) {\n const list = this.listeners[ev]\n const i = list.indexOf(fn)\n /* c8 ignore start */\n if (i === -1) {\n return\n }\n /* c8 ignore stop */\n if (i === 0 && list.length === 1) {\n list.length = 0\n } else {\n list.splice(i, 1)\n }\n }\n\n emit(\n ev: ExitEvent,\n code: number | null | undefined,\n signal: NodeJS.Signals | null\n ) {\n if (this.emitted[ev]) {\n return\n }\n this.emitted[ev] = true\n for (const fn of this.listeners[ev]) {\n fn(code, signal)\n }\n }\n}\n\nabstract class SignalExitBase {\n abstract onExit(cb: Handler, opts?: { alwaysLast?: boolean }): () => void\n abstract load(): void\n abstract unload(): void\n}\n\nconst signalExitWrap = (handler: T) => {\n return {\n onExit(cb: Handler, opts?: { alwaysLast?: boolean }) {\n return handler.onExit(cb, opts)\n },\n load() {\n return handler.load()\n },\n unload() {\n return handler.unload()\n },\n }\n}\n\nclass SignalExitFallback extends SignalExitBase {\n onExit() {\n return () => {}\n }\n load() {}\n unload() {}\n}\n\nclass SignalExit extends SignalExitBase {\n // \"SIGHUP\" throws an `ENOSYS` error on Windows,\n // so use a supported signal instead\n /* c8 ignore start */\n #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'\n /* c8 ignore stop */\n #emitter = new Emitter()\n #process: ProcessRE\n #originalProcessEmit: ProcessRE['emit']\n #originalProcessReallyExit: ProcessRE['reallyExit']\n\n #sigListeners: { [k in NodeJS.Signals]?: () => void } = {}\n #loaded: boolean = false\n\n constructor(process: ProcessRE) {\n super()\n this.#process = process\n // { : , ... }\n this.#sigListeners = {}\n for (const sig of signals) {\n this.#sigListeners[sig] = () => {\n // If there are no other listeners, an exit is coming!\n // Simplest way: remove us and then re-send the signal.\n // We know that this will kill the process, so we can\n // safely emit now.\n const listeners = this.#process.listeners(sig)\n let { count } = this.#emitter\n // This is a workaround for the fact that signal-exit v3 and signal\n // exit v4 are not aware of each other, and each will attempt to let\n // the other handle it, so neither of them do. To correct this, we\n // detect if we're the only handler *except* for previous versions\n // of signal-exit.\n /* c8 ignore start */\n //@ts-ignore\n if (typeof process.__signal_exit_emitter__ === 'object') count++\n /* c8 ignore stop */\n if (listeners.length === count) {\n this.unload()\n this.#emitter.emit('exit', null, sig)\n this.#emitter.emit('afterExit', null, sig)\n /* c8 ignore start */\n process.kill(process.pid, sig === 'SIGHUP' ? this.#hupSig : sig)\n /* c8 ignore stop */\n }\n }\n }\n\n this.#originalProcessReallyExit = process.reallyExit\n this.#originalProcessEmit = process.emit\n }\n\n onExit(cb: Handler, opts?: { alwaysLast?: boolean }) {\n /* c8 ignore start */\n if (!processOk(this.#process)) {\n return () => {}\n }\n /* c8 ignore stop */\n\n if (this.#loaded === false) {\n this.load()\n }\n\n const ev = opts?.alwaysLast ? 'afterExit' : 'exit'\n this.#emitter.on(ev, cb)\n return () => {\n this.#emitter.removeListener(ev, cb)\n if (\n this.#emitter.listeners['exit'].length === 0 &&\n this.#emitter.listeners['afterExit'].length === 0\n ) {\n this.unload()\n }\n }\n }\n\n load() {\n if (this.#loaded) {\n return\n }\n this.#loaded = true\n\n // This is the number of onSignalExit's that are in play.\n // It's important so that we can count the correct number of\n // listeners on signals, and don't wait for the other one to\n // handle it instead of us.\n this.#emitter.count += 1\n\n for (const sig of signals) {\n try {\n const fn = this.#sigListeners[sig]\n if (fn) this.#process.on(sig, fn)\n } catch (_) {}\n }\n\n this.#process.emit = (ev: string, ...a: any[]) => {\n return this.#processEmit(ev, ...a)\n }\n this.#process.reallyExit = (code?: number | null | undefined) => {\n return this.#processReallyExit(code)\n }\n }\n\n unload() {\n if (!this.#loaded) {\n return\n }\n this.#loaded = false\n\n signals.forEach(sig => {\n const listener = this.#sigListeners[sig]\n /* c8 ignore start */\n if (!listener) {\n throw new Error('Listener not defined for signal: ' + sig)\n }\n /* c8 ignore stop */\n try {\n this.#process.removeListener(sig, listener)\n /* c8 ignore start */\n } catch (_) {}\n /* c8 ignore stop */\n })\n this.#process.emit = this.#originalProcessEmit\n this.#process.reallyExit = this.#originalProcessReallyExit\n this.#emitter.count -= 1\n }\n\n #processReallyExit(code?: number | null | undefined) {\n /* c8 ignore start */\n if (!processOk(this.#process)) {\n return 0\n }\n this.#process.exitCode = code || 0\n /* c8 ignore stop */\n\n this.#emitter.emit('exit', this.#process.exitCode, null)\n this.#emitter.emit('afterExit', this.#process.exitCode, null)\n return this.#originalProcessReallyExit.call(\n this.#process,\n this.#process.exitCode\n )\n }\n\n #processEmit(ev: string, ...args: any[]): any {\n const og = this.#originalProcessEmit\n if (ev === 'exit' && processOk(this.#process)) {\n if (typeof args[0] === 'number') {\n this.#process.exitCode = args[0]\n /* c8 ignore start */\n }\n /* c8 ignore start */\n const ret = og.call(this.#process, ev, ...args)\n /* c8 ignore start */\n this.#emitter.emit('exit', this.#process.exitCode, null)\n this.#emitter.emit('afterExit', this.#process.exitCode, null)\n /* c8 ignore stop */\n return ret\n } else {\n return og.call(this.#process, ev, ...args)\n }\n }\n}\n\nconst process = globalThis.process\n// wrap so that we call the method on the actual handler, without\n// exporting it directly.\nexport const {\n /**\n * Called when the process is exiting, whether via signal, explicit\n * exit, or running out of stuff to do.\n *\n * If the global process object is not suitable for instrumentation,\n * then this will be a no-op.\n *\n * Returns a function that may be used to unload signal-exit.\n */\n onExit,\n\n /**\n * Load the listeners. Likely you never need to call this, unless\n * doing a rather deep integration with signal-exit functionality.\n * Mostly exposed for the benefit of testing.\n *\n * @internal\n */\n load,\n\n /**\n * Unload the listeners. Likely you never need to call this, unless\n * doing a rather deep integration with signal-exit functionality.\n * Mostly exposed for the benefit of testing.\n *\n * @internal\n */\n unload,\n} = signalExitWrap(\n processOk(process) ? new SignalExit(process) : new SignalExitFallback()\n)\n"]} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/package.json b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/package.json deleted file mode 100644 index 5bbefffbab..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "commonjs" -} diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.d.ts b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.d.ts deleted file mode 100644 index 3f01ef00de..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -/// -/** - * This is not the set of all possible signals. - * - * It IS, however, the set of all signals that trigger - * an exit on either Linux or BSD systems. Linux is a - * superset of the signal names supported on BSD, and - * the unknown signals just fail to register, so we can - * catch that easily enough. - * - * Windows signals are a different set, since there are - * signals that terminate Windows processes, but don't - * terminate (or don't even exist) on Posix systems. - * - * Don't bother with SIGKILL. It's uncatchable, which - * means that we can't fire any callbacks anyway. - * - * If a user does happen to register a handler on a non- - * fatal signal like SIGWINCH or something, and then - * exit, it'll end up firing `process.emit('exit')`, so - * the handler will be fired anyway. - * - * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised - * artificially, inherently leave the process in a - * state from which it is not safe to try and enter JS - * listeners. - */ -export declare const signals: NodeJS.Signals[]; -//# sourceMappingURL=signals.d.ts.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.d.ts.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.d.ts.map deleted file mode 100644 index 891fe1e682..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/signals.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,OAAO,EAAO,CAAA"} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.js b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.js deleted file mode 100644 index 28afc5027d..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.js +++ /dev/null @@ -1,42 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.signals = void 0; -/** - * This is not the set of all possible signals. - * - * It IS, however, the set of all signals that trigger - * an exit on either Linux or BSD systems. Linux is a - * superset of the signal names supported on BSD, and - * the unknown signals just fail to register, so we can - * catch that easily enough. - * - * Windows signals are a different set, since there are - * signals that terminate Windows processes, but don't - * terminate (or don't even exist) on Posix systems. - * - * Don't bother with SIGKILL. It's uncatchable, which - * means that we can't fire any callbacks anyway. - * - * If a user does happen to register a handler on a non- - * fatal signal like SIGWINCH or something, and then - * exit, it'll end up firing `process.emit('exit')`, so - * the handler will be fired anyway. - * - * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised - * artificially, inherently leave the process in a - * state from which it is not safe to try and enter JS - * listeners. - */ -exports.signals = []; -exports.signals.push('SIGHUP', 'SIGINT', 'SIGTERM'); -if (process.platform !== 'win32') { - exports.signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT' - // should detect profiler and enable/disable accordingly. - // see #21 - // 'SIGPROF' - ); -} -if (process.platform === 'linux') { - exports.signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT'); -} -//# sourceMappingURL=signals.js.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.js.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.js.map deleted file mode 100644 index 78c613f660..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/cjs/signals.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/signals.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACU,QAAA,OAAO,GAAqB,EAAE,CAAA;AAC3C,eAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;AAE3C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;IAChC,eAAO,CAAC,IAAI,CACV,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,QAAQ;IACR,yDAAyD;IACzD,UAAU;IACV,YAAY;KACb,CAAA;CACF;AAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;IAChC,eAAO,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;CACxD","sourcesContent":["/**\n * This is not the set of all possible signals.\n *\n * It IS, however, the set of all signals that trigger\n * an exit on either Linux or BSD systems. Linux is a\n * superset of the signal names supported on BSD, and\n * the unknown signals just fail to register, so we can\n * catch that easily enough.\n *\n * Windows signals are a different set, since there are\n * signals that terminate Windows processes, but don't\n * terminate (or don't even exist) on Posix systems.\n *\n * Don't bother with SIGKILL. It's uncatchable, which\n * means that we can't fire any callbacks anyway.\n *\n * If a user does happen to register a handler on a non-\n * fatal signal like SIGWINCH or something, and then\n * exit, it'll end up firing `process.emit('exit')`, so\n * the handler will be fired anyway.\n *\n * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised\n * artificially, inherently leave the process in a\n * state from which it is not safe to try and enter JS\n * listeners.\n */\nexport const signals: NodeJS.Signals[] = []\nsignals.push('SIGHUP', 'SIGINT', 'SIGTERM')\n\nif (process.platform !== 'win32') {\n signals.push(\n 'SIGALRM',\n 'SIGABRT',\n 'SIGVTALRM',\n 'SIGXCPU',\n 'SIGXFSZ',\n 'SIGUSR2',\n 'SIGTRAP',\n 'SIGSYS',\n 'SIGQUIT',\n 'SIGIOT'\n // should detect profiler and enable/disable accordingly.\n // see #21\n // 'SIGPROF'\n )\n}\n\nif (process.platform === 'linux') {\n signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT')\n}\n"]} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.d.ts b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.d.ts deleted file mode 100644 index 90f2e3f112..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * This is a browser shim that provides the same functional interface - * as the main node export, but it does nothing. - * @module - */ -import type { Handler } from './index.js'; -export declare const onExit: (cb: Handler, opts: { - alwaysLast?: boolean; -}) => () => void; -export declare const load: () => void; -export declare const unload: () => void; -//# sourceMappingURL=browser.d.ts.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.d.ts.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.d.ts.map deleted file mode 100644 index aacc1d3b6d..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,eAAO,MAAM,MAAM,EAAE,CACnB,EAAE,EAAE,OAAO,EACX,IAAI,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,KAC3B,MAAM,IAAqB,CAAA;AAChC,eAAO,MAAM,IAAI,YAAW,CAAA;AAC5B,eAAO,MAAM,MAAM,YAAW,CAAA"} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.js b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.js deleted file mode 100644 index 9c5f9b9e74..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.js +++ /dev/null @@ -1,4 +0,0 @@ -export const onExit = () => () => { }; -export const load = () => { }; -export const unload = () => { }; -//# sourceMappingURL=browser.js.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.js.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.js.map deleted file mode 100644 index b3ff303aff..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/browser.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,MAAM,GAGD,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC,CAAA;AAChC,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAC5B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA","sourcesContent":["/**\n * This is a browser shim that provides the same functional interface\n * as the main node export, but it does nothing.\n * @module\n */\nimport type { Handler } from './index.js'\nexport const onExit: (\n cb: Handler,\n opts: { alwaysLast?: boolean }\n) => () => void = () => () => {}\nexport const load = () => {}\nexport const unload = () => {}\n"]} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.d.ts b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.d.ts deleted file mode 100644 index 18a4cc653b..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -/// -import { signals } from './signals.js'; -export { signals }; -/** - * A function that takes an exit code and signal as arguments - */ -export type Handler = (code: number | null | undefined, signal: NodeJS.Signals | null) => any; -export declare const -/** - * Called when the process is exiting, whether via signal, explicit - * exit, or running out of stuff to do. - * - * If the global process object is not suitable for instrumentation, - * then this will be a no-op. - * - * Returns a function that may be used to unload signal-exit. - */ -onExit: (cb: Handler, opts?: { - alwaysLast?: boolean | undefined; -} | undefined) => () => void, -/** - * Load the listeners. Likely you never need to call this, unless - * doing a rather deep integration with signal-exit functionality. - * Mostly exposed for the benefit of testing. - * - * @internal - */ -load: () => void, -/** - * Unload the listeners. Likely you never need to call this, unless - * doing a rather deep integration with signal-exit functionality. - * Mostly exposed for the benefit of testing. - * - * @internal - */ -unload: () => void; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.d.ts.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.d.ts.map deleted file mode 100644 index ee8640d9e6..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,CAAA;AAuBlB;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,CACpB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,KAC1B,GAAG,CAAA;AAmQR,eAAO;AACL;;;;;;;;GAQG;AACH,MAAM,OAnMO,OAAO;;wBAPiD,IAAI;AA4MzE;;;;;;GAMG;AACH,IAAI;AAEJ;;;;;;GAMG;AACH,MAAM,YAGP,CAAA"} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.js b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.js deleted file mode 100644 index 97f409239c..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.js +++ /dev/null @@ -1,268 +0,0 @@ -// Note: since nyc uses this module to output coverage, any lines -// that are in the direct sync flow of nyc's outputCoverage are -// ignored, since we can never get coverage for them. -// grab a reference to node's real process object right away -import { signals } from './signals.js'; -export { signals }; -const processOk = (process) => !!process && - typeof process === 'object' && - typeof process.removeListener === 'function' && - typeof process.emit === 'function' && - typeof process.reallyExit === 'function' && - typeof process.listeners === 'function' && - typeof process.kill === 'function' && - typeof process.pid === 'number' && - typeof process.on === 'function'; -const kExitEmitter = Symbol.for('signal-exit emitter'); -const global = globalThis; -const ObjectDefineProperty = Object.defineProperty.bind(Object); -// teeny tiny ee -class Emitter { - emitted = { - afterExit: false, - exit: false, - }; - listeners = { - afterExit: [], - exit: [], - }; - count = 0; - id = Math.random(); - constructor() { - if (global[kExitEmitter]) { - return global[kExitEmitter]; - } - ObjectDefineProperty(global, kExitEmitter, { - value: this, - writable: false, - enumerable: false, - configurable: false, - }); - } - on(ev, fn) { - this.listeners[ev].push(fn); - } - removeListener(ev, fn) { - const list = this.listeners[ev]; - const i = list.indexOf(fn); - /* c8 ignore start */ - if (i === -1) { - return; - } - /* c8 ignore stop */ - if (i === 0 && list.length === 1) { - list.length = 0; - } - else { - list.splice(i, 1); - } - } - emit(ev, code, signal) { - if (this.emitted[ev]) { - return; - } - this.emitted[ev] = true; - for (const fn of this.listeners[ev]) { - fn(code, signal); - } - } -} -class SignalExitBase { -} -const signalExitWrap = (handler) => { - return { - onExit(cb, opts) { - return handler.onExit(cb, opts); - }, - load() { - return handler.load(); - }, - unload() { - return handler.unload(); - }, - }; -}; -class SignalExitFallback extends SignalExitBase { - onExit() { - return () => { }; - } - load() { } - unload() { } -} -class SignalExit extends SignalExitBase { - // "SIGHUP" throws an `ENOSYS` error on Windows, - // so use a supported signal instead - /* c8 ignore start */ - #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'; - /* c8 ignore stop */ - #emitter = new Emitter(); - #process; - #originalProcessEmit; - #originalProcessReallyExit; - #sigListeners = {}; - #loaded = false; - constructor(process) { - super(); - this.#process = process; - // { : , ... } - this.#sigListeners = {}; - for (const sig of signals) { - this.#sigListeners[sig] = () => { - // If there are no other listeners, an exit is coming! - // Simplest way: remove us and then re-send the signal. - // We know that this will kill the process, so we can - // safely emit now. - const listeners = this.#process.listeners(sig); - let { count } = this.#emitter; - // This is a workaround for the fact that signal-exit v3 and signal - // exit v4 are not aware of each other, and each will attempt to let - // the other handle it, so neither of them do. To correct this, we - // detect if we're the only handler *except* for previous versions - // of signal-exit. - /* c8 ignore start */ - //@ts-ignore - if (typeof process.__signal_exit_emitter__ === 'object') - count++; - /* c8 ignore stop */ - if (listeners.length === count) { - this.unload(); - this.#emitter.emit('exit', null, sig); - this.#emitter.emit('afterExit', null, sig); - /* c8 ignore start */ - process.kill(process.pid, sig === 'SIGHUP' ? this.#hupSig : sig); - /* c8 ignore stop */ - } - }; - } - this.#originalProcessReallyExit = process.reallyExit; - this.#originalProcessEmit = process.emit; - } - onExit(cb, opts) { - /* c8 ignore start */ - if (!processOk(this.#process)) { - return () => { }; - } - /* c8 ignore stop */ - if (this.#loaded === false) { - this.load(); - } - const ev = opts?.alwaysLast ? 'afterExit' : 'exit'; - this.#emitter.on(ev, cb); - return () => { - this.#emitter.removeListener(ev, cb); - if (this.#emitter.listeners['exit'].length === 0 && - this.#emitter.listeners['afterExit'].length === 0) { - this.unload(); - } - }; - } - load() { - if (this.#loaded) { - return; - } - this.#loaded = true; - // This is the number of onSignalExit's that are in play. - // It's important so that we can count the correct number of - // listeners on signals, and don't wait for the other one to - // handle it instead of us. - this.#emitter.count += 1; - for (const sig of signals) { - try { - const fn = this.#sigListeners[sig]; - if (fn) - this.#process.on(sig, fn); - } - catch (_) { } - } - this.#process.emit = (ev, ...a) => { - return this.#processEmit(ev, ...a); - }; - this.#process.reallyExit = (code) => { - return this.#processReallyExit(code); - }; - } - unload() { - if (!this.#loaded) { - return; - } - this.#loaded = false; - signals.forEach(sig => { - const listener = this.#sigListeners[sig]; - /* c8 ignore start */ - if (!listener) { - throw new Error('Listener not defined for signal: ' + sig); - } - /* c8 ignore stop */ - try { - this.#process.removeListener(sig, listener); - /* c8 ignore start */ - } - catch (_) { } - /* c8 ignore stop */ - }); - this.#process.emit = this.#originalProcessEmit; - this.#process.reallyExit = this.#originalProcessReallyExit; - this.#emitter.count -= 1; - } - #processReallyExit(code) { - /* c8 ignore start */ - if (!processOk(this.#process)) { - return 0; - } - this.#process.exitCode = code || 0; - /* c8 ignore stop */ - this.#emitter.emit('exit', this.#process.exitCode, null); - this.#emitter.emit('afterExit', this.#process.exitCode, null); - return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode); - } - #processEmit(ev, ...args) { - const og = this.#originalProcessEmit; - if (ev === 'exit' && processOk(this.#process)) { - if (typeof args[0] === 'number') { - this.#process.exitCode = args[0]; - /* c8 ignore start */ - } - /* c8 ignore start */ - const ret = og.call(this.#process, ev, ...args); - /* c8 ignore start */ - this.#emitter.emit('exit', this.#process.exitCode, null); - this.#emitter.emit('afterExit', this.#process.exitCode, null); - /* c8 ignore stop */ - return ret; - } - else { - return og.call(this.#process, ev, ...args); - } - } -} -const process = globalThis.process; -// wrap so that we call the method on the actual handler, without -// exporting it directly. -export const { -/** - * Called when the process is exiting, whether via signal, explicit - * exit, or running out of stuff to do. - * - * If the global process object is not suitable for instrumentation, - * then this will be a no-op. - * - * Returns a function that may be used to unload signal-exit. - */ -onExit, -/** - * Load the listeners. Likely you never need to call this, unless - * doing a rather deep integration with signal-exit functionality. - * Mostly exposed for the benefit of testing. - * - * @internal - */ -load, -/** - * Unload the listeners. Likely you never need to call this, unless - * doing a rather deep integration with signal-exit functionality. - * Mostly exposed for the benefit of testing. - * - * @internal - */ -unload, } = signalExitWrap(processOk(process) ? new SignalExit(process) : new SignalExitFallback()); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.js.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.js.map deleted file mode 100644 index 718ba2d5cb..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Note: since nyc uses this module to output coverage, any lines\n// that are in the direct sync flow of nyc's outputCoverage are\n// ignored, since we can never get coverage for them.\n// grab a reference to node's real process object right away\nimport { signals } from './signals.js'\nexport { signals }\n\n// just a loosened process type so we can do some evil things\ntype ProcessRE = NodeJS.Process & {\n reallyExit: (code?: number | undefined | null) => any\n emit: (ev: string, ...a: any[]) => any\n}\n\nconst processOk = (process: any): process is ProcessRE =>\n !!process &&\n typeof process === 'object' &&\n typeof process.removeListener === 'function' &&\n typeof process.emit === 'function' &&\n typeof process.reallyExit === 'function' &&\n typeof process.listeners === 'function' &&\n typeof process.kill === 'function' &&\n typeof process.pid === 'number' &&\n typeof process.on === 'function'\n\nconst kExitEmitter = Symbol.for('signal-exit emitter')\nconst global: typeof globalThis & { [kExitEmitter]?: Emitter } = globalThis\nconst ObjectDefineProperty = Object.defineProperty.bind(Object)\n\n/**\n * A function that takes an exit code and signal as arguments\n */\nexport type Handler = (\n code: number | null | undefined,\n signal: NodeJS.Signals | null\n) => any\ntype ExitEvent = 'afterExit' | 'exit'\ntype Emitted = { [k in ExitEvent]: boolean }\ntype Listeners = { [k in ExitEvent]: Handler[] }\n\n// teeny tiny ee\nclass Emitter {\n emitted: Emitted = {\n afterExit: false,\n exit: false,\n }\n\n listeners: Listeners = {\n afterExit: [],\n exit: [],\n }\n\n count: number = 0\n id: number = Math.random()\n\n constructor() {\n if (global[kExitEmitter]) {\n return global[kExitEmitter]\n }\n ObjectDefineProperty(global, kExitEmitter, {\n value: this,\n writable: false,\n enumerable: false,\n configurable: false,\n })\n }\n\n on(ev: ExitEvent, fn: Handler) {\n this.listeners[ev].push(fn)\n }\n\n removeListener(ev: ExitEvent, fn: Handler) {\n const list = this.listeners[ev]\n const i = list.indexOf(fn)\n /* c8 ignore start */\n if (i === -1) {\n return\n }\n /* c8 ignore stop */\n if (i === 0 && list.length === 1) {\n list.length = 0\n } else {\n list.splice(i, 1)\n }\n }\n\n emit(\n ev: ExitEvent,\n code: number | null | undefined,\n signal: NodeJS.Signals | null\n ) {\n if (this.emitted[ev]) {\n return\n }\n this.emitted[ev] = true\n for (const fn of this.listeners[ev]) {\n fn(code, signal)\n }\n }\n}\n\nabstract class SignalExitBase {\n abstract onExit(cb: Handler, opts?: { alwaysLast?: boolean }): () => void\n abstract load(): void\n abstract unload(): void\n}\n\nconst signalExitWrap = (handler: T) => {\n return {\n onExit(cb: Handler, opts?: { alwaysLast?: boolean }) {\n return handler.onExit(cb, opts)\n },\n load() {\n return handler.load()\n },\n unload() {\n return handler.unload()\n },\n }\n}\n\nclass SignalExitFallback extends SignalExitBase {\n onExit() {\n return () => {}\n }\n load() {}\n unload() {}\n}\n\nclass SignalExit extends SignalExitBase {\n // \"SIGHUP\" throws an `ENOSYS` error on Windows,\n // so use a supported signal instead\n /* c8 ignore start */\n #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'\n /* c8 ignore stop */\n #emitter = new Emitter()\n #process: ProcessRE\n #originalProcessEmit: ProcessRE['emit']\n #originalProcessReallyExit: ProcessRE['reallyExit']\n\n #sigListeners: { [k in NodeJS.Signals]?: () => void } = {}\n #loaded: boolean = false\n\n constructor(process: ProcessRE) {\n super()\n this.#process = process\n // { : , ... }\n this.#sigListeners = {}\n for (const sig of signals) {\n this.#sigListeners[sig] = () => {\n // If there are no other listeners, an exit is coming!\n // Simplest way: remove us and then re-send the signal.\n // We know that this will kill the process, so we can\n // safely emit now.\n const listeners = this.#process.listeners(sig)\n let { count } = this.#emitter\n // This is a workaround for the fact that signal-exit v3 and signal\n // exit v4 are not aware of each other, and each will attempt to let\n // the other handle it, so neither of them do. To correct this, we\n // detect if we're the only handler *except* for previous versions\n // of signal-exit.\n /* c8 ignore start */\n //@ts-ignore\n if (typeof process.__signal_exit_emitter__ === 'object') count++\n /* c8 ignore stop */\n if (listeners.length === count) {\n this.unload()\n this.#emitter.emit('exit', null, sig)\n this.#emitter.emit('afterExit', null, sig)\n /* c8 ignore start */\n process.kill(process.pid, sig === 'SIGHUP' ? this.#hupSig : sig)\n /* c8 ignore stop */\n }\n }\n }\n\n this.#originalProcessReallyExit = process.reallyExit\n this.#originalProcessEmit = process.emit\n }\n\n onExit(cb: Handler, opts?: { alwaysLast?: boolean }) {\n /* c8 ignore start */\n if (!processOk(this.#process)) {\n return () => {}\n }\n /* c8 ignore stop */\n\n if (this.#loaded === false) {\n this.load()\n }\n\n const ev = opts?.alwaysLast ? 'afterExit' : 'exit'\n this.#emitter.on(ev, cb)\n return () => {\n this.#emitter.removeListener(ev, cb)\n if (\n this.#emitter.listeners['exit'].length === 0 &&\n this.#emitter.listeners['afterExit'].length === 0\n ) {\n this.unload()\n }\n }\n }\n\n load() {\n if (this.#loaded) {\n return\n }\n this.#loaded = true\n\n // This is the number of onSignalExit's that are in play.\n // It's important so that we can count the correct number of\n // listeners on signals, and don't wait for the other one to\n // handle it instead of us.\n this.#emitter.count += 1\n\n for (const sig of signals) {\n try {\n const fn = this.#sigListeners[sig]\n if (fn) this.#process.on(sig, fn)\n } catch (_) {}\n }\n\n this.#process.emit = (ev: string, ...a: any[]) => {\n return this.#processEmit(ev, ...a)\n }\n this.#process.reallyExit = (code?: number | null | undefined) => {\n return this.#processReallyExit(code)\n }\n }\n\n unload() {\n if (!this.#loaded) {\n return\n }\n this.#loaded = false\n\n signals.forEach(sig => {\n const listener = this.#sigListeners[sig]\n /* c8 ignore start */\n if (!listener) {\n throw new Error('Listener not defined for signal: ' + sig)\n }\n /* c8 ignore stop */\n try {\n this.#process.removeListener(sig, listener)\n /* c8 ignore start */\n } catch (_) {}\n /* c8 ignore stop */\n })\n this.#process.emit = this.#originalProcessEmit\n this.#process.reallyExit = this.#originalProcessReallyExit\n this.#emitter.count -= 1\n }\n\n #processReallyExit(code?: number | null | undefined) {\n /* c8 ignore start */\n if (!processOk(this.#process)) {\n return 0\n }\n this.#process.exitCode = code || 0\n /* c8 ignore stop */\n\n this.#emitter.emit('exit', this.#process.exitCode, null)\n this.#emitter.emit('afterExit', this.#process.exitCode, null)\n return this.#originalProcessReallyExit.call(\n this.#process,\n this.#process.exitCode\n )\n }\n\n #processEmit(ev: string, ...args: any[]): any {\n const og = this.#originalProcessEmit\n if (ev === 'exit' && processOk(this.#process)) {\n if (typeof args[0] === 'number') {\n this.#process.exitCode = args[0]\n /* c8 ignore start */\n }\n /* c8 ignore start */\n const ret = og.call(this.#process, ev, ...args)\n /* c8 ignore start */\n this.#emitter.emit('exit', this.#process.exitCode, null)\n this.#emitter.emit('afterExit', this.#process.exitCode, null)\n /* c8 ignore stop */\n return ret\n } else {\n return og.call(this.#process, ev, ...args)\n }\n }\n}\n\nconst process = globalThis.process\n// wrap so that we call the method on the actual handler, without\n// exporting it directly.\nexport const {\n /**\n * Called when the process is exiting, whether via signal, explicit\n * exit, or running out of stuff to do.\n *\n * If the global process object is not suitable for instrumentation,\n * then this will be a no-op.\n *\n * Returns a function that may be used to unload signal-exit.\n */\n onExit,\n\n /**\n * Load the listeners. Likely you never need to call this, unless\n * doing a rather deep integration with signal-exit functionality.\n * Mostly exposed for the benefit of testing.\n *\n * @internal\n */\n load,\n\n /**\n * Unload the listeners. Likely you never need to call this, unless\n * doing a rather deep integration with signal-exit functionality.\n * Mostly exposed for the benefit of testing.\n *\n * @internal\n */\n unload,\n} = signalExitWrap(\n processOk(process) ? new SignalExit(process) : new SignalExitFallback()\n)\n"]} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/package.json b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/package.json deleted file mode 100644 index 3dbc1ca591..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.d.ts b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.d.ts deleted file mode 100644 index 3f01ef00de..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -/// -/** - * This is not the set of all possible signals. - * - * It IS, however, the set of all signals that trigger - * an exit on either Linux or BSD systems. Linux is a - * superset of the signal names supported on BSD, and - * the unknown signals just fail to register, so we can - * catch that easily enough. - * - * Windows signals are a different set, since there are - * signals that terminate Windows processes, but don't - * terminate (or don't even exist) on Posix systems. - * - * Don't bother with SIGKILL. It's uncatchable, which - * means that we can't fire any callbacks anyway. - * - * If a user does happen to register a handler on a non- - * fatal signal like SIGWINCH or something, and then - * exit, it'll end up firing `process.emit('exit')`, so - * the handler will be fired anyway. - * - * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised - * artificially, inherently leave the process in a - * state from which it is not safe to try and enter JS - * listeners. - */ -export declare const signals: NodeJS.Signals[]; -//# sourceMappingURL=signals.d.ts.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.d.ts.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.d.ts.map deleted file mode 100644 index 891fe1e682..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/signals.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,OAAO,EAAO,CAAA"} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.js b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.js deleted file mode 100644 index 7dbf15a5a6..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * This is not the set of all possible signals. - * - * It IS, however, the set of all signals that trigger - * an exit on either Linux or BSD systems. Linux is a - * superset of the signal names supported on BSD, and - * the unknown signals just fail to register, so we can - * catch that easily enough. - * - * Windows signals are a different set, since there are - * signals that terminate Windows processes, but don't - * terminate (or don't even exist) on Posix systems. - * - * Don't bother with SIGKILL. It's uncatchable, which - * means that we can't fire any callbacks anyway. - * - * If a user does happen to register a handler on a non- - * fatal signal like SIGWINCH or something, and then - * exit, it'll end up firing `process.emit('exit')`, so - * the handler will be fired anyway. - * - * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised - * artificially, inherently leave the process in a - * state from which it is not safe to try and enter JS - * listeners. - */ -export const signals = []; -signals.push('SIGHUP', 'SIGINT', 'SIGTERM'); -if (process.platform !== 'win32') { - signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT' - // should detect profiler and enable/disable accordingly. - // see #21 - // 'SIGPROF' - ); -} -if (process.platform === 'linux') { - signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT'); -} -//# sourceMappingURL=signals.js.map \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.js.map b/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.js.map deleted file mode 100644 index 91008c9174..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/dist/mjs/signals.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/signals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,OAAO,GAAqB,EAAE,CAAA;AAC3C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;AAE3C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;IAChC,OAAO,CAAC,IAAI,CACV,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,QAAQ;IACR,yDAAyD;IACzD,UAAU;IACV,YAAY;KACb,CAAA;CACF;AAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;IAChC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;CACxD","sourcesContent":["/**\n * This is not the set of all possible signals.\n *\n * It IS, however, the set of all signals that trigger\n * an exit on either Linux or BSD systems. Linux is a\n * superset of the signal names supported on BSD, and\n * the unknown signals just fail to register, so we can\n * catch that easily enough.\n *\n * Windows signals are a different set, since there are\n * signals that terminate Windows processes, but don't\n * terminate (or don't even exist) on Posix systems.\n *\n * Don't bother with SIGKILL. It's uncatchable, which\n * means that we can't fire any callbacks anyway.\n *\n * If a user does happen to register a handler on a non-\n * fatal signal like SIGWINCH or something, and then\n * exit, it'll end up firing `process.emit('exit')`, so\n * the handler will be fired anyway.\n *\n * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised\n * artificially, inherently leave the process in a\n * state from which it is not safe to try and enter JS\n * listeners.\n */\nexport const signals: NodeJS.Signals[] = []\nsignals.push('SIGHUP', 'SIGINT', 'SIGTERM')\n\nif (process.platform !== 'win32') {\n signals.push(\n 'SIGALRM',\n 'SIGABRT',\n 'SIGVTALRM',\n 'SIGXCPU',\n 'SIGXFSZ',\n 'SIGUSR2',\n 'SIGTRAP',\n 'SIGSYS',\n 'SIGQUIT',\n 'SIGIOT'\n // should detect profiler and enable/disable accordingly.\n // see #21\n // 'SIGPROF'\n )\n}\n\nif (process.platform === 'linux') {\n signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT')\n}\n"]} \ No newline at end of file diff --git a/node_modules/write-file-atomic/node_modules/signal-exit/package.json b/node_modules/write-file-atomic/node_modules/signal-exit/package.json deleted file mode 100644 index 455452f96a..0000000000 --- a/node_modules/write-file-atomic/node_modules/signal-exit/package.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "name": "signal-exit", - "version": "4.0.2", - "description": "when you want to fire an event no matter how a process exits.", - "main": "./dist/cjs/index.js", - "module": "./dist/mjs/index.js", - "browser": "./dist/mjs/browser.js", - "types": "./dist/mjs/index.d.ts", - "exports": { - ".": { - "import": { - "types": "./dist/mjs/index.d.ts", - "default": "./dist/mjs/index.js" - }, - "require": { - "types": "./dist/cjs/index.d.ts", - "default": "./dist/cjs/index.js" - } - }, - "./signals": { - "import": { - "types": "./dist/mjs/signals.d.ts", - "default": "./dist/mjs/signals.js" - }, - "require": { - "types": "./dist/cjs/signals.d.ts", - "default": "./dist/cjs/signals.js" - } - }, - "./browser": { - "import": { - "types": "./dist/mjs/browser.d.ts", - "default": "./dist/mjs/browser.js" - }, - "require": { - "types": "./dist/cjs/browser.d.ts", - "default": "./dist/cjs/browser.js" - } - } - }, - "files": [ - "dist" - ], - "engines": { - "node": ">=14" - }, - "repository": { - "type": "git", - "url": "https://github.com/tapjs/signal-exit.git" - }, - "keywords": [ - "signal", - "exit" - ], - "author": "Ben Coe ", - "license": "ISC", - "devDependencies": { - "@types/cross-spawn": "^6.0.2", - "@types/node": "^18.15.11", - "@types/signal-exit": "^3.0.1", - "@types/tap": "^15.0.8", - "c8": "^7.13.0", - "prettier": "^2.8.6", - "tap": "^16.3.4", - "ts-node": "^10.9.1", - "typedoc": "^0.23.28", - "typescript": "^5.0.2" - }, - "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "preprepare": "rm -rf dist", - "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh", - "pretest": "npm run prepare", - "presnap": "npm run prepare", - "test": "c8 tap", - "snap": "c8 tap", - "format": "prettier --write . --loglevel warn", - "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" - }, - "prettier": { - "semi": false, - "printWidth": 75, - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "jsxSingleQuote": false, - "bracketSameLine": true, - "arrowParens": "avoid", - "endOfLine": "lf" - }, - "tap": { - "coverage": false, - "jobs": 1, - "node-arg": [ - "--no-warnings", - "--loader", - "ts-node/esm" - ], - "ts": false - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } -} diff --git a/node_modules/yoctocolors/base.d.ts b/node_modules/yoctocolors/base.d.ts new file mode 100644 index 0000000000..a0e3d38212 --- /dev/null +++ b/node_modules/yoctocolors/base.d.ts @@ -0,0 +1,47 @@ +export type Format = (string: string) => string; + +export const reset: Format; +export const bold: Format; +export const dim: Format; +export const italic: Format; +export const underline: Format; +export const overline: Format; +export const inverse: Format; +export const hidden: Format; +export const strikethrough: Format; + +export const black: Format; +export const red: Format; +export const green: Format; +export const yellow: Format; +export const blue: Format; +export const magenta: Format; +export const cyan: Format; +export const white: Format; +export const gray: Format; + +export const bgBlack: Format; +export const bgRed: Format; +export const bgGreen: Format; +export const bgYellow: Format; +export const bgBlue: Format; +export const bgMagenta: Format; +export const bgCyan: Format; +export const bgWhite: Format; +export const bgGray: Format; + +export const redBright: Format; +export const greenBright: Format; +export const yellowBright: Format; +export const blueBright: Format; +export const magentaBright: Format; +export const cyanBright: Format; +export const whiteBright: Format; + +export const bgRedBright: Format; +export const bgGreenBright: Format; +export const bgYellowBright: Format; +export const bgBlueBright: Format; +export const bgMagentaBright: Format; +export const bgCyanBright: Format; +export const bgWhiteBright: Format; diff --git a/node_modules/yoctocolors/base.js b/node_modules/yoctocolors/base.js new file mode 100644 index 0000000000..6126da3e46 --- /dev/null +++ b/node_modules/yoctocolors/base.js @@ -0,0 +1,89 @@ +import tty from 'node:tty'; + +// eslint-disable-next-line no-warning-comments +// TODO: Use a better method when it's added to Node.js (https://github.com/nodejs/node/pull/40240) +// Lots of optionals here to support Deno. +const hasColors = tty?.WriteStream?.prototype?.hasColors?.() ?? false; + +const format = (open, close) => { + if (!hasColors) { + return input => input; + } + + const openCode = `\u001B[${open}m`; + const closeCode = `\u001B[${close}m`; + + return input => { + const string = input + ''; // eslint-disable-line no-implicit-coercion -- This is faster. + let index = string.indexOf(closeCode); + + if (index === -1) { + // Note: Intentionally not using string interpolation for performance reasons. + return openCode + string + closeCode; + } + + // Handle nested colors. + + // We could have done this, but it's too slow (as of Node.js 22). + // return openCode + string.replaceAll(closeCode, openCode) + closeCode; + + let result = openCode; + let lastIndex = 0; + + while (index !== -1) { + result += string.slice(lastIndex, index) + openCode; + lastIndex = index + closeCode.length; + index = string.indexOf(closeCode, lastIndex); + } + + result += string.slice(lastIndex) + closeCode; + + return result; + }; +}; + +export const reset = format(0, 0); +export const bold = format(1, 22); +export const dim = format(2, 22); +export const italic = format(3, 23); +export const underline = format(4, 24); +export const overline = format(53, 55); +export const inverse = format(7, 27); +export const hidden = format(8, 28); +export const strikethrough = format(9, 29); + +export const black = format(30, 39); +export const red = format(31, 39); +export const green = format(32, 39); +export const yellow = format(33, 39); +export const blue = format(34, 39); +export const magenta = format(35, 39); +export const cyan = format(36, 39); +export const white = format(37, 39); +export const gray = format(90, 39); + +export const bgBlack = format(40, 49); +export const bgRed = format(41, 49); +export const bgGreen = format(42, 49); +export const bgYellow = format(43, 49); +export const bgBlue = format(44, 49); +export const bgMagenta = format(45, 49); +export const bgCyan = format(46, 49); +export const bgWhite = format(47, 49); +export const bgGray = format(100, 49); + +export const redBright = format(91, 39); +export const greenBright = format(92, 39); +export const yellowBright = format(93, 39); +export const blueBright = format(94, 39); +export const magentaBright = format(95, 39); +export const cyanBright = format(96, 39); +export const whiteBright = format(97, 39); + +export const bgRedBright = format(101, 49); +export const bgGreenBright = format(102, 49); +export const bgYellowBright = format(103, 49); +export const bgBlueBright = format(104, 49); +export const bgMagentaBright = format(105, 49); +export const bgCyanBright = format(106, 49); +export const bgWhiteBright = format(107, 49); diff --git a/node_modules/yoctocolors/index.d.ts b/node_modules/yoctocolors/index.d.ts new file mode 100644 index 0000000000..4ba092badf --- /dev/null +++ b/node_modules/yoctocolors/index.d.ts @@ -0,0 +1,2 @@ +export * from './base.js'; +export * as default from './base.js'; diff --git a/node_modules/yoctocolors/index.js b/node_modules/yoctocolors/index.js new file mode 100644 index 0000000000..4ba092badf --- /dev/null +++ b/node_modules/yoctocolors/index.js @@ -0,0 +1,2 @@ +export * from './base.js'; +export * as default from './base.js'; diff --git a/node_modules/yoctocolors/license b/node_modules/yoctocolors/license new file mode 100644 index 0000000000..fa7ceba3eb --- /dev/null +++ b/node_modules/yoctocolors/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/yoctocolors/package.json b/node_modules/yoctocolors/package.json new file mode 100644 index 0000000000..51acd2fe9d --- /dev/null +++ b/node_modules/yoctocolors/package.json @@ -0,0 +1,69 @@ +{ + "name": "yoctocolors", + "version": "2.1.1", + "description": "The smallest and fastest command-line coloring package on the internet", + "license": "MIT", + "repository": "sindresorhus/yoctocolors", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts", + "base.js", + "base.d.ts" + ], + "keywords": [ + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "string", + "ansi", + "style", + "styles", + "tty", + "formatting", + "shell", + "xterm", + "log", + "logging", + "command-line", + "text" + ], + "devDependencies": { + "@jonahsnider/benchmark": "^5.0.3", + "ansi-colors": "^4.1.3", + "ava": "^6.1.3", + "chalk": "^5.3.0", + "cli-color": "^2.0.4", + "colorette": "^2.0.20", + "kleur": "^4.1.5", + "nanocolors": "^0.2.13", + "picocolors": "^1.0.1", + "tsd": "^0.31.0", + "xo": "^0.58.0" + }, + "ava": { + "environmentVariables": { + "FORCE_COLOR": "1" + } + } +} diff --git a/node_modules/yoctocolors/readme.md b/node_modules/yoctocolors/readme.md new file mode 100644 index 0000000000..782c32c191 --- /dev/null +++ b/node_modules/yoctocolors/readme.md @@ -0,0 +1,138 @@ +yoctocolors 🌈 + +> The smallest and fastest command-line coloring package on the internet + +*Check out [Chalk](https://github.com/chalk/chalk) if you want something more mature and comprehensive.* + +## Highlights + +- Tiny +- Fast +- Handles nested colors +- Tree-shakeable +- No dependencies +- Actively maintained + +## Install + +ESM: + +```sh +npm install yoctocolors +``` + +Or CommonJS: + +```sh +npm install yoctocolors-cjs +``` + +## Usage + +```js +import colors from 'yoctocolors'; + +console.log(colors.red('Yo!')); + +console.log(colors.blue(`Welcome to the ${colors.green('yoctocolors')} package!`)); +``` + +You can also import colors as named imports: + +```js +import {red, blue, green} from 'yoctocolors'; + +console.log(red('Yo!')); + +console.log(blue(`Welcome to the ${green('yoctocolors')} package!`)); +``` + +*This package supports [basic color detection](https://nodejs.org/api/tty.html#writestreamhascolorscount-env). Colors can be forcefully enabled by setting the `FORCE_COLOR` environment variable to `1` and can be forcefully disabled by setting `NO_COLOR` or `NODE_DISABLE_COLORS` to any value. [More info.](https://nodejs.org/api/tty.html#writestreamgetcolordepthenv)* + +## Styles + +### Modifiers + +- `reset` - Reset the current style. +- `bold` - Make the text bold. +- `dim` - Make the text have lower opacity. +- `italic` - Make the text italic. *(Not widely supported)* +- `underline` - Put a horizontal line above the text. *(Not widely supported)* +- `overline` - Put a horizontal line below the text. *(Not widely supported)* +- `inverse`- Invert background and foreground colors. +- `hidden` - Print the text but make it invisible. +- `strikethrough` - Put a horizontal line through the center of the text. *(Not widely supported)* + +### Colors + +- `black` +- `red` +- `green` +- `yellow` +- `blue` +- `magenta` +- `cyan` +- `white` +- `gray` +- `redBright` +- `greenBright` +- `yellowBright` +- `blueBright` +- `magentaBright` +- `cyanBright` +- `whiteBright` + +### Background colors + +- `bgBlack` +- `bgRed` +- `bgGreen` +- `bgYellow` +- `bgBlue` +- `bgMagenta` +- `bgCyan` +- `bgWhite` +- `bgGray` +- `bgRedBright` +- `bgGreenBright` +- `bgYellowBright` +- `bgBlueBright` +- `bgMagentaBright` +- `bgCyanBright` +- `bgWhiteBright` + +## Prior art + +Yes + +## Benchmark + +```sh +$ ./benchmark.js +┌─────────┬────────────────┬─────────────┐ +│ (index) │ library │ ops/sec │ +├─────────┼────────────────┼─────────────┤ +│ 0 │ 'yoctocolors' │ '8,000,000' │ +│ 1 │ 'colorette' │ '8,000,000' │ +│ 2 │ 'picocolors' │ '8,000,000' │ +│ 3 │ 'nanocolors' │ '5,988,024' │ +│ 4 │ 'chalk' │ '4,807,692' │ +│ 5 │ 'kleur/colors' │ '4,807,692' │ +│ 6 │ 'kleur' │ '4,784,689' │ +│ 7 │ 'ansi-colors' │ '2,178,649' │ +│ 8 │ 'cli-color' │ '585,138' │ +└─────────┴────────────────┴─────────────┘ +``` + +*See [benchmark.js](benchmark.js).* + +## FAQ + +### What is yocto? + +[It was the smallest official unit prefix in the metric system until 2022.](https://en.wikipedia.org/wiki/Yocto-) Much smaller than nano. + +## Related + +- [yoctodelay](https://github.com/sindresorhus/yoctodelay) - Delay a promise a given amount of time +- [chalk](https://github.com/chalk/chalk) - Terminal string styling diff --git a/package-lock.json b/package-lock.json index d12036935d..023673830a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,10 +44,10 @@ "zlib": "^1.0.5" }, "devDependencies": { - "@ava/typescript": "4.1.0", - "@eslint/compat": "^1.1.1", + "@ava/typescript": "6.0.0", + "@eslint/compat": "^1.3.1", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.28.0", + "@eslint/js": "^9.30.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", @@ -57,7 +57,7 @@ "@types/node": "20.9.0", "@types/semver": "^7.7.0", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.33.1", + "@typescript-eslint/eslint-plugin": "^8.35.1", "@typescript-eslint/parser": "^8.32.1", "ava": "^5.3.1", "eslint": "^8.57.1", @@ -68,7 +68,7 @@ "eslint-plugin-no-async-foreach": "^0.1.1", "nock": "^14.0.5", "removeNPMAbsolutePaths": "3.0.1", - "sinon": "^20.0.0", + "sinon": "^21.0.0", "typescript": "^5.8.3" } }, @@ -433,15 +433,16 @@ } }, "node_modules/@ava/typescript": { - "version": "4.1.0", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ava/typescript/-/typescript-6.0.0.tgz", + "integrity": "sha512-+8oDYc4J5cCaWZh1VUbyc+cegGplJO9FqHpqR4LVAVx8fRLVRaYlC4yyA6cqHJ1vWP23Ff/ECS5U68Zz6OLZlg==", "dev": true, - "license": "MIT", "dependencies": { "escape-string-regexp": "^5.0.0", - "execa": "^7.1.1" + "execa": "^9.6.0" }, "engines": { - "node": "^14.19 || ^16.15 || ^18 || ^20" + "node": "^20.8 || ^22 || >=24" } }, "node_modules/@ava/typescript/node_modules/escape-string-regexp": { @@ -809,12 +810,20 @@ } }, "node_modules/@eslint/compat": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.1.1.tgz", - "integrity": "sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.3.1.tgz", + "integrity": "sha512-k8MHony59I5EPic6EQTCNOuPoVBnoYXkP+20xvwFjN7t0qI3ImyvyBgg+hIVPwC8JaxVjjUZld+cLfBLFDLucg==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^8.40 || 9" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/@eslint/eslintrc": { @@ -882,9 +891,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.28.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", - "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.0.tgz", + "integrity": "sha512-Wzw3wQwPvc9sHM+NjakWTcPx11mbZyiYHuwWa/QfZ7cIRX7WK54PSk7bdyXDaoaopUcMatv1zaQvOAAO8hCdww==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1817,6 +1826,24 @@ "version": "0.0.10", "license": "MIT" }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -1956,16 +1983,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", - "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz", + "integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/type-utils": "8.33.1", - "@typescript-eslint/utils": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/type-utils": "8.35.1", + "@typescript-eslint/utils": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -1979,19 +2006,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.33.1", + "@typescript-eslint/parser": "^8.35.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", - "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2002,9 +2029,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2015,15 +2042,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", - "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2043,15 +2070,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", - "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz", + "integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1" + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2066,13 +2093,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", - "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2083,18 +2110,18 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2140,15 +2167,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", - "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz", + "integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4" }, "engines": { @@ -2164,13 +2191,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", - "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2181,9 +2208,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2194,15 +2221,15 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", - "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2222,13 +2249,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", - "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2239,18 +2266,18 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2287,13 +2314,13 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", - "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz", + "integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==", "dev": true, "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.33.1", - "@typescript-eslint/types": "^8.33.1", + "@typescript-eslint/tsconfig-utils": "^8.35.1", + "@typescript-eslint/types": "^8.35.1", "debug": "^4.3.4" }, "engines": { @@ -2308,9 +2335,9 @@ } }, "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2339,9 +2366,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", - "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz", + "integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2355,13 +2382,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", - "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz", + "integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.33.1", - "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/utils": "8.35.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -2378,13 +2405,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", - "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2395,9 +2422,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2408,15 +2435,15 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", - "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2436,15 +2463,15 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", - "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz", + "integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1" + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2459,13 +2486,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", - "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2476,18 +2503,18 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4380,24 +4407,6 @@ "eslint": "^8 || ^9" } }, - "node_modules/eslint-plugin-github/node_modules/@eslint/compat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.2.3.tgz", - "integrity": "sha512-wlZhwlDFxkxIZ571aH0FoK4h4Vwx7P3HJx62Gp8hTc10bfpwT2x0nULuAHmQSJBOWPgPeVf+9YtnD4j50zVHmA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": "^9.10.0" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, "node_modules/eslint-plugin-github/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -4894,27 +4903,85 @@ } }, "node_modules/execa": { - "version": "7.1.1", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", + "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", "dev": true, - "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" }, "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + "node": "^18.19.0 || >=20.5.0" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/execa/node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/pretty-ms": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", + "dev": true, + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fast-content-type-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", @@ -5129,18 +5196,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/form-data": { "version": "2.5.1", "license": "MIT", @@ -5268,11 +5323,16 @@ } }, "node_modules/get-stream": { - "version": "6.0.1", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "dev": true, - "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5526,11 +5586,12 @@ } }, "node_modules/human-signals": { - "version": "4.3.1", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", "dev": true, - "license": "Apache-2.0", "engines": { - "node": ">=14.18.0" + "node": ">=18.18.0" } }, "node_modules/ieee754": { @@ -5843,6 +5904,18 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-plain-object": { "version": "5.0.0", "license": "MIT", @@ -5886,11 +5959,12 @@ } }, "node_modules/is-stream": { - "version": "3.0.0", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, - "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6290,11 +6364,6 @@ "url": "https://github.com/sindresorhus/mem?sponsor=1" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/merge2": { "version": "1.4.1", "license": "MIT", @@ -6454,14 +6523,16 @@ } }, "node_modules/npm-run-path": { - "version": "5.1.0", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", "dev": true, - "license": "MIT", "dependencies": { - "path-key": "^4.0.0" + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6469,8 +6540,9 @@ }, "node_modules/npm-run-path/node_modules/path-key": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -6711,20 +6783,6 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.3", "dev": true, @@ -7432,14 +7490,20 @@ } }, "node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/sinon": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-20.0.0.tgz", - "integrity": "sha512-+FXOAbdnj94AQIxH0w1v8gzNxkawVvNqE3jUzRLptR71Oykeu2RrQXXl/VQjKay+Qnh73fDt/oDfMo6xMeDQbQ==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.0.tgz", + "integrity": "sha512-TOgRcwFPbfGtpqvZw+hyqJDvqfapr1qUlOizROIk4bBLjlsjlB00Pg6wMFXNtJRpu+eCZuVOaLatG7M8105kAw==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.1", @@ -7688,11 +7752,12 @@ } }, "node_modules/strip-final-newline": { - "version": "3.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", "dev": true, - "license": "MIT", "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8258,6 +8323,18 @@ "version": "5.26.5", "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universal-github-app-jwt": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-2.2.2.tgz", @@ -8494,17 +8571,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/write-file-atomic/node_modules/signal-exit": { - "version": "4.0.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/xml2js": { "version": "0.5.0", "license": "MIT", @@ -8567,6 +8633,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", + "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", diff --git a/package.json b/package.json index 2a9d8d920d..c88c012805 100644 --- a/package.json +++ b/package.json @@ -57,10 +57,10 @@ "zlib": "^1.0.5" }, "devDependencies": { - "@ava/typescript": "4.1.0", - "@eslint/compat": "^1.1.1", + "@ava/typescript": "6.0.0", + "@eslint/compat": "^1.3.1", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.28.0", + "@eslint/js": "^9.30.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", @@ -70,7 +70,7 @@ "@types/node": "20.9.0", "@types/semver": "^7.7.0", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.33.1", + "@typescript-eslint/eslint-plugin": "^8.35.1", "@typescript-eslint/parser": "^8.32.1", "ava": "^5.3.1", "eslint": "^8.57.1", @@ -81,7 +81,7 @@ "eslint-plugin-no-async-foreach": "^0.1.1", "nock": "^14.0.5", "removeNPMAbsolutePaths": "3.0.1", - "sinon": "^20.0.0", + "sinon": "^21.0.0", "typescript": "^5.8.3" }, "overrides": {