rn-update-cli 1.0.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.
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/README.zh-CN.md +167 -0
- package/cli.json +525 -0
- package/lib/api.d.ts +56 -0
- package/lib/api.js +671 -0
- package/lib/app.d.ts +107 -0
- package/lib/app.js +329 -0
- package/lib/auto-update.d.ts +35 -0
- package/lib/auto-update.js +507 -0
- package/lib/bin.d.ts +2 -0
- package/lib/bin.js +133 -0
- package/lib/bundle-pack.d.ts +6 -0
- package/lib/bundle-pack.js +91 -0
- package/lib/bundle-runner.d.ts +168 -0
- package/lib/bundle-runner.js +1305 -0
- package/lib/bundle.d.ts +45 -0
- package/lib/bundle.js +226 -0
- package/lib/cache.d.ts +10 -0
- package/lib/cache.js +25 -0
- package/lib/commands.d.ts +11 -0
- package/lib/commands.js +72 -0
- package/lib/diff.d.ts +18 -0
- package/lib/diff.js +690 -0
- package/lib/exports.d.ts +11 -0
- package/lib/exports.js +20 -0
- package/lib/install.d.ts +9 -0
- package/lib/install.js +51 -0
- package/lib/locales/en.d.ts +187 -0
- package/lib/locales/en.js +194 -0
- package/lib/locales/zh.d.ts +187 -0
- package/lib/locales/zh.js +194 -0
- package/lib/native-package.d.ts +21 -0
- package/lib/native-package.js +298 -0
- package/lib/package.d.ts +68 -0
- package/lib/package.js +487 -0
- package/lib/provider.d.ts +24 -0
- package/lib/provider.js +244 -0
- package/lib/standalone-publish.d.ts +17 -0
- package/lib/standalone-publish.js +433 -0
- package/lib/symbolicate.d.ts +35 -0
- package/lib/symbolicate.js +130 -0
- package/lib/types.d.ts +152 -0
- package/lib/types.js +2 -0
- package/lib/user.d.ts +8 -0
- package/lib/user.js +50 -0
- package/lib/utils/add-gitignore.d.ts +6 -0
- package/lib/utils/add-gitignore.js +44 -0
- package/lib/utils/app-info-parser/aab.d.ts +27 -0
- package/lib/utils/app-info-parser/aab.js +256 -0
- package/lib/utils/app-info-parser/apk.d.ts +19 -0
- package/lib/utils/app-info-parser/apk.js +95 -0
- package/lib/utils/app-info-parser/app.d.ts +9 -0
- package/lib/utils/app-info-parser/app.js +15 -0
- package/lib/utils/app-info-parser/index.d.ts +21 -0
- package/lib/utils/app-info-parser/index.js +51 -0
- package/lib/utils/app-info-parser/ipa.d.ts +19 -0
- package/lib/utils/app-info-parser/ipa.js +101 -0
- package/lib/utils/app-info-parser/resource-finder.d.ts +49 -0
- package/lib/utils/app-info-parser/resource-finder.js +429 -0
- package/lib/utils/app-info-parser/utils.d.ts +36 -0
- package/lib/utils/app-info-parser/utils.js +140 -0
- package/lib/utils/app-info-parser/xml-parser/binary.d.ts +61 -0
- package/lib/utils/app-info-parser/xml-parser/binary.js +577 -0
- package/lib/utils/app-info-parser/xml-parser/manifest.d.ts +15 -0
- package/lib/utils/app-info-parser/xml-parser/manifest.js +207 -0
- package/lib/utils/app-info-parser/zip.d.ts +29 -0
- package/lib/utils/app-info-parser/zip.js +97 -0
- package/lib/utils/check-lockfile.d.ts +6 -0
- package/lib/utils/check-lockfile.js +93 -0
- package/lib/utils/check-plugin.d.ts +12 -0
- package/lib/utils/check-plugin.js +36 -0
- package/lib/utils/command-result.d.ts +8 -0
- package/lib/utils/command-result.js +27 -0
- package/lib/utils/constants.d.ts +10 -0
- package/lib/utils/constants.js +39 -0
- package/lib/utils/dep-versions.d.ts +20 -0
- package/lib/utils/dep-versions.js +129 -0
- package/lib/utils/git.d.ts +14 -0
- package/lib/utils/git.js +64 -0
- package/lib/utils/hbcTransform.d.ts +111 -0
- package/lib/utils/hbcTransform.js +561 -0
- package/lib/utils/hermes-base.d.ts +227 -0
- package/lib/utils/hermes-base.js +1287 -0
- package/lib/utils/hermes-literals.d.ts +64 -0
- package/lib/utils/hermes-literals.js +260 -0
- package/lib/utils/http-helper.d.ts +10 -0
- package/lib/utils/http-helper.js +150 -0
- package/lib/utils/i18n.d.ts +22 -0
- package/lib/utils/i18n.js +46 -0
- package/lib/utils/index.d.ts +67 -0
- package/lib/utils/index.js +545 -0
- package/lib/utils/latest-version/index.d.ts +154 -0
- package/lib/utils/latest-version/index.js +331 -0
- package/lib/utils/options.d.ts +10 -0
- package/lib/utils/options.js +68 -0
- package/lib/utils/plugin-config.d.ts +14 -0
- package/lib/utils/plugin-config.js +66 -0
- package/lib/utils/runtime.d.ts +54 -0
- package/lib/utils/runtime.js +263 -0
- package/lib/utils/slim-sourcemap.d.ts +28 -0
- package/lib/utils/slim-sourcemap.js +106 -0
- package/lib/utils/zip-entries.d.ts +10 -0
- package/lib/utils/zip-entries.js +211 -0
- package/lib/utils/zip-options.d.ts +17 -0
- package/lib/utils/zip-options.js +190 -0
- package/lib/utils/zip-range.d.ts +148 -0
- package/lib/utils/zip-range.js +581 -0
- package/lib/utils/zip-raw-writer.d.ts +52 -0
- package/lib/utils/zip-raw-writer.js +209 -0
- package/lib/version-operations.d.ts +21 -0
- package/lib/version-operations.js +320 -0
- package/lib/versions.d.ts +66 -0
- package/lib/versions.js +402 -0
- package/package.json +113 -0
- package/proto/Configuration.proto +183 -0
- package/proto/Resources.proto +569 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export type LiteralValue = {
|
|
2
|
+
kind: 'null' | 'true' | 'false' | 'undefined';
|
|
3
|
+
} | {
|
|
4
|
+
kind: 'number';
|
|
5
|
+
value: number;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'int';
|
|
8
|
+
value: number;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'string';
|
|
11
|
+
id: number;
|
|
12
|
+
};
|
|
13
|
+
/** The literal buffers of an HBC file, in one of the two layouts. */
|
|
14
|
+
export type LiteralBuffers = {
|
|
15
|
+
layout: 'split';
|
|
16
|
+
version: number;
|
|
17
|
+
array: Buffer;
|
|
18
|
+
objectKeys: Buffer;
|
|
19
|
+
objectValues: Buffer;
|
|
20
|
+
} | {
|
|
21
|
+
layout: 'shaped';
|
|
22
|
+
version: number;
|
|
23
|
+
values: Buffer;
|
|
24
|
+
objectKeys: Buffer;
|
|
25
|
+
shapes: Buffer;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Read only the literal buffers of an HBC file (header + three byte ranges,
|
|
29
|
+
* never the whole file). Null for a file whose layout is unknown: the caller
|
|
30
|
+
* then falls back to comparing the dumped buffers as a whole.
|
|
31
|
+
*/
|
|
32
|
+
export declare function readLiteralBuffers(file: string): Promise<LiteralBuffers | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Decode `count` literal values starting at byte `offset`. Null when the
|
|
35
|
+
* offset or a run reaches outside the buffer or a tag type is unknown; the
|
|
36
|
+
* caller reports that as a difference rather than guessing. `layout` decides
|
|
37
|
+
* what type 6 means (see the file comment).
|
|
38
|
+
*/
|
|
39
|
+
export declare function decodeSerializedLiterals(buffer: Buffer, offset: number, count: number, layout?: LiteralBuffers['layout']): LiteralValue[] | null;
|
|
40
|
+
/**
|
|
41
|
+
* One literal as text, string ids resolved through the dump's string table
|
|
42
|
+
* (an unknown id stays visible as `?id`). Doubles keep their exact bits in
|
|
43
|
+
* the text so -0 and 0, or two NaNs, never collide by accident.
|
|
44
|
+
*/
|
|
45
|
+
export declare function renderLiteral(value: LiteralValue, strings: Map<number, string>): string;
|
|
46
|
+
/**
|
|
47
|
+
* Decodes the literals an instruction refers to, for one side of a compare.
|
|
48
|
+
* Returns rendered entries, or null when the offset cannot be decoded.
|
|
49
|
+
*/
|
|
50
|
+
export declare class LiteralResolver {
|
|
51
|
+
private readonly buffers;
|
|
52
|
+
private readonly strings;
|
|
53
|
+
constructor(buffers: LiteralBuffers, strings: Map<number, string>);
|
|
54
|
+
private decode;
|
|
55
|
+
get layout(): LiteralBuffers['layout'];
|
|
56
|
+
array(offset: number, count: number): string[] | null;
|
|
57
|
+
objectKeys(offset: number, count: number): string[] | null;
|
|
58
|
+
objectValues(offset: number, count: number): string[] | null;
|
|
59
|
+
/** Shape table entry (HBC v98); null out of range or in the split layout. */
|
|
60
|
+
shape(index: number): {
|
|
61
|
+
keyOffset: number;
|
|
62
|
+
count: number;
|
|
63
|
+
} | null;
|
|
64
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LiteralResolver = void 0;
|
|
4
|
+
exports.readLiteralBuffers = readLiteralBuffers;
|
|
5
|
+
exports.decodeSerializedLiterals = decodeSerializedLiterals;
|
|
6
|
+
exports.renderLiteral = renderLiteral;
|
|
7
|
+
/**
|
|
8
|
+
* [INPUT]: 依赖 HBC 头部布局解析与二进制文件句柄,读取 Hermes 字面量缓冲区和 v98 shape 表
|
|
9
|
+
* [OUTPUT]: 对外提供字面量缓冲区读取、SLP 值解码、文本渲染与按指令定位的 LiteralResolver
|
|
10
|
+
* [POS]: CLI Hermes 等价校验的二进制语义层,屏蔽 split/shaped HBC 布局差异,不负责反汇编进程
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Binary literal buffers of an HBC file, for the Hermes base equivalence
|
|
14
|
+
* check (see docs/hermes-base-verification.md §3.2).
|
|
15
|
+
*
|
|
16
|
+
* `NewArrayWithBuffer` / `NewObjectWithBuffer` reference their literals by
|
|
17
|
+
* *byte offset* into the serialized literal buffers. The text dump prints
|
|
18
|
+
* those buffers entry by entry without byte positions, so the offsets in the
|
|
19
|
+
* instructions cannot be mapped to entries from the dump alone — and a delta
|
|
20
|
+
* build may lay the buffers out differently (deduplicated runs, different
|
|
21
|
+
* order) while every instruction still resolves to the same literals. Reading
|
|
22
|
+
* the buffers from the file and decoding at each instruction's offset
|
|
23
|
+
* compares what the instruction actually builds.
|
|
24
|
+
*
|
|
25
|
+
* Serialized literal format (hermes SerializedLiteralGenerator): runs of
|
|
26
|
+
* same-typed values. Tag byte: bits 6..4 = type, bit 7 = "length continues in
|
|
27
|
+
* the next byte", bits 3..0 = low 4 bits of the run length (high 8 bits in
|
|
28
|
+
* the next byte when bit 7 is set). Values follow the tag, fixed width per
|
|
29
|
+
* type: none (null/true/false), 8-byte little-endian double, 4/2/1-byte
|
|
30
|
+
* string id, 4-byte little-endian int32. HBC v98 reuses type 6 (the 1-byte
|
|
31
|
+
* string id before) for `undefined`, which takes no value bytes; string ids
|
|
32
|
+
* there are always 2 or 4 bytes wide.
|
|
33
|
+
*
|
|
34
|
+
* Two file layouts use that format:
|
|
35
|
+
* - HBC v87–96 (`split`): arrayBuffer, objKeyBuffer, objValueBuffer.
|
|
36
|
+
* `NewArrayWithBuffer dst, sizeHint, count, arrayOffset`;
|
|
37
|
+
* `NewObjectWithBuffer dst, sizeHint, count, keyOffset, valueOffset`.
|
|
38
|
+
* - HBC v98 (`shaped`): literalValueBuffer (array elements and object values
|
|
39
|
+
* alike), objKeyBuffer, objShapeTable (8-byte entries: keyOffset u32,
|
|
40
|
+
* numProps u32). `NewArrayWithBuffer dst, sizeHint, count, valueOffset`;
|
|
41
|
+
* `NewObjectWithBuffer dst, shapeIndex, valueOffset` and
|
|
42
|
+
* `NewObjectWithBufferAndParent dst, parent, shapeIndex, valueOffset`.
|
|
43
|
+
*/
|
|
44
|
+
const promises_1 = require("node:fs/promises");
|
|
45
|
+
const hbcTransform_1 = require("./hbcTransform");
|
|
46
|
+
const HBC_HEADER_SIZE = 128;
|
|
47
|
+
const TAG_TYPE_MASK = 0x70;
|
|
48
|
+
const TAG_LENGTH_CONTINUES = 0x80;
|
|
49
|
+
const TAG_LENGTH_LOW = 0x0f;
|
|
50
|
+
var Tag;
|
|
51
|
+
(function (Tag) {
|
|
52
|
+
Tag[Tag["Null"] = 0] = "Null";
|
|
53
|
+
Tag[Tag["True"] = 16] = "True";
|
|
54
|
+
Tag[Tag["False"] = 32] = "False";
|
|
55
|
+
Tag[Tag["Number"] = 48] = "Number";
|
|
56
|
+
Tag[Tag["LongString"] = 64] = "LongString";
|
|
57
|
+
Tag[Tag["ShortString"] = 80] = "ShortString";
|
|
58
|
+
/** HBC ≤96: 1-byte string id; HBC v98: `undefined` */
|
|
59
|
+
Tag[Tag["ByteStringOrUndefined"] = 96] = "ByteStringOrUndefined";
|
|
60
|
+
Tag[Tag["Integer"] = 112] = "Integer";
|
|
61
|
+
})(Tag || (Tag = {}));
|
|
62
|
+
const SHAPE_ENTRY_SIZE = 8;
|
|
63
|
+
/**
|
|
64
|
+
* Read only the literal buffers of an HBC file (header + three byte ranges,
|
|
65
|
+
* never the whole file). Null for a file whose layout is unknown: the caller
|
|
66
|
+
* then falls back to comparing the dumped buffers as a whole.
|
|
67
|
+
*/
|
|
68
|
+
async function readLiteralBuffers(file) {
|
|
69
|
+
const handle = await (0, promises_1.open)(file, 'r');
|
|
70
|
+
try {
|
|
71
|
+
const { size } = await handle.stat();
|
|
72
|
+
if (size < HBC_HEADER_SIZE)
|
|
73
|
+
return null;
|
|
74
|
+
const header = Buffer.alloc(HBC_HEADER_SIZE);
|
|
75
|
+
const read = await handle.read(header, 0, HBC_HEADER_SIZE, 0);
|
|
76
|
+
if (read.bytesRead !== HBC_HEADER_SIZE)
|
|
77
|
+
return null;
|
|
78
|
+
const resolved = (0, hbcTransform_1.resolveHbcSections)(header, size);
|
|
79
|
+
if (!resolved)
|
|
80
|
+
return null;
|
|
81
|
+
const readRanges = async (names) => {
|
|
82
|
+
const ranges = names.map((name) => resolved.sections.get(name));
|
|
83
|
+
if (ranges.some((r) => !r))
|
|
84
|
+
return null;
|
|
85
|
+
const bufs = await Promise.all(ranges.map(async (r) => {
|
|
86
|
+
const buf = Buffer.alloc(r.size);
|
|
87
|
+
if (r.size === 0)
|
|
88
|
+
return buf;
|
|
89
|
+
const { bytesRead } = await handle.read(buf, 0, r.size, r.start);
|
|
90
|
+
return bytesRead === r.size ? buf : null;
|
|
91
|
+
}));
|
|
92
|
+
return bufs.some((b) => !b) ? null : bufs;
|
|
93
|
+
};
|
|
94
|
+
const { version } = resolved;
|
|
95
|
+
if (resolved.sections.has('objShapeTable')) {
|
|
96
|
+
const bufs = await readRanges([
|
|
97
|
+
'literalValueBuffer',
|
|
98
|
+
'objKeyBuffer',
|
|
99
|
+
'objShapeTable',
|
|
100
|
+
]);
|
|
101
|
+
if (!bufs)
|
|
102
|
+
return null;
|
|
103
|
+
const [values, objectKeys, shapes] = bufs;
|
|
104
|
+
return { layout: 'shaped', version, values, objectKeys, shapes };
|
|
105
|
+
}
|
|
106
|
+
const bufs = await readRanges([
|
|
107
|
+
'arrayBuffer',
|
|
108
|
+
'objKeyBuffer',
|
|
109
|
+
'objValueBuffer',
|
|
110
|
+
]);
|
|
111
|
+
if (!bufs)
|
|
112
|
+
return null;
|
|
113
|
+
const [array, objectKeys, objectValues] = bufs;
|
|
114
|
+
return { layout: 'split', version, array, objectKeys, objectValues };
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
await handle.close();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Decode `count` literal values starting at byte `offset`. Null when the
|
|
122
|
+
* offset or a run reaches outside the buffer or a tag type is unknown; the
|
|
123
|
+
* caller reports that as a difference rather than guessing. `layout` decides
|
|
124
|
+
* what type 6 means (see the file comment).
|
|
125
|
+
*/
|
|
126
|
+
function decodeSerializedLiterals(buffer, offset, count, layout = 'split') {
|
|
127
|
+
const values = [];
|
|
128
|
+
let pos = offset;
|
|
129
|
+
while (values.length < count) {
|
|
130
|
+
if (pos < 0 || pos >= buffer.length)
|
|
131
|
+
return null;
|
|
132
|
+
const tag = buffer[pos++];
|
|
133
|
+
let length = tag & TAG_LENGTH_LOW;
|
|
134
|
+
if (tag & TAG_LENGTH_CONTINUES) {
|
|
135
|
+
if (pos >= buffer.length)
|
|
136
|
+
return null;
|
|
137
|
+
length = (length << 8) | buffer[pos++];
|
|
138
|
+
}
|
|
139
|
+
const type = tag & TAG_TYPE_MASK;
|
|
140
|
+
for (let i = 0; i < length && values.length < count; i++) {
|
|
141
|
+
switch (type) {
|
|
142
|
+
case Tag.Null:
|
|
143
|
+
values.push({ kind: 'null' });
|
|
144
|
+
break;
|
|
145
|
+
case Tag.True:
|
|
146
|
+
values.push({ kind: 'true' });
|
|
147
|
+
break;
|
|
148
|
+
case Tag.False:
|
|
149
|
+
values.push({ kind: 'false' });
|
|
150
|
+
break;
|
|
151
|
+
case Tag.Number:
|
|
152
|
+
if (pos + 8 > buffer.length)
|
|
153
|
+
return null;
|
|
154
|
+
values.push({ kind: 'number', value: buffer.readDoubleLE(pos) });
|
|
155
|
+
pos += 8;
|
|
156
|
+
break;
|
|
157
|
+
case Tag.LongString:
|
|
158
|
+
if (pos + 4 > buffer.length)
|
|
159
|
+
return null;
|
|
160
|
+
values.push({ kind: 'string', id: buffer.readUInt32LE(pos) });
|
|
161
|
+
pos += 4;
|
|
162
|
+
break;
|
|
163
|
+
case Tag.ShortString:
|
|
164
|
+
if (pos + 2 > buffer.length)
|
|
165
|
+
return null;
|
|
166
|
+
values.push({ kind: 'string', id: buffer.readUInt16LE(pos) });
|
|
167
|
+
pos += 2;
|
|
168
|
+
break;
|
|
169
|
+
case Tag.ByteStringOrUndefined:
|
|
170
|
+
if (layout === 'shaped') {
|
|
171
|
+
values.push({ kind: 'undefined' });
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
if (pos + 1 > buffer.length)
|
|
175
|
+
return null;
|
|
176
|
+
values.push({ kind: 'string', id: buffer[pos] });
|
|
177
|
+
pos += 1;
|
|
178
|
+
break;
|
|
179
|
+
case Tag.Integer:
|
|
180
|
+
if (pos + 4 > buffer.length)
|
|
181
|
+
return null;
|
|
182
|
+
values.push({ kind: 'int', value: buffer.readInt32LE(pos) });
|
|
183
|
+
pos += 4;
|
|
184
|
+
break;
|
|
185
|
+
default:
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return values;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* One literal as text, string ids resolved through the dump's string table
|
|
194
|
+
* (an unknown id stays visible as `?id`). Doubles keep their exact bits in
|
|
195
|
+
* the text so -0 and 0, or two NaNs, never collide by accident.
|
|
196
|
+
*/
|
|
197
|
+
function renderLiteral(value, strings) {
|
|
198
|
+
switch (value.kind) {
|
|
199
|
+
case 'null':
|
|
200
|
+
case 'true':
|
|
201
|
+
case 'false':
|
|
202
|
+
case 'undefined':
|
|
203
|
+
return value.kind;
|
|
204
|
+
case 'int':
|
|
205
|
+
return `[int ${value.value}]`;
|
|
206
|
+
case 'number': {
|
|
207
|
+
const bits = Buffer.alloc(8);
|
|
208
|
+
bits.writeDoubleLE(value.value);
|
|
209
|
+
return `[double ${Object.is(value.value, -0) ? '-0' : String(value.value)}#${bits.toString('hex')}]`;
|
|
210
|
+
}
|
|
211
|
+
case 'string': {
|
|
212
|
+
const text = strings.get(value.id);
|
|
213
|
+
return `[String ${text === undefined ? `?${value.id}` : JSON.stringify(text)}]`;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Decodes the literals an instruction refers to, for one side of a compare.
|
|
219
|
+
* Returns rendered entries, or null when the offset cannot be decoded.
|
|
220
|
+
*/
|
|
221
|
+
class LiteralResolver {
|
|
222
|
+
buffers;
|
|
223
|
+
strings;
|
|
224
|
+
constructor(buffers, strings) {
|
|
225
|
+
this.buffers = buffers;
|
|
226
|
+
this.strings = strings;
|
|
227
|
+
}
|
|
228
|
+
decode(buffer, offset, count) {
|
|
229
|
+
const values = decodeSerializedLiterals(buffer, offset, count, this.buffers.layout);
|
|
230
|
+
return values ? values.map((v) => renderLiteral(v, this.strings)) : null;
|
|
231
|
+
}
|
|
232
|
+
get layout() {
|
|
233
|
+
return this.buffers.layout;
|
|
234
|
+
}
|
|
235
|
+
array(offset, count) {
|
|
236
|
+
const b = this.buffers;
|
|
237
|
+
return this.decode(b.layout === 'split' ? b.array : b.values, offset, count);
|
|
238
|
+
}
|
|
239
|
+
objectKeys(offset, count) {
|
|
240
|
+
return this.decode(this.buffers.objectKeys, offset, count);
|
|
241
|
+
}
|
|
242
|
+
objectValues(offset, count) {
|
|
243
|
+
const b = this.buffers;
|
|
244
|
+
return this.decode(b.layout === 'split' ? b.objectValues : b.values, offset, count);
|
|
245
|
+
}
|
|
246
|
+
/** Shape table entry (HBC v98); null out of range or in the split layout. */
|
|
247
|
+
shape(index) {
|
|
248
|
+
const b = this.buffers;
|
|
249
|
+
if (b.layout !== 'shaped' || index < 0)
|
|
250
|
+
return null;
|
|
251
|
+
const at = index * SHAPE_ENTRY_SIZE;
|
|
252
|
+
if (at + SHAPE_ENTRY_SIZE > b.shapes.length)
|
|
253
|
+
return null;
|
|
254
|
+
return {
|
|
255
|
+
keyOffset: b.shapes.readUInt32LE(at),
|
|
256
|
+
count: b.shapes.readUInt32LE(at + 4),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
exports.LiteralResolver = LiteralResolver;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function promiseAny<T>(promises: Promise<T>[]): Promise<T>;
|
|
2
|
+
export declare const ping: (url: string, signal?: AbortSignal) => Promise<string | null>;
|
|
3
|
+
export declare const testUrls: (urls?: string[], hedgeDelayMs?: number) => Promise<string | null>;
|
|
4
|
+
export declare const isStandaloneService: () => boolean;
|
|
5
|
+
/**
|
|
6
|
+
* The API base url: the env override, or the first default endpoint that
|
|
7
|
+
* answers a HEAD ping. Resolved lazily on the first API call (offline commands
|
|
8
|
+
* such as `hdiff`/`help` never ping) and memoized for the process lifetime.
|
|
9
|
+
*/
|
|
10
|
+
export declare const getBaseUrl: () => Promise<string>;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBaseUrl = exports.isStandaloneService = exports.testUrls = exports.ping = void 0;
|
|
4
|
+
exports.promiseAny = promiseAny;
|
|
5
|
+
/**
|
|
6
|
+
* [INPUT]: 依赖默认服务端点、RNU_SERVICE_URL 与运行时网络请求
|
|
7
|
+
* [OUTPUT]: 对外提供服务地址解析、独立服务判定、健康探测和并发竞速
|
|
8
|
+
* [POS]: CLI 网络寻址层,独立模式拒绝隐式回退到上游服务
|
|
9
|
+
*/
|
|
10
|
+
const constants_1 = require("./constants");
|
|
11
|
+
const runtime_1 = require("./runtime");
|
|
12
|
+
// const baseUrl = `http://localhost:9000`;
|
|
13
|
+
// let baseUrl = SERVER.main[0];
|
|
14
|
+
// const baseUrl = `https://p.reactnative.cn/api`;
|
|
15
|
+
function promiseAny(promises) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
let count = 0;
|
|
18
|
+
for (const promise of promises) {
|
|
19
|
+
Promise.resolve(promise)
|
|
20
|
+
.then(resolve)
|
|
21
|
+
.catch(() => {
|
|
22
|
+
count++;
|
|
23
|
+
if (count === promises.length) {
|
|
24
|
+
reject(new Error('All promises were rejected'));
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const ping = async (url, signal) => {
|
|
31
|
+
let timer;
|
|
32
|
+
try {
|
|
33
|
+
return await Promise.race([
|
|
34
|
+
(0, runtime_1.runtimeFetch)(url, {
|
|
35
|
+
method: 'HEAD',
|
|
36
|
+
signal,
|
|
37
|
+
}).then(({ status }) => {
|
|
38
|
+
if (status === 200) {
|
|
39
|
+
return url;
|
|
40
|
+
}
|
|
41
|
+
throw new Error('ping failed');
|
|
42
|
+
}),
|
|
43
|
+
new Promise((_, reject) => {
|
|
44
|
+
timer = setTimeout(() => {
|
|
45
|
+
reject(new Error('ping timeout'));
|
|
46
|
+
}, 5000);
|
|
47
|
+
}),
|
|
48
|
+
]);
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
// clear the timer so it doesn't keep the process alive for 5s
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
exports.ping = ping;
|
|
56
|
+
const HEDGE_DELAY_MS = 250;
|
|
57
|
+
// Hedged race instead of pinging every endpoint at once: the preferred (first)
|
|
58
|
+
// url is tried immediately, each following one only after HEDGE_DELAY_MS of
|
|
59
|
+
// silence (or immediately when a previous ping failed). The first success wins
|
|
60
|
+
// and the losing pings are aborted. Falls back to urls[0] when all fail.
|
|
61
|
+
const testUrls = async (urls, hedgeDelayMs = HEDGE_DELAY_MS) => {
|
|
62
|
+
if (!urls?.length) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return new Promise((resolve) => {
|
|
66
|
+
const controllers = [];
|
|
67
|
+
let nextIndex = 0;
|
|
68
|
+
let pending = 0;
|
|
69
|
+
let settled = false;
|
|
70
|
+
let hedgeTimer;
|
|
71
|
+
const finish = (winner, winnerController) => {
|
|
72
|
+
if (settled) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
settled = true;
|
|
76
|
+
if (hedgeTimer) {
|
|
77
|
+
clearTimeout(hedgeTimer);
|
|
78
|
+
}
|
|
79
|
+
for (const controller of controllers) {
|
|
80
|
+
if (controller !== winnerController) {
|
|
81
|
+
controller.abort();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
resolve(winner ?? urls[0]);
|
|
85
|
+
};
|
|
86
|
+
const launchNext = () => {
|
|
87
|
+
if (hedgeTimer) {
|
|
88
|
+
clearTimeout(hedgeTimer);
|
|
89
|
+
hedgeTimer = undefined;
|
|
90
|
+
}
|
|
91
|
+
if (settled || nextIndex >= urls.length) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const url = urls[nextIndex++];
|
|
95
|
+
const controller = new AbortController();
|
|
96
|
+
controllers.push(controller);
|
|
97
|
+
pending++;
|
|
98
|
+
(0, exports.ping)(url, controller.signal).then(() => finish(url, controller), () => {
|
|
99
|
+
pending--;
|
|
100
|
+
if (settled) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (nextIndex < urls.length) {
|
|
104
|
+
// A failure frees its slot: hedge the next url right away.
|
|
105
|
+
launchNext();
|
|
106
|
+
}
|
|
107
|
+
else if (pending === 0) {
|
|
108
|
+
finish(null);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
if (!settled && nextIndex < urls.length) {
|
|
112
|
+
hedgeTimer = setTimeout(launchNext, hedgeDelayMs);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
launchNext();
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
exports.testUrls = testUrls;
|
|
119
|
+
let baseUrlPromise;
|
|
120
|
+
const isStandaloneService = () => Boolean(process.env.RNU_SERVICE_URL || process.env.RNU_API_MODE === 'standalone');
|
|
121
|
+
exports.isStandaloneService = isStandaloneService;
|
|
122
|
+
async function resolveBaseUrl() {
|
|
123
|
+
const testEndpoint = process.env.RNU_SERVICE_URL || process.env.PAKTA_REGISTRY || process.env.RNU_API;
|
|
124
|
+
if (testEndpoint) {
|
|
125
|
+
return testEndpoint.replace(/\/+$/, '');
|
|
126
|
+
}
|
|
127
|
+
if ((0, exports.isStandaloneService)()) {
|
|
128
|
+
throw new Error('独立服务必须显式配置 RNU_SERVICE_URL;CLI 不会连接上游默认地址。');
|
|
129
|
+
}
|
|
130
|
+
const ret = await (0, exports.testUrls)(constants_1.defaultEndpoints.map((url) => `${url}/status`));
|
|
131
|
+
let baseUrl = constants_1.defaultEndpoints[0];
|
|
132
|
+
if (ret) {
|
|
133
|
+
// remove /status
|
|
134
|
+
baseUrl = ret.replace('/status', '');
|
|
135
|
+
}
|
|
136
|
+
// console.log('baseUrl', baseUrl);
|
|
137
|
+
return baseUrl;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The API base url: the env override, or the first default endpoint that
|
|
141
|
+
* answers a HEAD ping. Resolved lazily on the first API call (offline commands
|
|
142
|
+
* such as `hdiff`/`help` never ping) and memoized for the process lifetime.
|
|
143
|
+
*/
|
|
144
|
+
const getBaseUrl = () => {
|
|
145
|
+
if (!baseUrlPromise) {
|
|
146
|
+
baseUrlPromise = resolveBaseUrl();
|
|
147
|
+
}
|
|
148
|
+
return baseUrlPromise;
|
|
149
|
+
};
|
|
150
|
+
exports.getBaseUrl = getBaseUrl;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [INPUT]: 依赖 i18next、CLI en/zh 文案资源与 RNU_LANG 环境覆盖
|
|
3
|
+
* [OUTPUT]: 对外提供 resolveLanguage 与 t,初始化 Pakta CLI 本地化资源
|
|
4
|
+
* [POS]: CLI 文案适配层,统一语言选择和模板翻译,不包含命令业务逻辑
|
|
5
|
+
*/
|
|
6
|
+
import en from '../locales/en';
|
|
7
|
+
import zh from '../locales/zh';
|
|
8
|
+
/**
|
|
9
|
+
* UI language: `RNU_LANG=en|zh` (a locale such as `zh_CN` counts by its
|
|
10
|
+
* prefix) overrides the Pakta default.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveLanguage(env?: NodeJS.ProcessEnv, defaultLanguage?: 'en' | 'zh'): 'en' | 'zh';
|
|
13
|
+
declare module 'i18next' {
|
|
14
|
+
interface CustomTypeOptions {
|
|
15
|
+
defaultNS: 'en';
|
|
16
|
+
resources: {
|
|
17
|
+
en: typeof en;
|
|
18
|
+
zh: typeof zh;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export declare function t(key: string, options?: any): string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* [INPUT]: 依赖 i18next、CLI en/zh 文案资源与 RNU_LANG 环境覆盖
|
|
4
|
+
* [OUTPUT]: 对外提供 resolveLanguage 与 t,初始化 Pakta CLI 本地化资源
|
|
5
|
+
* [POS]: CLI 文案适配层,统一语言选择和模板翻译,不包含命令业务逻辑
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.resolveLanguage = resolveLanguage;
|
|
12
|
+
exports.t = t;
|
|
13
|
+
const i18next_1 = __importDefault(require("i18next"));
|
|
14
|
+
const en_1 = __importDefault(require("../locales/en"));
|
|
15
|
+
const zh_1 = __importDefault(require("../locales/zh"));
|
|
16
|
+
/**
|
|
17
|
+
* UI language: `RNU_LANG=en|zh` (a locale such as `zh_CN` counts by its
|
|
18
|
+
* prefix) overrides the Pakta default.
|
|
19
|
+
*/
|
|
20
|
+
function resolveLanguage(env = process.env, defaultLanguage = 'zh') {
|
|
21
|
+
const override = env.RNU_LANG?.trim().toLowerCase();
|
|
22
|
+
if (override?.startsWith('zh'))
|
|
23
|
+
return 'zh';
|
|
24
|
+
if (override?.startsWith('en'))
|
|
25
|
+
return 'en';
|
|
26
|
+
return defaultLanguage;
|
|
27
|
+
}
|
|
28
|
+
i18next_1.default.init({
|
|
29
|
+
lng: resolveLanguage(),
|
|
30
|
+
// debug: process.env.NODE_ENV !== 'production',
|
|
31
|
+
// debug: true,
|
|
32
|
+
resources: {
|
|
33
|
+
en: {
|
|
34
|
+
translation: en_1.default,
|
|
35
|
+
},
|
|
36
|
+
zh: {
|
|
37
|
+
translation: zh_1.default,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
interpolation: {
|
|
41
|
+
escapeValue: false,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
function t(key, options) {
|
|
45
|
+
return i18next_1.default.t(key, options);
|
|
46
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { checkPlugins } from './check-plugin';
|
|
2
|
+
/**
|
|
3
|
+
* tty-table (~25 ms to load) only when a table is rendered. Bun's require of
|
|
4
|
+
* a CJS module can hand back a namespace object, so unwrap `default`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadTtyTable(): typeof import('tty-table');
|
|
7
|
+
/** True when prompts cannot or must not be shown. */
|
|
8
|
+
export declare function isNonInteractive(env?: NodeJS.ProcessEnv, stdinIsTTY?: boolean | undefined, globalFlag?: boolean | undefined): boolean;
|
|
9
|
+
export declare function question(query: string, password?: boolean): Promise<string>;
|
|
10
|
+
export declare function translateOptions<T extends Record<string, unknown>>(options: T, map?: Record<string, string>): T & Record<string, unknown>;
|
|
11
|
+
export declare const ApkBundleFileName: RegExp;
|
|
12
|
+
export declare function getApkInfo(fn: string): Promise<{
|
|
13
|
+
versionName: string;
|
|
14
|
+
buildTime: string;
|
|
15
|
+
bundleHash: string;
|
|
16
|
+
bundleFile: Blob | Buffer<ArrayBufferLike>;
|
|
17
|
+
channel: string;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function getAppInfo(fn: string): Promise<{
|
|
20
|
+
versionName: string | undefined;
|
|
21
|
+
buildTime: string;
|
|
22
|
+
bundleHash: string;
|
|
23
|
+
bundleFile: Buffer<ArrayBufferLike>;
|
|
24
|
+
channel: string;
|
|
25
|
+
}>;
|
|
26
|
+
export declare const IpaBundleFileName: RegExp;
|
|
27
|
+
export declare function getIpaInfo(fn: string): Promise<{
|
|
28
|
+
versionName: string;
|
|
29
|
+
buildTime: string;
|
|
30
|
+
bundleHash: string;
|
|
31
|
+
bundleFile: Blob | Buffer<ArrayBufferLike>;
|
|
32
|
+
channel: string;
|
|
33
|
+
}>;
|
|
34
|
+
export declare function getAabInfo(fn: string): Promise<{
|
|
35
|
+
versionName: string;
|
|
36
|
+
buildTime: string;
|
|
37
|
+
bundleHash?: string | undefined;
|
|
38
|
+
channel: string;
|
|
39
|
+
}>;
|
|
40
|
+
export interface VersionCheck {
|
|
41
|
+
/** settles once the registry check has finished (or failed); never rejects */
|
|
42
|
+
done: Promise<void>;
|
|
43
|
+
/** wait for the check, but never longer than `graceMs` */
|
|
44
|
+
settle: (graceMs: number) => Promise<void>;
|
|
45
|
+
/** launch a detached self-update after the foreground command is done */
|
|
46
|
+
startAutoUpdate: () => void;
|
|
47
|
+
/**
|
|
48
|
+
* Print the "newer version available" hints if the check has completed by
|
|
49
|
+
* now; a no-op while it is still pending, when nothing is newer, and after
|
|
50
|
+
* the first call. Safe to call from a process 'exit' handler.
|
|
51
|
+
*/
|
|
52
|
+
printHints: () => void;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Print the installed CLI / rn-update versions (and refuse or warn
|
|
56
|
+
* about unsupported client versions) immediately, without touching the
|
|
57
|
+
* network.
|
|
58
|
+
*
|
|
59
|
+
* With `wait: true` (the `-v`/`version` command) the registry is queried
|
|
60
|
+
* first and the latest versions are printed inline. Otherwise the registry
|
|
61
|
+
* check runs in the background and the returned `printHints` shows what is
|
|
62
|
+
* newer once the command is done — the command itself is never delayed by it.
|
|
63
|
+
*/
|
|
64
|
+
export declare function printVersionCommand({ wait, }?: {
|
|
65
|
+
wait?: boolean;
|
|
66
|
+
}): Promise<VersionCheck>;
|
|
67
|
+
export { checkPlugins };
|