1
0
mirror of https://gitcode.com/github-mirrors/react-native-update-cli.git synced 2025-09-17 18:06:10 +08:00
Code Issues Packages Projects Releases Wiki Activity GitHub Gitee

Compare commits

..

3 Commits

Author SHA1 Message Date
sunnylqm
fbad603d05 sort key 2025-03-14 13:42:09 +08:00
sunnylqm
a1231f6a73 add deps 2025-03-14 13:42:09 +08:00
sunnylqm
f32b201778 init 2025-03-14 13:42:09 +08:00
28 changed files with 729 additions and 2171 deletions

View File

@@ -12,8 +12,7 @@
"noDoubleEquals": "off"
},
"style": {
"noNonNullAssertion": "off",
"useNodejsImportProtocol": "off"
"noNonNullAssertion": "off"
},
"a11y": {
"useValidAnchor": "off"

400
bun.lock
View File

@@ -3,57 +3,55 @@
"workspaces": {
"": {
"dependencies": {
"@colors/colors": "^1.6.0",
"@badisi/latest-version": "^7.0.10",
"bplist-parser": "^0.3.2",
"bytebuffer": "^5.0.1",
"cgbi-to-png": "^1.0.7",
"chalk": "4",
"cli-arguments": "^0.2.1",
"commander": "^13",
"commander": "^12.1.0",
"compare-versions": "^6.1.1",
"filesize-parser": "^1.5.1",
"form-data": "^4.0.2",
"form-data": "^4.0.1",
"fs-extra": "8",
"global-dirs": "^4.0.0",
"gradle-to-js": "^2.0.1",
"i18next": "^24.2.3",
"isomorphic-git": "^1.30.1",
"i18next": "^24.2.2",
"isomorphic-git": "^1.29.0",
"isomorphic-unzip": "^1.1.5",
"node-fetch": "^2.6.1",
"plist": "^3.1.0",
"progress": "^2.0.3",
"properties": "^1.2.1",
"read": "^4.1.0",
"registry-auth-token": "^5.1.0",
"semver": "^7.7.2",
"read": "^4.0.0",
"semver": "^7.6.3",
"tcp-ping": "^0.1.1",
"tty-table": "4.2",
"update-notifier": "^5.1.0",
"yauzl": "^3.2.0",
"yazl": "3.3.1",
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@swc/cli": "0.7.7",
"@swc/core": "^1.11.24",
"@swc/cli": "^0.5.1",
"@swc/core": "^1.9.3",
"@types/filesize-parser": "^1.5.3",
"@types/fs-extra": "^11.0.4",
"@types/node": "^22.15.18",
"@types/node": "^22.9.3",
"@types/node-fetch": "^2.6.12",
"@types/progress": "^2.0.7",
"@types/semver": "^7.7.0",
"@types/semver": "^7.5.8",
"@types/tcp-ping": "^0.1.6",
"@types/update-notifier": "^6.0.8",
"@types/yauzl": "^2.10.3",
"@types/yazl": "^2.4.6",
"typescript": "^5.8.3",
"typescript": "^5.7.2",
},
},
},
"trustedDependencies": [
"@biomejs/biome",
"@swc/core",
],
"packages": {
"@babel/runtime": ["@babel/runtime@7.26.10", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw=="],
"@babel/runtime": ["@babel/runtime@7.26.9", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg=="],
"@badisi/latest-version": ["@badisi/latest-version@7.0.10", "", { "dependencies": { "@colors/colors": "^1.6.0", "global-dirs": "3.0.1", "ora": "^8.1.0", "registry-auth-token": "^5.0.2", "semver": "^7.6.3" }, "bin": { "latest-version": "bin/latest-version", "lv": "bin/latest-version" } }, "sha512-1lX9wvXiJC552C+rrwwjEbpvvuDwYTU3OLFwFA1pTVYTnJGUkbBkfqz1MuTIPP1fL2LCvjd21ri/u39sSIcMTg=="],
"@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="],
@@ -125,38 +123,40 @@
"@sindresorhus/is": ["@sindresorhus/is@5.6.0", "", {}, "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g=="],
"@swc/cli": ["@swc/cli@0.7.7", "", { "dependencies": { "@swc/counter": "^0.1.3", "@xhmikosr/bin-wrapper": "^13.0.5", "commander": "^8.3.0", "fast-glob": "^3.2.5", "minimatch": "^9.0.3", "piscina": "^4.3.1", "semver": "^7.3.8", "slash": "3.0.0", "source-map": "^0.7.3" }, "peerDependencies": { "@swc/core": "^1.2.66", "chokidar": "^4.0.1" }, "optionalPeers": ["chokidar"], "bin": { "swc": "bin/swc.js", "swcx": "bin/swcx.js", "spack": "bin/spack.js" } }, "sha512-j4yYm9bx3pxWofaJKX1BFwj/3ngUDynN4UIQ2Xd2h0h/7Gt7zkReBTpDN7g5S13mgAYxacaTHTOUsz18097E8w=="],
"@swc/cli": ["@swc/cli@0.5.1", "", { "dependencies": { "@swc/counter": "^0.1.3", "@xhmikosr/bin-wrapper": "^13.0.5", "commander": "^8.3.0", "fast-glob": "^3.2.5", "minimatch": "^9.0.3", "piscina": "^4.3.0", "semver": "^7.3.8", "slash": "3.0.0", "source-map": "^0.7.3" }, "peerDependencies": { "@swc/core": "^1.2.66", "chokidar": "^3.5.1" }, "optionalPeers": ["chokidar"], "bin": { "swc": "bin/swc.js", "swcx": "bin/swcx.js", "spack": "bin/spack.js" } }, "sha512-sxSXyjqFImYrqjhZSPymjmM/9V6auZG67UsDwbe7FZaBlyfW8ka3QG/zRjpJJ9+8Ahns/kKb8bXPKQq7V2MtBw=="],
"@swc/core": ["@swc/core@1.11.24", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.21" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.24", "@swc/core-darwin-x64": "1.11.24", "@swc/core-linux-arm-gnueabihf": "1.11.24", "@swc/core-linux-arm64-gnu": "1.11.24", "@swc/core-linux-arm64-musl": "1.11.24", "@swc/core-linux-x64-gnu": "1.11.24", "@swc/core-linux-x64-musl": "1.11.24", "@swc/core-win32-arm64-msvc": "1.11.24", "@swc/core-win32-ia32-msvc": "1.11.24", "@swc/core-win32-x64-msvc": "1.11.24" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-MaQEIpfcEMzx3VWWopbofKJvaraqmL6HbLlw2bFZ7qYqYw3rkhM0cQVEgyzbHtTWwCwPMFZSC2DUbhlZgrMfLg=="],
"@swc/core": ["@swc/core@1.9.3", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.17" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.9.3", "@swc/core-darwin-x64": "1.9.3", "@swc/core-linux-arm-gnueabihf": "1.9.3", "@swc/core-linux-arm64-gnu": "1.9.3", "@swc/core-linux-arm64-musl": "1.9.3", "@swc/core-linux-x64-gnu": "1.9.3", "@swc/core-linux-x64-musl": "1.9.3", "@swc/core-win32-arm64-msvc": "1.9.3", "@swc/core-win32-ia32-msvc": "1.9.3", "@swc/core-win32-x64-msvc": "1.9.3" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-oRj0AFePUhtatX+BscVhnzaAmWjpfAeySpM1TCbxA1rtBDeH/JDhi5yYzAKneDYtVtBvA7ApfeuzhMC9ye4xSg=="],
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.24", "", { "os": "darwin", "cpu": "arm64" }, "sha512-dhtVj0PC1APOF4fl5qT2neGjRLgHAAYfiVP8poJelhzhB/318bO+QCFWAiimcDoyMgpCXOhTp757gnoJJrheWA=="],
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.9.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-hGfl/KTic/QY4tB9DkTbNuxy5cV4IeejpPD4zo+Lzt4iLlDWIeANL4Fkg67FiVceNJboqg48CUX+APhDHO5G1w=="],
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.24", "", { "os": "darwin", "cpu": "x64" }, "sha512-H/3cPs8uxcj2Fe3SoLlofN5JG6Ny5bl8DuZ6Yc2wr7gQFBmyBkbZEz+sPVgsID7IXuz7vTP95kMm1VL74SO5AQ=="],
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.9.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-IaRq05ZLdtgF5h9CzlcgaNHyg4VXuiStnOFpfNEMuI5fm5afP2S0FHq8WdakUz5WppsbddTdplL+vpeApt/WCQ=="],
"@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.24", "", { "os": "linux", "cpu": "arm" }, "sha512-PHJgWEpCsLo/NGj+A2lXZ2mgGjsr96ULNW3+T3Bj2KTc8XtMUkE8tmY2Da20ItZOvPNC/69KroU7edyo1Flfbw=="],
"@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.9.3", "", { "os": "linux", "cpu": "arm" }, "sha512-Pbwe7xYprj/nEnZrNBvZfjnTxlBIcfApAGdz2EROhjpPj+FBqBa3wOogqbsuGGBdCphf8S+KPprL1z+oDWkmSQ=="],
"@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.24", "", { "os": "linux", "cpu": "arm64" }, "sha512-C2FJb08+n5SD4CYWCTZx1uR88BN41ZieoHvI8A55hfVf2woT8+6ZiBzt74qW2g+ntZ535Jts5VwXAKdu41HpBg=="],
"@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.9.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-AQ5JZiwNGVV/2K2TVulg0mw/3LYfqpjZO6jDPtR2evNbk9Yt57YsVzS+3vHSlUBQDRV9/jqMuZYVU3P13xrk+g=="],
"@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.11.24", "", { "os": "linux", "cpu": "arm64" }, "sha512-ypXLIdszRo0re7PNNaXN0+2lD454G8l9LPK/rbfRXnhLWDBPURxzKlLlU/YGd2zP98wPcVooMmegRSNOKfvErw=="],
"@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.9.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-tzVH480RY6RbMl/QRgh5HK3zn1ZTFsThuxDGo6Iuk1MdwIbdFYUY034heWUTI4u3Db97ArKh0hNL0xhO3+PZdg=="],
"@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.24", "", { "os": "linux", "cpu": "x64" }, "sha512-IM7d+STVZD48zxcgo69L0yYptfhaaE9cMZ+9OoMxirNafhKKXwoZuufol1+alEFKc+Wbwp+aUPe/DeWC/Lh3dg=="],
"@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.9.3", "", { "os": "linux", "cpu": "x64" }, "sha512-ivXXBRDXDc9k4cdv10R21ccBmGebVOwKXT/UdH1PhxUn9m/h8erAWjz5pcELwjiMf27WokqPgaWVfaclDbgE+w=="],
"@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.24", "", { "os": "linux", "cpu": "x64" }, "sha512-DZByJaMVzSfjQKKQn3cqSeqwy6lpMaQDQQ4HPlch9FWtDx/dLcpdIhxssqZXcR2rhaQVIaRQsCqwV6orSDGAGw=="],
"@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.9.3", "", { "os": "linux", "cpu": "x64" }, "sha512-ILsGMgfnOz1HwdDz+ZgEuomIwkP1PHT6maigZxaCIuC6OPEhKE8uYna22uU63XvYcLQvZYDzpR3ms47WQPuNEg=="],
"@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.24", "", { "os": "win32", "cpu": "arm64" }, "sha512-Q64Ytn23y9aVDKN5iryFi8mRgyHw3/kyjTjT4qFCa8AEb5sGUuSj//AUZ6c0J7hQKMHlg9do5Etvoe61V98/JQ=="],
"@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.9.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-e+XmltDVIHieUnNJHtspn6B+PCcFOMYXNJB1GqoCcyinkEIQNwC8KtWgMqUucUbEWJkPc35NHy9k8aCXRmw9Kg=="],
"@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.24", "", { "os": "win32", "cpu": "ia32" }, "sha512-9pKLIisE/Hh2vJhGIPvSoTK4uBSPxNVyXHmOrtdDot4E1FUUI74Vi8tFdlwNbaj8/vusVnb8xPXsxF1uB0VgiQ=="],
"@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.9.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-rqpzNfpAooSL4UfQnHhkW8aL+oyjqJniDP0qwZfGnjDoJSbtPysHg2LpcOBEdSnEH+uIZq6J96qf0ZFD8AGfXA=="],
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.24", "", { "os": "win32", "cpu": "x64" }, "sha512-sybnXtOsdB+XvzVFlBVGgRHLqp3yRpHK7CrmpuDKszhj/QhmsaZzY/GHSeALlMtLup13M0gqbcQvsTNlAHTg3w=="],
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.9.3", "", { "os": "win32", "cpu": "x64" }, "sha512-3YJJLQ5suIEHEKc1GHtqVq475guiyqisKSoUnoaRtxkDaW5g1yvPt9IoSLOe2mRs7+FFhGGU693RsBUSwOXSdQ=="],
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
"@swc/types": ["@swc/types@0.1.21", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ=="],
"@swc/types": ["@swc/types@0.1.17", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ=="],
"@szmarczak/http-timer": ["@szmarczak/http-timer@5.0.1", "", { "dependencies": { "defer-to-connect": "^2.0.1" } }, "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw=="],
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
"@types/configstore": ["@types/configstore@6.0.2", "", {}, "sha512-OS//b51j9uyR3zvwD04Kfs5kHpve2qalQ18JhY/ho3voGYUTPLEG90/ocfKPI48hyHH8T04f7KEEbK6Ue60oZQ=="],
"@types/filesize-parser": ["@types/filesize-parser@1.5.3", "", {}, "sha512-D8veS92mQAfcKz5kbV9WINfKvvaxVfQHqnO3OWW6FxdYTZozDDb8mTLWCsvEqe8M/M7skeULTZzYeMf3Lsss+A=="],
"@types/fs-extra": ["@types/fs-extra@11.0.4", "", { "dependencies": { "@types/jsonfile": "*", "@types/node": "*" } }, "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ=="],
@@ -165,16 +165,18 @@
"@types/jsonfile": ["@types/jsonfile@6.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ=="],
"@types/node": ["@types/node@22.15.18", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg=="],
"@types/node": ["@types/node@22.9.3", "", { "dependencies": { "undici-types": "~6.19.8" } }, "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw=="],
"@types/node-fetch": ["@types/node-fetch@2.6.12", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA=="],
"@types/progress": ["@types/progress@2.0.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-iadjw02vte8qWx7U0YM++EybBha2CQLPGu9iJ97whVgJUT5Zq9MjAPYUnbfRI2Kpehimf1QjFJYxD0t8nqzu5w=="],
"@types/semver": ["@types/semver@7.7.0", "", {}, "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA=="],
"@types/semver": ["@types/semver@7.5.8", "", {}, "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ=="],
"@types/tcp-ping": ["@types/tcp-ping@0.1.6", "", {}, "sha512-1TTOm3cK+0NrZ6uTlY51YERzo5tEW3RybX1594vy9oiZOc1vsVL4LmdiIklDJXYLlzmve5lBkM5GjvwBG1Bc4A=="],
"@types/update-notifier": ["@types/update-notifier@6.0.8", "", { "dependencies": { "@types/configstore": "*", "boxen": "^7.1.1" } }, "sha512-IlDFnfSVfYQD+cKIg63DEXn3RFmd7W1iYtKQsJodcHK9R1yr8aKbKaPKfBxzPpcHCq2DU8zUq4PIPmy19Thjfg=="],
"@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="],
"@types/yazl": ["@types/yazl@2.4.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-/ifFjQtcKaoZOjl5NNCQRR0fAKafB3Foxd7J/WvFPTMea46zekapcR30uzkwIkKAAuq5T6d0dkwz754RFH27hg=="],
@@ -201,6 +203,8 @@
"@xmldom/xmldom": ["@xmldom/xmldom@0.8.10", "", {}, "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="],
"ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
@@ -233,6 +237,8 @@
"bin-version-check": ["bin-version-check@5.1.0", "", { "dependencies": { "bin-version": "^6.0.0", "semver": "^7.5.3", "semver-truncate": "^3.0.0" } }, "sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g=="],
"boxen": ["boxen@7.1.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^7.0.1", "chalk": "^5.2.0", "cli-boxes": "^3.0.0", "string-width": "^5.1.2", "type-fest": "^2.13.0", "widest-line": "^4.0.1", "wrap-ansi": "^8.1.0" } }, "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog=="],
"bplist-parser": ["bplist-parser@0.3.2", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ=="],
"brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
@@ -255,34 +261,44 @@
"call-bind": ["call-bind@1.0.7", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.1" } }, "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
"camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="],
"camelcase": ["camelcase@7.0.1", "", {}, "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw=="],
"cgbi-to-png": ["cgbi-to-png@1.0.7", "", { "dependencies": { "bufferpack": "0.0.6", "crc": "^3.3.0", "stream-to-buffer": "^0.1.0", "streamifier": "^0.1.1" } }, "sha512-YR80kxTPuq9oRpZUdQmNEQWrmTKLINk1cfLVfyrV7Rfr9KLtLJdcockPKbreIr4JYAq+DhHBR7w+WA/tF5VDaQ=="],
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="],
"clean-git-ref": ["clean-git-ref@2.0.1", "", {}, "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw=="],
"cli-arguments": ["cli-arguments@0.2.1", "", {}, "sha512-vaoTjiREjxKlpTNMiaJUkQnYRhgui8r+huhB6mMHcGQyz5F7Hd1o1jsW9C/wRKjlNYQ6fTvODLtZe7DxfEIz8g=="],
"cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
"cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
"cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="],
"cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
"clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="],
"clone-response": ["clone-response@1.0.3", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="],
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
"commander": ["commander@13.1.0", "", {}, "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="],
"commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
"compare-versions": ["compare-versions@6.1.1", "", {}, "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg=="],
"config-chain": ["config-chain@1.1.13", "", { "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="],
"configstore": ["configstore@5.0.1", "", { "dependencies": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", "make-dir": "^3.0.0", "unique-string": "^2.0.0", "write-file-atomic": "^3.0.0", "xdg-basedir": "^4.0.0" } }, "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA=="],
"content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="],
"crc": ["crc@3.8.0", "", { "dependencies": { "buffer": "^5.1.0" } }, "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ=="],
@@ -291,6 +307,8 @@
"cross-spawn": ["cross-spawn@7.0.3", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="],
"crypto-random-string": ["crypto-random-string@2.0.0", "", {}, "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA=="],
"csv": ["csv@5.5.3", "", { "dependencies": { "csv-generate": "^3.4.3", "csv-parse": "^4.16.3", "csv-stringify": "^5.6.5", "stream-transform": "^2.1.3" } }, "sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g=="],
"csv-generate": ["csv-generate@3.4.3", "", {}, "sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw=="],
@@ -309,6 +327,8 @@
"decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="],
"deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
"defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="],
"defer-to-connect": ["defer-to-connect@2.0.1", "", {}, "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="],
@@ -321,19 +341,25 @@
"diff3": ["diff3@0.0.3", "", {}, "sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="],
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"duplexer3": ["duplexer3@0.1.5", "", {}, "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA=="],
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
"end-of-stream": ["end-of-stream@1.4.4", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="],
"es-abstract": ["es-abstract@1.23.3", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", "data-view-buffer": "^1.0.1", "data-view-byte-length": "^1.0.1", "data-view-byte-offset": "^1.0.0", "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", "get-symbol-description": "^1.0.2", "globalthis": "^1.0.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", "hasown": "^2.0.2", "internal-slot": "^1.0.7", "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", "is-data-view": "^1.0.1", "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", "object-inspect": "^1.13.1", "object-keys": "^1.1.1", "object.assign": "^4.1.5", "regexp.prototype.flags": "^1.5.2", "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", "string.prototype.trimend": "^1.0.8", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", "typed-array-byte-offset": "^1.0.2", "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", "which-typed-array": "^1.1.15" } }, "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A=="],
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
"es-define-property": ["es-define-property@1.0.0", "", { "dependencies": { "get-intrinsic": "^1.2.4" } }, "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ=="],
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
"es-object-atoms": ["es-object-atoms@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw=="],
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
"es-set-tostringtag": ["es-set-tostringtag@2.0.3", "", { "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", "hasown": "^2.0.1" } }, "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ=="],
"es-shim-unscopables": ["es-shim-unscopables@1.0.2", "", { "dependencies": { "hasown": "^2.0.0" } }, "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw=="],
@@ -341,6 +367,8 @@
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
"escape-goat": ["escape-goat@2.1.1", "", {}, "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q=="],
"execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
"ext-list": ["ext-list@2.2.2", "", { "dependencies": { "mime-db": "^1.28.0" } }, "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA=="],
@@ -371,7 +399,7 @@
"for-each": ["for-each@0.3.3", "", { "dependencies": { "is-callable": "^1.1.3" } }, "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw=="],
"form-data": ["form-data@4.0.2", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" } }, "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w=="],
"form-data": ["form-data@4.0.1", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw=="],
"form-data-encoder": ["form-data-encoder@2.1.4", "", {}, "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw=="],
@@ -385,9 +413,9 @@
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
"get-east-asian-width": ["get-east-asian-width@1.3.0", "", {}, "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ=="],
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
"get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
@@ -395,11 +423,11 @@
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"global-dirs": ["global-dirs@4.0.0", "", { "dependencies": { "ini": "2.0.0" } }, "sha512-PJ0OjGf/kVuu9gh5IPgAyssfJne5PsU9+ICxfWiRYDUnYq8ob+Y2nSWAEUNEHRj+gowyzI+wg5/nWkvcjcyLwg=="],
"global-dirs": ["global-dirs@3.0.1", "", { "dependencies": { "ini": "2.0.0" } }, "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA=="],
"globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="],
"got": ["got@13.0.0", "", { "dependencies": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", "cacheable-lookup": "^7.0.0", "cacheable-request": "^10.2.8", "decompress-response": "^6.0.0", "form-data-encoder": "^2.1.2", "get-stream": "^6.0.1", "http2-wrapper": "^2.1.10", "lowercase-keys": "^3.0.0", "p-cancelable": "^3.0.0", "responselike": "^3.0.0" } }, "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA=="],
@@ -417,10 +445,12 @@
"has-proto": ["has-proto@1.0.3", "", {}, "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q=="],
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
"has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
"has-yarn": ["has-yarn@2.1.0", "", {}, "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"http-cache-semantics": ["http-cache-semantics@4.1.1", "", {}, "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="],
@@ -429,12 +459,16 @@
"human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
"i18next": ["i18next@24.2.3", "", { "dependencies": { "@babel/runtime": "^7.26.10" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-lfbf80OzkocvX7nmZtu7nSTNbrTYR52sLWxPtlXX1zAhVw8WEnFk4puUkCR4B1dNQwbSpEHHHemcZu//7EcB7A=="],
"i18next": ["i18next@24.2.2", "", { "dependencies": { "@babel/runtime": "^7.23.2" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-NE6i86lBCKRYZa5TaUDkU5S4HFgLIEJRLr3Whf2psgaxBleQ2LC1YW1Vc+SCgkAW7VEzndT6al6+CzegSUHcTQ=="],
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"import-lazy": ["import-lazy@2.1.0", "", {}, "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A=="],
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
"ini": ["ini@2.0.0", "", {}, "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA=="],
@@ -451,6 +485,8 @@
"is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="],
"is-ci": ["is-ci@2.0.0", "", { "dependencies": { "ci-info": "^2.0.0" }, "bin": { "is-ci": "bin.js" } }, "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w=="],
"is-data-view": ["is-data-view@1.0.1", "", { "dependencies": { "is-typed-array": "^1.1.13" } }, "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w=="],
"is-date-object": ["is-date-object@1.0.5", "", { "dependencies": { "has-tostringtag": "^1.0.0" } }, "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ=="],
@@ -461,12 +497,22 @@
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
"is-installed-globally": ["is-installed-globally@0.4.0", "", { "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" } }, "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ=="],
"is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="],
"is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="],
"is-npm": ["is-npm@5.0.0", "", {}, "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA=="],
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-number-object": ["is-number-object@1.0.7", "", { "dependencies": { "has-tostringtag": "^1.0.0" } }, "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ=="],
"is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="],
"is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="],
"is-plain-obj": ["is-plain-obj@1.1.0", "", {}, "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg=="],
"is-regex": ["is-regex@1.1.4", "", { "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" } }, "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg=="],
@@ -481,13 +527,19 @@
"is-typed-array": ["is-typed-array@1.1.13", "", { "dependencies": { "which-typed-array": "^1.1.14" } }, "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw=="],
"is-typedarray": ["is-typedarray@1.0.0", "", {}, "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="],
"is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
"is-weakref": ["is-weakref@1.0.2", "", { "dependencies": { "call-bind": "^1.0.2" } }, "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ=="],
"is-yarn-global": ["is-yarn-global@0.3.0", "", {}, "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw=="],
"isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"isomorphic-git": ["isomorphic-git@1.30.1", "", { "dependencies": { "async-lock": "^1.4.1", "clean-git-ref": "^2.0.1", "crc-32": "^1.2.0", "diff3": "0.0.3", "ignore": "^5.1.4", "minimisted": "^2.0.0", "pako": "^1.0.10", "path-browserify": "^1.0.1", "pify": "^4.0.1", "readable-stream": "^3.4.0", "sha.js": "^2.4.9", "simple-get": "^4.0.1" }, "bin": { "isogit": "cli.cjs" } }, "sha512-eWBlPIPDOctGY/bTUc/whs6EZ8YvnG1H2kOjTCJ/AkvBWUzODXcfulhpiA8Y4Px9e+bRYYkifE5fSE8FcRk8Ew=="],
"isomorphic-git": ["isomorphic-git@1.29.0", "", { "dependencies": { "async-lock": "^1.4.1", "clean-git-ref": "^2.0.1", "crc-32": "^1.2.0", "diff3": "0.0.3", "ignore": "^5.1.4", "minimisted": "^2.0.0", "pako": "^1.0.10", "path-browserify": "^1.0.1", "pify": "^4.0.1", "readable-stream": "^3.4.0", "sha.js": "^2.4.9", "simple-get": "^4.0.1" }, "bin": { "isogit": "cli.cjs" } }, "sha512-zWGqk8901cicvVEhVpN76AwKrS/TzHak2NQCtNXIAavpMIy/yqh+d/JtC9A8AUKZAauUdOyEWKI29tuCLAL+Zg=="],
"isomorphic-unzip": ["isomorphic-unzip@1.1.5", "", { "dependencies": { "buffer": "^5.0.7", "yauzl": "^2.8.0" } }, "sha512-2McA51lWhmO3Kk438jxVcYeh6L+AOqVnl9XdX1yI7GlLA9RwEyTBgGem1rNuRIU2abAmOiv+IagThdUxASY4IA=="],
@@ -501,17 +553,19 @@
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
"latest-version": ["latest-version@5.1.0", "", { "dependencies": { "package-json": "^6.3.0" } }, "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA=="],
"locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
"log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="],
"long": ["long@3.2.0", "", {}, "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg=="],
"lowercase-keys": ["lowercase-keys@3.0.0", "", {}, "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ=="],
"make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
"make-dir": ["make-dir@3.1.0", "", { "dependencies": { "semver": "^6.0.0" } }, "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw=="],
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
@@ -525,6 +579,8 @@
"mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
"mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
"mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="],
"minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
@@ -553,6 +609,8 @@
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
"ora": ["ora@8.1.1", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-YWielGi1XzG1UTvOaCFaNgEnuhZVMSHYkW/FQ7UX8O26PtlpdM84c0f7wLPlkvx2RfiQmnzd61d/MGxmpQeJPw=="],
"p-cancelable": ["p-cancelable@3.0.0", "", {}, "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw=="],
"p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
@@ -561,6 +619,8 @@
"p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="],
"package-json": ["package-json@6.5.0", "", { "dependencies": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", "registry-url": "^5.0.0", "semver": "^6.2.0" } }, "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ=="],
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
"path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="],
@@ -583,19 +643,27 @@
"possible-typed-array-names": ["possible-typed-array-names@1.0.0", "", {}, "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q=="],
"prepend-http": ["prepend-http@2.0.0", "", {}, "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA=="],
"progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="],
"properties": ["properties@1.2.1", "", {}, "sha512-qYNxyMj1JeW54i/EWEFsM1cVwxJbtgPp8+0Wg9XjNaK6VE/c4oRi6PNu5p7w1mNXEIQIjV5Wwn8v8Gz82/QzdQ=="],
"proto-list": ["proto-list@1.2.4", "", {}, "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="],
"pump": ["pump@3.0.2", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw=="],
"pupa": ["pupa@2.1.1", "", { "dependencies": { "escape-goat": "^2.0.0" } }, "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A=="],
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
"queue-tick": ["queue-tick@1.0.1", "", {}, "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="],
"quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="],
"read": ["read@4.1.0", "", { "dependencies": { "mute-stream": "^2.0.0" } }, "sha512-uRfX6K+f+R8OOrYScaM3ixPY4erg69f8DN6pgTvMcA9iRc8iDhwrA4m3Yu8YYKsXJgVvum+m8PkRboZwwuLzYA=="],
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
"read": ["read@4.0.0", "", { "dependencies": { "mute-stream": "^2.0.0" } }, "sha512-nbYGT3cec3J5NPUeJia7l72I3oIzMIB6yeNyDqi8CVHr3WftwjrCUqR0j13daoHEMVaZ/rxCpmHKrbods3hI2g=="],
"readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
@@ -603,7 +671,9 @@
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.3", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "set-function-name": "^2.0.2" } }, "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ=="],
"registry-auth-token": ["registry-auth-token@5.1.0", "", { "dependencies": { "@pnpm/npm-conf": "^2.1.0" } }, "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw=="],
"registry-auth-token": ["registry-auth-token@5.0.2", "", { "dependencies": { "@pnpm/npm-conf": "^2.1.0" } }, "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ=="],
"registry-url": ["registry-url@5.1.0", "", { "dependencies": { "rc": "^1.2.8" } }, "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw=="],
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
@@ -613,6 +683,8 @@
"responselike": ["responselike@3.0.0", "", { "dependencies": { "lowercase-keys": "^3.0.0" } }, "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg=="],
"restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
"reusify": ["reusify@1.0.4", "", {}, "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="],
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
@@ -625,7 +697,9 @@
"seek-bzip": ["seek-bzip@2.0.0", "", { "dependencies": { "commander": "^6.0.0" }, "bin": { "seek-bunzip": "bin/seek-bunzip", "seek-table": "bin/seek-bzip-table" } }, "sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg=="],
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"semver": ["semver@7.6.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="],
"semver-diff": ["semver-diff@3.1.1", "", { "dependencies": { "semver": "^6.3.0" } }, "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg=="],
"semver-regex": ["semver-regex@4.0.5", "", {}, "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw=="],
@@ -661,6 +735,8 @@
"source-map": ["source-map@0.7.4", "", {}, "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="],
"stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
"stream-to": ["stream-to@0.2.2", "", {}, "sha512-Kg1BSDTwgGiVMtTCJNlo7kk/xzL33ZuZveEBRt6rXw+f1WLK/8kmz2NVCT/Qnv0JkV85JOHcLhD82mnXsR3kPw=="],
"stream-to-buffer": ["stream-to-buffer@0.1.0", "", { "dependencies": { "stream-to": "~0.2.0" } }, "sha512-Da4WoKaZyu3nf+bIdIifh7IPkFjARBnBK+pYqn0EUJqksjV9afojjaCCHUemH30Jmu7T2qcKvlZm2ykN38uzaw=="],
@@ -671,7 +747,7 @@
"streamx": ["streamx@2.20.2", "", { "dependencies": { "fast-fifo": "^1.3.2", "queue-tick": "^1.0.1", "text-decoder": "^1.1.0" }, "optionalDependencies": { "bare-events": "^2.2.0" } }, "sha512-aDGDLU+j9tJcUdPGOaHmVF1u/hhI+CsGkT02V3OKlHDV7IukOI+nTWAGkiZEKCO35rWN1wIr4tS7YFr1f4qSvA=="],
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
"string.prototype.trim": ["string.prototype.trim@1.2.9", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.0", "es-object-atoms": "^1.0.0" } }, "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw=="],
@@ -687,6 +763,8 @@
"strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
"strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
"strtok3": ["strtok3@9.0.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^5.3.1" } }, "sha512-ERPW+XkvX9W2A+ov07iy+ZFJpVdik04GhDA4eVogiG9hpC97Kem2iucyzhFxbFRvQ5o2UckFtKZdp1hkGvnrEw=="],
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
@@ -699,6 +777,8 @@
"through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="],
"to-readable-stream": ["to-readable-stream@1.0.0", "", {}, "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q=="],
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
"token-types": ["token-types@6.0.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA=="],
@@ -707,6 +787,8 @@
"tty-table": ["tty-table@4.2.3", "", { "dependencies": { "chalk": "^4.1.2", "csv": "^5.5.3", "kleur": "^4.1.5", "smartwrap": "^2.0.2", "strip-ansi": "^6.0.1", "wcwidth": "^1.0.1", "yargs": "^17.7.1" }, "bin": { "tty-table": "adapters/terminal-adapter.js" } }, "sha512-Fs15mu0vGzCrj8fmJNP7Ynxt5J7praPXqFN0leZeZBXJwkMxv9cb2D454k1ltrtUSJbZ4yH4e0CynsHLxmUfFA=="],
"type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="],
"typed-array-buffer": ["typed-array-buffer@1.0.2", "", { "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" } }, "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ=="],
"typed-array-byte-length": ["typed-array-byte-length@1.0.1", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-proto": "^1.0.3", "is-typed-array": "^1.1.13" } }, "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw=="],
@@ -715,7 +797,9 @@
"typed-array-length": ["typed-array-length@1.0.6", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0" } }, "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g=="],
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"typedarray-to-buffer": ["typedarray-to-buffer@3.1.5", "", { "dependencies": { "is-typedarray": "^1.0.0" } }, "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q=="],
"typescript": ["typescript@5.7.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg=="],
"uint8array-extras": ["uint8array-extras@1.4.0", "", {}, "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ=="],
@@ -723,10 +807,16 @@
"unbzip2-stream": ["unbzip2-stream@1.4.3", "", { "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" } }, "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg=="],
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
"undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
"unique-string": ["unique-string@2.0.0", "", { "dependencies": { "crypto-random-string": "^2.0.0" } }, "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg=="],
"universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="],
"update-notifier": ["update-notifier@5.1.0", "", { "dependencies": { "boxen": "^5.0.0", "chalk": "^4.1.0", "configstore": "^5.0.1", "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", "is-installed-globally": "^0.4.0", "is-npm": "^5.0.0", "is-yarn-global": "^0.3.0", "latest-version": "^5.1.0", "pupa": "^2.1.1", "semver": "^7.3.4", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" } }, "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw=="],
"url-parse-lax": ["url-parse-lax@3.0.0", "", { "dependencies": { "prepend-http": "^2.0.0" } }, "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ=="],
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="],
@@ -743,10 +833,16 @@
"which-typed-array": ["which-typed-array@1.1.15", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.2" } }, "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA=="],
"wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
"widest-line": ["widest-line@4.0.1", "", { "dependencies": { "string-width": "^5.0.1" } }, "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig=="],
"wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
"write-file-atomic": ["write-file-atomic@3.0.3", "", { "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q=="],
"xdg-basedir": ["xdg-basedir@4.0.0", "", {}, "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q=="],
"xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="],
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
@@ -763,168 +859,144 @@
"@swc/cli/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="],
"@types/fs-extra/@types/node": ["@types/node@22.9.3", "", { "dependencies": { "undici-types": "~6.19.8" } }, "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw=="],
"@types/jsonfile/@types/node": ["@types/node@22.9.3", "", { "dependencies": { "undici-types": "~6.19.8" } }, "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw=="],
"@types/node-fetch/@types/node": ["@types/node@22.9.3", "", { "dependencies": { "undici-types": "~6.19.8" } }, "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw=="],
"@types/node-fetch/form-data": ["form-data@4.0.1", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw=="],
"@types/progress/@types/node": ["@types/node@22.9.3", "", { "dependencies": { "undici-types": "~6.19.8" } }, "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw=="],
"@types/yauzl/@types/node": ["@types/node@22.9.3", "", { "dependencies": { "undici-types": "~6.19.8" } }, "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw=="],
"@types/yazl/@types/node": ["@types/node@22.9.3", "", { "dependencies": { "undici-types": "~6.19.8" } }, "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw=="],
"@xhmikosr/decompress/make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="],
"@xhmikosr/downloader/defaults": ["defaults@3.0.0", "", {}, "sha512-RsqXDEAALjfRTro+IFNKpcPCt0/Cy2FqHSIlnomiJp9YGadpQnrtbRpSgN2+np21qHcIKiva4fiOQGjS9/qR/A=="],
"arraybuffer.prototype.slice/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"bin-version-check/semver": ["semver@7.6.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="],
"boxen/chalk": ["chalk@5.3.0", "", {}, "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="],
"cacheable-request/mimic-response": ["mimic-response@4.0.0", "", {}, "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg=="],
"call-bind/es-define-property": ["es-define-property@1.0.0", "", { "dependencies": { "get-intrinsic": "^1.2.4" } }, "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ=="],
"cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"call-bind/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
"clone-response/mimic-response": ["mimic-response@1.0.1", "", {}, "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="],
"config-chain/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
"define-data-property/es-define-property": ["es-define-property@1.0.0", "", { "dependencies": { "get-intrinsic": "^1.2.4" } }, "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ=="],
"define-data-property/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="],
"es-abstract/es-define-property": ["es-define-property@1.0.0", "", { "dependencies": { "get-intrinsic": "^1.2.4" } }, "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ=="],
"es-abstract/es-object-atoms": ["es-object-atoms@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw=="],
"es-abstract/es-set-tostringtag": ["es-set-tostringtag@2.0.3", "", { "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", "hasown": "^2.0.1" } }, "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ=="],
"es-abstract/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"es-abstract/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="],
"es-abstract/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"file-type/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="],
"get-symbol-description/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"globalthis/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="],
"has-property-descriptors/es-define-property": ["es-define-property@1.0.0", "", { "dependencies": { "get-intrinsic": "^1.2.4" } }, "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ=="],
"has-tostringtag/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"is-array-buffer/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"is-symbol/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"isomorphic-unzip/yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="],
"make-dir/semver": ["semver@7.6.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="],
"log-symbols/chalk": ["chalk@5.3.0", "", {}, "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="],
"object.assign/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="],
"safe-array-concat/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"make-dir/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"safe-array-concat/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"ora/chalk": ["chalk@5.3.0", "", {}, "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="],
"ora/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
"ora/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"package-json/got": ["got@9.6.0", "", { "dependencies": { "@sindresorhus/is": "^0.14.0", "@szmarczak/http-timer": "^1.1.2", "cacheable-request": "^6.0.0", "decompress-response": "^3.3.0", "duplexer3": "^0.1.4", "get-stream": "^4.1.0", "lowercase-keys": "^1.0.1", "mimic-response": "^1.0.1", "p-cancelable": "^1.0.0", "to-readable-stream": "^1.0.0", "url-parse-lax": "^3.0.0" } }, "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q=="],
"package-json/registry-auth-token": ["registry-auth-token@4.2.2", "", { "dependencies": { "rc": "1.2.8" } }, "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg=="],
"package-json/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"rc/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
"restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
"restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
"seek-bzip/commander": ["commander@6.2.1", "", {}, "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="],
"semver-truncate/semver": ["semver@7.6.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="],
"set-function-length/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"set-function-length/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="],
"side-channel/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"semver-diff/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"smartwrap/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="],
"string.prototype.trim/es-object-atoms": ["es-object-atoms@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw=="],
"string-width/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"string.prototype.trimend/es-object-atoms": ["es-object-atoms@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw=="],
"update-notifier/boxen": ["boxen@5.1.2", "", { "dependencies": { "ansi-align": "^3.0.0", "camelcase": "^6.2.0", "chalk": "^4.1.0", "cli-boxes": "^2.2.1", "string-width": "^4.2.2", "type-fest": "^0.20.2", "widest-line": "^3.1.0", "wrap-ansi": "^7.0.0" } }, "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ=="],
"string.prototype.trimstart/es-object-atoms": ["es-object-atoms@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw=="],
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
"typed-array-byte-length/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="],
"wrap-ansi/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"typed-array-byte-offset/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="],
"typed-array-length/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="],
"unbox-primitive/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"which-typed-array/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="],
"yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"yazl/buffer-crc32": ["buffer-crc32@1.0.0", "", {}, "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w=="],
"@types/fs-extra/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
"ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"@types/jsonfile/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
"@types/node-fetch/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
"@types/progress/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
"@types/yauzl/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
"@types/yazl/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
"arraybuffer.prototype.slice/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"call-bind/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"define-data-property/es-define-property/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"define-data-property/gopd/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"file-type/get-stream/is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="],
"get-symbol-description/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"ora/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
"globalthis/gopd/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"ora/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
"has-property-descriptors/es-define-property/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"package-json/got/@sindresorhus/is": ["@sindresorhus/is@0.14.0", "", {}, "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ=="],
"is-array-buffer/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"package-json/got/@szmarczak/http-timer": ["@szmarczak/http-timer@1.1.2", "", { "dependencies": { "defer-to-connect": "^1.0.1" } }, "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA=="],
"set-function-length/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"package-json/got/cacheable-request": ["cacheable-request@6.1.0", "", { "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^3.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^4.1.0", "responselike": "^1.0.2" } }, "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg=="],
"side-channel/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"package-json/got/decompress-response": ["decompress-response@3.3.0", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA=="],
"package-json/got/get-stream": ["get-stream@4.1.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w=="],
"package-json/got/lowercase-keys": ["lowercase-keys@1.0.1", "", {}, "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="],
"package-json/got/mimic-response": ["mimic-response@1.0.1", "", {}, "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="],
"package-json/got/p-cancelable": ["p-cancelable@1.1.0", "", {}, "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw=="],
"smartwrap/yargs/cliui": ["cliui@6.0.0", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="],
"smartwrap/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"smartwrap/yargs/y18n": ["y18n@4.0.3", "", {}, "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="],
"smartwrap/yargs/yargs-parser": ["yargs-parser@18.1.3", "", { "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="],
"typed-array-byte-length/gopd/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"string-width/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
"typed-array-byte-offset/gopd/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"update-notifier/boxen/camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="],
"typed-array-length/gopd/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"update-notifier/boxen/cli-boxes": ["cli-boxes@2.2.1", "", {}, "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw=="],
"which-typed-array/gopd/get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
"update-notifier/boxen/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"define-data-property/es-define-property/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"update-notifier/boxen/type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="],
"define-data-property/gopd/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"update-notifier/boxen/widest-line": ["widest-line@3.1.0", "", { "dependencies": { "string-width": "^4.0.0" } }, "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg=="],
"globalthis/gopd/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"update-notifier/boxen/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
"has-property-descriptors/es-define-property/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
"yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"package-json/got/@szmarczak/http-timer/defer-to-connect": ["defer-to-connect@1.1.3", "", {}, "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ=="],
"package-json/got/cacheable-request/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
"package-json/got/cacheable-request/keyv": ["keyv@3.1.0", "", { "dependencies": { "json-buffer": "3.0.0" } }, "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA=="],
"package-json/got/cacheable-request/lowercase-keys": ["lowercase-keys@2.0.0", "", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="],
"package-json/got/cacheable-request/normalize-url": ["normalize-url@4.5.1", "", {}, "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA=="],
"package-json/got/cacheable-request/responselike": ["responselike@1.0.2", "", { "dependencies": { "lowercase-keys": "^1.0.0" } }, "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ=="],
"smartwrap/yargs/cliui/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="],
"typed-array-byte-length/gopd/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"smartwrap/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"typed-array-byte-offset/gopd/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"smartwrap/yargs/yargs-parser/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="],
"typed-array-length/gopd/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"update-notifier/boxen/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"which-typed-array/gopd/get-intrinsic/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"package-json/got/cacheable-request/keyv/json-buffer": ["json-buffer@3.0.0", "", {}, "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ=="],
"package-json/got/cacheable-request/responselike/lowercase-keys": ["lowercase-keys@1.0.1", "", {}, "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="],
}
}

