chore: Create script for managing dependency upgrades (#1875)
This commit is contained in:
+7
-3
@@ -146,13 +146,17 @@ Releases are done with GitHub actions:
|
||||
|
||||
## Upgrading Dependencies
|
||||
|
||||
Use [`taze`](https://www.npmjs.com/package/taze) to upgrade dependencies throughout the entire monorepo.
|
||||
WXT has custom rules around what dependencies can be upgraded. Use the `scripts/upgrade-deps.ts` script to upgrade dependencies and follow these rules.
|
||||
|
||||
```sh
|
||||
pnpm dlx taze -r
|
||||
pnpm tsx scripts/upgrade-deps.ts
|
||||
```
|
||||
|
||||
Configuration is in [`taze.config.ts`](./taze.config.ts).
|
||||
To see all the options, run:
|
||||
|
||||
```sh
|
||||
pnpm tsx scripts/upgrade-deps.ts --help
|
||||
```
|
||||
|
||||
## Install Unreleased Versions
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"@commitlint/config-conventional": "^19.8.1",
|
||||
"@commitlint/types": "^19.8.1",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/semver": "^7.7.1",
|
||||
"@vitest/coverage-v8": "^3.2.4",
|
||||
"changelogen": "^0.6.2",
|
||||
"consola": "^3.4.2",
|
||||
@@ -33,6 +34,7 @@
|
||||
"markdownlint-cli": "^0.45.0",
|
||||
"nano-spawn": "^1.0.2",
|
||||
"prettier": "^3.6.2",
|
||||
"semver": "^7.7.2",
|
||||
"simple-git-hooks": "^2.13.1",
|
||||
"tsx": "4.19.4",
|
||||
"typedoc": "^0.25.4",
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"wxt": ">=0.20.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.9.2",
|
||||
|
||||
@@ -46,11 +46,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"defu": "^6.1.4",
|
||||
"fs-extra": "^11.3.0",
|
||||
"fs-extra": "^11.3.1",
|
||||
"sharp": "^0.34.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"oxlint": "^1.14.0",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.9.2",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/chrome": "0.1.4",
|
||||
"fs-extra": "^11.3.0",
|
||||
"fs-extra": "^11.3.1",
|
||||
"nano-spawn": "^1.0.2",
|
||||
"tsx": "4.19.4",
|
||||
"typescript": "^5.9.2",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/chrome": "{{chromeTypesVersion}}",
|
||||
"fs-extra": "^11.3.0",
|
||||
"fs-extra": "^11.3.1",
|
||||
"nano-spawn": "^1.0.2",
|
||||
"tsx": "4.19.4",
|
||||
"typescript": "^5.9.2",
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"@types/node": "^20.17.6",
|
||||
"oxlint": "^1.14.0",
|
||||
"publint": "^0.3.12",
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"@vitejs/plugin-react": "^4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.3",
|
||||
"publint": "^0.3.12",
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"vite-plugin-solid": "^2.11.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"publint": "^0.3.12",
|
||||
"solid-js": "^1.9.6",
|
||||
"typescript": "^5.9.2",
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0 || ^5.0.0 || ^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.9.2",
|
||||
"unbuild": "^3.5.0",
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"@vitejs/plugin-vue": "^5.2.3 || ^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.9.2",
|
||||
"unbuild": "^3.5.0",
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"oxlint": "^1.14.0",
|
||||
"publint": "^0.3.12",
|
||||
"tsx": "4.19.4",
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"dequal": "^2.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"@webext-core/fake-browser": "^1.3.2",
|
||||
"oxlint": "^1.14.0",
|
||||
"publint": "^0.3.12",
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"wxt": ">=0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"oxlint": "^1.14.0",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.9.2",
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"wxt": ">=0.20.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"@types/webextension-polyfill": "^0.12.3",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.9.2",
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"esbuild": "^0.25.0",
|
||||
"fast-glob": "^3.3.3",
|
||||
"filesize": "^10.1.6",
|
||||
"fs-extra": "^11.3.0",
|
||||
"fs-extra": "^11.3.1",
|
||||
"get-port-please": "^3.1.2",
|
||||
"giget": "^1.2.3 || ^2.0.0",
|
||||
"hookable": "^5.5.3",
|
||||
@@ -63,7 +63,7 @@
|
||||
"web-ext-run": "^0.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@aklinker1/check": "^2.1.0",
|
||||
"@faker-js/faker": "^10.0.0",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/lodash.merge": "^4.6.9",
|
||||
|
||||
Generated
+47
-63
@@ -28,6 +28,9 @@ importers:
|
||||
'@types/fs-extra':
|
||||
specifier: ^11.0.4
|
||||
version: 11.0.4
|
||||
'@types/semver':
|
||||
specifier: ^7.7.1
|
||||
version: 7.7.1
|
||||
'@vitest/coverage-v8':
|
||||
specifier: ^3.2.4
|
||||
version: 3.2.4(vitest@3.2.0(@types/debug@4.1.12)(@types/node@20.17.30)(happy-dom@18.0.1)(jiti@2.5.1)(sass@1.89.1)(tsx@4.19.4)(yaml@2.7.0))
|
||||
@@ -61,6 +64,9 @@ importers:
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.6.2
|
||||
semver:
|
||||
specifier: ^7.7.2
|
||||
version: 7.7.2
|
||||
simple-git-hooks:
|
||||
specifier: ^2.13.1
|
||||
version: 2.13.1
|
||||
@@ -111,8 +117,8 @@ importers:
|
||||
version: 1.0.40
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@types/ua-parser-js':
|
||||
specifier: ^0.7.39
|
||||
version: 0.7.39
|
||||
@@ -135,15 +141,15 @@ importers:
|
||||
specifier: ^6.1.4
|
||||
version: 6.1.4
|
||||
fs-extra:
|
||||
specifier: ^11.3.0
|
||||
version: 11.3.0
|
||||
specifier: ^11.3.1
|
||||
version: 11.3.1
|
||||
sharp:
|
||||
specifier: ^0.34.1
|
||||
version: 0.34.1
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
oxlint:
|
||||
specifier: ^1.14.0
|
||||
version: 1.14.0
|
||||
@@ -173,8 +179,8 @@ importers:
|
||||
specifier: 0.1.4
|
||||
version: 0.1.4
|
||||
fs-extra:
|
||||
specifier: ^11.3.0
|
||||
version: 11.3.0
|
||||
specifier: ^11.3.1
|
||||
version: 11.3.1
|
||||
nano-spawn:
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
@@ -204,8 +210,8 @@ importers:
|
||||
version: 3.3.3
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@types/node':
|
||||
specifier: ^20.17.6
|
||||
version: 20.17.30
|
||||
@@ -238,8 +244,8 @@ importers:
|
||||
version: 4.5.0(vite@6.3.5(@types/node@20.17.30)(jiti@2.5.1)(sass@1.89.1)(tsx@4.19.4)(yaml@2.7.0))
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@types/react':
|
||||
specifier: ^19.1.2
|
||||
version: 19.1.6
|
||||
@@ -272,8 +278,8 @@ importers:
|
||||
version: 2.11.6(solid-js@1.9.7)(vite@6.3.5(@types/node@20.17.30)(jiti@2.5.1)(sass@1.89.1)(tsx@4.19.4)(yaml@2.7.0))
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
publint:
|
||||
specifier: ^0.3.12
|
||||
version: 0.3.12
|
||||
@@ -300,8 +306,8 @@ importers:
|
||||
version: 5.1.6
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
publint:
|
||||
specifier: ^0.3.12
|
||||
version: 0.3.12
|
||||
@@ -322,8 +328,8 @@ importers:
|
||||
version: 5.2.3(vite@6.3.5(@types/node@20.17.30)(jiti@2.5.1)(sass@1.89.1)(tsx@4.19.4)(yaml@2.7.0))(vue@3.5.21(typescript@5.9.2))
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
publint:
|
||||
specifier: ^0.3.12
|
||||
version: 0.3.12
|
||||
@@ -340,8 +346,8 @@ importers:
|
||||
packages/runner:
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
oxlint:
|
||||
specifier: ^1.14.0
|
||||
version: 1.14.0
|
||||
@@ -374,8 +380,8 @@ importers:
|
||||
version: 2.0.3
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@webext-core/fake-browser':
|
||||
specifier: ^1.3.2
|
||||
version: 1.3.2
|
||||
@@ -405,8 +411,8 @@ importers:
|
||||
version: 3.3.3
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
oxlint:
|
||||
specifier: ^1.14.0
|
||||
version: 1.14.0
|
||||
@@ -429,8 +435,8 @@ importers:
|
||||
packages/webextension-polyfill:
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@types/webextension-polyfill':
|
||||
specifier: ^0.12.3
|
||||
version: 0.12.3
|
||||
@@ -510,8 +516,8 @@ importers:
|
||||
specifier: ^10.1.6
|
||||
version: 10.1.6
|
||||
fs-extra:
|
||||
specifier: ^11.3.0
|
||||
version: 11.3.0
|
||||
specifier: ^11.3.1
|
||||
version: 11.3.1
|
||||
get-port-please:
|
||||
specifier: ^3.1.2
|
||||
version: 3.1.2
|
||||
@@ -589,8 +595,8 @@ importers:
|
||||
version: 0.2.3
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@faker-js/faker':
|
||||
specifier: ^10.0.0
|
||||
version: 10.0.0
|
||||
@@ -689,10 +695,6 @@ packages:
|
||||
resolution: {integrity: sha512-SL8NBNwOiTiCKjQnpOxTA4WfoeiTNhiVy1J6Ztk28xTbZQ7IL0zHbKODnEJAjuy8bfnxlChQT1ZMzjG7kBU4aw==}
|
||||
hasBin: true
|
||||
|
||||
'@aklinker1/check@2.0.0':
|
||||
resolution: {integrity: sha512-itoIc3WlLCtoVEwTIi/f6E4UKXJQJhYyMzbBqbQ73uvIsChgXKfmZHjaUwz4PyBtmkvlO4yhkh1JSQUzy2x5jA==}
|
||||
hasBin: true
|
||||
|
||||
'@aklinker1/check@2.1.0':
|
||||
resolution: {integrity: sha512-x+0vxb0vHV+6ZskcLYobI6FCAFG1jwVGgKuH9pTfHLW3vlzbGSGUKcxbCuMI3Q51WZS8oE4UfB+4v5M2+0uz1g==}
|
||||
hasBin: true
|
||||
@@ -2073,6 +2075,9 @@ packages:
|
||||
'@types/resolve@1.20.2':
|
||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||
|
||||
'@types/semver@7.7.1':
|
||||
resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==}
|
||||
|
||||
'@types/ua-parser-js@0.7.39':
|
||||
resolution: {integrity: sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==}
|
||||
|
||||
@@ -3106,10 +3111,6 @@ packages:
|
||||
fraction.js@4.3.7:
|
||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||
|
||||
fs-extra@11.3.0:
|
||||
resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==}
|
||||
engines: {node: '>=14.14'}
|
||||
|
||||
fs-extra@11.3.1:
|
||||
resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==}
|
||||
engines: {node: '>=14.14'}
|
||||
@@ -4523,11 +4524,6 @@ packages:
|
||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
|
||||
semver@7.7.1:
|
||||
resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
semver@7.7.2:
|
||||
resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -5317,12 +5313,6 @@ snapshots:
|
||||
proper-lockfile: 4.1.2
|
||||
yaml: 2.7.0
|
||||
|
||||
'@aklinker1/check@2.0.0':
|
||||
dependencies:
|
||||
'@antfu/utils': 0.7.10
|
||||
ci-info: 4.2.0
|
||||
citty: 0.1.6
|
||||
|
||||
'@aklinker1/check@2.1.0':
|
||||
dependencies:
|
||||
'@antfu/utils': 0.7.10
|
||||
@@ -6535,6 +6525,8 @@ snapshots:
|
||||
|
||||
'@types/resolve@1.20.2': {}
|
||||
|
||||
'@types/semver@7.7.1': {}
|
||||
|
||||
'@types/ua-parser-js@0.7.39': {}
|
||||
|
||||
'@types/unist@2.0.11': {}
|
||||
@@ -7767,12 +7759,6 @@ snapshots:
|
||||
|
||||
fraction.js@4.3.7: {}
|
||||
|
||||
fs-extra@11.3.0:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
jsonfile: 6.1.0
|
||||
universalify: 2.0.0
|
||||
|
||||
fs-extra@11.3.1:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
@@ -8274,7 +8260,7 @@ snapshots:
|
||||
|
||||
make-dir@4.0.0:
|
||||
dependencies:
|
||||
semver: 7.7.1
|
||||
semver: 7.7.2
|
||||
|
||||
make-error@1.3.6: {}
|
||||
|
||||
@@ -8570,7 +8556,7 @@ snapshots:
|
||||
pkg-types: 1.3.1
|
||||
postcss: 8.5.3
|
||||
postcss-nested: 7.0.2(postcss@8.5.3)
|
||||
semver: 7.7.1
|
||||
semver: 7.7.2
|
||||
tinyglobby: 0.2.12
|
||||
optionalDependencies:
|
||||
sass: 1.89.1
|
||||
@@ -8631,7 +8617,7 @@ snapshots:
|
||||
dependencies:
|
||||
growly: 1.3.0
|
||||
is-wsl: 2.2.0
|
||||
semver: 7.7.1
|
||||
semver: 7.7.2
|
||||
shellwords: 0.1.1
|
||||
uuid: 8.3.2
|
||||
which: 2.0.2
|
||||
@@ -8762,7 +8748,7 @@ snapshots:
|
||||
ky: 1.8.1
|
||||
registry-auth-token: 5.0.2
|
||||
registry-url: 6.0.1
|
||||
semver: 7.7.1
|
||||
semver: 7.7.2
|
||||
|
||||
package-manager-detector@0.2.11:
|
||||
dependencies:
|
||||
@@ -9311,8 +9297,6 @@ snapshots:
|
||||
|
||||
semver@6.3.1: {}
|
||||
|
||||
semver@7.7.1: {}
|
||||
|
||||
semver@7.7.2: {}
|
||||
|
||||
seroval-plugins@1.3.2(seroval@1.3.2):
|
||||
@@ -9332,7 +9316,7 @@ snapshots:
|
||||
dependencies:
|
||||
color: 4.2.3
|
||||
detect-libc: 2.0.3
|
||||
semver: 7.7.1
|
||||
semver: 7.7.2
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.34.1
|
||||
'@img/sharp-darwin-x64': 0.34.1
|
||||
@@ -9823,7 +9807,7 @@ snapshots:
|
||||
is-npm: 6.0.0
|
||||
latest-version: 9.0.0
|
||||
pupa: 3.1.0
|
||||
semver: 7.7.1
|
||||
semver: 7.7.2
|
||||
xdg-basedir: 5.1.0
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
import glob from 'fast-glob';
|
||||
import fs from 'fs-extra';
|
||||
import * as semver from 'semver';
|
||||
import { dirname } from 'node:path';
|
||||
import consola from 'consola';
|
||||
import spawn from 'nano-spawn';
|
||||
|
||||
const HELP_MESSAGE = `
|
||||
Upgrades dependencies throughout WXT using custom rules.
|
||||
|
||||
Usage:
|
||||
pnpm tsx scripts/upgrade-deps.ts [options]
|
||||
|
||||
Options:
|
||||
--write, -w Write changes to package.json files
|
||||
--major, -m Allow major version upgrades
|
||||
--dev-only, -d Only check/upgrade dev dependencies
|
||||
--prod-only, -p Only check/upgrade production dependencies
|
||||
--help, -h Display this help message
|
||||
`.slice(1, -1);
|
||||
|
||||
const IGNORED_PACKAGES = [
|
||||
// Very touchy, don't change:
|
||||
'typedoc',
|
||||
'typedoc-plugin-markdown',
|
||||
'typedoc-vitepress-theme',
|
||||
// Manually manage version so a single version is used:
|
||||
'esbuild',
|
||||
// Maintained manually to match min-node version
|
||||
'@types/node',
|
||||
// License changed in newer versions
|
||||
'ua-parser-js',
|
||||
];
|
||||
|
||||
await main();
|
||||
|
||||
async function main(): Promise<never> {
|
||||
const args = process.argv.slice(2);
|
||||
const isHelp = ['-h', '--help'].some((arg) => args.includes(arg));
|
||||
const isWrite = ['-w', '--write'].some((arg) => args.includes(arg));
|
||||
const isDevOnly = ['-d', '--dev-only'].some((arg) => args.includes(arg));
|
||||
const isProdOnly = ['-p', '--prod-only'].some((arg) => args.includes(arg));
|
||||
|
||||
if (isHelp) {
|
||||
console.log(HELP_MESSAGE);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const { packageJsonFiles, dependencyVersionsMap } =
|
||||
await getPackageJsonDependencies(isDevOnly, isProdOnly);
|
||||
const dependencyVersionMap = validateNoMultipleVersions(
|
||||
dependencyVersionsMap,
|
||||
);
|
||||
|
||||
consola.start(
|
||||
`Fetching ${Object.keys(dependencyVersionsMap).length} dependencies...`,
|
||||
);
|
||||
const dependencies = await fetchAllPackageInfos(dependencyVersionMap);
|
||||
consola.success('Done!');
|
||||
|
||||
const isMajor = ['-m', '--major'].some((arg) => args.includes(arg));
|
||||
const upgrades = await detectUpgrades(dependencies, isMajor);
|
||||
|
||||
if (upgrades.length === 0) {
|
||||
console.log();
|
||||
consola.info("No upgrades found, you're up to date!");
|
||||
console.log();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
printUpgrades(upgrades);
|
||||
|
||||
if (!isWrite) {
|
||||
consola.info('Run with `-w` to write changes to package.json files');
|
||||
console.log();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
consola.start('Writing new versions to package.json files...');
|
||||
await writeUpgrades(packageJsonFiles, upgrades);
|
||||
consola.success('Done!');
|
||||
console.log();
|
||||
consola.info('Run `pnpm i` to install new dependencies');
|
||||
console.log();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
type DependencyVersionsMap = Record<string, Set<string>>;
|
||||
type PackageJsonData = {
|
||||
content: any;
|
||||
path: string;
|
||||
folder: string;
|
||||
};
|
||||
|
||||
async function getPackageJsonDependencies(
|
||||
isDevOnly: boolean,
|
||||
isProdOnly: boolean,
|
||||
): Promise<{
|
||||
packageJsonFiles: string[];
|
||||
dependencyVersionsMap: DependencyVersionsMap;
|
||||
}> {
|
||||
const packageJsonFiles = await glob(
|
||||
['package.json', '*/*/package.json', '!**/node_modules'],
|
||||
{ onlyFiles: true },
|
||||
);
|
||||
const packageJsons: PackageJsonData[] = await Promise.all(
|
||||
packageJsonFiles.map(async (path) => ({
|
||||
content: await fs.readJson(path),
|
||||
path,
|
||||
folder: dirname(path),
|
||||
})),
|
||||
);
|
||||
|
||||
const dependencyVersionsMap = packageJsons.reduce<DependencyVersionsMap>(
|
||||
(map, { content }) => {
|
||||
const addToMap = ([name, version]: [string, any]) => {
|
||||
if (
|
||||
name === 'wxt' ||
|
||||
version.startsWith('workspace:') ||
|
||||
IGNORED_PACKAGES.includes(name)
|
||||
)
|
||||
return;
|
||||
|
||||
map[name] ||= new Set();
|
||||
map[name].add(version as string);
|
||||
};
|
||||
if (!isDevOnly)
|
||||
Object.entries(content.dependencies || {}).forEach(addToMap);
|
||||
if (!isProdOnly)
|
||||
Object.entries(content.devDependencies || {}).forEach(addToMap);
|
||||
return map;
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
return {
|
||||
packageJsonFiles,
|
||||
dependencyVersionsMap,
|
||||
};
|
||||
}
|
||||
|
||||
type DependencyVersionMap = Record<string, string>;
|
||||
|
||||
function validateNoMultipleVersions(
|
||||
dependencyVersionsMap: DependencyVersionsMap,
|
||||
): DependencyVersionMap {
|
||||
const depsWithMultipleVersions = Object.entries(dependencyVersionsMap).filter(
|
||||
([_, versions]) => versions.size > 1,
|
||||
);
|
||||
if (depsWithMultipleVersions.length === 0) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(dependencyVersionsMap).map(([name, versions]) => [
|
||||
name,
|
||||
[...versions][0],
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
const maxWidth = Math.max(
|
||||
...depsWithMultipleVersions.map(([name]) => name.length),
|
||||
);
|
||||
console.log(maxWidth);
|
||||
const addCyan = (text: string) => `\x1b[36m${text}\x1b[0m`;
|
||||
|
||||
consola.info('Found multiple versions of:');
|
||||
for (const [name, versions] of depsWithMultipleVersions) {
|
||||
console.log(
|
||||
` \x1b[35m${name.padEnd(maxWidth)}\x1b[0m ${Array.from(versions)
|
||||
.map(addCyan)
|
||||
.join('\t')}`,
|
||||
);
|
||||
}
|
||||
consola.error(`${depsWithMultipleVersions.length} problem(s) found`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
async function fetchPackageInfo(name: string): Promise<PackageInfo> {
|
||||
// Use PNPM instead of API in case dependencies don't come from NPM
|
||||
const res = await spawn('pnpm', ['view', name, '--json']);
|
||||
return JSON.parse(res.output);
|
||||
}
|
||||
|
||||
type PackageInfo = {
|
||||
name: string;
|
||||
'dist-tags': {
|
||||
latest: string;
|
||||
[tag: string]: string;
|
||||
};
|
||||
versions: string[];
|
||||
time: {
|
||||
created: string;
|
||||
modified: string;
|
||||
[version: string]: string;
|
||||
};
|
||||
};
|
||||
|
||||
type DependencyInfo = {
|
||||
name: string;
|
||||
currentVersionRange: string;
|
||||
info: PackageInfo;
|
||||
};
|
||||
|
||||
async function fetchAllPackageInfos(
|
||||
deps: DependencyVersionMap,
|
||||
): Promise<DependencyInfo[]> {
|
||||
const infos = await Promise.all(
|
||||
Object.entries(deps).map(async ([name, currentVersionRange]) => ({
|
||||
name,
|
||||
currentVersionRange,
|
||||
info: await fetchPackageInfo(name),
|
||||
})),
|
||||
);
|
||||
return infos.toSorted((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
type UpgradeDetails = {
|
||||
name: string;
|
||||
rangePrefix: string;
|
||||
currentVersion: string;
|
||||
currentVersionReleasedAt: Date;
|
||||
currentRange: string;
|
||||
upgradeToVersion: string;
|
||||
upgradeToVersionReleasedAt: Date;
|
||||
upgradeToRange: string;
|
||||
diff: semver.ReleaseType | null;
|
||||
latestVersion: string;
|
||||
latestVersionReleasedAt: Date;
|
||||
};
|
||||
|
||||
async function detectUpgrades(
|
||||
deps: DependencyInfo[],
|
||||
isMajor: boolean,
|
||||
): Promise<UpgradeDetails[]> {
|
||||
const results: UpgradeDetails[] = [];
|
||||
|
||||
for (const dep of deps) {
|
||||
const currentRange = dep.currentVersionRange;
|
||||
if (currentRange === '*') continue;
|
||||
|
||||
const parts = currentRange.split(' || ').map((part) => part.trim());
|
||||
const lastRange = parts[parts.length - 1];
|
||||
const isUnion = parts.length > 1;
|
||||
|
||||
const rangePrefix = lastRange.match(/^(.?)(\d+\.\d+\.\d+)/)?.[1] ?? '';
|
||||
|
||||
const currentVersion = semver.minVersion(lastRange)?.version;
|
||||
if (currentVersion == null)
|
||||
throw Error(`Invalid version specifier: ${dep.name}@${currentRange}`);
|
||||
|
||||
const currentVersionReleasedAt = new Date(dep.info.time[currentVersion]);
|
||||
const isPre1 = currentVersion.startsWith('0.');
|
||||
|
||||
const latestVersion = dep.info['dist-tags'].latest;
|
||||
const latestVersionReleasedAt = new Date(dep.info.time[latestVersion]);
|
||||
|
||||
semver.RELEASE_TYPES;
|
||||
const upgradeToVersion = isMajor
|
||||
? // Always use the latest version for major upgrades
|
||||
latestVersion
|
||||
: // Otherwise use the last stable version greater than the current version that is not a major release
|
||||
(dep.info.versions.findLast(
|
||||
(v) =>
|
||||
semver.gt(v, currentVersion) &&
|
||||
(isPre1 ? ['patch'] : ['patch', 'minor']).includes(
|
||||
semver.diff(v, currentVersion)!,
|
||||
) &&
|
||||
semver.prerelease(v) == null,
|
||||
) ?? currentVersion);
|
||||
const upgradeToVersionReleasedAt = new Date(
|
||||
dep.info.time[upgradeToVersion],
|
||||
);
|
||||
|
||||
let upgradeToRange = `${rangePrefix}${upgradeToVersion}`;
|
||||
upgradeToRange = isUnion
|
||||
? semver.satisfies(upgradeToVersion, currentRange)
|
||||
? currentRange
|
||||
: `${currentRange} || ${upgradeToRange}`
|
||||
: upgradeToRange;
|
||||
|
||||
let diff = semver.diff(currentVersion, upgradeToVersion);
|
||||
if (isPre1) {
|
||||
if (diff === 'minor') diff = 'major';
|
||||
if (diff === 'patch') diff = 'minor';
|
||||
}
|
||||
|
||||
if (upgradeToRange === currentRange) continue;
|
||||
// if (currentVersion === latestVersion) continue;
|
||||
|
||||
results.push({
|
||||
name: dep.name,
|
||||
rangePrefix,
|
||||
diff,
|
||||
currentVersion,
|
||||
currentVersionReleasedAt,
|
||||
currentRange,
|
||||
upgradeToVersion,
|
||||
upgradeToVersionReleasedAt,
|
||||
upgradeToRange,
|
||||
latestVersion,
|
||||
latestVersionReleasedAt,
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function printUpgrades(upgrades: UpgradeDetails[]): void {
|
||||
const namePadding = Math.max(...upgrades.map((u) => u.name.length));
|
||||
const currentVersionPadding = Math.max(
|
||||
...upgrades.map((u) => u.currentRange.length),
|
||||
);
|
||||
const upgradeToVersionPadding = Math.max(
|
||||
...upgrades.map((u) => u.upgradeToRange.length),
|
||||
);
|
||||
const numberPadding = String(upgrades.length + 1).length + 1;
|
||||
|
||||
consola.info(`Found ${upgrades.length} upgrades:`);
|
||||
console.log();
|
||||
for (let i = 0; i < upgrades.length; i++) {
|
||||
const upgrade = upgrades[i];
|
||||
const num = `\x1b[2m${(i + 1).toString().padStart(numberPadding)}.\x1b[0m`;
|
||||
const name = `\x1b[35m${upgrade.name.padEnd(namePadding)}\x1b[0m`;
|
||||
const color =
|
||||
upgrade.diff == null
|
||||
? '\x1b[2m'
|
||||
: upgrade.diff === 'patch'
|
||||
? '\x1b[32m'
|
||||
: upgrade.diff === 'minor'
|
||||
? '\x1b[33m'
|
||||
: '\x1b[31m';
|
||||
const currentVersion = `\x1b[2m${upgrade.currentRange.padEnd(currentVersionPadding)}\x1b[0m`;
|
||||
const upgradeToVersion = `${color}${upgrade.upgradeToRange.padEnd(upgradeToVersionPadding)}\x1b[0m`;
|
||||
const latest =
|
||||
upgrade.latestVersion !== upgrade.upgradeToVersion
|
||||
? ` \x1b[2m\x1b[31m(${upgrade.latestVersion} available)\x1b[0m`
|
||||
: '';
|
||||
console.log(
|
||||
` ${num} ${name} ${currentVersion} \x1b[2m→\x1b[0m ${upgradeToVersion}${latest}`,
|
||||
);
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
|
||||
async function writeUpgrades(
|
||||
packageJsonFiles: string[],
|
||||
upgrades: UpgradeDetails[],
|
||||
) {
|
||||
for (const packageJsonFile of packageJsonFiles) {
|
||||
const oldText = await fs.readFile(packageJsonFile, 'utf8');
|
||||
let newText = oldText;
|
||||
for (const upgrade of upgrades) {
|
||||
const search = `"${upgrade.name}": "${upgrade.currentRange}"`;
|
||||
const replace = `"${upgrade.name}": "${upgrade.upgradeToRange}"`;
|
||||
newText = newText.replaceAll(search, replace);
|
||||
}
|
||||
if (newText !== oldText) {
|
||||
await fs.writeFile(packageJsonFile, newText, 'utf8');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// https://github.com/antfu-collective/taze?tab=readme-ov-file#config-file
|
||||
export default {
|
||||
exclude: [
|
||||
// Very touchy, don't change:
|
||||
'typedoc',
|
||||
'typedoc-plugin-markdown',
|
||||
'typedoc-vitepress-theme',
|
||||
// Manually manage version so a single version is used:
|
||||
'esbuild',
|
||||
// Maintained manually to match min-node version
|
||||
'@types/node',
|
||||
// License changed in newer versions
|
||||
'ua-parser-js',
|
||||
],
|
||||
};
|
||||
Vendored
+1
-1
@@ -19,7 +19,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wxt-dev/module-vue": "^1.0.2",
|
||||
"typescript": "5.6.3",
|
||||
"typescript": "^5.9.2",
|
||||
"vue-tsc": "^2.2.10",
|
||||
"wxt": "^0.20.6"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user