@napi-rs/cli 3.0.0-alpha.1 → 3.0.0-alpha.100

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 (176) hide show
  1. package/cli.mjs +1 -1
  2. package/dist/api/__tests__/create-npm-dirs.spec.d.ts +1 -0
  3. package/dist/api/__tests__/new.spec.d.ts +1 -0
  4. package/dist/api/build.d.ts +2 -2
  5. package/dist/api/create-npm-dirs.d.ts +5 -0
  6. package/dist/api/templates/index.d.ts +0 -7
  7. package/dist/api/templates/js-binding.d.ts +2 -1
  8. package/dist/api/templates/load-wasi-template.d.ts +2 -0
  9. package/dist/api/templates/wasi-worker-template.d.ts +2 -0
  10. package/dist/cli.js +3961 -14
  11. package/dist/def/artifacts.d.ts +21 -1
  12. package/dist/def/build.d.ts +167 -4
  13. package/dist/def/create-npm-dirs.d.ts +10 -0
  14. package/dist/def/new.d.ts +25 -7
  15. package/dist/def/pre-publish.d.ts +21 -2
  16. package/dist/def/rename.d.ts +16 -6
  17. package/dist/def/universalize.d.ts +10 -0
  18. package/dist/def/version.d.ts +10 -0
  19. package/dist/index.cjs +10142 -20524
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.js +3711 -29
  22. package/dist/utils/__tests__/config.spec.d.ts +1 -0
  23. package/dist/utils/config.d.ts +70 -6
  24. package/dist/utils/index.d.ts +1 -1
  25. package/dist/utils/metadata.d.ts +13 -1
  26. package/dist/utils/misc.d.ts +3 -3
  27. package/dist/utils/read-config.d.ts +7 -0
  28. package/dist/utils/target.d.ts +9 -6
  29. package/dist/utils/typegen.d.ts +4 -1
  30. package/dist/utils/version.d.ts +2 -1
  31. package/package.json +60 -24
  32. package/src/api/__tests__/create-npm-dirs.spec.ts +210 -0
  33. package/src/api/__tests__/new.spec.ts +429 -0
  34. package/src/api/artifacts.ts +83 -8
  35. package/src/api/build.ts +682 -134
  36. package/src/api/create-npm-dirs.ts +64 -13
  37. package/src/api/new.ts +389 -125
  38. package/src/api/pre-publish.ts +27 -16
  39. package/src/api/rename.ts +103 -17
  40. package/src/api/templates/index.ts +0 -7
  41. package/src/api/templates/js-binding.ts +212 -107
  42. package/src/api/templates/load-wasi-template.ts +216 -0
  43. package/src/api/templates/wasi-worker-template.ts +122 -0
  44. package/src/api/universalize.ts +13 -8
  45. package/src/api/version.ts +5 -2
  46. package/src/commands/artifacts.ts +2 -2
  47. package/src/commands/build.ts +1 -1
  48. package/src/commands/new.ts +46 -49
  49. package/src/def/artifacts.ts +22 -3
  50. package/src/def/build.ts +83 -8
  51. package/src/def/create-npm-dirs.ts +9 -0
  52. package/src/def/new.ts +28 -3
  53. package/src/def/pre-publish.ts +24 -3
  54. package/src/def/rename.ts +11 -2
  55. package/src/def/universalize.ts +9 -0
  56. package/src/def/version.ts +9 -0
  57. package/src/index.ts +2 -0
  58. package/src/utils/__tests__/__fixtures__/napi_type_def +130 -130
  59. package/src/utils/__tests__/__snapshots__/config.spec.ts.md +97 -0
  60. package/src/utils/__tests__/__snapshots__/config.spec.ts.snap +0 -0
  61. package/src/utils/__tests__/__snapshots__/target.spec.ts.md +56 -0
  62. package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
  63. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +703 -164
  64. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
  65. package/src/utils/__tests__/__snapshots__/version.spec.ts.md +9 -8
  66. package/src/utils/__tests__/__snapshots__/version.spec.ts.snap +0 -0
  67. package/src/utils/__tests__/config.spec.ts +81 -0
  68. package/src/utils/__tests__/typegen.spec.ts +19 -4
  69. package/src/utils/cargo.ts +2 -2
  70. package/src/utils/config.ts +147 -13
  71. package/src/utils/index.ts +1 -1
  72. package/src/utils/log.ts +1 -1
  73. package/src/utils/metadata.ts +52 -14
  74. package/src/utils/misc.ts +21 -7
  75. package/src/utils/read-config.ts +20 -0
  76. package/src/utils/target.ts +53 -9
  77. package/src/utils/typegen.ts +100 -40
  78. package/src/utils/version.ts +11 -9
  79. package/dist/api/artifacts.js +0 -50
  80. package/dist/api/build.js +0 -404
  81. package/dist/api/create-npm-dirs.js +0 -63
  82. package/dist/api/new.js +0 -154
  83. package/dist/api/pre-publish.js +0 -157
  84. package/dist/api/rename.js +0 -28
  85. package/dist/api/templates/.gitignore.d.ts +0 -1
  86. package/dist/api/templates/.gitignore.js +0 -198
  87. package/dist/api/templates/.npmignore.d.ts +0 -1
  88. package/dist/api/templates/.npmignore.js +0 -14
  89. package/dist/api/templates/build.rs.d.ts +0 -1
  90. package/dist/api/templates/build.rs.js +0 -4
  91. package/dist/api/templates/cargo.toml.d.ts +0 -6
  92. package/dist/api/templates/cargo.toml.js +0 -25
  93. package/dist/api/templates/ci-template.d.ts +0 -1
  94. package/dist/api/templates/ci-template.js +0 -566
  95. package/dist/api/templates/ci.yml.d.ts +0 -1
  96. package/dist/api/templates/ci.yml.js +0 -92
  97. package/dist/api/templates/index.js +0 -8
  98. package/dist/api/templates/js-binding.js +0 -124
  99. package/dist/api/templates/lib.rs.d.ts +0 -1
  100. package/dist/api/templates/lib.rs.js +0 -10
  101. package/dist/api/templates/package.json.d.ts +0 -8
  102. package/dist/api/templates/package.json.js +0 -30
  103. package/dist/api/universalize.js +0 -38
  104. package/dist/api/version.js +0 -16
  105. package/dist/commands/artifacts.js +0 -19
  106. package/dist/commands/build.js +0 -34
  107. package/dist/commands/create-npm-dirs.js +0 -7
  108. package/dist/commands/help.js +0 -12
  109. package/dist/commands/new.js +0 -112
  110. package/dist/commands/pre-publish.js +0 -8
  111. package/dist/commands/rename.js +0 -7
  112. package/dist/commands/universalize.js +0 -7
  113. package/dist/commands/version.js +0 -7
  114. package/dist/def/artifacts.js +0 -38
  115. package/dist/def/build.js +0 -105
  116. package/dist/def/commands/artifacts.d.ts +0 -15
  117. package/dist/def/commands/artifacts.js +0 -29
  118. package/dist/def/commands/build.d.ts +0 -53
  119. package/dist/def/commands/build.js +0 -105
  120. package/dist/def/commands/create-npm-dirs.d.ts +0 -15
  121. package/dist/def/commands/create-npm-dirs.js +0 -29
  122. package/dist/def/commands/new.d.ts +0 -27
  123. package/dist/def/commands/new.js +0 -53
  124. package/dist/def/commands/pre-publish.d.ts +0 -23
  125. package/dist/def/commands/pre-publish.js +0 -45
  126. package/dist/def/commands/rename.d.ts +0 -25
  127. package/dist/def/commands/rename.js +0 -49
  128. package/dist/def/commands/universalize.d.ts +0 -13
  129. package/dist/def/commands/universalize.js +0 -25
  130. package/dist/def/commands/version.d.ts +0 -13
  131. package/dist/def/commands/version.js +0 -25
  132. package/dist/def/create-npm-dirs.js +0 -38
  133. package/dist/def/new.js +0 -66
  134. package/dist/def/options/artifacts.d.ts +0 -35
  135. package/dist/def/options/artifacts.js +0 -11
  136. package/dist/def/options/build.d.ts +0 -97
  137. package/dist/def/options/build.js +0 -3
  138. package/dist/def/options/create-npm-dirs.d.ts +0 -35
  139. package/dist/def/options/create-npm-dirs.js +0 -11
  140. package/dist/def/options/new.d.ts +0 -79
  141. package/dist/def/options/new.js +0 -15
  142. package/dist/def/options/pre-publish.d.ts +0 -65
  143. package/dist/def/options/pre-publish.js +0 -13
  144. package/dist/def/options/rename.d.ts +0 -75
  145. package/dist/def/options/rename.js +0 -11
  146. package/dist/def/options/universalize.d.ts +0 -28
  147. package/dist/def/options/universalize.js +0 -10
  148. package/dist/def/options/version.d.ts +0 -28
  149. package/dist/def/options/version.js +0 -10
  150. package/dist/def/pre-publish.js +0 -56
  151. package/dist/def/rename.js +0 -58
  152. package/dist/def/universalize.js +0 -33
  153. package/dist/def/version.js +0 -33
  154. package/dist/utils/__tests__/target.spec.js +0 -10
  155. package/dist/utils/__tests__/typegen.spec.js +0 -37
  156. package/dist/utils/__tests__/version.spec.js +0 -5
  157. package/dist/utils/cargo.js +0 -33
  158. package/dist/utils/ci.d.ts +0 -11
  159. package/dist/utils/ci.js +0 -86
  160. package/dist/utils/config.js +0 -42
  161. package/dist/utils/index.js +0 -9
  162. package/dist/utils/log.js +0 -14
  163. package/dist/utils/metadata.js +0 -19
  164. package/dist/utils/misc.js +0 -35
  165. package/dist/utils/target.js +0 -109
  166. package/dist/utils/typegen.js +0 -158
  167. package/dist/utils/version.js +0 -59
  168. package/src/api/templates/.gitignore.ts +0 -198
  169. package/src/api/templates/.npmignore.ts +0 -14
  170. package/src/api/templates/build.rs.ts +0 -4
  171. package/src/api/templates/cargo.toml.ts +0 -35
  172. package/src/api/templates/ci-template.ts +0 -566
  173. package/src/api/templates/ci.yml.ts +0 -116
  174. package/src/api/templates/lib.rs.ts +0 -10
  175. package/src/api/templates/package.json.ts +0 -44
  176. package/src/utils/ci.ts +0 -102
