mirror of
https://gitcode.com/github-mirrors/react-native-update-cli.git
synced 2025-09-16 01:41:37 +08:00
fix i18n
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-native-update-cli",
|
"name": "react-native-update-cli",
|
||||||
"version": "1.44.1",
|
"version": "1.44.2",
|
||||||
"description": "command line tool for react-native-update (remote updates for react native)",
|
"description": "command line tool for react-native-update (remote updates for react native)",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@@ -1,8 +1,12 @@
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { translateOptions } from './utils';
|
import { translateOptions } from './utils';
|
||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
import { ZipFile } from 'yazl';
|
import { ZipFile as YazlZipFile } from 'yazl';
|
||||||
import { open as openZipFile } from 'yauzl';
|
import {
|
||||||
|
type Entry,
|
||||||
|
open as openZipFile,
|
||||||
|
type ZipFile as YauzlZipFile,
|
||||||
|
} from 'yauzl';
|
||||||
import { question, checkPlugins } from './utils';
|
import { question, checkPlugins } from './utils';
|
||||||
import { checkPlatform } from './app';
|
import { checkPlatform } from './app';
|
||||||
import { spawn, spawnSync } from 'node:child_process';
|
import { spawn, spawnSync } from 'node:child_process';
|
||||||
@@ -16,9 +20,11 @@ import { tempDir } from './utils/constants';
|
|||||||
import { checkLockFiles } from './utils/check-lockfile';
|
import { checkLockFiles } from './utils/check-lockfile';
|
||||||
import { addGitIgnore } from './utils/add-gitignore';
|
import { addGitIgnore } from './utils/add-gitignore';
|
||||||
|
|
||||||
let bsdiff;
|
type Diff = (oldSource?: Buffer, newSource?: Buffer) => Buffer;
|
||||||
let hdiff;
|
|
||||||
let diff;
|
let bsdiff: Diff;
|
||||||
|
let hdiff: Diff;
|
||||||
|
let diff: Diff;
|
||||||
try {
|
try {
|
||||||
bsdiff = require('node-bsdiff').diff;
|
bsdiff = require('node-bsdiff').diff;
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
@@ -59,9 +65,7 @@ async function runReactNativeBundleCommand({
|
|||||||
if (platform === 'android') {
|
if (platform === 'android') {
|
||||||
gradleConfig = await checkGradleConfig();
|
gradleConfig = await checkGradleConfig();
|
||||||
if (gradleConfig.crunchPngs !== false) {
|
if (gradleConfig.crunchPngs !== false) {
|
||||||
console.warn(
|
console.warn(t('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',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +325,7 @@ async function compileHermesByteCode(
|
|||||||
sourcemapOutput: string,
|
sourcemapOutput: string,
|
||||||
shouldCleanSourcemap: boolean,
|
shouldCleanSourcemap: boolean,
|
||||||
) {
|
) {
|
||||||
console.log('Hermes enabled, now compiling to hermes bytecode:\n');
|
console.log(t('hermesEnabledCompiling'));
|
||||||
// >= rn 0.69
|
// >= rn 0.69
|
||||||
const rnDir = path.dirname(
|
const rnDir = path.dirname(
|
||||||
require.resolve('react-native', {
|
require.resolve('react-native', {
|
||||||
@@ -351,7 +355,9 @@ async function compileHermesByteCode(
|
|||||||
);
|
);
|
||||||
args.push('-output-source-map');
|
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, {
|
spawnSync(hermesCommand, args, {
|
||||||
stdio: 'ignore',
|
stdio: 'ignore',
|
||||||
});
|
});
|
||||||
@@ -387,7 +393,7 @@ async function copyDebugidForSentry(
|
|||||||
sourcemapOutput: string,
|
sourcemapOutput: string,
|
||||||
) {
|
) {
|
||||||
if (sourcemapOutput) {
|
if (sourcemapOutput) {
|
||||||
let copyDebugidPath;
|
let copyDebugidPath: string | undefined;
|
||||||
try {
|
try {
|
||||||
copyDebugidPath = require.resolve(
|
copyDebugidPath = require.resolve(
|
||||||
'@sentry/react-native/scripts/copy-debugid.js',
|
'@sentry/react-native/scripts/copy-debugid.js',
|
||||||
@@ -426,13 +432,13 @@ async function uploadSourcemapForSentry(
|
|||||||
version: string,
|
version: string,
|
||||||
) {
|
) {
|
||||||
if (sourcemapOutput) {
|
if (sourcemapOutput) {
|
||||||
let sentryCliPath;
|
let sentryCliPath: string | undefined;
|
||||||
try {
|
try {
|
||||||
sentryCliPath = require.resolve('@sentry/cli/bin/sentry-cli', {
|
sentryCliPath = require.resolve('@sentry/cli/bin/sentry-cli', {
|
||||||
paths: [process.cwd()],
|
paths: [process.cwd()],
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli');
|
console.error(t('sentryCliNotFound'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,12 +477,12 @@ 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(t('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 YazlZipFile();
|
||||||
|
|
||||||
function addDirectory(root: string, rel: string) {
|
function addDirectory(root: string, rel: string) {
|
||||||
if (rel) {
|
if (rel) {
|
||||||
@@ -513,10 +519,13 @@ async function pack(dir: string, output: string) {
|
|||||||
console.log(t('fileGenerated', { file: output }));
|
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[] = [];
|
const buffers: Buffer[] = [];
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
zipFile.openReadStream(entry, (err: any, stream: any) => {
|
zipFile.openReadStream(entry, (err, stream) => {
|
||||||
stream.pipe({
|
stream.pipe({
|
||||||
write(chunk: Buffer) {
|
write(chunk: Buffer) {
|
||||||
buffers.push(chunk);
|
buffers.push(chunk);
|
||||||
@@ -544,7 +553,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|||||||
const originEntries = {};
|
const originEntries = {};
|
||||||
const originMap = {};
|
const originMap = {};
|
||||||
|
|
||||||
let originSource;
|
let originSource: Buffer | undefined;
|
||||||
|
|
||||||
await enumZipEntries(origin, (entry, zipFile) => {
|
await enumZipEntries(origin, (entry, zipFile) => {
|
||||||
originEntries[entry.fileName] = entry;
|
originEntries[entry.fileName] = entry;
|
||||||
@@ -557,7 +566,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|||||||
entry.fileName === 'bundle.harmony.js'
|
entry.fileName === 'bundle.harmony.js'
|
||||||
) {
|
) {
|
||||||
// This is source.
|
// This is source.
|
||||||
return readEntire(entry, zipFile).then((v) => (originSource = v));
|
return readEntry(entry, zipFile).then((v) => (originSource = v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -570,7 +579,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|||||||
|
|
||||||
const copies = {};
|
const copies = {};
|
||||||
|
|
||||||
const zipfile = new ZipFile();
|
const zipfile = new YazlZipFile();
|
||||||
|
|
||||||
const writePromise = new Promise((resolve, reject) => {
|
const writePromise = new Promise((resolve, reject) => {
|
||||||
zipfile.outputStream.on('error', (err) => {
|
zipfile.outputStream.on('error', (err) => {
|
||||||
@@ -607,7 +616,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|||||||
}
|
}
|
||||||
} else if (entry.fileName === 'index.bundlejs') {
|
} else if (entry.fileName === 'index.bundlejs') {
|
||||||
//console.log('Found bundle');
|
//console.log('Found bundle');
|
||||||
return readEntire(entry, nextZipfile).then((newSource) => {
|
return readEntry(entry, nextZipfile).then((newSource) => {
|
||||||
//console.log('Begin diff');
|
//console.log('Begin diff');
|
||||||
zipfile.addBuffer(
|
zipfile.addBuffer(
|
||||||
diff(originSource, newSource),
|
diff(originSource, newSource),
|
||||||
@@ -617,7 +626,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|||||||
});
|
});
|
||||||
} else if (entry.fileName === 'bundle.harmony.js') {
|
} else if (entry.fileName === 'bundle.harmony.js') {
|
||||||
//console.log('Found bundle');
|
//console.log('Found bundle');
|
||||||
return readEntire(entry, nextZipfile).then((newSource) => {
|
return readEntry(entry, nextZipfile).then((newSource) => {
|
||||||
//console.log('Begin diff');
|
//console.log('Begin diff');
|
||||||
zipfile.addBuffer(
|
zipfile.addBuffer(
|
||||||
diff(originSource, newSource),
|
diff(originSource, newSource),
|
||||||
@@ -691,9 +700,9 @@ async function diffFromPackage(
|
|||||||
const originEntries = {};
|
const originEntries = {};
|
||||||
const originMap = {};
|
const originMap = {};
|
||||||
|
|
||||||
let originSource;
|
let originSource: Buffer | undefined;
|
||||||
|
|
||||||
await enumZipEntries(origin, (entry: any, zipFile: any) => {
|
await enumZipEntries(origin, (entry, zipFile) => {
|
||||||
if (!/\/$/.test(entry.fileName)) {
|
if (!/\/$/.test(entry.fileName)) {
|
||||||
const fn = transformPackagePath(entry.fileName);
|
const fn = transformPackagePath(entry.fileName);
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
@@ -707,7 +716,7 @@ async function diffFromPackage(
|
|||||||
|
|
||||||
if (fn === originBundleName) {
|
if (fn === originBundleName) {
|
||||||
// This is source.
|
// This is source.
|
||||||
return readEntire(entry, zipFile).then((v) => (originSource = v));
|
return readEntry(entry, zipFile).then((v) => (originSource = v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -720,7 +729,7 @@ async function diffFromPackage(
|
|||||||
|
|
||||||
const copies = {};
|
const copies = {};
|
||||||
|
|
||||||
const zipfile = new ZipFile();
|
const zipfile = new YazlZipFile();
|
||||||
|
|
||||||
const writePromise = new Promise((resolve, reject) => {
|
const writePromise = new Promise((resolve, reject) => {
|
||||||
zipfile.outputStream.on('error', (err) => {
|
zipfile.outputStream.on('error', (err) => {
|
||||||
@@ -737,7 +746,7 @@ async function diffFromPackage(
|
|||||||
zipfile.addEmptyDirectory(entry.fileName);
|
zipfile.addEmptyDirectory(entry.fileName);
|
||||||
} else if (entry.fileName === 'index.bundlejs') {
|
} else if (entry.fileName === 'index.bundlejs') {
|
||||||
//console.log('Found bundle');
|
//console.log('Found bundle');
|
||||||
return readEntire(entry, nextZipfile).then((newSource) => {
|
return readEntry(entry, nextZipfile).then((newSource) => {
|
||||||
//console.log('Begin diff');
|
//console.log('Begin diff');
|
||||||
zipfile.addBuffer(
|
zipfile.addBuffer(
|
||||||
diff(originSource, newSource),
|
diff(originSource, newSource),
|
||||||
@@ -747,7 +756,7 @@ async function diffFromPackage(
|
|||||||
});
|
});
|
||||||
} else if (entry.fileName === 'bundle.harmony.js') {
|
} else if (entry.fileName === 'bundle.harmony.js') {
|
||||||
//console.log('Found bundle');
|
//console.log('Found bundle');
|
||||||
return readEntire(entry, nextZipfile).then((newSource) => {
|
return readEntry(entry, nextZipfile).then((newSource) => {
|
||||||
//console.log('Begin diff');
|
//console.log('Begin diff');
|
||||||
zipfile.addBuffer(
|
zipfile.addBuffer(
|
||||||
diff(originSource, newSource),
|
diff(originSource, newSource),
|
||||||
@@ -789,14 +798,18 @@ async function diffFromPackage(
|
|||||||
|
|
||||||
export async function enumZipEntries(
|
export async function enumZipEntries(
|
||||||
zipFn: string,
|
zipFn: string,
|
||||||
callback: (entry: any, zipFile: any) => void,
|
callback: (
|
||||||
|
entry: Entry,
|
||||||
|
zipFile: YauzlZipFile,
|
||||||
|
nestedPath?: string,
|
||||||
|
) => Promise<any>,
|
||||||
nestedPath = '',
|
nestedPath = '',
|
||||||
) {
|
) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
openZipFile(
|
openZipFile(
|
||||||
zipFn,
|
zipFn,
|
||||||
{ lazyEntries: true },
|
{ lazyEntries: true },
|
||||||
async (err: any, zipfile: ZipFile) => {
|
async (err: any, zipfile: YauzlZipFile) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
@@ -850,7 +863,7 @@ export async function enumZipEntries(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function diffArgsCheck(args, options, diffFn) {
|
function diffArgsCheck(args: string[], options: any, diffFn: string) {
|
||||||
const [origin, next] = args;
|
const [origin, next] = args;
|
||||||
|
|
||||||
if (!origin || !next) {
|
if (!origin || !next) {
|
||||||
@@ -889,7 +902,7 @@ function diffArgsCheck(args, options, diffFn) {
|
|||||||
export const commands = {
|
export const commands = {
|
||||||
bundle: async function ({ options }) {
|
bundle: async function ({ options }) {
|
||||||
const platform = checkPlatform(
|
const platform = checkPlatform(
|
||||||
options.platform || (await question('平台(ios/android/harmony):')),
|
options.platform || (await question(t('platformPrompt'))),
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -943,7 +956,7 @@ export const commands = {
|
|||||||
|
|
||||||
await pack(path.resolve(intermediaDir), realOutput);
|
await pack(path.resolve(intermediaDir), realOutput);
|
||||||
|
|
||||||
const v = await question('是否现在上传此热更包?(Y/N)');
|
const v = await question(t('uploadBundlePrompt'));
|
||||||
if (v.toLowerCase() === 'y') {
|
if (v.toLowerCase() === 'y') {
|
||||||
const versionName = await this.publish({
|
const versionName = await this.publish({
|
||||||
args: [realOutput],
|
args: [realOutput],
|
||||||
|
@@ -8,7 +8,6 @@ function printUsage() {
|
|||||||
// const commandName = args[0];
|
// const commandName = args[0];
|
||||||
// TODO: print usage of commandName, or print global usage.
|
// TODO: print usage of commandName, or print global usage.
|
||||||
|
|
||||||
console.log('Usage is under development now.');
|
|
||||||
console.log(
|
console.log(
|
||||||
'Visit `https://github.com/reactnativecn/react-native-update` for document.',
|
'Visit `https://github.com/reactnativecn/react-native-update` for document.',
|
||||||
);
|
);
|
||||||
|
@@ -1,10 +1,60 @@
|
|||||||
export default {
|
export default {
|
||||||
loginFirst:
|
addedToGitignore: 'Added {{line}} to .gitignore',
|
||||||
'Not logged in.\nPlease run `cresc login` in the project directory to login.',
|
androidCrunchPngsWarning:
|
||||||
lockNotFound:
|
'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',
|
||||||
'No lock file detected, which may cause inconsistent dependencies and hot-updating issues.',
|
appId: 'App ID',
|
||||||
multipleLocksFound:
|
appIdMismatchApk:
|
||||||
'Multiple lock files detected ({{- lockFiles}}), which may cause inconsistent dependencies and hot-updating issues.',
|
'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: `
|
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.
|
||||||
@@ -12,84 +62,64 @@ 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.
|
||||||
`,
|
`,
|
||||||
|
lockNotFound:
|
||||||
|
'No lock file detected, which may cause inconsistent dependencies and hot-updating issues.',
|
||||||
|
loggedOut: 'Logged out',
|
||||||
loginExpired:
|
loginExpired:
|
||||||
'Login information has expired. Please use `cresc login` command to re-login',
|
'Login information has expired. Please use `cresc login` command to re-login',
|
||||||
fileSizeExceeded:
|
loginFirst:
|
||||||
'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}}',
|
'Not logged in.\nPlease run `cresc login` in the project directory to login.',
|
||||||
bundleNotFound:
|
multipleLocksFound:
|
||||||
'Bundle file not found. Please ensure that this {{packageType}} is a release version and the bundle file name is the default `{{entryFile}}`',
|
'Multiple lock files detected ({{- lockFiles}}), which may cause inconsistent dependencies and hot-updating issues.',
|
||||||
buildTimeNotFound:
|
nativePackageId: 'Native Package ID',
|
||||||
'Cannot get the build timestamp of this package. Please update `react-native-update` to the latest version and re-package and upload.',
|
nativeVersion: 'Native Version',
|
||||||
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',
|
|
||||||
nativeVersionNotFound: 'No native version found >= {{version}}',
|
nativeVersionNotFound: 'No native version found >= {{version}}',
|
||||||
nativeVersionNotFoundLess: 'No native version found <= {{version}}',
|
nativeVersionNotFoundLess: 'No native version found <= {{version}}',
|
||||||
nativeVersionNotFoundMatch: 'No matching 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',
|
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.',
|
platformRequired: 'Platform must be specified.',
|
||||||
bundleCommandError:
|
pluginDetectionError: 'error while detecting {{name}} plugin: {{error}}',
|
||||||
'"react-native bundle" command exited with code {{code}}.',
|
pluginDetected: 'detected {{name}} plugin',
|
||||||
copyHarmonyBundleError: 'Error copying Harmony bundle: {{error}}',
|
ppkPackageGenerated: 'ppk package generated and saved to: {{- output}}',
|
||||||
copyFileFailed: 'Failed to copy file: {{error}}',
|
processingError: 'Error processing file: {{error}}',
|
||||||
deleteFile: 'Delete {{- file}}',
|
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:
|
rolloutConfigSet:
|
||||||
'Set {{rollout}}% rollout for version {{version}} on native version(s) {{versions}}',
|
'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:
|
versionBind:
|
||||||
'Bound version {{version}} to native version {{nativeVersion}} (id: {{id}})',
|
'Bound version {{version}} to native version {{nativeVersion}} (id: {{id}})',
|
||||||
|
welcomeMessage: 'Welcome to Cresc hot update service, {{name}}.',
|
||||||
};
|
};
|
||||||
|
@@ -1,7 +1,58 @@
|
|||||||
export default {
|
export default {
|
||||||
loginFirst: '尚未登录。\n请在项目目录中运行`pushy login`命令来登录',
|
addedToGitignore: '已将 {{line}} 添加到 .gitignore',
|
||||||
lockNotFound:
|
androidCrunchPngsWarning:
|
||||||
'没有检测到任何 lock 文件,这可能导致依赖关系不一致而使热更异常。',
|
'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: `
|
lockBestPractice: `
|
||||||
关于 lock 文件的最佳实践:
|
关于 lock 文件的最佳实践:
|
||||||
1. 开发团队中的所有成员应该使用相同的包管理器,维护同一份 lock 文件。
|
1. 开发团队中的所有成员应该使用相同的包管理器,维护同一份 lock 文件。
|
||||||
@@ -9,81 +60,59 @@ export default {
|
|||||||
3. 代码审核时应关注 lock 文件的变化。
|
3. 代码审核时应关注 lock 文件的变化。
|
||||||
这样可以最大限度避免因依赖关系不一致而导致的热更异常,也降低供应链攻击等安全隐患。
|
这样可以最大限度避免因依赖关系不一致而导致的热更异常,也降低供应链攻击等安全隐患。
|
||||||
`,
|
`,
|
||||||
|
lockNotFound:
|
||||||
|
'没有检测到任何 lock 文件,这可能导致依赖关系不一致而使热更异常。',
|
||||||
|
loggedOut: '已退出登录',
|
||||||
|
loginExpired: '登录信息已过期,请使用 `pushy login` 命令重新登录',
|
||||||
|
loginFirst: '尚未登录。\n请在项目目录中运行`pushy login`命令来登录',
|
||||||
multipleLocksFound:
|
multipleLocksFound:
|
||||||
'检测到多种不同格式的锁文件({{- lockFiles}}),这可能导致依赖关系不一致而使热更异常。',
|
'检测到多种不同格式的锁文件({{- lockFiles}}),这可能导致依赖关系不一致而使热更异常。',
|
||||||
loginExpired: '登录信息已过期,请使用 `pushy login` 命令重新登录',
|
nativePackageId: '原生包 Id',
|
||||||
fileSizeExceeded:
|
nativeVersion: '原生版本',
|
||||||
'此文件大小 {{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 的整数',
|
|
||||||
nativeVersionNotFound: '未查询到 >= {{version}} 的原生版本',
|
nativeVersionNotFound: '未查询到 >= {{version}} 的原生版本',
|
||||||
nativeVersionNotFoundLess: '未查询到 <= {{version}} 的原生版本',
|
nativeVersionNotFoundLess: '未查询到 <= {{version}} 的原生版本',
|
||||||
nativeVersionNotFoundMatch: '未查询到匹配原生版本:{{version}}',
|
nativeVersionNotFoundMatch: '未查询到匹配原生版本:{{version}}',
|
||||||
packageIdRequired: '请提供 packageId 或 packageVersion 参数',
|
offset: '偏移量 {{offset}}',
|
||||||
operationComplete: '操作完成,共已绑定 {{count}} 个原生版本',
|
operationComplete: '操作完成,共已绑定 {{count}} 个原生版本',
|
||||||
|
operationSuccess: '操作成功',
|
||||||
|
packageIdRequired: '请提供 packageId 或 packageVersion 参数',
|
||||||
|
packageUploadSuccess: '已成功上传新热更包(id: {{id}})',
|
||||||
|
packing: '正在打包',
|
||||||
|
pausedStatus: '(已暂停)',
|
||||||
|
platform: '平台',
|
||||||
|
platformPrompt: '平台(ios/android/harmony):',
|
||||||
|
platformQuestion: '平台(ios/android/harmony):',
|
||||||
platformRequired: '必须指定平台。',
|
platformRequired: '必须指定平台。',
|
||||||
bundleCommandError: '"react-native bundle" 命令退出,代码为 {{code}}。',
|
pluginDetectionError: '检测 {{name}} 插件时出错:{{error}}',
|
||||||
copyHarmonyBundleError: '复制 Harmony bundle 错误:{{error}}',
|
pluginDetected: '检测到 {{name}} 插件',
|
||||||
copyFileFailed: '复制文件失败:{{error}}',
|
ppkPackageGenerated: 'ppk 热更包已生成并保存到: {{- output}}',
|
||||||
deleteFile: '删除 {{- file}}',
|
processingError: '处理文件时出错:{{error}}',
|
||||||
|
processingPackage: '正在处理包 {{count}}...',
|
||||||
|
processingStringPool: '正在处理字符串池...',
|
||||||
|
publishUsage:
|
||||||
|
'使用方法: pushy publish ppk后缀文件 --platform ios|android|harmony',
|
||||||
|
rnuVersionNotFound:
|
||||||
|
'react-native-update: 无法获取版本号。请在项目目录中运行命令',
|
||||||
rolloutConfigSet:
|
rolloutConfigSet:
|
||||||
'已在原生版本 {{versions}} 上设置灰度发布 {{rollout}}% 热更版本 {{version}}',
|
'已在原生版本 {{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:
|
versionBind:
|
||||||
'已将热更版本 {{version}} 绑定到原生版本 {{nativeVersion}} (id: {{id}})',
|
'已将热更版本 {{version}} 绑定到原生版本 {{nativeVersion}} (id: {{id}})',
|
||||||
|
welcomeMessage: '欢迎使用 pushy 热更新服务,{{name}}。',
|
||||||
};
|
};
|
||||||
|
@@ -13,22 +13,23 @@ import type { Platform } from 'types';
|
|||||||
export async function listPackage(appId: string) {
|
export async function listPackage(appId: string) {
|
||||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
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 = [];
|
const rows = [];
|
||||||
for (const pkg of data) {
|
for (const pkg of data) {
|
||||||
const { version } = pkg;
|
const { version } = pkg;
|
||||||
let versionInfo = '';
|
let versionInfo = '';
|
||||||
if (version) {
|
if (version) {
|
||||||
versionInfo = `, 已绑定:${version.name} (${version.id})`;
|
versionInfo = t('boundTo', { name: version.name, id: version.id });
|
||||||
} else {
|
|
||||||
// versionInfo = ' (newest)';
|
|
||||||
}
|
}
|
||||||
let output = pkg.name;
|
let output = pkg.name;
|
||||||
if (pkg.status === 'paused') {
|
if (pkg.status === 'paused') {
|
||||||
output += '(已暂停)';
|
output += t('pausedStatus');
|
||||||
}
|
}
|
||||||
if (pkg.status === 'expired') {
|
if (pkg.status === 'expired') {
|
||||||
output += '(已过期)';
|
output += t('expiredStatus');
|
||||||
}
|
}
|
||||||
output += versionInfo;
|
output += versionInfo;
|
||||||
rows.push([pkg.id, output]);
|
rows.push([pkg.id, output]);
|
||||||
@@ -43,7 +44,7 @@ export async function choosePackage(appId: string) {
|
|||||||
const list = await listPackage(appId);
|
const list = await listPackage(appId);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const id = await question('输入原生包 id:');
|
const id = await question(t('enterNativePackageId'));
|
||||||
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;
|
||||||
@@ -66,15 +67,11 @@ export const commands = {
|
|||||||
const { appId, appKey } = await getSelectedApp('ios');
|
const { appId, appKey } = await getSelectedApp('ios');
|
||||||
|
|
||||||
if (appIdInPkg && appIdInPkg != appId) {
|
if (appIdInPkg && appIdInPkg != appId) {
|
||||||
throw new Error(
|
throw new Error(t('appIdMismatchIpa', { appIdInPkg, appId }));
|
||||||
`appId不匹配!当前ipa: ${appIdInPkg}, 当前update.json: ${appId}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appKeyInPkg && appKeyInPkg !== appKey) {
|
if (appKeyInPkg && appKeyInPkg !== appKey) {
|
||||||
throw new Error(
|
throw new Error(t('appKeyMismatchIpa', { appKeyInPkg, appKey }));
|
||||||
`appKey不匹配!当前ipa: ${appKeyInPkg}, 当前update.json: ${appKey}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { hash } = await uploadFile(fn);
|
const { hash } = await uploadFile(fn);
|
||||||
@@ -87,9 +84,7 @@ export const commands = {
|
|||||||
commit: await getCommitInfo(),
|
commit: await getCommitInfo(),
|
||||||
});
|
});
|
||||||
saveToLocal(fn, `${appId}/package/${id}.ipa`);
|
saveToLocal(fn, `${appId}/package/${id}.ipa`);
|
||||||
console.log(
|
console.log(t('ipaUploadSuccess', { id, version: versionName, buildTime }));
|
||||||
`已成功上传ipa原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
uploadApk: async ({ args }: { args: string[] }) => {
|
uploadApk: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
@@ -105,15 +100,11 @@ export const commands = {
|
|||||||
const { appId, appKey } = await getSelectedApp('android');
|
const { appId, appKey } = await getSelectedApp('android');
|
||||||
|
|
||||||
if (appIdInPkg && appIdInPkg != appId) {
|
if (appIdInPkg && appIdInPkg != appId) {
|
||||||
throw new Error(
|
throw new Error(t('appIdMismatchApk', { appIdInPkg, appId }));
|
||||||
`appId不匹配!当前apk: ${appIdInPkg}, 当前update.json: ${appId}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appKeyInPkg && appKeyInPkg !== appKey) {
|
if (appKeyInPkg && appKeyInPkg !== appKey) {
|
||||||
throw new Error(
|
throw new Error(t('appKeyMismatchApk', { appKeyInPkg, appKey }));
|
||||||
`appKey不匹配!当前apk: ${appKeyInPkg}, 当前update.json: ${appKey}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { hash } = await uploadFile(fn);
|
const { hash } = await uploadFile(fn);
|
||||||
@@ -126,9 +117,7 @@ export const commands = {
|
|||||||
commit: await getCommitInfo(),
|
commit: await getCommitInfo(),
|
||||||
});
|
});
|
||||||
saveToLocal(fn, `${appId}/package/${id}.apk`);
|
saveToLocal(fn, `${appId}/package/${id}.apk`);
|
||||||
console.log(
|
console.log(t('apkUploadSuccess', { id, version: versionName, buildTime }));
|
||||||
`已成功上传apk原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
uploadApp: async ({ args }: { args: string[] }) => {
|
uploadApp: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
@@ -144,15 +133,11 @@ export const commands = {
|
|||||||
const { appId, appKey } = await getSelectedApp('harmony');
|
const { appId, appKey } = await getSelectedApp('harmony');
|
||||||
|
|
||||||
if (appIdInPkg && appIdInPkg != appId) {
|
if (appIdInPkg && appIdInPkg != appId) {
|
||||||
throw new Error(
|
throw new Error(t('appIdMismatchApp', { appIdInPkg, appId }));
|
||||||
`appId不匹配!当前app: ${appIdInPkg}, 当前update.json: ${appId}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appKeyInPkg && appKeyInPkg !== appKey) {
|
if (appKeyInPkg && appKeyInPkg !== appKey) {
|
||||||
throw new Error(
|
throw new Error(t('appKeyMismatchApp', { appKeyInPkg, appKey }));
|
||||||
`appKey不匹配!当前app: ${appKeyInPkg}, 当前update.json: ${appKey}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { hash } = await uploadFile(fn);
|
const { hash } = await uploadFile(fn);
|
||||||
@@ -165,9 +150,7 @@ export const commands = {
|
|||||||
commit: await getCommitInfo(),
|
commit: await getCommitInfo(),
|
||||||
});
|
});
|
||||||
saveToLocal(fn, `${appId}/package/${id}.app`);
|
saveToLocal(fn, `${appId}/package/${id}.app`);
|
||||||
console.log(
|
console.log(t('appUploadSuccess', { id, version: versionName, buildTime }));
|
||||||
`已成功上传app原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
parseApp: async ({ args }: { args: string[] }) => {
|
parseApp: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
@@ -192,7 +175,7 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
packages: async ({ options }: { options: { platform: Platform } }) => {
|
packages: async ({ options }: { options: { platform: Platform } }) => {
|
||||||
const platform = checkPlatform(
|
const platform = checkPlatform(
|
||||||
options.platform || (await question('平台(ios/android/harmony):')),
|
options.platform || (await question(t('platformPrompt'))),
|
||||||
);
|
);
|
||||||
const { appId } = await getSelectedApp(platform);
|
const { appId } = await getSelectedApp(platform);
|
||||||
await listPackage(appId);
|
await listPackage(appId);
|
||||||
|
@@ -125,9 +125,7 @@ export const commands = {
|
|||||||
const { name, description, metaInfo } = options;
|
const { name, description, metaInfo } = options;
|
||||||
|
|
||||||
if (!fn || !fn.endsWith('.ppk')) {
|
if (!fn || !fn.endsWith('.ppk')) {
|
||||||
throw new Error(
|
throw new Error(t('publishUsage'));
|
||||||
'使用方法: pushy publish ppk后缀文件 --platform ios|android|harmony',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const platform = checkPlatform(
|
const platform = checkPlatform(
|
||||||
@@ -204,7 +202,7 @@ export const commands = {
|
|||||||
minPkgVersion = String(minPkgVersion).trim();
|
minPkgVersion = String(minPkgVersion).trim();
|
||||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
||||||
const pkgs = data.filter((pkg: Package) =>
|
const pkgs = data.filter((pkg: Package) =>
|
||||||
compare(pkg.name, minPkgVersion, '>='),
|
compare(pkg.name, minPkgVersion!, '>='),
|
||||||
);
|
);
|
||||||
if (pkgs.length === 0) {
|
if (pkgs.length === 0) {
|
||||||
throw new Error(t('nativeVersionNotFound', { version: minPkgVersion }));
|
throw new Error(t('nativeVersionNotFound', { version: minPkgVersion }));
|
||||||
@@ -245,10 +243,12 @@ export const commands = {
|
|||||||
maxPkgVersion = String(maxPkgVersion).trim();
|
maxPkgVersion = String(maxPkgVersion).trim();
|
||||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
||||||
const pkgs = data.filter((pkg: Package) =>
|
const pkgs = data.filter((pkg: Package) =>
|
||||||
compare(pkg.name, maxPkgVersion, '<='),
|
compare(pkg.name, maxPkgVersion!, '<='),
|
||||||
);
|
);
|
||||||
if (pkgs.length === 0) {
|
if (pkgs.length === 0) {
|
||||||
throw new Error(t('nativeVersionNotFoundLess', { version: maxPkgVersion }));
|
throw new Error(
|
||||||
|
t('nativeVersionNotFoundLess', { version: maxPkgVersion }),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (rollout !== undefined) {
|
if (rollout !== undefined) {
|
||||||
const rolloutConfig: Record<string, number> = {};
|
const rolloutConfig: Record<string, number> = {};
|
||||||
@@ -290,7 +290,9 @@ export const commands = {
|
|||||||
if (pkg) {
|
if (pkg) {
|
||||||
pkgId = pkg.id;
|
pkgId = pkg.id;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(t('nativeVersionNotFoundMatch', { version: pkgVersion }));
|
throw new Error(
|
||||||
|
t('nativeVersionNotFoundMatch', { version: pkgVersion }),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pkgId) {
|
if (!pkgId) {
|
||||||
|
Reference in New Issue
Block a user