@napi-rs/cli 3.1.5 → 3.3.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.
Files changed (38) hide show
  1. package/cli.mjs +3 -3
  2. package/dist/cli.js +976 -1070
  3. package/dist/index.cjs +1114 -873
  4. package/dist/index.d.cts +32 -3
  5. package/dist/index.d.ts +31 -4
  6. package/dist/index.js +1065 -866
  7. package/package.json +21 -22
  8. package/src/api/artifacts.ts +8 -5
  9. package/src/api/build.ts +176 -111
  10. package/src/api/create-npm-dirs.ts +2 -2
  11. package/src/api/new.ts +5 -3
  12. package/src/api/pre-publish.ts +1 -1
  13. package/src/api/rename.ts +3 -4
  14. package/src/api/templates/js-binding.ts +31 -6
  15. package/src/api/universalize.ts +1 -1
  16. package/src/api/version.ts +4 -1
  17. package/src/cli.ts +1 -27
  18. package/src/commands/new.ts +2 -1
  19. package/src/index.ts +33 -0
  20. package/src/utils/config.ts +1 -1
  21. package/src/utils/misc.ts +15 -15
  22. package/src/utils/read-config.ts +1 -3
  23. package/src/utils/target.ts +7 -0
  24. package/src/api/__tests__/create-npm-dirs.spec.ts +0 -210
  25. package/src/api/__tests__/new.spec.ts +0 -429
  26. package/src/utils/__tests__/__fixtures__/napi_type_def +0 -201
  27. package/src/utils/__tests__/__snapshots__/config.spec.ts.md +0 -97
  28. package/src/utils/__tests__/__snapshots__/config.spec.ts.snap +0 -0
  29. package/src/utils/__tests__/__snapshots__/target.spec.ts.md +0 -166
  30. package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
  31. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +0 -1157
  32. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
  33. package/src/utils/__tests__/__snapshots__/version.spec.ts.md +0 -21
  34. package/src/utils/__tests__/__snapshots__/version.spec.ts.snap +0 -0
  35. package/src/utils/__tests__/config.spec.ts +0 -81
  36. package/src/utils/__tests__/target.spec.ts +0 -19
  37. package/src/utils/__tests__/typegen.spec.ts +0 -64
  38. package/src/utils/__tests__/version.spec.ts +0 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napi-rs/cli",
3
- "version": "3.1.5",
3
+ "version": "3.3.0",
4
4
  "description": "Cli tools for napi-rs",
5
5
  "author": "LongYinan <lynweklm@gmail.com>",
6
6
  "homepage": "https://github.com/napi-rs/napi-rs",
@@ -25,7 +25,8 @@
25
25
  },
26
26
  "files": [
27
27
  "dist",
28
- "src"
28
+ "src",
29
+ "!__tests__"
29
30
  ],
30
31
  "keywords": [
31
32
  "cli",
@@ -59,40 +60,38 @@
59
60
  "url": "https://github.com/napi-rs/napi-rs/issues"
60
61
  },
61
62
  "dependencies": {
62
- "@inquirer/prompts": "^7.4.0",
63
- "@napi-rs/cross-toolchain": "^1.0.0",
64
- "@napi-rs/wasm-tools": "^1.0.0",
63
+ "@inquirer/prompts": "^7.8.4",
64
+ "@napi-rs/cross-toolchain": "^1.0.3",
65
+ "@napi-rs/wasm-tools": "^1.0.1",
65
66
  "@octokit/rest": "^22.0.0",
66
67
  "clipanion": "^4.0.0-rc.4",
67
68
  "colorette": "^2.0.20",
68
- "debug": "^4.4.0",
69
- "emnapi": "^1.4.0",
70
- "es-toolkit": "^1.39.8",
71
- "find-up": "^7.0.0",
69
+ "debug": "^4.4.1",
70
+ "emnapi": "^1.5.0",
71
+ "es-toolkit": "^1.39.10",
72
72
  "js-yaml": "^4.1.0",
73
- "semver": "^7.7.1",
73
+ "semver": "^7.7.2",
74
74
  "typanion": "^3.14.0"
75
75
  },
