@napi-rs/cli 3.0.0-alpha.4 → 3.0.0-alpha.40

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 (177) hide show
  1. package/cli.mjs +0 -0
  2. package/dist/api/artifacts.js +32 -8
  3. package/dist/api/artifacts.js.map +1 -0
  4. package/dist/api/build.d.ts +1 -1
  5. package/dist/api/build.js +231 -30
  6. package/dist/api/build.js.map +1 -0
  7. package/dist/api/create-npm-dirs.js +46 -8
  8. package/dist/api/create-npm-dirs.js.map +1 -0
  9. package/dist/api/new.js +47 -20
  10. package/dist/api/new.js.map +1 -0
  11. package/dist/api/pre-publish.js +10 -7
  12. package/dist/api/pre-publish.js.map +1 -0
  13. package/dist/api/rename.js +10 -1
  14. package/dist/api/rename.js.map +1 -0
  15. package/dist/api/templates/.gitignore.d.ts +1 -1
  16. package/dist/api/templates/.gitignore.js +2 -0
  17. package/dist/api/templates/.gitignore.js.map +1 -0
  18. package/dist/api/templates/.npmignore.js +1 -0
  19. package/dist/api/templates/.npmignore.js.map +1 -0
  20. package/dist/api/templates/build.rs.js +1 -0
  21. package/dist/api/templates/build.rs.js.map +1 -0
  22. package/dist/api/templates/cargo.toml.js +1 -0
  23. package/dist/api/templates/cargo.toml.js.map +1 -0
  24. package/dist/api/templates/ci-template.d.ts +2 -1
  25. package/dist/api/templates/ci-template.js +150 -152
  26. package/dist/api/templates/ci-template.js.map +1 -0
  27. package/dist/api/templates/ci.yml.d.ts +2 -1
  28. package/dist/api/templates/ci.yml.js +19 -4
  29. package/dist/api/templates/ci.yml.js.map +1 -0
  30. package/dist/api/templates/index.js +1 -0
  31. package/dist/api/templates/index.js.map +1 -0
  32. package/dist/api/templates/js-binding.d.ts +1 -1
  33. package/dist/api/templates/js-binding.js +111 -13
  34. package/dist/api/templates/js-binding.js.map +1 -0
  35. package/dist/api/templates/lib.rs.js +2 -4
  36. package/dist/api/templates/lib.rs.js.map +1 -0
  37. package/dist/api/templates/load-wasi-template.d.ts +2 -0
  38. package/dist/api/templates/load-wasi-template.js +143 -0
  39. package/dist/api/templates/load-wasi-template.js.map +1 -0
  40. package/dist/api/templates/package.json.d.ts +9 -2
  41. package/dist/api/templates/package.json.js +53 -28
  42. package/dist/api/templates/package.json.js.map +1 -0
  43. package/dist/api/templates/wasi-worker-template.d.ts +2 -0
  44. package/dist/api/templates/wasi-worker-template.js +93 -0
  45. package/dist/api/templates/wasi-worker-template.js.map +1 -0
  46. package/dist/api/universalize.js +6 -5
  47. package/dist/api/universalize.js.map +1 -0
  48. package/dist/api/version.js +3 -2
  49. package/dist/api/version.js.map +1 -0
  50. package/dist/cli.js +1 -0
  51. package/dist/cli.js.map +1 -0
  52. package/dist/commands/artifacts.js +4 -4
  53. package/dist/commands/artifacts.js.map +1 -0
  54. package/dist/commands/build.js +2 -1
  55. package/dist/commands/build.js.map +1 -0
  56. package/dist/commands/create-npm-dirs.js +1 -0
  57. package/dist/commands/create-npm-dirs.js.map +1 -0
  58. package/dist/commands/help.js +2 -2
  59. package/dist/commands/help.js.map +1 -0
  60. package/dist/commands/new.js +15 -7
  61. package/dist/commands/new.js.map +1 -0
  62. package/dist/commands/pre-publish.js +1 -0
  63. package/dist/commands/pre-publish.js.map +1 -0
  64. package/dist/commands/rename.js +1 -0
  65. package/dist/commands/rename.js.map +1 -0
  66. package/dist/commands/universalize.js +1 -0
  67. package/dist/commands/universalize.js.map +1 -0
  68. package/dist/commands/version.js +1 -0
  69. package/dist/commands/version.js.map +1 -0
  70. package/dist/def/artifacts.d.ts +21 -1
  71. package/dist/def/artifacts.js +12 -4
  72. package/dist/def/artifacts.js.map +1 -0
  73. package/dist/def/build.d.ts +20 -2
  74. package/dist/def/build.js +16 -4
  75. package/dist/def/build.js.map +1 -0
  76. package/dist/def/create-npm-dirs.d.ts +10 -0
  77. package/dist/def/create-npm-dirs.js +6 -2
  78. package/dist/def/create-npm-dirs.js.map +1 -0
  79. package/dist/def/new.d.ts +24 -6
  80. package/dist/def/new.js +13 -3
  81. package/dist/def/new.js.map +1 -0
  82. package/dist/def/pre-publish.d.ts +10 -0
  83. package/dist/def/pre-publish.js +9 -5
  84. package/dist/def/pre-publish.js.map +1 -0
  85. package/dist/def/rename.d.ts +11 -1
  86. package/dist/def/rename.js +7 -3
  87. package/dist/def/rename.js.map +1 -0
  88. package/dist/def/universalize.d.ts +10 -0
  89. package/dist/def/universalize.js +6 -2
  90. package/dist/def/universalize.js.map +1 -0
  91. package/dist/def/version.d.ts +10 -0
  92. package/dist/def/version.js +6 -2
  93. package/dist/def/version.js.map +1 -0
  94. package/dist/index.cjs +5977 -8003
  95. package/dist/index.d.ts +1 -0
  96. package/dist/index.js +2 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/utils/__tests__/config.spec.d.ts +1 -0
  99. package/dist/utils/__tests__/config.spec.js +63 -0
  100. package/dist/utils/__tests__/config.spec.js.map +1 -0
  101. package/dist/utils/__tests__/target.spec.js +1 -0
  102. package/dist/utils/__tests__/target.spec.js.map +1 -0
  103. package/dist/utils/__tests__/typegen.spec.js +9 -4
  104. package/dist/utils/__tests__/typegen.spec.js.map +1 -0
  105. package/dist/utils/__tests__/version.spec.js +1 -0
  106. package/dist/utils/__tests__/version.spec.js.map +1 -0
  107. package/dist/utils/cargo.js +2 -1
  108. package/dist/utils/cargo.js.map +1 -0
  109. package/dist/utils/ci.js +1 -0
  110. package/dist/utils/ci.js.map +1 -0
  111. package/dist/utils/config.d.ts +25 -5
  112. package/dist/utils/config.js +39 -6
  113. package/dist/utils/config.js.map +1 -0
  114. package/dist/utils/index.js +1 -0
  115. package/dist/utils/index.js.map +1 -0
  116. package/dist/utils/log.js +1 -0
  117. package/dist/utils/log.js.map +1 -0
  118. package/dist/utils/metadata.js +3 -2
  119. package/dist/utils/metadata.js.map +1 -0
  120. package/dist/utils/misc.d.ts +1 -1
  121. package/dist/utils/misc.js +4 -3
  122. package/dist/utils/misc.js.map +1 -0
  123. package/dist/utils/target.d.ts +9 -5
  124. package/dist/utils/target.js +16 -1
  125. package/dist/utils/target.js.map +1 -0
  126. package/dist/utils/typegen.d.ts +4 -1
  127. package/dist/utils/typegen.js +27 -6
  128. package/dist/utils/typegen.js.map +1 -0
  129. package/dist/utils/version.d.ts +2 -1
  130. package/dist/utils/version.js +13 -10
  131. package/dist/utils/version.js.map +1 -0
  132. package/package.json +50 -16
  133. package/src/api/artifacts.ts +85 -10
  134. package/src/api/build.ts +381 -32
  135. package/src/api/create-npm-dirs.ts +56 -8
  136. package/src/api/new.ts +69 -33
  137. package/src/api/pre-publish.ts +21 -12
  138. package/src/api/rename.ts +10 -1
  139. package/src/api/templates/.gitignore.ts +1 -0
  140. package/src/api/templates/ci-template.ts +151 -152
  141. package/src/api/templates/ci.yml.ts +19 -4
  142. package/src/api/templates/js-binding.ts +114 -13
  143. package/src/api/templates/lib.rs.ts +1 -4
  144. package/src/api/templates/load-wasi-template.ts +150 -0
  145. package/src/api/templates/package.json.ts +74 -27
  146. package/src/api/templates/wasi-worker-template.ts +93 -0
  147. package/src/api/universalize.ts +8 -5
  148. package/src/api/version.ts +5 -2
  149. package/src/commands/artifacts.ts +2 -2
  150. package/src/commands/build.ts +1 -1
  151. package/src/commands/new.ts +14 -8
  152. package/src/def/artifacts.ts +22 -3
  153. package/src/def/build.ts +32 -4
  154. package/src/def/create-npm-dirs.ts +9 -0
  155. package/src/def/new.ts +28 -3
  156. package/src/def/pre-publish.ts +12 -3
  157. package/src/def/rename.ts +11 -2
  158. package/src/def/universalize.ts +9 -0
  159. package/src/def/version.ts +9 -0
  160. package/src/index.ts +2 -0
  161. package/src/utils/__tests__/__snapshots__/config.spec.ts.md +97 -0
  162. package/src/utils/__tests__/__snapshots__/config.spec.ts.snap +0 -0
  163. package/src/utils/__tests__/__snapshots__/target.spec.ts.md +7 -0
  164. package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
  165. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +555 -0
  166. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
  167. package/src/utils/__tests__/__snapshots__/version.spec.ts.md +9 -8
  168. package/src/utils/__tests__/__snapshots__/version.spec.ts.snap +0 -0
  169. package/src/utils/__tests__/config.spec.ts +81 -0
  170. package/src/utils/__tests__/typegen.spec.ts +19 -4
  171. package/src/utils/cargo.ts +1 -1
  172. package/src/utils/config.ts +85 -9
  173. package/src/utils/metadata.ts +2 -2
  174. package/src/utils/misc.ts +11 -3
  175. package/src/utils/target.ts +23 -7
  176. package/src/utils/typegen.ts +30 -5
  177. package/src/utils/version.ts +11 -9
