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

Compare commits

..

11 Commits

Author SHA1 Message Date
sunnylqm
5d1466ddec Update i18n strings to include whitespace control in ppkPackageGenerated messages for English and Chinese locales 2025-04-10 21:22:59 +08:00
sunnylqm
081d54ba63 update deps 2025-04-09 11:42:30 +08:00
sunnylqm
4326c08d79 downgrade commander 2025-04-09 10:52:38 +08:00
sunnylqm
20010a9ea6 Update version to 1.43.1 and handle optional chaining for origin URL in getCommitInfo function 2025-04-07 19:56:17 +08:00
sunnylqm
36220a48aa Update package description for clarity and specificity 2025-04-02 08:39:26 +08:00
sunnylqm
d281d72737 check lockfiles 2025-04-02 08:27:05 +08:00
sunnylqm
d351243ab7 check lockfile 2025-04-01 23:24:02 +08:00
sunnylqm
fbdacfffd2 add gitignore check 2025-04-01 23:13:20 +08:00
sunnylqm
b725d2b08e i18n 2025-03-30 23:40:28 +08:00
sunnylqm
3f1b43e38e update i18n 2025-03-25 09:36:58 +08:00
sunnylqm
328b1f5447 update i18n 2025-03-24 23:16:09 +08:00
18 changed files with 290 additions and 152 deletions

View File

