react-native-update-cli 1.31.1 → 1.32.2
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.
- package/index.js +1 -0
- package/lib/api.js +38 -42
- package/lib/bundle.js +16 -16
- package/lib/types.js +4 -0
- package/lib/utils/index.js +11 -11
- package/lib/versions.js +14 -13
- package/package.json +16 -15
- package/src/.DS_Store +0 -0
- package/src/{api.js → api.ts} +44 -52
- package/src/bundle.js +2 -2
- package/src/types.ts +8 -0
- package/src/utils/.DS_Store +0 -0
- package/src/utils/index.js +10 -15
- package/src/versions.js +13 -12
- /package/src/{index.js → index.ts} +0 -0
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./lib');
|
package/lib/api.js
CHANGED
|
@@ -41,25 +41,25 @@ _export(exports, {
|
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
const _nodefetch = /*#__PURE__*/ _interop_require_default(require("node-fetch"));
|
|
44
|
-
const
|
|
45
|
-
const
|
|
44
|
+
const _nodefs = /*#__PURE__*/ _interop_require_default(require("node:fs"));
|
|
45
|
+
const _nodeutil = /*#__PURE__*/ _interop_require_default(require("node:util"));
|
|
46
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
46
47
|
const _progress = /*#__PURE__*/ _interop_require_default(require("progress"));
|
|
47
48
|
const _packagejson = /*#__PURE__*/ _interop_require_default(require("../package.json"));
|
|
48
49
|
const _tcpping = /*#__PURE__*/ _interop_require_default(require("tcp-ping"));
|
|
49
|
-
const _util = /*#__PURE__*/ _interop_require_default(require("util"));
|
|
50
|
-
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
51
50
|
const _filesizeparser = /*#__PURE__*/ _interop_require_default(require("filesize-parser"));
|
|
52
51
|
const _utils = require("./utils");
|
|
52
|
+
const _formdata = /*#__PURE__*/ _interop_require_default(require("form-data"));
|
|
53
53
|
function _interop_require_default(obj) {
|
|
54
54
|
return obj && obj.__esModule ? obj : {
|
|
55
55
|
default: obj
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
+
const tcpPing = _nodeutil.default.promisify(_tcpping.default.ping);
|
|
59
|
+
let session;
|
|
60
|
+
let savedSession;
|
|
58
61
|
const defaultEndpoint = 'https://update.reactnative.cn/api';
|
|
59
62
|
let host = process.env.PUSHY_REGISTRY || defaultEndpoint;
|
|
60
|
-
const tcpPing = _util.default.promisify(_tcpping.default.ping);
|
|
61
|
-
let session = undefined;
|
|
62
|
-
let savedSession = undefined;
|
|
63
63
|
const userAgent = `react-native-update-cli/${_packagejson.default.version}`;
|
|
64
64
|
const getSession = function() {
|
|
65
65
|
return session;
|
|
@@ -68,9 +68,9 @@ const replaceSession = function(newSession) {
|
|
|
68
68
|
session = newSession;
|
|
69
69
|
};
|
|
70
70
|
const loadSession = async function() {
|
|
71
|
-
if (
|
|
71
|
+
if (_nodefs.default.existsSync('.update')) {
|
|
72
72
|
try {
|
|
73
|
-
replaceSession(JSON.parse(
|
|
73
|
+
replaceSession(JSON.parse(_nodefs.default.readFileSync('.update', 'utf8')));
|
|
74
74
|
savedSession = session;
|
|
75
75
|
} catch (e) {
|
|
76
76
|
console.error('Failed to parse file `.update`. Try to remove it manually.');
|
|
@@ -83,13 +83,13 @@ const saveSession = function() {
|
|
|
83
83
|
if (session !== savedSession) {
|
|
84
84
|
const current = session;
|
|
85
85
|
const data = JSON.stringify(current, null, 4);
|
|
86
|
-
|
|
86
|
+
_nodefs.default.writeFileSync('.update', data, 'utf8');
|
|
87
87
|
savedSession = current;
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
const closeSession = function() {
|
|
91
|
-
if (
|
|
92
|
-
|
|
91
|
+
if (_nodefs.default.existsSync('.update')) {
|
|
92
|
+
_nodefs.default.unlinkSync('.update');
|
|
93
93
|
savedSession = undefined;
|
|
94
94
|
}
|
|
95
95
|
session = undefined;
|
|
@@ -109,9 +109,7 @@ async function query(url, options) {
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
if (resp.status !== 200) {
|
|
112
|
-
throw
|
|
113
|
-
status: resp.status
|
|
114
|
-
});
|
|
112
|
+
throw new Error(`${resp.status}: ${resp.statusText}`);
|
|
115
113
|
}
|
|
116
114
|
return json;
|
|
117
115
|
}
|
|
@@ -145,7 +143,7 @@ const put = queryWithBody('PUT');
|
|
|
145
143
|
const doDelete = queryWithBody('DELETE');
|
|
146
144
|
async function uploadFile(fn, key) {
|
|
147
145
|
const { url, backupUrl, formData, maxSize } = await post('/upload', {
|
|
148
|
-
ext:
|
|
146
|
+
ext: _nodepath.default.extname(fn)
|
|
149
147
|
});
|
|
150
148
|
let realUrl = url;
|
|
151
149
|
if (backupUrl) {
|
|
@@ -164,38 +162,36 @@ async function uploadFile(fn, key) {
|
|
|
164
162
|
}
|
|
165
163
|
// console.log({realUrl});
|
|
166
164
|
}
|
|
167
|
-
const fileSize =
|
|
165
|
+
const fileSize = _nodefs.default.statSync(fn).size;
|
|
168
166
|
if (maxSize && fileSize > (0, _filesizeparser.default)(maxSize)) {
|
|
169
|
-
throw new Error(
|
|
167
|
+
throw new Error(`此文件大小 ${(fileSize / 1048576).toFixed(1)}m , 超出当前额度 ${maxSize} 。您可以考虑升级付费业务以提升此额度。详情请访问: ${_utils.pricingPageUrl}`);
|
|
170
168
|
}
|
|
171
169
|
const bar = new _progress.default(' 上传中 [:bar] :percent :etas', {
|
|
172
170
|
complete: '=',
|
|
173
171
|
incomplete: ' ',
|
|
174
172
|
total: fileSize
|
|
175
173
|
});
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return reject(Object.assign(new Error(body), {
|
|
192
|
-
status: resp.statusCode
|
|
193
|
-
}));
|
|
194
|
-
}
|
|
195
|
-
resolve({
|
|
196
|
-
hash: formData.key
|
|
197
|
-
});
|
|
198
|
-
});
|
|
174
|
+
const form = new _formdata.default();
|
|
175
|
+
Object.entries(formData).forEach(([k, v])=>{
|
|
176
|
+
form.append(k, v);
|
|
177
|
+
});
|
|
178
|
+
const fileStream = _nodefs.default.createReadStream(fn);
|
|
179
|
+
fileStream.on('data', function(data) {
|
|
180
|
+
bar.tick(data.length);
|
|
181
|
+
});
|
|
182
|
+
if (key) {
|
|
183
|
+
form.append('key', key);
|
|
184
|
+
}
|
|
185
|
+
form.append('file', fileStream);
|
|
186
|
+
const res = await (0, _nodefetch.default)(realUrl, {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
body: form
|
|
199
189
|
});
|
|
200
|
-
|
|
190
|
+
if (res.status > 299) {
|
|
191
|
+
throw new Error(`${res.status}: ${res.statusText}`);
|
|
192
|
+
}
|
|
193
|
+
// const body = await response.json();
|
|
194
|
+
return {
|
|
195
|
+
hash: key || formData.key
|
|
196
|
+
};
|
|
201
197
|
}
|
package/lib/bundle.js
CHANGED
|
@@ -8,13 +8,13 @@ Object.defineProperty(exports, "commands", {
|
|
|
8
8
|
return commands;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const
|
|
11
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
12
12
|
const _utils = require("./utils");
|
|
13
13
|
const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
|
|
14
14
|
const _yazl = require("yazl");
|
|
15
15
|
const _yauzl = require("yauzl");
|
|
16
16
|
const _app = require("./app");
|
|
17
|
-
const
|
|
17
|
+
const _nodechild_process = require("node:child_process");
|
|
18
18
|
const _os = /*#__PURE__*/ _interop_require_default(require("os"));
|
|
19
19
|
function _interop_require_default(obj) {
|
|
20
20
|
return obj && obj.__esModule ? obj : {
|
|
@@ -76,7 +76,7 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
|
|
|
76
76
|
if (platform === 'android') {
|
|
77
77
|
gradleConfig = await checkGradleConfig();
|
|
78
78
|
if (gradleConfig.crunchPngs !== false) {
|
|
79
|
-
console.warn('android的crunchPngs选项似乎尚未禁用(如已禁用则请忽略此提示),这可能导致热更包体积异常增大,具体请参考 https://pushy.reactnative.cn/docs/getting-started.html#%E7%A6%81%E7%94%A8-android-%E7%9A%84-crunch-%E4%BC%98%E5%8C%96 \n');
|
|
79
|
+
console.warn('android 的 crunchPngs 选项似乎尚未禁用(如已禁用则请忽略此提示),这可能导致热更包体积异常增大,具体请参考 https://pushy.reactnative.cn/docs/getting-started.html#%E7%A6%81%E7%94%A8-android-%E7%9A%84-crunch-%E4%BC%98%E5%8C%96 \n');
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
let reactNativeBundleArgs = [];
|
|
@@ -124,7 +124,7 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
|
|
|
124
124
|
'--assets-dest',
|
|
125
125
|
outputFolder,
|
|
126
126
|
'--bundle-output',
|
|
127
|
-
|
|
127
|
+
_nodepath.default.join(outputFolder, bundleName),
|
|
128
128
|
'--dev',
|
|
129
129
|
development,
|
|
130
130
|
'--entry-file',
|
|
@@ -139,7 +139,7 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
|
|
|
139
139
|
if (config) {
|
|
140
140
|
reactNativeBundleArgs.push('--config', config);
|
|
141
141
|
}
|
|
142
|
-
const reactNativeBundleProcess = (0,
|
|
142
|
+
const reactNativeBundleProcess = (0, _nodechild_process.spawn)('node', reactNativeBundleArgs);
|
|
143
143
|
console.log(`Running bundle command: node ${reactNativeBundleArgs.join(' ')}`);
|
|
144
144
|
return new Promise((resolve, reject)=>{
|
|
145
145
|
reactNativeBundleProcess.stdout.on('data', (data)=>{
|
|
@@ -207,12 +207,12 @@ async function checkGradleConfig() {
|
|
|
207
207
|
async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput) {
|
|
208
208
|
console.log(`Hermes enabled, now compiling to hermes bytecode:\n`);
|
|
209
209
|
// >= rn 0.69
|
|
210
|
-
const rnDir =
|
|
210
|
+
const rnDir = _nodepath.default.dirname(require.resolve('react-native', {
|
|
211
211
|
paths: [
|
|
212
212
|
process.cwd()
|
|
213
213
|
]
|
|
214
214
|
}));
|
|
215
|
-
let hermesPath =
|
|
215
|
+
let hermesPath = _nodepath.default.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
|
|
216
216
|
// < rn 0.69
|
|
217
217
|
if (!_fsextra.existsSync(hermesPath)) {
|
|
218
218
|
hermesPath = `node_modules/hermes-engine/${getHermesOSBin()}`;
|
|
@@ -221,21 +221,21 @@ async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput)
|
|
|
221
221
|
const args = [
|
|
222
222
|
'-emit-binary',
|
|
223
223
|
'-out',
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
_nodepath.default.join(outputFolder, bundleName),
|
|
225
|
+
_nodepath.default.join(outputFolder, bundleName),
|
|
226
226
|
'-O'
|
|
227
227
|
];
|
|
228
228
|
if (sourcemapOutput) {
|
|
229
229
|
args.push('-output-source-map');
|
|
230
230
|
}
|
|
231
231
|
console.log('Running hermesc: ' + hermesCommand + ' ' + args.join(' ') + '\n');
|
|
232
|
-
(0,
|
|
232
|
+
(0, _nodechild_process.spawnSync)(hermesCommand, args, {
|
|
233
233
|
stdio: 'ignore'
|
|
234
234
|
});
|
|
235
235
|
}
|
|
236
236
|
async function pack(dir, output) {
|
|
237
237
|
console.log('Packing');
|
|
238
|
-
_fsextra.ensureDirSync(
|
|
238
|
+
_fsextra.ensureDirSync(_nodepath.default.dirname(output));
|
|
239
239
|
await new Promise((resolve, reject)=>{
|
|
240
240
|
const zipfile = new _yazl.ZipFile();
|
|
241
241
|
function addDirectory(root, rel) {
|
|
@@ -247,7 +247,7 @@ async function pack(dir, output) {
|
|
|
247
247
|
if (name === '.' || name === '..' || name === 'index.bundlejs.map') {
|
|
248
248
|
continue;
|
|
249
249
|
}
|
|
250
|
-
const fullPath =
|
|
250
|
+
const fullPath = _nodepath.default.join(root, name);
|
|
251
251
|
const stat = _fsextra.statSync(fullPath);
|
|
252
252
|
if (stat.isFile()) {
|
|
253
253
|
//console.log('adding: ' + rel+name);
|
|
@@ -291,7 +291,7 @@ function basename(fn) {
|
|
|
291
291
|
return m && m[1];
|
|
292
292
|
}
|
|
293
293
|
async function diffFromPPK(origin, next, output) {
|
|
294
|
-
_fsextra.ensureDirSync(
|
|
294
|
+
_fsextra.ensureDirSync(_nodepath.default.dirname(output));
|
|
295
295
|
const originEntries = {};
|
|
296
296
|
const originMap = {};
|
|
297
297
|
let originSource;
|
|
@@ -394,7 +394,7 @@ async function diffFromPPK(origin, next, output) {
|
|
|
394
394
|
await writePromise;
|
|
395
395
|
}
|
|
396
396
|
async function diffFromPackage(origin, next, output, originBundleName, transformPackagePath = (v)=>v) {
|
|
397
|
-
_fsextra.ensureDirSync(
|
|
397
|
+
_fsextra.ensureDirSync(_nodepath.default.dirname(output));
|
|
398
398
|
const originEntries = {};
|
|
399
399
|
const originMap = {};
|
|
400
400
|
let originSource;
|
|
@@ -526,7 +526,7 @@ const commands = {
|
|
|
526
526
|
...options,
|
|
527
527
|
platform
|
|
528
528
|
});
|
|
529
|
-
const sourcemapOutput =
|
|
529
|
+
const sourcemapOutput = _nodepath.default.join(intermediaDir, bundleName + '.map');
|
|
530
530
|
const realOutput = output.replace(/\$\{time\}/g, '' + Date.now());
|
|
531
531
|
if (!platform) {
|
|
532
532
|
throw new Error('Platform must be specified.');
|
|
@@ -534,7 +534,7 @@ const commands = {
|
|
|
534
534
|
const { version, major, minor } = (0, _utils.getRNVersion)();
|
|
535
535
|
console.log('Bundling with react-native: ', version);
|
|
536
536
|
await runReactNativeBundleCommand(bundleName, dev, entryFile, intermediaDir, platform, sourcemap ? sourcemapOutput : '');
|
|
537
|
-
await pack(
|
|
537
|
+
await pack(_nodepath.default.resolve(intermediaDir), realOutput);
|
|
538
538
|
const v = await (0, _utils.question)('是否现在上传此热更包?(Y/N)');
|
|
539
539
|
if (v.toLowerCase() === 'y') {
|
|
540
540
|
await this.publish({
|
package/lib/types.js
ADDED
package/lib/utils/index.js
CHANGED
|
@@ -35,26 +35,26 @@ _export(exports, {
|
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
37
|
const _fsextra = /*#__PURE__*/ _interop_require_default(require("fs-extra"));
|
|
38
|
-
const
|
|
39
|
-
const
|
|
38
|
+
const _nodeos = /*#__PURE__*/ _interop_require_default(require("node:os"));
|
|
39
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
40
40
|
const _packagejson = /*#__PURE__*/ _interop_require_default(require("../../package.json"));
|
|
41
41
|
const _appinfoparser = /*#__PURE__*/ _interop_require_default(require("./app-info-parser"));
|
|
42
42
|
const _satisfies = /*#__PURE__*/ _interop_require_default(require("semver/functions/satisfies"));
|
|
43
|
-
const _read =
|
|
43
|
+
const _read = require("read");
|
|
44
44
|
function _interop_require_default(obj) {
|
|
45
45
|
return obj && obj.__esModule ? obj : {
|
|
46
46
|
default: obj
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
-
function question(query, password) {
|
|
49
|
+
async function question(query, password) {
|
|
50
50
|
if (NO_INTERACTIVE) {
|
|
51
|
-
return
|
|
51
|
+
return '';
|
|
52
52
|
}
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
return (0, _read.read)({
|
|
54
|
+
prompt: query,
|
|
55
|
+
silent: password,
|
|
56
|
+
replace: password ? '*' : undefined
|
|
57
|
+
});
|
|
58
58
|
}
|
|
59
59
|
function translateOptions(options) {
|
|
60
60
|
const ret = {};
|
|
@@ -140,7 +140,7 @@ async function getIpaInfo(fn) {
|
|
|
140
140
|
...appCredential
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
|
-
const localDir =
|
|
143
|
+
const localDir = _nodepath.default.resolve(_nodeos.default.homedir(), '.pushy');
|
|
144
144
|
_fsextra.default.ensureDirSync(localDir);
|
|
145
145
|
function saveToLocal(originPath, destName) {
|
|
146
146
|
// TODO
|
package/lib/versions.js
CHANGED
|
@@ -123,7 +123,9 @@ const commands = {
|
|
|
123
123
|
let minPkgVersion = options.minPackageVersion;
|
|
124
124
|
let maxPkgVersion = options.maxPackageVersion;
|
|
125
125
|
let rollout = options.rollout;
|
|
126
|
-
if (rollout
|
|
126
|
+
if (rollout === undefined) {
|
|
127
|
+
rollout = null;
|
|
128
|
+
} else {
|
|
127
129
|
try {
|
|
128
130
|
rollout = parseInt(rollout);
|
|
129
131
|
} catch (e) {
|
|
@@ -156,7 +158,7 @@ const commands = {
|
|
|
156
158
|
await (0, _api.put)(`/app/${appId}/package/${pkg.id}`, {
|
|
157
159
|
versionId
|
|
158
160
|
});
|
|
159
|
-
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name}`);
|
|
161
|
+
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name} (id: ${pkg.id})`);
|
|
160
162
|
}
|
|
161
163
|
console.log(`操作完成,共已绑定 ${pkgs.length} 个原生版本`);
|
|
162
164
|
return;
|
|
@@ -184,14 +186,14 @@ const commands = {
|
|
|
184
186
|
await (0, _api.put)(`/app/${appId}/package/${pkg.id}`, {
|
|
185
187
|
versionId
|
|
186
188
|
});
|
|
187
|
-
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name}`);
|
|
189
|
+
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name} (id: ${pkg.id})`);
|
|
188
190
|
}
|
|
189
191
|
console.log(`操作完成,共已绑定 ${pkgs.length} 个原生版本`);
|
|
190
192
|
return;
|
|
191
193
|
}
|
|
194
|
+
const { data } = await (0, _api.get)(`/app/${appId}/package/list?limit=1000`);
|
|
192
195
|
if (pkgVersion) {
|
|
193
196
|
pkgVersion = pkgVersion.trim();
|
|
194
|
-
const { data } = await (0, _api.get)(`/app/${appId}/package/list?limit=1000`);
|
|
195
197
|
const pkg = data.find((d)=>d.name === pkgVersion);
|
|
196
198
|
if (pkg) {
|
|
197
199
|
pkgId = pkg.id;
|
|
@@ -205,14 +207,13 @@ const commands = {
|
|
|
205
207
|
if (!pkgId) {
|
|
206
208
|
throw new Error('请提供 packageId 或 packageVersion 参数');
|
|
207
209
|
}
|
|
208
|
-
if (
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (pkg) {
|
|
213
|
-
pkgVersion = pkg.name;
|
|
214
|
-
}
|
|
210
|
+
if (!pkgVersion) {
|
|
211
|
+
const pkg = data.find((d)=>d.id === pkgId);
|
|
212
|
+
if (pkg) {
|
|
213
|
+
pkgVersion = pkg.name;
|
|
215
214
|
}
|
|
215
|
+
}
|
|
216
|
+
if (rollout) {
|
|
216
217
|
await (0, _api.put)(`/app/${appId}/version/${versionId}`, {
|
|
217
218
|
config: {
|
|
218
219
|
rollout: {
|
|
@@ -220,12 +221,12 @@ const commands = {
|
|
|
220
221
|
}
|
|
221
222
|
}
|
|
222
223
|
});
|
|
223
|
-
console.log(`已将在原生版本 ${pkgVersion} 上设置灰度发布 ${rollout}% 热更版本 ${versionId} `);
|
|
224
|
+
console.log(`已将在原生版本 ${pkgVersion} (id: ${pkgId}) 上设置灰度发布 ${rollout}% 热更版本 ${versionId} `);
|
|
224
225
|
}
|
|
225
226
|
await (0, _api.put)(`/app/${appId}/package/${pkgId}`, {
|
|
226
227
|
versionId
|
|
227
228
|
});
|
|
228
|
-
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkgVersion}`);
|
|
229
|
+
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkgVersion} (id: ${pkgId})`);
|
|
229
230
|
},
|
|
230
231
|
updateVersionInfo: async function({ args, options }) {
|
|
231
232
|
const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android):'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-update-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.2",
|
|
4
4
|
"description": "Command tools for javaScript updater with `pushy` service for react native apps.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "swc src -d lib --strip-leading-paths",
|
|
16
|
-
"
|
|
16
|
+
"prepare": "npm run build && chmod +x lib/index.js"
|
|
17
17
|
},
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
@@ -32,37 +32,38 @@
|
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://github.com/reactnativecn/react-native-pushy/tree/master/react-native-pushy-cli",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"bplist-parser": "^0.2
|
|
35
|
+
"bplist-parser": "^0.3.2",
|
|
36
36
|
"bytebuffer": "^5.0.1",
|
|
37
37
|
"cgbi-to-png": "^1.0.7",
|
|
38
38
|
"cli-arguments": "^0.2.1",
|
|
39
|
-
"commander": "^
|
|
39
|
+
"commander": "^12.1.0",
|
|
40
40
|
"compare-versions": "^6.1.1",
|
|
41
|
-
"filesize-parser": "^1.5.
|
|
41
|
+
"filesize-parser": "^1.5.1",
|
|
42
|
+
"form-data": "^4.0.1",
|
|
42
43
|
"fs-extra": "8",
|
|
43
44
|
"gradle-to-js": "^2.0.1",
|
|
44
45
|
"isomorphic-unzip": "^1.1.5",
|
|
45
46
|
"node-fetch": "^2.6.1",
|
|
46
|
-
"plist": "^3.0
|
|
47
|
+
"plist": "^3.1.0",
|
|
47
48
|
"progress": "^2.0.3",
|
|
48
49
|
"properties": "^1.2.1",
|
|
49
|
-
"read": "^
|
|
50
|
-
"request": "^2.88.2",
|
|
50
|
+
"read": "^4.0.0",
|
|
51
51
|
"semver": "^7.6.3",
|
|
52
52
|
"tcp-ping": "^0.1.1",
|
|
53
53
|
"tty-table": "4.2",
|
|
54
54
|
"update-notifier": "^5.1.0",
|
|
55
|
-
"yauzl": "^2.
|
|
56
|
-
"yazl": "
|
|
55
|
+
"yauzl": "^3.2.0",
|
|
56
|
+
"yazl": "3.3.0"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">= 10"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@swc/cli": "^0.
|
|
63
|
-
"@swc/core": "^1.
|
|
64
|
-
"@types/node": "^22.
|
|
65
|
-
"oxlint": "^0.
|
|
62
|
+
"@swc/cli": "^0.5.0",
|
|
63
|
+
"@swc/core": "^1.9.2",
|
|
64
|
+
"@types/node": "^22.9.0",
|
|
65
|
+
"oxlint": "^0.11.1",
|
|
66
66
|
"typescript": "^5.6.3"
|
|
67
|
-
}
|
|
67
|
+
},
|
|
68
|
+
"packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72"
|
|
68
69
|
}
|
package/src/.DS_Store
ADDED
|
Binary file
|
package/src/{api.js → api.ts}
RENAMED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import fetch from 'node-fetch';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
import request from 'request';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import util from 'node:util';
|
|
4
|
+
import path from 'node:path';
|
|
6
5
|
import ProgressBar from 'progress';
|
|
7
6
|
import packageJson from '../package.json';
|
|
8
7
|
import tcpp from 'tcp-ping';
|
|
9
|
-
import util from 'util';
|
|
10
|
-
import path from 'path';
|
|
11
8
|
import filesizeParser from 'filesize-parser';
|
|
12
9
|
import { pricingPageUrl } from './utils';
|
|
10
|
+
import { Session } from 'types';
|
|
11
|
+
import FormData from 'form-data';
|
|
13
12
|
|
|
14
13
|
const tcpPing = util.promisify(tcpp.ping);
|
|
15
14
|
|
|
16
|
-
let session
|
|
17
|
-
let savedSession
|
|
15
|
+
let session: Session | undefined;
|
|
16
|
+
let savedSession: Session | undefined;
|
|
17
|
+
|
|
18
|
+
const defaultEndpoint = 'https://update.reactnative.cn/api';
|
|
19
|
+
let host = process.env.PUSHY_REGISTRY || defaultEndpoint;
|
|
18
20
|
|
|
19
21
|
const userAgent = `react-native-update-cli/${packageJson.version}`;
|
|
20
22
|
|
|
@@ -22,7 +24,7 @@ export const getSession = function () {
|
|
|
22
24
|
return session;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
|
-
export const replaceSession = function (newSession) {
|
|
27
|
+
export const replaceSession = function (newSession: { token: string }) {
|
|
26
28
|
session = newSession;
|
|
27
29
|
};
|
|
28
30
|
|
|
@@ -59,7 +61,7 @@ export const closeSession = function () {
|
|
|
59
61
|
host = process.env.PUSHY_REGISTRY || defaultEndpoint;
|
|
60
62
|
};
|
|
61
63
|
|
|
62
|
-
async function query(url, options) {
|
|
64
|
+
async function query(url: string, options: fetch.RequestInit) {
|
|
63
65
|
const resp = await fetch(url, options);
|
|
64
66
|
const text = await resp.text();
|
|
65
67
|
let json;
|
|
@@ -74,18 +76,13 @@ async function query(url, options) {
|
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
if (resp.status !== 200) {
|
|
77
|
-
throw
|
|
78
|
-
new Error(json.message || json.error || resp.statusText),
|
|
79
|
-
{
|
|
80
|
-
status: resp.status,
|
|
81
|
-
},
|
|
82
|
-
);
|
|
79
|
+
throw new Error(`${resp.status}: ${resp.statusText}`);
|
|
83
80
|
}
|
|
84
81
|
return json;
|
|
85
82
|
}
|
|
86
83
|
|
|
87
|
-
function queryWithoutBody(method) {
|
|
88
|
-
return function (api) {
|
|
84
|
+
function queryWithoutBody(method: string) {
|
|
85
|
+
return function (api: string) {
|
|
89
86
|
return query(host + api, {
|
|
90
87
|
method,
|
|
91
88
|
headers: {
|
|
@@ -96,8 +93,8 @@ function queryWithoutBody(method) {
|
|
|
96
93
|
};
|
|
97
94
|
}
|
|
98
95
|
|
|
99
|
-
function queryWithBody(method) {
|
|
100
|
-
return function (api, body) {
|
|
96
|
+
function queryWithBody(method: string) {
|
|
97
|
+
return function (api: string, body: Record<string, any>) {
|
|
101
98
|
return query(host + api, {
|
|
102
99
|
method,
|
|
103
100
|
headers: {
|
|
@@ -115,12 +112,11 @@ export const post = queryWithBody('POST');
|
|
|
115
112
|
export const put = queryWithBody('PUT');
|
|
116
113
|
export const doDelete = queryWithBody('DELETE');
|
|
117
114
|
|
|
118
|
-
export async function uploadFile(fn, key) {
|
|
115
|
+
export async function uploadFile(fn: string, key?: string) {
|
|
119
116
|
const { url, backupUrl, formData, maxSize } = await post('/upload', {
|
|
120
117
|
ext: path.extname(fn),
|
|
121
118
|
});
|
|
122
119
|
let realUrl = url;
|
|
123
|
-
|
|
124
120
|
if (backupUrl) {
|
|
125
121
|
if (global.USE_ACC_OSS) {
|
|
126
122
|
realUrl = backupUrl;
|
|
@@ -141,9 +137,9 @@ export async function uploadFile(fn, key) {
|
|
|
141
137
|
const fileSize = fs.statSync(fn).size;
|
|
142
138
|
if (maxSize && fileSize > filesizeParser(maxSize)) {
|
|
143
139
|
throw new Error(
|
|
144
|
-
|
|
140
|
+
`此文件大小 ${(fileSize / 1048576).toFixed(
|
|
145
141
|
1,
|
|
146
|
-
)}m,
|
|
142
|
+
)}m , 超出当前额度 ${maxSize} 。您可以考虑升级付费业务以提升此额度。详情请访问: ${pricingPageUrl}`,
|
|
147
143
|
);
|
|
148
144
|
}
|
|
149
145
|
|
|
@@ -153,34 +149,30 @@ export async function uploadFile(fn, key) {
|
|
|
153
149
|
total: fileSize,
|
|
154
150
|
});
|
|
155
151
|
|
|
156
|
-
const
|
|
157
|
-
if (key) {
|
|
158
|
-
formData.key = key;
|
|
159
|
-
}
|
|
160
|
-
formData.file = fs.createReadStream(fn);
|
|
152
|
+
const form = new FormData();
|
|
161
153
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}),
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
resolve({ hash: formData.key });
|
|
182
|
-
},
|
|
183
|
-
);
|
|
154
|
+
Object.entries(formData).forEach(([k, v]) => {
|
|
155
|
+
form.append(k, v);
|
|
156
|
+
});
|
|
157
|
+
const fileStream = fs.createReadStream(fn);
|
|
158
|
+
fileStream.on('data', function (data) {
|
|
159
|
+
bar.tick(data.length);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
if (key) {
|
|
163
|
+
form.append('key', key);
|
|
164
|
+
}
|
|
165
|
+
form.append('file', fileStream);
|
|
166
|
+
|
|
167
|
+
const res = await fetch(realUrl, {
|
|
168
|
+
method: 'POST',
|
|
169
|
+
body: form,
|
|
184
170
|
});
|
|
185
|
-
|
|
171
|
+
|
|
172
|
+
if (res.status > 299) {
|
|
173
|
+
throw new Error(`${res.status}: ${res.statusText}`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// const body = await response.json();
|
|
177
|
+
return { hash: key || formData.key };
|
|
186
178
|
}
|
package/src/bundle.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import path from 'path';
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import { getRNVersion, translateOptions } from './utils';
|
|
3
3
|
import * as fs from 'fs-extra';
|
|
4
4
|
import { ZipFile } from 'yazl';
|
|
5
5
|
import { open as openZipFile } from 'yauzl';
|
|
6
6
|
import { question, printVersionCommand } from './utils';
|
|
7
7
|
import { checkPlatform } from './app';
|
|
8
|
-
import { spawn, spawnSync } from 'child_process';
|
|
8
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
9
9
|
const g2js = require('gradle-to-js/lib/parser');
|
|
10
10
|
import os from 'os';
|
|
11
11
|
const properties = require('properties');
|
package/src/types.ts
ADDED
|
Binary file
|
package/src/utils/index.js
CHANGED
|
@@ -1,26 +1,21 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
import path from 'path';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import pkg from '../../package.json';
|
|
5
5
|
import AppInfoParser from './app-info-parser';
|
|
6
6
|
import semverSatisfies from 'semver/functions/satisfies';
|
|
7
7
|
|
|
8
|
-
import read from 'read';
|
|
8
|
+
import { read } from 'read';
|
|
9
9
|
|
|
10
|
-
export function question(query, password) {
|
|
10
|
+
export async function question(query, password) {
|
|
11
11
|
if (NO_INTERACTIVE) {
|
|
12
|
-
return
|
|
12
|
+
return '';
|
|
13
13
|
}
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
replace: password ? '*' : undefined,
|
|
20
|
-
},
|
|
21
|
-
(err, result) => (err ? reject(err) : resolve(result)),
|
|
22
|
-
),
|
|
23
|
-
);
|
|
14
|
+
return read({
|
|
15
|
+
prompt: query,
|
|
16
|
+
silent: password,
|
|
17
|
+
replace: password ? '*' : undefined,
|
|
18
|
+
});
|
|
24
19
|
}
|
|
25
20
|
|
|
26
21
|
export function translateOptions(options) {
|
package/src/versions.js
CHANGED
|
@@ -173,7 +173,7 @@ export const commands = {
|
|
|
173
173
|
await put(`/app/${appId}/package/${pkg.id}`, {
|
|
174
174
|
versionId,
|
|
175
175
|
});
|
|
176
|
-
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name}`);
|
|
176
|
+
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name} (id: ${pkg.id})`);
|
|
177
177
|
}
|
|
178
178
|
console.log(`操作完成,共已绑定 ${pkgs.length} 个原生版本`);
|
|
179
179
|
return;
|
|
@@ -205,15 +205,15 @@ export const commands = {
|
|
|
205
205
|
await put(`/app/${appId}/package/${pkg.id}`, {
|
|
206
206
|
versionId,
|
|
207
207
|
});
|
|
208
|
-
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name}`);
|
|
208
|
+
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkg.name} (id: ${pkg.id})`);
|
|
209
209
|
}
|
|
210
210
|
console.log(`操作完成,共已绑定 ${pkgs.length} 个原生版本`);
|
|
211
211
|
return;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
|
214
215
|
if (pkgVersion) {
|
|
215
216
|
pkgVersion = pkgVersion.trim();
|
|
216
|
-
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
|
217
217
|
const pkg = data.find((d) => d.name === pkgVersion);
|
|
218
218
|
if (pkg) {
|
|
219
219
|
pkgId = pkg.id;
|
|
@@ -228,14 +228,15 @@ export const commands = {
|
|
|
228
228
|
if (!pkgId) {
|
|
229
229
|
throw new Error('请提供 packageId 或 packageVersion 参数');
|
|
230
230
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
pkgVersion = pkg.name;
|
|
237
|
-
}
|
|
231
|
+
|
|
232
|
+
if (!pkgVersion) {
|
|
233
|
+
const pkg = data.find((d) => d.id === pkgId);
|
|
234
|
+
if (pkg) {
|
|
235
|
+
pkgVersion = pkg.name;
|
|
238
236
|
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (rollout) {
|
|
239
240
|
await put(`/app/${appId}/version/${versionId}`, {
|
|
240
241
|
config: {
|
|
241
242
|
rollout: {
|
|
@@ -244,13 +245,13 @@ export const commands = {
|
|
|
244
245
|
},
|
|
245
246
|
});
|
|
246
247
|
console.log(
|
|
247
|
-
`已将在原生版本 ${pkgVersion} 上设置灰度发布 ${rollout}% 热更版本 ${versionId} `,
|
|
248
|
+
`已将在原生版本 ${pkgVersion} (id: ${pkgId}) 上设置灰度发布 ${rollout}% 热更版本 ${versionId} `,
|
|
248
249
|
);
|
|
249
250
|
}
|
|
250
251
|
await put(`/app/${appId}/package/${pkgId}`, {
|
|
251
252
|
versionId,
|
|
252
253
|
});
|
|
253
|
-
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkgVersion}`);
|
|
254
|
+
console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkgVersion} (id: ${pkgId})`);
|
|
254
255
|
},
|
|
255
256
|
updateVersionInfo: async function ({ args, options }) {
|
|
256
257
|
const platform = checkPlatform(
|
|
File without changes
|