react-native-update-cli 1.42.1 → 1.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,6 +46,7 @@ const _checkplugin = require("./check-plugin");
46
46
  const _read = require("read");
47
47
  const _constants = require("./constants");
48
48
  const _depversions = require("./dep-versions");
49
+ const _i18n = require("./i18n");
49
50
  function _interop_require_default(obj) {
50
51
  return obj && obj.__esModule ? obj : {
51
52
  default: obj
@@ -77,7 +78,10 @@ async function getApkInfo(fn) {
77
78
  const appInfoParser = new _appinfoparser.default(fn);
78
79
  const bundleFile = await appInfoParser.parser.getEntry(/assets\/index.android.bundle/);
79
80
  if (!bundleFile) {
80
- throw new Error('找不到bundle文件。请确保此apk为release版本,且bundle文件名为默认的index.android.bundle');
81
+ throw new Error((0, _i18n.t)('bundleNotFound', {
82
+ packageType: 'apk',
83
+ entryFile: 'index.android.bundle'
84
+ }));
81
85
  }
82
86
  const updateJsonFile = await appInfoParser.parser.getEntry(/res\/raw\/update.json/);
83
87
  let appCredential = {};
@@ -94,7 +98,7 @@ async function getApkInfo(fn) {
94
98
  }
95
99
  }
96
100
  if (buildTime == 0) {
97
- throw new Error('无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。');
101
+ throw new Error((0, _i18n.t)('buildTimeNotFound'));
98
102
  }
99
103
  return {
100
104
  versionName,
@@ -106,7 +110,10 @@ async function getAppInfo(fn) {
106
110
  const appInfoParser = new _appinfoparser.default(fn);
107
111
  const bundleFile = await appInfoParser.parser.getEntryFromHarmonyApp(/rawfile\/bundle.harmony.js/);
108
112
  if (!bundleFile) {
109
- throw new Error('找不到bundle文件。请确保此app为release版本,且bundle文件名为默认的bundle.harmony.js');
113
+ throw new Error((0, _i18n.t)('bundleNotFound', {
114
+ packageType: 'app',
115
+ entryFile: 'bundle.harmony.js'
116
+ }));
110
117
  }
111
118
  const updateJsonFile = await appInfoParser.parser.getEntryFromHarmonyApp(/rawfile\/update.json/);
112
119
  let appCredential = {};
@@ -124,7 +131,7 @@ async function getAppInfo(fn) {
124
131
  buildTime = pushy_build_time;
125
132
  }
126
133
  if (buildTime == 0) {
127
- throw new Error('无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。');
134
+ throw new Error((0, _i18n.t)('buildTimeNotFound'));
128
135
  }
129
136
  return {
130
137
  versionName,
@@ -136,7 +143,10 @@ async function getIpaInfo(fn) {
136
143
  const appInfoParser = new _appinfoparser.default(fn);
137
144
  const bundleFile = await appInfoParser.parser.getEntry(/payload\/.+?\.app\/main.jsbundle/);
138
145
  if (!bundleFile) {
139
- throw new Error('找不到bundle文件。请确保此ipa为release版本,且bundle文件名为默认的main.jsbundle');
146
+ throw new Error((0, _i18n.t)('bundleNotFound', {
147
+ packageType: 'ipa',
148
+ entryFile: 'main.jsbundle'
149
+ }));
140
150
  }
141
151
  const updateJsonFile = await appInfoParser.parser.getEntry(/payload\/.+?\.app\/assets\/update.json/);
142
152
  let appCredential = {};
@@ -150,7 +160,7 @@ async function getIpaInfo(fn) {
150
160
  buildTimeTxtBuffer = await appInfoParser.parser.getEntry(/payload\/.+?\.app\/frameworks\/react_native_update.framework\/pushy_build_time.txt/);
151
161
  }
152
162
  if (!buildTimeTxtBuffer) {
153
- throw new Error('无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。');
163
+ throw new Error((0, _i18n.t)('buildTimeNotFound'));
154
164
  }
155
165
  const buildTime = buildTimeTxtBuffer.toString().replace('\n', '');
156
166
  return {
@@ -176,27 +186,38 @@ async function getLatestVersion(pkgNames) {
176
186
  }).then((pkgs)=>pkgs.map((pkg)=>pkg.latest)).catch(()=>[]);
177
187
  }
178
188
  async function printVersionCommand() {
179
- let [latestPushyCliVersion, latestPushyVersion] = await getLatestVersion([
189
+ let [latestRnuCliVersion, latestRnuVersion] = await getLatestVersion([
180
190
  'react-native-update-cli',
181
191
  'react-native-update'
182
192
  ]);
183
- latestPushyCliVersion = latestPushyCliVersion ? ` (最新:${_chalk.default.green(latestPushyCliVersion)})` : '';
184
- console.log(`react-native-update-cli: ${_packagejson.default.version}${latestPushyCliVersion}`);
185
- let pushyVersion = '';
186
- pushyVersion = _depversions.depVersions['react-native-update'];
187
- latestPushyVersion = latestPushyVersion ? ` (最新:${_chalk.default.green(latestPushyVersion)})` : '';
188
- console.log(`react-native-update: ${pushyVersion}${latestPushyVersion}`);
189
- if (pushyVersion) {
190
- if ((0, _satisfies.default)(pushyVersion, '<8.5.2')) {
191
- console.warn(`当前版本已不再支持,请至少升级到 v8 的最新小版本后重新打包(代码无需改动): npm i react-native-update@8 .
192
- 如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`);
193
- } else if ((0, _satisfies.default)(pushyVersion, '9.0.0 - 9.2.1')) {
194
- console.warn(`当前版本已不再支持,请至少升级到 v9 的最新小版本后重新打包(代码无需改动,可直接热更): npm i react-native-update@9 .
195
- 如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`);
196
- } else if ((0, _satisfies.default)(pushyVersion, '10.0.0 - 10.17.0')) {
197
- console.warn('当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10');
193
+ latestRnuCliVersion = latestRnuCliVersion ? ` ${(0, _i18n.t)('latestVersionTag', {
194
+ version: _chalk.default.green(latestRnuCliVersion)
195
+ })}` : '';
196
+ console.log(`react-native-update-cli: ${_packagejson.default.version}${latestRnuCliVersion}`);
197
+ let rnuVersion = '';
198
+ rnuVersion = _depversions.depVersions['react-native-update'];
199
+ latestRnuVersion = latestRnuVersion ? ` ${(0, _i18n.t)('latestVersionTag', {
200
+ version: _chalk.default.green(latestRnuVersion)
201
+ })}` : '';
202
+ console.log(`react-native-update: ${rnuVersion}${latestRnuVersion}`);
203
+ if (rnuVersion) {
204
+ if (_constants.IS_CRESC) {
205
+ if ((0, _satisfies.default)(rnuVersion, '<10.27.0')) {
206
+ console.error('Unsupported version, please update to the latest version: npm i react-native-update@latest');
207
+ process.exit(1);
208
+ }
209
+ } else {
210
+ if ((0, _satisfies.default)(rnuVersion, '<8.5.2')) {
211
+ console.warn(`当前版本已不再支持,请至少升级到 v8 的最新小版本后重新打包(代码无需改动): npm i react-native-update@8 .
212
+ 如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`);
213
+ } else if ((0, _satisfies.default)(rnuVersion, '9.0.0 - 9.2.1')) {
214
+ console.warn(`当前版本已不再支持,请至少升级到 v9 的最新小版本后重新打包(代码无需改动,可直接热更): npm i react-native-update@9 .
215
+ 如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`);
216
+ } else if ((0, _satisfies.default)(rnuVersion, '10.0.0 - 10.17.0')) {
217
+ console.warn('当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10');
218
+ }
198
219
  }
199
220
  } else {
200
- console.log('react-native-update: 无法获取版本号,请在项目目录中运行命令');
221
+ console.log((0, _i18n.t)('rnuVersionNotFound'));
201
222
  }
202
223
  }
package/lib/versions.js CHANGED
@@ -58,7 +58,7 @@ async function chooseVersion(appId) {
58
58
  while(true){
59
59
  const data = await showVersion(appId, offset);
60
60
  const cmd = await (0, _utils.question)('Enter versionId or page Up/page Down/Begin(U/D/B)');
61
- switch(cmd.toLowerCase()){
61
+ switch(cmd.toUpperCase()){
62
62
  case 'U':
63
63
  offset = Math.max(0, offset - 10);
64
64
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-update-cli",
3
- "version": "1.42.1",
3
+ "version": "1.43.0",
4
4
  "description": "Command tools for javaScript updater with `pushy` service for react native apps.",
5
5
  "main": "index.js",
6
6
  "bin": {
package/src/api.ts CHANGED
@@ -6,19 +6,20 @@ import ProgressBar from 'progress';
6
6
  import packageJson from '../package.json';
7
7
  import tcpp from 'tcp-ping';
8
8
  import filesizeParser from 'filesize-parser';
9
- import { pricingPageUrl, credentialFile, IS_CRESC } from './utils/constants';
9
+ import {
10
+ pricingPageUrl,
11
+ credentialFile,
12
+ defaultEndpoint,
13
+ } from './utils/constants';
10
14
  import type { Session } from 'types';
11
15
  import FormData from 'form-data';
16
+ import { t } from './utils/i18n';
12
17
 
13
18
  const tcpPing = util.promisify(tcpp.ping);
14
19
 
15
20
  let session: Session | undefined;
16
21
  let savedSession: Session | undefined;
17
22
 
18
- const defaultEndpoint = IS_CRESC
19
- ? 'https://api.cresc.dev'
20
- : 'https://update.reactnative.cn/api';
21
-
22
23
  const host =
23
24
  process.env.PUSHY_REGISTRY || process.env.RNU_API || defaultEndpoint;
24
25
 
@@ -73,7 +74,7 @@ async function query(url: string, options: fetch.RequestInit) {
73
74
  if (resp.status !== 200) {
74
75
  const message = json?.message || resp.statusText;
75
76
  if (resp.status === 401) {
76
- throw new Error('登录信息已过期,请使用 pushy login 命令重新登录');
77
+ throw new Error(t('loginExpired'));
77
78
  }
78
79
  throw new Error(message);
79
80
  }
@@ -133,10 +134,13 @@ export async function uploadFile(fn: string, key?: string) {
133
134
 
134
135
  const fileSize = fs.statSync(fn).size;
135
136
  if (maxSize && fileSize > filesizeParser(maxSize)) {
137
+ const readableFileSize = `${(fileSize / 1048576).toFixed(1)}m`;
136
138
  throw new Error(
137
- `此文件大小 ${(fileSize / 1048576).toFixed(
138
- 1,
139
- )}m , 超出当前额度 ${maxSize} 。您可以考虑升级付费业务以提升此额度。详情请访问: ${pricingPageUrl}`,
139
+ t('fileSizeExceeded', {
140
+ fileSize: readableFileSize,
141
+ maxSize,
142
+ pricingPageUrl,
143
+ }),
140
144
  );
141
145
  }
142
146
 
package/src/app.ts CHANGED
@@ -4,16 +4,14 @@ import Table from 'tty-table';
4
4
 
5
5
  import { post, get, doDelete } from './api';
6
6
  import type { Platform } from './types';
7
+ import { t } from './utils/i18n';
8
+
9
+ const validPlatforms = ['ios', 'android', 'harmony'];
7
10
 
8
- const validPlatforms = {
9
- ios: 1,
10
- android: 1,
11
- harmony: 1,
12
- };
13
11
 
14
12
  export function checkPlatform(platform: Platform) {
15
- if (!validPlatforms[platform]) {
16
- throw new Error(`无法识别的平台 '${platform}'`);
13
+ if (!validPlatforms.includes(platform)) {
14
+ throw new Error(t('unsupportedPlatform', { platform }));
17
15
  }
18
16
  return platform;
19
17
  }
@@ -22,27 +20,23 @@ export function getSelectedApp(platform: Platform) {
22
20
  checkPlatform(platform);
23
21
 
24
22
  if (!fs.existsSync('update.json')) {
25
- throw new Error(
26
- `App not selected. run 'pushy selectApp --platform ${platform}' first!`,
27
- );
23
+ throw new Error(t('appNotSelected', { platform }));
28
24
  }
29
25
  const updateInfo = JSON.parse(fs.readFileSync('update.json', 'utf8'));
30
26
  if (!updateInfo[platform]) {
31
- throw new Error(
32
- `App not selected. run 'pushy selectApp --platform ${platform}' first!`,
33
- );
27
+ throw new Error(t('appNotSelected', { platform }));
34
28
  }
35
29
  return updateInfo[platform];
36
30
  }
37
31
 
38
- export async function listApp(platform: Platform) {
32
+ export async function listApp(platform: Platform | '' = '') {
39
33
  const { data } = await get('/app/list');
40
34
  const list = platform ? data.filter((v) => v.platform === platform) : data;
41
35
 
42
36
  const header = [
43
- { value: '应用 id' },
44
- { value: '应用名称' },
45
- { value: '平台' },
37
+ { value: t('appId') },
38
+ { value: t('appName') },
39
+ { value: t('platform') },
46
40
  ];
47
41
  const rows = [];
48
42
  for (const app of list) {
@@ -51,11 +45,7 @@ export async function listApp(platform: Platform) {
51
45
 
52
46
  console.log(Table(header, rows).render());
53
47
 
54
- if (platform) {
55
- console.log(`\共 ${list.length} ${platform} 个应用`);
56
- } else {
57
- console.log(`\共 ${list.length} 个应用`);
58
- }
48
+ console.log(`\n${t('totalApps', { count: list.length, platform })}`);
59
49
  return list;
60
50
  }
61
51
 
@@ -63,7 +53,7 @@ export async function chooseApp(platform: Platform) {
63
53
  const list = await listApp(platform);
64
54
 
65
55
  while (true) {
66
- const id = await question('输入应用 id:');
56
+ const id = await question(t('enterAppIdQuestion'));
67
57
  const app = list.find((v) => v.id === Number(id));
68
58
  if (app) {
69
59
  return app;
@@ -77,13 +67,13 @@ export const commands = {
77
67
  }: {
78
68
  options: { name: string; downloadUrl: string; platform: Platform };
79
69
  }) {
80
- const name = options.name || (await question('应用名称:'));
70
+ const name = options.name || (await question(t('appNameQuestion')));
81
71
  const { downloadUrl } = options;
82
72
  const platform = checkPlatform(
83
- options.platform || (await question('平台(ios/android/harmony):')),
73
+ options.platform || (await question(t('platformQuestion'))),
84
74
  );
85
75
  const { id } = await post('/app/create', { name, platform, downloadUrl });
86
- console.log(`已成功创建应用(id: ${id})`);
76
+ console.log(t('createAppSuccess', { id }));
87
77
  await this.selectApp({
88
78
  args: [id],
89
79
  options: { platform },
@@ -93,10 +83,10 @@ export const commands = {
93
83
  const { platform } = options;
94
84
  const id = args[0] || chooseApp(platform);
95
85
  if (!id) {
96
- console.log('已取消');
86
+ console.log(t('cancelled'));
97
87
  }
98
88
  await doDelete(`/app/${id}`);
99
- console.log('操作成功');
89
+ console.log(t('operationSuccess'));
100
90
  },
101
91
  apps: async ({ options }: { options: { platform: Platform } }) => {
102
92
  const { platform } = options;
@@ -104,7 +94,7 @@ export const commands = {
104
94
  },
105
95
  selectApp: async ({ args, options }: { args: string[]; options: { platform: Platform } }) => {
106
96
  const platform = checkPlatform(
107
- options.platform || (await question('平台(ios/android/harmony):')),
97
+ options.platform || (await question(t('platformQuestion'))),
108
98
  );
109
99
  const id = args[0]
110
100
  ? Number.parseInt(args[0])
@@ -115,9 +105,7 @@ export const commands = {
115
105
  try {
116
106
  updateInfo = JSON.parse(fs.readFileSync('update.json', 'utf8'));
117
107
  } catch (e) {
118
- console.error(
119
- 'Failed to parse file `update.json`. Try to remove it manually.',
120
- );
108
+ console.error(t('failedToParseUpdateJson'));
121
109
  throw e;
122
110
  }
123
111
  }
package/src/bundle.ts CHANGED
@@ -11,6 +11,10 @@ const g2js = require('gradle-to-js/lib/parser');
11
11
  import os from 'node:os';
12
12
  const properties = require('properties');
13
13
  import { depVersions } from './utils/dep-versions';
14
+ import { t } from './utils/i18n';
15
+ import { tempDir } from './utils/constants';
16
+ import { checkLockFiles } from './utils/check-lockfile';
17
+ import { addGitIgnore } from './utils/add-gitignore';
14
18
 
15
19
  let bsdiff;
16
20
  let hdiff;
@@ -512,7 +516,7 @@ async function pack(dir: string, output: string) {
512
516
  });
513
517
  zipfile.end();
514
518
  });
515
- console.log(`ppk热更包已生成并保存到: ${output}`);
519
+ console.log(t('ppkPackageGenerated', { output }));
516
520
  }
517
521
 
518
522
  export function readEntire(entry: string, zipFile: ZipFile) {
@@ -907,9 +911,13 @@ export const commands = {
907
911
  disableHermes,
908
912
  } = translateOptions({
909
913
  ...options,
914
+ tempDir,
910
915
  platform,
911
916
  });
912
917
 
918
+ checkLockFiles();
919
+ addGitIgnore();
920
+
913
921
  const bundleParams = await checkPlugins();
914
922
  const sourcemapPlugin = bundleParams.sourcemap;
915
923
  const isSentry = bundleParams.sentry;
package/src/locales/en.ts CHANGED
@@ -6,7 +6,7 @@ export default {
6
6
  lockNotFound:
7
7
  'No lock file detected, which may cause inconsistent dependencies and hot-updating issues.',
8
8
  multipleLocksFound:
9
- 'Multiple lock files detected ({lockFiles}), which may cause inconsistent dependencies and hot-updating issues.',
9
+ 'Multiple lock files detected ({{lockFiles}}), which may cause inconsistent dependencies and hot-updating issues.',
10
10
  lockBestPractice: `
11
11
  Best practices for lock files:
12
12
  1. All members of the development team should use the same package manager to maintain a single lock file.
@@ -14,4 +14,30 @@ Best practices for lock files:
14
14
  3. Pay attention to changes in the lock file during code review.
15
15
  This can reduce the risk of inconsistent dependencies and supply chain attacks.
16
16
  `,
17
+ loginExpired:
18
+ 'Login information has expired. Please use `cresc login` command to re-login',
19
+ fileSizeExceeded:
20
+ '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}}',
21
+ bundleNotFound:
22
+ 'Bundle file not found. Please ensure that this {{packageType}} is a release version and the bundle file name is the default `{{entryFile}}`',
23
+ buildTimeNotFound:
24
+ 'Cannot get the build timestamp of this package. Please update `react-native-update` to the latest version and re-package and upload.',
25
+ latestVersionTag: '(latest: {{version}})',
26
+ rnuVersionNotFound:
27
+ 'react-native-update: Cannot get the version number. Please run the command in the project directory',
28
+ unsupportedPlatform: 'Unsupported platform `{{platform}}`',
29
+ appId: 'App ID',
30
+ appName: 'App Name',
31
+ platform: 'Platform',
32
+ totalApps: 'Total {{count}} apps',
33
+ appNotSelected:
34
+ 'App not selected. run `cresc selectApp --platform {{platform}}` first!',
35
+ enterAppIdQuestion: 'Enter AppId:',
36
+ appNameQuestion: 'App Name:',
37
+ platformQuestion: 'Platform(ios/android/harmony):',
38
+ createAppSuccess: 'App created successfully (id: {{id}})',
39
+ cancelled: 'Cancelled',
40
+ operationSuccess: 'Operation successful',
41
+ failedToParseUpdateJson: 'Failed to parse file `update.json`. Try to remove it manually.',
42
+ ppkPackageGenerated: 'ppk package generated and saved to: {{output}}',
17
43
  };
package/src/locales/zh.ts CHANGED
@@ -12,5 +12,30 @@ export default {
12
12
  这样可以最大限度避免因依赖关系不一致而导致的热更异常,也降低供应链攻击等安全隐患。
13
13
  `,
14
14
  multipleLocksFound:
15
- '检测到多种不同格式的锁文件({lockFiles}),这可能导致依赖关系不一致而使热更异常。',
15
+ '检测到多种不同格式的锁文件({{lockFiles}}),这可能导致依赖关系不一致而使热更异常。',
16
+ loginExpired: '登录信息已过期,请使用 `pushy login` 命令重新登录',
17
+ fileSizeExceeded:
18
+ '此文件大小 {{fileSize}} , 超出当前额度 {{maxSize}} 。您可以考虑升级付费业务以提升此额度。详情请访问: {{pricingPageUrl}}',
19
+ bundleNotFound:
20
+ '找不到 bundle 文件。请确保此 {{packageType}} 为 release 版本,且 bundle 文件名为默认的 `{{entryFile}}`',
21
+ buildTimeNotFound:
22
+ '无法获取此包的编译时间戳。请更新 `react-native-update` 到最新版本后重新打包上传。',
23
+ latestVersionTag: '(最新:{{version}})',
24
+ rnuVersionNotFound:
25
+ 'react-native-update: 无法获取版本号。请在项目目录中运行命令',
26
+ unsupportedPlatform: '无法识别的平台 `{{platform}}`',
27
+ appId: '应用 id',
28
+ appName: '应用名称',
29
+ platform: '平台',
30
+ totalApps: '共 {{count}} 个{{platform}}应用',
31
+ appNotSelected:
32
+ '尚未选择应用。请先运行 `pushy selectApp --platform {{platform}}` 来选择应用',
33
+ enterAppIdQuestion: '输入应用 id:',
34
+ appNameQuestion: '应用名称:',
35
+ platformQuestion: '平台(ios/android/harmony):',
36
+ createAppSuccess: '已成功创建应用(id: {{id}})',
37
+ cancelled: '已取消',
38
+ operationSuccess: '操作成功',
39
+ failedToParseUpdateJson: '无法解析文件 `update.json`。请手动删除它。',
40
+ ppkPackageGenerated: 'ppk 热更包已生成并保存到: {{output}}',
16
41
  };
@@ -0,0 +1,34 @@
1
+ import fs from 'node:fs';
2
+ // import path from 'node:path';
3
+ import { credentialFile, tempDir } from './constants';
4
+
5
+ export function addGitIgnore() {
6
+ const shouldIgnore = [credentialFile, tempDir];
7
+
8
+ const gitignorePath = '.gitignore';
9
+
10
+ if (!fs.existsSync(gitignorePath)) {
11
+ return;
12
+ }
13
+
14
+ const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
15
+
16
+ const gitignoreLines = gitignoreContent.split('\n');
17
+
18
+ for (const line of gitignoreLines) {
19
+ const index = shouldIgnore.indexOf(line.trim());
20
+ if (index !== -1) {
21
+ shouldIgnore.splice(index, 1);
22
+ }
23
+ }
24
+
25
+ if (shouldIgnore.length > 0) {
26
+ gitignoreLines.push('# react-native-update');
27
+ for (const line of shouldIgnore) {
28
+ gitignoreLines.push(line);
29
+ console.log(`Added ${line} to .gitignore`);
30
+ }
31
+
32
+ fs.writeFileSync(gitignorePath, gitignoreLines.join('\n'));
33
+ }
34
+ }
@@ -4,17 +4,19 @@ const AppParser = require('./app');
4
4
  const supportFileTypes = ['ipa', 'apk', 'app'];
5
5
 
6
6
  class AppInfoParser {
7
+ file: string | File;
8
+ parser: any;
7
9
  /**
8
10
  * parser for parsing .ipa or .apk file
9
- * @param {String | File | Blob} file // file's path in Node, instance of File or Blob in Browser
11
+ * @param {String | File} file // file's path in Node, instance of File in Browser
10
12
  */
11
- constructor(file) {
13
+ constructor(file: string | File) {
12
14
  if (!file) {
13
15
  throw new Error(
14
- "Param miss: file(file's path in Node, instance of File or Blob in browser).",
16
+ "Param miss: file(file's path in Node, instance of File in browser).",
15
17
  );
16
18
  }
17
- const splits = (file.name || file).split('.');
19
+ const splits = (typeof file === 'string' ? file : file.name).split('.');
18
20
  const fileType = splits[splits.length - 1].toLowerCase();
19
21
  if (!supportFileTypes.includes(fileType)) {
20
22
  throw new Error(
@@ -40,4 +42,4 @@ class AppInfoParser {
40
42
  }
41
43
  }
42
44
 
43
- module.exports = AppInfoParser;
45
+ export default AppInfoParser;
@@ -0,0 +1,29 @@
1
+ import fs from 'node:fs';
2
+ import { t } from './i18n';
3
+
4
+ const lockFiles = [
5
+ 'package-lock.json',
6
+ 'yarn.lock',
7
+ 'pnpm-lock.yaml',
8
+ 'bun.lockb',
9
+ 'bun.lock',
10
+ ];
11
+
12
+ const existingLockFiles: string[] = [];
13
+ export function checkLockFiles() {
14
+ for (const file of lockFiles) {
15
+ if (fs.existsSync(file)) {
16
+ existingLockFiles.push(file);
17
+ }
18
+ }
19
+ if (existingLockFiles.length === 1) {
20
+ return;
21
+ }
22
+ console.warn(t('lockBestPractice'));
23
+ if (existingLockFiles.length === 0) {
24
+ throw new Error(t('lockNotFound'));
25
+ }
26
+ throw new Error(
27
+ t('multipleLocksFound', { lockFiles: existingLockFiles.join(', ') }),
28
+ );
29
+ }
@@ -17,10 +17,10 @@ export async function checkPlugins(): Promise<BundleParams> {
17
17
  const isEnabled = await plugin.detect();
18
18
  if (isEnabled && plugin.bundleParams) {
19
19
  Object.assign(params, plugin.bundleParams);
20
- console.log(`检测到 ${plugin.name} 插件,应用相应打包配置`);
20
+ console.log(`detected ${plugin.name} plugin`);
21
21
  }
22
22
  } catch (err) {
23
- console.warn(`检测 ${plugin.name} 插件时出错:`, err);
23
+ console.warn(`error while detecting ${plugin.name} plugin:`, err);
24
24
  }
25
25
  }
26
26
 
@@ -1,8 +1,6 @@
1
1
  import path from 'node:path';
2
2
 
3
- const scriptName: 'cresc' | 'pushy' = path.basename(process.argv[1]) as
4
- | 'cresc'
5
- | 'pushy';
3
+ const scriptName = path.basename(process.argv[1]) as 'cresc' | 'pushy';
6
4
  export const IS_CRESC = scriptName === 'cresc';
7
5
 
8
6
  export const credentialFile = IS_CRESC ? '.cresc.token' : '.update';
@@ -11,3 +9,7 @@ export const tempDir = IS_CRESC ? '.cresc.temp' : '.pushy';
11
9
  export const pricingPageUrl = IS_CRESC
12
10
  ? 'https://cresc.dev/pricing'
13
11
  : 'https://pushy.reactnative.cn/pricing.html';
12
+
13
+ export const defaultEndpoint = IS_CRESC
14
+ ? 'https://api.cresc.dev'
15
+ : 'https://update.reactnative.cn/api';
package/src/utils/i18n.ts CHANGED
@@ -2,12 +2,18 @@ import i18next from 'i18next';
2
2
  import en from '../locales/en';
3
3
  import zh from '../locales/zh';
4
4
  import { IS_CRESC } from './constants';
5
+
5
6
  i18next.init({
6
7
  lng: IS_CRESC ? 'en' : 'zh',
7
8
  // debug: process.env.NODE_ENV !== 'production',
9
+ // debug: true,
8
10
  resources: {
9
- en,
10
- zh,
11
+ en: {
12
+ translation: en,
13
+ },
14
+ zh: {
15
+ translation: zh,
16
+ },
11
17
  },
12
18
  });
13
19