@oniroproject/core 0.14.0 → 0.15.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/README.md +1 -0
- package/dist/index.cjs +388 -160
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +98 -13
- package/dist/index.d.ts +98 -13
- package/dist/index.js +380 -160
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -42,6 +42,7 @@ __export(index_exports, {
|
|
|
42
42
|
HUAWEI_SITES: () => HUAWEI_SITES,
|
|
43
43
|
INSTALL_TMP_DIRNAME: () => INSTALL_TMP_DIRNAME,
|
|
44
44
|
InsufficientSpaceError: () => InsufficientSpaceError,
|
|
45
|
+
OHOS_DAILY_BUILDS_URL: () => OHOS_DAILY_BUILDS_URL,
|
|
45
46
|
OHOS_URL_BASE: () => OHOS_URL_BASE,
|
|
46
47
|
OniroError: () => OniroError,
|
|
47
48
|
SIGNING_ERRORS: () => SIGNING_ERRORS,
|
|
@@ -62,6 +63,7 @@ __export(index_exports, {
|
|
|
62
63
|
buildHvigorwArgs: () => buildHvigorwArgs,
|
|
63
64
|
buildInputCommand: () => buildInputCommand,
|
|
64
65
|
buildRawTouchCommand: () => buildRawTouchCommand,
|
|
66
|
+
bundleNameFromHapConfig: () => bundleNameFromHapConfig,
|
|
65
67
|
captureBurst: () => captureBurst,
|
|
66
68
|
captureLog: () => captureLog,
|
|
67
69
|
cleanCodelinterOutput: () => cleanCodelinterOutput,
|
|
@@ -115,6 +117,7 @@ __export(index_exports, {
|
|
|
115
117
|
findLayoutNodes: () => findLayoutNodes,
|
|
116
118
|
findMissingProjectSdk: () => findMissingProjectSdk,
|
|
117
119
|
findRunningProcess: () => findRunningProcess,
|
|
120
|
+
findSdkOsDir: () => findSdkOsDir,
|
|
118
121
|
flattenLayout: () => flattenLayout,
|
|
119
122
|
forceStop: () => forceStop,
|
|
120
123
|
formatBytes: () => formatBytes,
|
|
@@ -148,10 +151,12 @@ __export(index_exports, {
|
|
|
148
151
|
hdcTargetArgs: () => hdcTargetArgs,
|
|
149
152
|
hdcTargetArgsFor: () => hdcTargetArgsFor,
|
|
150
153
|
hideKeyboard: () => hideKeyboard,
|
|
154
|
+
hilogTimeMs: () => hilogTimeMs,
|
|
151
155
|
installApp: () => installApp,
|
|
152
156
|
installCmdTools: () => installCmdTools,
|
|
153
157
|
installEmulator: () => installEmulator,
|
|
154
158
|
installFailureReason: () => installFailureReason,
|
|
159
|
+
installSdkFromArchive: () => installSdkFromArchive,
|
|
155
160
|
isBundleInstalled: () => isBundleInstalled,
|
|
156
161
|
isCmdToolsInstalled: () => isCmdToolsInstalled,
|
|
157
162
|
isEmulatorInstalled: () => isEmulatorInstalled,
|
|
@@ -168,6 +173,7 @@ __export(index_exports, {
|
|
|
168
173
|
listRunningProcesses: () => listRunningProcesses,
|
|
169
174
|
listTemplates: () => listTemplates,
|
|
170
175
|
locateTarget: () => locateTarget,
|
|
176
|
+
missingProjectRootFiles: () => missingProjectRootFiles,
|
|
171
177
|
needsCmdWrapper: () => needsCmdWrapper,
|
|
172
178
|
nonInteractivePrompter: () => nonInteractivePrompter,
|
|
173
179
|
noopLogger: () => noopLogger,
|
|
@@ -191,9 +197,11 @@ __export(index_exports, {
|
|
|
191
197
|
pickTarget: () => pickTarget,
|
|
192
198
|
prepareSigning: () => prepareSigning,
|
|
193
199
|
pruneLayout: () => pruneLayout,
|
|
200
|
+
readHapBundleName: () => readHapBundleName,
|
|
194
201
|
readJson5File: () => readJson5File,
|
|
195
202
|
readJsonFile: () => readJsonFile,
|
|
196
203
|
readProvisionProfile: () => readProvisionProfile,
|
|
204
|
+
readZipEntry: () => readZipEntry,
|
|
197
205
|
reboot: () => reboot,
|
|
198
206
|
recvFile: () => recvFile,
|
|
199
207
|
removeCmdTools: () => removeCmdTools,
|
|
@@ -424,6 +432,7 @@ var ALL_SDKS = [
|
|
|
424
432
|
{ version: "7.0", api: "26", tarballStrip: { linuxWindows: 1, darwin: 3 }, archiveSuffix: "_20260829" }
|
|
425
433
|
];
|
|
426
434
|
var OHOS_URL_BASE = "https://repo.huaweicloud.com/openharmony/os";
|
|
435
|
+
var OHOS_DAILY_BUILDS_URL = "https://dcp.openharmony.cn/workbench/cicd/dailybuild/dailylist";
|
|
427
436
|
|
|
428
437
|
// src/sdk/platform.ts
|
|
429
438
|
var os2 = __toESM(require("os"), 1);
|
|
@@ -1006,8 +1015,17 @@ async function extractZipWithProgress(opts) {
|
|
|
1006
1015
|
if (inc > 0) progress.report({ message: "Extracting: 100%", increment: inc });
|
|
1007
1016
|
}
|
|
1008
1017
|
}
|
|
1009
|
-
async function extractTarball(tarPath, dest, strip = 0) {
|
|
1010
|
-
await tar.x({ file: tarPath, cwd: dest, strip });
|
|
1018
|
+
async function extractTarball(tarPath, dest, strip = 0, filter) {
|
|
1019
|
+
await tar.x({ file: tarPath, cwd: dest, strip, ...filter ? { filter: (p) => filter(p) } : {} });
|
|
1020
|
+
}
|
|
1021
|
+
async function readZipEntry(zipPath, match) {
|
|
1022
|
+
const zip = new import_node_stream_zip.default.async({ file: zipPath });
|
|
1023
|
+
try {
|
|
1024
|
+
const entry = Object.values(await zip.entries()).find((e) => !e.isDirectory && match(e.name));
|
|
1025
|
+
return entry ? await zip.entryData(entry) : void 0;
|
|
1026
|
+
} finally {
|
|
1027
|
+
await zip.close();
|
|
1028
|
+
}
|
|
1011
1029
|
}
|
|
1012
1030
|
|
|
1013
1031
|
// src/sdk/list.ts
|
|
@@ -1113,34 +1131,7 @@ async function downloadAndInstallSdk(opts) {
|
|
|
1113
1131
|
`Expected folder '${osFolder}' not found in extracted SDK. Tarball layout may have changed.`
|
|
1114
1132
|
);
|
|
1115
1133
|
}
|
|
1116
|
-
|
|
1117
|
-
const componentsStart = 60;
|
|
1118
|
-
const componentsBudget = 35;
|
|
1119
|
-
const n = zipFiles.length;
|
|
1120
|
-
if (n === 0) {
|
|
1121
|
-
progress?.report({ message: "No SDK component ZIPs found.", increment: componentsBudget });
|
|
1122
|
-
} else {
|
|
1123
|
-
progress?.report({ message: "Extracting SDK components...", increment: 0 });
|
|
1124
|
-
}
|
|
1125
|
-
const base = n > 0 ? Math.floor(componentsBudget / n) : 0;
|
|
1126
|
-
let rem = n > 0 ? componentsBudget % n : 0;
|
|
1127
|
-
let cursor = componentsStart;
|
|
1128
|
-
for (const zipFile of zipFiles) {
|
|
1129
|
-
checkCancelled();
|
|
1130
|
-
logger.info(`Extracting component ${zipFile}`);
|
|
1131
|
-
const zipPath = path10.join(osContentPath, zipFile);
|
|
1132
|
-
const thisBudget = base + (rem > 0 ? 1 : 0);
|
|
1133
|
-
if (rem > 0) rem--;
|
|
1134
|
-
await extractZipWithProgress({ zipPath, dest: osContentPath, progress, start: cursor, range: thisBudget, logger });
|
|
1135
|
-
cursor += thisBudget;
|
|
1136
|
-
fs10.unlinkSync(zipPath);
|
|
1137
|
-
}
|
|
1138
|
-
progress?.report({ message: "Finalizing installation...", increment: 0 });
|
|
1139
|
-
if (fs10.existsSync(sdkInstallDir)) {
|
|
1140
|
-
fs10.rmSync(sdkInstallDir, { recursive: true, force: true });
|
|
1141
|
-
}
|
|
1142
|
-
movePath(osContentPath, sdkInstallDir);
|
|
1143
|
-
progress?.report({ message: "Finalizing installation...", increment: 3 });
|
|
1134
|
+
await installComponents({ osContentPath, sdkInstallDir, progress, logger, start: 60, range: 35, checkCancelled });
|
|
1144
1135
|
progress?.report({ message: "Cleaning up...", increment: 0 });
|
|
1145
1136
|
removeTempWorkDir(tmpDir, tmpRoot);
|
|
1146
1137
|
progress?.report({ message: "Cleaning up...", increment: 2 });
|
|
@@ -1151,6 +1142,115 @@ async function downloadAndInstallSdk(opts) {
|
|
|
1151
1142
|
throw wrapped;
|
|
1152
1143
|
}
|
|
1153
1144
|
}
|
|
1145
|
+
async function installComponents(opts) {
|
|
1146
|
+
const { osContentPath, sdkInstallDir, progress, logger, checkCancelled } = opts;
|
|
1147
|
+
const zipFiles = fs10.readdirSync(osContentPath).filter((n2) => n2.endsWith(".zip"));
|
|
1148
|
+
const n = zipFiles.length;
|
|
1149
|
+
if (n === 0) {
|
|
1150
|
+
progress?.report({ message: "No SDK component ZIPs found.", increment: opts.range });
|
|
1151
|
+
} else {
|
|
1152
|
+
progress?.report({ message: "Extracting SDK components...", increment: 0 });
|
|
1153
|
+
}
|
|
1154
|
+
const base = n > 0 ? Math.floor(opts.range / n) : 0;
|
|
1155
|
+
let rem = n > 0 ? opts.range % n : 0;
|
|
1156
|
+
let cursor = opts.start;
|
|
1157
|
+
for (const zipFile of zipFiles) {
|
|
1158
|
+
checkCancelled();
|
|
1159
|
+
logger.info(`Extracting component ${zipFile}`);
|
|
1160
|
+
const zipPath = path10.join(osContentPath, zipFile);
|
|
1161
|
+
const thisBudget = base + (rem > 0 ? 1 : 0);
|
|
1162
|
+
if (rem > 0) rem--;
|
|
1163
|
+
await extractZipWithProgress({ zipPath, dest: osContentPath, progress, start: cursor, range: thisBudget, logger });
|
|
1164
|
+
cursor += thisBudget;
|
|
1165
|
+
fs10.unlinkSync(zipPath);
|
|
1166
|
+
}
|
|
1167
|
+
progress?.report({ message: "Finalizing installation...", increment: 0 });
|
|
1168
|
+
if (fs10.existsSync(sdkInstallDir)) {
|
|
1169
|
+
fs10.rmSync(sdkInstallDir, { recursive: true, force: true });
|
|
1170
|
+
}
|
|
1171
|
+
movePath(osContentPath, sdkInstallDir);
|
|
1172
|
+
progress?.report({ message: "Finalizing installation...", increment: 3 });
|
|
1173
|
+
}
|
|
1174
|
+
async function installSdkFromArchive(opts) {
|
|
1175
|
+
const { config, archivePath, progress, abortSignal } = opts;
|
|
1176
|
+
const logger = opts.logger ?? noopLogger;
|
|
1177
|
+
if (!fs10.statSync(archivePath, { throwIfNoEntry: false })?.isFile()) {
|
|
1178
|
+
throw new OniroError(`SDK archive not found: ${archivePath}`);
|
|
1179
|
+
}
|
|
1180
|
+
const osFolder = getOsFolder();
|
|
1181
|
+
const what = `the SDK install from '${path10.basename(archivePath)}'`;
|
|
1182
|
+
const sdkRoot = getSdkRootDir(config);
|
|
1183
|
+
const { dir: tmpDir, root: tmpRoot } = createInstallTempDir({
|
|
1184
|
+
config,
|
|
1185
|
+
override: opts.tmpDir,
|
|
1186
|
+
installRoot: sdkRoot,
|
|
1187
|
+
prefix: "oniro-sdk-",
|
|
1188
|
+
logger
|
|
1189
|
+
});
|
|
1190
|
+
const extractDir = path10.join(tmpDir, "extract");
|
|
1191
|
+
fs10.mkdirSync(extractDir);
|
|
1192
|
+
const checkCancelled = () => {
|
|
1193
|
+
if (abortSignal?.aborted) throw new CancelledError();
|
|
1194
|
+
};
|
|
1195
|
+
try {
|
|
1196
|
+
progress?.report({ message: "Extracting SDK archive (this may take a while)...", increment: 0 });
|
|
1197
|
+
await extractTarball(archivePath, extractDir, 0, (p) => p.split("/").includes(osFolder));
|
|
1198
|
+
progress?.report({ message: "Extracting SDK archive (this may take a while)...", increment: 40 });
|
|
1199
|
+
checkCancelled();
|
|
1200
|
+
const osContentPath = findSdkOsDir(extractDir, osFolder);
|
|
1201
|
+
if (!osContentPath) {
|
|
1202
|
+
throw new OniroError(
|
|
1203
|
+
`No '${osFolder}' SDK components (a '${osFolder}' folder of ZIPs) found in ${archivePath}. Is it an OpenHarmony SDK archive for this OS?`
|
|
1204
|
+
);
|
|
1205
|
+
}
|
|
1206
|
+
const { api, version } = await readSdkComponentsMeta(osContentPath);
|
|
1207
|
+
const sdkInstallDir = path10.join(sdkRoot, osFolder, api);
|
|
1208
|
+
if (fs10.existsSync(sdkInstallDir) && !opts.force) {
|
|
1209
|
+
throw new OniroError(
|
|
1210
|
+
`An SDK for api ${api} is already installed at ${sdkInstallDir}; pass --force to replace it with this archive, or set ONIRO_SDK_ROOT_DIR to install it in a separate SDK root.`
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
fs10.mkdirSync(path10.dirname(sdkInstallDir), { recursive: true });
|
|
1214
|
+
await installComponents({ osContentPath, sdkInstallDir, progress, logger, start: 40, range: 55, checkCancelled });
|
|
1215
|
+
progress?.report({ message: "Cleaning up...", increment: 0 });
|
|
1216
|
+
removeTempWorkDir(tmpDir, tmpRoot);
|
|
1217
|
+
progress?.report({ message: "Cleaning up...", increment: 2 });
|
|
1218
|
+
return { api, version, dir: sdkInstallDir };
|
|
1219
|
+
} catch (err) {
|
|
1220
|
+
removeTempWorkDir(tmpDir, tmpRoot);
|
|
1221
|
+
throw toSpaceError(err, tmpRoot, what);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
function findSdkOsDir(root, osFolder, maxDepth = 4) {
|
|
1225
|
+
let level = [root];
|
|
1226
|
+
for (let depth = 0; depth < maxDepth && level.length > 0; depth++) {
|
|
1227
|
+
const next = [];
|
|
1228
|
+
for (const dir of level) {
|
|
1229
|
+
for (const entry of fs10.readdirSync(dir, { withFileTypes: true })) {
|
|
1230
|
+
if (!entry.isDirectory()) continue;
|
|
1231
|
+
const p = path10.join(dir, entry.name);
|
|
1232
|
+
if (entry.name === osFolder && fs10.readdirSync(p).some((n) => n.endsWith(".zip"))) return p;
|
|
1233
|
+
next.push(p);
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
level = next;
|
|
1237
|
+
}
|
|
1238
|
+
return void 0;
|
|
1239
|
+
}
|
|
1240
|
+
async function readSdkComponentsMeta(dir) {
|
|
1241
|
+
const zips = fs10.readdirSync(dir).filter((n) => n.endsWith(".zip")).sort((a, b) => Number(b.startsWith("ets-")) - Number(a.startsWith("ets-")));
|
|
1242
|
+
for (const name of zips) {
|
|
1243
|
+
const data = await readZipEntry(path10.join(dir, name), (e) => /^[^/]+\/oh-uni-package\.json$/.test(e));
|
|
1244
|
+
if (!data) continue;
|
|
1245
|
+
try {
|
|
1246
|
+
const pkg = JSON.parse(data.toString("utf8"));
|
|
1247
|
+
const api = String(pkg.apiVersion ?? "");
|
|
1248
|
+
if (/^\d+$/.test(api)) return { api, version: String(pkg.version ?? "") };
|
|
1249
|
+
} catch {
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
throw new OniroError("No SDK component in the archive declares a numeric apiVersion (oh-uni-package.json).");
|
|
1253
|
+
}
|
|
1154
1254
|
|
|
1155
1255
|
// src/cmdTools/install.ts
|
|
1156
1256
|
var fs11 = __toESM(require("fs"), 1);
|
|
@@ -1849,6 +1949,7 @@ var import_node_child_process4 = require("child_process");
|
|
|
1849
1949
|
|
|
1850
1950
|
// src/hdc/exec.ts
|
|
1851
1951
|
var fs15 = __toESM(require("fs"), 1);
|
|
1952
|
+
var import_node_string_decoder = require("string_decoder");
|
|
1852
1953
|
function errorMessage(err) {
|
|
1853
1954
|
return err instanceof Error ? err.message : String(err);
|
|
1854
1955
|
}
|
|
@@ -1876,6 +1977,8 @@ function runProcess(opts) {
|
|
|
1876
1977
|
let stderr = "";
|
|
1877
1978
|
let settled = false;
|
|
1878
1979
|
let timedOut = false;
|
|
1980
|
+
const stdoutDecoder = new import_node_string_decoder.StringDecoder("utf8");
|
|
1981
|
+
const stderrDecoder = new import_node_string_decoder.StringDecoder("utf8");
|
|
1879
1982
|
const cleanup = () => {
|
|
1880
1983
|
clearTimeout(timer);
|
|
1881
1984
|
abortSignal?.removeEventListener("abort", onAbort);
|
|
@@ -1893,14 +1996,14 @@ function runProcess(opts) {
|
|
|
1893
1996
|
}, timeoutMs);
|
|
1894
1997
|
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
1895
1998
|
child.stdout?.on("data", (d) => {
|
|
1896
|
-
const s =
|
|
1999
|
+
const s = stdoutDecoder.write(d);
|
|
1897
2000
|
stdout += s;
|
|
1898
|
-
onOutput?.(s, "stdout");
|
|
2001
|
+
if (s) onOutput?.(s, "stdout");
|
|
1899
2002
|
});
|
|
1900
2003
|
child.stderr?.on("data", (d) => {
|
|
1901
|
-
const s =
|
|
2004
|
+
const s = stderrDecoder.write(d);
|
|
1902
2005
|
stderr += s;
|
|
1903
|
-
onOutput?.(s, "stderr");
|
|
2006
|
+
if (s) onOutput?.(s, "stderr");
|
|
1904
2007
|
});
|
|
1905
2008
|
child.on("error", (err) => {
|
|
1906
2009
|
if (settled) return;
|
|
@@ -1912,6 +2015,12 @@ function runProcess(opts) {
|
|
|
1912
2015
|
if (settled) return;
|
|
1913
2016
|
settled = true;
|
|
1914
2017
|
cleanup();
|
|
2018
|
+
const stdoutTail = stdoutDecoder.end();
|
|
2019
|
+
const stderrTail = stderrDecoder.end();
|
|
2020
|
+
stdout += stdoutTail;
|
|
2021
|
+
stderr += stderrTail;
|
|
2022
|
+
if (stdoutTail) onOutput?.(stdoutTail, "stdout");
|
|
2023
|
+
if (stderrTail) onOutput?.(stderrTail, "stderr");
|
|
1915
2024
|
if (timedOut) {
|
|
1916
2025
|
reject(
|
|
1917
2026
|
new OniroError(
|
|
@@ -2199,6 +2308,7 @@ async function getEmulatorStatus(config, opts = {}) {
|
|
|
2199
2308
|
// src/hdc/devices.ts
|
|
2200
2309
|
var STATUS_TOKENS = /* @__PURE__ */ new Set([
|
|
2201
2310
|
"Connected",
|
|
2311
|
+
"Ready",
|
|
2202
2312
|
"Offline",
|
|
2203
2313
|
"Unauthorized",
|
|
2204
2314
|
"Authorizing",
|
|
@@ -2428,9 +2538,13 @@ function moduleOfHap(hapFileName) {
|
|
|
2428
2538
|
const dash = hapFileName.indexOf("-");
|
|
2429
2539
|
return dash > 0 ? hapFileName.slice(0, dash) : hapFileName.replace(/\.hap$/i, "");
|
|
2430
2540
|
}
|
|
2541
|
+
function isAppProjectRoot(dir) {
|
|
2542
|
+
return fs17.existsSync(path18.join(dir, "AppScope", "app.json5"));
|
|
2543
|
+
}
|
|
2431
2544
|
async function discoverHaps(opts) {
|
|
2432
2545
|
const { projectDir } = opts;
|
|
2433
2546
|
const maxDepth = opts.maxDepth ?? 8;
|
|
2547
|
+
const skipNestedProjects = isAppProjectRoot(projectDir);
|
|
2434
2548
|
const result = {};
|
|
2435
2549
|
const walk = async (dir, depth) => {
|
|
2436
2550
|
if (depth > maxDepth) return;
|
|
@@ -2439,6 +2553,7 @@ async function discoverHaps(opts) {
|
|
|
2439
2553
|
const full = path18.join(dir, e.name);
|
|
2440
2554
|
if (e.isDirectory()) {
|
|
2441
2555
|
if (e.name === "node_modules" || e.name === "oh_modules" || e.name === ".git") continue;
|
|
2556
|
+
if (skipNestedProjects && isAppProjectRoot(full)) continue;
|
|
2442
2557
|
await walk(full, depth + 1);
|
|
2443
2558
|
} else if (e.isFile() && e.name.endsWith(".hap")) {
|
|
2444
2559
|
const moduleName = moduleOfHap(e.name);
|
|
@@ -3630,6 +3745,54 @@ async function resolveProcessId(config, bundle, deviceSerial) {
|
|
|
3630
3745
|
const proc = await findRunningProcess({ config, bundle, deviceSerial });
|
|
3631
3746
|
return proc?.pid;
|
|
3632
3747
|
}
|
|
3748
|
+
async function readDeviceClock(config, deviceSerial) {
|
|
3749
|
+
try {
|
|
3750
|
+
const res = await shell({ config, command: "date +%Y-%m-%dT%H:%M:%S", deviceSerial, timeoutMs: 1e4 });
|
|
3751
|
+
const m = res.code === 0 ? /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/.exec(res.stdout) : null;
|
|
3752
|
+
if (!m) return null;
|
|
3753
|
+
const [year, month, day, hour, minute, second] = m.slice(1).map(Number);
|
|
3754
|
+
return Date.UTC(year, month - 1, day, hour, minute, second);
|
|
3755
|
+
} catch {
|
|
3756
|
+
return null;
|
|
3757
|
+
}
|
|
3758
|
+
}
|
|
3759
|
+
function hilogTimeMs(time, referenceMs) {
|
|
3760
|
+
const m = /^(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})\.(\d{3})$/.exec(time);
|
|
3761
|
+
if (!m) return null;
|
|
3762
|
+
const [month, day, hour, minute, second, ms] = m.slice(1).map(Number);
|
|
3763
|
+
const year = new Date(referenceMs).getUTCFullYear();
|
|
3764
|
+
let best = null;
|
|
3765
|
+
for (const y of [year - 1, year, year + 1]) {
|
|
3766
|
+
const t = Date.UTC(y, month - 1, day, hour, minute, second, ms);
|
|
3767
|
+
if (best === null || Math.abs(t - referenceMs) < Math.abs(best - referenceMs)) best = t;
|
|
3768
|
+
}
|
|
3769
|
+
return best;
|
|
3770
|
+
}
|
|
3771
|
+
async function recentEntryFilter(opts) {
|
|
3772
|
+
const passAll = { test: () => true, afterReconnect: async () => {
|
|
3773
|
+
} };
|
|
3774
|
+
const lookbackMs = opts.lookbackMs ?? 0;
|
|
3775
|
+
if (lookbackMs === Infinity) return passAll;
|
|
3776
|
+
const startedAt = Date.now();
|
|
3777
|
+
const now = await readDeviceClock(opts.config, opts.deviceSerial);
|
|
3778
|
+
if (now === null) {
|
|
3779
|
+
opts.logger.warn("Could not read the device clock, so lines already in the log buffer can match too.");
|
|
3780
|
+
return passAll;
|
|
3781
|
+
}
|
|
3782
|
+
let since = now - (Date.now() - startedAt) - lookbackMs;
|
|
3783
|
+
return {
|
|
3784
|
+
test: (entry) => {
|
|
3785
|
+
if (since === null) return true;
|
|
3786
|
+
const t = hilogTimeMs(entry.time, now);
|
|
3787
|
+
return t === null || t >= since;
|
|
3788
|
+
},
|
|
3789
|
+
afterReconnect: async () => {
|
|
3790
|
+
if (since === null) return;
|
|
3791
|
+
const later = await readDeviceClock(opts.config, opts.deviceSerial);
|
|
3792
|
+
if (later !== null && later < since) since = null;
|
|
3793
|
+
}
|
|
3794
|
+
};
|
|
3795
|
+
}
|
|
3633
3796
|
function waitForLog(opts) {
|
|
3634
3797
|
return new Promise((resolve7, reject) => {
|
|
3635
3798
|
const deadline = Date.now() + opts.timeoutMs;
|
|
@@ -3637,6 +3800,8 @@ function waitForLog(opts) {
|
|
|
3637
3800
|
let child = null;
|
|
3638
3801
|
let reconnectTimer;
|
|
3639
3802
|
let buf = "";
|
|
3803
|
+
let recent = { test: () => true, afterReconnect: async () => {
|
|
3804
|
+
} };
|
|
3640
3805
|
const cleanup = () => {
|
|
3641
3806
|
clearTimeout(timer);
|
|
3642
3807
|
if (reconnectTimer) clearTimeout(reconnectTimer);
|
|
@@ -3677,7 +3842,7 @@ function waitForLog(opts) {
|
|
|
3677
3842
|
buf = lines.pop() ?? "";
|
|
3678
3843
|
for (const line of lines) {
|
|
3679
3844
|
const entry = parseHilogLine(line);
|
|
3680
|
-
if (entry && opts.pattern.test(entryText(entry))) {
|
|
3845
|
+
if (entry && recent.test(entry) && opts.pattern.test(entryText(entry))) {
|
|
3681
3846
|
finish(entry);
|
|
3682
3847
|
return;
|
|
3683
3848
|
}
|
|
@@ -3687,13 +3852,21 @@ function waitForLog(opts) {
|
|
|
3687
3852
|
if (settled || child !== stream) return;
|
|
3688
3853
|
child = null;
|
|
3689
3854
|
if (Date.now() < deadline) {
|
|
3690
|
-
reconnectTimer = setTimeout(() => void
|
|
3855
|
+
reconnectTimer = setTimeout(() => void recent.afterReconnect().then(spawnStream).catch(failWith), 1e3);
|
|
3691
3856
|
}
|
|
3692
3857
|
};
|
|
3693
3858
|
stream.once("close", onEnd);
|
|
3694
3859
|
stream.once("error", onEnd);
|
|
3695
3860
|
};
|
|
3696
|
-
void
|
|
3861
|
+
void (async () => {
|
|
3862
|
+
recent = await recentEntryFilter({
|
|
3863
|
+
config: opts.config,
|
|
3864
|
+
deviceSerial: opts.deviceSerial,
|
|
3865
|
+
lookbackMs: opts.lookbackMs,
|
|
3866
|
+
logger: opts.logger ?? noopLogger
|
|
3867
|
+
});
|
|
3868
|
+
await spawnStream();
|
|
3869
|
+
})().catch(failWith);
|
|
3697
3870
|
});
|
|
3698
3871
|
}
|
|
3699
3872
|
function watchLog(opts) {
|
|
@@ -3702,6 +3875,8 @@ function watchLog(opts) {
|
|
|
3702
3875
|
let settled = false;
|
|
3703
3876
|
let child = null;
|
|
3704
3877
|
let buf = "";
|
|
3878
|
+
let recent = { test: () => true, afterReconnect: async () => {
|
|
3879
|
+
} };
|
|
3705
3880
|
const cleanup = () => {
|
|
3706
3881
|
clearTimeout(timer);
|
|
3707
3882
|
opts.abortSignal?.removeEventListener("abort", onAbort);
|
|
@@ -3725,6 +3900,13 @@ function watchLog(opts) {
|
|
|
3725
3900
|
const timer = setTimeout(done, opts.durationMs);
|
|
3726
3901
|
opts.abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
3727
3902
|
void (async () => {
|
|
3903
|
+
recent = await recentEntryFilter({
|
|
3904
|
+
config: opts.config,
|
|
3905
|
+
deviceSerial: opts.deviceSerial,
|
|
3906
|
+
lookbackMs: opts.lookbackMs,
|
|
3907
|
+
logger: opts.logger ?? noopLogger
|
|
3908
|
+
});
|
|
3909
|
+
if (settled) return;
|
|
3728
3910
|
const processId = await resolveProcessId(opts.config, opts.bundle, opts.deviceSerial);
|
|
3729
3911
|
if (settled) return;
|
|
3730
3912
|
const stream = streamHilog({ config: opts.config, processId, domain: opts.domain, deviceSerial: opts.deviceSerial });
|
|
@@ -3735,7 +3917,7 @@ function watchLog(opts) {
|
|
|
3735
3917
|
buf = lines.pop() ?? "";
|
|
3736
3918
|
for (const line of lines) {
|
|
3737
3919
|
const entry = parseHilogLine(line);
|
|
3738
|
-
if (entry && opts.pattern.test(entryText(entry))) matches.push(entry);
|
|
3920
|
+
if (entry && recent.test(entry) && opts.pattern.test(entryText(entry))) matches.push(entry);
|
|
3739
3921
|
}
|
|
3740
3922
|
});
|
|
3741
3923
|
})().catch((err) => {
|
|
@@ -4020,6 +4202,8 @@ async function ensureOhModules(opts) {
|
|
|
4020
4202
|
}
|
|
4021
4203
|
|
|
4022
4204
|
// src/build/codelinter.ts
|
|
4205
|
+
var fs26 = __toESM(require("fs"), 1);
|
|
4206
|
+
var path26 = __toESM(require("path"), 1);
|
|
4023
4207
|
var FINDING_RE = /^(.*?):(\d+):(?:(\d+):)?\s*(error|warning|warn|suggestion|info)\b[:\s-]*(.*)$/i;
|
|
4024
4208
|
var TRAILING_CODE_RE = /[([]([\w@/.\-]+)[)\]]\s*$/;
|
|
4025
4209
|
var FILE_HEADER_RE = /^(.+\.\w+)\((\d+)\)$/;
|
|
@@ -4106,6 +4290,16 @@ function parseCodelinterReport(output) {
|
|
|
4106
4290
|
function parseCodelinterFindings(output) {
|
|
4107
4291
|
return parseCodelinterReport(output).findings;
|
|
4108
4292
|
}
|
|
4293
|
+
var PROJECT_ROOT_FILES = [
|
|
4294
|
+
["build-profile.json5"],
|
|
4295
|
+
["hvigorfile.ts", "hvigorfile.js"],
|
|
4296
|
+
[path26.join("hvigor", "hvigor-config.json5")]
|
|
4297
|
+
];
|
|
4298
|
+
function missingProjectRootFiles(projectDir) {
|
|
4299
|
+
return PROJECT_ROOT_FILES.filter((names) => !names.some((f) => fs26.existsSync(path26.join(projectDir, f)))).map(
|
|
4300
|
+
(names) => names[0]
|
|
4301
|
+
);
|
|
4302
|
+
}
|
|
4109
4303
|
async function runCodelinter(opts) {
|
|
4110
4304
|
const res = await runProcess({
|
|
4111
4305
|
command: getCmdToolsBin(opts.config, "codelinter"),
|
|
@@ -4123,7 +4317,7 @@ async function runCodelinter(opts) {
|
|
|
4123
4317
|
var DIAGNOSIS_OUTPUT_LIMIT = 2e6;
|
|
4124
4318
|
function diagnoseBuildFailure(output) {
|
|
4125
4319
|
if (/is not exported from Kit|has no exported member .*@systemapi/i.test(output)) {
|
|
4126
|
-
return
|
|
4320
|
+
return `The project calls system APIs (\`@systemapi\`), which the public SDK leaves out. Build against the full OpenHarmony SDK: download an \`ohos-sdk-full\` archive from ${OHOS_DAILY_BUILDS_URL} and install it with \`oniro-app sdk install --from-archive <archive> --force\` (this replaces the public SDK of that API level; set ONIRO_SDK_ROOT_DIR to keep the two apart). Installing such an app also needs privileged signing (\`oniro-app sign --apl system_core --acls \u2026 --app-privilege-capabilities \u2026\`).`;
|
|
4127
4321
|
}
|
|
4128
4322
|
if (/00308018|SDK path does not exist|SDK license agreement is not accepted/i.test(output)) {
|
|
4129
4323
|
return "hvigor cannot find the SDK the project compiles against: check `oniro-app sdk list` against compileSdkVersion.";
|
|
@@ -4195,21 +4389,21 @@ function isValidBundleName(bundleName) {
|
|
|
4195
4389
|
}
|
|
4196
4390
|
|
|
4197
4391
|
// src/project/templates.ts
|
|
4198
|
-
var
|
|
4199
|
-
var
|
|
4392
|
+
var fs27 = __toESM(require("fs"), 1);
|
|
4393
|
+
var path27 = __toESM(require("path"), 1);
|
|
4200
4394
|
function toHumanTemplateName(folderName) {
|
|
4201
4395
|
return folderName.replace(/([a-z])([A-Z])/g, "$1 $2");
|
|
4202
4396
|
}
|
|
4203
4397
|
function listTemplates(templateRoot) {
|
|
4204
|
-
if (!
|
|
4205
|
-
const entries =
|
|
4398
|
+
if (!fs27.existsSync(templateRoot)) return [];
|
|
4399
|
+
const entries = fs27.readdirSync(templateRoot, { withFileTypes: true });
|
|
4206
4400
|
return entries.filter((e) => e.isDirectory()).map((e) => {
|
|
4207
|
-
const dir =
|
|
4208
|
-
const metaPath =
|
|
4401
|
+
const dir = path27.join(templateRoot, e.name);
|
|
4402
|
+
const metaPath = path27.join(dir, "template.json");
|
|
4209
4403
|
let meta = {};
|
|
4210
|
-
if (
|
|
4404
|
+
if (fs27.existsSync(metaPath)) {
|
|
4211
4405
|
try {
|
|
4212
|
-
meta = JSON.parse(
|
|
4406
|
+
meta = JSON.parse(fs27.readFileSync(metaPath, "utf8"));
|
|
4213
4407
|
} catch {
|
|
4214
4408
|
}
|
|
4215
4409
|
}
|
|
@@ -4224,57 +4418,57 @@ function listTemplates(templateRoot) {
|
|
|
4224
4418
|
function validateTemplateLayout(templateDir, defaultModuleName) {
|
|
4225
4419
|
const required = [
|
|
4226
4420
|
"build-profile.json5",
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4421
|
+
path27.join("AppScope", "app.json5"),
|
|
4422
|
+
path27.join(defaultModuleName, "src", "main", "module.json5"),
|
|
4423
|
+
path27.join(defaultModuleName, "oh-package.json5"),
|
|
4230
4424
|
"hvigorfile.ts"
|
|
4231
4425
|
];
|
|
4232
|
-
return required.filter((rel) => !
|
|
4426
|
+
return required.filter((rel) => !fs27.existsSync(path27.join(templateDir, rel)));
|
|
4233
4427
|
}
|
|
4234
4428
|
|
|
4235
4429
|
// src/project/createScaffold.ts
|
|
4236
|
-
var
|
|
4237
|
-
var
|
|
4430
|
+
var fs29 = __toESM(require("fs"), 1);
|
|
4431
|
+
var path28 = __toESM(require("path"), 1);
|
|
4238
4432
|
|
|
4239
4433
|
// src/project/jsonHelpers.ts
|
|
4240
|
-
var
|
|
4434
|
+
var fs28 = __toESM(require("fs"), 1);
|
|
4241
4435
|
var import_json55 = __toESM(require("json5"), 1);
|
|
4242
4436
|
function readJson5File(filePath) {
|
|
4243
|
-
return import_json55.default.parse(
|
|
4437
|
+
return import_json55.default.parse(fs28.readFileSync(filePath, "utf8"));
|
|
4244
4438
|
}
|
|
4245
4439
|
function writeJson5File(filePath, value) {
|
|
4246
|
-
|
|
4440
|
+
fs28.writeFileSync(filePath, JSON.stringify(value, null, 2) + "\n", "utf8");
|
|
4247
4441
|
}
|
|
4248
4442
|
function readJsonFile(filePath) {
|
|
4249
|
-
return JSON.parse(
|
|
4443
|
+
return JSON.parse(fs28.readFileSync(filePath, "utf8"));
|
|
4250
4444
|
}
|
|
4251
4445
|
function writeJsonFile(filePath, value) {
|
|
4252
|
-
|
|
4446
|
+
fs28.writeFileSync(filePath, JSON.stringify(value, null, 2) + "\n", "utf8");
|
|
4253
4447
|
}
|
|
4254
4448
|
|
|
4255
4449
|
// src/project/createScaffold.ts
|
|
4256
4450
|
var IGNORED_DIRS = /* @__PURE__ */ new Set(["oh_modules", "node_modules", "build", ".hvigor"]);
|
|
4257
4451
|
async function pathExists(p) {
|
|
4258
4452
|
try {
|
|
4259
|
-
await
|
|
4453
|
+
await fs29.promises.access(p);
|
|
4260
4454
|
return true;
|
|
4261
4455
|
} catch {
|
|
4262
4456
|
return false;
|
|
4263
4457
|
}
|
|
4264
4458
|
}
|
|
4265
4459
|
async function copyDirRecursive(srcDir, destDir) {
|
|
4266
|
-
await
|
|
4267
|
-
const entries = await
|
|
4460
|
+
await fs29.promises.mkdir(destDir, { recursive: true });
|
|
4461
|
+
const entries = await fs29.promises.readdir(srcDir, { withFileTypes: true });
|
|
4268
4462
|
for (const entry of entries) {
|
|
4269
|
-
const src =
|
|
4270
|
-
const dest =
|
|
4463
|
+
const src = path28.join(srcDir, entry.name);
|
|
4464
|
+
const dest = path28.join(destDir, entry.name);
|
|
4271
4465
|
if (entry.isDirectory()) {
|
|
4272
4466
|
await copyDirRecursive(src, dest);
|
|
4273
4467
|
} else if (entry.isSymbolicLink()) {
|
|
4274
4468
|
continue;
|
|
4275
4469
|
} else if (entry.isFile()) {
|
|
4276
4470
|
if (entry.name === "template.json") continue;
|
|
4277
|
-
await
|
|
4471
|
+
await fs29.promises.copyFile(src, dest);
|
|
4278
4472
|
}
|
|
4279
4473
|
}
|
|
4280
4474
|
}
|
|
@@ -4282,9 +4476,9 @@ async function normalizeJson5ToJson(projectDir, logger) {
|
|
|
4282
4476
|
const stack = [projectDir];
|
|
4283
4477
|
while (stack.length > 0) {
|
|
4284
4478
|
const currentDir = stack.pop();
|
|
4285
|
-
const entries = await
|
|
4479
|
+
const entries = await fs29.promises.readdir(currentDir, { withFileTypes: true });
|
|
4286
4480
|
for (const entry of entries) {
|
|
4287
|
-
const fullPath =
|
|
4481
|
+
const fullPath = path28.join(currentDir, entry.name);
|
|
4288
4482
|
if (entry.isDirectory()) {
|
|
4289
4483
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
4290
4484
|
stack.push(fullPath);
|
|
@@ -4306,23 +4500,23 @@ function toJavaPropertiesPath(p) {
|
|
|
4306
4500
|
function createOrUpdateLocalProperties(projectDir, sdkDir) {
|
|
4307
4501
|
const content = `sdk.dir=${toJavaPropertiesPath(sdkDir)}
|
|
4308
4502
|
`;
|
|
4309
|
-
|
|
4503
|
+
fs29.writeFileSync(path28.join(projectDir, "local.properties"), content, "utf8");
|
|
4310
4504
|
}
|
|
4311
4505
|
function renameIfExists(fromPath, toPath) {
|
|
4312
|
-
if (
|
|
4313
|
-
|
|
4506
|
+
if (fs29.existsSync(fromPath) && fromPath !== toPath) {
|
|
4507
|
+
fs29.renameSync(fromPath, toPath);
|
|
4314
4508
|
}
|
|
4315
4509
|
}
|
|
4316
4510
|
function updateTemplateConfigs(projectDir, args, sdkBaseDir) {
|
|
4317
|
-
const appJsonPath =
|
|
4318
|
-
if (
|
|
4511
|
+
const appJsonPath = path28.join(projectDir, "AppScope", "app.json5");
|
|
4512
|
+
if (fs29.existsSync(appJsonPath)) {
|
|
4319
4513
|
const appJson = readJson5File(appJsonPath);
|
|
4320
4514
|
appJson.app = appJson.app ?? {};
|
|
4321
4515
|
appJson.app.bundleName = args.bundleName;
|
|
4322
4516
|
writeJson5File(appJsonPath, appJson);
|
|
4323
4517
|
}
|
|
4324
|
-
const stringsPath =
|
|
4325
|
-
if (
|
|
4518
|
+
const stringsPath = path28.join(projectDir, "AppScope", "resources", "base", "element", "string.json");
|
|
4519
|
+
if (fs29.existsSync(stringsPath)) {
|
|
4326
4520
|
const strings = readJsonFile(stringsPath);
|
|
4327
4521
|
if (Array.isArray(strings.string)) {
|
|
4328
4522
|
const appName = strings.string.find((s) => s.name === "app_name");
|
|
@@ -4330,8 +4524,8 @@ function updateTemplateConfigs(projectDir, args, sdkBaseDir) {
|
|
|
4330
4524
|
}
|
|
4331
4525
|
writeJsonFile(stringsPath, strings);
|
|
4332
4526
|
}
|
|
4333
|
-
const buildProfilePath =
|
|
4334
|
-
if (
|
|
4527
|
+
const buildProfilePath = path28.join(projectDir, "build-profile.json5");
|
|
4528
|
+
if (fs29.existsSync(buildProfilePath)) {
|
|
4335
4529
|
const buildProfile = readJson5File(buildProfilePath);
|
|
4336
4530
|
buildProfile.app = buildProfile.app ?? {};
|
|
4337
4531
|
if (Array.isArray(buildProfile.app.products) && buildProfile.app.products.length > 0) {
|
|
@@ -4344,23 +4538,23 @@ function updateTemplateConfigs(projectDir, args, sdkBaseDir) {
|
|
|
4344
4538
|
}
|
|
4345
4539
|
writeJson5File(buildProfilePath, buildProfile);
|
|
4346
4540
|
}
|
|
4347
|
-
const moduleJsonPath =
|
|
4348
|
-
if (
|
|
4541
|
+
const moduleJsonPath = path28.join(projectDir, args.moduleName, "src", "main", "module.json5");
|
|
4542
|
+
if (fs29.existsSync(moduleJsonPath)) {
|
|
4349
4543
|
const moduleJson = readJson5File(moduleJsonPath);
|
|
4350
4544
|
moduleJson.module = moduleJson.module ?? {};
|
|
4351
4545
|
moduleJson.module.name = args.moduleName;
|
|
4352
4546
|
writeJson5File(moduleJsonPath, moduleJson);
|
|
4353
4547
|
}
|
|
4354
|
-
const moduleOhPackagePath =
|
|
4355
|
-
if (
|
|
4548
|
+
const moduleOhPackagePath = path28.join(projectDir, args.moduleName, "oh-package.json5");
|
|
4549
|
+
if (fs29.existsSync(moduleOhPackagePath)) {
|
|
4356
4550
|
const pkg = readJson5File(moduleOhPackagePath);
|
|
4357
4551
|
pkg.name = args.moduleName;
|
|
4358
4552
|
writeJson5File(moduleOhPackagePath, pkg);
|
|
4359
4553
|
}
|
|
4360
|
-
const vscodeDir =
|
|
4361
|
-
|
|
4554
|
+
const vscodeDir = path28.join(projectDir, ".vscode");
|
|
4555
|
+
fs29.mkdirSync(vscodeDir, { recursive: true });
|
|
4362
4556
|
const hapPath = `${args.moduleName}/build/default/outputs/default/${args.moduleName}-default-signed.hap`;
|
|
4363
|
-
writeJsonFile(
|
|
4557
|
+
writeJsonFile(path28.join(vscodeDir, "settings.json"), {
|
|
4364
4558
|
"oniro.hapPath": hapPath,
|
|
4365
4559
|
"files.associations": { "*.json5": "jsonc" }
|
|
4366
4560
|
});
|
|
@@ -4377,7 +4571,7 @@ async function createScaffold(opts) {
|
|
|
4377
4571
|
if (!opts.location || !await pathExists(opts.location)) {
|
|
4378
4572
|
throw new OniroError(`Location does not exist: ${opts.location}`);
|
|
4379
4573
|
}
|
|
4380
|
-
const templateDir =
|
|
4574
|
+
const templateDir = path28.join(opts.templateRoot, opts.templateId);
|
|
4381
4575
|
if (!await pathExists(templateDir)) {
|
|
4382
4576
|
throw new OniroError(`Template not found: ${templateDir}`);
|
|
4383
4577
|
}
|
|
@@ -4412,17 +4606,17 @@ async function createScaffold(opts) {
|
|
|
4412
4606
|
}
|
|
4413
4607
|
}
|
|
4414
4608
|
}
|
|
4415
|
-
const projectDir =
|
|
4609
|
+
const projectDir = path28.join(opts.location, opts.projectName);
|
|
4416
4610
|
if (await pathExists(projectDir)) {
|
|
4417
4611
|
if (!opts.overwrite) {
|
|
4418
4612
|
throw new OniroError(`Destination already exists: ${projectDir}. Pass overwrite: true to replace it.`);
|
|
4419
4613
|
}
|
|
4420
|
-
await
|
|
4614
|
+
await fs29.promises.rm(projectDir, { recursive: true, force: true });
|
|
4421
4615
|
}
|
|
4422
4616
|
logger.info(`[create] Scaffolding ${opts.templateId} at ${projectDir}`);
|
|
4423
4617
|
await copyDirRecursive(templateDir, projectDir);
|
|
4424
4618
|
if (moduleName !== defaultModuleName) {
|
|
4425
|
-
renameIfExists(
|
|
4619
|
+
renameIfExists(path28.join(projectDir, defaultModuleName), path28.join(projectDir, moduleName));
|
|
4426
4620
|
}
|
|
4427
4621
|
updateTemplateConfigs(
|
|
4428
4622
|
projectDir,
|
|
@@ -4439,11 +4633,11 @@ async function createScaffold(opts) {
|
|
|
4439
4633
|
}
|
|
4440
4634
|
|
|
4441
4635
|
// src/project/listModules.ts
|
|
4442
|
-
var
|
|
4443
|
-
var
|
|
4636
|
+
var fs30 = __toESM(require("fs"), 1);
|
|
4637
|
+
var path29 = __toESM(require("path"), 1);
|
|
4444
4638
|
function listModules(opts) {
|
|
4445
|
-
const buildProfile =
|
|
4446
|
-
if (!
|
|
4639
|
+
const buildProfile = path29.join(opts.projectDir, "build-profile.json5");
|
|
4640
|
+
if (!fs30.existsSync(buildProfile)) {
|
|
4447
4641
|
throw new OniroError(`build-profile.json5 not found at ${buildProfile}`);
|
|
4448
4642
|
}
|
|
4449
4643
|
const parsed = readJson5File(buildProfile);
|
|
@@ -4455,12 +4649,12 @@ function listModules(opts) {
|
|
|
4455
4649
|
}
|
|
4456
4650
|
|
|
4457
4651
|
// src/project/abilities.ts
|
|
4458
|
-
var
|
|
4459
|
-
var
|
|
4652
|
+
var fs31 = __toESM(require("fs"), 1);
|
|
4653
|
+
var path30 = __toESM(require("path"), 1);
|
|
4460
4654
|
function listAbilities(opts) {
|
|
4461
4655
|
const moduleName = opts.moduleName ?? "entry";
|
|
4462
|
-
const moduleJsonPath =
|
|
4463
|
-
if (!
|
|
4656
|
+
const moduleJsonPath = path30.join(opts.projectDir, moduleName, "src", "main", "module.json5");
|
|
4657
|
+
if (!fs31.existsSync(moduleJsonPath)) {
|
|
4464
4658
|
throw new OniroError(`Could not find module.json5 at ${moduleJsonPath}`);
|
|
4465
4659
|
}
|
|
4466
4660
|
const parsed = readJson5File(moduleJsonPath);
|
|
@@ -4468,12 +4662,12 @@ function listAbilities(opts) {
|
|
|
4468
4662
|
}
|
|
4469
4663
|
|
|
4470
4664
|
// src/project/prepareSigning.ts
|
|
4471
|
-
var
|
|
4472
|
-
var
|
|
4665
|
+
var fs32 = __toESM(require("fs"), 1);
|
|
4666
|
+
var path31 = __toESM(require("path"), 1);
|
|
4473
4667
|
function hasSigningArtifacts(dir) {
|
|
4474
|
-
if (!
|
|
4475
|
-
const buildProfile =
|
|
4476
|
-
if (!
|
|
4668
|
+
if (!fs32.existsSync(path31.join(dir, "signatures"))) return false;
|
|
4669
|
+
const buildProfile = path31.join(dir, "build-profile.json5");
|
|
4670
|
+
if (!fs32.existsSync(buildProfile)) return false;
|
|
4477
4671
|
try {
|
|
4478
4672
|
const parsed = readJson5File(buildProfile);
|
|
4479
4673
|
return Array.isArray(parsed.app?.signingConfigs) && parsed.app.signingConfigs.length > 0;
|
|
@@ -4576,8 +4770,25 @@ async function diffHapAssets(opts) {
|
|
|
4576
4770
|
}
|
|
4577
4771
|
|
|
4578
4772
|
// src/install/apply.ts
|
|
4579
|
-
var
|
|
4580
|
-
var
|
|
4773
|
+
var fs33 = __toESM(require("fs"), 1);
|
|
4774
|
+
var path32 = __toESM(require("path"), 1);
|
|
4775
|
+
|
|
4776
|
+
// src/install/hapBundleName.ts
|
|
4777
|
+
function bundleNameFromHapConfig(text) {
|
|
4778
|
+
try {
|
|
4779
|
+
const parsed = JSON.parse(text.replace(/^/, ""));
|
|
4780
|
+
const name = parsed.app?.bundleName;
|
|
4781
|
+
return typeof name === "string" && name ? name : null;
|
|
4782
|
+
} catch {
|
|
4783
|
+
return null;
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
async function readHapBundleName(hapPath) {
|
|
4787
|
+
const config = await readZipEntry(hapPath, (n) => n === "module.json") ?? await readZipEntry(hapPath, (n) => n === "config.json");
|
|
4788
|
+
return config ? bundleNameFromHapConfig(config.toString("utf8")) : null;
|
|
4789
|
+
}
|
|
4790
|
+
|
|
4791
|
+
// src/install/apply.ts
|
|
4581
4792
|
function decideInstallMethod(s) {
|
|
4582
4793
|
if (!s.signInfoInconsistent) return "replace";
|
|
4583
4794
|
if (s.isSystemBundle && !s.allowUninstall) return "refuse";
|
|
@@ -4598,7 +4809,7 @@ async function pidOf(config, bundle, deviceSerial) {
|
|
|
4598
4809
|
async function resolveHap(opts, logger) {
|
|
4599
4810
|
let hap;
|
|
4600
4811
|
if (opts.hapPath) {
|
|
4601
|
-
const hapPath = !
|
|
4812
|
+
const hapPath = !path32.isAbsolute(opts.hapPath) && opts.projectDir ? path32.join(opts.projectDir, opts.hapPath) : opts.hapPath;
|
|
4602
4813
|
hap = existingHapOrUnsigned(hapPath);
|
|
4603
4814
|
if (!hap) throw new OniroError(`HAP not found at ${hapPath}.`);
|
|
4604
4815
|
} else {
|
|
@@ -4607,7 +4818,7 @@ async function resolveHap(opts, logger) {
|
|
|
4607
4818
|
if (!picked) throw new OniroError(`No HAP found${opts.module ? ` for module ${opts.module}` : ""}. Build first.`);
|
|
4608
4819
|
hap = { path: picked.path, fallback: !picked.signed };
|
|
4609
4820
|
}
|
|
4610
|
-
if (hap.fallback) logger.warn(`No signed HAP found; installing the unsigned ${
|
|
4821
|
+
if (hap.fallback) logger.warn(`No signed HAP found; installing the unsigned ${path32.basename(hap.path)}.`);
|
|
4611
4822
|
return hap;
|
|
4612
4823
|
}
|
|
4613
4824
|
async function applyChanges(opts) {
|
|
@@ -4617,9 +4828,18 @@ async function applyChanges(opts) {
|
|
|
4617
4828
|
const allowUninstall = opts.allowUninstall ?? false;
|
|
4618
4829
|
const hap = await resolveHap(opts, logger);
|
|
4619
4830
|
const hapPath = hap.path;
|
|
4831
|
+
const hapBundle = await readHapBundleName(hapPath).catch((err) => {
|
|
4832
|
+
logger.debug(`bundle name check skipped: ${err.message}`);
|
|
4833
|
+
return null;
|
|
4834
|
+
});
|
|
4835
|
+
if (hapBundle && hapBundle !== bundle) {
|
|
4836
|
+
throw new OniroError(
|
|
4837
|
+
`${path32.basename(hapPath)} (${hapPath}) is bundle ${hapBundle}, not ${bundle}, so installing it would not update ${bundle}. Choose the HAP explicitly, or name ${hapBundle} as the bundle if it is the app to update.`
|
|
4838
|
+
);
|
|
4839
|
+
}
|
|
4620
4840
|
logger.info(`installing ${hapPath}`);
|
|
4621
4841
|
let assetsChanged = false;
|
|
4622
|
-
if (opts.installedHapPath &&
|
|
4842
|
+
if (opts.installedHapPath && fs33.existsSync(opts.installedHapPath)) {
|
|
4623
4843
|
try {
|
|
4624
4844
|
const diff = await diffHapAssets({ installedHap: opts.installedHapPath, newHap: hapPath });
|
|
4625
4845
|
assetsChanged = diff.addedAssetPaths.length > 0 || diff.removedAssetPaths.length > 0;
|
|
@@ -4652,7 +4872,7 @@ async function applyChanges(opts) {
|
|
|
4652
4872
|
}
|
|
4653
4873
|
if (!await isBundleInstalled({ config, bundle, deviceSerial })) {
|
|
4654
4874
|
throw new OniroError(
|
|
4655
|
-
`hdc reported ${
|
|
4875
|
+
`hdc reported ${path32.basename(hapPath)} as installed, but bm dump does not list ${bundle}. Check that the HAP was built from this project (its bundleName must match).`
|
|
4656
4876
|
);
|
|
4657
4877
|
}
|
|
4658
4878
|
let postInstallPid = await pidOf(config, bundle, deviceSerial);
|
|
@@ -4729,9 +4949,9 @@ var AUTH_PATHS = {
|
|
|
4729
4949
|
};
|
|
4730
4950
|
|
|
4731
4951
|
// src/harmonyos/auth/tokenStore.ts
|
|
4732
|
-
var
|
|
4952
|
+
var fs34 = __toESM(require("fs"), 1);
|
|
4733
4953
|
var os11 = __toESM(require("os"), 1);
|
|
4734
|
-
var
|
|
4954
|
+
var path33 = __toESM(require("path"), 1);
|
|
4735
4955
|
var crypto3 = __toESM(require("crypto"), 1);
|
|
4736
4956
|
var ALGORITHM = "aes-256-gcm";
|
|
4737
4957
|
var KEY_LENGTH = 32;
|
|
@@ -4767,7 +4987,7 @@ function permissionHint(dir) {
|
|
|
4767
4987
|
}
|
|
4768
4988
|
function ensureDir(dir) {
|
|
4769
4989
|
try {
|
|
4770
|
-
|
|
4990
|
+
fs34.mkdirSync(dir, { recursive: true, mode: DIR_MODE });
|
|
4771
4991
|
} catch (err) {
|
|
4772
4992
|
if (err.code === "EACCES") {
|
|
4773
4993
|
throw new OniroError(permissionHint(dir), err);
|
|
@@ -4778,17 +4998,17 @@ function ensureDir(dir) {
|
|
|
4778
4998
|
function createTokenStore(opts) {
|
|
4779
4999
|
const logger = opts.logger ?? noopLogger;
|
|
4780
5000
|
const authDir = opts.config.get("harmonyosAuthDir", defaultPaths.harmonyosAuthDir());
|
|
4781
|
-
const tokenPath =
|
|
4782
|
-
const keyPath =
|
|
5001
|
+
const tokenPath = path33.join(authDir, TOKEN_FILE);
|
|
5002
|
+
const keyPath = path33.join(os11.homedir(), ".local", "share", "oniro-app", "keys", KEY_FILE);
|
|
4783
5003
|
function loadOrCreateKey() {
|
|
4784
|
-
if (
|
|
4785
|
-
const existing =
|
|
5004
|
+
if (fs34.existsSync(keyPath)) {
|
|
5005
|
+
const existing = fs34.readFileSync(keyPath);
|
|
4786
5006
|
if (existing.length === KEY_LENGTH) return existing;
|
|
4787
5007
|
logger.warn("[harmonyos] The token key file was malformed; regenerating (you will need to log in again).");
|
|
4788
5008
|
}
|
|
4789
|
-
ensureDir(
|
|
5009
|
+
ensureDir(path33.dirname(keyPath));
|
|
4790
5010
|
const key = crypto3.randomBytes(KEY_LENGTH);
|
|
4791
|
-
|
|
5011
|
+
fs34.writeFileSync(keyPath, key, { mode: FILE_MODE });
|
|
4792
5012
|
return key;
|
|
4793
5013
|
}
|
|
4794
5014
|
return {
|
|
@@ -4798,12 +5018,12 @@ function createTokenStore(opts) {
|
|
|
4798
5018
|
const payload = Buffer.from(JSON.stringify(session), "utf8");
|
|
4799
5019
|
const blob = encrypt2(loadOrCreateKey(), payload);
|
|
4800
5020
|
ensureDir(authDir);
|
|
4801
|
-
|
|
5021
|
+
fs34.writeFileSync(tokenPath, JSON.stringify(blob, null, 2), { mode: FILE_MODE });
|
|
4802
5022
|
},
|
|
4803
5023
|
load() {
|
|
4804
|
-
if (!
|
|
5024
|
+
if (!fs34.existsSync(tokenPath)) return null;
|
|
4805
5025
|
try {
|
|
4806
|
-
const blob = JSON.parse(
|
|
5026
|
+
const blob = JSON.parse(fs34.readFileSync(tokenPath, "utf8"));
|
|
4807
5027
|
if (!isEncryptedBlob(blob)) return null;
|
|
4808
5028
|
const { jwtToken, siteId } = JSON.parse(decrypt2(loadOrCreateKey(), blob).toString("utf8"));
|
|
4809
5029
|
return typeof jwtToken === "string" && jwtToken && typeof siteId === "string" ? { jwtToken, siteId } : null;
|
|
@@ -4815,7 +5035,7 @@ function createTokenStore(opts) {
|
|
|
4815
5035
|
}
|
|
4816
5036
|
logger.debug(`[harmonyos] Discarding unreadable token at ${tokenPath}.`);
|
|
4817
5037
|
try {
|
|
4818
|
-
|
|
5038
|
+
fs34.rmSync(tokenPath, { force: true });
|
|
4819
5039
|
} catch {
|
|
4820
5040
|
}
|
|
4821
5041
|
return null;
|
|
@@ -4823,7 +5043,7 @@ function createTokenStore(opts) {
|
|
|
4823
5043
|
},
|
|
4824
5044
|
clear() {
|
|
4825
5045
|
try {
|
|
4826
|
-
|
|
5046
|
+
fs34.rmSync(tokenPath, { force: true });
|
|
4827
5047
|
} catch (err) {
|
|
4828
5048
|
throw new OniroError(`Failed to remove ${tokenPath}.`, err);
|
|
4829
5049
|
}
|
|
@@ -5304,7 +5524,7 @@ function mapAgcError(operation, statusCode, reasonPhrase, body) {
|
|
|
5304
5524
|
}
|
|
5305
5525
|
|
|
5306
5526
|
// src/harmonyos/signing/profile.ts
|
|
5307
|
-
var
|
|
5527
|
+
var fs35 = __toESM(require("fs"), 1);
|
|
5308
5528
|
var import_node_crypto3 = require("crypto");
|
|
5309
5529
|
var import_node_forge = __toESM(require("node-forge"), 1);
|
|
5310
5530
|
function extractProfileJson(buffer) {
|
|
@@ -5336,7 +5556,7 @@ function extractProfileJson(buffer) {
|
|
|
5336
5556
|
function readProvisionProfile(profilePath) {
|
|
5337
5557
|
let raw;
|
|
5338
5558
|
try {
|
|
5339
|
-
const json = extractProfileJson(
|
|
5559
|
+
const json = extractProfileJson(fs35.readFileSync(profilePath));
|
|
5340
5560
|
if (!json) return null;
|
|
5341
5561
|
raw = JSON.parse(json);
|
|
5342
5562
|
} catch {
|
|
@@ -5365,7 +5585,7 @@ function parseCertificate(pem) {
|
|
|
5365
5585
|
}
|
|
5366
5586
|
function keystoreHoldsKey(p12Path, keyAlias, keyPwd, certificate) {
|
|
5367
5587
|
try {
|
|
5368
|
-
const der = import_node_forge.default.util.createBuffer(
|
|
5588
|
+
const der = import_node_forge.default.util.createBuffer(fs35.readFileSync(p12Path).toString("binary"));
|
|
5369
5589
|
const p12 = import_node_forge.default.pkcs12.pkcs12FromAsn1(import_node_forge.default.asn1.fromDer(der), keyPwd);
|
|
5370
5590
|
const certBag = import_node_forge.default.pki.oids.certBag ?? "1.2.840.113549.1.12.10.1.3";
|
|
5371
5591
|
const wanted = certificate.publicKey.export({ type: "spki", format: "der" });
|
|
@@ -5381,7 +5601,7 @@ function keystoreHoldsKey(p12Path, keyAlias, keyPwd, certificate) {
|
|
|
5381
5601
|
}
|
|
5382
5602
|
}
|
|
5383
5603
|
function verifySigningMaterial(opts) {
|
|
5384
|
-
const pems =
|
|
5604
|
+
const pems = fs35.readFileSync(opts.cerPath, "utf8").match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g);
|
|
5385
5605
|
const chain = (pems ?? []).map(parseCertificate);
|
|
5386
5606
|
const leaf = chain.find((c) => !c.ca) ?? chain.at(-1);
|
|
5387
5607
|
if (!leaf) throw new AgcError(SIGNING_ERRORS.CERT_INVALID);
|
|
@@ -5400,14 +5620,14 @@ function verifySigningMaterial(opts) {
|
|
|
5400
5620
|
|
|
5401
5621
|
// src/harmonyos/signing/autoSign.ts
|
|
5402
5622
|
var crypto9 = __toESM(require("crypto"), 1);
|
|
5403
|
-
var
|
|
5404
|
-
var
|
|
5623
|
+
var fs40 = __toESM(require("fs"), 1);
|
|
5624
|
+
var path39 = __toESM(require("path"), 1);
|
|
5405
5625
|
var import_json57 = __toESM(require("json5"), 1);
|
|
5406
5626
|
|
|
5407
5627
|
// src/harmonyos/signing/agc.ts
|
|
5408
5628
|
var crypto6 = __toESM(require("crypto"), 1);
|
|
5409
|
-
var
|
|
5410
|
-
var
|
|
5629
|
+
var fs36 = __toESM(require("fs"), 1);
|
|
5630
|
+
var path34 = __toESM(require("path"), 1);
|
|
5411
5631
|
var ENDPOINTS = {
|
|
5412
5632
|
CERT_LIST: "/api/cps/harmony-cert-manage/v1/cert/list",
|
|
5413
5633
|
CERT_ADD: "/api/cps/harmony-cert-manage/v1/cert/add",
|
|
@@ -5493,8 +5713,8 @@ function createAgcClient(http3, auth) {
|
|
|
5493
5713
|
if (target.sha256 && actual !== target.sha256.toLowerCase()) {
|
|
5494
5714
|
throw new ChecksumMismatchError(target.sha256, actual);
|
|
5495
5715
|
}
|
|
5496
|
-
|
|
5497
|
-
|
|
5716
|
+
fs36.mkdirSync(path34.dirname(dest), { recursive: true, mode: 448 });
|
|
5717
|
+
fs36.writeFileSync(dest, buffer, { mode: 384 });
|
|
5498
5718
|
}
|
|
5499
5719
|
};
|
|
5500
5720
|
}
|
|
@@ -5545,22 +5765,22 @@ async function registerDevices(agc, connected, logger) {
|
|
|
5545
5765
|
|
|
5546
5766
|
// src/harmonyos/signing/keystore.ts
|
|
5547
5767
|
var crypto7 = __toESM(require("crypto"), 1);
|
|
5548
|
-
var
|
|
5549
|
-
var
|
|
5768
|
+
var fs38 = __toESM(require("fs"), 1);
|
|
5769
|
+
var path36 = __toESM(require("path"), 1);
|
|
5550
5770
|
|
|
5551
5771
|
// src/harmonyos/java.ts
|
|
5552
|
-
var
|
|
5553
|
-
var
|
|
5772
|
+
var fs37 = __toESM(require("fs"), 1);
|
|
5773
|
+
var path35 = __toESM(require("path"), 1);
|
|
5554
5774
|
var JAVA_BIN = process.platform === "win32" ? "java.exe" : "java";
|
|
5555
5775
|
function findJava(sdk, env = process.env) {
|
|
5556
5776
|
const candidates = [
|
|
5557
|
-
env.JAVA_HOME &&
|
|
5558
|
-
sdk &&
|
|
5777
|
+
env.JAVA_HOME && path35.join(env.JAVA_HOME, "bin", JAVA_BIN),
|
|
5778
|
+
sdk && path35.join(sdk.installRoot, "jbr", "bin", JAVA_BIN),
|
|
5559
5779
|
// macOS: the JBR is itself a bundle inside Studio's Contents.
|
|
5560
|
-
sdk &&
|
|
5561
|
-
...(env.PATH ?? "").split(
|
|
5780
|
+
sdk && path35.join(sdk.installRoot, "jbr", "Contents", "Home", "bin", JAVA_BIN),
|
|
5781
|
+
...(env.PATH ?? "").split(path35.delimiter).map((dir) => dir && path35.join(dir, JAVA_BIN))
|
|
5562
5782
|
];
|
|
5563
|
-
const found = candidates.find((c) => !!c &&
|
|
5783
|
+
const found = candidates.find((c) => !!c && fs37.existsSync(c));
|
|
5564
5784
|
if (found) return found;
|
|
5565
5785
|
throw new OniroError(
|
|
5566
5786
|
"No Java runtime found. HarmonyOS signing runs the SDK's hap-sign-tool.jar, which needs one: install a JDK and set JAVA_HOME, or install DevEco Studio, whose bundled runtime is used automatically."
|
|
@@ -5574,13 +5794,13 @@ function redactArgs(args) {
|
|
|
5574
5794
|
return args.map((arg, i) => args[i - 1] === "-keyPwd" || args[i - 1] === "-keystorePwd" ? "******" : arg);
|
|
5575
5795
|
}
|
|
5576
5796
|
async function generateKeystoreAndCsr(opts) {
|
|
5577
|
-
const jar =
|
|
5578
|
-
if (!
|
|
5797
|
+
const jar = path36.join(opts.sdk.sdkPath, "default", "openharmony", "toolchains", "lib", "hap-sign-tool.jar");
|
|
5798
|
+
if (!fs38.existsSync(jar)) {
|
|
5579
5799
|
throw new OniroError(`hap-sign-tool.jar not found at ${jar}; the HarmonyOS SDK looks incomplete.`);
|
|
5580
5800
|
}
|
|
5581
5801
|
const java = findJava(opts.sdk);
|
|
5582
5802
|
const keyPwd = crypto7.randomBytes(12).toString("base64url").replaceAll(/[-_]/g, "");
|
|
5583
|
-
|
|
5803
|
+
fs38.mkdirSync(path36.dirname(opts.p12Path), { recursive: true, mode: 448 });
|
|
5584
5804
|
const run = async (what, args) => {
|
|
5585
5805
|
const argv = ["-jar", jar, ...args, "-keyAlias", KEY_ALIAS, "-keystoreFile", opts.p12Path, "-keystorePwd", keyPwd, "-keyPwd", keyPwd];
|
|
5586
5806
|
opts.logger.debug(`[harmonyos] ${java} ${redactArgs(argv).join(" ")}`);
|
|
@@ -5594,28 +5814,28 @@ ${detail}` : ""}`);
|
|
|
5594
5814
|
opts.logger.info("[harmonyos] Generating the local keystore and certificate signing request...");
|
|
5595
5815
|
await run("generate the key pair", ["generate-keypair", "-keyAlg", "ECC", "-keySize", "NIST-P-256"]);
|
|
5596
5816
|
await run("generate the CSR", ["generate-csr", "-subject", "CN=DebugKey", "-signAlg", SIGN_ALG, "-outFile", opts.csrPath]);
|
|
5597
|
-
return { keyPwd, csr:
|
|
5817
|
+
return { keyPwd, csr: fs38.readFileSync(opts.csrPath, "utf8") };
|
|
5598
5818
|
}
|
|
5599
5819
|
|
|
5600
5820
|
// src/harmonyos/signing/paths.ts
|
|
5601
5821
|
var crypto8 = __toESM(require("crypto"), 1);
|
|
5602
|
-
var
|
|
5822
|
+
var path37 = __toESM(require("path"), 1);
|
|
5603
5823
|
function sanitizeNamePart(raw) {
|
|
5604
5824
|
const safe = (raw?.trim() ?? "").replace(/[\\/:*?"<>|=.-]+/g, "_");
|
|
5605
5825
|
return safe.slice(0, 64) || "default";
|
|
5606
5826
|
}
|
|
5607
5827
|
function resolveSigningMaterialPaths(config, productName, projectRoot) {
|
|
5608
5828
|
const hash = crypto8.createHash("sha256").update(projectRoot, "utf8").digest("base64url").replaceAll(/[-_]/g, "");
|
|
5609
|
-
const base =
|
|
5829
|
+
const base = path37.join(
|
|
5610
5830
|
config.get("harmonyosSigningDir", defaultPaths.harmonyosSigningDir()),
|
|
5611
|
-
`${sanitizeNamePart(productName)}_${
|
|
5831
|
+
`${sanitizeNamePart(productName)}_${path37.basename(projectRoot)}_${hash}=`
|
|
5612
5832
|
);
|
|
5613
5833
|
return { p12Path: `${base}.p12`, csrPath: `${base}.csr`, cerPath: `${base}.cer`, profilePath: `${base}.p7b` };
|
|
5614
5834
|
}
|
|
5615
5835
|
|
|
5616
5836
|
// src/harmonyos/signing/project.ts
|
|
5617
|
-
var
|
|
5618
|
-
var
|
|
5837
|
+
var fs39 = __toESM(require("fs"), 1);
|
|
5838
|
+
var path38 = __toESM(require("path"), 1);
|
|
5619
5839
|
var import_json56 = __toESM(require("json5"), 1);
|
|
5620
5840
|
|
|
5621
5841
|
// src/harmonyos/signing/aclPermissionList.ts
|
|
@@ -5683,9 +5903,9 @@ var ACL_PERMISSIONS = /* @__PURE__ */ new Set([
|
|
|
5683
5903
|
|
|
5684
5904
|
// src/harmonyos/signing/project.ts
|
|
5685
5905
|
function readRequestedPermissions(moduleConfigPath) {
|
|
5686
|
-
if (!
|
|
5906
|
+
if (!fs39.existsSync(moduleConfigPath)) return [];
|
|
5687
5907
|
try {
|
|
5688
|
-
const parsed = import_json56.default.parse(
|
|
5908
|
+
const parsed = import_json56.default.parse(fs39.readFileSync(moduleConfigPath, "utf-8"));
|
|
5689
5909
|
return (parsed.module?.requestPermissions ?? []).map((p) => p?.name).filter((n) => typeof n === "string" && n.length > 0);
|
|
5690
5910
|
} catch {
|
|
5691
5911
|
return [];
|
|
@@ -5694,10 +5914,10 @@ function readRequestedPermissions(moduleConfigPath) {
|
|
|
5694
5914
|
function collectAclPermissions(projectDir, logger = noopLogger) {
|
|
5695
5915
|
const requested = /* @__PURE__ */ new Set();
|
|
5696
5916
|
for (const module2 of listModules({ projectDir })) {
|
|
5697
|
-
const moduleRoot =
|
|
5917
|
+
const moduleRoot = path38.resolve(projectDir, module2.srcPath);
|
|
5698
5918
|
for (const sourceSet of ["main", "ohosTest"]) {
|
|
5699
5919
|
for (const name of readRequestedPermissions(
|
|
5700
|
-
|
|
5920
|
+
path38.join(moduleRoot, "src", sourceSet, "module.json5")
|
|
5701
5921
|
)) {
|
|
5702
5922
|
requested.add(name);
|
|
5703
5923
|
}
|
|
@@ -5713,7 +5933,7 @@ function collectAclPermissions(projectDir, logger = noopLogger) {
|
|
|
5713
5933
|
// src/harmonyos/signing/autoSign.ts
|
|
5714
5934
|
function shouldRegenerate(input) {
|
|
5715
5935
|
if (input.force) return "--force was passed";
|
|
5716
|
-
const missing = Object.values(input.paths).find((file) => !
|
|
5936
|
+
const missing = Object.values(input.paths).find((file) => !fs40.existsSync(file));
|
|
5717
5937
|
if (missing) return `${missing} is missing`;
|
|
5718
5938
|
const config = input.buildProfile.app?.signingConfigs?.find((c) => c.name === input.productName);
|
|
5719
5939
|
if (config?.type !== "HarmonyOS" || config.material?.profile !== input.paths.profilePath) {
|
|
@@ -5752,16 +5972,16 @@ function writeSigningConfig(opts) {
|
|
|
5752
5972
|
for (const product of app.products ?? []) {
|
|
5753
5973
|
if (product.name === opts.productName) product.signingConfig = opts.productName;
|
|
5754
5974
|
}
|
|
5755
|
-
|
|
5975
|
+
fs40.writeFileSync(opts.buildProfilePath, JSON.stringify(opts.buildProfile, null, 2));
|
|
5756
5976
|
}
|
|
5757
5977
|
async function harmonyOsAutoSign(opts) {
|
|
5758
5978
|
const logger = opts.logger ?? noopLogger;
|
|
5759
5979
|
const productName = opts.productName ?? "default";
|
|
5760
|
-
const projectDir =
|
|
5761
|
-
const buildProfilePath =
|
|
5980
|
+
const projectDir = path39.resolve(opts.projectDir);
|
|
5981
|
+
const buildProfilePath = path39.join(projectDir, "build-profile.json5");
|
|
5762
5982
|
let buildProfile;
|
|
5763
5983
|
try {
|
|
5764
|
-
buildProfile = import_json57.default.parse(
|
|
5984
|
+
buildProfile = import_json57.default.parse(fs40.readFileSync(buildProfilePath, "utf-8"));
|
|
5765
5985
|
} catch (err) {
|
|
5766
5986
|
throw new OniroError(`Could not read ${buildProfilePath}: ${err.message}`, err);
|
|
5767
5987
|
}
|
|
@@ -5801,7 +6021,7 @@ async function harmonyOsAutoSign(opts) {
|
|
|
5801
6021
|
logger.info(`[harmonyos] Regenerating signing material: ${reason}.`);
|
|
5802
6022
|
const agc = createAgcClient(opts.http ?? createHttpClient({ logger }), auth);
|
|
5803
6023
|
const deviceIds = await registerDevices(agc, connected, logger);
|
|
5804
|
-
for (const file of Object.values(paths))
|
|
6024
|
+
for (const file of Object.values(paths)) fs40.rmSync(file, { force: true });
|
|
5805
6025
|
const certName = `oniro_debug_${auth.teamId.replace(/[\\/.:]/g, "")}.cer`;
|
|
5806
6026
|
const stale = (await agc.listCertificates()).find((c) => c.certName === certName);
|
|
5807
6027
|
if (stale) {
|
|
@@ -5832,10 +6052,10 @@ async function harmonyOsAutoSign(opts) {
|
|
|
5832
6052
|
try {
|
|
5833
6053
|
verifySigningMaterial({ ...paths, keyAlias: KEY_ALIAS, keyPwd });
|
|
5834
6054
|
} catch (err) {
|
|
5835
|
-
|
|
6055
|
+
fs40.rmSync(paths.profilePath, { force: true });
|
|
5836
6056
|
throw err;
|
|
5837
6057
|
}
|
|
5838
|
-
const materialDir =
|
|
6058
|
+
const materialDir = path39.join(path39.dirname(paths.p12Path), "material");
|
|
5839
6059
|
try {
|
|
5840
6060
|
getKey(materialDir);
|
|
5841
6061
|
} catch {
|
|
@@ -5847,7 +6067,7 @@ async function harmonyOsAutoSign(opts) {
|
|
|
5847
6067
|
}
|
|
5848
6068
|
|
|
5849
6069
|
// src/index.ts
|
|
5850
|
-
var VERSION = "0.
|
|
6070
|
+
var VERSION = "0.15.0";
|
|
5851
6071
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5852
6072
|
0 && (module.exports = {
|
|
5853
6073
|
ALL_SDKS,
|
|
@@ -5862,6 +6082,7 @@ var VERSION = "0.14.0";
|
|
|
5862
6082
|
HUAWEI_SITES,
|
|
5863
6083
|
INSTALL_TMP_DIRNAME,
|
|
5864
6084
|
InsufficientSpaceError,
|
|
6085
|
+
OHOS_DAILY_BUILDS_URL,
|
|
5865
6086
|
OHOS_URL_BASE,
|
|
5866
6087
|
OniroError,
|
|
5867
6088
|
SIGNING_ERRORS,
|
|
@@ -5882,6 +6103,7 @@ var VERSION = "0.14.0";
|
|
|
5882
6103
|
buildHvigorwArgs,
|
|
5883
6104
|
buildInputCommand,
|
|
5884
6105
|
buildRawTouchCommand,
|
|
6106
|
+
bundleNameFromHapConfig,
|
|
5885
6107
|
captureBurst,
|
|
5886
6108
|
captureLog,
|
|
5887
6109
|
cleanCodelinterOutput,
|
|
@@ -5935,6 +6157,7 @@ var VERSION = "0.14.0";
|
|
|
5935
6157
|
findLayoutNodes,
|
|
5936
6158
|
findMissingProjectSdk,
|
|
5937
6159
|
findRunningProcess,
|
|
6160
|
+
findSdkOsDir,
|
|
5938
6161
|
flattenLayout,
|
|
5939
6162
|
forceStop,
|
|
5940
6163
|
formatBytes,
|
|
@@ -5968,10 +6191,12 @@ var VERSION = "0.14.0";
|
|
|
5968
6191
|
hdcTargetArgs,
|
|
5969
6192
|
hdcTargetArgsFor,
|
|
5970
6193
|
hideKeyboard,
|
|
6194
|
+
hilogTimeMs,
|
|
5971
6195
|
installApp,
|
|
5972
6196
|
installCmdTools,
|
|
5973
6197
|
installEmulator,
|
|
5974
6198
|
installFailureReason,
|
|
6199
|
+
installSdkFromArchive,
|
|
5975
6200
|
isBundleInstalled,
|
|
5976
6201
|
isCmdToolsInstalled,
|
|
5977
6202
|
isEmulatorInstalled,
|
|
@@ -5988,6 +6213,7 @@ var VERSION = "0.14.0";
|
|
|
5988
6213
|
listRunningProcesses,
|
|
5989
6214
|
listTemplates,
|
|
5990
6215
|
locateTarget,
|
|
6216
|
+
missingProjectRootFiles,
|
|
5991
6217
|
needsCmdWrapper,
|
|
5992
6218
|
nonInteractivePrompter,
|
|
5993
6219
|
noopLogger,
|
|
@@ -6011,9 +6237,11 @@ var VERSION = "0.14.0";
|
|
|
6011
6237
|
pickTarget,
|
|
6012
6238
|
prepareSigning,
|
|
6013
6239
|
pruneLayout,
|
|
6240
|
+
readHapBundleName,
|
|
6014
6241
|
readJson5File,
|
|
6015
6242
|
readJsonFile,
|
|
6016
6243
|
readProvisionProfile,
|
|
6244
|
+
readZipEntry,
|
|
6017
6245
|
reboot,
|
|
6018
6246
|
recvFile,
|
|
6019
6247
|
removeCmdTools,
|