View File

@@ -87,14 +87,8 @@
"maxPackageVersion": {
"hasValue": true
},
"packageVersionRange": {
"hasValue": true
},
"rollout": {
"hasValue": true
},
"dryRun": {
"default": false
}
}
},
@@ -124,7 +118,7 @@
"description": "Bundle javascript and copy assets."
},
"bundle": {
"description": "Bundle javascript code only and optionally publish.",
"description": "Bundle javascript code only.",
"options": {
"dev": {
"default": "false",
@@ -142,11 +136,11 @@
"hasValue": true
},
"intermediaDir": {
"default": "${tempDir}/intermedia/${platform}",
"default": ".pushy/intermedia/${platform}",
"hasValue": true
},
"output": {
"default": "${tempDir}/output/${platform}.${time}.ppk",
"default": ".pushy/output/${platform}.${time}.ppk",
"hasValue": true
},
"sourcemap": {
@@ -163,18 +157,6 @@
},
"disableHermes": {
"default": false
},
"name": {
"hasValue": true,
"description": "Version name for publishing"
},
"description": {
"hasValue": true,
"description": "Version description for publishing"
},
"metaInfo": {
"hasValue": true,
"description": "Meta information for publishing"
}
}
},
@@ -185,7 +167,7 @@
"description": "Create diff patch",
"options": {
"output": {
"default": "${tempDir}/output/diff",
"default": ".pushy/output/diff",
"hasValue": true
}
}
@@ -194,7 +176,7 @@
"description": "Create diff patch from a Android package(.apk)",
"options": {
"output": {
"default": "${tempDir}/output/diff-${time}.apk-patch",
"default": ".pushy/output/diff-${time}.apk-patch",
"hasValue": true
}
}
@@ -203,7 +185,7 @@
"description": "Create diff patch from a iOS package(.ipa)",
"options": {
"output": {
"default": "${tempDir}/output/diff-${time}.ipa-patch",
"default": ".pushy/output/diff-${time}.ipa-patch",
"hasValue": true
}
}
@@ -212,7 +194,7 @@
"description": "Create hdiff patch",
"options": {
"output": {
"default": "${tempDir}/output/hdiff",
"default": ".pushy/output/hdiff",
"hasValue": true
}
}
@@ -221,7 +203,7 @@
"description": "Create hdiff patch from a Android package(.apk)",
"options": {
"output": {
"default": "${tempDir}/output/hdiff-${time}.apk-patch",
"default": ".pushy/output/hdiff-${time}.apk-patch",
"hasValue": true
}
}
@@ -230,7 +212,7 @@
"description": "Create hdiff patch from a Prepare package(.ppk)",
"options": {
"output": {
"default": "${tempDir}/output/hdiff-${time}.ppk-patch",
"default": ".pushy/output/hdiff-${time}.ppk-patch",
"hasValue": true
}
}
@@ -239,7 +221,7 @@
"description": "Create hdiff patch from a Harmony package(.app)",
"options": {
"output": {
"default": "${tempDir}/output/hdiff-${time}.app-patch",
"default": ".pushy/output/hdiff-${time}.app-patch",
"hasValue": true
}
}
@@ -248,7 +230,7 @@
"description": "Create hdiff patch from a iOS package(.ipa)",
"options": {
"output": {
"default": "${tempDir}/output/hdiff-${time}.ipa-patch",
"default": ".pushy/output/hdiff-${time}.ipa-patch",
"hasValue": true
}
}
@@ -259,4 +241,4 @@
"default": false
}
}
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "react-native-update-cli",
"version": "1.45.5",
"description": "command line tool for react-native-update (remote updates for react native)",
"version": "1.42.0",
"description": "Command tools for javaScript updater with `pushy` service for react native apps.",
"main": "index.js",
"bin": {
"pushy": "lib/index.js",
@@ -14,7 +14,7 @@
],
"scripts": {
"build": "swc src -d lib --strip-leading-paths",
"prepublishOnly": "npm run build && chmod +x lib/index.js",
"prepare": "npm run build && chmod +x lib/index.js",
"lint": "tsc --noEmit & biome check --write ."
},
"repository": {
@@ -35,54 +35,50 @@
},
"homepage": "https://github.com/reactnativecn/react-native-pushy/tree/master/react-native-pushy-cli",
"dependencies": {
"@colors/colors": "^1.6.0",
"@badisi/latest-version": "^7.0.10",
"bplist-parser": "^0.3.2",
"bytebuffer": "^5.0.1",
"cgbi-to-png": "^1.0.7",
"chalk": "4",
"cli-arguments": "^0.2.1",
"commander": "^13",
"commander": "^12.1.0",
"compare-versions": "^6.1.1",
"filesize-parser": "^1.5.1",
"form-data": "^4.0.2",
"form-data": "^4.0.1",
"fs-extra": "8",
"global-dirs": "^4.0.0",
"gradle-to-js": "^2.0.1",
"i18next": "^24.2.3",
"isomorphic-git": "^1.30.1",
"i18next": "^24.2.2",
"isomorphic-git": "^1.29.0",
"isomorphic-unzip": "^1.1.5",
"node-fetch": "^2.6.1",
"plist": "^3.1.0",
"progress": "^2.0.3",
"properties": "^1.2.1",
"read": "^4.1.0",
"registry-auth-token": "^5.1.0",
"semver": "^7.7.2",
"read": "^4.0.0",
"semver": "^7.6.3",
"tcp-ping": "^0.1.1",
"tty-table": "4.2",
"update-notifier": "^5.1.0",
"yauzl": "^3.2.0",
"yazl": "3.3.1"
},
"engines": {
"node": ">= 14"
"node": ">= 10"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@swc/cli": "0.7.7",
"@swc/core": "^1.11.24",
"@swc/cli": "^0.5.1",
"@swc/core": "^1.9.3",
"@types/filesize-parser": "^1.5.3",
"@types/fs-extra": "^11.0.4",
"@types/node": "^22.15.18",
"@types/node": "^22.9.3",
"@types/node-fetch": "^2.6.12",
"@types/progress": "^2.0.7",
"@types/semver": "^7.7.0",
"@types/semver": "^7.5.8",
"@types/tcp-ping": "^0.1.6",
"@types/update-notifier": "^6.0.8",
"@types/yauzl": "^2.10.3",
"@types/yazl": "^2.4.6",
"typescript": "^5.8.3"
},
"trustedDependencies": [
"@biomejs/biome",
"@swc/core"
]
"typescript": "^5.7.2"
}
}

