@napi-rs/cli 3.0.0-alpha.5 → 3.0.0-alpha.50

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 (178) hide show
  1. package/dist/api/artifacts.js +32 -8
  2. package/dist/api/artifacts.js.map +1 -0
  3. package/dist/api/build.d.ts +1 -1
  4. package/dist/api/build.js +249 -25
  5. package/dist/api/build.js.map +1 -0
  6. package/dist/api/create-npm-dirs.js +46 -8
  7. package/dist/api/create-npm-dirs.js.map +1 -0
  8. package/dist/api/new.js +58 -20
  9. package/dist/api/new.js.map +1 -0
  10. package/dist/api/pre-publish.js +10 -7
  11. package/dist/api/pre-publish.js.map +1 -0
  12. package/dist/api/rename.js +10 -1
  13. package/dist/api/rename.js.map +1 -0
  14. package/dist/api/templates/.gitignore.d.ts +1 -1
  15. package/dist/api/templates/.gitignore.js +2 -0
  16. package/dist/api/templates/.gitignore.js.map +1 -0
  17. package/dist/api/templates/.npmignore.js +1 -0
  18. package/dist/api/templates/.npmignore.js.map +1 -0
  19. package/dist/api/templates/build.rs.js +1 -0
  20. package/dist/api/templates/build.rs.js.map +1 -0
  21. package/dist/api/templates/cargo.toml.js +1 -0
  22. package/dist/api/templates/cargo.toml.js.map +1 -0
  23. package/dist/api/templates/ci-template.d.ts +3 -1
  24. package/dist/api/templates/ci-template.js +167 -150
  25. package/dist/api/templates/ci-template.js.map +1 -0
  26. package/dist/api/templates/ci.yml.d.ts +3 -1
  27. package/dist/api/templates/ci.yml.js +13 -2
  28. package/dist/api/templates/ci.yml.js.map +1 -0
  29. package/dist/api/templates/index.js +1 -0
  30. package/dist/api/templates/index.js.map +1 -0
  31. package/dist/api/templates/js-binding.js +150 -225
  32. package/dist/api/templates/js-binding.js.map +1 -0
  33. package/dist/api/templates/lib.rs.js +2 -4
  34. package/dist/api/templates/lib.rs.js.map +1 -0
  35. package/dist/api/templates/load-wasi-template.d.ts +2 -0
  36. package/dist/api/templates/load-wasi-template.js +146 -0
  37. package/dist/api/templates/load-wasi-template.js.map +1 -0
  38. package/dist/api/templates/package.json.d.ts +9 -2
  39. package/dist/api/templates/package.json.js +27 -4
  40. package/dist/api/templates/package.json.js.map +1 -0
  41. package/dist/api/templates/wasi-worker-template.d.ts +2 -0
  42. package/dist/api/templates/wasi-worker-template.js +103 -0
  43. package/dist/api/templates/wasi-worker-template.js.map +1 -0
  44. package/dist/api/universalize.js +6 -5
  45. package/dist/api/universalize.js.map +1 -0
  46. package/dist/api/version.js +3 -2
  47. package/dist/api/version.js.map +1 -0
  48. package/dist/cli.js +1 -0
  49. package/dist/cli.js.map +1 -0
  50. package/dist/commands/artifacts.js +3 -2
  51. package/dist/commands/artifacts.js.map +1 -0
  52. package/dist/commands/build.js +2 -1
  53. package/dist/commands/build.js.map +1 -0
  54. package/dist/commands/create-npm-dirs.js +1 -0
  55. package/dist/commands/create-npm-dirs.js.map +1 -0
  56. package/dist/commands/help.js +1 -0
  57. package/dist/commands/help.js.map +1 -0
  58. package/dist/commands/new.js +17 -6
  59. package/dist/commands/new.js.map +1 -0
  60. package/dist/commands/pre-publish.js +1 -0
  61. package/dist/commands/pre-publish.js.map +1 -0
  62. package/dist/commands/rename.js +1 -0
  63. package/dist/commands/rename.js.map +1 -0
  64. package/dist/commands/universalize.js +1 -0
  65. package/dist/commands/universalize.js.map +1 -0
  66. package/dist/commands/version.js +1 -0
  67. package/dist/commands/version.js.map +1 -0
  68. package/dist/def/artifacts.d.ts +21 -1
  69. package/dist/def/artifacts.js +11 -2
  70. package/dist/def/artifacts.js.map +1 -0
  71. package/dist/def/build.d.ts +20 -2
  72. package/dist/def/build.js +15 -2
  73. package/dist/def/build.js.map +1 -0
  74. package/dist/def/create-npm-dirs.d.ts +10 -0
  75. package/dist/def/create-npm-dirs.js +5 -0
  76. package/dist/def/create-npm-dirs.js.map +1 -0
  77. package/dist/def/new.d.ts +24 -6
  78. package/dist/def/new.js +12 -1
  79. package/dist/def/new.js.map +1 -0
  80. package/dist/def/pre-publish.d.ts +10 -0
  81. package/dist/def/pre-publish.js +8 -3
  82. package/dist/def/pre-publish.js.map +1 -0
  83. package/dist/def/rename.d.ts +11 -1
  84. package/dist/def/rename.js +6 -1
  85. package/dist/def/rename.js.map +1 -0
  86. package/dist/def/universalize.d.ts +10 -0
  87. package/dist/def/universalize.js +5 -0
  88. package/dist/def/universalize.js.map +1 -0
  89. package/dist/def/version.d.ts +10 -0
  90. package/dist/def/version.js +5 -0
  91. package/dist/def/version.js.map +1 -0
  92. package/dist/index.cjs +3918 -715
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +2 -0
  95. package/dist/index.js.map +1 -0
  96. package/dist/utils/__tests__/config.spec.d.ts +1 -0
  97. package/dist/utils/__tests__/config.spec.js +63 -0
  98. package/dist/utils/__tests__/config.spec.js.map +1 -0
  99. package/dist/utils/__tests__/target.spec.js +1 -0
  100. package/dist/utils/__tests__/target.spec.js.map +1 -0
  101. package/dist/utils/__tests__/typegen.spec.js +9 -4
  102. package/dist/utils/__tests__/typegen.spec.js.map +1 -0
  103. package/dist/utils/__tests__/version.spec.js +1 -0
  104. package/dist/utils/__tests__/version.spec.js.map +1 -0
  105. package/dist/utils/cargo.js +2 -1
  106. package/dist/utils/cargo.js.map +1 -0
  107. package/dist/utils/config.d.ts +40 -5
  108. package/dist/utils/config.js +39 -6
  109. package/dist/utils/config.js.map +1 -0
  110. package/dist/utils/index.d.ts +0 -1
  111. package/dist/utils/index.js +1 -1
  112. package/dist/utils/index.js.map +1 -0
  113. package/dist/utils/log.js +1 -0
  114. package/dist/utils/log.js.map +1 -0
  115. package/dist/utils/metadata.js +3 -2
  116. package/dist/utils/metadata.js.map +1 -0
  117. package/dist/utils/misc.d.ts +1 -1
  118. package/dist/utils/misc.js +4 -3
  119. package/dist/utils/misc.js.map +1 -0
  120. package/dist/utils/target.d.ts +9 -5
  121. package/dist/utils/target.js +25 -1
  122. package/dist/utils/target.js.map +1 -0
  123. package/dist/utils/typegen.d.ts +1 -1
  124. package/dist/utils/typegen.js +8 -6
  125. package/dist/utils/typegen.js.map +1 -0
  126. package/dist/utils/version.d.ts +2 -1
  127. package/dist/utils/version.js +11 -8
  128. package/dist/utils/version.js.map +1 -0
  129. package/package.json +46 -13
  130. package/src/api/artifacts.ts +83 -8
  131. package/src/api/build.ts +416 -27
  132. package/src/api/create-npm-dirs.ts +56 -8
  133. package/src/api/new.ts +82 -31
  134. package/src/api/pre-publish.ts +13 -7
  135. package/src/api/rename.ts +10 -1
  136. package/src/api/templates/.gitignore.ts +1 -0
  137. package/src/api/templates/ci-template.ts +176 -150
  138. package/src/api/templates/ci.yml.ts +16 -3
  139. package/src/api/templates/js-binding.ts +150 -225
  140. package/src/api/templates/lib.rs.ts +1 -4
  141. package/src/api/templates/load-wasi-template.ts +157 -0
  142. package/src/api/templates/package.json.ts +47 -5
  143. package/src/api/templates/wasi-worker-template.ts +103 -0
  144. package/src/api/universalize.ts +8 -5
  145. package/src/api/version.ts +5 -2
  146. package/src/commands/artifacts.ts +2 -2
  147. package/src/commands/build.ts +1 -1
  148. package/src/commands/new.ts +16 -6
  149. package/src/def/artifacts.ts +22 -3
  150. package/src/def/build.ts +32 -4
  151. package/src/def/create-npm-dirs.ts +9 -0
  152. package/src/def/new.ts +28 -3
  153. package/src/def/pre-publish.ts +12 -3
  154. package/src/def/rename.ts +11 -2
  155. package/src/def/universalize.ts +9 -0
  156. package/src/def/version.ts +9 -0
  157. package/src/index.ts +2 -0
  158. package/src/utils/__tests__/__snapshots__/config.spec.ts.md +97 -0
  159. package/src/utils/__tests__/__snapshots__/config.spec.ts.snap +0 -0
  160. package/src/utils/__tests__/__snapshots__/target.spec.ts.md +28 -0
  161. package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
  162. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +555 -0
  163. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
  164. package/src/utils/__tests__/__snapshots__/version.spec.ts.md +8 -7
  165. package/src/utils/__tests__/__snapshots__/version.spec.ts.snap +0 -0
  166. package/src/utils/__tests__/config.spec.ts +81 -0
  167. package/src/utils/__tests__/typegen.spec.ts +18 -3
  168. package/src/utils/cargo.ts +1 -1
  169. package/src/utils/config.ts +104 -12
  170. package/src/utils/index.ts +0 -1
  171. package/src/utils/metadata.ts +2 -2
  172. package/src/utils/misc.ts +11 -3
  173. package/src/utils/target.ts +34 -7
  174. package/src/utils/typegen.ts +11 -5
  175. package/src/utils/version.ts +10 -8
  176. package/dist/utils/ci.d.ts +0 -11
  177. package/dist/utils/ci.js +0 -95
  178. package/src/utils/ci.ts +0 -111
