@napi-rs/cli 3.10.4 → 3.10.6

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/src/api/build.ts CHANGED
@@ -42,7 +42,9 @@ import {
42
42
  removeNodeStreamWebTypeImports,
43
43
  rewriteUnboundNodeGlobalTypeQueries,
44
44
  rewriteTypeImportReferences,
45
+ checkSelfsign,
45
46
  scanExportedName,
47
+ signFileAtomic,
46
48
  type Target,
47
49
  targetToEnvVar,
48
50
  tryInstallCargoBinary,
@@ -254,7 +256,7 @@ export function checkAsyncRuntimeHostContract({
254
256
  }
255
257
  if (!asyncRuntime && missingHostExports.length === 0) {
256
258
  return {
257
- warning: `${packageName} exports the napi-async-runtime host contract but napi.wasm.asyncRuntime is not enabled. The generated WASI loaders will not install the CurrentThread task and timer hosts, so async exports will never make progress unless the host is installed by hand.`,
259
+ warning: `${packageName} exports the napi-async-runtime host contract but napi.wasm.asyncRuntime is not enabled. The generated WASI loaders will not install the CurrentThread task and timer hosts, so a binding running the CurrentThread flavor (the default on every wasm target) will make no progress unless the hosts are installed by hand. A wasm32-wasip1-threads binding that configures MultiThread does not need them.`,
258
260
  }
259
261
  }
260
262
  return {}
@@ -1138,6 +1140,7 @@ export async function buildProject(rawOptions: BuildOptions) {
1138
1140
 
1139
1141
  const options: ParsedBuildOptions = {
1140
1142
  dtsCache: true,
1143
+ ohosSign: true,
1141
1144
  ...rawOptions,
1142
1145
  format: resolveBuildFormat(rawOptions),
1143
1146
  cwd: rawOptions.cwd ?? process.cwd(),
@@ -2466,6 +2469,40 @@ class Builder {
2466
2469
  } else {
2467
2470
  await copyFileAtomic(src, dest)
2468
2471
  artifactReplaced = true
2472
+ // OpenHarmony devices refuse to load unsigned `.so` files, so inject
2473
+ // the fs-verity `.codesign` self-signature unless `--no-ohos-sign`.
2474
+ if (
2475
+ this.target.platform === 'openharmony' &&
2476
+ this.options.ohosSign !== false
2477
+ ) {
2478
+ debug('Self-signing OpenHarmony artifact:')
2479
+ debug(' %i', dest)
2480
+ try {
2481
+ // Force mode: the OHOS SDK linker can already self-sign artifacts
2482
+ // when its opt-in code-signing is enabled — strip that signature
2483
+ // and re-sign rather than failing on the existing `.codesign`
2484
+ // section.
2485
+ signFileAtomic(dest, true)
2486
+ // Re-verify the signature we just wrote so a corrupt or
2487
+ // mis-injected `.codesign` section is surfaced immediately.
2488
+ const { ok, reason } = checkSelfsign(readFileSync(dest))
2489
+ if (!ok) {
2490
+ debug.warn(
2491
+ `OpenHarmony self-sign verification failed: ${dest}: ${reason}`,
2492
+ )
2493
+ }
2494
+ } catch (e) {
2495
+ // Self-signing is best-effort: HarmonyOS only ships on aarch64,
2496
+ // and the algorithm (like the official binary-sign-tool) is only
2497
+ // exercised against aarch64 artifacts — warn instead of failing
2498
+ // the whole build when e.g. an x86_64 artifact cannot be signed.
2499
+ // signElf rejects before writing anything, so `dest` still holds
2500
+ // the copied artifact.
2501
+ debug.warn(
2502
+ `Skip OpenHarmony self-signing: ${dest}: ${(e as Error).message}`,
2503
+ )
2504
+ }
2505
+ }
2469
2506
  }
2470
2507
  this.outputs.push({
2471
2508
  kind: dest.endsWith('.node') ? 'node' : isWasm ? 'wasm' : 'exe',