package/src/api/rename.ts CHANGED
@@ -1,14 +1,19 @@
1
- import { resolve } from 'path'
1
+ import { existsSync } from 'node:fs'
2
+ import { rename } from 'node:fs/promises'
3
+ import { resolve, join } from 'node:path'
2
4
 
5
+ import { parse as parseToml, stringify as stringifyToml } from '@std/toml'
6
+ import { load as yamlParse, dump as yamlStringify } from 'js-yaml'
3
7
  import { isNil, merge, omitBy, pick } from 'lodash-es'
8
+ import { findUp } from 'find-up'
4
9
 
5
10
  import { applyDefaultRenameOptions, RenameOptions } from '../def/rename.js'
6
- import { readFileAsync, writeFileAsync } from '../utils/index.js'
7
-
8
- import { createNpmDirs } from './create-npm-dirs.js'
11
+ import { readConfig, readFileAsync, writeFileAsync } from '../utils/index.js'
9
12
 
10
13
  export async function renameProject(userOptions: RenameOptions) {
11
14
  const options = applyDefaultRenameOptions(userOptions)
15
+ const napiConfig = await readConfig(options)
16
+ const oldName = napiConfig.binaryName
12
17
 
13
18
  const packageJsonPath = resolve(options.cwd, options.packageJsonPath)
14
19
  const cargoTomlPath = resolve(options.cwd, options.manifestPath)
@@ -30,22 +35,103 @@ export async function renameProject(userOptions: RenameOptions) {
30
35
  },
31
36
  )