76
76
  "devDependencies": {
77
- "@emnapi/core": "^1.4.0",
78
- "@emnapi/runtime": "^1.4.0",
77
+ "@emnapi/runtime": "^1.5.0",
79
78
  "@oxc-node/core": "^0.0.32",
80
- "@std/toml": "npm:@jsr/std__toml@^1.0.8",
79
+ "@std/toml": "npm:@jsr/std__toml@^1.0.10",
81
80
  "@types/debug": "^4.1.12",
82
- "@types/inquirer": "^9.0.7",
81
+ "@types/inquirer": "^9.0.9",
83
82
  "@types/js-yaml": "^4.0.9",
84
- "@types/node": "^22.13.16",
85
- "@types/semver": "^7.7.0",
86
- "ava": "^6.2.0",
83
+ "@types/node": "^24.3.1",
84
+ "@types/semver": "^7.7.1",
85
+ "ava": "^6.4.1",
86
+ "empathic": "^2.0.0",
87
87
  "env-paths": "^3.0.0",
88
- "prettier": "^3.5.3",
89
- "tsdown": "^0.14.0",
88
+ "prettier": "^3.6.2",
89
+ "tsdown": "^0.15.0",
90
90
  "tslib": "^2.8.1",
91
- "typescript": "^5.8.2"
91
+ "typescript": "^5.9.2"
92
92
  },
93
93
  "peerDependencies": {
94
- "@emnapi/runtime": "^1.1.0",
95
- "emnapi": "^1.1.0"
94
+ "@emnapi/runtime": "^1.5.0"
96
95
  },