@@ -2,11 +2,12 @@ import { load, dump } from 'js-yaml'
2
2
 
3
3
  import {
4
4
  NodeArchToCpu,
5
+ type SupportedPackageManager,
5
6
  UniArchsByPlatform,
6
7
  parseTriple,
7
8
  } from '../../utils/index.js'
8
9
 
9
- import { YAML } from './ci-template.js'
10
+ import { type WasiTargetName, YAML } from './ci-template.js'
10
11
 
11
12
  const BUILD_FREEBSD = 'build-freebsd'
12
13
  const TEST_MACOS_WINDOWS = 'test-macOS-windows-binding'
@@ -15,11 +16,13 @@ const TEST_LINUX_X64_MUSL = 'test-linux-x64-musl-binding'
15
16
  const TEST_LINUX_AARCH64_GNU = 'test-linux-aarch64-gnu-binding'
16
17
  const TEST_LINUX_AARCH64_MUSL = 'test-linux-aarch64-musl-binding'
17
18
  const TEST_LINUX_ARM_GNUEABIHF = 'test-linux-arm-gnueabihf-binding'
19
+ const TEST_WASI = 'test-wasi-nodejs'
18
20
  const UNIVERSAL_MACOS = 'universal-macOS'
19
21
 
20
22
  export const createGithubActionsCIYml = (
21
- binaryName: string,
22
23
  targets: string[],
24
+ packageManager: SupportedPackageManager,
25
+ wasiTargetName?: WasiTargetName,
23
26
  ) => {
24
27
  const allTargets = new Set(
25
28
  targets.flatMap((t) => {
@@ -34,7 +37,7 @@ export const createGithubActionsCIYml = (
34
37
  }),
35
38
  )
36
39
 
37
- const fullTemplate = load(YAML()) as any
40
+ const fullTemplate = load(YAML(packageManager, wasiTargetName)) as any
38
41
 
39
42
  const requiredSteps = []
40
43
  const enableWindowsX86 = allTargets.has('x86_64-pc-windows-msvc')
@@ -46,6 +49,10 @@ export const createGithubActionsCIYml = (
46
49
  const enableLinuxArm7 = allTargets.has('armv7-unknown-linux-gnueabihf')
47
50
  const enableFreeBSD = allTargets.has('x86_64-unknown-freebsd')
48
51
  const enableMacOSUni = allTargets.has('universal-apple-darwin')
52
+ const enableWasi =
53
+ allTargets.has('wasm32-wasi-preview1-threads') ||
54
+ allTargets.has('wasm32-wasip1-threads') ||
55
+ allTargets.has('wasm32-wasip2')
49
56
  fullTemplate.jobs.build.strategy.matrix.settings =
50
57
  fullTemplate.jobs.build.strategy.matrix.settings.filter(
51
58
  ({ target }: { target: string }) => allTargets.has(target),
@@ -114,6 +121,12 @@ export const createGithubActionsCIYml = (
114
121
  requiredSteps.push(UNIVERSAL_MACOS)
115
122
  }
116
123
 
124
+ if (!enableWasi) {
125
+ delete fullTemplate.jobs[TEST_WASI]
126
+ } else {
127
+ requiredSteps.push(TEST_WASI)
128
+ }
129
+
117
130
  fullTemplate.jobs.publish.needs = requiredSteps
118
131
 
119
132
  return dump(fullTemplate, {
@@ -3,260 +3,185 @@ export function createCjsBinding(
3
3
  pkgName: string,
4
4
  idents: string[],
5
5
  ): string {
6
+ function requireTuple(tuple: string) {
7
+ return `try {
8
+ return require('./${localName}.${tuple}.node')
9
+ } catch (e) {
10
+ loadErrors.push(e)
11
+ }
12
+ try {
13
+ return require('${pkgName}-${tuple}')
14
+ } catch (e) {
15
+ loadErrors.push(e)
16
+ }
17
+ `
18
+ }
19
+
6
20
  return `// prettier-ignore
7
21
  /* eslint-disable */
8
22
  /* auto-generated by NAPI-RS */
9
23
 
10
- const { existsSync, readFileSync } = require('fs')
11
- const { join } = require('path')
12
-
13
- const { platform, arch } = process
24
+ const { readFileSync } = require('fs')
14
25
 
15
26
  let nativeBinding = null
16
- let localFileExisted = false
17
- let loadError = null
27
+ const loadErrors = []
18
28
 
19
- function isMusl() {
20
- // For Node 10
21
- if (!process.report || typeof process.report.getReport !== 'function') {
22
- try {
23
- const lddPath = require('child_process').execSync('which ldd').toString().trim()
24
- return readFileSync(lddPath, 'utf8').includes('musl')
25
- } catch (e) {
29
+ const isMusl = () => {
30
+ let musl = false
31
+ if (process.platform === 'linux') {
32
+ musl = isMuslFromFilesystem()
33
+ if (musl === null) {
34
+ musl = isMuslFromReport()
35
+ }
36
+ if (musl === null) {
37
+ musl = isMuslFromChildProcess()
38
+ }
39
+ }
40
+ return musl
41
+ }
42
+
43
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
44
+
45
+ const isMuslFromFilesystem = () => {
46
+ try {
47
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
48
+ } catch {
49
+ return null
50
+ }
51
+ }
52
+
53
+ const isMuslFromReport = () => {
54
+ const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null
55
+ if (!report) {
56
+ return null
57
+ }
58
+ if (report.header && report.header.glibcVersionRuntime) {
59
+ return false
60
+ }
61
+ if (Array.isArray(report.sharedObjects)) {
62
+ if (report.sharedObjects.some(isFileMusl)) {
26
63
  return true
27
64
  }
28
- } else {
29
- const { glibcVersionRuntime } = process.report.getReport().header
30
- return !glibcVersionRuntime
65
+ }
66
+ return false
67
+ }
68
+
69
+ const isMuslFromChildProcess = () => {
70
+ try {
71
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
72
+ } catch (e) {
73
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
74
+ return false
31
75
  }
32
76
  }
33
77
 
34
- switch (platform) {
35
- case 'android':
36
- switch (arch) {
37
- case 'arm64':
38
- localFileExisted = existsSync(join(__dirname, '${localName}.android-arm64.node'))
39
- try {
40
- if (localFileExisted) {
41
- nativeBinding = require('./${localName}.android-arm64.node')
42
- } else {
43
- nativeBinding = require('${pkgName}-android-arm64')
44
- }
45
- } catch (e) {
46
- loadError = e
47
- }
48
- break
49
- case 'arm':
50
- localFileExisted = existsSync(join(__dirname, '${localName}.android-arm-eabi.node'))
51
- try {
52
- if (localFileExisted) {
53
- nativeBinding = require('./${localName}.android-arm-eabi.node')
54
- } else {
55
- nativeBinding = require('${pkgName}-android-arm-eabi')
56
- }
57
- } catch (e) {
58
- loadError = e
59
- }
60
- break
61
- default:
62
- throw new Error(\`Unsupported architecture on Android \${arch}\`)
78
+ function requireNative() {
79
+ if (process.platform === 'android') {
80
+ if (process.arch === 'arm64') {
81
+ ${requireTuple('android-arm64')}
82
+ } else if (process.arch === 'arm') {
83
+ ${requireTuple('android-arm-eabi')}
84
+ } else {
85
+ loadErrors.push(new Error(\`Unsupported architecture on Android \${process.arch}\`))
63
86
  }
64
- break
65
- case 'win32':
66
- switch (arch) {
67
- case 'x64':
68
- localFileExisted = existsSync(
69
- join(__dirname, '${localName}.win32-x64-msvc.node')
70
- )
71
- try {
72
- if (localFileExisted) {
73
- nativeBinding = require('./${localName}.win32-x64-msvc.node')
74
- } else {
75
- nativeBinding = require('${pkgName}-win32-x64-msvc')
76
- }
77
- } catch (e) {
78
- loadError = e
79
- }
80
- break
81
- case 'ia32':
82
- localFileExisted = existsSync(
83
- join(__dirname, '${localName}.win32-ia32-msvc.node')
84
- )
85
- try {
86
- if (localFileExisted) {
87
- nativeBinding = require('./${localName}.win32-ia32-msvc.node')
88
- } else {
89
- nativeBinding = require('${pkgName}-win32-ia32-msvc')
90
- }
91
- } catch (e) {
92
- loadError = e
93
- }
94
- break
95
- case 'arm64':
96
- localFileExisted = existsSync(
97
- join(__dirname, '${localName}.win32-arm64-msvc.node')
98
- )
99
- try {
100
- if (localFileExisted) {
101
- nativeBinding = require('./${localName}.win32-arm64-msvc.node')
102
- } else {
103
- nativeBinding = require('${pkgName}-win32-arm64-msvc')
104
- }
105
- } catch (e) {
106
- loadError = e
107
- }
108
- break
109
- default:
110
- throw new Error(\`Unsupported architecture on Windows: \${arch}\`)
87
+ } else if (process.platform === 'win32') {
88
+ if (process.arch === 'x64') {
89
+ ${requireTuple('win32-x64-msvc')}
90
+ } else if (process.arch === 'ia32') {
91
+ ${requireTuple('win32-ia32-msvc')}
92
+ } else if (process.arch === 'arm64') {
93
+ ${requireTuple('win32-arm64-msvc')}
94
+ } else {
95
+ loadErrors.push(new Error(\`Unsupported architecture on Windows: \${process.arch}\`))
111
96
  }
112
- break
113
- case 'darwin':
114
- localFileExisted = existsSync(join(__dirname, '${localName}.darwin-universal.node'))
115
- try {
116
- if (localFileExisted) {
117
- nativeBinding = require('./${localName}.darwin-universal.node')
97
+ } else if (process.platform === 'darwin') {
98
+ ${requireTuple('darwin-universal')}
99
+ if (process.arch === 'x64') {
100
+ ${requireTuple('darwin-x64')}
101
+ } else if (process.arch === 'arm64') {
102
+ ${requireTuple('darwin-arm64')}
103
+ } else {
104
+ loadErrors.push(new Error(\`Unsupported architecture on macOS: \${process.arch}\`))
105
+ }
106
+ } else if (process.platform === 'freebsd') {
107
+ if (process.arch === 'x64') {
108
+ ${requireTuple('freebsd-x64')}
109
+ } else if (process.arch === 'arm64') {
110
+ ${requireTuple('freebsd-arm64')}
111
+ } else {
112
+ loadErrors.push(new Error(\`Unsupported architecture on FreeBSD: \${process.arch}\`))
113
+ }
114
+ } else if (process.platform === 'linux') {
115
+ if (process.arch === 'x64') {
116
+ if (isMusl()) {
117
+ ${requireTuple('linux-x64-musl')}
118
+ } else {
119
+ ${requireTuple('linux-x64-gnu')}
120
+ }
121
+ } else if (process.arch === 'arm64') {
122
+ if (isMusl()) {
123
+ ${requireTuple('linux-arm64-musl')}
124
+ } else {
125
+ ${requireTuple('linux-arm64-gnu')}
126
+ }
127
+ } else if (process.arch === 'arm') {
128
+ if (isMusl()) {
129
+ ${requireTuple('linux-arm-musleabihf')}
130
+ } else {
131
+ ${requireTuple('linux-arm-gnueabihf')}
132
+ }
133
+ } else if (process.arch === 'riscv64') {
134
+ if (isMusl()) {
135
+ ${requireTuple('linux-riscv64-musl')}
118
136
  } else {
119
- nativeBinding = require('${pkgName}-darwin-universal')
137
+ ${requireTuple('linux-riscv64-gnu')}
120
138
  }
121
- break
122
- } catch {}
123
- switch (arch) {
124
- case 'x64':
125
- localFileExisted = existsSync(join(__dirname, '${localName}.darwin-x64.node'))
126
- try {
127
- if (localFileExisted) {
128
- nativeBinding = require('./${localName}.darwin-x64.node')
129
- } else {
130
- nativeBinding = require('${pkgName}-darwin-x64')
131
- }
132
- } catch (e) {
133
- loadError = e
134
- }
135
- break
136
- case 'arm64':
137
- localFileExisted = existsSync(
138
- join(__dirname, '${localName}.darwin-arm64.node')
139
- )
140
- try {
141
- if (localFileExisted) {
142
- nativeBinding = require('./${localName}.darwin-arm64.node')
143
- } else {
144
- nativeBinding = require('${pkgName}-darwin-arm64')
145
- }
146
- } catch (e) {
147
- loadError = e
148
- }
149
- break
150
- default:
151
- throw new Error(\`Unsupported architecture on macOS: \${arch}\`)
139
+ } else if (process.arch === 'ppc64') {
140
+ ${requireTuple('linux-ppc64-gnu')}
141
+ } else if (process.arch === 's390x') {
142
+ ${requireTuple('linux-s390x-gnu')}
143
+ } else {
144
+ loadErrors.push(new Error(\`Unsupported architecture on Linux: \${process.arch}\`))
152
145
  }
153
- break
154
- case 'freebsd':
155
- if (arch !== 'x64') {
156
- throw new Error(\`Unsupported architecture on FreeBSD: \${arch}\`)
146
+ } else {
147
+ loadErrors.push(new Error(\`Unsupported OS: \${process.platform}, architecture: \${process.arch}\`))
148
+ }
149
+ }
150
+
151
+ nativeBinding = requireNative()
152
+
153
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
154
+ try {
155
+ nativeBinding = require('./${localName}.wasi.cjs')
156
+ } catch (err) {
157
+ if (process.env.NAPI_RS_FORCE_WASI) {
158
+ console.error(err)
157
159
  }
158
- localFileExisted = existsSync(join(__dirname, '${localName}.freebsd-x64.node'))
160
+ }
161
+ if (!nativeBinding) {
159
162
  try {
160
- if (localFileExisted) {
161
- nativeBinding = require('./${localName}.freebsd-x64.node')
162
- } else {
163
- nativeBinding = require('${pkgName}-freebsd-x64')
163
+ nativeBinding = require('${pkgName}-wasm32-wasi')
164
+ } catch (err) {
165
+ if (process.env.NAPI_RS_FORCE_WASI) {
166
+ console.error(err)
164
167
  }
165
- } catch (e) {
166
- loadError = e
167
168
  }
168
- break
169
- case 'linux':
170
- switch (arch) {
171
- case 'x64':
172
- if (isMusl()) {
173
- localFileExisted = existsSync(
174
- join(__dirname, '${localName}.linux-x64-musl.node')
175
- )
176
- try {
177
- if (localFileExisted) {
178
- nativeBinding = require('./${localName}.linux-x64-musl.node')
179
- } else {
180
- nativeBinding = require('${pkgName}-linux-x64-musl')
181
- }
182
- } catch (e) {
183
- loadError = e
184
- }
185
- } else {
186
- localFileExisted = existsSync(
187
- join(__dirname, '${localName}.linux-x64-gnu.node')
188
- )
189
- try {
190
- if (localFileExisted) {
191
- nativeBinding = require('./${localName}.linux-x64-gnu.node')
192
- } else {
193
- nativeBinding = require('${pkgName}-linux-x64-gnu')
194
- }
195
- } catch (e) {
196
- loadError = e
197
- }
198
- }
199
- break
200
- case 'arm64':
201
- if (isMusl()) {
202
- localFileExisted = existsSync(
203
- join(__dirname, '${localName}.linux-arm64-musl.node')
204
- )
205
- try {
206
- if (localFileExisted) {
207
- nativeBinding = require('./${localName}.linux-arm64-musl.node')
208
- } else {
209
- nativeBinding = require('${pkgName}-linux-arm64-musl')
210
- }
211
- } catch (e) {
212
- loadError = e
213
- }
214
- } else {
215
- localFileExisted = existsSync(
216
- join(__dirname, '${localName}.linux-arm64-gnu.node')
217
- )
218
- try {
219
- if (localFileExisted) {
220
- nativeBinding = require('./${localName}.linux-arm64-gnu.node')
221
- } else {
222
- nativeBinding = require('${pkgName}-linux-arm64-gnu')
223
- }
224
- } catch (e) {
225
- loadError = e
226
- }
227
- }
228
- break
229
- case 'arm':
230
- localFileExisted = existsSync(
231
- join(__dirname, '${localName}.linux-arm-gnueabihf.node')
232
- )
233
- try {
234
- if (localFileExisted) {
235
- nativeBinding = require('./${localName}.linux-arm-gnueabihf.node')
236
- } else {
237
- nativeBinding = require('${pkgName}-linux-arm-gnueabihf')
238
- }
239
- } catch (e) {
240
- loadError = e
241
- }
242
- break
243
- default:
244
- throw new Error(\`Unsupported architecture on Linux: \${arch}\`)
245
- }
246
- break
247
- default:
248
- throw new Error(\`Unsupported OS: \${platform}, architecture: \${arch}\`)
169
+ }
249
170
  }
250
171
 
251
172
  if (!nativeBinding) {
252
- if (loadError) {
253
- throw loadError
173
+ if (loadErrors.length > 0) {
174
+ // TODO Link to documentation with potential fixes
175
+ // - The package owner could build/publish bindings for this arch
176
+ // - The user may need to bundle the correct files
177
+ // - The user may need to re-install node_modules to get new packages
178
+ throw new Error('Failed to load native binding', { cause: loadErrors })
254
179
  }
255
180
  throw new Error(\`Failed to load native binding\`)
256
181
  }
257
182
 
258
183
  ${idents
259
- .map((ident) => `module.exports.${ident} = binding.${ident}`)
184
+ .map((ident) => `module.exports.${ident} = nativeBinding.${ident}`)
260
185
  .join('\n')}
261
186
  `
262
187
  }
@@ -1,7 +1,4 @@
1
- export const createLibRs = () => `#![deny(clippy::all)]
2
-
3
- #[macro_use]
4
- extern crate napi_derive;
1
+ export const createLibRs = () => `use napi_derive::napi;
5
2
 
6
3
  #[napi]
7
4
  pub fn sum(a: i32, b: i32) -> i32 {
@@ -0,0 +1,157 @@
1
+ export const createWasiBrowserBinding = (
2
+ wasiFilename: string,
3
+ wasiRegisterFunctions: string[],
4
+ initialMemory = 4000,
5
+ maximumMemory = 65536,
6
+ ) => `import {
7
+ instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync,
8
+ getDefaultContext as __emnapiGetDefaultContext,
9
+ WASI as __WASI,
10
+ } from '@napi-rs/wasm-runtime'
11
+ import { Volume as __Volume, createFsFromVolume as __createFsFromVolume } from '@napi-rs/wasm-runtime/fs'
12
+
13
+ import __wasmUrl from './${wasiFilename}.wasm?url'
14
+
15
+ const __fs = __createFsFromVolume(
16
+ __Volume.fromJSON({
17
+ '/': null,
18
+ }),
19
+ )
20
+
21
+ const __wasi = new __WASI({
22
+ version: 'preview1',
23
+ fs: __fs,
24
+ })
25
+
26
+ const __emnapiContext = __emnapiGetDefaultContext()
27
+
28
+ const __sharedMemory = new WebAssembly.Memory({
29
+ initial: ${initialMemory},
30
+ maximum: ${maximumMemory},
31
+ shared: true,
32
+ })
33
+
34
+ const __wasmFile = await fetch(__wasmUrl).then((res) => res.arrayBuffer())
35
+
36
+ const {
37
+ instance: __napiInstance,
38
+ module: __wasiModule,
39
+ napiModule: __napiModule,
40
+ } = __emnapiInstantiateNapiModuleSync(__wasmFile, {
41
+ context: __emnapiContext,
42
+ asyncWorkPoolSize: 4,
43
+ wasi: __wasi,
44
+ onCreateWorker() {
45
+ return new Worker(new URL('./wasi-worker-browser.mjs', import.meta.url), {
46
+ type: 'module',
47
+ })
48
+ },
49
+ overwriteImports(importObject) {
50
+ importObject.env = {
51
+ ...importObject.env,
52
+ ...importObject.napi,
53
+ ...importObject.emnapi,
54
+ memory: __sharedMemory,
55
+ }
56
+ return importObject
57
+ },
58
+ beforeInit({ instance }) {
59
+ __napi_rs_initialize_modules(instance)
60
+ },
61
+ })
62
+
63
+ function __napi_rs_initialize_modules(__napiInstance) {
64
+ ${wasiRegisterFunctions
65
+ .map((name) => ` __napiInstance.exports['${name}']?.()`)
66
+ .join('\n')}
67
+ }
68
+ `
69
+
70
+ export const createWasiBinding = (
71
+ wasmFileName: string,
72
+ packageName: string,
73
+ wasiRegisterFunctions: string[],
74
+ initialMemory = 4000,
75
+ maximumMemory = 65536,
76
+ ) => `/* eslint-disable */
77
+ /* prettier-ignore */
78
+
79
+ /* auto-generated by NAPI-RS */
80
+
81
+ const __nodeFs= require('node:fs')
82
+ const __nodePath = require('node:path')
83
+ const { WASI: __nodeWASI } = require('node:wasi')
84
+ const { Worker } = require('node:worker_threads')
85
+
86
+ const {
87
+ instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync,
88
+ getDefaultContext: __emnapiGetDefaultContext,
89
+ } = require('@napi-rs/wasm-runtime')
90
+
91
+ const __wasi = new __nodeWASI({
92
+ version: 'preview1',
93
+ env: process.env,
94
+ preopens: {
95
+ '/': '/'
96
+ }
97
+ })
98
+
99
+ const __emnapiContext = __emnapiGetDefaultContext()
100
+
101
+ const __sharedMemory = new WebAssembly.Memory({
102
+ initial: ${initialMemory},
103
+ maximum: ${maximumMemory},
104
+ shared: true,
105
+ })
106
+
107
+ let __wasmFilePath = __nodePath.join(__dirname, '${wasmFileName}.wasm')
108
+ const __wasmDebugFilePath = __nodePath.join(__dirname, '${wasmFileName}.debug.wasm')
109
+
110
+ if (__nodeFs.existsSync(__wasmDebugFilePath)) {
111
+ __wasmFilePath = __wasmDebugFilePath
112
+ } else if (!__nodeFs.existsSync(__wasmFilePath)) {
113
+ try {
114
+ __wasmFilePath = __nodePath.resolve('${packageName}-wasm32-wasi')
115
+ } catch {
116
+ throw new Error('Cannot find ${wasmFileName}.wasm file, and ${packageName}-wasm32-wasi package is not installed.')
117
+ }
118
+ }
119
+
120
+ const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule } = __emnapiInstantiateNapiModuleSync(__nodeFs.readFileSync(__wasmFilePath), {
121
+ context: __emnapiContext,
122
+ asyncWorkPoolSize: (function() {
123
+ const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE)
124
+ // NaN > 0 is false
125
+ if (threadsSizeFromEnv > 0) {
126
+ return threadsSizeFromEnv
127
+ } else {
128
+ return 4
129
+ }
130
+ })(),
131
+ wasi: __wasi,
132
+ onCreateWorker() {
133
+ return new Worker(__nodePath.join(__dirname, 'wasi-worker.mjs'), {
134
+ env: process.env,
135
+ execArgv: ['--experimental-wasi-unstable-preview1'],
136
+ })
137
+ },
138
+ overwriteImports(importObject) {
139
+ importObject.env = {
140
+ ...importObject.env,
141
+ ...importObject.napi,
142
+ ...importObject.emnapi,
143
+ memory: __sharedMemory,
144
+ }
145
+ return importObject
146
+ },
147
+ beforeInit({ instance }) {
148
+ __napi_rs_initialize_modules(instance)
149
+ }
150
+ })
151
+
152
+ function __napi_rs_initialize_modules(__napiInstance) {
153
+ ${wasiRegisterFunctions
154
+ .map((name) => ` __napiInstance.exports['${name}']?.()`)
155
+ .join('\n')}
156
+ }
157
+ `