@@ -3,20 +3,20 @@
"workspaces": { "workspaces": {
"": { "": {
"dependencies": { "dependencies": {
"@badisi/latest-version": "^7.0.12", "@badisi/latest-version": "^7.0.13",
"bplist-parser": "^0.3.2", "bplist-parser": "^0.3.2",
"bytebuffer": "^5.0.1", "bytebuffer": "^5.0.1",
"cgbi-to-png": "^1.0.7", "cgbi-to-png": "^1.0.7",
"chalk": "4", "chalk": "4",
"cli-arguments": "^0.2.1", "cli-arguments": "^0.2.1",
"commander": "^13.1.0", "commander": "^13",
"compare-versions": "^6.1.1", "compare-versions": "^6.1.1",
"filesize-parser": "^1.5.1", "filesize-parser": "^1.5.1",
"form-data": "^4.0.2", "form-data": "^4.0.2",
"fs-extra": "8", "fs-extra": "8",
"gradle-to-js": "^2.0.1", "gradle-to-js": "^2.0.1",
"i18next": "^24.2.3", "i18next": "^24.2.3",
"isomorphic-git": "^1.29.0", "isomorphic-git": "^1.30.1",
"isomorphic-unzip": "^1.1.5", "isomorphic-unzip": "^1.1.5",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"plist": "^3.1.0", "plist": "^3.1.0",
@@ -33,25 +33,25 @@
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^1.9.4", "@biomejs/biome": "^1.9.4",
"@swc/cli": "^0.6.0", "@swc/cli": "^0.6.0",
"@swc/core": "^1.11.9", "@swc/core": "^1.11.18",
"@types/filesize-parser": "^1.5.3", "@types/filesize-parser": "^1.5.3",
"@types/fs-extra": "^11.0.4", "@types/fs-extra": "^11.0.4",
"@types/node": "^22.13.10", "@types/node": "^22.14.0",
"@types/node-fetch": "^2.6.12", "@types/node-fetch": "^2.6.12",
"@types/progress": "^2.0.7", "@types/progress": "^2.0.7",
"@types/semver": "^7.5.8", "@types/semver": "^7.7.0",
"@types/tcp-ping": "^0.1.6", "@types/tcp-ping": "^0.1.6",
"@types/update-notifier": "^6.0.8", "@types/update-notifier": "^6.0.8",
"@types/yauzl": "^2.10.3", "@types/yauzl": "^2.10.3",
"@types/yazl": "^2.4.6", "@types/yazl": "^2.4.6",
"typescript": "^5.8.2", "typescript": "^5.8.3",
}, },
}, },
}, },
"packages": { "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.10", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw=="],
"@badisi/latest-version": ["@badisi/latest-version@7.0.12", "", { "dependencies": { "@colors/colors": "^1.6.0", "global-dirs": "3.0.1", "ora": "^8.2.0", "registry-auth-token": "^5.1.0", "semver": "^7.7.1" }, "bin": { "latest-version": "bin/latest-version", "lv": "bin/latest-version" } }, "sha512-Ae5c0510gSWpy97PpAtfVunvGt8u2nkaX4jahtTFTii8V+/etMNvfxUw3XhCXSG9zZ6y2uxGZXWMfO0hUtSRJQ=="], "@badisi/latest-version": ["@badisi/latest-version@7.0.13", "", { "dependencies": { "@colors/colors": "^1.6.0", "global-dirs": "3.0.1", "ora": "^8.2.0", "registry-auth-token": "^5.1.0", "semver": "^7.7.1" }, "bin": { "latest-version": "bin/latest-version", "lv": "bin/latest-version" } }, "sha512-iie68SUX7vUt6Ap9tVeb5tGE/Oj1wUAzAMhzY6mqOSy81jO9FrhRdGa8c3A7QJX3KSedn281pZ/ZZDgtsaFI6g=="],
"@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=="], "@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,31 +125,31 @@
"@swc/cli": ["@swc/cli@0.6.0", "", { "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-Q5FsI3Cw0fGMXhmsg7c08i4EmXCrcl+WnAxb6LYOLHw4JFFC3yzmx9LaXZ7QMbA+JZXbigU2TirI7RAfO0Qlnw=="], "@swc/cli": ["@swc/cli@0.6.0", "", { "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-Q5FsI3Cw0fGMXhmsg7c08i4EmXCrcl+WnAxb6LYOLHw4JFFC3yzmx9LaXZ7QMbA+JZXbigU2TirI7RAfO0Qlnw=="],
"@swc/core": ["@swc/core@1.11.9", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.19" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.9", "@swc/core-darwin-x64": "1.11.9", "@swc/core-linux-arm-gnueabihf": "1.11.9", "@swc/core-linux-arm64-gnu": "1.11.9", "@swc/core-linux-arm64-musl": "1.11.9", "@swc/core-linux-x64-gnu": "1.11.9", "@swc/core-linux-x64-musl": "1.11.9", "@swc/core-win32-arm64-msvc": "1.11.9", "@swc/core-win32-ia32-msvc": "1.11.9", "@swc/core-win32-x64-msvc": "1.11.9" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-4UQ66FwTkFDr+UzYzRNKQyHMScOrc4zJbTJHyK6dP1yVMrxi5sl0FTzNKiqoYvRZ7j8TAYgtYvvuPSW/XXvp5g=="], "@swc/core": ["@swc/core@1.11.18", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.21" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.18", "@swc/core-darwin-x64": "1.11.18", "@swc/core-linux-arm-gnueabihf": "1.11.18", "@swc/core-linux-arm64-gnu": "1.11.18", "@swc/core-linux-arm64-musl": "1.11.18", "@swc/core-linux-x64-gnu": "1.11.18", "@swc/core-linux-x64-musl": "1.11.18", "@swc/core-win32-arm64-msvc": "1.11.18", "@swc/core-win32-ia32-msvc": "1.11.18", "@swc/core-win32-x64-msvc": "1.11.18" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-ORZxyCKKiqYt2iHdh1C7pfVR1GBjkuFOdwqZggQzaq0vt22DpGca+2JsUtkUoWQmWcct04v5+ScwgvsHuMObxA=="],
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-moqbPCWG6SHiDMENTDYsEQJ0bFustbLtrdbDbdjnijSyhCyIcm9zKowmovE6MF8JBdOwmLxbuN1Yarq6CrPNlw=="], "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.18", "", { "os": "darwin", "cpu": "arm64" }, "sha512-K6AntdUlNMQg8aChqjeXwnVhK6d4WRZ9TgtLSTmdU0Ugll4an7QK49s9NrT7XQU91cEsVvzdr++p1bNImx0hJg=="],
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-/lgMo5l9q6y3jjLM3v30y6SBvuuyLsM/K94hv3hPvDf91N+YlZLw4D7KY0Qknfhj6WytoAcjOIDU6xwBRPyUWg=="], "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.18", "", { "os": "darwin", "cpu": "x64" }, "sha512-RCRvC6Q9M5BArTvj/IzUAAYGrgxYFbTTnAtf6UX7JFq2DAn+hEwYUjmC1m0gFso9HqFU0m5QZUGfZvVmACGWUw=="],
"@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.9", "", { "os": "linux", "cpu": "arm" }, "sha512-7bL6z/63If11IpBElQRozIGRadiy6rt3DoUyfGuFIFQKxtnZxzHuLxm1/wrCAGN9iAZxrpHxHP0VbPQvr6Mcjg=="], "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.18", "", { "os": "linux", "cpu": "arm" }, "sha512-wteAKf8YKb3jOnZFm3EzuIMzzCVXMuQOLHsz1IgEOc44/gdgNXKxaYTWAowZuej7t68tf/w0cRNMc7Le414v/g=="],
"@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-9ArpxjrNbyFTr7gG+toiGbbK2mfS+X97GIruBKPsD8CJH/yJlMknBsX3lfy9h/L119zYVnFBmZDnwsv5yW8/cw=="], "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-hY6jJYZ6PKHSBo5OATswfyKsUgsWu9+4nDcN8liYIRRgz3E0G9wk0VUTP4cFPivBFeHWTTAGz687/Nf2aQEIpw=="],
"@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.11.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-UOnunJWu7T7oNkBr4DLMwXXbldjiwi+JxmqBKrD2+BNiHGu6P5VpqDHiTGuWuLrda0TcTmeNE6gzlIVOVBo/vw=="], "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.11.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-slu0mlP2nucvQalttnapfpqpD/LlM9NHx9g3ofgsLzjObyMEBiX4ZysQ3y65U8Mjw71RNqtLd/ZmvxI6OmLdiQ=="],
"@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.9", "", { "os": "linux", "cpu": "x64" }, "sha512-HAqmCkNoNhRusBqSokyylXKsLJ/dr3dnMgBERdUrCIh47L8CKR2qEFUP6FI05sHVB85403ctWnfzBYblcarpqg=="], "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.18", "", { "os": "linux", "cpu": "x64" }, "sha512-h9a/8PA25arMCQ9t8CE8rA1s0c77z4kCZZ7dUuUkD88yEXIrARMca1IKR7of+S3slfQrf1Zlq3Ac1Fb1HVJziQ=="],
"@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.9", "", { "os": "linux", "cpu": "x64" }, "sha512-THwUT2g2qSWUxhi3NGRCEdmh/q7WKl3d5jcN9mz/4jum76Tb46LB9p3oOVPBIcfnFQ9OaddExjCwLoUl0ju2pA=="], "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.18", "", { "os": "linux", "cpu": "x64" }, "sha512-0sMDJj5qUGK9QEw4lrxLxkTP/4AoKciqNzXvqbk+J9XuXN2aIv4BsR1Y7z3GwAeMFGsba2lbHLOtJlDsaqIsiA=="],
"@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-r4SGD9lR0MM9HSIsQ72BEL3Za3XsuVj+govuXQTlK0mty5gih4L+Qgfnb9PmhjFakK3F63gZyyEr2y8Fj0mN6Q=="], "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.18", "", { "os": "win32", "cpu": "arm64" }, "sha512-zGv9HnfgBcKyt54MJRWdwRNu9BuYkAFM7bx+tWtKhd37Ef7ZX20QLs9xXl5wWDXCbsOdRxXIZgXs6PEL+Pzmrw=="],
"@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.9", "", { "os": "win32", "cpu": "ia32" }, "sha512-jrEh6MDSnhwfpjRlSWd2Bk8pS5EjreQD1YbkNcnXviQf3+H0wSPmeVSktZyoIdkxAuc2suFx8mj7Yja2UXAgUg=="], "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.18", "", { "os": "win32", "cpu": "ia32" }, "sha512-uBKj0S1lYv/E2ZhxHZOxSiQwoegYmzbPRpjq6eHBZDv97mu7W3K27/lsnPbvAfQ6b6rnv8BI+EsmJ7VLQBAHBQ=="],
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.9", "", { "os": "win32", "cpu": "x64" }, "sha512-oAwuhzr+1Bmb4As2wa3k57/WPJeyVEYRQelwEMYjPgi/h6TH+Y69jQAgKOd+ec1Yl8L5nkWTZMVA/dKDac1bAQ=="], "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.18", "", { "os": "win32", "cpu": "x64" }, "sha512-8USTRcdgeFMNBgvVXl8tz6n4+9s9m+zHsfDeBT4jPgwnq2bnLBlTUlwnPwzDxfg9nUJr6RFD4xeKfWyZZRosZg=="],
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
"@swc/types": ["@swc/types@0.1.19", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-WkAZaAfj44kh/UFdAQcrMP1I0nwRqpt27u+08LMBYMqmQfwwMofYoMh/48NGkMMRfC4ynpfwRbJuu8ErfNloeA=="], "@swc/types": ["@swc/types@0.1.21", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ=="],
"@szmarczak/http-timer": ["@szmarczak/http-timer@5.0.1", "", { "dependencies": { "defer-to-connect": "^2.0.1" } }, "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw=="], "@szmarczak/http-timer": ["@szmarczak/http-timer@5.0.1", "", { "dependencies": { "defer-to-connect": "^2.0.1" } }, "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw=="],
@@ -165,13 +165,13 @@
"@types/jsonfile": ["@types/jsonfile@6.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ=="], "@types/jsonfile": ["@types/jsonfile@6.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ=="],
"@types/node": ["@types/node@22.13.10", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw=="], "@types/node": ["@types/node@22.14.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA=="],
"@types/node-fetch": ["@types/node-fetch@2.6.12", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA=="], "@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/progress": ["@types/progress@2.0.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-iadjw02vte8qWx7U0YM++EybBha2CQLPGu9iJ97whVgJUT5Zq9MjAPYUnbfRI2Kpehimf1QjFJYxD0t8nqzu5w=="],
"@types/semver": ["@types/semver@7.5.8", "", {}, "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ=="], "@types/semver": ["@types/semver@7.7.0", "", {}, "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA=="],
"@types/tcp-ping": ["@types/tcp-ping@0.1.6", "", {}, "sha512-1TTOm3cK+0NrZ6uTlY51YERzo5tEW3RybX1594vy9oiZOc1vsVL4LmdiIklDJXYLlzmve5lBkM5GjvwBG1Bc4A=="], "@types/tcp-ping": ["@types/tcp-ping@0.1.6", "", {}, "sha512-1TTOm3cK+0NrZ6uTlY51YERzo5tEW3RybX1594vy9oiZOc1vsVL4LmdiIklDJXYLlzmve5lBkM5GjvwBG1Bc4A=="],
@@ -545,7 +545,7 @@
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"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-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-unzip": ["isomorphic-unzip@1.1.5", "", { "dependencies": { "buffer": "^5.0.7", "yauzl": "^2.8.0" } }, "sha512-2McA51lWhmO3Kk438jxVcYeh6L+AOqVnl9XdX1yI7GlLA9RwEyTBgGem1rNuRIU2abAmOiv+IagThdUxASY4IA=="], "isomorphic-unzip": ["isomorphic-unzip@1.1.5", "", { "dependencies": { "buffer": "^5.0.7", "yauzl": "^2.8.0" } }, "sha512-2McA51lWhmO3Kk438jxVcYeh6L+AOqVnl9XdX1yI7GlLA9RwEyTBgGem1rNuRIU2abAmOiv+IagThdUxASY4IA=="],
@@ -807,7 +807,7 @@
"typedarray-to-buffer": ["typedarray-to-buffer@3.1.5", "", { "dependencies": { "is-typedarray": "^1.0.0" } }, "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q=="], "typedarray-to-buffer": ["typedarray-to-buffer@3.1.5", "", { "dependencies": { "is-typedarray": "^1.0.0" } }, "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q=="],
"typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"uint8array-extras": ["uint8array-extras@1.4.0", "", {}, "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ=="], "uint8array-extras": ["uint8array-extras@1.4.0", "", {}, "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ=="],
@@ -815,7 +815,7 @@
"unbzip2-stream": ["unbzip2-stream@1.4.3", "", { "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" } }, "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg=="], "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.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
"unique-string": ["unique-string@2.0.0", "", { "dependencies": { "crypto-random-string": "^2.0.0" } }, "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg=="], "unique-string": ["unique-string@2.0.0", "", { "dependencies": { "crypto-random-string": "^2.0.0" } }, "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg=="],

View File

@@ -136,11 +136,11 @@
"hasValue": true "hasValue": true
}, },
"intermediaDir": { "intermediaDir": {
"default": ".pushy/intermedia/${platform}", "default": "${tempDir}/intermedia/${platform}",
"hasValue": true "hasValue": true
}, },
"output": { "output": {
"default": ".pushy/output/${platform}.${time}.ppk", "default": "${tempDir}/output/${platform}.${time}.ppk",
"hasValue": true "hasValue": true
}, },
"sourcemap": { "sourcemap": {
@@ -167,7 +167,7 @@
"description": "Create diff patch", "description": "Create diff patch",
"options": { "options": {
"output": { "output": {
"default": ".pushy/output/diff", "default": "${tempDir}/output/diff",
"hasValue": true "hasValue": true
} }
} }
@@ -176,7 +176,7 @@
"description": "Create diff patch from a Android package(.apk)", "description": "Create diff patch from a Android package(.apk)",
"options": { "options": {
"output": { "output": {
"default": ".pushy/output/diff-${time}.apk-patch", "default": "${tempDir}/output/diff-${time}.apk-patch",
"hasValue": true "hasValue": true
} }
} }
@@ -185,7 +185,7 @@
"description": "Create diff patch from a iOS package(.ipa)", "description": "Create diff patch from a iOS package(.ipa)",
"options": { "options": {
"output": { "output": {
"default": ".pushy/output/diff-${time}.ipa-patch", "default": "${tempDir}/output/diff-${time}.ipa-patch",
"hasValue": true "hasValue": true
} }
} }
@@ -194,7 +194,7 @@
"description": "Create hdiff patch", "description": "Create hdiff patch",
"options": { "options": {
"output": { "output": {
"default": ".pushy/output/hdiff", "default": "${tempDir}/output/hdiff",
"hasValue": true "hasValue": true
} }
} }
@@ -203,7 +203,7 @@
"description": "Create hdiff patch from a Android package(.apk)", "description": "Create hdiff patch from a Android package(.apk)",
"options": { "options": {
"output": { "output": {
"default": ".pushy/output/hdiff-${time}.apk-patch", "default": "${tempDir}/output/hdiff-${time}.apk-patch",
"hasValue": true "hasValue": true
} }
} }
@@ -212,7 +212,7 @@
"description": "Create hdiff patch from a Prepare package(.ppk)", "description": "Create hdiff patch from a Prepare package(.ppk)",
"options": { "options": {
"output": { "output": {
"default": ".pushy/output/hdiff-${time}.ppk-patch", "default": "${tempDir}/output/hdiff-${time}.ppk-patch",
"hasValue": true "hasValue": true
} }
} }
@@ -221,7 +221,7 @@
"description": "Create hdiff patch from a Harmony package(.app)", "description": "Create hdiff patch from a Harmony package(.app)",
"options": { "options": {
"output": { "output": {
"default": ".pushy/output/hdiff-${time}.app-patch", "default": "${tempDir}/output/hdiff-${time}.app-patch",
"hasValue": true "hasValue": true
} }
} }
@@ -230,7 +230,7 @@
"description": "Create hdiff patch from a iOS package(.ipa)", "description": "Create hdiff patch from a iOS package(.ipa)",
"options": { "options": {
"output": { "output": {
"default": ".pushy/output/hdiff-${time}.ipa-patch", "default": "${tempDir}/output/hdiff-${time}.ipa-patch",
"hasValue": true "hasValue": true
} }
} }

View File

@@ -1,7 +1,7 @@
{ {
"name": "react-native-update-cli", "name": "react-native-update-cli",
"version": "1.42.1", "version": "1.43.3",
"description": "Command tools for javaScript updater with `pushy` service for react native apps.", "description": "command line tool for react-native-update (remote updates for react native)",
"main": "index.js", "main": "index.js",
"bin": { "bin": {
"pushy": "lib/index.js", "pushy": "lib/index.js",
@@ -35,20 +35,20 @@
}, },
"homepage": "https://github.com/reactnativecn/react-native-pushy/tree/master/react-native-pushy-cli", "homepage": "https://github.com/reactnativecn/react-native-pushy/tree/master/react-native-pushy-cli",
"dependencies": { "dependencies": {
"@badisi/latest-version": "^7.0.12", "@badisi/latest-version": "^7.0.13",
"bplist-parser": "^0.3.2", "bplist-parser": "^0.3.2",
"bytebuffer": "^5.0.1", "bytebuffer": "^5.0.1",
"cgbi-to-png": "^1.0.7", "cgbi-to-png": "^1.0.7",
"chalk": "4", "chalk": "4",
"cli-arguments": "^0.2.1", "cli-arguments": "^0.2.1",
"commander": "^13.1.0", "commander": "^13",
"compare-versions": "^6.1.1", "compare-versions": "^6.1.1",
"filesize-parser": "^1.5.1", "filesize-parser": "^1.5.1",
"form-data": "^4.0.2", "form-data": "^4.0.2",
"fs-extra": "8", "fs-extra": "8",
"gradle-to-js": "^2.0.1", "gradle-to-js": "^2.0.1",
"i18next": "^24.2.3", "i18next": "^24.2.3",
"isomorphic-git": "^1.29.0", "isomorphic-git": "^1.30.1",
"isomorphic-unzip": "^1.1.5", "isomorphic-unzip": "^1.1.5",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"plist": "^3.1.0", "plist": "^3.1.0",
@@ -63,22 +63,22 @@
"yazl": "3.3.1" "yazl": "3.3.1"
}, },
"engines": { "engines": {
"node": ">= 10" "node": ">= 14"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^1.9.4", "@biomejs/biome": "^1.9.4",
"@swc/cli": "^0.6.0", "@swc/cli": "^0.6.0",
"@swc/core": "^1.11.9", "@swc/core": "^1.11.18",
"@types/filesize-parser": "^1.5.3", "@types/filesize-parser": "^1.5.3",
"@types/fs-extra": "^11.0.4", "@types/fs-extra": "^11.0.4",
"@types/node": "^22.13.10", "@types/node": "^22.14.0",
"@types/node-fetch": "^2.6.12", "@types/node-fetch": "^2.6.12",
"@types/progress": "^2.0.7", "@types/progress": "^2.0.7",
"@types/semver": "^7.5.8", "@types/semver": "^7.7.0",
"@types/tcp-ping": "^0.1.6", "@types/tcp-ping": "^0.1.6",
"@types/update-notifier": "^6.0.8", "@types/update-notifier": "^6.0.8",
"@types/yauzl": "^2.10.3", "@types/yauzl": "^2.10.3",
"@types/yazl": "^2.4.6", "@types/yazl": "^2.4.6",
"typescript": "^5.8.2" "typescript": "^5.8.3"
} }
} }

View File

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

View File

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

View File

@@ -11,6 +11,10 @@ const g2js = require('gradle-to-js/lib/parser');
import os from 'node:os'; import os from 'node:os';
const properties = require('properties'); const properties = require('properties');
import { depVersions } from './utils/dep-versions'; 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';
let bsdiff; let bsdiff;
let hdiff; let hdiff;
@@ -512,7 +516,7 @@ async function pack(dir: string, output: string) {
}); });
zipfile.end(); zipfile.end();
}); });
console.log(`ppk热更包已生成并保存到: ${output}`); console.log(t('ppkPackageGenerated', { output }));
} }
export function readEntire(entry: string, zipFile: ZipFile) { export function readEntire(entry: string, zipFile: ZipFile) {
@@ -907,9 +911,13 @@ export const commands = {
disableHermes, disableHermes,
} = translateOptions({ } = translateOptions({
...options, ...options,
tempDir,
platform, platform,
}); });
checkLockFiles();
addGitIgnore();
const bundleParams = await checkPlugins(); const bundleParams = await checkPlugins();
const sourcemapPlugin = bundleParams.sourcemap; const sourcemapPlugin = bundleParams.sourcemap;
const isSentry = bundleParams.sentry; const isSentry = bundleParams.sentry;

View File

@@ -6,7 +6,7 @@ export default {
lockNotFound: lockNotFound:
'No lock file detected, which may cause inconsistent dependencies and hot-updating issues.', 'No lock file detected, which may cause inconsistent dependencies and hot-updating issues.',
multipleLocksFound: multipleLocksFound:
'Multiple lock files detected ({lockFiles}), which may cause inconsistent dependencies and hot-updating issues.', 'Multiple lock files detected ({{lockFiles}}), which may cause inconsistent dependencies and hot-updating issues.',
lockBestPractice: ` lockBestPractice: `
Best practices for lock files: Best practices for lock files:
1. All members of the development team should use the same package manager to maintain a single lock file. 1. All members of the development team should use the same package manager to maintain a single lock file.
@@ -14,4 +14,30 @@ Best practices for lock files:
3. Pay attention to changes in the lock file during code review. 3. Pay attention to changes in the lock file during code review.
This can reduce the risk of inconsistent dependencies and supply chain attacks. This can reduce the risk of inconsistent dependencies and supply chain attacks.
`, `,
loginExpired:
'Login information has expired. Please use `cresc login` command to re-login',
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}}',
bundleNotFound:
'Bundle file not found. Please ensure that this {{packageType}} is a release version and the bundle file name is the default `{{entryFile}}`',
buildTimeNotFound:
'Cannot get the build timestamp of this package. Please update `react-native-update` to the latest version and re-package and upload.',
latestVersionTag: '(latest: {{version}})',
rnuVersionNotFound:
'react-native-update: Cannot get the version number. Please run the command in the project directory',
unsupportedPlatform: 'Unsupported platform `{{platform}}`',
appId: 'App ID',
appName: 'App Name',
platform: 'Platform',
totalApps: 'Total {{count}} apps',
appNotSelected:
'App not selected. run `cresc selectApp --platform {{platform}}` first!',
enterAppIdQuestion: 'Enter AppId:',
appNameQuestion: 'App Name:',
platformQuestion: 'Platform(ios/android/harmony):',
createAppSuccess: 'App created successfully (id: {{id}})',
cancelled: 'Cancelled',
operationSuccess: 'Operation successful',
failedToParseUpdateJson: 'Failed to parse file `update.json`. Try to remove it manually.',
ppkPackageGenerated: 'ppk package generated and saved to: {{- output}}',
}; };

