diff --git a/.github/ISSUE_TEMPLATE/blank.yml b/.github/ISSUE_TEMPLATE/blank.yml index 89588f3d8..8deb782ca 100644 --- a/.github/ISSUE_TEMPLATE/blank.yml +++ b/.github/ISSUE_TEMPLATE/blank.yml @@ -5,9 +5,9 @@ body: - type: markdown attributes: value: | - ![Are you a developer? No? This form is not for you!](https://github.com/Vendicated/Vencord/blob/main/.github/ISSUE_TEMPLATE/developer-banner.png?raw=true) + ![Are you a developer? No? This form is not for you!](https://github.com/Equicord/Equicord/blob/main/.github/ISSUE_TEMPLATE/developer-banner.png?raw=true) - GitHub Issues are for development, not support! Please use our [support server](https://vencord.dev/discord) unless you are a Vencord Developer. + GitHub Issues are for development, not support! Please use our [support server](https://equicord.org/discord) unless you are a Vencord Developer. - type: textarea id: content diff --git a/README.md b/README.md index 63fa54e90..8088cf240 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ Equicord is a fork of [Vencord](https://github.com/Vendicated/Vencord), with over 300+ plugins. -You can join our [discord server](https://equicord.org/discord) for commits, changes, chat or even support. +You can join our [Discord server](https://equicord.org/discord) for commits, changes, chatting, or even support. ### Included Plugins -Our included plugins can be found [here](https://equicord.org/plugins) +Our included plugins can be found [here](https://equicord.org/plugins). ## Installing / Uninstalling @@ -90,7 +90,7 @@ Thank you to [Vendicated](https://github.com/Vendicated) for creating [Vencord]( ## Disclaimer -Discord is trademark of Discord Inc. and solely mentioned for the sake of descriptivity. +Discord is trademark of Discord Inc., and solely mentioned for the sake of descriptivity. Mentioning it does not imply any affiliation with or endorsement by Discord Inc. Vencord is not connected to Equicord and as such, all donation links go to Vendicated's donation link. @@ -101,8 +101,8 @@ Client modifications are against Discord’s Terms of Service. However, Discord is pretty indifferent about them and there are no known cases of users getting banned for using client mods! So you should generally be fine if you don’t use plugins that implement abusive behaviour. But no worries, all inbuilt plugins are safe to use! -Regardless, if your account is essential to you and getting disabled would be a disaster for you, you should probably not use any client mods (not exclusive to Equicord), just to be safe +Regardless, if your account is essential to you and getting disabled would be a disaster for you, you should probably not use any client mods (not exclusive to Equicord), just to be safe. -Additionally, make sure not to post screenshots with Equicord in a server where you might get banned for it +Additionally, make sure not to post screenshots with Equicord in a server where you might get banned for it. diff --git a/package.json b/package.json index c62a68020..cfca43418 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@ffmpeg/ffmpeg": "^0.12.10", "@ffmpeg/util": "^0.12.1", "@intrnl/xxhash64": "^0.1.2", - "@types/less": "^3.0.6", + "@types/less": "^3.0.8", "@types/stylus": "^0.48.42", "@types/tinycolor2": "^1.4.6", "@vap/core": "0.0.12", @@ -56,8 +56,9 @@ "virtual-merge": "^1.0.1" }, "devDependencies": { - "@electron/asar": "^3.2.10", + "@electron/asar": "^4.0.1", "@stylistic/eslint-plugin": "^4.2.0", + "@types/adm-zip": "^0.5.7", "@types/chrome": "^0.0.312", "@types/diff": "^7.0.2", "@types/lodash": "^4.17.14", @@ -66,6 +67,7 @@ "@types/react-dom": "^19.0.4", "@types/yazl": "^2.4.5", "@vencord/discord-types": "link:packages/discord-types", + "adm-zip": "^0.5.16", "diff": "^7.0.0", "esbuild": "^0.25.1", "eslint": "9.20.1", @@ -77,7 +79,7 @@ "highlight.js": "11.11.1", "html-minifier-terser": "^7.2.0", "moment": "^2.22.2", - "puppeteer-core": "^24.4.0", + "puppeteer-core": "^24.19.0", "standalone-electron-types": "^34.2.0", "stylelint": "^16.17.0", "stylelint-config-standard": "^37.0.0", @@ -87,14 +89,13 @@ "type-fest": "^4.38.0", "typescript": "^5.8.2", "typescript-eslint": "^8.28.0", - "typescript-transform-paths": "^3.5.5", - "zip-local": "^0.3.5" + "typescript-transform-paths": "^3.5.5" }, "packageManager": "pnpm@10.14.0", "pnpm": { "patchedDependencies": { "eslint@9.20.1": "patches/eslint@9.20.1.patch", - "@types/less@3.0.6": "patches/@types__less@3.0.6.patch" + "@types/less@3.0.8": "patches/@types__less@3.0.8.patch" }, "peerDependencyRules": { "ignoreMissing": [ @@ -111,7 +112,10 @@ }, "onlyBuiltDependencies": [ "esbuild" - ] + ], + "overrides": { + "@eslint/plugin-kit@<0.3.4": ">=0.3.4" + } }, "engines": { "node": ">=18" diff --git a/patches/@types__less@3.0.6.patch b/patches/@types__less@3.0.8.patch similarity index 100% rename from patches/@types__less@3.0.6.patch rename to patches/@types__less@3.0.8.patch diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b46a73ac3..59a443581 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,10 +4,13 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@eslint/plugin-kit@<0.3.4': '>=0.3.4' + patchedDependencies: - '@types/less@3.0.6': + '@types/less@3.0.8': hash: 641e6c93bb737bac7fc283416857bd095cd85bcbcba63becb7a8bbcc78f73076 - path: patches/@types__less@3.0.6.patch + path: patches/@types__less@3.0.8.patch eslint@9.20.1: hash: 4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215 path: patches/eslint@9.20.1.patch @@ -26,8 +29,8 @@ importers: specifier: ^0.1.2 version: 0.1.2 '@types/less': - specifier: ^3.0.6 - version: 3.0.6(patch_hash=641e6c93bb737bac7fc283416857bd095cd85bcbcba63becb7a8bbcc78f73076) + specifier: ^3.0.8 + version: 3.0.8(patch_hash=641e6c93bb737bac7fc283416857bd095cd85bcbcba63becb7a8bbcc78f73076) '@types/stylus': specifier: ^0.48.42 version: 0.48.42 @@ -66,11 +69,14 @@ importers: version: 1.0.2 devDependencies: '@electron/asar': - specifier: ^3.2.10 - version: 3.2.10 + specifier: ^4.0.1 + version: 4.0.1 '@stylistic/eslint-plugin': specifier: ^4.2.0 - version: 4.2.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2) + version: 4.4.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2) + '@types/adm-zip': + specifier: ^0.5.7 + version: 0.5.7 '@types/chrome': specifier: ^0.0.312 version: 0.0.312 @@ -95,6 +101,9 @@ importers: '@vencord/discord-types': specifier: link:packages/discord-types version: link:packages/discord-types + adm-zip: + specifier: ^0.5.16 + version: 0.5.16 diff: specifier: ^7.0.0 version: 7.0.0 @@ -129,8 +138,8 @@ importers: specifier: ^2.22.2 version: 2.30.1 puppeteer-core: - specifier: ^24.4.0 - version: 24.4.0 + specifier: ^24.19.0 + version: 24.19.0 standalone-electron-types: specifier: ^34.2.0 version: 34.2.0 @@ -161,9 +170,6 @@ importers: typescript-transform-paths: specifier: ^3.5.5 version: 3.5.5(typescript@5.8.2) - zip-local: - specifier: ^0.3.5 - version: 0.3.5 packages/discord-types: dependencies: @@ -248,9 +254,9 @@ packages: '@dual-bundle/import-meta-resolve@4.1.0': resolution: {integrity: sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==} - '@electron/asar@3.2.10': - resolution: {integrity: sha512-mvBSwIBUeiRscrCeJE1LwctAriBj65eUDm0Pc11iE5gRwzkmsdbS7FnZ1XUWjpSeQWL1L5g12Fc/SchPM9DUOw==} - engines: {node: '>=10.12.0'} + '@electron/asar@4.0.1': + resolution: {integrity: sha512-F4Ykm1jiBGY1WV/o8Q8oFW8Nq0u+S2/vPujzNJtdSJ6C4LHC4CiGLn7c17s7SolZ23gcvCebMncmZtNc+MkxPQ==} + engines: {node: '>=22.12.0'} hasBin: true '@esbuild/aix-ppc64@0.25.1': @@ -409,6 +415,12 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/regexpp@4.12.1': resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -421,8 +433,8 @@ packages: resolution: {integrity: sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.12.0': - resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + '@eslint/core@0.15.2': + resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': @@ -437,8 +449,8 @@ packages: resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.7': - resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} + '@eslint/plugin-kit@0.3.5': + resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ffmpeg/ffmpeg@0.12.10': @@ -476,6 +488,18 @@ packages: '@intrnl/xxhash64@0.1.2': resolution: {integrity: sha512-1+lx7j99fdph+uy3EnjQyr39KQZ7LP56+aWOr6finJWpgYpvb7XrhFUqDwnEk/wpPC98nCjAT6RulpW3crWjlg==} + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -512,16 +536,16 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@puppeteer/browsers@2.8.0': - resolution: {integrity: sha512-yTwt2KWRmCQAfhvbCRjebaSX8pV1//I0Y3g+A7f/eS7gf0l4eRJoUCvcYdVtboeU4CTOZQuqYbZNS8aBYb8ROQ==} + '@puppeteer/browsers@2.10.8': + resolution: {integrity: sha512-f02QYEnBDE0p8cteNoPYHHjbDuwyfbe4cCIVlNi8/MRicIxFW4w4CfgU0LNgWEID6s06P+hRJ1qjpBLMhPRCiQ==} engines: {node: '>=18'} hasBin: true '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@stylistic/eslint-plugin@4.2.0': - resolution: {integrity: sha512-8hXezgz7jexGHdo5WN6JBEIPHCSFyyU4vgbxevu4YLVS5vl+sxqAAGyXSzfNDyR6xMNSH5H1x67nsXcYMOHtZA==} + '@stylistic/eslint-plugin@4.4.1': + resolution: {integrity: sha512-CEigAk7eOLyHvdgmpZsKFwtiqS2wFwI1fn4j09IU9GmD4euFM4jEBAViWeCqaNLlbX2k2+A/Fq9cje4HQBXuJQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=9.0.0' @@ -529,6 +553,9 @@ packages: '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@types/adm-zip@0.5.7': + resolution: {integrity: sha512-DNEs/QvmyRLurdQPChqq0Md4zGvPwHerAJYWk9l2jCbD1VPpnzRJorOdiq4zsw09NFbYnhfsoEhWtxIzXpn2yw==} + '@types/chrome@0.0.312': resolution: {integrity: sha512-m204djOoU/YqF1dRw3YLk2L3tcDTYREUERDQDUAmROK3Rv94nLbMJ4uvjzr/Yj/A7SyEpTrpoCuXBKTuerEdqg==} @@ -559,8 +586,8 @@ packages: '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - '@types/less@3.0.6': - resolution: {integrity: sha512-PecSzorDGdabF57OBeQO/xFbAkYWo88g4Xvnsx7LRwqLC17I7OoKtA3bQB9uXkY6UkMWCOsA8HSVpaoitscdXw==} + '@types/less@3.0.8': + resolution: {integrity: sha512-Gjm4+H9noDJgu5EdT3rUw5MhPBag46fiOy27BefvWkNL8mlZnKnCaVVVTLKj6RYXed9b62CPKnPav9govyQDzA==} '@types/lodash@4.17.15': resolution: {integrity: sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==} @@ -615,10 +642,26 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/project-service@8.43.0': + resolution: {integrity: sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/scope-manager@8.28.0': resolution: {integrity: sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.43.0': + resolution: {integrity: sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.43.0': + resolution: {integrity: sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/type-utils@8.28.0': resolution: {integrity: sha512-oRoXu2v0Rsy/VoOGhtWrOKDiIehvI+YNrDk5Oqj40Mwm0Yt01FC/Q7nFqg088d3yAsR1ZcZFVfPCTTFCe/KPwg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -630,12 +673,22 @@ packages: resolution: {integrity: sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.43.0': + resolution: {integrity: sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.28.0': resolution: {integrity: sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/typescript-estree@8.43.0': + resolution: {integrity: sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/utils@8.28.0': resolution: {integrity: sha512-OELa9hbTYciYITqgurT1u/SzpQVtDLmQMFzy/N8pQE+tefOyCWT79jHsav294aTqV1q1u+VzqDGbuujvRYaeSQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -643,10 +696,21 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/utils@8.43.0': + resolution: {integrity: sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/visitor-keys@8.28.0': resolution: {integrity: sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.43.0': + resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@vap/core@0.0.12': resolution: {integrity: sha512-3csHpkE1zUSRTZwl7xIf2uXg1cD4IhhtUm0F6K/dWydc95R5Nj+krB4OTNATuqkewIv/ViCbwjPfkafAgvZQSg==} @@ -663,6 +727,15 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + adm-zip@0.5.16: + resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==} + engines: {node: '>=12.0'} + agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} @@ -677,6 +750,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -685,6 +762,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -736,9 +817,6 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} - async@1.5.2: - resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} - available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -789,11 +867,11 @@ packages: resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} engines: {node: '>=10.0.0'} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -842,8 +920,8 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chromium-bidi@2.1.2: - resolution: {integrity: sha512-vtRWBK2uImo5/W2oG6/cDkkHSm+2t6VHgnj+Rcwhb0pP74OoUb4GipyRX/T/y39gYQPhioP0DPShn+A7P6CHNw==} + chromium-bidi@8.0.0: + resolution: {integrity: sha512-d1VmE0FD7lxZQHzcDUCKZSNRtRwISXDsdg4HjdTR5+Ll5nQ/vzU12JeNmupD6VWffrPSlrnGhEWlLESKH3VO+g==} peerDependencies: devtools-protocol: '*' @@ -875,13 +953,13 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - commander@5.1.0: - resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} - engines: {node: '>= 6'} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -938,8 +1016,8 @@ packages: supports-color: optional: true - debug@4.3.6: - resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -947,8 +1025,8 @@ packages: supports-color: optional: true - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -971,8 +1049,8 @@ packages: resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} engines: {node: '>= 14'} - devtools-protocol@0.0.1413902: - resolution: {integrity: sha512-yRtvFD8Oyk7C9Os3GmnFZLu53yAfsnyw1s+mLmHHUK0GQEc9zthHWvS1r67Zqzm5t7v56PILHIVZ7kmFMaL2yQ==} + devtools-protocol@0.0.1495869: + resolution: {integrity: sha512-i+bkd9UYFis40RcnkW7XrOprCujXRAHg62IVh/Ah3G8MmNXpCGt1m0dTFhSdx/AVs8XEMbdOGRwdkR1Bcta8AA==} diff@7.0.0: resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} @@ -993,9 +1071,15 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -1137,8 +1221,8 @@ packages: '@typescript-eslint/eslint-plugin': optional: true - eslint-scope@8.3.0: - resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: @@ -1149,6 +1233,10 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint@9.20.1: resolution: {integrity: sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1159,8 +1247,8 @@ packages: jiti: optional: true - espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esprima@4.0.1: @@ -1253,13 +1341,14 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + fs-extra@11.3.0: resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} engines: {node: '>=14.14'} - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1322,9 +1411,10 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + glob@11.0.3: + resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} + engines: {node: 20 || >=22} + hasBin: true global-modules@2.0.0: resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} @@ -1450,13 +1540,6 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} @@ -1605,6 +1688,10 @@ packages: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1647,9 +1734,6 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} - jszip@2.7.0: - resolution: {integrity: sha512-JIsRKRVC3gTRo2vM4Wy9WBC3TRcfnIZU8k65Phi3izkvPH975FowRYtKGT6PxevA0XnJ/yO8b0QwV0ydVyQwfw==} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1687,6 +1771,10 @@ packages: lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lru-cache@11.2.1: + resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} + engines: {node: 20 || >=22} + lru-cache@7.18.3: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} @@ -1713,6 +1801,10 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -1723,6 +1815,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -1732,9 +1828,6 @@ packages: monaco-editor@0.52.2: resolution: {integrity: sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1825,8 +1918,8 @@ packages: resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} engines: {node: '>= 14'} - pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} @@ -1846,10 +1939,6 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1857,6 +1946,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -1871,8 +1964,8 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} possible-typed-array-names@1.1.0: @@ -1924,14 +2017,10 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - puppeteer-core@24.4.0: - resolution: {integrity: sha512-eFw66gCnWo0X8Hyf9KxxJtms7a61NJVMiSaWfItsFPzFBsjsWdmcNlBdsA1WVwln6neoHhsG+uTVesKmTREn/g==} + puppeteer-core@24.19.0: + resolution: {integrity: sha512-qsEys4OIb2VGC2tNWKAs4U0mnjkIAxueMOOzk2nEFM9g4Y8QuvYkEMtmwsEdvzNGsUFd7DprOQfABmlN7WBOlg==} engines: {node: '>=18'} - q@1.5.1: - resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} - engines: {node: '>=0.6.0', teleport: '>=0.2.0'} - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -2005,6 +2094,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -2093,6 +2187,10 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string.prototype.matchall@4.0.12: resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} engines: {node: '>= 0.4'} @@ -2116,6 +2214,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -2164,8 +2266,8 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tar-fs@3.0.8: - resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==} + tar-fs@3.1.0: + resolution: {integrity: sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==} tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} @@ -2325,6 +2427,10 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -2332,8 +2438,8 @@ packages: resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - ws@8.18.1: - resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -2363,9 +2469,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - zip-local@0.3.5: - resolution: {integrity: sha512-GRV3D5TJY+/PqyeRm5CYBs7xVrKTKzljBoEXvocZu0HJ7tPEcgpSOYa2zFIsCZWgKWMuc4U3yMFgFkERGFIB9w==} - zod@3.24.2: resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} @@ -2402,11 +2505,11 @@ snapshots: '@dual-bundle/import-meta-resolve@4.1.0': {} - '@electron/asar@3.2.10': + '@electron/asar@4.0.1': dependencies: - commander: 5.1.0 - glob: 7.2.3 - minimatch: 3.1.2 + commander: 13.1.0 + glob: 11.0.3 + minimatch: 10.0.3 '@esbuild/aix-ppc64@0.25.1': optional: true @@ -2488,12 +2591,17 @@ snapshots: eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215) eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.9.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))': + dependencies: + eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215) + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.12.1': {} '@eslint/config-array@0.19.2': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.0 + debug: 4.4.1 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -2502,15 +2610,15 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@0.12.0': + '@eslint/core@0.15.2': dependencies: '@types/json-schema': 7.0.15 '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.3.6 - espree: 10.3.0 + debug: 4.4.1 + espree: 10.4.0 globals: 14.0.0 ignore: 5.3.1 import-fresh: 3.3.1 @@ -2524,9 +2632,9 @@ snapshots: '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.2.7': + '@eslint/plugin-kit@0.3.5': dependencies: - '@eslint/core': 0.12.0 + '@eslint/core': 0.15.2 levn: 0.4.1 '@ffmpeg/ffmpeg@0.12.10': @@ -2552,6 +2660,21 @@ snapshots: '@intrnl/xxhash64@0.1.2': {} + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -2590,14 +2713,14 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@puppeteer/browsers@2.8.0': + '@puppeteer/browsers@2.10.8': dependencies: - debug: 4.4.0 + debug: 4.4.1 extract-zip: 2.0.1 progress: 2.0.3 proxy-agent: 6.5.0 - semver: 7.7.1 - tar-fs: 3.0.8 + semver: 7.7.2 + tar-fs: 3.1.0 yargs: 17.7.2 transitivePeerDependencies: - bare-buffer @@ -2605,20 +2728,24 @@ snapshots: '@rtsao/scc@1.1.0': {} - '@stylistic/eslint-plugin@4.2.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)': + '@stylistic/eslint-plugin@4.4.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)': dependencies: - '@typescript-eslint/utils': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2) + '@typescript-eslint/utils': 8.43.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2) eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215) - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.2 + picomatch: 4.0.3 transitivePeerDependencies: - supports-color - typescript '@tootallnate/quickjs-emscripten@0.23.0': {} + '@types/adm-zip@0.5.7': + dependencies: + '@types/node': 22.13.13 + '@types/chrome@0.0.312': dependencies: '@types/filesystem': 0.0.36 @@ -2649,7 +2776,7 @@ snapshots: dependencies: '@types/node': 22.13.13 - '@types/less@3.0.6(patch_hash=641e6c93bb737bac7fc283416857bd095cd85bcbcba63becb7a8bbcc78f73076)': {} + '@types/less@3.0.8(patch_hash=641e6c93bb737bac7fc283416857bd095cd85bcbcba63becb7a8bbcc78f73076)': {} '@types/lodash@4.17.15': {} @@ -2724,11 +2851,29 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/project-service@8.43.0(typescript@5.8.2)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.8.2) + '@typescript-eslint/types': 8.43.0 + debug: 4.4.1 + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@8.28.0': dependencies: '@typescript-eslint/types': 8.28.0 '@typescript-eslint/visitor-keys': 8.28.0 + '@typescript-eslint/scope-manager@8.43.0': + dependencies: + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/visitor-keys': 8.43.0 + + '@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.8.2)': + dependencies: + typescript: 5.8.2 + '@typescript-eslint/type-utils@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)': dependencies: '@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2) @@ -2742,6 +2887,8 @@ snapshots: '@typescript-eslint/types@8.28.0': {} + '@typescript-eslint/types@8.43.0': {} + '@typescript-eslint/typescript-estree@8.28.0(typescript@5.8.2)': dependencies: '@typescript-eslint/types': 8.28.0 @@ -2756,6 +2903,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.43.0(typescript@5.8.2)': + dependencies: + '@typescript-eslint/project-service': 8.43.0(typescript@5.8.2) + '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.8.2) + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/visitor-keys': 8.43.0 + debug: 4.4.1 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)': dependencies: '@eslint-community/eslint-utils': 4.5.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)) @@ -2767,11 +2930,27 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.43.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)) + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.8.2) + eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/visitor-keys@8.28.0': dependencies: '@typescript-eslint/types': 8.28.0 eslint-visitor-keys: 4.2.0 + '@typescript-eslint/visitor-keys@8.43.0': + dependencies: + '@typescript-eslint/types': 8.43.0 + eslint-visitor-keys: 4.2.1 + '@vap/core@0.0.12': dependencies: eventemitter3: 4.0.7 @@ -2782,12 +2961,16 @@ snapshots: vscode-oniguruma: 1.7.0 vscode-textmate: 5.2.0 - acorn-jsx@5.3.2(acorn@8.14.1): + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: - acorn: 8.14.1 + acorn: 8.15.0 acorn@8.14.1: {} + acorn@8.15.0: {} + + adm-zip@0.5.16: {} + agent-base@7.1.3: {} ajv@6.12.6: @@ -2806,6 +2989,8 @@ snapshots: ansi-regex@5.0.1: {} + ansi-regex@6.2.2: {} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -2814,6 +2999,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.3: {} + argparse@2.0.1: {} array-buffer-byte-length@1.0.2: @@ -2891,8 +3078,6 @@ snapshots: async-function@1.0.0: {} - async@1.5.2: {} - available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 @@ -2932,12 +3117,12 @@ snapshots: basic-ftp@5.0.5: {} - brace-expansion@1.1.11: + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.1: + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 @@ -3002,9 +3187,9 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chromium-bidi@2.1.2(devtools-protocol@0.0.1413902): + chromium-bidi@8.0.0(devtools-protocol@0.0.1495869): dependencies: - devtools-protocol: 0.0.1413902 + devtools-protocol: 0.0.1495869 mitt: 3.0.1 zod: 3.24.2 @@ -3034,9 +3219,9 @@ snapshots: commander@10.0.1: {} - commander@2.20.3: {} + commander@13.1.0: {} - commander@5.1.0: {} + commander@2.20.3: {} concat-map@0.0.1: {} @@ -3090,14 +3275,14 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.6: - dependencies: - ms: 2.1.2 - debug@4.4.0: dependencies: ms: 2.1.3 + debug@4.4.1: + dependencies: + ms: 2.1.3 + deep-is@0.1.4: {} define-data-property@1.1.4: @@ -3118,7 +3303,7 @@ snapshots: escodegen: 2.1.0 esprima: 4.0.1 - devtools-protocol@0.0.1413902: {} + devtools-protocol@0.0.1495869: {} diff@7.0.0: {} @@ -3141,8 +3326,12 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + eastasianwidth@0.2.0: {} + emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -3392,7 +3581,7 @@ snapshots: optionalDependencies: '@typescript-eslint/eslint-plugin': 8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2) - eslint-scope@8.3.0: + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 @@ -3401,15 +3590,17 @@ snapshots: eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.2.1: {} + eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215): dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.19.2 '@eslint/core': 0.11.0 '@eslint/eslintrc': 3.3.1 '@eslint/js': 9.20.0 - '@eslint/plugin-kit': 0.2.7 + '@eslint/plugin-kit': 0.3.5 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.2 @@ -3418,11 +3609,11 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.3.6 + debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -3440,11 +3631,11 @@ snapshots: transitivePeerDependencies: - supports-color - espree@10.3.0: + espree@10.4.0: dependencies: - acorn: 8.14.1 - acorn-jsx: 5.3.2(acorn@8.14.1) - eslint-visitor-keys: 4.2.0 + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 esprima@4.0.1: {} @@ -3464,7 +3655,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.0 + debug: 4.4.1 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -3536,14 +3727,17 @@ snapshots: dependencies: is-callable: 1.2.7 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + fs-extra@11.3.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.1 - fs.realpath@1.0.0: {} - fsevents@2.3.3: optional: true @@ -3619,7 +3813,7 @@ snapshots: dependencies: basic-ftp: 5.0.5 data-uri-to-buffer: 6.0.2 - debug: 4.4.0 + debug: 4.4.1 fs-extra: 11.3.0 transitivePeerDependencies: - supports-color @@ -3634,14 +3828,14 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@7.2.3: + glob@11.0.3: dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 + foreground-child: 3.3.1 + jackspeak: 4.1.1 + minimatch: 10.0.3 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 global-modules@2.0.0: dependencies: @@ -3734,14 +3928,14 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.3 - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.3 - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -3760,13 +3954,6 @@ snapshots: imurmurhash@0.1.4: {} - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - ini@1.3.8: {} ini@4.1.3: {} @@ -3920,6 +4107,10 @@ snapshots: has-symbols: 1.1.0 set-function-name: 2.0.2 + jackspeak@4.1.1: + dependencies: + '@isaacs/cliui': 8.0.2 + js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -3959,10 +4150,6 @@ snapshots: object.assign: 4.1.5 object.values: 1.2.1 - jszip@2.7.0: - dependencies: - pako: 1.0.11 - keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -3998,6 +4185,8 @@ snapshots: dependencies: tslib: 2.6.2 + lru-cache@11.2.1: {} + lru-cache@7.18.3: {} math-intrinsics@1.1.0: {} @@ -4015,24 +4204,28 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + minimatch@10.0.3: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + minimatch@3.1.2: dependencies: - brace-expansion: 1.1.11 + brace-expansion: 1.1.12 minimatch@9.0.5: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimist@1.2.8: {} + minipass@7.1.2: {} + mitt@3.0.1: {} moment@2.30.1: {} monaco-editor@0.52.2: {} - ms@2.1.2: {} - ms@2.1.3: {} nanoid@3.3.11: {} @@ -4130,7 +4323,7 @@ snapshots: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.3 - debug: 4.4.0 + debug: 4.4.1 get-uri: 6.0.3 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 @@ -4144,7 +4337,7 @@ snapshots: degenerator: 5.0.1 netmask: 2.0.2 - pako@1.0.11: {} + package-json-from-dist@1.0.1: {} param-case@3.0.4: dependencies: @@ -4169,12 +4362,15 @@ snapshots: path-exists@4.0.0: {} - path-is-absolute@1.0.1: {} - path-key@3.1.1: {} path-parse@1.0.7: {} + path-scurry@2.0.0: + dependencies: + lru-cache: 11.2.1 + minipass: 7.1.2 + path-type@4.0.0: {} pend@1.2.0: {} @@ -4183,7 +4379,7 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.2: {} + picomatch@4.0.3: {} possible-typed-array-names@1.1.0: {} @@ -4219,7 +4415,7 @@ snapshots: proxy-agent@6.5.0: dependencies: agent-base: 7.1.3 - debug: 4.4.0 + debug: 4.4.1 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 lru-cache: 7.18.3 @@ -4238,22 +4434,20 @@ snapshots: punycode@2.3.1: {} - puppeteer-core@24.4.0: + puppeteer-core@24.19.0: dependencies: - '@puppeteer/browsers': 2.8.0 - chromium-bidi: 2.1.2(devtools-protocol@0.0.1413902) - debug: 4.4.0 - devtools-protocol: 0.0.1413902 + '@puppeteer/browsers': 2.10.8 + chromium-bidi: 8.0.0(devtools-protocol@0.0.1495869) + debug: 4.4.1 + devtools-protocol: 0.0.1495869 typed-query-selector: 2.12.0 - ws: 8.18.1 + ws: 8.18.3 transitivePeerDependencies: - bare-buffer - bufferutil - supports-color - utf-8-validate - q@1.5.1: {} - queue-microtask@1.2.3: {} react-is@16.13.1: {} @@ -4331,6 +4525,8 @@ snapshots: semver@7.7.1: {} + semver@7.7.2: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -4402,7 +4598,7 @@ snapshots: socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.3 - debug: 4.4.0 + debug: 4.4.1 socks: 2.8.4 transitivePeerDependencies: - supports-color @@ -4442,6 +4638,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + string.prototype.matchall@4.0.12: dependencies: call-bind: 1.0.8 @@ -4490,6 +4692,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + strip-bom@3.0.0: {} strip-json-comments@3.1.1: {} @@ -4572,7 +4778,7 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tar-fs@3.0.8: + tar-fs@3.1.0: dependencies: pump: 3.0.0 tar-stream: 3.1.7 @@ -4782,6 +4988,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + wrappy@1.0.2: {} write-file-atomic@5.0.1: @@ -4789,7 +5001,7 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.1.0 - ws@8.18.1: {} + ws@8.18.3: {} y18n@5.0.8: {} @@ -4812,11 +5024,4 @@ snapshots: yocto-queue@0.1.0: {} - zip-local@0.3.5: - dependencies: - async: 1.5.2 - graceful-fs: 4.2.11 - jszip: 2.7.0 - q: 1.5.1 - zod@3.24.2: {} diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs index 0436c3094..262832ae2 100644 --- a/scripts/build/buildWeb.mjs +++ b/scripts/build/buildWeb.mjs @@ -21,10 +21,10 @@ import { readFileSync } from "fs"; import { appendFile, mkdir, readdir, readFile, rm, writeFile } from "fs/promises"; -import { join } from "path"; -import Zip from "zip-local"; +import path, { join } from "path"; import { BUILD_TIMESTAMP, commonOpts, globPlugins, IS_DEV, IS_REPORTER, IS_COMPANION_TEST, VERSION, commonRendererPlugins, buildOrWatchAll, stringifyValues } from "./common.mjs"; +import AdmZip from "adm-zip"; /** * @type {import("esbuild").BuildOptions} @@ -203,14 +203,15 @@ if (!process.argv.includes("--skip-extension")) { buildExtension("firefox-unpacked", ["background.js", "content.js", "manifestv2.json", "icon.png"]), ]); - Zip.zip("dist/browser/chromium-unpacked", (_err, zip) => { - zip.compress().save("dist/extension-chrome.zip"); - console.info("Packed Chromium Extension written to dist/extension-chrome.zip"); - }); - Zip.zip("dist/browser/firefox-unpacked", (_err, zip) => { - zip.compress().save("dist/extension-firefox.zip"); - console.info("Packed Firefox Extension written to dist/extension-firefox.zip"); - }); + const chromiumZip = new AdmZip(); + chromiumZip.addLocalFolder("dist/browser/chromium-unpacked"); + chromiumZip.writeZip(path.resolve("dist/extension-chrome.zip")); + console.info("Packed Chromium Extension written to dist/extension-chrome.zip"); + + const firefoxZip = new AdmZip(); + firefoxZip.addLocalFolder("dist/browser/firefox-unpacked"); + firefoxZip.writeZip(path.resolve("dist/extension-firefox.zip")); + console.info("Packed Firefox Extension written to dist/extension-firefox.zip"); } else { await appendCssRuntime; } diff --git a/src/Vencord.ts b/src/Vencord.ts index d7c36ea0b..fb1aad9fa 100644 --- a/src/Vencord.ts +++ b/src/Vencord.ts @@ -155,7 +155,7 @@ async function init() { syncSettings(); - if (!IS_WEB && !IS_UPDATER_DISABLED) { + if (!IS_WEB && !IS_UPDATER_DISABLED || !IS_DEV) { runUpdateCheck(); // this tends to get really annoying, so only do this if the user has auto-update without notification enabled diff --git a/src/components/settings/tabs/sync/CloudTab.tsx b/src/components/settings/tabs/sync/CloudTab.tsx index 07489cb62..7f8295ff8 100644 --- a/src/components/settings/tabs/sync/CloudTab.tsx +++ b/src/components/settings/tabs/sync/CloudTab.tsx @@ -22,10 +22,10 @@ import { CheckedTextInput } from "@components/CheckedTextInput"; import { Grid } from "@components/Grid"; import { Link } from "@components/Link"; import { SettingsTab, wrapTab } from "@components/settings/tabs/BaseTab"; -import { authorizeCloud, checkCloudUrlCsp, cloudLogger, deauthorizeCloud, getCloudAuth, getCloudUrl } from "@utils/cloud"; +import { authorizeCloud, cloudLogger, deauthorizeCloud, getCloudAuth, getCloudUrl } from "@utils/cloud"; import { Margins } from "@utils/margins"; import { deleteCloudSettings, getCloudSettings, putCloudSettings } from "@utils/settingsSync"; -import { Alerts, Button, Forms, Switch, Tooltip } from "@webpack/common"; +import { Alerts, Button, Forms, Switch, Tooltip, useState } from "@webpack/common"; function validateUrl(url: string) { try { @@ -37,8 +37,6 @@ function validateUrl(url: string) { } async function eraseAllData() { - if (!await checkCloudUrlCsp()) return; - const res = await fetch(new URL("/v1/", getCloudUrl()), { method: "DELETE", headers: { Authorization: await getCloudAuth() } @@ -119,15 +117,31 @@ function SettingsSyncSection() { function CloudTab() { const settings = useSettings(["cloud.authenticated", "cloud.url"]); + const [inputKey, setInputKey] = useState(0); + + async function changeUrl(url: string) { + settings.cloud.url = url; + settings.cloud.authenticated = false; + + await deauthorizeCloud(); + await authorizeCloud(); + + setInputKey(prev => prev + 1); + } return ( - Equicord comes with a cloud integration that adds goodies like settings sync across devices. - It respects your privacy, and - the source code is AGPL 3.0 licensed so you - can host it yourself. + Equicord comes with a cloud integration allowing settings to be synced across apps and devices. +
+ We use Vencord's cloud source code to provide our cloud instance which has a 32MB backup cap. +
+ Our privacy policy allows you to see what information we store, how we use it, and data retention. +
+ The Vencord Cloud repository is AGPL 3.0 licensed so you can host it yourself it you would like. +
+ You can swap between Equicord and Vencord's different cloud instances below if needed.
{ settings.cloud.url = v; settings.cloud.authenticated = false; - deauthorizeCloud(); + await deauthorizeCloud(); }} validate={validateUrl} /> @@ -162,8 +176,8 @@ function CloudTab() { size={Button.Sizes.MEDIUM} disabled={!settings.cloud.authenticated} onClick={async () => { - await deauthorizeCloud(); settings.cloud.authenticated = false; + await deauthorizeCloud(); await authorizeCloud(); }} > @@ -184,6 +198,12 @@ function CloudTab() { > Erase All Data + + diff --git a/src/equicordplugins/autoJump/index.tsx b/src/equicordplugins/autoJump/index.tsx new file mode 100644 index 000000000..2a6824dd6 --- /dev/null +++ b/src/equicordplugins/autoJump/index.tsx @@ -0,0 +1,80 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { NavContextMenuPatchCallback } from "@api/ContextMenu"; +import { EquicordDevs } from "@utils/constants"; +import definePlugin from "@utils/types"; +import { Menu, ChannelStore, NavigationRouter, FluxDispatcher, MessageActions, MessageStore } from "@webpack/common"; + +interface ChannelSelectEvent { + type: "CHANNEL_SELECT"; + channelId: string | null; + guildId: string | null; +} + +let lastChan = "0"; + +function jumpToPresent(channelId, { limit }: { limit?: number } = {}) { + MessageActions.trackJump(channelId, null, "Present"); + + const jump = { present: true }; + + if (MessageStore.hasPresent(channelId)) { + FluxDispatcher.dispatch({ + type: "LOAD_MESSAGES_SUCCESS_CACHED", + jump, + channelId, + limit + }); + } else { + MessageActions.fetchMessages({ + channelId, + limit, + jump + }); + } +} + +function autoJump(channel: any) { + const guildId = channel.guild_id ?? "@me"; + const channelId = channel.id; + + if (channelId === lastChan) return; + + NavigationRouter.transitionTo(`/channels/${guildId}/${channelId}`); + lastChan = channelId; + + jumpToPresent(channelId, { limit: 100 }); +} + +const MenuPatch: NavContextMenuPatchCallback = (children, { channel }) => { + children.push( + autoJump(channel)} + /> + ); +}; + +export default definePlugin({ + name: "AutoJump", + description: "Automatically jumps to the last message in selected channel & adds a context-menu option to jump to the last message.", + authors: [EquicordDevs.omaw], + contextMenus: { + "channel-context": MenuPatch, + "user-context": MenuPatch, + "thread-context": MenuPatch + }, + flux: { + async CHANNEL_SELECT({ guildId, channelId }: ChannelSelectEvent) { + if (!guildId || !channelId) return; + const channel = ChannelStore.getChannel(channelId); + if (!channel || lastChan === channel.id) return; + autoJump(channel); + } + } +}); diff --git a/src/equicordplugins/betterCommands/index.ts b/src/equicordplugins/betterCommands/index.ts index c6044c384..26dc8dd05 100644 --- a/src/equicordplugins/betterCommands/index.ts +++ b/src/equicordplugins/betterCommands/index.ts @@ -4,9 +4,11 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ +import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands"; import { definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; +import { FluxDispatcher, UserStore } from "@webpack/common"; const settings = definePluginSettings({ autoFillArguments: { @@ -16,6 +18,13 @@ const settings = definePluginSettings({ } }); +function fetchIndex(target: object) { + FluxDispatcher.dispatch({ + type: "APPLICATION_COMMAND_INDEX_FETCH_REQUEST", + target + }); +} + export default definePlugin({ name: "BetterCommands", description: "Enhances the command system with miscellaneous improvements.", @@ -32,5 +41,52 @@ export default definePlugin({ }, ] } + ], + commands: [ + { + name: "refresh", + description: "Refreshes Discord application commands locally", + options: [ + { + name: "user", + description: "specific user to try and refresh", + type: ApplicationCommandOptionType.USER, + } + ], + inputType: ApplicationCommandInputType.BOT, + execute: async (opts, ctx) => { + try { + const channelId = ctx.channel.id; + const guildId = ctx.guild?.id; + const user = findOption(opts, "user") as string; + + sendBotMessage(ctx.channel.id, { + content: "Refreshing application commands...", + }); + + fetchIndex({ type: "channel", channelId }); + + if (guildId) fetchIndex({ type: "guild", guildId }); + + if (user) { + const target = await UserStore.getUser(user); + fetchIndex( + target.bot + ? { type: "application", applicationId: target.id } + : { type: "user" } + ); + } + + sendBotMessage(ctx.channel.id, { + content: "Commands refreshed successfully!", + }); + } catch (err) { + console.error("[Refresh Command] Error refreshing commands:", err); + sendBotMessage(ctx.channel.id, { + content: "Failed to refresh commands. Check the console for details.", + }); + } + }, + }, ] }); diff --git a/src/equicordplugins/customUserColors/SetColorModal.tsx b/src/equicordplugins/customUserColors/SetColorModal.tsx index ba979da67..2fdf260ce 100644 --- a/src/equicordplugins/customUserColors/SetColorModal.tsx +++ b/src/equicordplugins/customUserColors/SetColorModal.tsx @@ -14,8 +14,8 @@ import { colors, DATASTORE_KEY } from "./index"; const cl = classNameFactory("vc-customColors-"); -export function SetColorModal({ userId, modalProps }: { userId: string, modalProps: ModalProps; }) { - const initialColor = parseInt(colors[userId], 16) || 372735; +export function SetColorModal({ id, modalProps }: { id: string, modalProps: ModalProps; }) { + const initialColor = parseInt(colors[id], 16) || 372735; // color picker default to current color set for user (if null it's 0x05afff :3 ) const [colorPickerColor, setColorPickerColor] = useState(initialColor); @@ -32,13 +32,13 @@ export function SetColorModal({ userId, modalProps }: { userId: string, modalPro } async function saveUserColor() { - colors[userId] = colorPickerColor.toString(16).padStart(6, "0"); + colors[id] = colorPickerColor.toString(16).padStart(6, "0"); await set(DATASTORE_KEY, colors); modalProps.onClose(); } async function deleteUserColor() { - delete colors[userId]; + delete colors[id]; await set(DATASTORE_KEY, colors); modalProps.onClose(); } diff --git a/src/equicordplugins/customUserColors/index.tsx b/src/equicordplugins/customUserColors/index.tsx index 9efc00684..b09bd0b9a 100644 --- a/src/equicordplugins/customUserColors/index.tsx +++ b/src/equicordplugins/customUserColors/index.tsx @@ -12,9 +12,9 @@ import { definePluginSettings, Settings } from "@api/Settings"; import { EquicordDevs } from "@utils/constants"; import { openModal } from "@utils/modal"; import definePlugin, { OptionType } from "@utils/types"; -import { User } from "@vencord/discord-types"; +import { Channel, User } from "@vencord/discord-types"; import { extractAndLoadChunksLazy } from "@webpack"; -import { Menu } from "@webpack/common"; +import { ChannelStore, Menu, SelectedChannelStore } from "@webpack/common"; import { SetColorModal } from "./SetColorModal"; @@ -52,20 +52,37 @@ const userContextMenuPatch: NavContextMenuPatchCallback = (children, { user }: { icon={ColorIcon} action={async () => { await requireSettingsMenu(); - openModal(modalProps => ); + openModal(modalProps => ); }} /> ); children.push(, setCustomColorItem); - }; -export function getCustomColorString(userId: string | undefined, withHash?: boolean): string | undefined { - if (!userId) return; - if (!colors[userId] || !Settings.plugins.CustomUserColors.enabled) return; - if (withHash) return `#${colors[userId]}`; - return colors[userId]; +const channelContextMenuPatch: NavContextMenuPatchCallback = (children, { channel }: { channel: Channel; }) => { + if (channel?.id == null) return; + + const setCustomColorItem = ( + { + await requireSettingsMenu(); + openModal(modalProps => ); + }} + /> + ); + + children.push(, setCustomColorItem); +}; + +export function getCustomColorString(id: string | undefined, withHash?: boolean): string | undefined { + if (!id) return; + if (!colors[id] || !Settings.plugins.CustomUserColors.enabled) return; + if (withHash) return `#${colors[id]}`; + return colors[id]; } const settings = definePluginSettings({ @@ -85,7 +102,10 @@ export default definePlugin({ name: "CustomUserColors", description: "Lets you add a custom color to any user, anywhere! Highly recommend to use with typingTweaks and roleColorEverywhere", authors: [EquicordDevs.mochienya], - contextMenus: { "user-context": userContextMenuPatch }, + contextMenus: { + "user-context": userContextMenuPatch, + "gdm-context": channelContextMenuPatch, + }, settings, requireSettingsMenu, getCustomColorString, @@ -135,10 +155,12 @@ export default definePlugin({ wrapMessageColorProps(colorProps: { colorString: string, colorStrings?: Record<"primaryColor" | "secondaryColor" | "tertiaryColor", string>; }, context: any) { try { + const channelId = SelectedChannelStore.getChannelId(); + const channel = ChannelStore.getChannel(channelId); + const isDM = channel.isDM() || channel.isMultiUserDM(); const colorString = this.colorIfServer(context); - if (colorString === colorProps.colorString) { - return colorProps; - } + if (colorString === colorProps.colorString) return colorProps; + if (!settings.store.colorInServers && !isDM) return colorProps; return { ...colorProps, @@ -156,8 +178,9 @@ export default definePlugin({ }, colorDMList(context: any): string | undefined { - const userId = context?.user?.id; - const colorString = getCustomColorString(userId, true); + const id = context?.user?.id ?? context?.channel?.id; + const colorString = getCustomColorString(id, true); + return colorString ?? "inherit"; }, diff --git a/src/equicordplugins/instantScreenshare/utils.tsx b/src/equicordplugins/instantScreenshare/utils.tsx index 4c4d7d4b5..31bade9f5 100644 --- a/src/equicordplugins/instantScreenshare/utils.tsx +++ b/src/equicordplugins/instantScreenshare/utils.tsx @@ -7,15 +7,14 @@ import { definePluginSettings } from "@api/Settings"; import { Logger } from "@utils/Logger"; import { OptionType } from "@utils/types"; -import { findByCodeLazy, findByPropsLazy } from "@webpack"; -import { Forms, SearchableSelect, useEffect, useState } from "@webpack/common"; +import { findByCodeLazy } from "@webpack"; +import { Forms, MediaEngineStore, SearchableSelect, useEffect, useState } from "@webpack/common"; interface PickerProps { streamMediaSelection: any[]; streamMedia: any[]; } -const mediaEngine = findByPropsLazy("getMediaEngine"); const getDesktopSources = findByCodeLazy("desktop sources"); export const settings = definePluginSettings({ @@ -26,7 +25,7 @@ export const settings = definePluginSettings({ }); export async function getCurrentMedia() { - const media = mediaEngine.getMediaEngine(); + const media = MediaEngineStore.getMediaEngine(); const sources = [ ...(await getDesktopSources(media, ["screen"], null) ?? []), ...(await getDesktopSources(media, ["window", "application"], null) ?? []) @@ -63,7 +62,7 @@ function StreamSimplePicker({ streamMediaSelection, streamMedia }: PickerProps) function ScreenSetting() { const { streamMedia } = settings.use(["streamMedia"]); - const media = mediaEngine.getMediaEngine(); + const media = MediaEngineStore.getMediaEngine(); const [streamMediaSelection, setStreamMediaSelection] = useState([]); const [loading, setLoading] = useState(true); diff --git a/src/equicordplugins/newPluginsManager/NewPluginsModal.css b/src/equicordplugins/newPluginsManager/NewPluginsModal.css new file mode 100644 index 000000000..163505ae7 --- /dev/null +++ b/src/equicordplugins/newPluginsManager/NewPluginsModal.css @@ -0,0 +1,20 @@ +.vc-newPluginsManager-restart-tooltip { + max-width: 280px; +} + +.vc-newPluginsManager-restart-list { + padding-left: 1.25em; +} + +.vc-newPluginsManager-restart-list li { + list-style: disc; +} + +.vc-newPluginsManager-close > div { + display: flex; +} + +.vc-newPluginsManager-disable-wrapper { + display: flex; + margin: auto 0; +} \ No newline at end of file diff --git a/src/equicordplugins/newPluginsManager/NewPluginsModal.tsx b/src/equicordplugins/newPluginsManager/NewPluginsModal.tsx index e4eef0db1..50c4014a0 100644 --- a/src/equicordplugins/newPluginsManager/NewPluginsModal.tsx +++ b/src/equicordplugins/newPluginsManager/NewPluginsModal.tsx @@ -4,47 +4,36 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import { useSettings } from "@api/Settings"; +import "./NewPluginsModal.css"; + +import { Settings, useSettings } from "@api/Settings"; import { classNameFactory } from "@api/Styles"; -import { PluginCard } from "@components/settings/tabs/plugins/PluginCard"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { PluginCard } from "@components/settings/tabs/plugins"; import { ChangeList } from "@utils/ChangeList"; -import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; -import { Alerts, Button, Flex, Forms, Parser, React, Text, Tooltip, useMemo } from "@webpack/common"; +import { classes, Margins } from "@utils/index"; +import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; +import { useForceUpdater } from "@utils/react"; +import { findComponentByCodeLazy } from "@webpack"; +import { Button, Flex, Forms, React, Text, Tooltip, useMemo } from "@webpack/common"; import { JSX } from "react"; import Plugins from "~plugins"; -import { getNewPlugins, writeKnownPlugins } from "./knownPlugins"; +import { getNewPlugins, getNewSettings, KnownPluginSettingsMap, writeKnownSettings } from "./knownSettings"; const cl = classNameFactory("vc-plugins-"); +const Checkbox = findComponentByCodeLazy(".checkboxWrapperDisabled:"); + let hasSeen = false; // Most of this was stolen from PluginSettings directly. -export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalProps; newPlugins: Set; }) { +export function NewPluginsModal({ modalProps, newPlugins, newSettings }: { modalProps: ModalProps; newPlugins: Set; newSettings: KnownPluginSettingsMap; }) { const settings = useSettings(); const changes = React.useMemo(() => new ChangeList(), []); - - React.useEffect(() => { - return () => void (changes.hasChanges && Alerts.show({ - title: "Restart required", - body: ( - <> -

The following plugins require a restart:

-
{changes.map((s, i) => ( - <> - {i > 0 && ", "} - {Parser.parse("`" + s + "`")} - - ))}
- - ), - confirmText: "Restart now", - cancelText: "Later!", - onConfirm: () => location.reload() - })); - }, []); + let updateContinueButton = () => { }; const depMap = React.useMemo(() => { const o = {} as Record; @@ -60,8 +49,13 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP return o; }, []); - const sortedPlugins = useMemo(() => [...newPlugins].map(pn => Plugins[pn]) - .sort((a, b) => a.name.localeCompare(b.name)), []); + const mapPlugins = (array: string[]) => array.map(pn => Plugins[pn]) + .sort((a, b) => a.name.localeCompare(b.name)); + + const sortedPlugins = useMemo(() => [ + ...mapPlugins([...newPlugins]), + ...mapPlugins([...newSettings.keys()].filter(p => !newPlugins.has(p))) + ], []); const plugins = [] as JSX.Element[]; const requiredPlugins = [] as JSX.Element[]; @@ -83,10 +77,14 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP changes.handleChange(name)} + onRestartNeeded={name => { + changes.handleChange(name); + updateContinueButton(); + }} disabled={true} plugin={p} key={p.name} + isNew={newPlugins.has(p.name)} /> )} @@ -94,10 +92,14 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP } else { plugins.push( changes.handleChange(name)} + onRestartNeeded={name => { + changes.handleChange(name); + updateContinueButton(); + }} disabled={false} plugin={p} key={p.name} + isNew={newPlugins.has(p.name)} /> ); } @@ -106,7 +108,17 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP return - New Plugins ({[...plugins, ...requiredPlugins].length}) + New Plugins and Settings ({[...plugins, ...requiredPlugins].length}) + + {tooltipProps => +
+ +
+ } +
@@ -115,39 +127,79 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP - + void) => updateContinueButton = v} + /> + + +
+ { + Settings.plugins.NewPluginsManager.enabled = !settings?.plugins?.NewPluginsManager?.enabled; + }} + > + Don't show this again + +
; } +function ContinueButton(props: { callback: (update: () => void) => void; changes: ChangeList; close: () => any; }) { + const update = useForceUpdater(); + props.callback(update); + return + The following plugins require a restart: +
+
    + {props.changes.map(p =>
  • {p}
  • )} +
+ } + shouldShow={props.changes.hasChanges} + > + {tooltipProps => + + } + ; +} + function makeDependencyList(deps: string[]) { return ( This plugin is required by: - {deps.map((dep: string) => {dep})} + {deps.map((dep: string) => {dep})} ); } export async function openNewPluginsModal() { const newPlugins = await getNewPlugins(); - if (newPlugins.size && !hasSeen) { + const newSettings = await getNewSettings(); + if ((newPlugins.size || newSettings.size) && !hasSeen) { hasSeen = true; - openModal(modalProps => ( + const modalKey = openModal(modalProps => { closeModal(modalKey); }}> - )); + ); } } diff --git a/src/equicordplugins/newPluginsManager/index.tsx b/src/equicordplugins/newPluginsManager/index.tsx index 294036ab1..eb8852684 100644 --- a/src/equicordplugins/newPluginsManager/index.tsx +++ b/src/equicordplugins/newPluginsManager/index.tsx @@ -7,18 +7,22 @@ import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; -import { KNOWN_PLUGINS_DATA_KEY } from "./knownPlugins"; +import * as KnownSettings from "./knownSettings"; +import { KNOWN_PLUGINS_LEGACY_DATA_KEY, KNOWN_SETTINGS_DATA_KEY } from "./knownSettings"; import { openNewPluginsModal } from "./NewPluginsModal"; export default definePlugin({ name: "NewPluginsManager", - description: "Utility that notifies you when new plugins are added to Equicord", + description: "Utility that notifies you when new plugins are added to Vencord", authors: [Devs.Sqaaakoi], + enabledByDefault: true, flux: { async POST_CONNECTION_OPEN() { openNewPluginsModal(); } }, openNewPluginsModal, - KNOWN_PLUGINS_DATA_KEY + KNOWN_PLUGINS_LEGACY_DATA_KEY, + KNOWN_SETTINGS_DATA_KEY, + KnownSettings }); diff --git a/src/equicordplugins/newPluginsManager/knownPlugins.ts b/src/equicordplugins/newPluginsManager/knownPlugins.ts deleted file mode 100644 index 2a9dea6f4..000000000 --- a/src/equicordplugins/newPluginsManager/knownPlugins.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { DataStore } from "@api/index"; - -import plugins from "~plugins"; - -export const KNOWN_PLUGINS_DATA_KEY = "NewPluginsManager_KnownPlugins"; - -export async function getKnownPlugins(): Promise> { - let knownPlugins = await DataStore.get(KNOWN_PLUGINS_DATA_KEY) as string[]; - if (knownPlugins === undefined) { - knownPlugins = Object.keys(plugins); - DataStore.set(KNOWN_PLUGINS_DATA_KEY, knownPlugins); - } - return new Set(knownPlugins); -} - -export async function getNewPlugins(): Promise> { - const currentPlugins = Object.keys(plugins); - const knownPlugins = await getKnownPlugins(); - return new Set(currentPlugins.filter(p => !knownPlugins.has(p))); -} - -export async function writeKnownPlugins(): Promise { - const currentPlugins = Object.keys(plugins); - const knownPlugins = await getKnownPlugins(); - DataStore.set(KNOWN_PLUGINS_DATA_KEY, [...new Set([...currentPlugins, ...knownPlugins])]); -} diff --git a/src/equicordplugins/newPluginsManager/knownSettings.ts b/src/equicordplugins/newPluginsManager/knownSettings.ts new file mode 100644 index 000000000..397d1390a --- /dev/null +++ b/src/equicordplugins/newPluginsManager/knownSettings.ts @@ -0,0 +1,91 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { DataStore } from "@api/index"; + +import plugins from "~plugins"; + +export type KnownPluginSettingsMap = Map>; + +export const KNOWN_PLUGINS_LEGACY_DATA_KEY = "NewPluginsManager_KnownPlugins"; +export const KNOWN_SETTINGS_DATA_KEY = "NewPluginsManager_KnownSettings"; + +function getSettingsSetForPlugin(plugin: string): Set { + const settings = plugins[plugin]?.settings?.def || {}; + return new Set(Object.keys(settings).filter(setting => setting !== "enabled")); +} + +function getCurrentSettings(pluginList: string[]): KnownPluginSettingsMap { + return new Map(pluginList.map(name => [ + name, + getSettingsSetForPlugin(name) + ])); +} + +export async function getKnownSettings(): Promise { + let map = await DataStore.get(KNOWN_SETTINGS_DATA_KEY) as KnownPluginSettingsMap; + if (map === undefined) { + const knownPlugins = await DataStore.get(KNOWN_PLUGINS_LEGACY_DATA_KEY) ?? [] as string[]; + const Plugins = [...Object.keys(plugins), ...knownPlugins]; + map = getCurrentSettings(Plugins); + DataStore.set(KNOWN_SETTINGS_DATA_KEY, map); + } + return map; +} + +export async function getNewSettings(): Promise { + const map = getCurrentSettings(Object.keys(plugins)); + const knownSettings = await getKnownSettings(); + map.forEach((settings, plugin) => { + const filteredSettings = [...settings].filter(setting => !knownSettings.get(plugin)?.has(setting)); + if (!filteredSettings.length) return map.delete(plugin); + map.set(plugin, new Set(filteredSettings)); + }); + return map; +} + +export async function getKnownPlugins(): Promise> { + const knownSettings = await getKnownSettings(); + return new Set(knownSettings.keys()); +} + +export async function getNewPlugins(): Promise> { + const currentPlugins = Object.keys(plugins); + const knownPlugins = await getKnownPlugins(); + return new Set(currentPlugins.filter(p => !knownPlugins.has(p))); +} + +export async function writeKnownSettings() { + const currentSettings = getCurrentSettings(Object.keys(plugins)); + const knownSettings = await getKnownSettings(); + const allSettings = new Map(); + new Set([...currentSettings.keys(), ...knownSettings.keys()]).forEach(plugin => { + allSettings.set(plugin, new Set([ + ...(currentSettings.get(plugin) || []), + ...(knownSettings.get(plugin) || []) + ])); + }); + await DataStore.set(KNOWN_SETTINGS_DATA_KEY, allSettings); +} + +export async function debugWipeSomeData() { + const settings = await getKnownSettings(); + settings.forEach((value, key) => { + if (Math.random() > 0.8) { + if (Math.random() > 0.5) return settings.set(key, new Set([...value].filter(() => Math.random() > 0.5))); + return settings.delete(key); + } + }); + await DataStore.set(KNOWN_SETTINGS_DATA_KEY, settings); +} + +export async function editRawData(patcher: (data: KnownPluginSettingsMap) => (Promise | any)) { + if (!patcher) return; + const map = await DataStore.get(KNOWN_SETTINGS_DATA_KEY) as KnownPluginSettingsMap; + const newMap = new Map(map); + await patcher(newMap); + await DataStore.set(KNOWN_SETTINGS_DATA_KEY, newMap ?? map); +} diff --git a/src/equicordplugins/questify/utils/components.tsx b/src/equicordplugins/questify/utils/components.tsx index fde38d57b..a5c17f630 100644 --- a/src/equicordplugins/questify/utils/components.tsx +++ b/src/equicordplugins/questify/utils/components.tsx @@ -16,7 +16,7 @@ export const GuildlessServerListItemComponent = findComponentByCodeLazy("tooltip export const GuildedServerListItemPillComponent = findComponentByCodeLazy('"pill":"empty"'); export const ServerListItemLowerBadgeComponent = findComponentByCodeLazy("STATUS_DANGER,disableColor:"); export const ServerListItemUpperBadgeComponent = findComponentByCodeLazy("STATUS_DANGER,shape:", "iconBadge,"); -export const RadioGroup = findComponentByCodeLazy("radioItemIconClassName,"); +export const RadioGroup = findComponentByCodeLazy("\"label\",\"description\"]);"); export const QuestTile = findComponentByCodeLazy(".rowIndex,trackGuildAndChannelMetadata"); export enum QuestStatus { diff --git a/src/equicordplugins/randomVoice/index.tsx b/src/equicordplugins/randomVoice/index.tsx index 7d82d9a37..f0d2432a6 100644 --- a/src/equicordplugins/randomVoice/index.tsx +++ b/src/equicordplugins/randomVoice/index.tsx @@ -10,7 +10,7 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { debounce } from "@shared/debounce"; import { Devs, EquicordDevs } from "@utils/constants"; import definePlugin, { makeRange, OptionType } from "@utils/types"; -import { findByCode, findByProps, findByPropsLazy, findComponentByCodeLazy } from "@webpack"; +import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy } from "@webpack"; import { ChannelRouter, ChannelStore, ContextMenuApi, GuildStore, MediaEngineStore, Menu, PermissionsBits, PermissionStore, React, SelectedChannelStore, Toasts, UserStore, VoiceActions, VoiceStateStore } from "@webpack/common"; import style from "./styles.css?managed"; @@ -18,6 +18,8 @@ import style from "./styles.css?managed"; const ChatVoiceIcon = findComponentByCodeLazy("0l1.8-1.8c.17"); const Button = findComponentByCodeLazy(".NONE,disabled:", ".PANEL_BUTTON"); const ChannelActions = findByPropsLazy("selectChannel", "selectVoiceChannel"); +const startStream = findByCodeLazy('type:"STREAM_START"'); +const getDesktopSources = findByCodeLazy("desktop sources"); const valueOperation = [ { label: "More than", value: "<", default: false }, @@ -770,9 +772,7 @@ function JoinVc(channelID) { } async function autoStream() { - const startStream = findByCode('type:"STREAM_START"'); - const mediaEngine = findByProps("getMediaEngine").getMediaEngine(); - const getDesktopSources = findByCode("desktop sources"); + const mediaEngine = MediaEngineStore.getMediaEngine(); const selected = SelectedChannelStore.getVoiceChannelId(); if (!selected) return; const channel = ChannelStore.getChannel(selected); diff --git a/src/equicordplugins/toneIndicators/ToneIndicator.tsx b/src/equicordplugins/toneIndicators/ToneIndicator.tsx new file mode 100644 index 000000000..99d5a4ed0 --- /dev/null +++ b/src/equicordplugins/toneIndicators/ToneIndicator.tsx @@ -0,0 +1,34 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2025 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Tooltip } from "@webpack/common"; +import type { ReactElement } from "react"; + +export interface ToneIndicatorProps { + indicator: string; + desc: string; +} + +export default function ToneIndicator({ + indicator, + desc, +}: ToneIndicatorProps): ReactElement { + return ( + + {tooltipProps => ( + + /{indicator} + + )} + + ); +} diff --git a/src/equicordplugins/toneIndicators/index.tsx b/src/equicordplugins/toneIndicators/index.tsx new file mode 100644 index 000000000..b70bc0d4a --- /dev/null +++ b/src/equicordplugins/toneIndicators/index.tsx @@ -0,0 +1,142 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2025 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { definePluginSettings } from "@api/Settings"; +import { EquicordDevs } from "@utils/constants"; +import definePlugin, { OptionType } from "@utils/types"; +import { React } from "@webpack/common"; +import { type ReactNode } from "react"; + +import indicatorsDefault from "./indicators"; +import ToneIndicator from "./ToneIndicator"; + +const settings = definePluginSettings({ + customIndicators: { + type: OptionType.STRING, + description: "Custom tone indicators (format: jk=Joking; srs=Serious)", + default: "", + }, + maxIndicators: { + type: OptionType.NUMBER, + description: "Maximum number of tone indicators to show per message", + default: 5, + }, +}); + +function getCustomIndicators(): Record { + const raw = settings.store.customIndicators || ""; + const result: Record = {}; + + raw.split("; ").forEach(entry => { + const [key, ...rest] = entry.split("="); + if (key && rest.length > 0) { + result[key.trim().toLowerCase()] = rest.join("=").trim(); + } + }); + + return result; +} + +function getIndicator(text: string): string | null { + text = text.toLowerCase(); + const customIndicators = getCustomIndicators(); + + return ( + customIndicators[text] || + customIndicators[`_${text}`] || + indicatorsDefault.get(text) || + indicatorsDefault.get(`_${text}`) || + null + ); +} + +function splitTextWithIndicators(text: string): ReactNode[] { + const nodes: ReactNode[] = []; + let lastIndex = 0; + let count = 0; + const regex = /\/([a-z]{1,20})(?=\s|$|[^\w])/gi; + let match: RegExpExecArray | null; + + while ((match = regex.exec(text)) && count < settings.store.maxIndicators) { + const indicator = match[1]; + const desc = getIndicator(indicator); + if (!desc) continue; + + if (match.index > lastIndex) { + nodes.push(text.slice(lastIndex, match.index)); + } + + nodes.push( + , + ); + + lastIndex = regex.lastIndex; + count++; + } + + if (lastIndex < text.length) nodes.push(text.slice(lastIndex)); + + return nodes; +} + +function patchChildrenTree(children: any): any { + const transform = (node: any): any => { + if (node == null) return node; + + if (typeof node === "string") { + if (!/\/[a-z]+/i.test(node)) return node; + const parts = splitTextWithIndicators(node); + return parts.length === 1 ? parts[0] : parts; + } + + if (node?.props?.children != null) { + const c = node.props.children; + if (Array.isArray(c)) { + node.props.children = c.map(transform).flat(); + } else { + node.props.children = transform(c); + } + return node; + } + + return node; + }; + + if (Array.isArray(children)) return children.map(transform).flat(); + return transform(children); +} + +export default definePlugin({ + name: "ToneIndicators", + description: "Show tooltips for tone indicators like /srs, /gen, etc. in sent messages.", + authors: [EquicordDevs.justjxke], + settings, + + patches: [ + { + find: '["strong","em","u","text","inlineCode","s","spoiler"]', + replacement: [ + { + match: /(?=return\{hasSpoilerEmbeds:\i,content:(\i)\})/, + replace: (_: any, content: string) => + `${content}=$self.patchToneIndicators(${content});`, + }, + ], + }, + ], + + patchToneIndicators(content: any): any { + try { + return patchChildrenTree(content); + } catch { + return content; + } + }, +}); diff --git a/src/equicordplugins/toneIndicators/indicators.ts b/src/equicordplugins/toneIndicators/indicators.ts new file mode 100644 index 000000000..e03a45015 --- /dev/null +++ b/src/equicordplugins/toneIndicators/indicators.ts @@ -0,0 +1,62 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2025 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +const defaultIndicators = new Map( + Object.entries({ + j: "Joking", + hj: "Half Joking", + s: "Sarcastic", + _sarc: "Sarcastic", // Alias for s + gen: "Genuine", + _g: "Genuine", // Alias for gen, + genq: "Genuine Question", + _gq: "Genuine Question", // Alias for genq + srs: "Serious", + nsrs: "Non-Serious", + pos: "Positive Connotation", + _pc: "Positive Connotation", // Alias for pos + neu: "Neutral Connotation", + neg: "Negative Connotation", + _nc: "Negative Connotation", // Alias for neg + p: "Platonic", + r: "Romantic", + a: "Alterous", + c: "Copypasta", + l: "Lyrics", + _ly: "Lyrics", // Alias for l + lh: "Light-Hearted", + nm: "Not Mad", + lu: "A Little Upset", + nbh: "Not Directed At Anybody Here", + nay: "Not Directed At You", + ay: "Directed At You", + nsb: "Not Subtweeting", + x: "Sexual Intent", + _sx: "Sexual Intent", // Alias for x + nx: "Non-Sexual Intent", + _nsx: "Non-Sexual Intent", // Alias for nx + rh: "Rhetorical Question", + _rt: "Rhetorical Question", // Alias for rh + t: "Teasing", + ij: "Inside Joke", + m: "Metaphorically", + li: "Literally", + hyp: "Hyperbole", + ex: "Exaggeration", + f: "Fake", + q: "Quote", + th: "Threat", + cb: "Clickbait", + ref: "Reference", + nf: "Not Forced", + nbr: "Not Being Rude", + ot: "Off-Topic", + nj: "Not Joking", + naj: "Not A Joke", + }), +); + +export default defaultIndicators; diff --git a/src/plugins/_api/badges/index.tsx b/src/plugins/_api/badges/index.tsx index f4f407b7d..4423b69a3 100644 --- a/src/plugins/_api/badges/index.tsx +++ b/src/plugins/_api/badges/index.tsx @@ -142,10 +142,10 @@ export default definePlugin({ ] }, { - find: "profileCardUsernameRow,children", + find: "profileCardUsernameRow,children:", replacement: { - match: /(?<=accountProfileCard.{0,50}displayProfile:(\i).*?badges:)(\i)/, - replace: "[...$self.getBadges($1),...$2]" + match: /badges:(\i)(?<=displayProfile:(\i).+?)/, + replace: "badges:[...$self.getBadges($2),...$1]" } } ], diff --git a/src/plugins/fakeNitro/index.tsx b/src/plugins/fakeNitro/index.tsx index 707cfc1fb..05d74b3b3 100644 --- a/src/plugins/fakeNitro/index.tsx +++ b/src/plugins/fakeNitro/index.tsx @@ -284,6 +284,8 @@ export default definePlugin({ // Allow users to use custom client themes { find: "customUserThemeSettings:{", + // Discord has two separate modules for treatments 1 and 2 + all: true, replacement: { match: /(?<=\i=)\(0,\i\.\i\)\(\i\.\i\.TIER_2\)(?=,|;)/g, replace: "true" diff --git a/src/plugins/messageLogger/messageLogger.css b/src/plugins/messageLogger/messageLogger.css index 501544069..11fb684f6 100644 --- a/src/plugins/messageLogger/messageLogger.css +++ b/src/plugins/messageLogger/messageLogger.css @@ -2,7 +2,7 @@ display: none; } -.messagelogger-deleted:is(.messagelogger-deleted-attachment, +.messagelogger-deleted :is(.messagelogger-deleted-attachment, .emoji, [data-type="sticker"], [class*="embedIframe"], @@ -95,4 +95,4 @@ .messagelogger-diff-disabled .messagelogger-diff-removed [class*="emojiContainer"]::after, .messagelogger-diff-disabled .messagelogger-diff-removed img.emoji::after { display: none !important; -} \ No newline at end of file +} diff --git a/src/plugins/noBlockedMessages/index.ts b/src/plugins/noBlockedMessages/index.ts index bc5a39d0b..62512e75f 100644 --- a/src/plugins/noBlockedMessages/index.ts +++ b/src/plugins/noBlockedMessages/index.ts @@ -17,119 +17,184 @@ */ import { definePluginSettings, migratePluginSetting } from "@api/Settings"; -import { Devs } from "@utils/constants"; -import { runtimeHashMessageKey } from "@utils/intlHash"; +import { Devs, EquicordDevs } from "@utils/constants"; import { Logger } from "@utils/Logger"; import definePlugin, { OptionType } from "@utils/types"; import { Message } from "@vencord/discord-types"; -import { i18n, MessageStore, RelationshipStore } from "@webpack/common"; +import { MessageStore, RelationshipStore } from "@webpack/common"; -interface MessageDeleteProps { - // Internal intl message for BLOCKED_MESSAGE_COUNT - collapsedReason: () => any; +interface ChannelStreamDividerProps { + type: "DIVIDER", + content?: string, + contentKey?: string, + unreadId?: string, } -// Remove this migration once enough time has passed -migratePluginSetting("NoBlockedMessages", "ignoreMessages", "ignoreBlockedMessages"); +interface ChannelStreamMessageProps { + type: "MESSAGE", + content: Message, +} + +interface ChannelStreamGroupProps { + type: "MESSAGE_GROUP_BLOCKED" | "MESSAGE_GROUP_IGNORED", + content: ChannelStreamMessageProps[] | any, +} + +migratePluginSetting("NoBlockedMessages", "disableNotifications", "ignoreMessages"); +migratePluginSetting("NoBlockedMessages", "alsoHideIgnoredUsers", "applyToIgnoredUsers"); + const settings = definePluginSettings({ - ignoreMessages: { - description: "Completely ignores incoming messages from blocked and ignored (if enabled) users", + alsoHideIgnoredUsers: { + description: "Also hide messages from ignored users.", + type: OptionType.BOOLEAN, + default: true, + restartNeeded: false + }, + disableNotifications: { + description: "Hide new message notifications for blocked/ignored users. Always true if \"Default Hide Users\" is enabled below and the user triggering the notification is not exempted in \"Override Users\".", type: OptionType.BOOLEAN, default: false, - restartNeeded: true + restartNeeded: false }, - hideRepliesToBlockedMessages: { - description: "Hides replies to blocked messages.", + hideBlockedUserReplies: { + description: "Hide replies to blocked/ignored users.", type: OptionType.BOOLEAN, default: false, restartNeeded: false, }, - applyToIgnoredUsers: { - description: "Additionally apply to 'ignored' users", + defaultHideUsers: { type: OptionType.BOOLEAN, + description: "If enabled, messages from blocked/ignored users will be completely hidden and any messages from user IDs in the override list will be collapsed (default Discord behavior) instead. If disabled, messages from blocked/ignored users will be collapsed and any messages from user IDs in the override list will be completely hidden instead.", default: true, - restartNeeded: false - } + restartNeeded: false, + }, + overrideUsers: { + type: OptionType.STRING, + description: "Comma separated list of user IDs which will be hidden or collapsed instead of the default behavior selected above.", + restartNeeded: false, + default: "" + }, }); export default definePlugin({ name: "NoBlockedMessages", - description: "Hides all blocked/ignored messages from chat completely", - authors: [Devs.rushii, Devs.Samu, Devs.jamesbt365], + description: "Hide all blocked/ignored messages from chat completely.", + authors: [Devs.rushii, Devs.Samu, Devs.jamesbt365, Devs.Elvyra, EquicordDevs.Etorix], settings, - patches: [ - { - find: ".__invalid_blocked,", - replacement: [ - { - match: /let{expanded:\i,[^}]*?collapsedReason[^}]*}/, - replace: "if($self.shouldHide(arguments[0]))return null;$&" - } - ] - }, ...[ '"MessageStore"', '"ReadStateStore"' ].map(find => ({ find, - predicate: () => settings.store.ignoreMessages, replacement: [ { match: /(?<=function (\i)\((\i)\){)(?=.*MESSAGE_CREATE:\1)/, - replace: (_, _funcName, props) => `if($self.shouldIgnoreMessage(${props}.message)||$self.isReplyToBlocked(${props}.message))return;` + replace: (_, _funcName, props) => `if($self.disableNotification(${props}.message)){return;};` } ] })), { - find: "referencedUsernameProfile,referencedAvatarProfile", + find: '"forum-post-action-bar-"', replacement: [ { - match: /(?=\(0,\i.jsx\)\(\i.\i,\{offset)/, - replace: "$&!$self.isReplyToBlocked(arguments[0].message)&&", + match: /(\i).map\(/, + replace: "$self.filterStream($1).map(" } - ], + ] }, ], - shouldIgnoreMessage(message: Message) { + hideBlockedMessage(userId: string) { + const overrideUsers = settings.store.overrideUsers.split(",").map(id => id.trim()).filter(id => id.length > 0); + + if (settings.store.defaultHideUsers) { + // If hidden by default, overriding shows messages as collapsed. + return overrideUsers.includes(userId); + } else { + // If collapsed by default, overriding hides messages. + return !overrideUsers.includes(userId); + } + }, + + shouldKeepMessage(message: Message) { + const blocked = this.isBlocked(message); + const replyToBlocked = this.isReplyToBlocked(message); + + if (blocked) return [this.hideBlockedMessage(message.author.id), true]; + if (replyToBlocked) return [this.hideBlockedMessage(replyToBlocked.author.id), true]; + + // [Message Visible, Author Blocked/Ignored] + return [true, false]; + }, + + disableNotification(message: Message) { + if (!message) return false; + const messageFilteredData = this.shouldKeepMessage(message); + const messageHidden = !messageFilteredData[0]; + const messageBlocked = messageFilteredData[1]; + // Always disable notifications for completely hidden messages as not doing so will + // cause the client to scroll up into the loaded messages in search of an + // unread message which it can't find because it was filtered. + return messageHidden || (messageBlocked && settings.store.disableNotifications); + }, + + filterStream(channelStream: [ChannelStreamGroupProps | ChannelStreamMessageProps | ChannelStreamDividerProps]) { + const { alsoHideIgnoredUsers, disableNotifications, hideBlockedUserReplies, defaultHideUsers, overrideUsers } = settings.use(); + + const newChannelStream = channelStream.map(item => { + if (item.type === "MESSAGE_GROUP_BLOCKED" || (item.type === "MESSAGE_GROUP_IGNORED" && alsoHideIgnoredUsers)) { + const groupItem = item as ChannelStreamGroupProps; + + const filteredContent = groupItem.content.filter((item: ChannelStreamMessageProps) => { + return item.type !== "MESSAGE" || this.shouldKeepMessage(item.content)[0]; + }); + + return filteredContent.some(item => item.type === "MESSAGE") ? { ...groupItem, content: filteredContent } : null; + } + + return (item.type !== "MESSAGE" || this.shouldKeepMessage((item as ChannelStreamMessageProps).content)[0]) ? item : null; + }).filter(item => item !== null); + + let lastItem = newChannelStream[newChannelStream.length - 1]; + + // Remove the NEW Message divider if it is the last item, + // implying the messages it was announcing got filtered. + while (lastItem && lastItem.type === "DIVIDER" && lastItem.unreadId !== undefined) { + newChannelStream.pop(); + lastItem = newChannelStream[newChannelStream.length - 1]; + } + + return newChannelStream; + }, + + isReplyToBlocked(message: Message) { + if (!settings.store.hideBlockedUserReplies) return false; + + try { + // Messages received from the non-focused channel may have a referenced_message property. + let repliedMessage: Message | null = (message as any).referenced_message || null; + + if (!repliedMessage) { + const messageReference = message.messageReference || (message as any).message_reference; + repliedMessage = messageReference ? MessageStore.getMessage(messageReference.channel_id, messageReference.message_id) : null; + } + + return repliedMessage && this.isBlocked(repliedMessage) ? repliedMessage : false; + } catch (e) { + new Logger("NoBlockedMessages").error("Failed to check if referenced message is blocked or ignored:", e); + } + }, + + isBlocked(message: Message) { try { if (RelationshipStore.isBlocked(message.author.id)) { return true; } - return settings.store.applyToIgnoredUsers && RelationshipStore.isIgnored(message.author.id); + + return settings.store.alsoHideIgnoredUsers && RelationshipStore.isIgnored(message.author.id); } catch (e) { - new Logger("NoBlockedMessages").error("Failed to check if user is blocked or ignored:", e); - return false; + new Logger("NoBlockedMessages").error("Failed to check if message is blocked or ignored:", e); } }, - - shouldHide(props: MessageDeleteProps): boolean { - try { - const collapsedReason = props.collapsedReason(); - const blockedReason = i18n.t[runtimeHashMessageKey("BLOCKED_MESSAGE_COUNT")](); - const ignoredReason = settings.store.applyToIgnoredUsers - ? i18n.t[runtimeHashMessageKey("IGNORED_MESSAGE_COUNT")]() - : null; - - return collapsedReason === blockedReason || collapsedReason === ignoredReason; - } catch (e) { - console.error(e); - return false; - } - }, - - isReplyToBlocked(message: Message) { - if (!settings.store.hideRepliesToBlockedMessages) return false; - try { - const { messageReference } = message; - if (!messageReference) return false; - - const replyMessage = MessageStore.getMessage(messageReference.channel_id, messageReference.message_id); - - return replyMessage ? this.shouldIgnoreMessage(replyMessage) : false; - } catch (e) { - new Logger("NoBlockedMessages").error("Failed to check if referenced message is blocked:", e); - } - } }); diff --git a/src/plugins/pinDms/index.tsx b/src/plugins/pinDms/index.tsx index bf4f5252c..0cba4e332 100644 --- a/src/plugins/pinDms/index.tsx +++ b/src/plugins/pinDms/index.tsx @@ -64,7 +64,7 @@ export const settings = definePluginSettings({ }, disableCreateDMButton: { type: OptionType.BOOLEAN, - description: "Disabled the create dm button", + description: "Disables the create dm button", default: true } }); @@ -160,9 +160,9 @@ export default definePlugin({ } }, { - find: ".createDMButtonContainer", + find: ".createDMButtonContainer,", replacement: { - match: /"full-width"===\i/, + match: /"create-dm"\)/, replace: "$&&&false" }, predicate: () => settings.store.disableCreateDMButton diff --git a/src/plugins/typingTweaks/index.tsx b/src/plugins/typingTweaks/index.tsx index 1c9bae563..7e3342ce6 100644 --- a/src/plugins/typingTweaks/index.tsx +++ b/src/plugins/typingTweaks/index.tsx @@ -153,7 +153,11 @@ export default definePlugin({ const myId = useStateFromStores([AuthenticationStore], () => AuthenticationStore.getId()); return Object.keys(typingUsers) - .filter(id => id && id !== myId && !RelationshipStore.isBlockedOrIgnored(id)) + .filter(id => { + if (!id || RelationshipStore.isBlockedOrIgnored(id)) return false; + if (id === myId) return Settings.plugins.AmITyping?.enabled; + return true; + }) .map(id => UserStore.getUser(id)) .filter(isNonNullish); } catch (e) { diff --git a/src/utils/cloud.tsx b/src/utils/cloud.tsx index 6e0c49f7f..8895e419b 100644 --- a/src/utils/cloud.tsx +++ b/src/utils/cloud.tsx @@ -19,41 +19,16 @@ import * as DataStore from "@api/DataStore"; import { showNotification } from "@api/Notifications"; import { Settings } from "@api/Settings"; -import { Alerts, OAuth2AuthorizeModal, UserStore } from "@webpack/common"; +import { OAuth2AuthorizeModal, UserStore } from "@webpack/common"; import { Logger } from "./Logger"; import { openModal } from "./modal"; -import { relaunch } from "./native"; export const cloudLogger = new Logger("Cloud", "#39b7e0"); export const getCloudUrl = () => new URL(Settings.cloud.url); const getCloudUrlOrigin = () => getCloudUrl().origin; -export async function checkCloudUrlCsp() { - if (IS_WEB) return true; - - const { host } = getCloudUrl(); - if (host === "api.vencord.dev") return true; - if (host === "cloud.equicord.org") return true; - - if (await VencordNative.csp.isDomainAllowed(Settings.cloud.url, ["connect-src"])) { - return true; - } - - const res = await VencordNative.csp.requestAddOverride(Settings.cloud.url, ["connect-src"], "Cloud Sync"); - if (res === "ok") { - Alerts.show({ - title: "Cloud Integration enabled", - body: `${host} has been added to the whitelist. Please restart the app for the changes to take effect.`, - confirmText: "Restart now", - cancelText: "Later!", - onConfirm: relaunch - }); - } - return false; -} - const getUserId = () => { const id = UserStore.getCurrentUser()?.id; if (!id) throw new Error("User not yet logged in"); @@ -104,8 +79,6 @@ export async function authorizeCloud() { return; } - if (!await checkCloudUrlCsp()) return; - try { const oauthConfiguration = await fetch(new URL("/v1/oauth/settings", getCloudUrl())); var { clientId, redirectUri } = await oauthConfiguration.json(); diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 81425d7d1..bfb5a4bc3 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1145,6 +1145,10 @@ export const EquicordDevs = Object.freeze({ name: "Mocha", id: 808802000224518264n }, + justjxke: { + name: "justjxke", + id: 852558183087472640n + } } satisfies Record); // iife so #__PURE__ works correctly diff --git a/src/utils/settingsSync.ts b/src/utils/settingsSync.ts index f21fe050e..19900d833 100644 --- a/src/utils/settingsSync.ts +++ b/src/utils/settingsSync.ts @@ -22,7 +22,7 @@ import { PlainSettings, Settings } from "@api/Settings"; import { moment, SettingsRouter, Toasts } from "@webpack/common"; import { deflateSync, inflateSync } from "fflate"; -import { checkCloudUrlCsp, getCloudAuth, getCloudUrl } from "./cloud"; +import { getCloudAuth, getCloudUrl } from "./cloud"; import { Logger } from "./Logger"; import { relaunch } from "./native"; import { chooseFile, saveFile } from "./web"; @@ -118,8 +118,6 @@ const cloudSettingsLogger = new Logger("Cloud:Settings", "#39b7e0"); export async function putCloudSettings(manual?: boolean) { const settings = await exportSettings({ minify: true }); - if (!await checkCloudUrlCsp()) return; - try { const res = await fetch(new URL("/v1/settings", getCloudUrl()), { method: "PUT", @@ -164,8 +162,6 @@ export async function putCloudSettings(manual?: boolean) { } export async function getCloudSettings(shouldNotify = true, force = false) { - if (!await checkCloudUrlCsp()) return; - try { const res = await fetch(new URL("/v1/settings", getCloudUrl()), { method: "GET", @@ -268,8 +264,6 @@ export async function getCloudSettings(shouldNotify = true, force = false) { } export async function deleteCloudSettings() { - if (!await checkCloudUrlCsp()) return; - try { const res = await fetch(new URL("/v1/settings", getCloudUrl()), { method: "DELETE",