View File

@@ -1,25 +1,24 @@
import fetch from 'node-fetch';
import fs from 'fs';
import util from 'util';
import path from 'path';
import fs from 'node:fs';
import util from 'node:util';
import path from 'node:path';
import ProgressBar from 'progress';
import packageJson from '../package.json';
import tcpp from 'tcp-ping';
import filesizeParser from 'filesize-parser';
import {
pricingPageUrl,
credentialFile,
defaultEndpoint,
} from './utils/constants';
import type { Session, Package } from 'types';
import { pricingPageUrl, credentialFile, IS_CRESC } from './utils/constants';
import type { Session } from 'types';
import FormData from 'form-data';
import { t } from './utils/i18n';
const tcpPing = util.promisify(tcpp.ping);
let session: Session | undefined;
let savedSession: Session | undefined;
const defaultEndpoint = IS_CRESC
? 'https://api.cresc.dev'
: 'https://update.reactnative.cn/api';
const host =
process.env.PUSHY_REGISTRY || process.env.RNU_API || defaultEndpoint;
@@ -74,7 +73,7 @@ async function query(url: string, options: fetch.RequestInit) {
if (resp.status !== 200) {
const message = json?.message || resp.statusText;
if (resp.status === 401) {
throw new Error(t('loginExpired'));
throw new Error('登录信息已过期,请使用 pushy login 命令重新登录');
}
throw new Error(message);
}
@@ -93,7 +92,7 @@ function queryWithoutBody(method: string) {
}
function queryWithBody(method: string) {
return (api: string, body?: Record<string, any>) =>
return (api: string, body: Record<string, any>) =>
query(host + api, {
method,
headers: {
@@ -134,13 +133,10 @@ export async function uploadFile(fn: string, key?: string) {
const fileSize = fs.statSync(fn).size;
if (maxSize && fileSize > filesizeParser(maxSize)) {
const readableFileSize = `${(fileSize / 1048576).toFixed(1)}m`;
throw new Error(
t('fileSizeExceeded', {
fileSize: readableFileSize,
maxSize,
pricingPageUrl,
}),
`此文件大小 ${(fileSize / 1048576).toFixed(
1,
)}m , 超出当前额度 ${maxSize} 。您可以考虑升级付费业务以提升此额度。详情请访问: ${pricingPageUrl}`,
);
}
@@ -177,8 +173,3 @@ export async function uploadFile(fn: string, key?: string) {
// const body = await response.json();
return { hash: key || formData.key };
}
export const getAllPackages = async (appId: string) => {
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
return data as Package[] | undefined | null;
};

View File

@@ -1,47 +1,48 @@
import { question } from './utils';
import fs from 'fs';
import fs from 'node:fs';
import Table from 'tty-table';
import { post, get, doDelete } from './api';
import type { Platform } from './types';
import { t } from './utils/i18n';
const validPlatforms = ['ios', 'android', 'harmony'];
const validPlatforms = {
ios: 1,
android: 1,
harmony: 1,
};
export async function getPlatform(platform?: string) {
return assertPlatform(
platform || (await question(t('platformQuestion'))),
) as Platform;
}
export function assertPlatform(platform: string) {
if (!validPlatforms.includes(platform)) {
throw new Error(t('unsupportedPlatform', { platform }));
export function checkPlatform(platform: Platform) {
if (!validPlatforms[platform]) {
throw new Error(`无法识别的平台 '${platform}'`);
}
return platform;
}
export function getSelectedApp(platform: Platform) {
assertPlatform(platform);
checkPlatform(platform);
if (!fs.existsSync('update.json')) {
throw new Error(t('appNotSelected', { platform }));
throw new Error(
`App not selected. run 'pushy selectApp --platform ${platform}' first!`,
);
}
const updateInfo = JSON.parse(fs.readFileSync('update.json', 'utf8'));
if (!updateInfo[platform]) {
throw new Error(t('appNotSelected', { platform }));
throw new Error(
`App not selected. run 'pushy selectApp --platform ${platform}' first!`,
);
}
return updateInfo[platform];
}
export async function listApp(platform: Platform | '' = '') {
export async function listApp(platform: Platform) {
const { data } = await get('/app/list');
const list = platform ? data.filter((v) => v.platform === platform) : data;
const header = [
{ value: t('appId') },
{ value: t('appName') },
{ value: t('platform') },
{ value: '应用 id' },
{ value: '应用名称' },
{ value: '平台' },
];
const rows = [];
for (const app of list) {
@@ -50,7 +51,11 @@ export async function listApp(platform: Platform | '' = '') {
console.log(Table(header, rows).render());
console.log(`\n${t('totalApps', { count: list.length, platform })}`);
if (platform) {
console.log(`\${list.length} ${platform} 个应用`);
} else {
console.log(`\${list.length} 个应用`);
}
return list;
}
@@ -58,7 +63,7 @@ export async function chooseApp(platform: Platform) {
const list = await listApp(platform);
while (true) {
const id = await question(t('enterAppIdQuestion'));
const id = await question('输入应用 id:');
const app = list.find((v) => v.id === Number(id));
if (app) {
return app;
@@ -67,60 +72,48 @@ export async function chooseApp(platform: Platform) {
}
export const commands = {
createApp: async function ({
options,
}: {
options: { name: string; downloadUrl: string; platform: Platform };
}) {
const name = options.name || (await question(t('appNameQuestion')));
createApp: async function ({ options }) {
const name = options.name || (await question('应用名称:'));
const { downloadUrl } = options;
const platform = await getPlatform(options.platform);
const { id } = await post('/app/create', { name, platform, downloadUrl });
console.log(t('createAppSuccess', { id }));
const platform = checkPlatform(
options.platform || (await question('平台(ios/android/harmony):')),
);
const { id } = await post('/app/create', { name, platform });
console.log(`已成功创建应用id: ${id}`);
await this.selectApp({
args: [id],
options: { platform },
options: { platform, downloadUrl },
});
},
deleteApp: async ({
args,
options,
}: {
args: string[];
options: { platform: Platform };
}) => {
deleteApp: async ({ args, options }) => {
const { platform } = options;
const id = args[0] || chooseApp(platform);
if (!id) {
console.log(t('cancelled'));
console.log('已取消');
}
await doDelete(`/app/${id}`);
console.log(t('operationSuccess'));
console.log('操作成功');
},
apps: async ({ options }: { options: { platform: Platform } }) => {
apps: async ({ options }) => {
const { platform } = options;
listApp(platform);
},
selectApp: async ({
args,
options,
}: {
args: string[];
options: { platform: Platform };
}) => {
const platform = await getPlatform(options.platform);
selectApp: async ({ args, options }) => {
const platform = checkPlatform(
options.platform || (await question('平台(ios/android/harmony):')),
);
const id = args[0]
? Number.parseInt(args[0])
: (await chooseApp(platform)).id;
let updateInfo: Partial<
Record<Platform, { appId: number; appKey: string }>
> = {};
let updateInfo = {};
if (fs.existsSync('update.json')) {
try {
updateInfo = JSON.parse(fs.readFileSync('update.json', 'utf8'));
} catch (e) {
console.error(t('failedToParseUpdateJson'));
console.error(
'Failed to parse file `update.json`. Try to remove it manually.',
);
throw e;
}
}

View File

@@ -1,31 +1,20 @@
import path from 'path';
import path from 'node:path';
import { translateOptions } from './utils';
import * as fs from 'fs-extra';
import { ZipFile as YazlZipFile } from 'yazl';
import {
type Entry,
open as openZipFile,
type ZipFile as YauzlZipFile,
} from 'yauzl';
import { ZipFile } from 'yazl';
import { open as openZipFile } from 'yauzl';
import { question, checkPlugins } from './utils';
import { getPlatform } from './app';
import { spawn, spawnSync } from 'child_process';
import { satisfies } from 'compare-versions';
import { checkPlatform } from './app';
import { spawn, spawnSync } from 'node:child_process';
import semverSatisfies from 'semver/functions/satisfies';
const g2js = require('gradle-to-js/lib/parser');
import os from 'os';
import os from 'node:os';
const properties = require('properties');
import { depVersions } from './utils/dep-versions';
import { t } from './utils/i18n';
import { tempDir } from './utils/constants';
import { checkLockFiles } from './utils/check-lockfile';
import { addGitIgnore } from './utils/add-gitignore';
import { commands as versionCommands } from './versions';
type Diff = (oldSource?: Buffer, newSource?: Buffer) => Buffer;
let bsdiff: Diff;
let hdiff: Diff;
let diff: Diff;
let bsdiff;
let hdiff;
let diff;
try {
bsdiff = require('node-bsdiff').diff;
} catch (e) {}
@@ -66,7 +55,9 @@ async function runReactNativeBundleCommand({
if (platform === 'android') {
gradleConfig = await checkGradleConfig();
if (gradleConfig.crunchPngs !== false) {
console.warn(t('androidCrunchPngsWarning'));
console.warn(
'android 的 crunchPngs 选项似乎尚未禁用(如已禁用则请忽略此提示),这可能导致热更包体积异常增大,具体请参考 https://pushy.reactnative.cn/docs/getting-started.html#%E7%A6%81%E7%94%A8-android-%E7%9A%84-crunch-%E4%BC%98%E5%8C%96 \n',
);
}
}
@@ -101,7 +92,7 @@ async function runReactNativeBundleCommand({
.toString(),
).version;
// expo cli 0.10.17 (expo 49) 开始支持 bundle:embed
if (satisfies(expoCliVersion, '>= 0.10.17')) {
if (semverSatisfies(expoCliVersion, '>= 0.10.17')) {
usingExpo = true;
} else {
cliPath = undefined;
@@ -111,13 +102,13 @@ async function runReactNativeBundleCommand({
const getRnCli = () => {
try {
// rn < 0.75
cliPath = require.resolve('react-native/local-cli/cli.js', {
// rn >= 0.75
cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
paths: [process.cwd()],
});
} catch (e) {
// rn >= 0.75
cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
// rn < 0.75
cliPath = require.resolve('react-native/local-cli/cli.js', {
paths: [process.cwd()],
});
}
@@ -219,13 +210,17 @@ async function runReactNativeBundleCommand({
reactNativeBundleProcess.on('close', async (exitCode) => {
if (exitCode) {
reject(new Error(t('bundleCommandError', { code: exitCode })));
reject(
new Error(
`"react-native bundle" command exited with code ${exitCode}.`,
),
);
} else {
let hermesEnabled: boolean | undefined = false;
if (disableHermes) {
hermesEnabled = false;
console.log(t('hermesDisabled'));
console.log('Hermes disabled');
} else if (platform === 'android') {
const gradlePropeties = await new Promise<{
hermesEnabled?: boolean;
@@ -284,8 +279,8 @@ async function copyHarmonyBundle(outputFolder: string) {
await fs.ensureDir(outputFolder);
await fs.copy(harmonyRawPath, outputFolder);
} catch (error: any) {
console.error(t('copyHarmonyBundleError', { error }));
throw new Error(t('copyFileFailed', { error: error.message }));
console.error('copyHarmonyBundle 错误:', error);
throw new Error(`复制文件失败: ${error.message}`);
}
}
@@ -326,7 +321,7 @@ async function compileHermesByteCode(
sourcemapOutput: string,
shouldCleanSourcemap: boolean,
) {
console.log(t('hermesEnabledCompiling'));
console.log('Hermes enabled, now compiling to hermes bytecode:\n');
// >= rn 0.69
const rnDir = path.dirname(
require.resolve('react-native', {
@@ -356,9 +351,7 @@ async function compileHermesByteCode(
);
args.push('-output-source-map');
}
console.log(
t('runningHermesc', { command: hermesCommand, args: args.join(' ') }),
);
console.log(`Running hermesc: ${hermesCommand} ${args.join(' ')}`);
spawnSync(hermesCommand, args, {
stdio: 'ignore',
});
@@ -368,7 +361,7 @@ async function compileHermesByteCode(
if (!fs.existsSync(composerPath)) {
return;
}
console.log(t('composingSourceMap'));
console.log('Composing source map');
spawnSync(
'node',
[
@@ -394,7 +387,7 @@ async function copyDebugidForSentry(
sourcemapOutput: string,
) {
if (sourcemapOutput) {
let copyDebugidPath: string | undefined;
let copyDebugidPath;
try {
copyDebugidPath = require.resolve(
'@sentry/react-native/scripts/copy-debugid.js',
@@ -403,14 +396,16 @@ async function copyDebugidForSentry(
},
);
} catch (error) {
console.error(t('sentryCliNotFound'));
console.error(
'无法找到 Sentry copy-debugid.js 脚本文件,请确保已正确安装 @sentry/react-native',
);
return;
}
if (!fs.existsSync(copyDebugidPath)) {
return;
}
console.log(t('copyingDebugId'));
console.log('Copying debugid');
spawnSync(
'node',
[
@@ -433,13 +428,13 @@ async function uploadSourcemapForSentry(
version: string,
) {
if (sourcemapOutput) {
let sentryCliPath: string | undefined;
let sentryCliPath;
try {
sentryCliPath = require.resolve('@sentry/cli/bin/sentry-cli', {
paths: [process.cwd()],
});
} catch (error) {
console.error(t('sentryCliNotFound'));
console.error('无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli');
return;
}
@@ -454,9 +449,9 @@ async function uploadSourcemapForSentry(
stdio: 'inherit',
},
);
console.log(t('sentryReleaseCreated', { version }));
console.log(`Sentry release created for version: ${version}`);
console.log(t('uploadingSourcemap'));
console.log('Uploading sourcemap');
spawnSync(
'node',
[
@@ -478,12 +473,12 @@ async function uploadSourcemapForSentry(
}
const ignorePackingFileNames = ['.', '..', 'index.bundlejs.map'];
const ignorePackingExtensions = ['DS_Store', 'txt.map'];
const ignorePackingExtensions = ['DS_Store'];
async function pack(dir: string, output: string) {
console.log(t('packing'));
console.log('Packing');
fs.ensureDirSync(path.dirname(output));
await new Promise<void>((resolve, reject) => {
const zipfile = new YazlZipFile();
const zipfile = new ZipFile();
function addDirectory(root: string, rel: string) {
if (rel) {
@@ -517,16 +512,13 @@ async function pack(dir: string, output: string) {
});
zipfile.end();
});
console.log(t('fileGenerated', { file: output }));
console.log(`ppk热更包已生成并保存到: ${output}`);
}
export function readEntry(
entry: Entry,
zipFile: YauzlZipFile,
): Promise<Buffer> {
export function readEntire(entry: string, zipFile: ZipFile) {
const buffers: Buffer[] = [];
return new Promise((resolve, reject) => {
zipFile.openReadStream(entry, (err, stream) => {
zipFile.openReadStream(entry, (err: any, stream: any) => {
stream.pipe({
write(chunk: Buffer) {
buffers.push(chunk);
@@ -554,7 +546,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
const originEntries = {};
const originMap = {};
let originSource: Buffer | undefined;
let originSource;
await enumZipEntries(origin, (entry, zipFile) => {
originEntries[entry.fileName] = entry;
@@ -567,7 +559,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
entry.fileName === 'bundle.harmony.js'
) {
// This is source.
return readEntry(entry, zipFile).then((v) => (originSource = v));
return readEntire(entry, zipFile).then((v) => (originSource = v));
}
}
});
@@ -580,7 +572,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
const copies = {};
const zipfile = new YazlZipFile();
const zipfile = new ZipFile();
const writePromise = new Promise((resolve, reject) => {
zipfile.outputStream.on('error', (err) => {
@@ -617,7 +609,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
}
} else if (entry.fileName === 'index.bundlejs') {
//console.log('Found bundle');
return readEntry(entry, nextZipfile).then((newSource) => {
return readEntire(entry, nextZipfile).then((newSource) => {
//console.log('Begin diff');
zipfile.addBuffer(
diff(originSource, newSource),
@@ -627,7 +619,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
});
} else if (entry.fileName === 'bundle.harmony.js') {
//console.log('Found bundle');
return readEntry(entry, nextZipfile).then((newSource) => {
return readEntire(entry, nextZipfile).then((newSource) => {
//console.log('Begin diff');
zipfile.addBuffer(
diff(originSource, newSource),
@@ -675,7 +667,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
for (const k in originEntries) {
if (!newEntries[k]) {
console.log(t('deleteFile', { file: k }));
console.log(`Delete ${k}`);
deletes[k] = 1;
}
}
@@ -701,9 +693,9 @@ async function diffFromPackage(
const originEntries = {};
const originMap = {};
let originSource: Buffer | undefined;
let originSource;
await enumZipEntries(origin, (entry, zipFile) => {
await enumZipEntries(origin, (entry: any, zipFile: any) => {
if (!/\/$/.test(entry.fileName)) {
const fn = transformPackagePath(entry.fileName);
if (!fn) {
@@ -717,7 +709,7 @@ async function diffFromPackage(
if (fn === originBundleName) {
// This is source.
return readEntry(entry, zipFile).then((v) => (originSource = v));
return readEntire(entry, zipFile).then((v) => (originSource = v));
}
}
});
@@ -730,7 +722,7 @@ async function diffFromPackage(
const copies = {};
const zipfile = new YazlZipFile();
const zipfile = new ZipFile();
const writePromise = new Promise((resolve, reject) => {
zipfile.outputStream.on('error', (err) => {
@@ -747,7 +739,7 @@ async function diffFromPackage(
zipfile.addEmptyDirectory(entry.fileName);
} else if (entry.fileName === 'index.bundlejs') {
//console.log('Found bundle');
return readEntry(entry, nextZipfile).then((newSource) => {
return readEntire(entry, nextZipfile).then((newSource) => {
//console.log('Begin diff');
zipfile.addBuffer(
diff(originSource, newSource),
@@ -757,7 +749,7 @@ async function diffFromPackage(
});
} else if (entry.fileName === 'bundle.harmony.js') {
//console.log('Found bundle');
return readEntry(entry, nextZipfile).then((newSource) => {
return readEntire(entry, nextZipfile).then((newSource) => {
//console.log('Begin diff');
zipfile.addBuffer(
diff(originSource, newSource),
@@ -799,18 +791,14 @@ async function diffFromPackage(
export async function enumZipEntries(
zipFn: string,
callback: (
entry: Entry,
zipFile: YauzlZipFile,
nestedPath?: string,
) => Promise<any>,
callback: (entry: any, zipFile: any) => void,
nestedPath = '',
) {
return new Promise((resolve, reject) => {
openZipFile(
zipFn,
{ lazyEntries: true },
async (err: any, zipfile: YauzlZipFile) => {
async (err: any, zipfile: ZipFile) => {
if (err) {
return reject(err);
}
@@ -852,7 +840,7 @@ export async function enumZipEntries(
await result;
}
} catch (error) {
console.error(t('processingError', { error }));
console.error('处理文件时出错:', error);
}
zipfile.readEntry();
@@ -864,11 +852,11 @@ export async function enumZipEntries(
});
}
function diffArgsCheck(args: string[], options: any, diffFn: string) {
function diffArgsCheck(args, options, diffFn) {
const [origin, next] = args;
if (!origin || !next) {
console.error(t('usageDiff', { command: diffFn }));
console.error(`Usage: pushy ${diffFn} <origin> <next>`);
process.exit(1);
}
@@ -901,8 +889,10 @@ function diffArgsCheck(args: string[], options: any, diffFn: string) {
}
export const commands = {
bundle: async ({ options }) => {
const platform = await getPlatform(options.platform);
bundle: async function ({ options }) {
const platform = checkPlatform(
options.platform || (await question('平台(ios/android/harmony):')),
);
const {
bundleName,
@@ -915,18 +905,11 @@ export const commands = {
expo,
rncli,
disableHermes,
name,
description,
metaInfo,
} = translateOptions({
...options,
tempDir,
platform,
});
checkLockFiles();
addGitIgnore();
const bundleParams = await checkPlugins();
const sourcemapPlugin = bundleParams.sourcemap;
const isSentry = bundleParams.sentry;
@@ -936,7 +919,7 @@ export const commands = {
const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
if (!platform) {
throw new Error(t('platformRequired'));
throw new Error('Platform must be specified.');
}
console.log(`Bundling with react-native: ${depVersions['react-native']}`);
@@ -958,17 +941,14 @@ export const commands = {
await pack(path.resolve(intermediaDir), realOutput);
if (name) {
const versionName = await versionCommands.publish({
const v = await question('是否现在上传此热更包?(Y/N)');
if (v.toLowerCase() === 'y') {
const versionName = await this.publish({
args: [realOutput],
options: {
platform,
name,
description,
metaInfo,
},
});
if (isSentry) {
await copyDebugidForSentry(bundleName, intermediaDir, sourcemapOutput);
await uploadSourcemapForSentry(
@@ -978,43 +958,20 @@ export const commands = {
versionName,
);
}
} else if (!options['no-interactive']) {
const v = await question(t('uploadBundlePrompt'));
if (v.toLowerCase() === 'y') {
const versionName = await versionCommands.publish({
args: [realOutput],
options: {
platform,
},
});
if (isSentry) {
await copyDebugidForSentry(
bundleName,
intermediaDir,
sourcemapOutput,
);
await uploadSourcemapForSentry(
bundleName,
intermediaDir,
sourcemapOutput,
versionName,
);
}
}
}
},
async diff({ args, options }) {
const { origin, next, realOutput } = diffArgsCheck(args, options, 'diff');
await diffFromPPK(origin, next, realOutput);
await diffFromPPK(origin, next, realOutput, 'index.bundlejs');
console.log(`${realOutput} generated.`);
},
async hdiff({ args, options }) {
const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiff');
await diffFromPPK(origin, next, realOutput);
await diffFromPPK(origin, next, realOutput, 'index.bundlejs');
console.log(`${realOutput} generated.`);
},

View File

@@ -1,15 +1,36 @@
#!/usr/bin/env node
import { loadSession } from './api';
import updateNotifier from 'update-notifier';
import { printVersionCommand } from './utils';
import { t } from './utils/i18n';
import pkg from '../package.json';
import i18next from 'i18next';
import en from './locales/en';
import zh from './locales/zh';
import { IS_CRESC } from './utils/constants';
i18next.init({
lng: IS_CRESC ? 'en' : 'zh',
// debug: process.env.NODE_ENV !== 'production',
resources: {
en,
zh,
},
});
updateNotifier({ pkg }).notify({
isGlobal: true,
message:
'建议运行 `{updateCommand}` 来更新命令行工具以获得功能、性能和安全性的持续改进',
});
function printUsage() {
// const commandName = args[0];
// TODO: print usage of commandName, or print global usage.
console.log('Usage is under development now.');
console.log(
'Visit `https://github.com/reactnativecn/react-native-update` for document.',
'Visit `https://github.com/reactnativecn/react-native-pushy` for early document.',
);
process.exit(1);
}
@@ -37,7 +58,7 @@ async function run() {
.then(() => commands[argv.command](argv))
.catch((err) => {
if (err.status === 401) {
console.log(t('loginFirst'));
console.log('尚未登录。\n请在项目目录中运行`pushy login`命令来登录');
return;
}
console.error(err.stack);

View File

@@ -1,133 +1 @@
export default {
addedToGitignore: 'Added {{line}} to .gitignore',
androidCrunchPngsWarning:
'The crunchPngs option of android seems not disabled (Please ignore this warning if already disabled), which may cause abnormal consumption of mobile network traffic. Please refer to https://cresc.dev/docs/getting-started#disable-crunchpngs-on-android \n',
appId: 'App ID',
appIdMismatchApk:
'App ID mismatch! Current APK: {{appIdInPkg}}, current update.json: {{appId}}',
appIdMismatchApp:
'App ID mismatch! Current APP: {{appIdInPkg}}, current update.json: {{appId}}',
appIdMismatchIpa:
'App ID mismatch! Current IPA: {{appIdInPkg}}, current update.json: {{appId}}',
appKeyMismatchApk:
'App Key mismatch! Current APK: {{appKeyInPkg}}, current update.json: {{appKey}}',
appKeyMismatchApp:
'App Key mismatch! Current APP: {{appKeyInPkg}}, current update.json: {{appKey}}',
appKeyMismatchIpa:
'App Key mismatch! Current IPA: {{appKeyInPkg}}, current update.json: {{appKey}}',
appName: 'App Name',
appNameQuestion: 'App Name:',
appNotSelected:
'App not selected. run `cresc selectApp --platform {{platform}}` first!',
appUploadSuccess:
'Successfully uploaded APP native package (id: {{id}}, version: {{version}}, buildTime: {{buildTime}})',
apkUploadSuccess:
'Successfully uploaded APK native package (id: {{id}}, version: {{version}}, buildTime: {{buildTime}})',
boundTo: ', bound to: {{name}} ({{id}})',
buildTimeNotFound:
'Cannot get the build timestamp of this package. Please update `react-native-update` to the latest version and re-package and upload.',
bundleCommandError:
'"react-native bundle" command exited with code {{code}}.',
bundleNotFound:
'Bundle file not found. Please ensure that this {{packageType}} is a release version and the bundle file name is the default `{{entryFile}}`',
bundlingWithRN: 'Bundling with react-native: {{version}}',
cancelled: 'Cancelled',
composingSourceMap: 'Composing source map',
copyFileFailed: 'Failed to copy file: {{error}}',
copyHarmonyBundleError: 'Error copying Harmony bundle: {{error}}',
copyingDebugId: 'Copying debugid',
createAppSuccess: 'App created successfully (id: {{id}})',
deleteFile: 'Delete {{- file}}',
deletingFile: 'Delete {{- file}}',
enterAppIdQuestion: 'Enter AppId:',
enterNativePackageId: 'Enter native package ID:',
errorInHarmonyApp: 'Error in getEntryFromHarmonyApp: {{error}}',
expiredStatus: '(Expired)',
failedToParseIcon: '[Warning] failed to parse icon: {{error}}',
failedToParseUpdateJson:
'Failed to parse file `update.json`. Try to remove it manually.',
fileGenerated: '{{- file}} generated.',
fileSizeExceeded:
'This file size is {{fileSize}} , exceeding the current quota {{maxSize}} . You may consider upgrading to a higher plan to increase this quota. Details can be found at: {{- pricingPageUrl}}',
hermesDisabled: 'Hermes disabled',
hermesEnabledCompiling: 'Hermes enabled, now compiling to hermes bytecode:\n',
ipaUploadSuccess:
'Successfully uploaded IPA native package (id: {{id}}, version: {{version}}, buildTime: {{buildTime}})',
keyStrings: 'Key strings:',
latestVersionTag: '(latest: {{version}})',
lockBestPractice: `
Best practices for lock files:
1. All members of the development team should use the same package manager to maintain a single lock file.
2. Add the lock file to version control (but do not commit multiple lock files of different formats).
3. Pay attention to changes in the lock file during code review.
This can reduce the risk of inconsistent dependencies and supply chain attacks.
`,
lockNotFound:
'No lock file detected, which may cause inconsistent dependencies and hot-updating issues.',
loggedOut: 'Logged out',
loginExpired:
'Login information has expired. Please use `cresc login` command to re-login',
loginFirst:
'Not logged in.\nPlease run `cresc login` in the project directory to login.',
multipleLocksFound:
'Multiple lock files detected ({{- lockFiles}}), which may cause inconsistent dependencies and hot-updating issues.',
nativePackageId: 'Native Package ID',
nativeVersion: 'Native Version',
nativeVersionNotFoundGte: 'No native version found >= {{version}}',
nativeVersionNotFoundLte: 'No native version found <= {{version}}',
nativeVersionNotFoundMatch: 'No matching native version found: {{version}}',
nativePackageIdNotFound: 'No native package id found: {{id}}',
noPackagesFound: 'No packages found. (appId: {{appId}})',
offset: 'Offset {{offset}}',
operationComplete: 'Operation complete, bound to {{count}} native versions',
operationSuccess: 'Operation successful',
packageIdRequired: 'Please provide packageId or packageVersion parameter',
packageUploadSuccess:
'Successfully uploaded new hot update package (id: {{id}})',
packing: 'Packing',
pausedStatus: '(Paused)',
platform: 'Platform',
platformPrompt: 'Platform (ios/android/harmony):',
platformQuestion: 'Platform(ios/android/harmony):',
platformRequired: 'Platform must be specified.',
pluginDetectionError: 'error while detecting {{name}} plugin: {{error}}',
pluginDetected: 'detected {{name}} plugin',
ppkPackageGenerated: 'ppk package generated and saved to: {{- output}}',
processingError: 'Error processing file: {{error}}',
processingPackage: 'Processing the package {{count}} ...',
processingStringPool: 'Processing the string pool ...',
publishUsage:
'Usage: pushy publish <ppk file> --platform ios|android|harmony',
rnuVersionNotFound:
'react-native-update: Cannot get the version number. Please run the command in the project directory',
rolloutConfigSet:
'Set {{rollout}}% rollout for OTA update {{version}} on native version(s) {{versions}}',
rolloutRangeError: 'rollout must be an integer between 1-100',
runningHermesc: 'Running hermesc: {{- command}} {{- args}}',
sentryCliNotFound:
'Cannot find Sentry CLI tool, please make sure @sentry/cli is properly installed',
sentryReleaseCreated: 'Sentry release created for version: {{version}}',
totalApps: 'Total {{count}} {{platform}} apps',
totalPackages: 'Total {{count}} packages',
typeStrings: 'Type strings:',
unsupportedPlatform: 'Unsupported platform `{{platform}}`',
uploadBundlePrompt: 'Upload this bundle now?(Y/N)',
uploadingSourcemap: 'Uploading sourcemap',
usageDiff: 'Usage: cresc {{command}} <origin> <next>',
usageParseApk: 'Usage: cresc parseApk <apk file>',
usageParseApp: 'Usage: cresc parseApp <app file>',
usageParseIpa: 'Usage: cresc parseIpa <ipa file>',
usageUnderDevelopment: 'Usage is under development now.',
usageUploadApk: 'Usage: cresc uploadApk <apk file>',
usageUploadApp: 'Usage: cresc uploadApp <app file>',
usageUploadIpa: 'Usage: cresc uploadIpa <ipa file>',
versionBind:
'Bound hot update {{version}} to native version {{nativeVersion}} (id: {{id}})',
welcomeMessage: 'Welcome to Cresc hot update service, {{name}}.',
versionNameQuestion: 'Enter OTA update name:',
versionDescriptionQuestion: 'Enter OTA update description:',
versionMetaInfoQuestion: 'Enter custom meta info:',
updateNativePackageQuestion: 'Bind to native package now?(Y/N)',
unnamed: '(Unnamed)',
dryRun: 'Below is the dry-run result, no actual operation will be performed:',
};
export default {};

View File

@@ -1,126 +1 @@
export default {
addedToGitignore: '已将 {{line}} 添加到 .gitignore',
androidCrunchPngsWarning:
'android 的 crunchPngs 选项似乎尚未禁用(如已禁用则请忽略此提示),这可能导致热更包体积异常增大,具体请参考 https://pushy.reactnative.cn/docs/getting-started.html#%E7%A6%81%E7%94%A8-android-%E7%9A%84-crunch-%E4%BC%98%E5%8C%96 \n',
appId: '应用 id',
appIdMismatchApk:
'appId不匹配当前apk: {{appIdInPkg}}, 当前update.json: {{appId}}',
appIdMismatchApp:
'appId不匹配当前app: {{appIdInPkg}}, 当前update.json: {{appId}}',
appIdMismatchIpa:
'appId不匹配当前ipa: {{appIdInPkg}}, 当前update.json: {{appId}}',
appKeyMismatchApk:
'appKey不匹配当前apk: {{appKeyInPkg}}, 当前update.json: {{appKey}}',
appKeyMismatchApp:
'appKey不匹配当前app: {{appKeyInPkg}}, 当前update.json: {{appKey}}',
appKeyMismatchIpa:
'appKey不匹配当前ipa: {{appKeyInPkg}}, 当前update.json: {{appKey}}',
appName: '应用名称',
appNameQuestion: '应用名称:',
appNotSelected:
'尚未选择应用。请先运行 `pushy selectApp --platform {{platform}}` 来选择应用',
appUploadSuccess:
'已成功上传app原生包id: {{id}}, version: {{version}}, buildTime: {{buildTime}}',
apkUploadSuccess:
'已成功上传apk原生包id: {{id}}, version: {{version}}, buildTime: {{buildTime}}',
boundTo: ', 已绑定:{{name}} ({{id}})',
buildTimeNotFound:
'无法获取此包的编译时间戳。请更新 `react-native-update` 到最新版本后重新打包上传。',
bundleCommandError: '"react-native bundle" 命令退出,代码为 {{code}}。',
bundleNotFound:
'找不到 bundle 文件。请确保此 {{packageType}} 为 release 版本,且 bundle 文件名为默认的 `{{entryFile}}`',
bundlingWithRN: '正在使用 react-native {{version}} 打包',
cancelled: '已取消',
composingSourceMap: '正在生成 source map',
copyFileFailed: '复制文件失败:{{error}}',
copyHarmonyBundleError: '复制 Harmony bundle 错误:{{error}}',
copyingDebugId: '正在复制 debugid',
createAppSuccess: '已成功创建应用id: {{id}}',
deleteFile: '删除 {{- file}}',
deletingFile: '删除 {{- file}}',
enterAppIdQuestion: '输入应用 id:',
enterNativePackageId: '输入原生包 id:',
errorInHarmonyApp: '获取 Harmony 应用入口时出错:{{error}}',
expiredStatus: '(已过期)',
failedToParseIcon: '[警告] 解析图标失败:{{error}}',
failedToParseUpdateJson: '无法解析文件 `update.json`。请手动删除它。',
fileGenerated: '已生成 {{- file}}',
fileSizeExceeded:
'此文件大小 {{fileSize}} , 超出当前额度 {{maxSize}} 。您可以考虑升级付费业务以提升此额度。详情请访问: {{- pricingPageUrl}}',
hermesDisabled: 'Hermes 已禁用',
hermesEnabledCompiling: 'Hermes 已启用,正在编译为 hermes 字节码:\n',
ipaUploadSuccess:
'已成功上传ipa原生包id: {{id}}, version: {{version}}, buildTime: {{buildTime}}',
keyStrings: '键字符串:',
latestVersionTag: '(最新:{{version}}',
lockBestPractice: `
关于 lock 文件的最佳实践:
1. 开发团队中的所有成员应该使用相同的包管理器,维护同一份 lock 文件。
2. 将 lock 文件添加到版本控制中(但不要同时提交多种不同格式的 lock 文件)。
3. 代码审核时应关注 lock 文件的变化。
这样可以最大限度避免因依赖关系不一致而导致的热更异常,也降低供应链攻击等安全隐患。
`,
lockNotFound:
'没有检测到任何 lock 文件,这可能导致依赖关系不一致而使热更异常。',
loggedOut: '已退出登录',
loginExpired: '登录信息已过期,请使用 `pushy login` 命令重新登录',
loginFirst: '尚未登录。\n请在项目目录中运行`pushy login`命令来登录',
multipleLocksFound:
'检测到多种不同格式的锁文件({{- lockFiles}}),这可能导致依赖关系不一致而使热更异常。',
nativePackageId: '原生包 Id',
nativeVersion: '原生版本',
nativeVersionNotFoundGte: '未查询到 >= {{version}} 的原生版本',
nativeVersionNotFoundLte: '未查询到 <= {{version}} 的原生版本',
nativeVersionNotFoundMatch: '未查询到匹配原生版本:{{version}}',
nativePackageIdNotFound: '未查询到原生包 id: {{id}}',
noPackagesFound: '未查询到任何原生包appId: {{appId}}',
offset: '偏移量 {{offset}}',
operationComplete: '操作完成,共已绑定 {{count}} 个原生版本',
operationSuccess: '操作成功',
packageIdRequired: '请提供 packageId 或 packageVersion 参数',
packageUploadSuccess: '已成功上传新热更包id: {{id}}',
packing: '正在打包',
pausedStatus: '(已暂停)',
platform: '平台',
platformPrompt: '平台(ios/android/harmony):',
platformQuestion: '平台(ios/android/harmony):',
platformRequired: '必须指定平台。',
pluginDetectionError: '检测 {{name}} 插件时出错:{{error}}',
pluginDetected: '检测到 {{name}} 插件',
ppkPackageGenerated: 'ppk 热更包已生成并保存到: {{- output}}',
processingError: '处理文件时出错:{{error}}',
processingPackage: '正在处理包 {{count}}...',
processingStringPool: '正在处理字符串池...',
publishUsage:
'使用方法: pushy publish ppk后缀文件 --platform ios|android|harmony',
rnuVersionNotFound:
'react-native-update: 无法获取版本号。请在项目目录中运行命令',
rolloutConfigSet:
'已在原生版本 {{versions}} 上设置灰度发布 {{rollout}}% 热更包 {{version}}',
rolloutRangeError: 'rollout 必须是 1-100 的整数',
runningHermesc: '运行 hermesc{{- command}} {{- args}}',
sentryCliNotFound: '无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli',
sentryReleaseCreated: '已为版本 {{version}} 创建 Sentry release',
totalApps: '共 {{count}} 个 {{platform}} 应用',
totalPackages: '共 {{count}} 个包',
typeStrings: '类型字符串:',
unsupportedPlatform: '无法识别的平台 `{{platform}}`',
uploadBundlePrompt: '是否现在上传此热更包?(Y/N)',
uploadingSourcemap: '正在上传 sourcemap',
usageDiff: '用法pushy {{command}} <origin> <next>',
usageParseApk: '使用方法: pushy parseApk apk后缀文件',
usageParseApp: '使用方法: pushy parseApp app后缀文件',
usageParseIpa: '使用方法: pushy parseIpa ipa后缀文件',
usageUploadApk: '使用方法: pushy uploadApk apk后缀文件',
usageUploadApp: '使用方法: pushy uploadApp app后缀文件',
usageUploadIpa: '使用方法: pushy uploadIpa ipa后缀文件',
versionBind:
'已将热更包 {{version}} 绑定到原生版本 {{nativeVersion}} (id: {{id}})',
welcomeMessage: '欢迎使用 pushy 热更新服务,{{name}}。',
versionNameQuestion: '输入版本名称:',
versionDescriptionQuestion: '输入版本描述:',
versionMetaInfoQuestion: '输入自定义的 meta info:',
updateNativePackageQuestion: '是否现在将此热更应用到原生包上?(Y/N)',
unnamed: '(未命名)',
dryRun: '以下是 dry-run 模拟运行结果,不会实际执行任何操作:',
};
export default {};

View File

@@ -1,50 +1,46 @@
import { get, getAllPackages, post, uploadFile } from './api';
import { get, post, uploadFile } from './api';
import { question, saveToLocal } from './utils';
import { t } from './utils/i18n';
import { getPlatform, getSelectedApp } from './app';
import { checkPlatform, getSelectedApp } from './app';
import { getApkInfo, getIpaInfo, getAppInfo } from './utils';
import Table from 'tty-table';
import { depVersions } from './utils/dep-versions';
import { getCommitInfo } from './utils/git';
import type { Platform } from 'types';
export async function listPackage(appId: string) {
const allPkgs = await getAllPackages(appId);
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
const header = [
{ value: t('nativePackageId') },
{ value: t('nativeVersion') },
];
const header = [{ value: '原生包 Id' }, { value: '原生版本' }];
const rows = [];
for (const pkg of allPkgs) {
for (const pkg of data) {
const { version } = pkg;
let versionInfo = '';
if (version) {
versionInfo = t('boundTo', { name: version.name, id: version.id });
versionInfo = `, 已绑定:${version.name} (${version.id})`;
} else {
// versionInfo = ' (newest)';
}
let output = pkg.name;
if (pkg.status === 'paused') {
output += t('pausedStatus');
output += '(已暂停)';
}
if (pkg.status === 'expired') {
output += t('expiredStatus');
output += '(已过期)';
}
output += versionInfo;
rows.push([pkg.id, output]);
}
console.log(Table(header, rows).render());
console.log(t('totalPackages', { count: allPkgs.length }));
return allPkgs;
console.log(`\n共 ${data.length} 个包`);
return data;
}
export async function choosePackage(appId: string) {
const list = await listPackage(appId);
while (true) {
const id = await question(t('enterNativePackageId'));
const id = await question('输入原生包 id:');
const app = list.find((v) => v.id === Number(id));
if (app) {
return app;
@@ -56,7 +52,7 @@ export const commands = {
uploadIpa: async ({ args }: { args: string[] }) => {
const fn = args[0];
if (!fn || !fn.endsWith('.ipa')) {
throw new Error(t('usageUploadIpa'));
throw new Error('使用方法: pushy uploadIpa ipa后缀文件');
}
const {
versionName,
@@ -67,11 +63,15 @@ export const commands = {
const { appId, appKey } = await getSelectedApp('ios');
if (appIdInPkg && appIdInPkg != appId) {
throw new Error(t('appIdMismatchIpa', { appIdInPkg, appId }));
throw new Error(
`appId不匹配当前ipa: ${appIdInPkg}, 当前update.json: ${appId}`,
);
}
if (appKeyInPkg && appKeyInPkg !== appKey) {
throw new Error(t('appKeyMismatchIpa', { appKeyInPkg, appKey }));
throw new Error(
`appKey不匹配当前ipa: ${appKeyInPkg}, 当前update.json: ${appKey}`,
);
}
const { hash } = await uploadFile(fn);
@@ -81,15 +81,16 @@ export const commands = {
hash,
buildTime,
deps: depVersions,
commit: await getCommitInfo(),
});
saveToLocal(fn, `${appId}/package/${id}.ipa`);
console.log(t('ipaUploadSuccess', { id, version: versionName, buildTime }));
console.log(
`已成功上传ipa原生包id: ${id}, version: ${versionName}, buildTime: ${buildTime}`,
);
},
uploadApk: async ({ args }: { args: string[] }) => {
uploadApk: async ({ args }) => {
const fn = args[0];
if (!fn || !fn.endsWith('.apk')) {
throw new Error(t('usageUploadApk'));
throw new Error('使用方法: pushy uploadApk apk后缀文件');
}
const {
versionName,
@@ -100,11 +101,15 @@ export const commands = {
const { appId, appKey } = await getSelectedApp('android');
if (appIdInPkg && appIdInPkg != appId) {
throw new Error(t('appIdMismatchApk', { appIdInPkg, appId }));
throw new Error(
`appId不匹配当前apk: ${appIdInPkg}, 当前update.json: ${appId}`,
);
}
if (appKeyInPkg && appKeyInPkg !== appKey) {
throw new Error(t('appKeyMismatchApk', { appKeyInPkg, appKey }));
throw new Error(
`appKey不匹配当前apk: ${appKeyInPkg}, 当前update.json: ${appKey}`,
);
}
const { hash } = await uploadFile(fn);
@@ -114,15 +119,16 @@ export const commands = {
hash,
buildTime,
deps: depVersions,
commit: await getCommitInfo(),
});
saveToLocal(fn, `${appId}/package/${id}.apk`);
console.log(t('apkUploadSuccess', { id, version: versionName, buildTime }));
console.log(
`已成功上传apk原生包id: ${id}, version: ${versionName}, buildTime: ${buildTime}`,
);
},
uploadApp: async ({ args }: { args: string[] }) => {
uploadApp: async ({ args }) => {
const fn = args[0];
if (!fn || !fn.endsWith('.app')) {
throw new Error(t('usageUploadApp'));
throw new Error('使用方法: pushy uploadApp app后缀文件');
}
const {
versionName,
@@ -133,11 +139,15 @@ export const commands = {
const { appId, appKey } = await getSelectedApp('harmony');
if (appIdInPkg && appIdInPkg != appId) {
throw new Error(t('appIdMismatchApp', { appIdInPkg, appId }));
throw new Error(
`appId不匹配当前app: ${appIdInPkg}, 当前update.json: ${appId}`,
);
}
if (appKeyInPkg && appKeyInPkg !== appKey) {
throw new Error(t('appKeyMismatchApp', { appKeyInPkg, appKey }));
throw new Error(
`appKey不匹配当前app: ${appKeyInPkg}, 当前update.json: ${appKey}`,
);
}
const { hash } = await uploadFile(fn);
@@ -147,34 +157,37 @@ export const commands = {
hash,
buildTime,
deps: depVersions,
commit: await getCommitInfo(),
});
saveToLocal(fn, `${appId}/package/${id}.app`);
console.log(t('appUploadSuccess', { id, version: versionName, buildTime }));
console.log(
`已成功上传app原生包id: ${id}, version: ${versionName}, buildTime: ${buildTime}`,
);
},
parseApp: async ({ args }: { args: string[] }) => {
parseApp: async ({ args }) => {
const fn = args[0];
if (!fn || !fn.endsWith('.app')) {
throw new Error(t('usageParseApp'));
throw new Error('使用方法: pushy parseApp app后缀文件');
}
console.log(await getAppInfo(fn));
},
parseIpa: async ({ args }: { args: string[] }) => {
parseIpa: async ({ args }) => {
const fn = args[0];
if (!fn || !fn.endsWith('.ipa')) {
throw new Error(t('usageParseIpa'));
throw new Error('使用方法: pushy parseIpa ipa后缀文件');
}
console.log(await getIpaInfo(fn));
},
parseApk: async ({ args }: { args: string[] }) => {
parseApk: async ({ args }) => {
const fn = args[0];
if (!fn || !fn.endsWith('.apk')) {
throw new Error(t('usageParseApk'));
throw new Error('使用方法: pushy parseApk apk后缀文件');
}
console.log(await getApkInfo(fn));
},
packages: async ({ options }: { options: { platform: Platform } }) => {
const platform = await getPlatform(options.platform);
packages: async ({ options }) => {
const platform = checkPlatform(
options.platform || (await question('平台(ios/android/harmony):')),
);
const { appId } = await getSelectedApp(platform);
await listPackage(appId);
},

View File

@@ -8,15 +8,3 @@ export interface Session {
}
export type Platform = 'ios' | 'android' | 'harmony';
export interface Package {
id: string;
name: string;
}
export interface Version {
id: string;
hash: string;
name: string;
packages?: Package[];
}

View File

@@ -1,7 +1,6 @@
import { question } from './utils';
import { post, get, replaceSession, saveSession, closeSession } from './api';
import crypto from 'crypto';
import { t } from './utils/i18n';
import crypto from 'node:crypto';
function md5(str: string) {
return crypto.createHash('md5').update(str).digest('hex');
@@ -17,11 +16,11 @@ export const commands = {
});
replaceSession({ token });
await saveSession();
console.log(t('welcomeMessage', { name: info.name }));
console.log(`欢迎使用 pushy 热更新服务, ${info.name}.`);
},
logout: async () => {
await closeSession();
console.log(t('loggedOut'));
console.log('已退出登录');
},
me: async () => {
const me = await get('/user/me');

View File

@@ -1,35 +0,0 @@
import fs from 'fs';
// import path from 'path';
import { credentialFile, tempDir } from './constants';
import { t } from './i18n';
export function addGitIgnore() {
const shouldIgnore = [credentialFile, tempDir];
const gitignorePath = '.gitignore';
if (!fs.existsSync(gitignorePath)) {
return;
}
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
const gitignoreLines = gitignoreContent.split('\n');
for (const line of gitignoreLines) {
const index = shouldIgnore.indexOf(line.trim());
if (index !== -1) {
shouldIgnore.splice(index, 1);
}
}
if (shouldIgnore.length > 0) {
gitignoreLines.push('# react-native-update');
for (const line of shouldIgnore) {
gitignoreLines.push(line);
console.log(t('addedToGitignore', { line }));
}
fs.writeFileSync(gitignorePath, gitignoreLines.join('\n'));
}
}

View File

@@ -4,19 +4,17 @@ const AppParser = require('./app');
const supportFileTypes = ['ipa', 'apk', 'app'];
class AppInfoParser {
file: string | File;
parser: any;
/**
* parser for parsing .ipa or .apk file
* @param {String | File} file // file's path in Node, instance of File in Browser
* @param {String | File | Blob} file // file's path in Node, instance of File or Blob in Browser
*/
constructor(file: string | File) {
constructor(file) {
if (!file) {
throw new Error(
"Param miss: file(file's path in Node, instance of File in browser).",
"Param miss: file(file's path in Node, instance of File or Blob in browser).",
);
}
const splits = (typeof file === 'string' ? file : file.name).split('.');
const splits = (file.name || file).split('.');
const fileType = splits[splits.length - 1].toLowerCase();
if (!supportFileTypes.includes(fileType)) {
throw new Error(
@@ -42,4 +40,4 @@ class AppInfoParser {
}
}
export default AppInfoParser;
module.exports = AppInfoParser;

View File

@@ -30,7 +30,7 @@ function mapInfoResource (apkInfo, resourceMap) {
iteratorObj(apkInfo)
return apkInfo
function iteratorObj (obj) {
for (const i in obj) {
for (var i in obj) {
if (isArray(obj[i])) {
iteratorArray(obj[i])
} else if (isObject(obj[i])) {

View File

@@ -1,6 +1,6 @@
const Unzip = require('isomorphic-unzip');
const { isBrowser, decodeNullUnicode } = require('./utils');
import { enumZipEntries, readEntry } from '../../bundle';
import { enumZipEntries, readEntire } from '../../bundle';
class Zip {
constructor(file) {
@@ -53,7 +53,7 @@ class Zip {
let originSource;
await enumZipEntries(this.file, (entry, zipFile) => {
if (regex.test(entry.fileName)) {
return readEntry(entry, zipFile).then((v) => (originSource = v));
return readEntire(entry, zipFile).then((v) => (originSource = v));
}
});
return originSource;

View File

@@ -1,89 +0,0 @@
import fs from 'fs';
import path from 'path';
import { t } from './i18n';
const lockFiles = [
'package-lock.json',
'yarn.lock',
'pnpm-lock.yaml',
'bun.lockb',
'bun.lock',
];
// Function to check if a package.json has a workspaces field
function hasWorkspaces(dir: string): boolean {
const pkgPath = path.join(dir, 'package.json');
if (fs.existsSync(pkgPath)) {
try {
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
return !!pkg.workspaces;
} catch (e) {
// Ignore parsing errors
}
}
return false;
}
// Helper function to find lock files in a specific directory
function findLockFilesInDir(directory: string): string[] {
const found: string[] = [];
for (const file of lockFiles) {
const filePath = path.join(directory, file);
if (fs.existsSync(filePath)) {
found.push(filePath);
}
}
return found;
}
export function checkLockFiles() {
const cwd = process.cwd();
let searchDir = cwd;
let foundLockFiles = findLockFilesInDir(searchDir);
// If no lock file in cwd, try to find monorepo root and check there
if (foundLockFiles.length === 0) {
// Search upwards for package.json with workspaces
let currentDir = path.dirname(cwd); // Start searching from parent
let projectRootDir: string | null = null;
while (true) {
if (hasWorkspaces(currentDir)) {
projectRootDir = currentDir;
break;
}
const parentDir = path.dirname(currentDir);
if (parentDir === currentDir) {
// Reached the filesystem root
break;
}
currentDir = parentDir;
}
// If a potential root was found, switch search directory and re-check
if (projectRootDir) {
searchDir = projectRootDir;
foundLockFiles = findLockFilesInDir(searchDir);
}
// If no projectRootDir found, foundLockFiles remains empty and searchDir remains cwd
}
// Handle results based on findings in the final searchDir
if (foundLockFiles.length === 1) {
// Successfully found one lock file in the determined searchDir
return;
}
if (foundLockFiles.length > 1) {
// Found multiple lock files in the determined searchDir
console.warn(t('lockBestPractice'));
throw new Error(
t('multipleLocksFound', { lockFiles: foundLockFiles.join(', ') }),
);
}
// If we reach here, foundLockFiles.length === 0
console.warn(t('lockBestPractice'));
// Warn instead of throwing an error if no lock file is found
console.warn(t('lockNotFound'));
}

View File

@@ -1,5 +1,4 @@
import { plugins } from './plugin-config';
import { t } from './i18n';
interface BundleParams {
sentry: boolean;
@@ -18,10 +17,10 @@ export async function checkPlugins(): Promise<BundleParams> {
const isEnabled = await plugin.detect();
if (isEnabled && plugin.bundleParams) {
Object.assign(params, plugin.bundleParams);
console.log(t('pluginDetected', { name: plugin.name }));
console.log(`检测到 ${plugin.name} 插件,应用相应打包配置`);
}
} catch (err) {
console.warn(t('pluginDetectionError', { name: plugin.name, error: err }));
console.warn(`检测 ${plugin.name} 插件时出错:`, err);
}
}

View File

@@ -1,6 +1,8 @@
import path from 'path';
import path from 'node:path';
const scriptName = path.basename(process.argv[1]) as 'cresc' | 'pushy';
const scriptName: 'cresc' | 'pushy' = path.basename(process.argv[1]) as
| 'cresc'
| 'pushy';
export const IS_CRESC = scriptName === 'cresc';
export const credentialFile = IS_CRESC ? '.cresc.token' : '.update';
@@ -9,7 +11,3 @@ export const tempDir = IS_CRESC ? '.cresc.temp' : '.pushy';
export const pricingPageUrl = IS_CRESC
? 'https://cresc.dev/pricing'
: 'https://pushy.reactnative.cn/pricing.html';
export const defaultEndpoint = IS_CRESC
? 'https://api.cresc.dev'
: 'https://update.reactnative.cn/api';

View File

@@ -1,21 +1,19 @@
const currentPackage = require(`${process.cwd()}/package.json`);
const depKeys = Object.keys(currentPackage.dependencies);
const devDepKeys = Object.keys(currentPackage.devDependencies);
const dedupedDeps = [...new Set([...depKeys, ...devDepKeys])];
const _depVersions: Record<string, string> = {};
if (currentPackage) {
const depKeys = currentPackage.dependencies ? Object.keys(currentPackage.dependencies) : [];
const devDepKeys = currentPackage.devDependencies ? Object.keys(currentPackage.devDependencies) : [];
const dedupedDeps = [...new Set([...depKeys, ...devDepKeys])];
for (const dep of dedupedDeps) {
try {
const packageJsonPath = require.resolve(`${dep}/package.json`, {
paths: [process.cwd()],
});
const version = require(packageJsonPath).version;
_depVersions[dep] = version;
} catch (e) {}
}
for (const dep of dedupedDeps) {
try {
const packageJsonPath = require.resolve(`${dep}/package.json`, {
paths: [process.cwd()],
});
const version = require(packageJsonPath).version;
_depVersions[dep] = version;
} catch (e) {}
}
export const depVersions = Object.keys(_depVersions)

View File

@@ -1,50 +0,0 @@
import git from 'isomorphic-git';
import fs from 'fs';
import path from 'path';
export interface CommitInfo {
hash: string;
message: string;
author: string;
timestamp: string;
origin: string;
}
function findGitRoot(dir = process.cwd()) {
const gitRoot = fs.readdirSync(dir).find((dir) => dir === '.git');
if (gitRoot) {
// console.log({ gitRoot });
return path.join(dir, gitRoot);
}
const parentDir = path.dirname(dir);
if (parentDir === dir) {
return null;
}
return findGitRoot(parentDir);
}
const gitRoot = findGitRoot();
export async function getCommitInfo(): Promise<CommitInfo | undefined> {
if (!gitRoot) {
return;
}
try {
const remotes = await git.listRemotes({ fs, gitdir: gitRoot });
const origin =
remotes.find((remote) => remote.remote === 'origin') || remotes[0];
const { commit, oid } = (
await git.log({ fs, gitdir: gitRoot, depth: 1 })
)[0];
return {
hash: oid,
message: commit.message,
author: commit.author.name || commit.committer.name,
timestamp: String(commit.committer.timestamp),
origin: origin?.url,
};
} catch (error) {
console.error(error);
return;
}
}

View File

@@ -1,37 +0,0 @@
import i18next from 'i18next';
import en from '../locales/en';
import zh from '../locales/zh';
import { IS_CRESC } from './constants';
i18next.init({
lng: IS_CRESC ? 'en' : 'zh',
// debug: process.env.NODE_ENV !== 'production',
// debug: true,
resources: {
en: {
translation: en,
},
zh: {
translation: zh,
},
},
interpolation: {
escapeValue: false,
},
});
declare module 'i18next' {
// Extend CustomTypeOptions
interface CustomTypeOptions {
// custom namespace type, if you changed it
defaultNS: 'en';
// custom resources type
resources: {
en: typeof en;
zh: typeof zh;
};
// other
}
}
export const t = i18next.t;

View File

@@ -1,17 +1,16 @@
import fs from 'fs-extra';
import os from 'os';
import path from 'path';
import os from 'node:os';
import path from 'node:path';
import pkg from '../../package.json';
import AppInfoParser from './app-info-parser';
import { satisfies } from 'compare-versions';
import semverSatisfies from 'semver/functions/satisfies';
import chalk from 'chalk';
import latestVersion from '../utils/latest-version';
import latestVersion from '@badisi/latest-version';
import { checkPlugins } from './check-plugin';
import { read } from 'read';
import { IS_CRESC, tempDir } from './constants';
import { tempDir } from './constants';
import { depVersions } from './dep-versions';
import { t } from './i18n';
export async function question(query: string, password?: boolean) {
if (NO_INTERACTIVE) {
@@ -47,10 +46,7 @@ export async function getApkInfo(fn: string) {
);
if (!bundleFile) {
throw new Error(
t('bundleNotFound', {
packageType: 'apk',
entryFile: 'index.android.bundle',
}),
'找不到bundle文件。请确保此apk为release版本且bundle文件名为默认的index.android.bundle',
);
}
const updateJsonFile = await appInfoParser.parser.getEntry(
@@ -70,22 +66,21 @@ export async function getApkInfo(fn: string) {
}
}
if (buildTime == 0) {
throw new Error(t('buildTimeNotFound'));
throw new Error(
'无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。',
);
}
return { versionName, buildTime, ...appCredential };
}
export async function getAppInfo(fn: string) {
export async function getAppInfo(fn) {
const appInfoParser = new AppInfoParser(fn);
const bundleFile = await appInfoParser.parser.getEntryFromHarmonyApp(
/rawfile\/bundle.harmony.js/,
);
if (!bundleFile) {
throw new Error(
t('bundleNotFound', {
packageType: 'app',
entryFile: 'bundle.harmony.js',
}),
'找不到bundle文件。请确保此app为release版本且bundle文件名为默认的bundle.harmony.js',
);
}
const updateJsonFile = await appInfoParser.parser.getEntryFromHarmonyApp(
@@ -98,7 +93,7 @@ export async function getAppInfo(fn: string) {
const metaJsonFile = await appInfoParser.parser.getEntryFromHarmonyApp(
/rawfile\/meta.json/,
);
let metaData: Record<string, any> = {};
let metaData = {};
if (metaJsonFile) {
metaData = JSON.parse(metaJsonFile.toString());
}
@@ -108,7 +103,9 @@ export async function getAppInfo(fn: string) {
buildTime = pushy_build_time;
}
if (buildTime == 0) {
throw new Error(t('buildTimeNotFound'));
throw new Error(
'无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。',
);
}
return { versionName, buildTime, ...appCredential };
}
@@ -120,10 +117,7 @@ export async function getIpaInfo(fn: string) {
);
if (!bundleFile) {
throw new Error(
t('bundleNotFound', {
packageType: 'ipa',
entryFile: 'main.jsbundle',
}),
'找不到bundle文件。请确保此ipa为release版本且bundle文件名为默认的main.jsbundle',
);
}
const updateJsonFile = await appInfoParser.parser.getEntry(
@@ -145,7 +139,9 @@ export async function getIpaInfo(fn: string) {
);
}
if (!buildTimeTxtBuffer) {
throw new Error(t('buildTimeNotFound'));
throw new Error(
'无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。',
);
}
const buildTime = buildTimeTxtBuffer.toString().replace('\n', '');
return { versionName, buildTime, ...appCredential };
@@ -162,7 +158,7 @@ export function saveToLocal(originPath: string, destName: string) {
async function getLatestVersion(pkgNames: string[]) {
return latestVersion(pkgNames, {
// useCache: true,
useCache: true,
requestOptions: {
timeout: 2000,
},
@@ -172,48 +168,40 @@ async function getLatestVersion(pkgNames: string[]) {
}
export async function printVersionCommand() {
let [latestRnuCliVersion, latestRnuVersion] = await getLatestVersion([
let [latestPushyCliVersion, latestPushyVersion] = await getLatestVersion([
'react-native-update-cli',
'react-native-update',
]);
latestRnuCliVersion = latestRnuCliVersion
? ` ${t('latestVersionTag', {
version: chalk.green(latestRnuCliVersion),
})}`
latestPushyCliVersion = latestPushyCliVersion
? ` (最新:${chalk.green(latestPushyCliVersion)}`
: '';
console.log(`react-native-update-cli: ${pkg.version}${latestRnuCliVersion}`);
const rnuVersion = depVersions['react-native-update'];
if (rnuVersion) {
latestRnuVersion = latestRnuVersion
? ` ${t('latestVersionTag', { version: chalk.green(latestRnuVersion) })}`
: '';
console.log(`react-native-update: ${rnuVersion}${latestRnuVersion}`);
if (IS_CRESC) {
if (satisfies(rnuVersion, '<10.27.0')) {
console.error(
'Unsupported version, please update to the latest version: npm i react-native-update@latest',
);
process.exit(1);
}
} else {
if (satisfies(rnuVersion, '<8.5.2')) {
console.warn(
`当前版本已不再支持,请至少升级到 v8 的最新小版本后重新打包(代码无需改动): npm i react-native-update@8 .
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
);
} else if (satisfies(rnuVersion, '9.0.0 - 9.2.1')) {
console.warn(
`当前版本已不再支持,请至少升级到 v9 的最新小版本后重新打包(代码无需改动,可直接热更): npm i react-native-update@9 .
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
);
} else if (satisfies(rnuVersion, '10.0.0 - 10.17.0')) {
console.warn(
'当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10',
);
}
console.log(
`react-native-update-cli: ${pkg.version}${latestPushyCliVersion}`,
);
let pushyVersion = '';
pushyVersion = depVersions['react-native-update'];
latestPushyVersion = latestPushyVersion
? ` (最新:${chalk.green(latestPushyVersion)}`
: '';
console.log(`react-native-update: ${pushyVersion}${latestPushyVersion}`);
if (pushyVersion) {
if (semverSatisfies(pushyVersion, '<8.5.2')) {
console.warn(
`当前版本已不再支持,请至少升级到 v8 的最新小版本后重新打包(代码无需改动): npm i react-native-update@8 .
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
);
} else if (semverSatisfies(pushyVersion, '9.0.0 - 9.2.1')) {
console.warn(
`当前版本已不再支持,请至少升级到 v9 的最新小版本后重新打包(代码无需改动,可直接热更: npm i react-native-update@9 .
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
);
} else if (semverSatisfies(pushyVersion, '10.0.0 - 10.17.0')) {
console.warn(
'当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10',
);
}
} else {
console.log(t('rnuVersionNotFound'));
console.log('react-native-update: 无法获取版本号,请在项目目录中运行命令');
}
}

View File

@@ -1,443 +0,0 @@
import {
blue,
bold,
cyan,
gray,
green,
italic,
magenta,
red,
reset,
strip,
underline,
yellow,
} from '@colors/colors/safe';
import { existsSync, readFileSync } from 'fs';
import { dirname } from 'path';
import latestVersion, {
type Package,
type PackageJson,
type LatestVersionPackage,
type LatestVersionOptions,
} from '.';
import semverMajor from 'semver/functions/major';
import semverDiff from 'semver/functions/diff';
interface TableColumn {
label: string;
attrName: keyof TableRow;
align: 'left' | 'center' | 'right';
maxLength: number;
items: string[];
}
type TableRowGroup =
| 'patch'
| 'minor'
| 'major'
| 'majorVersionZero'
| 'unknown';
interface TableRow {
name: string;
location: string;
installed: string;
tagOrRange: string;
separator: string;
wanted: string;
latest: string;
group: TableRowGroup;
}
const colorizeDiff = (from: string, to: string): string => {
const toParts = to.split('.');
const diffIndex = from.split('.').findIndex((part, i) => part !== toParts[i]);
if (diffIndex !== -1) {
let color = magenta;
if (toParts[0] !== '0') {
color = diffIndex === 0 ? red : diffIndex === 1 ? cyan : green;
}
const start = toParts.slice(0, diffIndex).join('.');
const mid = diffIndex === 0 ? '' : '.';
const end = color(toParts.slice(diffIndex).join('.'));
return `${start}${mid}${end}`;
}
return to;
};
const columnCellRenderer = (column: TableColumn, row: TableRow): string => {
let text = row[column.attrName];
const gap =
text.length < column.maxLength
? ' '.repeat(column.maxLength - text.length)
: '';
switch (column.attrName) {
case 'name':
text = yellow(text);
break;
case 'installed':
case 'separator':
text = blue(text);
break;
case 'location':
case 'tagOrRange':
text = gray(text);
break;
case 'wanted':
text = colorizeDiff(row.installed, text);
break;
case 'latest':
if (text !== row.wanted) {
text = colorizeDiff(row.installed, text);
}
break;
default:
break;
}
return column.align === 'right' ? `${gap}${text}` : `${text}${gap}`;
};
const columnHeaderRenderer = (column: TableColumn): string => {
const text = column.label;
const gap =
text.length < column.maxLength
? ' '.repeat(column.maxLength - text.length)
: '';
return column.align === 'right'
? `${gap}${underline(text)}`
: `${underline(text)}${gap}`;
};
const drawBox = (
lines: string[],
color = yellow,
horizontalPadding = 3,
): void => {
const maxLineWidth = lines.reduce(
(max, row) => Math.max(max, strip(row).length),
0,
);
console.log(color(`${'─'.repeat(maxLineWidth + horizontalPadding * 2)}`));
lines.forEach((row) => {
const padding = ' '.repeat(horizontalPadding);
const fullRow = `${row}${' '.repeat(maxLineWidth - strip(row).length)}`;
console.log(
`${color('│')}${padding}${reset(fullRow)}${padding}${color('│')}`,
);
});
console.log(color(`${'─'.repeat(maxLineWidth + horizontalPadding * 2)}`));
};
const getTableColumns = (rows: TableRow[]): TableColumn[] => {
const columns: TableColumn[] = [
{
label: 'Package',
attrName: 'name',
align: 'left',
maxLength: 0,
items: [],
},
{
label: 'Location',
attrName: 'location',
align: 'left',
maxLength: 0,
items: [],
},
{
label: 'Installed',
attrName: 'installed',
align: 'right',
maxLength: 0,
items: [],
},
{
label: '',
attrName: 'separator',
align: 'center',
maxLength: 0,
items: [],
},
{
label: 'Range',
attrName: 'tagOrRange',
align: 'right',
maxLength: 0,
items: [],
},
{
label: '',
attrName: 'separator',
align: 'center',
maxLength: 0,
items: [],
},
{
label: 'Wanted',
attrName: 'wanted',
align: 'right',
maxLength: 0,
items: [],
},
{
label: 'Latest',
attrName: 'latest',
align: 'right',
maxLength: 0,
items: [],
},
];
rows.forEach((row) => {
columns.forEach((column) => {
column.maxLength = Math.max(
column.label.length,
column.maxLength,
row[column.attrName].length || 0,
);
});
});
return columns;
};
const getTableRows = (updates: LatestVersionPackage[]): TableRow[] => {
return updates.reduce<TableRow[]>((all, pkg) => {
const {
name,
latest,
local,
globalNpm,
globalYarn,
wantedTagOrRange,
updatesAvailable,
} = pkg;
const getGroup = (a?: string, b?: string): TableRowGroup => {
if (b && semverMajor(b) === 0) {
return 'majorVersionZero';
} else if (a && b) {
const releaseType = semverDiff(a, b) ?? '';
if (['major', 'premajor', 'prerelease'].includes(releaseType)) {
return 'major';
} else if (['minor', 'preminor'].includes(releaseType)) {
return 'minor';
} else if (['patch', 'prepatch'].includes(releaseType)) {
return 'patch';
}
}
return 'unknown';
};
const add = (
group: TableRowGroup,
location: string,
installed?: string,
wanted?: string,
) =>
all.push({
name: ' ' + name,
location,
installed: installed ?? 'unknown',
latest: latest ?? 'unknown',
tagOrRange: wantedTagOrRange ?? 'unknown',
separator: '→',
wanted: wanted ?? 'unknown',
group,
});
if (updatesAvailable) {
if (updatesAvailable.local) {
add(
getGroup(local, updatesAvailable.local),
'local',
local,
updatesAvailable.local,
);
}
if (updatesAvailable.globalNpm) {
add(
getGroup(globalNpm, updatesAvailable.globalNpm),
'NPM global',
globalNpm,
updatesAvailable.globalNpm,
);
}
if (updatesAvailable.globalYarn) {
add(
getGroup(globalYarn, updatesAvailable.globalYarn),
'YARN global',
globalYarn,
updatesAvailable.globalYarn,
);
}
} else {
if (local && local !== latest) {
add(getGroup(local, latest), 'local', local, pkg.wanted);
}
if (globalNpm && globalNpm !== latest) {
add(getGroup(globalNpm, latest), 'NPM global', globalNpm, pkg.wanted);
}
if (globalYarn && globalYarn !== latest) {
add(
getGroup(globalYarn, latest),
'YARN global',
globalYarn,
pkg.wanted,
);
}
if (!local && !globalNpm && !globalYarn) {
add('unknown', 'unknown', 'unknown', pkg.wanted);
}
}
return all;
}, []);
};
const displayTable = (latestVersionPackages: LatestVersionPackage[]): void => {
const updates = latestVersionPackages.filter((pkg) => pkg.updatesAvailable);
if (updates.length) {
const rows = getTableRows(updates);
const hasUpdates = rows.some((row) => row.installed !== 'unknown');
const columns = getTableColumns(rows);
const columnGap = 2;
const getGroupLines = (
groupType: TableRowGroup,
color: (str: string) => string,
title: string,
description?: string,
): string[] => {
const items = rows
.filter((row) => row.group === groupType)
.sort((a, b) => (a.name > b.name ? 1 : -1));
return !items.length
? []
: [
'',
color(`${bold(title)} ${italic(`(${description})`)}`),
...items.map((row) =>
columns
.map((column) => columnCellRenderer(column, row))
.join(' '.repeat(columnGap)),
),
];
};
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
drawBox(
[
'',
hasUpdates ? yellow('Important updates are available.') : undefined,
hasUpdates ? '' : undefined,
columns.map(columnHeaderRenderer).join(' '.repeat(columnGap)),
...getGroupLines(
'patch',
green,
'Patch',
'backwards-compatible bug fixes',
),
...getGroupLines(
'minor',
cyan,
'Minor',
'backwards-compatible features',
),
...getGroupLines(
'major',
red,
'Major',
'potentially breaking API changes',
),
...getGroupLines(
'majorVersionZero',
magenta,
'Major version zero',
'not stable, anything may change',
),
...getGroupLines('unknown', blue, 'Missing', 'not installed'),
'',
].filter((line) => line !== undefined) as string[],
);
} else {
console.log(green('🎉 Packages are up-to-date'));
}
};
const checkVersions = async (
packages: Package | Package[] | PackageJson,
skipMissing: boolean,
options: LatestVersionOptions = { useCache: true },
): Promise<void> => {
const ora = (await import('ora')).default;
const spinner = ora({ text: cyan('Checking versions...') });
spinner.start();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
let latestVersionPackages: LatestVersionPackage[] = await latestVersion(
packages,
options,
);
if (skipMissing) {
latestVersionPackages = latestVersionPackages.filter(
(pkg) => pkg.local ?? pkg.globalNpm ?? pkg.globalYarn,
);
}
spinner.stop();
displayTable(latestVersionPackages);
};
void (async () => {
let args = process.argv.slice(2);
const skipMissing = args.includes('--skip-missing');
// Remove any options from the arguments
args = args.filter((arg) => !arg.startsWith('-'));
// If argument is a package.json file
if (args.length === 1 && args[0].endsWith('package.json')) {
if (existsSync(args[0])) {
process.chdir(dirname(args[0]));
await checkVersions(
JSON.parse(readFileSync(args[0]).toString()) as PackageJson,
skipMissing,
);
} else {
console.log(cyan('No package.json file were found'));
}
}
// else..
else {
// Check if a local package.json file exists
let localPkgJson: PackageJson | undefined;
if (existsSync('package.json')) {
localPkgJson = JSON.parse(readFileSync('package.json').toString());
}
// Check given arguments
if (args.length) {
// Map arguments with any range that could be found in local package.json
args = args.map((arg) => {
if (localPkgJson?.dependencies?.[arg]) {
return `${arg}@${localPkgJson.dependencies?.[arg]}`;
}
if (localPkgJson?.devDependencies?.[arg]) {
return `${arg}@${localPkgJson.devDependencies?.[arg]}`;
}
if (localPkgJson?.peerDependencies?.[arg]) {
return `${arg}@${localPkgJson.peerDependencies?.[arg]}`;
}
return arg;
});
await checkVersions(args, skipMissing);
}
// ...else check the local package.json if any
else if (localPkgJson) {
await checkVersions(localPkgJson, skipMissing);
}
// ...else do nothing
else {
console.log(cyan('No packages were found'));
}
}
})();

View File

@@ -1,497 +0,0 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import type {
RequestOptions as HttpRequestOptions,
Agent,
IncomingMessage,
} from 'http';
import type { RequestOptions as HttpsRequestOptions } from 'https';
import { join, dirname, resolve as pathResolve, parse } from 'path';
import { npm, yarn } from 'global-dirs';
import { homedir } from 'os';
import { URL } from 'url';
import getRegistryUrl from 'registry-auth-token/registry-url';
import registryAuthToken from 'registry-auth-token';
import maxSatisfying from 'semver/ranges/max-satisfying';
import gt from 'semver/functions/gt';
interface RegistryVersions {
/**
* The latest version of the package found on the registry (if found).
*/
latest?: string;
/**
* The next version of the package found on the registry (if found).
*/
next?: string;
/**
* The latest version of the package found on the registry and satisfied by the wanted tag or version range.
*/
wanted?: string;
}
interface InstalledVersions {
/**
* The current local installed version of the package (if installed).
*/
local?: string;
/**
* The current npm global installed version of the package (if installed).
*/
globalNpm?: string;
/**
* The current yarn global installed version of the package (if installed).
*/
globalYarn?: string;
}
interface LatestVersionPackage extends InstalledVersions, RegistryVersions {
/**
* The name of the package.
*/
name: string;
/**
* The tag or version range that was provided (if provided).
* @default "latest"
*/
wantedTagOrRange?: string;
/**
* Whether the local or global installed versions (if any) could be upgraded or not, based on the wanted version.
*/
updatesAvailable:
| {
local: string | false;
globalNpm: string | false;
globalYarn: string | false;
}
| false;
/**
* Any error that might have occurred during the process.
*/
error?: Error;
}
interface RequestOptions {
readonly ca?: string | Buffer | Array<string | Buffer>;
readonly rejectUnauthorized?: boolean;
readonly agent?: Agent | boolean;
readonly timeout?: number;
}
interface LatestVersionOptions {
/**
* Awaiting the api to return might take time, depending on the network, and might impact your package loading performance.
* You can use the cache mechanism to improve load performance and reduce unnecessary network requests.
* If `useCache` is not supplied, the api will always check for updates and wait for every requests to return before returning itself.
* If `useCache` is used, the api will always returned immediately, with either (for each provided packages):
* 1) a latest/next version available if a cache was found
* 2) no latest/next version available if no cache was found - in such case updates will be fetched in the background and a cache will
* be created for each provided packages and made available for the next call to the api.
* @default false
*/
readonly useCache?: boolean;
/**
* How long the cache for the provided packages should be used before being refreshed (in milliseconds).
* If `useCache` is not supplied, this option has no effect.
* If `0` is used, this will force the cache to refresh immediately:
* 1) The api will returned immediately (without any latest nor next version available for the provided packages)
* 2) New updates will be fetched in the background
* 3) The cache for each provided packages will be refreshed and made available for the next call to the api
* @default ONE_DAY
*/
readonly cacheMaxAge?: number;
/**
* A JavaScript package registry url that implements the CommonJS Package Registry specification.
* @default "Looks at any registry urls in the .npmrc file or fallback to the default npm registry instead"
* @example <caption>.npmrc</caption>
* registry = 'https://custom-registry.com/'
* @pkgscope:registry = 'https://custom-registry.com/'
*/
readonly registryUrl?: string;
/**
* Set of options to be passed down to Node.js http/https request.
* @example <caption>Behind a proxy with self-signed certificate</caption>
* { ca: [ fs.readFileSync('proxy-cert.pem') ] }
* @example <caption>Bypassing certificate validation</caption>
* { rejectUnauthorized: false }
*/
readonly requestOptions?: RequestOptions;
}
interface LatestVersion {
/**
* Get latest versions of packages from of a package json like object.
* @param {PackageJson} item - A package json like object (with dependencies, devDependencies and peerDependencies attributes).
* @example { dependencies: { 'npm': 'latest' }, devDependencies: { 'npm': '1.3.2' }, peerDependencies: { '@scope/name': '^5.0.2' } }
* @param {LatestVersionOptions} [options] - An object optionally specifying the use of the cache, the max age of the cache, the registry url and the http or https options.
* If `useCache` is not supplied, the default of `false` is used.
* If `cacheMaxAge` is not supplied, the default of `one day` is used.
* If `registryUrl` is not supplied, the default from `.npmrc` is used or a fallback to the `npm registry url` instead.
* @returns {Promise<LatestVersionPackage[]>}
*/
(item: PackageJson, options?: LatestVersionOptions): Promise<
LatestVersionPackage[]
>;
/**
* Get latest version of a single package.
* @param {Package} item - A single package object (represented by a string that should match the following format: `${'@' | ''}${string}@${string}`)
* @example 'npm', 'npm@1.3.2', '@scope/name@^5.0.2'
* @param {LatestVersionOptions} [options] - An object optionally specifying the use of the cache, the max age of the cache, the registry url and the http or https options.
* If `useCache` is not supplied, the default of `false` is used.
* If `cacheMaxAge` is not supplied, the default of `one day` is used.
* If `registryUrl` is not supplied, the default from `.npmrc` is used or a fallback to the npm registry url instead.
* @returns {Promise<LatestVersionPackage>}
*/
(
item: Package,
options?: LatestVersionOptions,
): Promise<LatestVersionPackage>;
/**
* Get latest versions of a collection of packages.
* @param {Package[]} items - A collection of package object (represented by a string that should match the following format: `${'@' | ''}${string}@${string}`)
* @example ['npm', 'npm@1.3.2', '@scope/name@^5.0.2']
* @param {LatestVersionOptions} [options] - An object optionally specifying the use of the cache, the max age of the cache, the registry url and the http or https options.
* If `useCache` is not supplied, the default of `false` is used.
* If `cacheMaxAge` is not supplied, the default of `one day` is used.
* If `registryUrl` is not supplied, the default from `.npmrc` is used or a fallback to the npm registry url instead.
* @returns {Promise<LatestVersionPackage[]>}
*/
(items: Package[], options?: LatestVersionOptions): Promise<
LatestVersionPackage[]
>; // eslint-disable-line @typescript-eslint/unified-signatures
}
type PackageRange = `${'@' | ''}${string}@${string}`;
type Package = PackageRange | string; // eslint-disable-line @typescript-eslint/no-redundant-type-constituents
type PackageJsonDependencies = Record<string, string>;
type PackageJson = Record<string, any> &
(
| {
dependencies: PackageJsonDependencies;
}
| {
devDependencies: PackageJsonDependencies;
}
| {
peerDependencies: PackageJsonDependencies;
}
);
/**
* @internal
*/
interface PackageMetadata {
name: string;
lastUpdateDate: number;
versions: string[];
distTags: Record<string, string>;
}
export const ONE_DAY = 1000 * 60 * 60 * 24; // eslint-disable-line @typescript-eslint/naming-convention
const isPackageJson = (obj: any): obj is PackageJson => {
return (
(obj as PackageJson).dependencies !== undefined ||
(obj as PackageJson).devDependencies !== undefined ||
(obj as PackageJson).peerDependencies !== undefined
);
};
const downloadMetadata = (
pkgName: string,
options?: LatestVersionOptions,
): Promise<PackageMetadata> => {
return new Promise((resolve, reject) => {
const i = pkgName.indexOf('/');
const pkgScope = i !== -1 ? pkgName.slice(0, i) : '';
const registryUrl = options?.registryUrl ?? getRegistryUrl(pkgScope);
const pkgUrl = new URL(
encodeURIComponent(pkgName).replace(/^%40/, '@'),
registryUrl,
);
let requestOptions: HttpRequestOptions | HttpsRequestOptions = {
headers: {
accept:
'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*',
},
host: pkgUrl.hostname,
path: pkgUrl.pathname,
port: pkgUrl.port,
};
const authInfo = registryAuthToken(pkgUrl.toString(), { recursive: true });
if (authInfo && requestOptions.headers) {
requestOptions.headers.authorization = `${authInfo.type} ${authInfo.token}`;
}
if (options?.requestOptions) {
requestOptions = { ...requestOptions, ...options.requestOptions };
}
const { get } = require(pkgUrl.protocol === 'https:' ? 'https' : 'http');
const request = get(requestOptions, (res: IncomingMessage) => {
if (res.statusCode === 200) {
let rawData = '';
res.setEncoding('utf8');
res.on('data', (chunk: string) => (rawData += chunk));
res.once('error', (err) => {
res.removeAllListeners();
reject(`Request error (${err.message}): ${pkgUrl}`);
});
res.once('end', () => {
res.removeAllListeners();
try {
const pkgMetadata = JSON.parse(rawData);
resolve({
name: pkgName,
lastUpdateDate: Date.now(),
versions: Object.keys(pkgMetadata.versions as string[]),
distTags: pkgMetadata['dist-tags'],
});
return;
} catch (err) {
reject(err);
return;
}
});
} else {
res.removeAllListeners();
res.resume(); // consume response data to free up memory
reject(`Request error (${res.statusCode}): ${pkgUrl}`);
return;
}
});
const abort = (error: Error | string): void => {
request.destroy();
reject(error);
};
request.once('timeout', () => {
abort(`Request timed out: ${pkgUrl}`);
});
request.once('error', (err: Error) => {
abort(err);
});
request.on('close', () => {
request.removeAllListeners();
});
});
};
const getCacheDir = (name = '@badisi/latest-version'): string => {
const homeDir = homedir();
switch (process.platform) {
case 'darwin':
return join(homeDir, 'Library', 'Caches', name);
case 'win32':
return join(
process.env.LOCALAPPDATA ?? join(homeDir, 'AppData', 'Local'),
name,
'Cache',
);
default:
return join(process.env.XDG_CACHE_HOME ?? join(homeDir, '.cache'), name);
}
};
const saveMetadataToCache = (pkg: PackageMetadata): void => {
const filePath = join(getCacheDir(), `${pkg.name}.json`);
if (!existsSync(dirname(filePath))) {
mkdirSync(dirname(filePath), { recursive: true });
}
writeFileSync(filePath, JSON.stringify(pkg));
};
const getMetadataFromCache = (
pkgName: string,
options?: LatestVersionOptions,
): PackageMetadata | undefined => {
const maxAge = options?.cacheMaxAge ?? ONE_DAY;
if (maxAge !== 0) {
const pkgCacheFilePath = join(getCacheDir(), `${pkgName}.json`);
if (existsSync(pkgCacheFilePath)) {
const pkg = JSON.parse(
readFileSync(pkgCacheFilePath).toString(),
) as PackageMetadata;
if (Date.now() - pkg.lastUpdateDate < maxAge) {
return pkg;
}
}
}
return undefined; // invalidates cache
};
const getRegistryVersions = async (
pkgName: string,
tagOrRange?: string,
options?: LatestVersionOptions,
): Promise<RegistryVersions> => {
let pkgMetadata: PackageMetadata | undefined;
if (pkgName.length && options?.useCache) {
pkgMetadata = getMetadataFromCache(pkgName, options);
if (!pkgMetadata) {
pkgMetadata = await downloadMetadata(pkgName, options);
saveMetadataToCache(pkgMetadata);
}
} else if (pkgName.length) {
pkgMetadata = await downloadMetadata(pkgName, options);
}
const versions: RegistryVersions = {
latest: pkgMetadata?.distTags.latest,
next: pkgMetadata?.distTags.next,
};
if (tagOrRange && pkgMetadata?.distTags[tagOrRange]) {
versions.wanted = pkgMetadata.distTags[tagOrRange];
} else if (tagOrRange && pkgMetadata?.versions.length) {
versions.wanted =
maxSatisfying(pkgMetadata.versions, tagOrRange) ?? undefined;
}
return versions;
};
const getInstalledVersion = (
pkgName: string,
location: keyof InstalledVersions = 'local',
): string | undefined => {
try {
if (location === 'globalNpm') {
return require(join(npm.packages, pkgName, 'package.json'))
?.version as string;
} else if (location === 'globalYarn') {
// Make sure package is globally installed by Yarn
const yarnGlobalPkg = require(pathResolve(
yarn.packages,
'..',
'package.json',
));
if (!yarnGlobalPkg?.dependencies?.[pkgName]) {
return undefined;
}
return require(join(yarn.packages, pkgName, 'package.json'))
?.version as string;
} else {
/**
* Compute the local paths manually as require.resolve() and require.resolve.paths()
* cannot be trusted anymore.
* @see https://github.com/nodejs/node/issues/33460
* @see https://github.com/nodejs/loaders/issues/26
*/
const { root } = parse(process.cwd());
let path = process.cwd();
const localPaths = [join(path, 'node_modules')];
while (path !== root) {
path = dirname(path);
localPaths.push(join(path, 'node_modules'));
}
for (const localPath of localPaths) {
const pkgPath = join(localPath, pkgName, 'package.json');
if (existsSync(pkgPath)) {
return require(pkgPath)?.version as string;
}
}
}
return undefined;
} catch {
return undefined;
}
};
const getInfo = async (
pkg: Package,
options?: LatestVersionOptions,
): Promise<LatestVersionPackage> => {
const i = pkg.lastIndexOf('@');
let pkgInfo: LatestVersionPackage = {
name: i > 1 ? pkg.slice(0, i) : pkg,
wantedTagOrRange: i > 1 ? pkg.slice(i + 1) : 'latest',
updatesAvailable: false,
};
try {
pkgInfo = {
...pkgInfo,
local: getInstalledVersion(pkgInfo.name, 'local'),
globalNpm: getInstalledVersion(pkgInfo.name, 'globalNpm'),
globalYarn: getInstalledVersion(pkgInfo.name, 'globalYarn'),
...(await getRegistryVersions(
pkgInfo.name,
pkgInfo.wantedTagOrRange,
options,
)),
};
const local =
pkgInfo.local && pkgInfo.wanted
? gt(pkgInfo.wanted, pkgInfo.local)
? pkgInfo.wanted
: false
: false;
const globalNpm =
pkgInfo.globalNpm && pkgInfo.wanted
? gt(pkgInfo.wanted, pkgInfo.globalNpm)
? pkgInfo.wanted
: false
: false;
const globalYarn =
pkgInfo.globalYarn && pkgInfo.wanted
? gt(pkgInfo.wanted, pkgInfo.globalYarn)
? pkgInfo.wanted
: false
: false;
pkgInfo.updatesAvailable =
local || globalNpm || globalYarn
? { local, globalNpm, globalYarn }
: false;
} catch (err: any) {
pkgInfo.error = err?.message ?? err;
}
return pkgInfo;
};
const latestVersion: LatestVersion = async (
arg: Package | Package[] | PackageJson,
options?: LatestVersionOptions,
): Promise<any> => {
const pkgs: Package[] = [];
if (typeof arg === 'string') {
pkgs.push(arg);
} else if (Array.isArray(arg)) {
pkgs.push(...arg);
} else if (isPackageJson(arg)) {
const addDeps = (deps?: PackageJsonDependencies): void => {
if (deps) {
pkgs.push(
...Object.keys(deps).map((key: string) => `${key}@${deps[key]}`),
);
}
};
addDeps(arg.dependencies as PackageJsonDependencies | undefined);
addDeps(arg.devDependencies as PackageJsonDependencies | undefined);
addDeps(arg.peerDependencies as PackageJsonDependencies | undefined);
}
const jobs = await Promise.allSettled(
pkgs.map((pkg) => getInfo(pkg, options)),
);
const results = jobs.map(
(jobResult: PromiseSettledResult<LatestVersionPackage>) =>
(jobResult as PromiseFulfilledResult<LatestVersionPackage>).value,
);
return typeof arg === 'string' ? results[0] : results;
};
export type {
LatestVersion,
Package,
PackageRange,
PackageJson,
PackageJsonDependencies,
RegistryVersions,
LatestVersionPackage,
RequestOptions,
LatestVersionOptions,
};
export default latestVersion;

24
src/utils/lock-checker.ts Normal file
View File

@@ -0,0 +1,24 @@
const lockFiles = [
'package-lock.json',
'yarn.lock',
'pnpm-lock.yaml',
'bun.lockb',
'bun.lock',
];
const lockNotFound = `
没有检测到任何 lock 文件,这可能导致依赖关系不一致而使热更异常。
`;
const multipleLocksFound = `
检测到多个锁文件(),这可能导致依赖关系不一致而使热更异常。
`;
const lockBestPractice = `
关于 lock 文件的最佳实践:
1. 开发团队中的所有成员应该使用相同的包管理器,维护同一份 lock 文件。
2. 将 lock 文件添加到版本控制中(但不要同时提交多种不同格式的 lock 文件)。
3. 代码审核时应关注 lock 文件的变化。
这样可以最大限度避免因依赖关系不一致而导致的热更异常,也降低供应链攻击等安全隐患。
`;

View File

@@ -1,48 +1,27 @@
import { get, getAllPackages, post, put, uploadFile } from './api';
import { get, post, put, uploadFile } from './api';
import { question, saveToLocal } from './utils';
import { t } from './utils/i18n';
import { getPlatform, getSelectedApp } from './app';
import { checkPlatform, getSelectedApp } from './app';
import { choosePackage } from './package';
import { compare } from 'compare-versions';
import { depVersions } from './utils/dep-versions';
import { getCommitInfo } from './utils/git';
import type { Package, Platform, Version } from 'types';
import { satisfies } from 'compare-versions';
import chalk from 'chalk';
interface CommandOptions {
name?: string;
description?: string;
metaInfo?: string;
platform?: Platform;
versionId?: string;
packageId?: string;
packageVersion?: string;
minPackageVersion?: string;
maxPackageVersion?: string;
packageVersionRange?: string;
rollout?: string;
dryRun?: boolean;
}
async function showVersion(appId: string, offset: number) {
const { data, count } = await get(`/app/${appId}/version/list`);
console.log(t('offset', { offset }));
console.log(`Offset ${offset}`);
for (const version of data) {
const pkgCount = version.packages?.length || 0;
let packageInfo = '';
let packageInfo = version.packages
.slice(0, 3)
.map((v) => v.name)
.join(', ');
const pkgCount = version.packages.length;
if (pkgCount > 3) {
packageInfo += `...and ${pkgCount - 3} more`;
}
if (pkgCount === 0) {
packageInfo = 'no package';
} else {
packageInfo = version.packages
?.slice(0, 3)
.map((pkg: Package) => pkg.name)
.join(', ');
if (pkgCount > 3) {
packageInfo += `...and ${pkgCount - 3} more`;
} else {
packageInfo = `[${packageInfo}]`;
}
packageInfo = `[${packageInfo}]`;
}
console.log(
`${version.id}) ${version.hash.slice(0, 8)} ${
@@ -81,7 +60,7 @@ async function chooseVersion(appId: string) {
const cmd = await question(
'Enter versionId or page Up/page Down/Begin(U/D/B)',
);
switch (cmd.toUpperCase()) {
switch (cmd.toLowerCase()) {
case 'U':
offset = Math.max(0, offset - 10);
break;
@@ -92,10 +71,7 @@ async function chooseVersion(appId: string) {
offset = 0;
break;
default: {
const versionId = Number.parseInt(cmd, 10);
const v = data.find(
(version: Version) => version.id === String(versionId),
);
const v = data.find((v) => v.id === (cmd | 0));
if (v) {
return v;
}
@@ -104,227 +80,201 @@ async function chooseVersion(appId: string) {
}
}
export const bindVersionToPackages = async ({
appId,
versionId,
pkgs,
rollout,
dryRun,
}: {
appId: string;
versionId: string;
pkgs: Package[];
rollout?: number;
dryRun?: boolean;
}) => {
if (dryRun) {
console.log(chalk.yellow(t('dryRun')));
}
if (rollout !== undefined) {
const rolloutConfig: Record<string, number> = {};
for (const pkg of pkgs) {
rolloutConfig[pkg.name] = rollout;
}
if (!dryRun) {
await put(`/app/${appId}/version/${versionId}`, {
config: {
rollout: rolloutConfig,
},
});
}
console.log(
`${t('rolloutConfigSet', {
versions: pkgs.map((pkg: Package) => pkg.name).join(', '),
rollout: rollout,
})}`,
);
}
for (const pkg of pkgs) {
if (!dryRun) {
await put(`/app/${appId}/package/${pkg.id}`, {
versionId,
});
}
console.log(
`${t('versionBind', {
version: versionId,
nativeVersion: pkg.name,
id: pkg.id,
})}`,
);
}
console.log(t('operationComplete', { count: pkgs.length }));
};
export const commands = {
publish: async function ({
args,
options,
}: {
args: string[];
options: CommandOptions;
}) {
publish: async function ({ args, options }) {
const fn = args[0];
const { name, description, metaInfo } = options;
if (!fn || !fn.endsWith('.ppk')) {
throw new Error(t('publishUsage'));
throw new Error(
'使用方法: pushy publish ppk后缀文件 --platform ios|android|harmony',
);
}
const platform = await getPlatform(options.platform);
const platform = checkPlatform(
options.platform || (await question('平台(ios/android/harmony):')),
);
const { appId } = await getSelectedApp(platform);
const { hash } = await uploadFile(fn);
const versionName =
name || (await question(t('versionNameQuestion'))) || t('unnamed');
const versionName = name || (await question('输入版本名称: ')) || '(未命名)';
const { id } = await post(`/app/${appId}/version/create`, {
name: versionName,
hash,
description:
description || (await question(t('versionDescriptionQuestion'))),
metaInfo: metaInfo || (await question(t('versionMetaInfoQuestion'))),
description: description || (await question('输入版本描述:')),
metaInfo: metaInfo || (await question('输入自定义的 meta info:')),
deps: depVersions,
commit: await getCommitInfo(),
});
// TODO local diff
saveToLocal(fn, `${appId}/ppk/${id}.ppk`);
console.log(t('packageUploadSuccess', { id }));
console.log(`已成功上传新热更包id: ${id}`);
const v = await question(t('updateNativePackageQuestion'));
const v = await question('是否现在将此热更应用到原生包上?(Y/N)');
if (v.toLowerCase() === 'y') {
await this.update({ args: [], options: { versionId: id, platform } });
}
return versionName;
},
versions: async ({ options }: { options: CommandOptions }) => {
const platform = await getPlatform(options.platform);
versions: async ({ options }) => {
const platform = checkPlatform(
options.platform || (await question('平台(ios/android/harmony):')),
);
const { appId } = await getSelectedApp(platform);
await listVersions(appId);
},
update: async ({
args,
options,
}: {
args: string[];
options: CommandOptions;
}) => {
const platform = await getPlatform(options.platform);
update: async ({ args, options }) => {
const platform = checkPlatform(
options.platform || (await question('平台(ios/android/harmony):')),
);
const { appId } = await getSelectedApp(platform);
let versionId = options.versionId || (await chooseVersion(appId)).id;
if (versionId === 'null') {
versionId = undefined;
versionId = null;
}
let pkgId = options.packageId;
let pkgId;
let pkgVersion = options.packageVersion;
let minPkgVersion = options.minPackageVersion;
let maxPkgVersion = options.maxPackageVersion;
let packageVersionRange = options.packageVersionRange;
let rollout: number | undefined = undefined;
if (options.rollout !== undefined) {
let rollout = options.rollout;
if (rollout === undefined) {
rollout = null;
} else {
try {
rollout = Number.parseInt(options.rollout);
rollout = Number.parseInt(rollout);
} catch (e) {
throw new Error(t('rolloutRangeError'));
throw new Error('rollout 必须是 1-100 的整数');
}
if (rollout < 1 || rollout > 100) {
throw new Error(t('rolloutRangeError'));
throw new Error('rollout 必须是 1-100 的整数');
}
}
const allPkgs = await getAllPackages(appId);
if (!allPkgs) {
throw new Error(t('noPackagesFound', { appId }));
}
let pkgsToBind: Package[] = [];
if (minPkgVersion) {
minPkgVersion = String(minPkgVersion).trim();
pkgsToBind = allPkgs.filter((pkg: Package) =>
satisfies(pkg.name, `>=${minPkgVersion}`),
);
if (pkgsToBind.length === 0) {
throw new Error(
t('nativeVersionNotFoundGte', { version: minPkgVersion }),
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
const pkgs = data.filter((d) => compare(d.name, minPkgVersion, '>='));
if (pkgs.length === 0) {
throw new Error(`未查询到 >= ${minPkgVersion} 的原生版本`);
}
if (rollout) {
const rolloutConfig = {};
for (const pkg of pkgs) {
rolloutConfig[pkg.name] = rollout;
}
await put(`/app/${appId}/version/${versionId}`, {
config: {
rollout: rolloutConfig,
},
});
console.log(
`已在原生版本 ${pkgs
.map((p) => p.name)
.join(', ')} 上设置灰度发布 ${rollout}% 热更版本 ${versionId}`,
);
}
} else if (maxPkgVersion) {
for (const pkg of pkgs) {
await put(`/app/${appId}/package/${pkg.id}`, {
versionId,
});
console.log(
`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name} (id: ${pkg.id})`,
);
}
console.log(`操作完成,共已绑定 ${pkgs.length} 个原生版本`);
return;
}
if (maxPkgVersion) {
maxPkgVersion = String(maxPkgVersion).trim();
pkgsToBind = allPkgs.filter((pkg: Package) =>
satisfies(pkg.name, `<=${maxPkgVersion}`),
);
if (pkgsToBind.length === 0) {
throw new Error(
t('nativeVersionNotFoundLte', { version: maxPkgVersion }),
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
const pkgs = data.filter((d) => compare(d.name, maxPkgVersion, '<='));
if (pkgs.length === 0) {
throw new Error(`未查询到 <= ${maxPkgVersion} 的原生版本`);
}
if (rollout) {
const rolloutConfig = {};
for (const pkg of pkgs) {
rolloutConfig[pkg.name] = rollout;
}
await put(`/app/${appId}/version/${versionId}`, {
config: {
rollout: rolloutConfig,
},
});
console.log(
`已在原生版本 ${pkgs
.map((p) => p.name)
.join(', ')} 上设置灰度发布 ${rollout}% 热更版本 ${versionId}`,
);
}
} else if (pkgVersion) {
pkgVersion = pkgVersion.trim();
const pkg = allPkgs.find((pkg: Package) => pkg.name === pkgVersion);
if (pkg) {
pkgsToBind = [pkg];
} else {
throw new Error(
t('nativeVersionNotFoundMatch', { version: pkgVersion }),
for (const pkg of pkgs) {
await put(`/app/${appId}/package/${pkg.id}`, {
versionId,
});
console.log(
`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name} (id: ${pkg.id})`,
);
}
} else if (packageVersionRange) {
packageVersionRange = packageVersionRange.trim();
pkgsToBind = allPkgs.filter((pkg: Package) =>
satisfies(pkg.name, packageVersionRange!),
);
if (pkgsToBind.length === 0) {
throw new Error(
t('nativeVersionNotFoundMatch', { version: packageVersionRange }),
);
}
} else {
if (!pkgId) {
pkgId = (await choosePackage(appId)).id;
}
console.log(`操作完成,共已绑定 ${pkgs.length} 个原生版本`);
return;
}
if (!pkgId) {
throw new Error(t('packageIdRequired'));
}
const pkg = allPkgs.find(
(pkg: Package) => String(pkg.id) === String(pkgId),
);
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
if (pkgVersion) {
pkgVersion = pkgVersion.trim();
const pkg = data.find((d) => d.name === pkgVersion);
if (pkg) {
pkgsToBind = [pkg];
pkgId = pkg.id;
} else {
throw new Error(t('nativePackageIdNotFound', { id: pkgId }));
throw new Error(`未查询到匹配原生版本:${pkgVersion}`);
}
}
if (!pkgId) {
pkgId = options.packageId || (await choosePackage(appId)).id;
}
if (!pkgId) {
throw new Error('请提供 packageId 或 packageVersion 参数');
}
if (!pkgVersion) {
const pkg = data.find((d) => d.id === pkgId);
if (pkg) {
pkgVersion = pkg.name;
}
}
await bindVersionToPackages({
appId,
if (rollout) {
await put(`/app/${appId}/version/${versionId}`, {
config: {
rollout: {
[pkgVersion]: rollout,
},
},
});
console.log(
`已将在原生版本 ${pkgVersion} (id: ${pkgId}) 上设置灰度发布 ${rollout}% 热更版本 ${versionId} `,
);
}
await put(`/app/${appId}/package/${pkgId}`, {
versionId,
pkgs: pkgsToBind,
rollout,
dryRun: options.dryRun,
});
console.log(
`已将热更版本 ${versionId} 绑定到原生版本 ${pkgVersion} (id: ${pkgId})`,
);
},
updateVersionInfo: async ({
args,
options,
}: {
args: string[];
options: CommandOptions;
}) => {
const platform = await getPlatform(options.platform);
updateVersionInfo: async ({ args, options }) => {
const platform = checkPlatform(
options.platform || (await question('平台(ios/android/harmony):')),
);
const { appId } = await getSelectedApp(platform);
const versionId = options.versionId || (await chooseVersion(appId)).id;
const updateParams: Record<string, string> = {};
if (options.name) updateParams.name = options.name;
if (options.description) updateParams.description = options.description;
if (options.metaInfo) updateParams.metaInfo = options.metaInfo;
const updateParams = {};
options.name && (updateParams.name = options.name);
options.description && (updateParams.description = options.description);
options.metaInfo && (updateParams.metaInfo = options.metaInfo);
await put(`/app/${appId}/version/${versionId}`, updateParams);
console.log(t('operationSuccess'));
console.log('操作成功');
},
};