View File

@@ -12,5 +12,30 @@ export default {
这样可以最大限度避免因依赖关系不一致而导致的热更异常,也降低供应链攻击等安全隐患。 这样可以最大限度避免因依赖关系不一致而导致的热更异常,也降低供应链攻击等安全隐患。
`, `,
multipleLocksFound: multipleLocksFound:
'检测到多种不同格式的锁文件({lockFiles}),这可能导致依赖关系不一致而使热更异常。', '检测到多种不同格式的锁文件({{lockFiles}}),这可能导致依赖关系不一致而使热更异常。',
loginExpired: '登录信息已过期,请使用 `pushy login` 命令重新登录',
fileSizeExceeded:
'此文件大小 {{fileSize}} , 超出当前额度 {{maxSize}} 。您可以考虑升级付费业务以提升此额度。详情请访问: {{pricingPageUrl}}',
bundleNotFound:
'找不到 bundle 文件。请确保此 {{packageType}} 为 release 版本,且 bundle 文件名为默认的 `{{entryFile}}`',
buildTimeNotFound:
'无法获取此包的编译时间戳。请更新 `react-native-update` 到最新版本后重新打包上传。',
latestVersionTag: '(最新:{{version}}',
rnuVersionNotFound:
'react-native-update: 无法获取版本号。请在项目目录中运行命令',
unsupportedPlatform: '无法识别的平台 `{{platform}}`',
appId: '应用 id',
appName: '应用名称',
platform: '平台',
totalApps: '共 {{count}} 个{{platform}}应用',
appNotSelected:
'尚未选择应用。请先运行 `pushy selectApp --platform {{platform}}` 来选择应用',
enterAppIdQuestion: '输入应用 id:',
appNameQuestion: '应用名称:',
platformQuestion: '平台(ios/android/harmony):',
createAppSuccess: '已成功创建应用id: {{id}}',
cancelled: '已取消',
operationSuccess: '操作成功',
failedToParseUpdateJson: '无法解析文件 `update.json`。请手动删除它。',
ppkPackageGenerated: 'ppk 热更包已生成并保存到: {{- output}}',
}; };