97
96
  "peerDependenciesMeta": {
98
97
  "@emnapi/runtime": {
@@ -1,10 +1,10 @@
1
- import { join, parse } from 'node:path'
1
+ import { join, resolve, parse } from 'node:path'
2
2
 
3
3
  import * as colors from 'colorette'
4
4
 
5
5
  import {
6
6
  applyDefaultArtifactsOptions,
7
- ArtifactsOptions,
7
+ type ArtifactsOptions,
8
8
  } from '../def/artifacts.js'
9
9
  import {
10
10
  readNapiConfig,
@@ -20,9 +20,12 @@ const debug = debugFactory('artifacts')
20
20
  export async function collectArtifacts(userOptions: ArtifactsOptions) {
21
21
  const options = applyDefaultArtifactsOptions(userOptions)
22
22
 
23
- const packageJsonPath = join(options.cwd, options.packageJsonPath)
24
- const { targets, binaryName, packageName } =
25
- await readNapiConfig(packageJsonPath)
23
+ const resolvePath = (...paths: string[]) => resolve(options.cwd, ...paths)
24
+ const packageJsonPath = resolvePath(options.packageJsonPath)
25
+ const { targets, binaryName, packageName } = await readNapiConfig(
26
+ packageJsonPath,
27
+ options.configPath ? resolvePath(options.configPath) : undefined,
28
+ )
26
29
 
27
30
  const distDirs = targets.map((platform) =>
28
31
  join(options.cwd, options.npmDir, platform.platformArchABI),
package/src/api/build.ts CHANGED
@@ -7,31 +7,31 @@ import { parse, join, resolve } from 'node:path'
7
7
 
8
8
  import * as colors from 'colorette'
9
9
 
10
- import { BuildOptions as RawBuildOptions } from '../def/build.js'
10
+ import type { BuildOptions as RawBuildOptions } from '../def/build.js'
11
11
  import {
12
12
  CLI_VERSION,
13
13
  copyFileAsync,
14
- Crate,
14
+ type Crate,
15
15
  debugFactory,
16
16
  DEFAULT_TYPE_DEF_HEADER,
17
17
  fileExists,
18
18
  getSystemDefaultTarget,
19
19
  getTargetLinker,
20
20
  mkdirAsync,
21
- NapiConfig,
21
+ type NapiConfig,
22
22
  parseMetadata,
23
23
  parseTriple,
24
24
  processTypeDef,
25
25
  readFileAsync,
26
26
  readNapiConfig,
27
- Target,
27
+ type Target,
28
28
  targetToEnvVar,
29
29
  tryInstallCargoBinary,
30
30
  unlinkAsync,
31
31
  writeFileAsync,
32
32
  dirExistsAsync,
33
33
  readdirAsync,
34
- CargoWorkspaceMetadata,
34
+ type CargoWorkspaceMetadata,
35
35
  } from '../utils/index.js'
36
36
 
37
37
  import { createCjsBinding, createEsmBinding } from './templates/index.js'
@@ -82,9 +82,7 @@ export async function buildProject(rawOptions: BuildOptions) {
82
82
  )
83
83
  }
84
84
  const config = await readNapiConfig(
85
- resolvePath(
86
- options.configPath ?? options.packageJsonPath ?? 'package.json',
87
- ),
85
+ resolvePath(options.packageJsonPath ?? 'package.json'),
88
86
  options.configPath ? resolvePath(options.configPath) : undefined,
89
87
  )
90
88
 
@@ -878,121 +876,42 @@ class Builder {
878
876
 
879
877
  private async generateTypeDef() {
880
878
  const typeDefDir = this.envs.NAPI_TYPE_DEF_TMP_FOLDER
881
- if (!this.enableTypeDef || !(await dirExistsAsync(typeDefDir))) {
882
- return []
883
- }
884
-
885
- const dest = join(this.outputDir, this.options.dts ?? 'index.d.ts')
886
-
887
- let header = ''
888
- let dts = ''
889
- let exports: string[] = []
890
-
891
- if (!this.options.noDtsHeader) {
892
- const dtsHeader = this.options.dtsHeader ?? this.config.dtsHeader
893
- // `dtsHeaderFile` in config > `dtsHeader` in cli flag > `dtsHeader` in config
894
- if (this.config.dtsHeaderFile) {
895
- try {
896
- header = await readFileAsync(
897
- join(this.options.cwd, this.config.dtsHeaderFile),
898
- 'utf-8',
899
- )
900
- } catch (e) {
901
- debug.warn(
902
- `Failed to read dts header file ${this.config.dtsHeaderFile}`,
903
- e,
904
- )
905
- }
906
- } else if (dtsHeader) {
907
- header = dtsHeader
908
- } else {
909
- header = DEFAULT_TYPE_DEF_HEADER
910
- }
911
- }
912
-
913
- const files = await readdirAsync(typeDefDir, { withFileTypes: true })
914
-
915
- if (!files.length) {
916
- debug('No type def files found. Skip generating dts file.')
879
+ if (!this.enableTypeDef) {
917
880
  return []
918
881
  }
919
882
 
920
- for (const file of files) {
921
- if (!file.isFile()) {
922
- continue
923
- }
924
-
925
- const { dts: fileDts, exports: fileExports } = await processTypeDef(
926
- join(typeDefDir, file.name),
927
- this.options.constEnum ?? this.config.constEnum ?? true,
928
- )
929
-
930
- dts += fileDts
931
- exports.push(...fileExports)
932
- }
933
-
934
- if (dts.indexOf('ExternalObject<') > -1) {
935
- header += `
936
- export declare class ExternalObject<T> {
937
- readonly '': {
938
- readonly '': unique symbol
939
- [K: symbol]: T
940
- }
941
- }
942
- `
943
- }
944
-
945
- if (dts.indexOf('TypedArray') > -1) {
946
- header += `
947
- export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array
948
- `
949
- }
950
-
951
- dts = header + dts
883
+ const exports = await generateTypeDef({
884
+ typeDefDir,
885
+ outputDir: this.outputDir,
886
+ dts: this.options.dts,
887
+ noDtsHeader: this.options.noDtsHeader,
888
+ dtsHeader: this.options.dtsHeader,
889
+ configDtsHeader: this.config.dtsHeader,
890
+ configDtsHeaderFile: this.config.dtsHeaderFile,
891
+ constEnum: this.options.constEnum ?? this.config.constEnum,
892
+ cwd: this.options.cwd,
893
+ })
952
894
 
953
- try {
954
- debug('Writing type def to:')
955
- debug(' %i', dest)
956
- await writeFileAsync(dest, dts, 'utf-8')
895
+ if (exports.length > 0) {
896
+ const dest = join(this.outputDir, this.options.dts ?? 'index.d.ts')
957
897
  this.outputs.push({ kind: 'dts', path: dest })
958
- } catch (e) {
959
- debug.error('Failed to write type def file')
960
- debug.error(e as Error)
961
898
  }
962
899
 
963
900
  return exports
964
901
  }
965
902
 
966
903
  private async writeJsBinding(idents: string[]) {
967
- if (
968
- !this.options.platform ||
969
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
970
- this.options.noJsBinding ||
971
- idents.length === 0
972
- ) {
973
- return
974
- }
975
-
976
- const name = this.options.jsBinding ?? 'index.js'
977
-
978
- const createBinding = this.options.esm ? createEsmBinding : createCjsBinding
979
- const binding = createBinding(
980
- this.config.binaryName,
981
- this.config.packageName,
904
+ return writeJsBinding({
905
+ platform: this.options.platform,
906
+ noJsBinding: this.options.noJsBinding,
982
907
  idents,
983
- // in npm preversion hook
984
- process.env.npm_new_version ?? this.config.packageJson.version,
985
- )
986
-
987
- try {
988
- const dest = join(this.outputDir, name)
989
- debug('Writing js binding to:')
990
- debug(' %i', dest)
991
- await writeFileAsync(dest, binding, 'utf-8')
992
- return { kind: 'js', path: dest } satisfies Output
993
- } catch (e) {
994
- throw new Error('Failed to write js binding file', { cause: e })
995
- }
908
+ jsBinding: this.options.jsBinding,
909
+ esm: this.options.esm,
910
+ binaryName: this.config.binaryName,
911
+ packageName: this.config.packageName,
912
+ version: process.env.npm_new_version ?? this.config.packageJson.version,
913
+ outputDir: this.outputDir,
914
+ })
996
915
  }
997
916
 
998
917
  private async writeWasiBinding(
@@ -1076,3 +995,149 @@ export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array
1076
995
  }
1077
996
  }
1078
997
  }
998
+
999
+ export interface WriteJsBindingOptions {
1000
+ platform?: boolean
1001
+ noJsBinding?: boolean
1002
+ idents: string[]
1003
+ jsBinding?: string
1004
+ esm?: boolean
1005
+ binaryName: string
1006
+ packageName: string
1007
+ version: string
1008
+ outputDir: string
1009
+ }
1010
+
1011
+ export async function writeJsBinding(
1012
+ options: WriteJsBindingOptions,
1013
+ ): Promise<Output | undefined> {
1014
+ if (
1015
+ !options.platform ||
1016
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
1017
+ options.noJsBinding ||
1018
+ options.idents.length === 0
1019
+ ) {
1020
+ return
1021
+ }
1022
+
1023
+ const name = options.jsBinding ?? 'index.js'
1024
+
1025
+ const createBinding = options.esm ? createEsmBinding : createCjsBinding
1026
+ const binding = createBinding(
1027
+ options.binaryName,
1028
+ options.packageName,
1029
+ options.idents,
1030
+ // in npm preversion hook
1031
+ options.version,
1032
+ )
1033
+
1034
+ try {
1035
+ const dest = join(options.outputDir, name)
1036
+ debug('Writing js binding to:')
1037
+ debug(' %i', dest)
1038
+ await writeFileAsync(dest, binding, 'utf-8')
1039
+ return { kind: 'js', path: dest } satisfies Output
1040
+ } catch (e) {
1041
+ throw new Error('Failed to write js binding file', { cause: e })
1042
+ }
1043
+ }
1044
+
1045
+ export interface GenerateTypeDefOptions {
1046
+ typeDefDir: string
1047
+ outputDir: string
1048
+ dts?: string
1049
+ noDtsHeader?: boolean
1050
+ dtsHeader?: string
1051
+ dtsHeaderFile?: string
1052
+ configDtsHeader?: string
1053
+ configDtsHeaderFile?: string
1054
+ constEnum?: boolean
1055
+ cwd: string
1056
+ }
1057
+
1058
+ export async function generateTypeDef(
1059
+ options: GenerateTypeDefOptions,
1060
+ ): Promise<string[]> {
1061
+ if (!(await dirExistsAsync(options.typeDefDir))) {
1062
+ return []
1063
+ }
1064
+
1065
+ const dest = join(options.outputDir, options.dts ?? 'index.d.ts')
1066
+
1067
+ let header = ''
1068
+ let dts = ''
1069
+ let exports: string[] = []
1070
+
1071
+ if (!options.noDtsHeader) {
1072
+ const dtsHeader = options.dtsHeader ?? options.configDtsHeader
1073
+ // `dtsHeaderFile` in config > `dtsHeader` in cli flag > `dtsHeader` in config
1074
+ if (options.configDtsHeaderFile) {
1075
+ try {
1076
+ header = await readFileAsync(
1077
+ join(options.cwd, options.configDtsHeaderFile),
1078
+ 'utf-8',
1079
+ )
1080
+ } catch (e) {
1081
+ debug.warn(
1082
+ `Failed to read dts header file ${options.configDtsHeaderFile}`,
1083
+ e,
1084
+ )
1085
+ }
1086
+ } else if (dtsHeader) {
1087
+ header = dtsHeader
1088
+ } else {
1089
+ header = DEFAULT_TYPE_DEF_HEADER
1090
+ }
1091
+ }
1092
+
1093
+ const files = await readdirAsync(options.typeDefDir, { withFileTypes: true })
1094
+
1095
+ if (!files.length) {
1096
+ debug('No type def files found. Skip generating dts file.')
1097
+ return []
1098
+ }
1099
+
1100
+ for (const file of files) {
1101
+ if (!file.isFile()) {
1102
+ continue
1103
+ }
1104
+
1105
+ const { dts: fileDts, exports: fileExports } = await processTypeDef(
1106
+ join(options.typeDefDir, file.name),
1107
+ options.constEnum ?? true,
1108
+ )
1109
+
1110
+ dts += fileDts
1111
+ exports.push(...fileExports)
1112
+ }
1113
+
1114
+ if (dts.indexOf('ExternalObject<') > -1) {
1115
+ header += `
1116
+ export declare class ExternalObject<T> {
1117
+ readonly '': {
1118
+ readonly '': unique symbol
1119
+ [K: symbol]: T
1120
+ }
1121
+ }
1122
+ `
1123
+ }
1124
+
1125
+ if (dts.indexOf('TypedArray') > -1) {
1126
+ header += `
1127
+ export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array
1128
+ `
1129
+ }
1130
+
1131
+ dts = header + dts
1132
+
1133
+ try {
1134
+ debug('Writing type def to:')
1135
+ debug(' %i', dest)
1136
+ await writeFileAsync(dest, dts, 'utf-8')
1137
+ } catch (e) {
1138
+ debug.error('Failed to write type def file')
1139
+ debug.error(e as Error)
1140
+ }
1141
+
1142
+ return exports
1143
+ }
@@ -4,7 +4,7 @@ import { parse } from 'semver'
4
4
 
5
5
  import {
6
6
  applyDefaultCreateNpmDirsOptions,
7
- CreateNpmDirsOptions,
7
+ type CreateNpmDirsOptions,
8
8
  } from '../def/create-npm-dirs.js'
9
9
  import {
10
10
  debugFactory,
@@ -12,7 +12,7 @@ import {
12
12
  mkdirAsync as rawMkdirAsync,
13
13
  pick,
14
14
  writeFileAsync as rawWriteFileAsync,
15
- Target,
15
+ type Target,
16
16
  type CommonPackageJsonFields,
17
17
  } from '../utils/index.js'
18
18
 
package/src/api/new.ts CHANGED
@@ -8,7 +8,7 @@ import { load as yamlLoad, dump as yamlDump } from 'js-yaml'
8
8
 
9
9
  import {
10
10
  applyDefaultNewOptions,
11
- NewOptions as RawNewOptions,
11
+ type NewOptions as RawNewOptions,
12
12
  } from '../def/new.js'
13
13
  import {
14
14
  AVAILABLE_TARGETS,
@@ -17,7 +17,7 @@ import {
17
17
  mkdirAsync,
18
18
  readdirAsync,
19
19
  statAsync,
20
- SupportedPackageManager,
20
+ type SupportedPackageManager,
21
21
  } from '../utils/index.js'
22
22
  import { napiEngineRequirement } from '../utils/version.js'
23
23
  import { renameProject } from './rename.js'
@@ -169,6 +169,7 @@ async function filterTargetsInGithubActions(
169
169
 
170
170
  const macOSAndWindowsTargets = new Set([
171
171
  'x86_64-pc-windows-msvc',
172
+ 'x86_64-pc-windows-gnu',
172
173
  'aarch64-pc-windows-msvc',
173
174
  'x86_64-apple-darwin',
174
175
  ])
@@ -180,6 +181,7 @@ async function filterTargetsInGithubActions(
180
181
  'aarch64-unknown-linux-musl',
181
182
  'armv7-unknown-linux-gnueabihf',
182
183
  'armv7-unknown-linux-musleabihf',
184
+ 'loongarch64-unknown-linux-gnu',
183
185
  'riscv64gc-unknown-linux-gnu',
184
186
  'powerpc64le-unknown-linux-gnu',
185
187
  's390x-unknown-linux-gnu',
@@ -467,4 +469,4 @@ function getBinaryName(name: string): string {
467
469
  return name.split('/').pop()!
468
470
  }
469
471
 
470
- export { NewOptions }
472
+ export type { NewOptions }
@@ -6,7 +6,7 @@ import { Octokit } from '@octokit/rest'
6
6
 
7
7
  import {
8
8
  applyDefaultPrePublishOptions,
9
- PrePublishOptions,
9
+ type PrePublishOptions,
10
10
  } from '../def/pre-publish.js'
11
11
  import {
12
12
  readFileAsync,
package/src/api/rename.ts CHANGED
@@ -5,9 +5,9 @@ import { resolve, join } from 'node:path'
5
5
  import { parse as parseToml, stringify as stringifyToml } from '@std/toml'
6
6
  import { load as yamlParse, dump as yamlStringify } from 'js-yaml'
7
7
  import { isNil, merge, omitBy, pick } from 'es-toolkit'
8
- import { findUp } from 'find-up'
8
+ import * as find from 'empathic/find'
9
9
 
10
- import { applyDefaultRenameOptions, RenameOptions } from '../def/rename.js'
10
+ import { applyDefaultRenameOptions, type RenameOptions } from '../def/rename.js'
11
11
  import { readConfig, readFileAsync, writeFileAsync } from '../utils/index.js'
12
12
 
13
13
  export async function renameProject(userOptions: RenameOptions) {
@@ -74,9 +74,8 @@ export async function renameProject(userOptions: RenameOptions) {
74
74
 
75
75
  await writeFileAsync(cargoTomlPath, updatedTomlContent)
76
76
  if (oldName !== options.binaryName) {
77
- const githubActionsPath = await findUp('.github', {
77
+ const githubActionsPath = find.dir('.github', {
78
78
  cwd: options.cwd,
79
- type: 'directory',
80
79
  })
81
80
  if (githubActionsPath) {
82
81
  const githubActionsCIYmlPath = join(
@@ -132,7 +132,7 @@ const isMuslFromChildProcess = () => {
132
132
  function requireNative() {
133
133
  if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
134
134
  try {
135
- nativeBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
135
+ return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
136
136
  } catch (err) {
137
137
  loadErrors.push(err)
138
138
  }
@@ -146,7 +146,11 @@ function requireNative() {
146
146
  }
147
147
  } else if (process.platform === 'win32') {
148
148
  if (process.arch === 'x64') {
149
- ${requireTuple('win32-x64-msvc')}
149
+ if (process.report?.getReport?.()?.header?.osName?.startsWith?.('MINGW')) {
150
+ ${requireTuple('win32-x64-gnu')}
151
+ } else {
152
+ ${requireTuple('win32-x64-msvc')}
153
+ }
150
154
  } else if (process.arch === 'ia32') {
151
155
  ${requireTuple('win32-ia32-msvc')}
152
156
  } else if (process.arch === 'arm64') {
@@ -190,6 +194,12 @@ function requireNative() {
190
194
  } else {
191
195
  ${requireTuple('linux-arm-gnueabihf', 10)}
192
196
  }
197
+ } else if (process.arch === 'loong64') {
198
+ if (isMusl()) {
199
+ ${requireTuple('linux-loong64-musl', 10)}
200
+ } else {
201
+ ${requireTuple('linux-loong64-gnu', 10)}
202
+ }
193
203
  } else if (process.arch === 'riscv64') {
194
204
  if (isMusl()) {
195
205
  ${requireTuple('linux-riscv64-musl', 10)}
@@ -221,22 +231,32 @@ function requireNative() {
221
231
  nativeBinding = requireNative()
222
232
 
223
233
  if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
234
+ let wasiBinding = null
235
+ let wasiBindingError = null
224
236
  try {
225
- nativeBinding = require('./${localName}.wasi.cjs')
237
+ wasiBinding = require('./${localName}.wasi.cjs')
238
+ nativeBinding = wasiBinding
226
239
  } catch (err) {
227
240
  if (process.env.NAPI_RS_FORCE_WASI) {
228
- loadErrors.push(err)
241
+ wasiBindingError = err
229
242
  }
230
243
  }
231
244
  if (!nativeBinding) {
232
245
  try {
233
- nativeBinding = require('${pkgName}-wasm32-wasi')
246
+ wasiBinding = require('${pkgName}-wasm32-wasi')
247
+ nativeBinding = wasiBinding
234
248
  } catch (err) {
235
249
  if (process.env.NAPI_RS_FORCE_WASI) {
250
+ wasiBindingError.cause = err
236
251
  loadErrors.push(err)
237
252
  }
238
253
  }
239
254
  }
255
+ if (process.env.NAPI_RS_FORCE_WASI === 'error' && !wasiBinding) {
256
+ const error = new Error('WASI binding not found and NAPI_RS_FORCE_WASI is set to error')
257
+ error.cause = wasiBindingError
258
+ throw error
259
+ }
240
260
  }
241
261
 
242
262
  if (!nativeBinding) {
@@ -245,7 +265,12 @@ if (!nativeBinding) {
245
265
  \`Cannot find native binding. \` +
246
266
  \`npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). \` +
247
267
  'Please try \`npm i\` again after removing both package-lock.json and node_modules directory.',
248
- { cause: loadErrors }
268
+ {
269
+ cause: loadErrors.reduce((err, cur) => {
270
+ cur.cause = err
271
+ return cur
272
+ }),
273
+ },
249
274
  )
250
275
  }
251
276
  throw new Error(\`Failed to load native binding\`)
@@ -3,7 +3,7 @@ import { join, resolve } from 'node:path'
3
3
 
4
4
  import {
5
5
  applyDefaultUniversalizeOptions,
6
- UniversalizeOptions,
6
+ type UniversalizeOptions,
7
7
  } from '../def/universalize.js'
8
8
  import { readNapiConfig } from '../utils/config.js'
9
9
  import { debugFactory } from '../utils/log.js'
@@ -1,6 +1,9 @@
1
1
  import { join, resolve } from 'node:path'
2
2
 
3
- import { applyDefaultVersionOptions, VersionOptions } from '../def/version.js'
3
+ import {
4
+ applyDefaultVersionOptions,
5
+ type VersionOptions,
6
+ } from '../def/version.js'
4
7
  import {
5
8
  readNapiConfig,
6
9
  debugFactory,
package/src/cli.ts CHANGED
@@ -1,31 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { Cli } from 'clipanion'
4
-
5
- import { ArtifactsCommand } from './commands/artifacts.js'
6
- import { BuildCommand } from './commands/build.js'
7
- import { CreateNpmDirsCommand } from './commands/create-npm-dirs.js'
8
- import { HelpCommand } from './commands/help.js'
9
- import { NewCommand } from './commands/new.js'
10
- import { PrePublishCommand } from './commands/pre-publish.js'
11
- import { RenameCommand } from './commands/rename.js'
12
- import { UniversalizeCommand } from './commands/universalize.js'
13
- import { VersionCommand } from './commands/version.js'
14
- import { CLI_VERSION } from './utils/misc.js'
15
-
16
- const cli = new Cli({
17
- binaryName: 'napi',
18
- binaryVersion: CLI_VERSION,
19
- })
20
-
21
- cli.register(NewCommand)
22
- cli.register(BuildCommand)
23
- cli.register(CreateNpmDirsCommand)
24
- cli.register(ArtifactsCommand)
25
- cli.register(UniversalizeCommand)
26
- cli.register(RenameCommand)
27
- cli.register(PrePublishCommand)
28
- cli.register(VersionCommand)
29
- cli.register(HelpCommand)
3
+ import { cli } from './index.js'
30
4
 
31
5
  void cli.runExit(process.argv.slice(2))