32
37
 
38
+ if (options.configPath) {
39
+ const configPath = resolve(options.cwd, options.configPath)
40
+ const configContent = await readFileAsync(configPath, 'utf8')
41
+ const configData = JSON.parse(configContent)
42
+ configData.binaryName = options.binaryName
43
+ configData.packageName = options.packageName
44
+ await writeFileAsync(configPath, JSON.stringify(configData, null, 2))
45
+ }
46
+
33
47
  await writeFileAsync(
34
48
  packageJsonPath,
35
49
  JSON.stringify(packageJsonData, null, 2),
36
50
  )
37
51
 
38
- let tomlContent = await readFileAsync(cargoTomlPath, 'utf8')
39
- tomlContent = tomlContent.replace(
40
- /name\s?=\s?"([\w+])"/,
41
- `name = "${options.binaryName}"`,
42
- )
43
- await writeFileAsync(cargoTomlPath, tomlContent)
44
-
45
- await createNpmDirs({
46
- cwd: options.cwd,
47
- packageJsonPath: options.packageJsonPath,
48
- npmDir: options.npmDir,
49
- dryRun: false,
50
- })
52
+ const tomlContent = await readFileAsync(cargoTomlPath, 'utf8')
53
+ const cargoToml = parseToml(tomlContent) as any
54
+
55
+ // Update the package name
56
+ if (cargoToml.package && options.binaryName) {
57
+ // Sanitize the binary name for Rust package naming conventions
58
+ const sanitizedName = options.binaryName
59
+ .replace('@', '')
60
+ .replace('/', '_')
61
+ .replace(/-/g, '_')
62
+ .toLowerCase()
63
+ cargoToml.package.name = sanitizedName
64
+ }
65
+
66
+ // Stringify the updated TOML
67
+ const updatedTomlContent = stringifyToml(cargoToml)
68
+
69
+ await writeFileAsync(cargoTomlPath, updatedTomlContent)
70
+ if (oldName !== options.binaryName) {
71
+ const githubActionsPath = await findUp('.github', {
72
+ cwd: options.cwd,
73
+ type: 'directory',
74
+ })
75
+ if (githubActionsPath) {
76
+ const githubActionsCIYmlPath = join(
77
+ githubActionsPath,
78
+ 'workflows',
79
+ 'CI.yml',
80
+ )
81
+ if (existsSync(githubActionsCIYmlPath)) {
82
+ const githubActionsContent = await readFileAsync(
83
+ githubActionsCIYmlPath,
84
+ 'utf8',
85
+ )
86
+ const githubActionsData = yamlParse(githubActionsContent) as any
87
+ if (githubActionsData.env?.APP_NAME) {
88
+ githubActionsData.env.APP_NAME = options.binaryName
89
+ await writeFileAsync(
90
+ githubActionsCIYmlPath,
91
+ yamlStringify(githubActionsData, {
92
+ lineWidth: -1,
93
+ noRefs: true,
94
+ sortKeys: false,
95
+ }),
96
+ )
97
+ }
98
+ }
99
+ }
100
+ const oldWasiBrowserBindingPath = join(
101
+ options.cwd,
102
+ `${oldName}.wasi-browser.js`,
103
+ )
104
+ if (existsSync(oldWasiBrowserBindingPath)) {
105
+ await rename(
106
+ oldWasiBrowserBindingPath,
107
+ join(options.cwd, `${options.binaryName}.wasi-browser.js`),
108
+ )
109
+ }
110
+ const oldWasiBindingPath = join(options.cwd, `${oldName}.wasi.cjs`)
111
+ if (existsSync(oldWasiBindingPath)) {
112
+ await rename(
113
+ oldWasiBindingPath,
114
+ join(options.cwd, `${options.binaryName}.wasi.cjs`),
115
+ )
116
+ }
117
+ const gitAttributesPath = join(options.cwd, '.gitattributes')
118
+ if (existsSync(gitAttributesPath)) {
119
+ const gitAttributesContent = await readFileAsync(
120
+ gitAttributesPath,
121
+ 'utf8',
122
+ )
123
+ const gitAttributesData = gitAttributesContent
124
+ .split('\n')
125
+ .map((line) => {
126
+ return line
127
+ .replace(
128
+ `${oldName}.wasi-browser.js`,
129
+ `${options.binaryName}.wasi-browser.js`,
130
+ )
131
+ .replace(`${oldName}.wasi.cjs`, `${options.binaryName}.wasi.cjs`)
132
+ })
133
+ .join('\n')
134
+ await writeFileAsync(gitAttributesPath, gitAttributesData)
135
+ }
136
+ }
51
137
  }