View File

@@ -0,0 +1,34 @@
import fs from 'node:fs';
// import path from 'node:path';
import { credentialFile, tempDir } from './constants';
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(`Added ${line} to .gitignore`);
}
fs.writeFileSync(gitignorePath, gitignoreLines.join('\n'));
}
}

View File

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

View File

@@ -0,0 +1,29 @@
import fs from 'node:fs';
import { t } from './i18n';
const lockFiles = [
'package-lock.json',
'yarn.lock',
'pnpm-lock.yaml',
'bun.lockb',
'bun.lock',
];
const existingLockFiles: string[] = [];
export function checkLockFiles() {
for (const file of lockFiles) {
if (fs.existsSync(file)) {
existingLockFiles.push(file);
}
}
if (existingLockFiles.length === 1) {
return;
}
console.warn(t('lockBestPractice'));
if (existingLockFiles.length === 0) {
throw new Error(t('lockNotFound'));
}
throw new Error(
t('multipleLocksFound', { lockFiles: existingLockFiles.join(', ') }),
);
}

View File

@@ -17,10 +17,10 @@ export async function checkPlugins(): Promise<BundleParams> {
const isEnabled = await plugin.detect(); const isEnabled = await plugin.detect();
if (isEnabled && plugin.bundleParams) { if (isEnabled && plugin.bundleParams) {
Object.assign(params, plugin.bundleParams); Object.assign(params, plugin.bundleParams);
console.log(`检测到 ${plugin.name} 插件,应用相应打包配置`); console.log(`detected ${plugin.name} plugin`);
} }
} catch (err) { } catch (err) {
console.warn(`检测 ${plugin.name} 插件时出错:`, err); console.warn(`error while detecting ${plugin.name} plugin:`, err);
} }
} }

