mirror of
https://gitcode.com/github-mirrors/react-native-update-cli.git
synced 2025-09-17 10:02:19 +08:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2e8e242e75 | ||
![]() |
0cfb1a9beb | ||
![]() |
b22c598ca4 | ||
![]() |
573ab60e44 |
35
bun.lock
35
bun.lock
@@ -3,7 +3,7 @@
|
||||
"workspaces": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@badisi/latest-version": "^7.0.13",
|
||||
"@badisi/latest-version": "^7.0.14",
|
||||
"bplist-parser": "^0.3.2",
|
||||
"bytebuffer": "^5.0.1",
|
||||
"cgbi-to-png": "^1.0.7",
|
||||
@@ -31,8 +31,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@swc/cli": "^0.7.2",
|
||||
"@swc/core": "^1.11.21",
|
||||
"@swc/cli": "0.7.3",
|
||||
"@swc/core": "^1.11.24",
|
||||
"@types/filesize-parser": "^1.5.3",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/node": "^22.14.1",
|
||||
@@ -50,10 +50,13 @@
|
||||
"@biomejs/biome",
|
||||
"@swc/core",
|
||||
],
|
||||
"patchedDependencies": {
|
||||
"@badisi/latest-version@7.0.14": "patches/@badisi%2Flatest-version@7.0.14.patch",
|
||||
},
|
||||
"packages": {
|
||||
"@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.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=="],
|
||||
"@badisi/latest-version": ["@badisi/latest-version@7.0.14", "", { "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-/p+0uggyIiv8PkNIcRgUvm/CWWnclJHRSSeYry4iHzXF3m1IXRS6hXKR9dtEgpF3XsvNYEvlGGF/0MBvBACgQA=="],
|
||||
|
||||
"@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,29 +128,29 @@
|
||||
|
||||
"@sindresorhus/is": ["@sindresorhus/is@5.6.0", "", {}, "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g=="],
|
||||
|
||||
"@swc/cli": ["@swc/cli@0.7.2", "", { "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-B73b2Orrd0tauaX3Jct9MxkAI79U3OMHzRB++x2wfyq+JPjgC6foJK6zyY2JI0vsTlaTbGpx9+hsowTQ8RtQFA=="],
|
||||
"@swc/cli": ["@swc/cli@0.7.3", "", { "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-rnVXNnlURjdOuPaBIwZ3TmBA44BF/eP0j154LanlgPEYfau74ige7cpKlKkZr1IBqMOG99lAnYNxQipDWA3hdg=="],
|
||||
|
||||
"@swc/core": ["@swc/core@1.11.21", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.21" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.21", "@swc/core-darwin-x64": "1.11.21", "@swc/core-linux-arm-gnueabihf": "1.11.21", "@swc/core-linux-arm64-gnu": "1.11.21", "@swc/core-linux-arm64-musl": "1.11.21", "@swc/core-linux-x64-gnu": "1.11.21", "@swc/core-linux-x64-musl": "1.11.21", "@swc/core-win32-arm64-msvc": "1.11.21", "@swc/core-win32-ia32-msvc": "1.11.21", "@swc/core-win32-x64-msvc": "1.11.21" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-/Y3BJLcwd40pExmdar8MH2UGGvCBrqNN7hauOMckrEX2Ivcbv3IMhrbGX4od1dnF880Ed8y/E9aStZCIQi0EGw=="],
|
||||
"@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-darwin-arm64": ["@swc/core-darwin-arm64@1.11.21", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v6gjw9YFWvKulCw3ZA1dY+LGMafYzJksm1mD4UZFZ9b36CyHFowYVYug1ajYRIRqEvvfIhHUNV660zTLoVFR8g=="],
|
||||
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.24", "", { "os": "darwin", "cpu": "arm64" }, "sha512-dhtVj0PC1APOF4fl5qT2neGjRLgHAAYfiVP8poJelhzhB/318bO+QCFWAiimcDoyMgpCXOhTp757gnoJJrheWA=="],
|
||||
|
||||
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.21", "", { "os": "darwin", "cpu": "x64" }, "sha512-CUiTiqKlzskwswrx9Ve5NhNoab30L1/ScOfQwr1duvNlFvarC8fvQSgdtpw2Zh3MfnfNPpyLZnYg7ah4kbT9JQ=="],
|
||||
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.24", "", { "os": "darwin", "cpu": "x64" }, "sha512-H/3cPs8uxcj2Fe3SoLlofN5JG6Ny5bl8DuZ6Yc2wr7gQFBmyBkbZEz+sPVgsID7IXuz7vTP95kMm1VL74SO5AQ=="],
|
||||
|
||||
"@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.21", "", { "os": "linux", "cpu": "arm" }, "sha512-YyBTAFM/QPqt1PscD8hDmCLnqPGKmUZpqeE25HXY8OLjl2MUs8+O4KjwPZZ+OGxpdTbwuWFyMoxjcLy80JODvg=="],
|
||||
"@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-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.21", "", { "os": "linux", "cpu": "arm64" }, "sha512-DQD+ooJmwpNsh4acrftdkuwl5LNxxg8U4+C/RJNDd7m5FP9Wo4c0URi5U0a9Vk/6sQNh9aSGcYChDpqCDWEcBw=="],
|
||||
"@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-musl": ["@swc/core-linux-arm64-musl@1.11.21", "", { "os": "linux", "cpu": "arm64" }, "sha512-y1L49+snt1a1gLTYPY641slqy55QotPdtRK9Y6jMi4JBQyZwxC8swWYlQWb+MyILwxA614fi62SCNZNznB3XSA=="],
|
||||
"@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-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.21", "", { "os": "linux", "cpu": "x64" }, "sha512-NesdBXv4CvVEaFUlqKj+GA4jJMNUzK2NtKOrUNEtTbXaVyNiXjFCSaDajMTedEB0jTAd9ybB0aBvwhgkJUWkWA=="],
|
||||
"@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-musl": ["@swc/core-linux-x64-musl@1.11.21", "", { "os": "linux", "cpu": "x64" }, "sha512-qFV60pwpKVOdmX67wqQzgtSrUGWX9Cibnp1CXyqZ9Mmt8UyYGvmGu7p6PMbTyX7vdpVUvWVRf8DzrW2//wmVHg=="],
|
||||
"@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.24", "", { "os": "linux", "cpu": "x64" }, "sha512-DZByJaMVzSfjQKKQn3cqSeqwy6lpMaQDQQ4HPlch9FWtDx/dLcpdIhxssqZXcR2rhaQVIaRQsCqwV6orSDGAGw=="],
|
||||
|
||||
"@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.21", "", { "os": "win32", "cpu": "arm64" }, "sha512-DJJe9k6gXR/15ZZVLv1SKhXkFst8lYCeZRNHH99SlBodvu4slhh/MKQ6YCixINRhCwliHrpXPym8/5fOq8b7Ig=="],
|
||||
"@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-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.21", "", { "os": "win32", "cpu": "ia32" }, "sha512-TqEXuy6wedId7bMwLIr9byds+mKsaXVHctTN88R1UIBPwJA92Pdk0uxDgip0pEFzHB/ugU27g6d8cwUH3h2eIw=="],
|
||||
"@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.24", "", { "os": "win32", "cpu": "ia32" }, "sha512-9pKLIisE/Hh2vJhGIPvSoTK4uBSPxNVyXHmOrtdDot4E1FUUI74Vi8tFdlwNbaj8/vusVnb8xPXsxF1uB0VgiQ=="],
|
||||
|
||||
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.21", "", { "os": "win32", "cpu": "x64" }, "sha512-BT9BNNbMxdpUM1PPAkYtviaV0A8QcXttjs2MDtOeSqqvSJaPtyM+Fof2/+xSwQDmDEFzbGCcn75M5+xy3lGqpA=="],
|
||||
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.24", "", { "os": "win32", "cpu": "x64" }, "sha512-sybnXtOsdB+XvzVFlBVGgRHLqp3yRpHK7CrmpuDKszhj/QhmsaZzY/GHSeALlMtLup13M0gqbcQvsTNlAHTg3w=="],
|
||||
|
||||
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
|
||||
|
||||
|
14
cli.json
14
cli.json
@@ -118,7 +118,7 @@
|
||||
"description": "Bundle javascript and copy assets."
|
||||
},
|
||||
"bundle": {
|
||||
"description": "Bundle javascript code only.",
|
||||
"description": "Bundle javascript code only and optionally publish.",
|
||||
"options": {
|
||||
"dev": {
|
||||
"default": "false",
|
||||
@@ -157,6 +157,18 @@
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
15
package.json
15
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-update-cli",
|
||||
"version": "1.44.1",
|
||||
"version": "1.44.3",
|
||||
"description": "command line tool for react-native-update (remote updates for react native)",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
@@ -14,7 +14,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "swc src -d lib --strip-leading-paths",
|
||||
"prepare": "npm run build && chmod +x lib/index.js",
|
||||
"prepublishOnly": "npm run build && chmod +x lib/index.js",
|
||||
"lint": "tsc --noEmit & biome check --write ."
|
||||
},
|
||||
"repository": {
|
||||
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/reactnativecn/react-native-pushy/tree/master/react-native-pushy-cli",
|
||||
"dependencies": {
|
||||
"@badisi/latest-version": "^7.0.13",
|
||||
"@badisi/latest-version": "^7.0.14",
|
||||
"bplist-parser": "^0.3.2",
|
||||
"bytebuffer": "^5.0.1",
|
||||
"cgbi-to-png": "^1.0.7",
|
||||
@@ -66,8 +66,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@swc/cli": "^0.7.2",
|
||||
"@swc/core": "^1.11.21",
|
||||
"@swc/cli": "0.7.3",
|
||||
"@swc/core": "^1.11.24",
|
||||
"@types/filesize-parser": "^1.5.3",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/node": "^22.14.1",
|
||||
@@ -82,5 +82,8 @@
|
||||
"trustedDependencies": [
|
||||
"@biomejs/biome",
|
||||
"@swc/core"
|
||||
]
|
||||
],
|
||||
"patchedDependencies": {
|
||||
"@badisi/latest-version@7.0.14": "patches/@badisi%2Flatest-version@7.0.14.patch"
|
||||
}
|
||||
}
|
||||
|
23
patches/@badisi%2Flatest-version@7.0.14.patch
Normal file
23
patches/@badisi%2Flatest-version@7.0.14.patch
Normal file
@@ -0,0 +1,23 @@
|
||||
diff --git a/index.js b/index.js
|
||||
index a7af7990160fa54a549cbb6245017d55e6b150f5..74b3372c53b9c693af5b571722bafd97e448a34b 100644
|
||||
--- a/index.js
|
||||
+++ b/index.js
|
||||
@@ -100,7 +100,7 @@ var downloadMetadata = (pkgName, options) => {
|
||||
}
|
||||
});
|
||||
const abort = (error) => {
|
||||
- request.removeAllListeners();
|
||||
+ // request.removeAllListeners();
|
||||
request.destroy();
|
||||
reject(error);
|
||||
};
|
||||
@@ -110,6 +110,9 @@ var downloadMetadata = (pkgName, options) => {
|
||||
request.once("error", (err) => {
|
||||
abort(err);
|
||||
});
|
||||
+ request.on("close", () => {
|
||||
+ request.removeAllListeners();
|
||||
+ });
|
||||
});
|
||||
};
|
||||
var getCacheDir = (name = "@badisi/latest-version") => {
|
109
src/bundle.ts
109
src/bundle.ts
@@ -1,8 +1,12 @@
|
||||
import path from 'node:path';
|
||||
import { translateOptions } from './utils';
|
||||
import * as fs from 'fs-extra';
|
||||
import { ZipFile } from 'yazl';
|
||||
import { open as openZipFile } from 'yauzl';
|
||||
import { ZipFile as YazlZipFile } from 'yazl';
|
||||
import {
|
||||
type Entry,
|
||||
open as openZipFile,
|
||||
type ZipFile as YauzlZipFile,
|
||||
} from 'yauzl';
|
||||
import { question, checkPlugins } from './utils';
|
||||
import { checkPlatform } from './app';
|
||||
import { spawn, spawnSync } from 'node:child_process';
|
||||
@@ -15,10 +19,13 @@ 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';
|
||||
|
||||
let bsdiff;
|
||||
let hdiff;
|
||||
let diff;
|
||||
type Diff = (oldSource?: Buffer, newSource?: Buffer) => Buffer;
|
||||
|
||||
let bsdiff: Diff;
|
||||
let hdiff: Diff;
|
||||
let diff: Diff;
|
||||
try {
|
||||
bsdiff = require('node-bsdiff').diff;
|
||||
} catch (e) {}
|
||||
@@ -59,9 +66,7 @@ async function runReactNativeBundleCommand({
|
||||
if (platform === 'android') {
|
||||
gradleConfig = await checkGradleConfig();
|
||||
if (gradleConfig.crunchPngs !== false) {
|
||||
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',
|
||||
);
|
||||
console.warn(t('androidCrunchPngsWarning'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +326,7 @@ async function compileHermesByteCode(
|
||||
sourcemapOutput: string,
|
||||
shouldCleanSourcemap: boolean,
|
||||
) {
|
||||
console.log('Hermes enabled, now compiling to hermes bytecode:\n');
|
||||
console.log(t('hermesEnabledCompiling'));
|
||||
// >= rn 0.69
|
||||
const rnDir = path.dirname(
|
||||
require.resolve('react-native', {
|
||||
@@ -351,7 +356,9 @@ async function compileHermesByteCode(
|
||||
);
|
||||
args.push('-output-source-map');
|
||||
}
|
||||
console.log(t('runningHermesc', { command: hermesCommand, args: args.join(' ') }));
|
||||
console.log(
|
||||
t('runningHermesc', { command: hermesCommand, args: args.join(' ') }),
|
||||
);
|
||||
spawnSync(hermesCommand, args, {
|
||||
stdio: 'ignore',
|
||||
});
|
||||
@@ -387,7 +394,7 @@ async function copyDebugidForSentry(
|
||||
sourcemapOutput: string,
|
||||
) {
|
||||
if (sourcemapOutput) {
|
||||
let copyDebugidPath;
|
||||
let copyDebugidPath: string | undefined;
|
||||
try {
|
||||
copyDebugidPath = require.resolve(
|
||||
'@sentry/react-native/scripts/copy-debugid.js',
|
||||
@@ -426,13 +433,13 @@ async function uploadSourcemapForSentry(
|
||||
version: string,
|
||||
) {
|
||||
if (sourcemapOutput) {
|
||||
let sentryCliPath;
|
||||
let sentryCliPath: string | undefined;
|
||||
try {
|
||||
sentryCliPath = require.resolve('@sentry/cli/bin/sentry-cli', {
|
||||
paths: [process.cwd()],
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli');
|
||||
console.error(t('sentryCliNotFound'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -471,12 +478,12 @@ async function uploadSourcemapForSentry(
|
||||
}
|
||||
|
||||
const ignorePackingFileNames = ['.', '..', 'index.bundlejs.map'];
|
||||
const ignorePackingExtensions = ['DS_Store','txt.map'];
|
||||
const ignorePackingExtensions = ['DS_Store', 'txt.map'];
|
||||
async function pack(dir: string, output: string) {
|
||||
console.log(t('packing'));
|
||||
fs.ensureDirSync(path.dirname(output));
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const zipfile = new ZipFile();
|
||||
const zipfile = new YazlZipFile();
|
||||
|
||||
function addDirectory(root: string, rel: string) {
|
||||
if (rel) {
|
||||
@@ -513,10 +520,13 @@ async function pack(dir: string, output: string) {
|
||||
console.log(t('fileGenerated', { file: output }));
|
||||
}
|
||||
|
||||
export function readEntire(entry: string, zipFile: ZipFile) {
|
||||
export function readEntry(
|
||||
entry: Entry,
|
||||
zipFile: YauzlZipFile,
|
||||
): Promise<Buffer> {
|
||||
const buffers: Buffer[] = [];
|
||||
return new Promise((resolve, reject) => {
|
||||
zipFile.openReadStream(entry, (err: any, stream: any) => {
|
||||
zipFile.openReadStream(entry, (err, stream) => {
|
||||
stream.pipe({
|
||||
write(chunk: Buffer) {
|
||||
buffers.push(chunk);
|
||||
@@ -544,7 +554,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
||||
const originEntries = {};
|
||||
const originMap = {};
|
||||
|
||||
let originSource;
|
||||
let originSource: Buffer | undefined;
|
||||
|
||||
await enumZipEntries(origin, (entry, zipFile) => {
|
||||
originEntries[entry.fileName] = entry;
|
||||
@@ -557,7 +567,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
||||
entry.fileName === 'bundle.harmony.js'
|
||||
) {
|
||||
// This is source.
|
||||
return readEntire(entry, zipFile).then((v) => (originSource = v));
|
||||
return readEntry(entry, zipFile).then((v) => (originSource = v));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -570,7 +580,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
||||
|
||||
const copies = {};
|
||||
|
||||
const zipfile = new ZipFile();
|
||||
const zipfile = new YazlZipFile();
|
||||
|
||||
const writePromise = new Promise((resolve, reject) => {
|
||||
zipfile.outputStream.on('error', (err) => {
|
||||
@@ -607,7 +617,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
||||
}
|
||||
} else if (entry.fileName === 'index.bundlejs') {
|
||||
//console.log('Found bundle');
|
||||
return readEntire(entry, nextZipfile).then((newSource) => {
|
||||
return readEntry(entry, nextZipfile).then((newSource) => {
|
||||
//console.log('Begin diff');
|
||||
zipfile.addBuffer(
|
||||
diff(originSource, newSource),
|
||||
@@ -617,7 +627,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
||||
});
|
||||
} else if (entry.fileName === 'bundle.harmony.js') {
|
||||
//console.log('Found bundle');
|
||||
return readEntire(entry, nextZipfile).then((newSource) => {
|
||||
return readEntry(entry, nextZipfile).then((newSource) => {
|
||||
//console.log('Begin diff');
|
||||
zipfile.addBuffer(
|
||||
diff(originSource, newSource),
|
||||
@@ -691,9 +701,9 @@ async function diffFromPackage(
|
||||
const originEntries = {};
|
||||
const originMap = {};
|
||||
|
||||
let originSource;
|
||||
let originSource: Buffer | undefined;
|
||||
|
||||
await enumZipEntries(origin, (entry: any, zipFile: any) => {
|
||||
await enumZipEntries(origin, (entry, zipFile) => {
|
||||
if (!/\/$/.test(entry.fileName)) {
|
||||
const fn = transformPackagePath(entry.fileName);
|
||||
if (!fn) {
|
||||
@@ -707,7 +717,7 @@ async function diffFromPackage(
|
||||
|
||||
if (fn === originBundleName) {
|
||||
// This is source.
|
||||
return readEntire(entry, zipFile).then((v) => (originSource = v));
|
||||
return readEntry(entry, zipFile).then((v) => (originSource = v));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -720,7 +730,7 @@ async function diffFromPackage(
|
||||
|
||||
const copies = {};
|
||||
|
||||
const zipfile = new ZipFile();
|
||||
const zipfile = new YazlZipFile();
|
||||
|
||||
const writePromise = new Promise((resolve, reject) => {
|
||||
zipfile.outputStream.on('error', (err) => {
|
||||
@@ -737,7 +747,7 @@ async function diffFromPackage(
|
||||
zipfile.addEmptyDirectory(entry.fileName);
|
||||
} else if (entry.fileName === 'index.bundlejs') {
|
||||
//console.log('Found bundle');
|
||||
return readEntire(entry, nextZipfile).then((newSource) => {
|
||||
return readEntry(entry, nextZipfile).then((newSource) => {
|
||||
//console.log('Begin diff');
|
||||
zipfile.addBuffer(
|
||||
diff(originSource, newSource),
|
||||
@@ -747,7 +757,7 @@ async function diffFromPackage(
|
||||
});
|
||||
} else if (entry.fileName === 'bundle.harmony.js') {
|
||||
//console.log('Found bundle');
|
||||
return readEntire(entry, nextZipfile).then((newSource) => {
|
||||
return readEntry(entry, nextZipfile).then((newSource) => {
|
||||
//console.log('Begin diff');
|
||||
zipfile.addBuffer(
|
||||
diff(originSource, newSource),
|
||||
@@ -789,14 +799,18 @@ async function diffFromPackage(
|
||||
|
||||
export async function enumZipEntries(
|
||||
zipFn: string,
|
||||
callback: (entry: any, zipFile: any) => void,
|
||||
callback: (
|
||||
entry: Entry,
|
||||
zipFile: YauzlZipFile,
|
||||
nestedPath?: string,
|
||||
) => Promise<any>,
|
||||
nestedPath = '',
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openZipFile(
|
||||
zipFn,
|
||||
{ lazyEntries: true },
|
||||
async (err: any, zipfile: ZipFile) => {
|
||||
async (err: any, zipfile: YauzlZipFile) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
@@ -850,7 +864,7 @@ export async function enumZipEntries(
|
||||
});
|
||||
}
|
||||
|
||||
function diffArgsCheck(args, options, diffFn) {
|
||||
function diffArgsCheck(args: string[], options: any, diffFn: string) {
|
||||
const [origin, next] = args;
|
||||
|
||||
if (!origin || !next) {
|
||||
@@ -889,7 +903,7 @@ function diffArgsCheck(args, options, diffFn) {
|
||||
export const commands = {
|
||||
bundle: async function ({ options }) {
|
||||
const platform = checkPlatform(
|
||||
options.platform || (await question('平台(ios/android/harmony):')),
|
||||
options.platform || (await question(t('platformPrompt'))),
|
||||
);
|
||||
|
||||
const {
|
||||
@@ -903,6 +917,9 @@ export const commands = {
|
||||
expo,
|
||||
rncli,
|
||||
disableHermes,
|
||||
name,
|
||||
description,
|
||||
metaInfo,
|
||||
} = translateOptions({
|
||||
...options,
|
||||
tempDir,
|
||||
@@ -943,14 +960,17 @@ export const commands = {
|
||||
|
||||
await pack(path.resolve(intermediaDir), realOutput);
|
||||
|
||||
const v = await question('是否现在上传此热更包?(Y/N)');
|
||||
if (v.toLowerCase() === 'y') {
|
||||
const versionName = await this.publish({
|
||||
if (name) {
|
||||
const versionName = await versionCommands.publish({
|
||||
args: [realOutput],
|
||||
options: {
|
||||
platform,
|
||||
name,
|
||||
description,
|
||||
metaInfo,
|
||||
},
|
||||
});
|
||||
|
||||
if (isSentry) {
|
||||
await copyDebugidForSentry(bundleName, intermediaDir, sourcemapOutput);
|
||||
await uploadSourcemapForSentry(
|
||||
@@ -960,6 +980,25 @@ 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@@ -8,7 +8,6 @@ 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.',
|
||||
);
|
||||
|
@@ -1,10 +1,60 @@
|
||||
export default {
|
||||
loginFirst:
|
||||
'Not logged in.\nPlease run `cresc login` in the project directory to login.',
|
||||
lockNotFound:
|
||||
'No lock file detected, which may cause inconsistent dependencies and hot-updating issues.',
|
||||
multipleLocksFound:
|
||||
'Multiple lock files detected ({{- lockFiles}}), which may cause inconsistent dependencies and hot-updating issues.',
|
||||
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.
|
||||
@@ -12,84 +62,64 @@ Best practices for lock files:
|
||||
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',
|
||||
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}} {{platform}} 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}}',
|
||||
Message: 'Welcome to Cresc hot update service, {{name}}.',
|
||||
loggedOut: 'Logged out',
|
||||
usageUnderDevelopment: 'Usage is under development now.',
|
||||
hermesDisabled: 'Hermes disabled',
|
||||
hermesEnabled: 'Hermes enabled, now compiling to hermes bytecode:\n',
|
||||
runningHermesc: 'Running hermesc: {{command}} {{args}}',
|
||||
composingSourceMap: 'Composing source map',
|
||||
copyingDebugId: 'Copying debugid',
|
||||
sentryCliNotFound:
|
||||
'Cannot find Sentry CLI tool, please make sure @sentry/cli is properly installed',
|
||||
sentryReleaseCreated: 'Sentry release created for version: {{version}}',
|
||||
uploadingSourcemap: 'Uploading sourcemap',
|
||||
packing: 'Packing',
|
||||
deletingFile: 'Delete {{- file}}',
|
||||
bundlingWithRN: 'Bundling with react-native: {{version}}',
|
||||
fileGenerated: '{{- file}} generated.',
|
||||
processingError: 'Error processing file: {{error}}',
|
||||
usageDiff: 'Usage: cresc {{command}} <origin> <next>',
|
||||
pluginDetected: 'detected {{name}} plugin',
|
||||
pluginDetectionError: 'error while detecting {{name}} plugin: {{error}}',
|
||||
addedToGitignore: 'Added {{line}} to .gitignore',
|
||||
processingStringPool: 'Processing the string pool ...',
|
||||
processingPackage: 'Processing the package {{count}} ...',
|
||||
typeStrings: 'Type strings:',
|
||||
keyStrings: 'Key strings:',
|
||||
failedToParseIcon: '[Warning] failed to parse icon: {{error}}',
|
||||
errorInHarmonyApp: 'Error in getEntryFromHarmonyApp: {{error}}',
|
||||
totalPackages: 'Total {{count}} packages',
|
||||
usageUploadIpa: 'Usage: cresc uploadIpa <ipa file>',
|
||||
usageUploadApk: 'Usage: cresc uploadApk <apk file>',
|
||||
usageUploadApp: 'Usage: cresc uploadApp <app file>',
|
||||
usageParseApp: 'Usage: cresc parseApp <app file>',
|
||||
usageParseIpa: 'Usage: cresc parseIpa <ipa file>',
|
||||
usageParseApk: 'Usage: cresc parseApk <apk file>',
|
||||
offset: 'Offset {{offset}}',
|
||||
packageUploadSuccess:
|
||||
'Successfully uploaded new hot update package (id: {{id}})',
|
||||
rolloutRangeError: 'rollout must be an integer between 1-100',
|
||||
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',
|
||||
nativeVersionNotFound: 'No native version found >= {{version}}',
|
||||
nativeVersionNotFoundLess: 'No native version found <= {{version}}',
|
||||
nativeVersionNotFoundMatch: 'No matching native version found: {{version}}',
|
||||
packageIdRequired: 'Please provide packageId or packageVersion parameter',
|
||||
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.',
|
||||
bundleCommandError:
|
||||
'"react-native bundle" command exited with code {{code}}.',
|
||||
copyHarmonyBundleError: 'Error copying Harmony bundle: {{error}}',
|
||||
copyFileFailed: 'Failed to copy file: {{error}}',
|
||||
deleteFile: 'Delete {{- file}}',
|
||||
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 version {{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 version {{version}} to native version {{nativeVersion}} (id: {{id}})',
|
||||
welcomeMessage: 'Welcome to Cresc hot update service, {{name}}.',
|
||||
};
|
||||
|
@@ -1,7 +1,58 @@
|
||||
export default {
|
||||
loginFirst: '尚未登录。\n请在项目目录中运行`pushy login`命令来登录',
|
||||
lockNotFound:
|
||||
'没有检测到任何 lock 文件,这可能导致依赖关系不一致而使热更异常。',
|
||||
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 文件。
|
||||
@@ -9,81 +60,59 @@ export default {
|
||||
3. 代码审核时应关注 lock 文件的变化。
|
||||
这样可以最大限度避免因依赖关系不一致而导致的热更异常,也降低供应链攻击等安全隐患。
|
||||
`,
|
||||
lockNotFound:
|
||||
'没有检测到任何 lock 文件,这可能导致依赖关系不一致而使热更异常。',
|
||||
loggedOut: '已退出登录',
|
||||
loginExpired: '登录信息已过期,请使用 `pushy login` 命令重新登录',
|
||||
loginFirst: '尚未登录。\n请在项目目录中运行`pushy login`命令来登录',
|
||||
multipleLocksFound:
|
||||
'检测到多种不同格式的锁文件({{- 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}}',
|
||||
welcomeMessage: '欢迎使用 pushy 热更新服务,{{name}}。',
|
||||
loggedOut: '已退出登录',
|
||||
usageUnderDevelopment: '使用说明正在开发中。',
|
||||
hermesDisabled: 'Hermes 已禁用',
|
||||
hermesEnabled: 'Hermes 已启用,正在编译为 hermes 字节码:\n',
|
||||
runningHermesc: '运行 hermesc:{{command}} {{args}}',
|
||||
composingSourceMap: '正在生成 source map',
|
||||
copyingDebugId: '正在复制 debugid',
|
||||
sentryCliNotFound: '无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli',
|
||||
sentryReleaseCreated: '已为版本 {{version}} 创建 Sentry release',
|
||||
uploadingSourcemap: '正在上传 sourcemap',
|
||||
packing: '正在打包',
|
||||
deletingFile: '删除 {{- file}}',
|
||||
bundlingWithRN: '正在使用 react-native {{version}} 打包',
|
||||
fileGenerated: '已生成 {{- file}}',
|
||||
processingError: '处理文件时出错:{{error}}',
|
||||
usageDiff: '用法:pushy {{command}} <origin> <next>',
|
||||
pluginDetected: '检测到 {{name}} 插件',
|
||||
pluginDetectionError: '检测 {{name}} 插件时出错:{{error}}',
|
||||
addedToGitignore: '已将 {{line}} 添加到 .gitignore',
|
||||
processingStringPool: '正在处理字符串池...',
|
||||
processingPackage: '正在处理包 {{count}}...',
|
||||
typeStrings: '类型字符串:',
|
||||
keyStrings: '键字符串:',
|
||||
failedToParseIcon: '[警告] 解析图标失败:{{error}}',
|
||||
errorInHarmonyApp: '获取 Harmony 应用入口时出错:{{error}}',
|
||||
totalPackages: '共 {{count}} 个包',
|
||||
usageUploadIpa: '使用方法: pushy uploadIpa ipa后缀文件',
|
||||
usageUploadApk: '使用方法: pushy uploadApk apk后缀文件',
|
||||
usageUploadApp: '使用方法: pushy uploadApp app后缀文件',
|
||||
usageParseApp: '使用方法: pushy parseApp app后缀文件',
|
||||
usageParseIpa: '使用方法: pushy parseIpa ipa后缀文件',
|
||||
usageParseApk: '使用方法: pushy parseApk apk后缀文件',
|
||||
offset: '偏移量 {{offset}}',
|
||||
packageUploadSuccess: '已成功上传新热更包(id: {{id}})',
|
||||
rolloutRangeError: 'rollout 必须是 1-100 的整数',
|
||||
nativePackageId: '原生包 Id',
|
||||
nativeVersion: '原生版本',
|
||||
nativeVersionNotFound: '未查询到 >= {{version}} 的原生版本',
|
||||
nativeVersionNotFoundLess: '未查询到 <= {{version}} 的原生版本',
|
||||
nativeVersionNotFoundMatch: '未查询到匹配原生版本:{{version}}',
|
||||
packageIdRequired: '请提供 packageId 或 packageVersion 参数',
|
||||
offset: '偏移量 {{offset}}',
|
||||
operationComplete: '操作完成,共已绑定 {{count}} 个原生版本',
|
||||
operationSuccess: '操作成功',
|
||||
packageIdRequired: '请提供 packageId 或 packageVersion 参数',
|
||||
packageUploadSuccess: '已成功上传新热更包(id: {{id}})',
|
||||
packing: '正在打包',
|
||||
pausedStatus: '(已暂停)',
|
||||
platform: '平台',
|
||||
platformPrompt: '平台(ios/android/harmony):',
|
||||
platformQuestion: '平台(ios/android/harmony):',
|
||||
platformRequired: '必须指定平台。',
|
||||
bundleCommandError: '"react-native bundle" 命令退出,代码为 {{code}}。',
|
||||
copyHarmonyBundleError: '复制 Harmony bundle 错误:{{error}}',
|
||||
copyFileFailed: '复制文件失败:{{error}}',
|
||||
deleteFile: '删除 {{- file}}',
|
||||
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}}。',
|
||||
};
|
||||
|
@@ -13,22 +13,23 @@ import type { Platform } from 'types';
|
||||
export async function listPackage(appId: string) {
|
||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
||||
|
||||
const header = [{ value: '原生包 Id' }, { value: '原生版本' }];
|
||||
const header = [
|
||||
{ value: t('nativePackageId') },
|
||||
{ value: t('nativeVersion') },
|
||||
];
|
||||
const rows = [];
|
||||
for (const pkg of data) {
|
||||
const { version } = pkg;
|
||||
let versionInfo = '';
|
||||
if (version) {
|
||||
versionInfo = `, 已绑定:${version.name} (${version.id})`;
|
||||
} else {
|
||||
// versionInfo = ' (newest)';
|
||||
versionInfo = t('boundTo', { name: version.name, id: version.id });
|
||||
}
|
||||
let output = pkg.name;
|
||||
if (pkg.status === 'paused') {
|
||||
output += '(已暂停)';
|
||||
output += t('pausedStatus');
|
||||
}
|
||||
if (pkg.status === 'expired') {
|
||||
output += '(已过期)';
|
||||
output += t('expiredStatus');
|
||||
}
|
||||
output += versionInfo;
|
||||
rows.push([pkg.id, output]);
|
||||
@@ -43,7 +44,7 @@ export async function choosePackage(appId: string) {
|
||||
const list = await listPackage(appId);
|
||||
|
||||
while (true) {
|
||||
const id = await question('输入原生包 id:');
|
||||
const id = await question(t('enterNativePackageId'));
|
||||
const app = list.find((v) => v.id === Number(id));
|
||||
if (app) {
|
||||
return app;
|
||||
@@ -66,15 +67,11 @@ export const commands = {
|
||||
const { appId, appKey } = await getSelectedApp('ios');
|
||||
|
||||
if (appIdInPkg && appIdInPkg != appId) {
|
||||
throw new Error(
|
||||
`appId不匹配!当前ipa: ${appIdInPkg}, 当前update.json: ${appId}`,
|
||||
);
|
||||
throw new Error(t('appIdMismatchIpa', { appIdInPkg, appId }));
|
||||
}
|
||||
|
||||
if (appKeyInPkg && appKeyInPkg !== appKey) {
|
||||
throw new Error(
|
||||
`appKey不匹配!当前ipa: ${appKeyInPkg}, 当前update.json: ${appKey}`,
|
||||
);
|
||||
throw new Error(t('appKeyMismatchIpa', { appKeyInPkg, appKey }));
|
||||
}
|
||||
|
||||
const { hash } = await uploadFile(fn);
|
||||
@@ -87,9 +84,7 @@ export const commands = {
|
||||
commit: await getCommitInfo(),
|
||||
});
|
||||
saveToLocal(fn, `${appId}/package/${id}.ipa`);
|
||||
console.log(
|
||||
`已成功上传ipa原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`,
|
||||
);
|
||||
console.log(t('ipaUploadSuccess', { id, version: versionName, buildTime }));
|
||||
},
|
||||
uploadApk: async ({ args }: { args: string[] }) => {
|
||||
const fn = args[0];
|
||||
@@ -105,15 +100,11 @@ export const commands = {
|
||||
const { appId, appKey } = await getSelectedApp('android');
|
||||
|
||||
if (appIdInPkg && appIdInPkg != appId) {
|
||||
throw new Error(
|
||||
`appId不匹配!当前apk: ${appIdInPkg}, 当前update.json: ${appId}`,
|
||||
);
|
||||
throw new Error(t('appIdMismatchApk', { appIdInPkg, appId }));
|
||||
}
|
||||
|
||||
if (appKeyInPkg && appKeyInPkg !== appKey) {
|
||||
throw new Error(
|
||||
`appKey不匹配!当前apk: ${appKeyInPkg}, 当前update.json: ${appKey}`,
|
||||
);
|
||||
throw new Error(t('appKeyMismatchApk', { appKeyInPkg, appKey }));
|
||||
}
|
||||
|
||||
const { hash } = await uploadFile(fn);
|
||||
@@ -126,9 +117,7 @@ export const commands = {
|
||||
commit: await getCommitInfo(),
|
||||
});
|
||||
saveToLocal(fn, `${appId}/package/${id}.apk`);
|
||||
console.log(
|
||||
`已成功上传apk原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`,
|
||||
);
|
||||
console.log(t('apkUploadSuccess', { id, version: versionName, buildTime }));
|
||||
},
|
||||
uploadApp: async ({ args }: { args: string[] }) => {
|
||||
const fn = args[0];
|
||||
@@ -144,15 +133,11 @@ export const commands = {
|
||||
const { appId, appKey } = await getSelectedApp('harmony');
|
||||
|
||||
if (appIdInPkg && appIdInPkg != appId) {
|
||||
throw new Error(
|
||||
`appId不匹配!当前app: ${appIdInPkg}, 当前update.json: ${appId}`,
|
||||
);
|
||||
throw new Error(t('appIdMismatchApp', { appIdInPkg, appId }));
|
||||
}
|
||||
|
||||
if (appKeyInPkg && appKeyInPkg !== appKey) {
|
||||
throw new Error(
|
||||
`appKey不匹配!当前app: ${appKeyInPkg}, 当前update.json: ${appKey}`,
|
||||
);
|
||||
throw new Error(t('appKeyMismatchApp', { appKeyInPkg, appKey }));
|
||||
}
|
||||
|
||||
const { hash } = await uploadFile(fn);
|
||||
@@ -165,9 +150,7 @@ export const commands = {
|
||||
commit: await getCommitInfo(),
|
||||
});
|
||||
saveToLocal(fn, `${appId}/package/${id}.app`);
|
||||
console.log(
|
||||
`已成功上传app原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`,
|
||||
);
|
||||
console.log(t('appUploadSuccess', { id, version: versionName, buildTime }));
|
||||
},
|
||||
parseApp: async ({ args }: { args: string[] }) => {
|
||||
const fn = args[0];
|
||||
@@ -192,7 +175,7 @@ export const commands = {
|
||||
},
|
||||
packages: async ({ options }: { options: { platform: Platform } }) => {
|
||||
const platform = checkPlatform(
|
||||
options.platform || (await question('平台(ios/android/harmony):')),
|
||||
options.platform || (await question(t('platformPrompt'))),
|
||||
);
|
||||
const { appId } = await getSelectedApp(platform);
|
||||
await listPackage(appId);
|
||||
|
@@ -15,6 +15,9 @@ i18next.init({
|
||||
translation: zh,
|
||||
},
|
||||
},
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
});
|
||||
|
||||
declare module 'i18next' {
|
||||
|
@@ -98,7 +98,7 @@ export async function getAppInfo(fn: string) {
|
||||
const metaJsonFile = await appInfoParser.parser.getEntryFromHarmonyApp(
|
||||
/rawfile\/meta.json/,
|
||||
);
|
||||
let metaData = {};
|
||||
let metaData: Record<string, any> = {};
|
||||
if (metaJsonFile) {
|
||||
metaData = JSON.parse(metaJsonFile.toString());
|
||||
}
|
||||
@@ -181,16 +181,13 @@ export async function printVersionCommand() {
|
||||
version: chalk.green(latestRnuCliVersion),
|
||||
})}`
|
||||
: '';
|
||||
console.log(
|
||||
`react-native-update-cli: ${pkg.version}${latestRnuCliVersion}`,
|
||||
);
|
||||
let rnuVersion = '';
|
||||
rnuVersion = depVersions['react-native-update'];
|
||||
latestRnuVersion = latestRnuVersion
|
||||
? ` ${t('latestVersionTag', { version: chalk.green(latestRnuVersion) })}`
|
||||
: '';
|
||||
console.log(`react-native-update: ${rnuVersion}${latestRnuVersion}`);
|
||||
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 (semverSatisfies(rnuVersion, '<10.27.0')) {
|
||||
console.error(
|
||||
|
@@ -125,9 +125,7 @@ export const commands = {
|
||||
const { name, description, metaInfo } = options;
|
||||
|
||||
if (!fn || !fn.endsWith('.ppk')) {
|
||||
throw new Error(
|
||||
'使用方法: pushy publish ppk后缀文件 --platform ios|android|harmony',
|
||||
);
|
||||
throw new Error(t('publishUsage'));
|
||||
}
|
||||
|
||||
const platform = checkPlatform(
|
||||
@@ -204,7 +202,7 @@ export const commands = {
|
||||
minPkgVersion = String(minPkgVersion).trim();
|
||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
||||
const pkgs = data.filter((pkg: Package) =>
|
||||
compare(pkg.name, minPkgVersion, '>='),
|
||||
compare(pkg.name, minPkgVersion!, '>='),
|
||||
);
|
||||
if (pkgs.length === 0) {
|
||||
throw new Error(t('nativeVersionNotFound', { version: minPkgVersion }));
|
||||
@@ -245,10 +243,12 @@ export const commands = {
|
||||
maxPkgVersion = String(maxPkgVersion).trim();
|
||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
||||
const pkgs = data.filter((pkg: Package) =>
|
||||
compare(pkg.name, maxPkgVersion, '<='),
|
||||
compare(pkg.name, maxPkgVersion!, '<='),
|
||||
);
|
||||
if (pkgs.length === 0) {
|
||||
throw new Error(t('nativeVersionNotFoundLess', { version: maxPkgVersion }));
|
||||
throw new Error(
|
||||
t('nativeVersionNotFoundLess', { version: maxPkgVersion }),
|
||||
);
|
||||
}
|
||||
if (rollout !== undefined) {
|
||||
const rolloutConfig: Record<string, number> = {};
|
||||
@@ -290,7 +290,9 @@ export const commands = {
|
||||
if (pkg) {
|
||||
pkgId = pkg.id;
|
||||
} else {
|
||||
throw new Error(t('nativeVersionNotFoundMatch', { version: pkgVersion }));
|
||||
throw new Error(
|
||||
t('nativeVersionNotFoundMatch', { version: pkgVersion }),
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!pkgId) {
|
||||
|
Reference in New Issue
Block a user