mirror of
https://gitcode.com/github-mirrors/react-native-update-cli.git
synced 2025-09-16 01:41:37 +08:00
add logic to support multi language (#11)
* add logic to support multi language * Update en.ts * Update en.ts --------- Co-authored-by: Sunny Luo <sunnylqm@gmail.com>
This commit is contained in:
@@ -214,17 +214,13 @@ async function runReactNativeBundleCommand({
|
|||||||
|
|
||||||
reactNativeBundleProcess.on('close', async (exitCode) => {
|
reactNativeBundleProcess.on('close', async (exitCode) => {
|
||||||
if (exitCode) {
|
if (exitCode) {
|
||||||
reject(
|
reject(new Error(t('bundleCommandError', { code: exitCode })));
|
||||||
new Error(
|
|
||||||
`"react-native bundle" command exited with code ${exitCode}.`,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
let hermesEnabled: boolean | undefined = false;
|
let hermesEnabled: boolean | undefined = false;
|
||||||
|
|
||||||
if (disableHermes) {
|
if (disableHermes) {
|
||||||
hermesEnabled = false;
|
hermesEnabled = false;
|
||||||
console.log('Hermes disabled');
|
console.log(t('hermesDisabled'));
|
||||||
} else if (platform === 'android') {
|
} else if (platform === 'android') {
|
||||||
const gradlePropeties = await new Promise<{
|
const gradlePropeties = await new Promise<{
|
||||||
hermesEnabled?: boolean;
|
hermesEnabled?: boolean;
|
||||||
@@ -283,8 +279,8 @@ async function copyHarmonyBundle(outputFolder: string) {
|
|||||||
await fs.ensureDir(outputFolder);
|
await fs.ensureDir(outputFolder);
|
||||||
await fs.copy(harmonyRawPath, outputFolder);
|
await fs.copy(harmonyRawPath, outputFolder);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('copyHarmonyBundle 错误:', error);
|
console.error(t('copyHarmonyBundleError', { error }));
|
||||||
throw new Error(`复制文件失败: ${error.message}`);
|
throw new Error(t('copyFileFailed', { error: error.message }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +351,7 @@ async function compileHermesByteCode(
|
|||||||
);
|
);
|
||||||
args.push('-output-source-map');
|
args.push('-output-source-map');
|
||||||
}
|
}
|
||||||
console.log(`Running hermesc: ${hermesCommand} ${args.join(' ')}`);
|
console.log(t('runningHermesc', { command: hermesCommand, args: args.join(' ') }));
|
||||||
spawnSync(hermesCommand, args, {
|
spawnSync(hermesCommand, args, {
|
||||||
stdio: 'ignore',
|
stdio: 'ignore',
|
||||||
});
|
});
|
||||||
@@ -365,7 +361,7 @@ async function compileHermesByteCode(
|
|||||||
if (!fs.existsSync(composerPath)) {
|
if (!fs.existsSync(composerPath)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('Composing source map');
|
console.log(t('composingSourceMap'));
|
||||||
spawnSync(
|
spawnSync(
|
||||||
'node',
|
'node',
|
||||||
[
|
[
|
||||||
@@ -400,16 +396,14 @@ async function copyDebugidForSentry(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(
|
console.error(t('sentryCliNotFound'));
|
||||||
'无法找到 Sentry copy-debugid.js 脚本文件,请确保已正确安装 @sentry/react-native',
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(copyDebugidPath)) {
|
if (!fs.existsSync(copyDebugidPath)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('Copying debugid');
|
console.log(t('copyingDebugId'));
|
||||||
spawnSync(
|
spawnSync(
|
||||||
'node',
|
'node',
|
||||||
[
|
[
|
||||||
@@ -453,9 +447,9 @@ async function uploadSourcemapForSentry(
|
|||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
console.log(`Sentry release created for version: ${version}`);
|
console.log(t('sentryReleaseCreated', { version }));
|
||||||
|
|
||||||
console.log('Uploading sourcemap');
|
console.log(t('uploadingSourcemap'));
|
||||||
spawnSync(
|
spawnSync(
|
||||||
'node',
|
'node',
|
||||||
[
|
[
|
||||||
@@ -479,7 +473,7 @@ async function uploadSourcemapForSentry(
|
|||||||
const ignorePackingFileNames = ['.', '..', 'index.bundlejs.map'];
|
const ignorePackingFileNames = ['.', '..', 'index.bundlejs.map'];
|
||||||
const ignorePackingExtensions = ['DS_Store','txt.map'];
|
const ignorePackingExtensions = ['DS_Store','txt.map'];
|
||||||
async function pack(dir: string, output: string) {
|
async function pack(dir: string, output: string) {
|
||||||
console.log('Packing');
|
console.log(t('packing'));
|
||||||
fs.ensureDirSync(path.dirname(output));
|
fs.ensureDirSync(path.dirname(output));
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
const zipfile = new ZipFile();
|
const zipfile = new ZipFile();
|
||||||
@@ -516,7 +510,7 @@ async function pack(dir: string, output: string) {
|
|||||||
});
|
});
|
||||||
zipfile.end();
|
zipfile.end();
|
||||||
});
|
});
|
||||||
console.log(t('ppkPackageGenerated', { output }));
|
console.log(t('fileGenerated', { file: output }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readEntire(entry: string, zipFile: ZipFile) {
|
export function readEntire(entry: string, zipFile: ZipFile) {
|
||||||
@@ -671,7 +665,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|||||||
|
|
||||||
for (const k in originEntries) {
|
for (const k in originEntries) {
|
||||||
if (!newEntries[k]) {
|
if (!newEntries[k]) {
|
||||||
console.log(`Delete ${k}`);
|
console.log(t('deleteFile', { file: k }));
|
||||||
deletes[k] = 1;
|
deletes[k] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -844,7 +838,7 @@ export async function enumZipEntries(
|
|||||||
await result;
|
await result;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('处理文件时出错:', error);
|
console.error(t('processingError', { error }));
|
||||||
}
|
}
|
||||||
|
|
||||||
zipfile.readEntry();
|
zipfile.readEntry();
|
||||||
@@ -860,7 +854,7 @@ function diffArgsCheck(args, options, diffFn) {
|
|||||||
const [origin, next] = args;
|
const [origin, next] = args;
|
||||||
|
|
||||||
if (!origin || !next) {
|
if (!origin || !next) {
|
||||||
console.error(`Usage: pushy ${diffFn} <origin> <next>`);
|
console.error(t('usageDiff', { command: diffFn }));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -927,7 +921,7 @@ export const commands = {
|
|||||||
const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
|
const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
|
||||||
|
|
||||||
if (!platform) {
|
if (!platform) {
|
||||||
throw new Error('Platform must be specified.');
|
throw new Error(t('platformRequired'));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Bundling with react-native: ${depVersions['react-native']}`);
|
console.log(`Bundling with react-native: ${depVersions['react-native']}`);
|
||||||
@@ -972,14 +966,14 @@ export const commands = {
|
|||||||
async diff({ args, options }) {
|
async diff({ args, options }) {
|
||||||
const { origin, next, realOutput } = diffArgsCheck(args, options, 'diff');
|
const { origin, next, realOutput } = diffArgsCheck(args, options, 'diff');
|
||||||
|
|
||||||
await diffFromPPK(origin, next, realOutput, 'index.bundlejs');
|
await diffFromPPK(origin, next, realOutput);
|
||||||
console.log(`${realOutput} generated.`);
|
console.log(`${realOutput} generated.`);
|
||||||
},
|
},
|
||||||
|
|
||||||
async hdiff({ args, options }) {
|
async hdiff({ args, options }) {
|
||||||
const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiff');
|
const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiff');
|
||||||
|
|
||||||
await diffFromPPK(origin, next, realOutput, 'index.bundlejs');
|
await diffFromPPK(origin, next, realOutput);
|
||||||
console.log(`${realOutput} generated.`);
|
console.log(`${realOutput} generated.`);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@@ -40,4 +40,52 @@ This can reduce the risk of inconsistent dependencies and supply chain attacks.
|
|||||||
operationSuccess: 'Operation successful',
|
operationSuccess: 'Operation successful',
|
||||||
failedToParseUpdateJson: 'Failed to parse file `update.json`. Try to remove it manually.',
|
failedToParseUpdateJson: 'Failed to parse file `update.json`. Try to remove it manually.',
|
||||||
ppkPackageGenerated: 'ppk package generated and saved to: {{- output}}',
|
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',
|
||||||
|
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',
|
||||||
|
operationComplete: 'Operation complete, bound to {{count}} native versions',
|
||||||
|
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}}',
|
||||||
|
rolloutConfigSet: 'Set {{rollout}}% rollout for version {{version}} on native version(s) {{versions}}',
|
||||||
|
versionBind: 'Bound version {{version}} to native version {{nativeVersion}} (id: {{id}})',
|
||||||
};
|
};
|
||||||
|
@@ -38,4 +38,52 @@ export default {
|
|||||||
operationSuccess: '操作成功',
|
operationSuccess: '操作成功',
|
||||||
failedToParseUpdateJson: '无法解析文件 `update.json`。请手动删除它。',
|
failedToParseUpdateJson: '无法解析文件 `update.json`。请手动删除它。',
|
||||||
ppkPackageGenerated: 'ppk 热更包已生成并保存到: {{- output}}',
|
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 的整数',
|
||||||
|
nativeVersionNotFound: '未查询到 >= {{version}} 的原生版本',
|
||||||
|
nativeVersionNotFoundLess: '未查询到 <= {{version}} 的原生版本',
|
||||||
|
nativeVersionNotFoundMatch: '未查询到匹配原生版本:{{version}}',
|
||||||
|
packageIdRequired: '请提供 packageId 或 packageVersion 参数',
|
||||||
|
operationComplete: '操作完成,共已绑定 {{count}} 个原生版本',
|
||||||
|
platformRequired: '必须指定平台。',
|
||||||
|
bundleCommandError: '"react-native bundle" 命令退出,代码为 {{code}}。',
|
||||||
|
copyHarmonyBundleError: '复制 Harmony bundle 错误:{{error}}',
|
||||||
|
copyFileFailed: '复制文件失败:{{error}}',
|
||||||
|
deleteFile: '删除 {{file}}',
|
||||||
|
rolloutConfigSet: '已在原生版本 {{versions}} 上设置灰度发布 {{rollout}}% 热更版本 {{version}}',
|
||||||
|
versionBind: '已将热更版本 {{version}} 绑定到原生版本 {{nativeVersion}} (id: {{id}})',
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { get, post, uploadFile } from './api';
|
import { get, post, uploadFile } from './api';
|
||||||
import { question, saveToLocal } from './utils';
|
import { question, saveToLocal } from './utils';
|
||||||
|
import { t } from './utils/i18n';
|
||||||
|
|
||||||
import { checkPlatform, getSelectedApp } from './app';
|
import { checkPlatform, getSelectedApp } from './app';
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ export async function listPackage(appId: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log(Table(header, rows).render());
|
console.log(Table(header, rows).render());
|
||||||
console.log(`\n共 ${data.length} 个包`);
|
console.log(t('totalPackages', { count: data.length }));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ export const commands = {
|
|||||||
uploadIpa: async ({ args }: { args: string[] }) => {
|
uploadIpa: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
if (!fn || !fn.endsWith('.ipa')) {
|
if (!fn || !fn.endsWith('.ipa')) {
|
||||||
throw new Error('使用方法: pushy uploadIpa ipa后缀文件');
|
throw new Error(t('usageUploadIpa'));
|
||||||
}
|
}
|
||||||
const {
|
const {
|
||||||
versionName,
|
versionName,
|
||||||
@@ -93,7 +94,7 @@ export const commands = {
|
|||||||
uploadApk: async ({ args }: { args: string[] }) => {
|
uploadApk: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
if (!fn || !fn.endsWith('.apk')) {
|
if (!fn || !fn.endsWith('.apk')) {
|
||||||
throw new Error('使用方法: pushy uploadApk apk后缀文件');
|
throw new Error(t('usageUploadApk'));
|
||||||
}
|
}
|
||||||
const {
|
const {
|
||||||
versionName,
|
versionName,
|
||||||
@@ -132,7 +133,7 @@ export const commands = {
|
|||||||
uploadApp: async ({ args }: { args: string[] }) => {
|
uploadApp: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
if (!fn || !fn.endsWith('.app')) {
|
if (!fn || !fn.endsWith('.app')) {
|
||||||
throw new Error('使用方法: pushy uploadApp app后缀文件');
|
throw new Error(t('usageUploadApp'));
|
||||||
}
|
}
|
||||||
const {
|
const {
|
||||||
versionName,
|
versionName,
|
||||||
@@ -171,21 +172,21 @@ export const commands = {
|
|||||||
parseApp: async ({ args }: { args: string[] }) => {
|
parseApp: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
if (!fn || !fn.endsWith('.app')) {
|
if (!fn || !fn.endsWith('.app')) {
|
||||||
throw new Error('使用方法: pushy parseApp app后缀文件');
|
throw new Error(t('usageParseApp'));
|
||||||
}
|
}
|
||||||
console.log(await getAppInfo(fn));
|
console.log(await getAppInfo(fn));
|
||||||
},
|
},
|
||||||
parseIpa: async ({ args }: { args: string[] }) => {
|
parseIpa: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
if (!fn || !fn.endsWith('.ipa')) {
|
if (!fn || !fn.endsWith('.ipa')) {
|
||||||
throw new Error('使用方法: pushy parseIpa ipa后缀文件');
|
throw new Error(t('usageParseIpa'));
|
||||||
}
|
}
|
||||||
console.log(await getIpaInfo(fn));
|
console.log(await getIpaInfo(fn));
|
||||||
},
|
},
|
||||||
parseApk: async ({ args }: { args: string[] }) => {
|
parseApk: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
if (!fn || !fn.endsWith('.apk')) {
|
if (!fn || !fn.endsWith('.apk')) {
|
||||||
throw new Error('使用方法: pushy parseApk apk后缀文件');
|
throw new Error(t('usageParseApk'));
|
||||||
}
|
}
|
||||||
console.log(await getApkInfo(fn));
|
console.log(await getApkInfo(fn));
|
||||||
},
|
},
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import { question } from './utils';
|
import { question } from './utils';
|
||||||
import { post, get, replaceSession, saveSession, closeSession } from './api';
|
import { post, get, replaceSession, saveSession, closeSession } from './api';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
|
import { t } from './utils/i18n';
|
||||||
|
|
||||||
function md5(str: string) {
|
function md5(str: string) {
|
||||||
return crypto.createHash('md5').update(str).digest('hex');
|
return crypto.createHash('md5').update(str).digest('hex');
|
||||||
@@ -16,11 +17,11 @@ export const commands = {
|
|||||||
});
|
});
|
||||||
replaceSession({ token });
|
replaceSession({ token });
|
||||||
await saveSession();
|
await saveSession();
|
||||||
console.log(`欢迎使用 pushy 热更新服务, ${info.name}.`);
|
console.log(t('welcomeMessage', { name: info.name }));
|
||||||
},
|
},
|
||||||
logout: async () => {
|
logout: async () => {
|
||||||
await closeSession();
|
await closeSession();
|
||||||
console.log('已退出登录');
|
console.log(t('loggedOut'));
|
||||||
},
|
},
|
||||||
me: async () => {
|
me: async () => {
|
||||||
const me = await get('/user/me');
|
const me = await get('/user/me');
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
// import path from 'node:path';
|
// import path from 'node:path';
|
||||||
import { credentialFile, tempDir } from './constants';
|
import { credentialFile, tempDir } from './constants';
|
||||||
|
import { t } from './i18n';
|
||||||
|
|
||||||
export function addGitIgnore() {
|
export function addGitIgnore() {
|
||||||
const shouldIgnore = [credentialFile, tempDir];
|
const shouldIgnore = [credentialFile, tempDir];
|
||||||
@@ -26,7 +27,7 @@ export function addGitIgnore() {
|
|||||||
gitignoreLines.push('# react-native-update');
|
gitignoreLines.push('# react-native-update');
|
||||||
for (const line of shouldIgnore) {
|
for (const line of shouldIgnore) {
|
||||||
gitignoreLines.push(line);
|
gitignoreLines.push(line);
|
||||||
console.log(`Added ${line} to .gitignore`);
|
console.log(t('addedToGitignore', { line }));
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(gitignorePath, gitignoreLines.join('\n'));
|
fs.writeFileSync(gitignorePath, gitignoreLines.join('\n'));
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { plugins } from './plugin-config';
|
import { plugins } from './plugin-config';
|
||||||
|
import { t } from './i18n';
|
||||||
|
|
||||||
interface BundleParams {
|
interface BundleParams {
|
||||||
sentry: boolean;
|
sentry: boolean;
|
||||||
@@ -17,10 +18,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(`detected ${plugin.name} plugin`);
|
console.log(t('pluginDetected', { name: plugin.name }));
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(`error while detecting ${plugin.name} plugin:`, err);
|
console.warn(t('pluginDetectionError', { name: plugin.name, error: err }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { get, post, put, uploadFile } from './api';
|
import { get, post, put, uploadFile } from './api';
|
||||||
import { question, saveToLocal } from './utils';
|
import { question, saveToLocal } from './utils';
|
||||||
|
import { t } from './utils/i18n';
|
||||||
|
|
||||||
import { checkPlatform, getSelectedApp } from './app';
|
import { checkPlatform, getSelectedApp } from './app';
|
||||||
import { choosePackage } from './package';
|
import { choosePackage } from './package';
|
||||||
@@ -35,7 +36,7 @@ interface CommandOptions {
|
|||||||
|
|
||||||
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`);
|
||||||
console.log(`Offset ${offset}`);
|
console.log(t('offset', { offset }));
|
||||||
for (const version of data) {
|
for (const version of data) {
|
||||||
const pkgCount = version.packages?.length || 0;
|
const pkgCount = version.packages?.length || 0;
|
||||||
let packageInfo = '';
|
let packageInfo = '';
|
||||||
@@ -149,7 +150,7 @@ export const commands = {
|
|||||||
});
|
});
|
||||||
// TODO local diff
|
// TODO local diff
|
||||||
saveToLocal(fn, `${appId}/ppk/${id}.ppk`);
|
saveToLocal(fn, `${appId}/ppk/${id}.ppk`);
|
||||||
console.log(`已成功上传新热更包(id: ${id})`);
|
console.log(t('packageUploadSuccess', { id }));
|
||||||
|
|
||||||
const v = await question('是否现在将此热更应用到原生包上?(Y/N)');
|
const v = await question('是否现在将此热更应用到原生包上?(Y/N)');
|
||||||
if (v.toLowerCase() === 'y') {
|
if (v.toLowerCase() === 'y') {
|
||||||
@@ -192,10 +193,10 @@ export const commands = {
|
|||||||
try {
|
try {
|
||||||
rollout = Number.parseInt(options.rollout);
|
rollout = Number.parseInt(options.rollout);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error('rollout 必须是 1-100 的整数');
|
throw new Error(t('rolloutRangeError'));
|
||||||
}
|
}
|
||||||
if (rollout < 1 || rollout > 100) {
|
if (rollout < 1 || rollout > 100) {
|
||||||
throw new Error('rollout 必须是 1-100 的整数');
|
throw new Error(t('rolloutRangeError'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +207,7 @@ export const commands = {
|
|||||||
compare(pkg.name, minPkgVersion, '>='),
|
compare(pkg.name, minPkgVersion, '>='),
|
||||||
);
|
);
|
||||||
if (pkgs.length === 0) {
|
if (pkgs.length === 0) {
|
||||||
throw new Error(`未查询到 >= ${minPkgVersion} 的原生版本`);
|
throw new Error(t('nativeVersionNotFound', { version: minPkgVersion }));
|
||||||
}
|
}
|
||||||
if (rollout !== undefined) {
|
if (rollout !== undefined) {
|
||||||
const rolloutConfig: Record<string, number> = {};
|
const rolloutConfig: Record<string, number> = {};
|
||||||
@@ -219,9 +220,10 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log(
|
console.log(
|
||||||
`已在原生版本 ${pkgs
|
`${t('rolloutConfigSet', {
|
||||||
.map((pkg: Package) => pkg.name)
|
versions: pkgs.map((pkg: Package) => pkg.name).join(', '),
|
||||||
.join(', ')} 上设置灰度发布 ${rollout}% 热更版本 ${versionId}`,
|
rollout: rollout,
|
||||||
|
})}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for (const pkg of pkgs) {
|
for (const pkg of pkgs) {
|
||||||
@@ -229,10 +231,14 @@ export const commands = {
|
|||||||
versionId,
|
versionId,
|
||||||
});
|
});
|
||||||
console.log(
|
console.log(
|
||||||
`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name} (id: ${pkg.id})`,
|
`${t('versionBind', {
|
||||||
|
version: versionId,
|
||||||
|
nativeVersion: pkg.name,
|
||||||
|
id: pkg.id,
|
||||||
|
})}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
console.log(`操作完成,共已绑定 ${pkgs.length} 个原生版本`);
|
console.log(t('operationComplete', { count: pkgs.length }));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (maxPkgVersion) {
|
if (maxPkgVersion) {
|
||||||
@@ -242,7 +248,7 @@ export const commands = {
|
|||||||
compare(pkg.name, maxPkgVersion, '<='),
|
compare(pkg.name, maxPkgVersion, '<='),
|
||||||
);
|
);
|
||||||
if (pkgs.length === 0) {
|
if (pkgs.length === 0) {
|
||||||
throw new Error(`未查询到 <= ${maxPkgVersion} 的原生版本`);
|
throw new Error(t('nativeVersionNotFoundLess', { version: maxPkgVersion }));
|
||||||
}
|
}
|
||||||
if (rollout !== undefined) {
|
if (rollout !== undefined) {
|
||||||
const rolloutConfig: Record<string, number> = {};
|
const rolloutConfig: Record<string, number> = {};
|
||||||
@@ -255,9 +261,10 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log(
|
console.log(
|
||||||
`已在原生版本 ${pkgs
|
`${t('rolloutConfigSet', {
|
||||||
.map((pkg: Package) => pkg.name)
|
versions: pkgs.map((pkg: Package) => pkg.name).join(', '),
|
||||||
.join(', ')} 上设置灰度发布 ${rollout}% 热更版本 ${versionId}`,
|
rollout: rollout,
|
||||||
|
})}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for (const pkg of pkgs) {
|
for (const pkg of pkgs) {
|
||||||
@@ -265,10 +272,14 @@ export const commands = {
|
|||||||
versionId,
|
versionId,
|
||||||
});
|
});
|
||||||
console.log(
|
console.log(
|
||||||
`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name} (id: ${pkg.id})`,
|
`${t('versionBind', {
|
||||||
|
version: versionId,
|
||||||
|
nativeVersion: pkg.name,
|
||||||
|
id: pkg.id,
|
||||||
|
})}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
console.log(`操作完成,共已绑定 ${pkgs.length} 个原生版本`);
|
console.log(t('operationComplete', { count: pkgs.length }));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +290,7 @@ export const commands = {
|
|||||||
if (pkg) {
|
if (pkg) {
|
||||||
pkgId = pkg.id;
|
pkgId = pkg.id;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`未查询到匹配原生版本:${pkgVersion}`);
|
throw new Error(t('nativeVersionNotFoundMatch', { version: pkgVersion }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pkgId) {
|
if (!pkgId) {
|
||||||
@@ -287,7 +298,7 @@ export const commands = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pkgId) {
|
if (!pkgId) {
|
||||||
throw new Error('请提供 packageId 或 packageVersion 参数');
|
throw new Error(t('packageIdRequired'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pkgVersion) {
|
if (!pkgVersion) {
|
||||||
@@ -306,7 +317,10 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log(
|
console.log(
|
||||||
`已将在原生版本 ${pkgVersion} (id: ${pkgId}) 上设置灰度发布 ${rollout}% 热更版本 ${versionId} `,
|
`${t('rolloutConfigSet', {
|
||||||
|
versions: pkgVersion,
|
||||||
|
rollout: rollout,
|
||||||
|
})}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,9 +329,14 @@ export const commands = {
|
|||||||
versionId,
|
versionId,
|
||||||
});
|
});
|
||||||
console.log(
|
console.log(
|
||||||
`已将热更版本 ${versionId} 绑定到原生版本 ${pkgVersion} (id: ${pkgId})`,
|
`${t('versionBind', {
|
||||||
|
version: versionId,
|
||||||
|
nativeVersion: pkgVersion,
|
||||||
|
id: pkgId,
|
||||||
|
})}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
console.log(t('operationSuccess'));
|
||||||
},
|
},
|
||||||
updateVersionInfo: async ({
|
updateVersionInfo: async ({
|
||||||
args,
|
args,
|
||||||
@@ -339,6 +358,6 @@ export const commands = {
|
|||||||
if (options.metaInfo) updateParams.metaInfo = options.metaInfo;
|
if (options.metaInfo) updateParams.metaInfo = options.metaInfo;
|
||||||
|
|
||||||
await put(`/app/${appId}/version/${versionId}`, updateParams);
|
await put(`/app/${appId}/version/${versionId}`, updateParams);
|
||||||
console.log('操作成功');
|
console.log(t('operationSuccess'));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user