View File

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

View File

@@ -41,7 +41,7 @@ export async function getCommitInfo(): Promise<CommitInfo | undefined> {
message: commit.message, message: commit.message,
author: commit.author.name || commit.committer.name, author: commit.author.name || commit.committer.name,
timestamp: String(commit.committer.timestamp), timestamp: String(commit.committer.timestamp),
origin: origin.url, origin: origin?.url,
}; };
} catch (error) { } catch (error) {
console.error(error); console.error(error);

View File

@@ -2,12 +2,18 @@ import i18next from 'i18next';
import en from '../locales/en'; import en from '../locales/en';
import zh from '../locales/zh'; import zh from '../locales/zh';
import { IS_CRESC } from './constants'; import { IS_CRESC } from './constants';
i18next.init({ i18next.init({
lng: IS_CRESC ? 'en' : 'zh', lng: IS_CRESC ? 'en' : 'zh',
// debug: process.env.NODE_ENV !== 'production', // debug: process.env.NODE_ENV !== 'production',
// debug: true,
resources: { resources: {
en, en: {
zh, translation: en,
},
zh: {
translation: zh,
},
}, },
}); });

View File

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

View File

@@ -1,7 +0,0 @@
const lockFiles = [
'package-lock.json',
'yarn.lock',
'pnpm-lock.yaml',
'bun.lockb',
'bun.lock',
];

View File

@@ -6,6 +6,7 @@ import { choosePackage } from './package';
import { compare } from 'compare-versions'; import { compare } from 'compare-versions';
import { depVersions } from './utils/dep-versions'; import { depVersions } from './utils/dep-versions';
import { getCommitInfo } from './utils/git'; import { getCommitInfo } from './utils/git';
import { Platform } from 'types';
async function showVersion(appId: string, offset: number) { async function showVersion(appId: string, offset: number) {
const { data, count } = await get(`/app/${appId}/version/list`); const { data, count } = await get(`/app/${appId}/version/list`);
@@ -61,7 +62,7 @@ async function chooseVersion(appId: string) {
const cmd = await question( const cmd = await question(
'Enter versionId or page Up/page Down/Begin(U/D/B)', 'Enter versionId or page Up/page Down/Begin(U/D/B)',
); );
switch (cmd.toLowerCase()) { switch (cmd.toUpperCase()) {
case 'U': case 'U':
offset = Math.max(0, offset - 10); offset = Math.max(0, offset - 10);
break; break;
@@ -82,7 +83,12 @@ async function chooseVersion(appId: string) {
} }
export const commands = { export const commands = {
publish: async function ({ args, options }) { publish: async function ({ args, options }: { args: string[]; options: {
name: string;
description?: string;
metaInfo?: string;
platform?: Platform;
} }) {
const fn = args[0]; const fn = args[0];
const { name, description, metaInfo } = options; const { name, description, metaInfo } = options;
@@ -136,7 +142,7 @@ export const commands = {
versionId = null; versionId = null;
} }
let pkgId; let pkgId: string | undefined;
let pkgVersion = options.packageVersion; let pkgVersion = options.packageVersion;
let minPkgVersion = options.minPackageVersion; let minPkgVersion = options.minPackageVersion;
let maxPkgVersion = options.maxPackageVersion; let maxPkgVersion = options.maxPackageVersion;