@@ -1,8 +1 @@
1
- export * from './.gitignore.js'
2
- export * from './.npmignore.js'
3
- export * from './build.rs.js'
4
- export * from './cargo.toml.js'
5
- export * from './ci.yml.js'
6
- export * from './lib.rs.js'
7
- export * from './package.json.js'
8
1
  export * from './js-binding.js'
@@ -1,130 +1,235 @@
1
- /* eslint-disable @typescript-eslint/switch-exhaustiveness-check */
1
+ export function createCjsBinding(
2
+ localName: string,
3
+ pkgName: string,
4
+ idents: string[],
5
+ ): string {
6
+ return `${bindingHeader}
7
+ const { createRequire } = require('node:module')
8
+ require = createRequire(__filename)
2
9
 
3
- function loadNapiModule(binaryName: string, packageName: string) {
4
- const { existsSync, readFileSync } = require('fs')
5
- const { join } = require('path')
6
- const { platform, arch } = process
10
+ ${createCommonBinding(localName, pkgName)}
11
+ module.exports = nativeBinding
12
+ ${idents
13
+ .map((ident) => `module.exports.${ident} = nativeBinding.${ident}`)
14
+ .join('\n')}
15
+ `
16
+ }
7
17
 
8
- const candidates: string[] = []
18
+ export function createEsmBinding(
19
+ localName: string,
20
+ pkgName: string,
21
+ idents: string[],
22
+ ): string {
23
+ return `${bindingHeader}
24
+ import { createRequire } from 'node:module'
25
+ const require = createRequire(import.meta.url)
26
+ const __dirname = new URL('.', import.meta.url).pathname
9
27
 
10
- function isMusl() {
11
- // For Node 10
12
- if (!process.report || typeof process.report.getReport !== 'function') {
13
- try {
14
- const lddPath = require('child_process')
15
- .execSync('which ldd')
16
- .toString()
17
- .trim()
18
- return readFileSync(lddPath, 'utf8').includes('musl')
19
- } catch (e) {
20
- return true
21
- }
22
- } else {
23
- // @ts-expect-error
24
- const { glibcVersionRuntime } = process.report.getReport().header
25
- return !glibcVersionRuntime
28
+ ${createCommonBinding(localName, pkgName)}
29
+ const { ${idents.join(', ')} } = nativeBinding
30
+ ${idents.map((ident) => `export { ${ident} }`).join('\n')}
31
+ `
32
+ }
33
+
34
+ const bindingHeader = `// prettier-ignore
35
+ /* eslint-disable */
36
+ // @ts-nocheck
37
+ /* auto-generated by NAPI-RS */
38
+ `
39
+
40
+ function createCommonBinding(localName: string, pkgName: string): string {
41
+ function requireTuple(tuple: string, identSize = 8) {
42
+ const identLow = ' '.repeat(identSize - 2)
43
+ const ident = ' '.repeat(identSize)
44
+ return `try {
45
+ ${ident}return require('./${localName}.${tuple}.node')
46
+ ${identLow}} catch (e) {
47
+ ${ident}loadErrors.push(e)
48
+ ${identLow}}
49
+ ${identLow}try {
50
+ ${ident}return require('${pkgName}-${tuple}')
51
+ ${identLow}} catch (e) {
52
+ ${ident}loadErrors.push(e)
53
+ ${identLow}}`
54
+ }
55
+
56
+ return `const { readFileSync } = require('node:fs')
57
+ let nativeBinding = null
58
+ const loadErrors = []
59
+
60
+ const isMusl = () => {
61
+ let musl = false
62
+ if (process.platform === 'linux') {
63
+ musl = isMuslFromFilesystem()
64
+ if (musl === null) {
65
+ musl = isMuslFromReport()
66
+ }
67
+ if (musl === null) {
68
+ musl = isMuslFromChildProcess()
26
69
  }
27
70
  }
71
+ return musl
72
+ }
28
73
 
29
- switch (platform) {
30
- case 'android':
31
- switch (arch) {
32
- case 'arm64':
33
- candidates.push('android-arm64')
34
- break
35
- case 'arm':
36
- candidates.push('android-arm-eabi')
37
- break
38
- }
39
- break
40
- case 'win32':
41
- switch (arch) {
42
- case 'x64':
43
- candidates.push('win32-x64-msvc')
44
- break
45
- case 'ia32':
46
- candidates.push('win32-ia32-msvc')
47
- break
48
- case 'arm64':
49
- candidates.push('win32-arm64-msvc')
50
- break
51
- }
52
- break
53
- case 'darwin':
54
- candidates.push('darwin-universal')
55
- switch (arch) {
56
- case 'x64':
57
- candidates.push('darwin-x64')
58
- break
59
- case 'arm64':
60
- candidates.push('darwin-arm64')
61
- break
62
- }
63
- break
64
- case 'freebsd':
65
- if (arch === 'x64') {
66
- candidates.push('freebsd-x64')
67
- }
68
- break
69
- case 'linux':
70
- switch (arch) {
71
- case 'x64':
72
- if (isMusl()) {
73
- candidates.push('linux-x64-musl')
74
- } else {
75
- candidates.push('linux-x64-gnu')
76
- }
77
- break
78
- case 'arm64':
79
- if (isMusl()) {
80
- candidates.push('linux-arm64-musl')
81
- } else {
82
- candidates.push('linux-arm64-gnu')
83
- }
84
- break
85
- case 'arm':
86
- candidates.push('linux-arm-gnueabihf')
87
- break
88
- }
89
- break
74
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
75
+
76
+ const isMuslFromFilesystem = () => {
77
+ try {
78
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
79
+ } catch {
80
+ return null
90
81
  }
82
+ }
91
83
 
92
- let nativeBinding: any
93
- let loadError: any
84
+ const isMuslFromReport = () => {
85
+ let report = null
86
+ if (typeof process.report?.getReport === 'function') {
87
+ process.report.excludeNetwork = true
88
+ report = process.report.getReport()
89
+ }
90
+ if (!report) {
91
+ return null
92
+ }
93
+ if (report.header && report.header.glibcVersionRuntime) {
94
+ return false
95
+ }
96
+ if (Array.isArray(report.sharedObjects)) {
97
+ if (report.sharedObjects.some(isFileMusl)) {
98
+ return true
99
+ }
100
+ }
101
+ return false
102
+ }
94
103
 
95
- for (const suffix of candidates) {
96
- const localPath = join(__dirname, `${binaryName}.${suffix}.node`)
97
- const pkgPath = `${packageName}-${suffix}`
104
+ const isMuslFromChildProcess = () => {
105
+ try {
106
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
107
+ } catch (e) {
108
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
109
+ return false
110
+ }
111
+ }
98
112
 
113
+ function requireNative() {
114
+ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
99
115
  try {
100
- if (existsSync(localPath)) {
101
- nativeBinding = require(localPath)
116
+ nativeBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
117
+ } catch (err) {
118
+ loadErrors.push(err)
119
+ }
120
+ } else if (process.platform === 'android') {
121
+ if (process.arch === 'arm64') {
122
+ ${requireTuple('android-arm64')}
123
+ } else if (process.arch === 'arm') {
124
+ ${requireTuple('android-arm-eabi')}
125
+ } else {
126
+ loadErrors.push(new Error(\`Unsupported architecture on Android \${process.arch}\`))
127
+ }
128
+ } else if (process.platform === 'win32') {
129
+ if (process.arch === 'x64') {
130
+ ${requireTuple('win32-x64-msvc')}
131
+ } else if (process.arch === 'ia32') {
132
+ ${requireTuple('win32-ia32-msvc')}
133
+ } else if (process.arch === 'arm64') {
134
+ ${requireTuple('win32-arm64-msvc')}
135
+ } else {
136
+ loadErrors.push(new Error(\`Unsupported architecture on Windows: \${process.arch}\`))
137
+ }
138
+ } else if (process.platform === 'darwin') {
139
+ ${requireTuple('darwin-universal', 6)}
140
+ if (process.arch === 'x64') {
141
+ ${requireTuple('darwin-x64')}
142
+ } else if (process.arch === 'arm64') {
143
+ ${requireTuple('darwin-arm64')}
144
+ } else {
145
+ loadErrors.push(new Error(\`Unsupported architecture on macOS: \${process.arch}\`))
146
+ }
147
+ } else if (process.platform === 'freebsd') {
148
+ if (process.arch === 'x64') {
149
+ ${requireTuple('freebsd-x64')}
150
+ } else if (process.arch === 'arm64') {
151
+ ${requireTuple('freebsd-arm64')}
152
+ } else {
153
+ loadErrors.push(new Error(\`Unsupported architecture on FreeBSD: \${process.arch}\`))
154
+ }
155
+ } else if (process.platform === 'linux') {
156
+ if (process.arch === 'x64') {
157
+ if (isMusl()) {
158
+ ${requireTuple('linux-x64-musl', 10)}
102
159
  } else {
103
- nativeBinding = require(pkgPath)
160
+ ${requireTuple('linux-x64-gnu', 10)}
104
161
  }
105
- } catch (e) {
106
- loadError = e
107
- continue
162
+ } else if (process.arch === 'arm64') {
163
+ if (isMusl()) {
164
+ ${requireTuple('linux-arm64-musl', 10)}
165
+ } else {
166
+ ${requireTuple('linux-arm64-gnu', 10)}
167
+ }
168
+ } else if (process.arch === 'arm') {
169
+ if (isMusl()) {
170
+ ${requireTuple('linux-arm-musleabihf', 10)}
171
+ } else {
172
+ ${requireTuple('linux-arm-gnueabihf', 10)}
173
+ }
174
+ } else if (process.arch === 'riscv64') {
175
+ if (isMusl()) {
176
+ ${requireTuple('linux-riscv64-musl', 10)}
177
+ } else {
178
+ ${requireTuple('linux-riscv64-gnu', 10)}
179
+ }
180
+ } else if (process.arch === 'ppc64') {
181
+ ${requireTuple('linux-ppc64-gnu')}
182
+ } else if (process.arch === 's390x') {
183
+ ${requireTuple('linux-s390x-gnu')}
184
+ } else {
185
+ loadErrors.push(new Error(\`Unsupported architecture on Linux: \${process.arch}\`))
108
186
  }
109
-
110
- loadError = null
111
- break
187
+ } else if (process.platform === 'openharmony') {
188
+ if (process.arch === 'arm64') {
189
+ ${requireTuple('linux-arm64-ohos')}
190
+ } else if (process.arch === 'x64') {
191
+ ${requireTuple('linux-x64-ohos')}
192
+ } else if (process.arch === 'arm') {
193
+ ${requireTuple('linux-arm-ohos')}
194
+ } else {
195
+ loadErrors.push(new Error(\`Unsupported architecture on OpenHarmony: \${process.arch}\`))
196
+ }
197
+ } else {
198
+ loadErrors.push(new Error(\`Unsupported OS: \${process.platform}, architecture: \${process.arch}\`))
112
199
  }
200
+ }
113
201
 
202
+ nativeBinding = requireNative()
203
+
204
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
205
+ try {
206
+ nativeBinding = require('./${localName}.wasi.cjs')
207
+ } catch (err) {
208
+ if (process.env.NAPI_RS_FORCE_WASI) {
209
+ loadErrors.push(err)
210
+ }
211
+ }
114
212
  if (!nativeBinding) {
115
- if (loadError) {
116
- throw loadError
213
+ try {
214
+ nativeBinding = require('${pkgName}-wasm32-wasi')
215
+ } catch (err) {
216
+ if (process.env.NAPI_RS_FORCE_WASI) {
217
+ loadErrors.push(err)
218
+ }
117
219
  }
118
-
119
- throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
120
220
  }
121
-
122
- return nativeBinding
123
221
  }
124
222
 
125
- export function createJsBinding(localName: string, pkgName: string): string {
126
- return `${loadNapiModule.toString()}
127
-
128
- module.exports = loadNapiModule('${localName}', '${pkgName}')
223
+ if (!nativeBinding) {
224
+ if (loadErrors.length > 0) {
225
+ throw new Error(
226
+ \`Cannot find native binding. \` +
227
+ \`npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). \` +
228
+ 'Please try \`npm i\` again after removing both package-lock.json and node_modules directory.',
229
+ { cause: loadErrors }
230
+ )
231
+ }
232
+ throw new Error(\`Failed to load native binding\`)
233
+ }
129
234
  `
130
235
  }