@@ -2,6 +2,7 @@ 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'
@@ -15,11 +16,12 @@ 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,
23
25
  ) => {
24
26
  const allTargets = new Set(
25
27
  targets.flatMap((t) => {
@@ -34,7 +36,7 @@ export const createGithubActionsCIYml = (
34
36
  }),
35
37
  )
36
38
 
37
- const fullTemplate = load(YAML()) as any
39
+ const fullTemplate = load(YAML(packageManager)) as any
38
40
 
39
41
  const requiredSteps = []
40
42
  const enableWindowsX86 = allTargets.has('x86_64-pc-windows-msvc')
@@ -46,6 +48,7 @@ export const createGithubActionsCIYml = (
46
48
  const enableLinuxArm7 = allTargets.has('armv7-unknown-linux-gnueabihf')
47
49
  const enableFreeBSD = allTargets.has('x86_64-unknown-freebsd')
48
50
  const enableMacOSUni = allTargets.has('universal-apple-darwin')
51
+ const enableWasi = allTargets.has('wasm32-wasi-preview1-threads')
49
52
  fullTemplate.jobs.build.strategy.matrix.settings =
50
53
  fullTemplate.jobs.build.strategy.matrix.settings.filter(
51
54
  ({ target }: { target: string }) => allTargets.has(target),
@@ -63,10 +66,16 @@ export const createGithubActionsCIYml = (
63
66
  if (!enableWindowsX86 && !enableMacOSX86) {
64
67
  delete fullTemplate.jobs[TEST_MACOS_WINDOWS]
65
68
  } else {
66
- const filterTarget = enableWindowsX86 ? 'macos-latest' : 'windows-latest'
69
+ const filterTargets = new Set<string>()
70
+ if (enableWindowsX86) {
71
+ filterTargets.add('windows-latest')
72
+ }
73
+ if (enableMacOSUni || enableMacOSX86) {
74
+ filterTargets.add('macos-latest')
75
+ }
67
76
  fullTemplate.jobs[TEST_MACOS_WINDOWS].strategy.matrix.settings =
68
77
  fullTemplate.jobs[TEST_MACOS_WINDOWS].strategy.matrix.settings.filter(
69
- ({ host }: { host: string; target: string }) => host !== filterTarget,
78
+ ({ host }: { host: string; target: string }) => filterTargets.has(host),
70
79
  )
71
80
 
72
81
  requiredSteps.push(TEST_MACOS_WINDOWS)
@@ -108,6 +117,12 @@ export const createGithubActionsCIYml = (
108
117
  requiredSteps.push(UNIVERSAL_MACOS)
109
118
  }
110
119
 
120
+ if (!enableWasi) {
121
+ delete fullTemplate.jobs[TEST_WASI]
122
+ } else {
123
+ requiredSteps.push(TEST_WASI)
124
+ }
125
+
111
126
  fullTemplate.jobs.publish.needs = requiredSteps
112
127
 
113
128
  return dump(fullTemplate, {
@@ -1,8 +1,10 @@
1
- export function createJsBinding(localName: string, pkgName: string): string {
1
+ export function createCjsBinding(
2
+ localName: string,
3
+ pkgName: string,
4
+ idents: string[],
5
+ ): string {
2
6
  return `// prettier-ignore
3
- /* tslint:disable */
4
7
  /* eslint-disable */
5
-
6
8
  /* auto-generated by NAPI-RS */
7
9
 
8
10
  const { existsSync, readFileSync } = require('fs')
@@ -14,18 +16,52 @@ let nativeBinding = null
14
16
  let localFileExisted = false
15
17
  let loadError = null
16
18
 
17
- function isMusl() {
18
- // For Node 10
19
- if (!process.report || typeof process.report.getReport !== 'function') {
20
- try {
21
- const lddPath = require('child_process').execSync('which ldd').toString().trim()
22
- return readFileSync(lddPath, 'utf8').includes('musl')
23
- } catch (e) {
19
+ const isMusl = () => {
20
+ let musl = false
21
+ if (process.platform === 'linux') {
22
+ musl = isMuslFromFilesystem()
23
+ if (musl === null) {
24
+ musl = isMuslFromReport()
25
+ }
26
+ if (musl === null) {
27
+ musl = isMuslFromChildProcess()
28
+ }
29
+ }
30
+ return musl
31
+ }
32
+
33
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
34
+
35
+ const isMuslFromFilesystem = () => {
36
+ try {
37
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
38
+ } catch {
39
+ return null
40
+ }
41
+ }
42
+
43
+ const isMuslFromReport = () => {
44
+ const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null
45
+ if (!report) {
46
+ return null
47
+ }
48
+ if (report.header && report.header.glibcVersionRuntime) {
49
+ return false
50
+ }
51
+ if (Array.isArray(report.sharedObjects)) {
52
+ if (report.sharedObjects.some(isFileMusl)) {
24
53
  return true
25
54
  }
26
- } else {
27
- const { glibcVersionRuntime } = process.report.getReport().header
28
- return !glibcVersionRuntime
55
+ }
56
+ return false
57
+ }
58
+
59
+ const isMuslFromChildProcess = () => {
60
+ try {
61
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
62
+ } catch (e) {
63
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
64
+ return false
29
65
  }
30
66
  }
31
67
 
@@ -238,6 +274,49 @@ switch (platform) {
238
274
  loadError = e
239
275
  }
240
276
  break
277
+ case 'riscv64':
278
+ if (isMusl()) {
279
+ localFileExisted = existsSync(
280
+ join(__dirname, '${localName}.linux-riscv64-musl.node')
281
+ )
282
+ try {
283
+ if (localFileExisted) {
284
+ nativeBinding = require('./${localName}.linux-riscv64-musl.node')
285
+ } else {
286
+ nativeBinding = require('${pkgName}-linux-riscv64-musl')
287
+ }
288
+ } catch (e) {
289
+ loadError = e
290
+ }
291
+ } else {
292
+ localFileExisted = existsSync(
293
+ join(__dirname, '${localName}.linux-riscv64-gnu.node')
294
+ )
295
+ try {
296
+ if (localFileExisted) {
297
+ nativeBinding = require('./${localName}.linux-riscv64-gnu.node')
298
+ } else {
299
+ nativeBinding = require('${pkgName}-linux-riscv64-gnu')
300
+ }
301
+ } catch (e) {
302
+ loadError = e
303
+ }
304
+ }
305
+ break
306
+ case 's390x':
307
+ localFileExisted = existsSync(
308
+ join(__dirname, '${localName}.linux-s390x-gnu.node')
309
+ )
310
+ try {
311
+ if (localFileExisted) {
312
+ nativeBinding = require('./${localName}.linux-s390x-gnu.node')
313
+ } else {
314
+ nativeBinding = require('${pkgName}-linux-s390x-gnu')
315
+ }
316
+ } catch (e) {
317
+ loadError = e
318
+ }
319
+ break
241
320
  default:
242
321
  throw new Error(\`Unsupported architecture on Linux: \${arch}\`)
243
322
  }
@@ -246,6 +325,25 @@ switch (platform) {
246
325
  throw new Error(\`Unsupported OS: \${platform}, architecture: \${arch}\`)
247
326
  }
248
327
 
328
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
329
+ try {
330
+ nativeBinding = require('./${localName}.wasi.cjs')
331
+ } catch (err) {
332
+ if (process.env.NAPI_RS_FORCE_WASI) {
333
+ console.error(err)
334
+ }
335
+ }
336
+ if (!nativeBinding) {
337
+ try {
338
+ nativeBinding = require('${pkgName}-wasm32-wasi')
339
+ } catch (err) {
340
+ if (process.env.NAPI_RS_FORCE_WASI) {
341
+ console.error(err)
342
+ }
343
+ }
344
+ }
345
+ }
346
+
249
347
  if (!nativeBinding) {
250
348
  if (loadError) {
251
349
  throw loadError
@@ -253,5 +351,8 @@ if (!nativeBinding) {
253
351
  throw new Error(\`Failed to load native binding\`)
254
352
  }
255
353
 
354
+ ${idents
355
+ .map((ident) => `module.exports.${ident} = nativeBinding.${ident}`)
356
+ .join('\n')}
256
357
  `
257
358
  }
@@ -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,150 @@
1
+ export const createWasiBrowserBinding = (
2
+ wasiFilename: string,
3
+ wasiRegisterFunctions: string[],
4
+ ) => `import {
5
+ instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync,
6
+ getDefaultContext as __emnapiGetDefaultContext,
7
+ WASI as __WASI,
8
+ } from '@napi-rs/wasm-runtime'
9
+ import { Volume as __Volume, createFsFromVolume as __createFsFromVolume } from '@napi-rs/wasm-runtime/fs'
10
+
11
+ import __wasmUrl from './${wasiFilename}.wasm?url'
12
+
13
+ const __fs = __createFsFromVolume(
14
+ __Volume.fromJSON({
15
+ '/': null,
16
+ }),
17
+ )
18
+
19
+ const __wasi = new __WASI({
20
+ version: 'preview1',
21
+ fs: __fs,
22
+ })
23
+
24
+ const __emnapiContext = __emnapiGetDefaultContext()
25
+
26
+ const __sharedMemory = new WebAssembly.Memory({
27
+ initial: 1024,
28
+ maximum: 10240,
29
+ shared: true,
30
+ })
31
+
32
+ const __wasmFile = await fetch(__wasmUrl).then((res) => res.arrayBuffer())
33
+
34
+ const {
35
+ instance: __napiInstance,
36
+ module: __wasiModule,
37
+ napiModule: __napiModule,
38
+ } = __emnapiInstantiateNapiModuleSync(__wasmFile, {
39
+ context: __emnapiContext,
40
+ asyncWorkPoolSize: 4,
41
+ wasi: __wasi,
42
+ onCreateWorker() {
43
+ return new Worker(new URL('./wasi-worker-browser.mjs', import.meta.url), {
44
+ type: 'module',
45
+ })
46
+ },
47
+ overwriteImports(importObject) {
48
+ importObject.env = {
49
+ ...importObject.env,
50
+ ...importObject.napi,
51
+ ...importObject.emnapi,
52
+ memory: __sharedMemory,
53
+ }
54
+ return importObject
55
+ },
56
+ beforeInit({ instance }) {
57
+ __napi_rs_initialize_modules(instance)
58
+ },
59
+ })
60
+
61
+ function __napi_rs_initialize_modules(__napiInstance) {
62
+ ${wasiRegisterFunctions
63
+ .map((name) => ` __napiInstance.exports['${name}']?.()`)
64
+ .join('\n')}
65
+ }
66
+ `
67
+
68
+ export const createWasiBinding = (
69
+ wasmFileName: string,
70
+ packageName: string,
71
+ wasiRegisterFunctions: string[],
72
+ ) => `/* eslint-disable */
73
+ /* prettier-ignore */
74
+
75
+ /* auto-generated by NAPI-RS */
76
+
77
+ const __nodeFs= require('node:fs')
78
+ const __nodePath = require('node:path')
79
+ const { WASI: __nodeWASI } = require('node:wasi')
80
+ const { Worker } = require('node:worker_threads')
81
+
82
+ const {
83
+ instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync,
84
+ getDefaultContext: __emnapiGetDefaultContext,
85
+ } = require('@napi-rs/wasm-runtime')
86
+
87
+ const __wasi = new __nodeWASI({
88
+ version: 'preview1',
89
+ env: process.env,
90
+ preopens: {
91
+ '/': '/'
92
+ }
93
+ })
94
+
95
+ const __emnapiContext = __emnapiGetDefaultContext()
96
+
97
+ const __sharedMemory = new WebAssembly.Memory({
98
+ initial: 1024,
99
+ maximum: 10240,
100
+ shared: true,
101
+ })
102
+
103
+ let __wasmFilePath = __nodePath.join(__dirname, '${wasmFileName}.wasm')
104
+
105
+ if (!__nodeFs.existsSync(__wasmFilePath)) {
106
+ try {
107
+ __wasmFilePath = __nodePath.resolve('${packageName}-wasm32-wasi')
108
+ } catch {
109
+ throw new Error('Cannot find ${wasmFileName}.wasm file, and ${packageName}-wasm32-wasi package is not installed.')
110
+ }
111
+ }
112
+
113
+ const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule } = __emnapiInstantiateNapiModuleSync(__nodeFs.readFileSync(__wasmFilePath), {
114
+ context: __emnapiContext,
115
+ asyncWorkPoolSize: (function() {
116
+ const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE)
117
+ // NaN > 0 is false
118
+ if (threadsSizeFromEnv > 0) {
119
+ return threadsSizeFromEnv
120
+ } else {
121
+ return 4
122
+ }
123
+ })(),
124
+ wasi: __wasi,
125
+ onCreateWorker() {
126
+ return new Worker(__nodePath.join(__dirname, 'wasi-worker.mjs'), {
127
+ env: process.env,
128
+ execArgv: ['--experimental-wasi-unstable-preview1'],
129
+ })
130
+ },
131
+ overwriteImports(importObject) {
132
+ importObject.env = {
133
+ ...importObject.env,
134
+ ...importObject.napi,
135
+ ...importObject.emnapi,
136
+ memory: __sharedMemory,
137
+ }
138
+ return importObject
139
+ },
140
+ beforeInit({ instance }) {
141
+ __napi_rs_initialize_modules(instance)
142
+ }
143
+ })
144
+
145
+ function __napi_rs_initialize_modules(__napiInstance) {
146
+ ${wasiRegisterFunctions
147
+ .map((name) => ` __napiInstance.exports['${name}']?.()`)
148
+ .join('\n')}
149
+ }
150
+ `
@@ -1,10 +1,21 @@
1
- export const createPackageJson = ({
1
+ import type {
2
+ CommonPackageJsonFields,
3
+ SupportedTestFramework,
4
+ } from '../../utils/config.js'
5
+ import { UNIVERSAL_TARGETS } from '../../utils/target.js'
6
+
7
+ export interface PackageMeta {
8
+ 'dist-tags': { [index: string]: string }
9
+ }
10
+
11
+ export const createPackageJson = async ({
2
12
  name,
3
13
  binaryName,
4
14
  targets,
5
15
  license,
6
16
  engineRequirement,
7
17
  cliVersion,
18
+ testFramework,
8
19
  }: {
9
20
  name: string
10
21
  binaryName: string
@@ -12,32 +23,68 @@ export const createPackageJson = ({
12
23
  license: string
13
24
  engineRequirement: string
14
25
  cliVersion: string
26
+ testFramework: SupportedTestFramework
15
27
  }) => {
16
- return `{
17
- "name": "${name}",
18
- "version": "1.0.0",
19
- "main": "index.js",
20
- "types": "index.d.ts",
21
- "license": "${license}",
22
- "engines": {
23
- "node": "${engineRequirement}"
24
- },
25
- "napi": {
26
- "binaryName": "${binaryName}",
27
- "targets": [
28
- ${targets.map((t) => `"${t}"`).join(',\n ')}
29
- ]
30
- },
31
- "scripts": {
32
- "test": "node -e \\"assert(require('.').sum(1, 2) === 3)\\"",
33
- "build": "napi build --release --platform --strip",
34
- "build:debug": "napi build",
35
- "prepublishOnly": "napi prepublish -t npm",
36
- "artifacts": "napi artifacts",
37
- "version": "napi version"
38
- },
39
- "devDependencies": {
40
- "@napi-rs/cli": "^${cliVersion}"
28
+ const hasWasmTarget = targets.some((t) => t.includes('wasm'))
29
+ const universalTargets = targets.filter(
30
+ (t) => t in UNIVERSAL_TARGETS,
31
+ ) as (keyof typeof UNIVERSAL_TARGETS)[]
32
+ const unifiedtargets = universalTargets.length
33
+ ? targets.filter(
34
+ (target) =>
35
+ !universalTargets.some((t) => {
36
+ // @ts-expect-error
37
+ return UNIVERSAL_TARGETS[t].includes(target)
38
+ }),
39
+ )
40
+ : targets
41
+ const content: CommonPackageJsonFields = {
42
+ name,
43
+ version: '0.0.0',
44
+ license,
45
+ engines: {
46
+ node: engineRequirement,
47
+ },
48
+ type: 'commonjs',
49
+ main: 'index.js',
50
+ types: 'index.d.ts',
51
+ browser: 'browser.js',
52
+ module: undefined,
53
+ exports: undefined,
54
+ napi: {
55
+ binaryName,
56
+ targets: unifiedtargets,
57
+ },
58
+ scripts: {
59
+ test: testFramework,
60
+ build: 'napi build --release --platform --strip',
61
+ 'build:debug': 'napi build',
62
+ prepublishOnly: 'napi prepublish -t npm',
63
+ artifacts: 'napi artifacts',
64
+ version: 'napi version',
65
+ },
66
+ devDependencies: {
67
+ '@napi-rs/cli': `^${cliVersion}`,
68
+ },
69
+ }
70
+
71
+ if (testFramework === 'ava') {
72
+ const avaMeta = await fetch(`https://registry.npmjs.org/ava`).then(
73
+ (res) => res.json() as Promise<PackageMeta>,
74
+ )
75
+ content.devDependencies!['ava'] = `^${avaMeta['dist-tags'].latest}`
76
+ content.ava = {
77
+ timeout: '1m',
78
+ }
79
+ }
80
+
81
+ if (hasWasmTarget) {
82
+ const wasmRuntime = await fetch(
83
+ `https://registry.npmjs.org/@napi-rs/wasm-runtime`,
84
+ ).then((res) => res.json() as Promise<PackageMeta>)
85
+ const latest = wasmRuntime['dist-tags'].latest
86
+ content.devDependencies!['@napi-rs/wasm-runtime'] = `^${latest}`
41
87
  }
42
- }`
88
+
89
+ return JSON.stringify(content, null, 2)
43
90
  }
@@ -0,0 +1,93 @@
1
+ export const WASI_WORKER_TEMPLATE = `import fs from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { parentPort, Worker } from "node:worker_threads";
4
+
5
+ import { instantiateNapiModuleSync, MessageHandler, WASI } from "@napi-rs/wasm-runtime";
6
+
7
+ const require = createRequire(import.meta.url);
8
+
9
+ if (parentPort) {
10
+ parentPort.on("message", (data) => {
11
+ globalThis.onmessage({ data });
12
+ });
13
+ }
14
+
15
+ Object.assign(globalThis, {
16
+ self: globalThis,
17
+ require,
18
+ Worker,
19
+ importScripts: function (f) {
20
+ ;(0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f);
21
+ },
22
+ postMessage: function (msg) {
23
+ if (parentPort) {
24
+ parentPort.postMessage(msg);
25
+ }
26
+ },
27
+ });
28
+
29
+ const handler = new MessageHandler({
30
+ onLoad({ wasmModule, wasmMemory }) {
31
+ const wasi = new WASI({ fs });
32
+
33
+ return instantiateNapiModuleSync(wasmModule, {
34
+ childThread: true,
35
+ wasi,
36
+ overwriteImports(importObject) {
37
+ importObject.env = {
38
+ ...importObject.env,
39
+ ...importObject.napi,
40
+ ...importObject.emnapi,
41
+ memory: wasmMemory
42
+ };
43
+ },
44
+ });
45
+ },
46
+ });
47
+
48
+ globalThis.onmessage = function (e) {
49
+ handler.handle(e);
50
+ };
51
+ `
52
+
53
+ export const WASI_WORKER_BROWSER_TEMPLATE = `import { instantiateNapiModuleSync, MessageHandler, WASI } from '@napi-rs/wasm-runtime'
54
+ import { Volume, createFsFromVolume } from '@napi-rs/wasm-runtime/fs'
55
+
56
+ const fs = createFsFromVolume(
57
+ Volume.fromJSON({
58
+ '/': null,
59
+ }),
60
+ )
61
+
62
+ const handler = new MessageHandler({
63
+ onLoad({ wasmModule, wasmMemory }) {
64
+ const wasi = new WASI({
65
+ fs,
66
+ print: function () {
67
+ // eslint-disable-next-line no-console
68
+ console.log.apply(console, arguments)
69
+ },
70
+ printErr: function() {
71
+ // eslint-disable-next-line no-console
72
+ console.error.apply(console, arguments)
73
+ },
74
+ })
75
+ return instantiateNapiModuleSync(wasmModule, {
76
+ childThread: true,
77
+ wasi,
78
+ overwriteImports(importObject) {
79
+ importObject.env = {
80
+ ...importObject.env,
81
+ ...importObject.napi,
82
+ ...importObject.emnapi,
83
+ memory: wasmMemory,
84
+ }
85
+ },
86
+ })
87
+ },
88
+ })
89
+
90
+ globalThis.onmessage = function (e) {
91
+ handler.handle(e)
92
+ }
93
+ `
@@ -1,5 +1,5 @@
1
- import { spawnSync } from 'child_process'
2
- import { join, resolve } from 'path'
1
+ import { spawnSync } from 'node:child_process'
2
+ import { join, resolve } from 'node:path'
3
3
 
4
4
  import {
5
5
  applyDefaultUniversalizeOptions,
@@ -27,7 +27,10 @@ export async function universalizeBinaries(userOptions: UniversalizeOptions) {
27
27
 
28
28
  const packageJsonPath = join(options.cwd, options.packageJsonPath)
29
29
 
30
- const config = await readNapiConfig(packageJsonPath)
30
+ const config = await readNapiConfig(
31
+ packageJsonPath,
32
+ options.configPath ? resolve(options.cwd, options.configPath) : undefined,
33
+ )
31
34
 
32
35
  const target = config.targets.find(
33
36
  (t) => t.platform === process.platform && t.arch === 'universal',
@@ -40,7 +43,7 @@ export async function universalizeBinaries(userOptions: UniversalizeOptions) {
40
43
  }
41
44
 
42
45
  const srcFiles = UniArchsByPlatform[process.platform]?.map(
43
- (arch) => `${config.binaryName}.${process.platform}-${arch}.node`,
46
+ (arch) => resolve(options.cwd, options.outputDir, `${config.binaryName}.${process.platform}-${arch}.node`),
44
47
  )
45
48
 
46
49
  if (!srcFiles || !universalizers[process.platform]) {
@@ -53,7 +56,7 @@ export async function universalizeBinaries(userOptions: UniversalizeOptions) {
53
56
  debug(' %O', srcFiles)
54
57
 
55
58
  const srcFileLookup = await Promise.all(
56
- srcFiles.map((f) => fileExists(resolve(options.cwd, options.outputDir, f))),
59
+ srcFiles.map((f) => fileExists(f)),
57
60
  )
58
61
 
59
62
  const notFoundFiles = srcFiles.filter((_, i) => !srcFileLookup[i])
@@ -1,4 +1,4 @@
1
- import { join, resolve } from 'path'
1
+ import { join, resolve } from 'node:path'
2
2
 
3
3
  import { applyDefaultVersionOptions, VersionOptions } from '../def/version.js'
4
4
  import {
@@ -13,7 +13,10 @@ export async function version(userOptions: VersionOptions) {
13
13
  const options = applyDefaultVersionOptions(userOptions)
14
14
  const packageJsonPath = resolve(options.cwd, options.packageJsonPath)
15
15
 
16
- const config = await readNapiConfig(packageJsonPath)
16
+ const config = await readNapiConfig(
17
+ packageJsonPath,
18
+ options.configPath ? resolve(options.cwd, options.configPath) : undefined,
19
+ )
17
20
 
18
21
  for (const target of config.targets) {
19
22
  const pkgDir = resolve(options.cwd, options.npmDir, target.platformArchABI)
@@ -8,9 +8,9 @@ export class ArtifactsCommand extends BaseArtifactsCommand {
8
8
  description: 'Copy artifacts from Github Actions into specified dir',
9
9
  examples: [
10
10
  [
11
- '$0 artifacts --dir . --dist ./npm',
11
+ '$0 artifacts --output-dir ./artifacts --dist ./npm',
12
12
  `Copy [binaryName].[platform].node under current dir(.) into packages under npm dir.
13
- e.g: index.linux-x64-gnu.node --> ./npm/linux-x64-gnu/index.node`,
13
+ e.g: index.linux-x64-gnu.node --> ./npm/linux-x64-gnu/index.linux-x64-gnu.node`,
14
14
  ],
15
15
  ],
16
16
  })
@@ -1,4 +1,4 @@
1
- import { execSync } from 'child_process'
1
+ import { execSync } from 'node:child_process'
2
2
 
3
3
  import { Option } from 'clipanion'
4
4