@napi-rs/cli 3.0.0-alpha.10 → 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 (199) 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 +1 -1
  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 +1 -0
  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 -15
  11. package/dist/def/artifacts.d.ts +21 -1
  12. package/dist/def/build.d.ts +149 -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 +10052 -15662
  20. package/dist/index.js +3712 -32
  21. package/dist/utils/__tests__/config.spec.d.ts +1 -0
  22. package/dist/utils/config.d.ts +56 -4
  23. package/dist/utils/index.d.ts +1 -1
  24. package/dist/utils/metadata.d.ts +13 -1
  25. package/dist/utils/misc.d.ts +3 -3
  26. package/dist/utils/read-config.d.ts +7 -0
  27. package/dist/utils/target.d.ts +8 -6
  28. package/dist/utils/typegen.d.ts +1 -1
  29. package/dist/utils/version.d.ts +2 -1
  30. package/package.json +38 -34
  31. package/src/api/__tests__/create-npm-dirs.spec.ts +210 -0
  32. package/src/api/__tests__/new.spec.ts +429 -0
  33. package/src/api/artifacts.ts +81 -9
  34. package/src/api/build.ts +595 -183
  35. package/src/api/create-npm-dirs.ts +64 -13
  36. package/src/api/new.ts +389 -122
  37. package/src/api/pre-publish.ts +19 -11
  38. package/src/api/rename.ts +103 -17
  39. package/src/api/templates/index.ts +0 -7
  40. package/src/api/templates/js-binding.ts +159 -220
  41. package/src/api/templates/load-wasi-template.ts +216 -0
  42. package/src/api/templates/wasi-worker-template.ts +122 -0
  43. package/src/api/universalize.ts +13 -8
  44. package/src/api/version.ts +5 -2
  45. package/src/commands/artifacts.ts +2 -2
  46. package/src/commands/build.ts +1 -1
  47. package/src/commands/new.ts +46 -45
  48. package/src/def/artifacts.ts +22 -3
  49. package/src/def/build.ts +55 -8
  50. package/src/def/create-npm-dirs.ts +9 -0
  51. package/src/def/new.ts +28 -3
  52. package/src/def/pre-publish.ts +24 -3
  53. package/src/def/rename.ts +11 -2
  54. package/src/def/universalize.ts +9 -0
  55. package/src/def/version.ts +9 -0
  56. package/src/utils/__tests__/__fixtures__/napi_type_def +130 -130
  57. package/src/utils/__tests__/__snapshots__/config.spec.ts.md +97 -0
  58. package/src/utils/__tests__/__snapshots__/config.spec.ts.snap +0 -0
  59. package/src/utils/__tests__/__snapshots__/target.spec.ts.md +49 -0
  60. package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
  61. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +316 -332
  62. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
  63. package/src/utils/__tests__/__snapshots__/version.spec.ts.md +8 -7
  64. package/src/utils/__tests__/__snapshots__/version.spec.ts.snap +0 -0
  65. package/src/utils/__tests__/config.spec.ts +81 -0
  66. package/src/utils/cargo.ts +2 -2
  67. package/src/utils/config.ts +127 -9
  68. package/src/utils/index.ts +1 -1
  69. package/src/utils/log.ts +1 -1
  70. package/src/utils/metadata.ts +52 -14
  71. package/src/utils/misc.ts +21 -12
  72. package/src/utils/read-config.ts +20 -0
  73. package/src/utils/target.ts +37 -5
  74. package/src/utils/typegen.ts +87 -52
  75. package/src/utils/version.ts +10 -8
  76. package/dist/api/artifacts.js +0 -53
  77. package/dist/api/artifacts.js.map +0 -1
  78. package/dist/api/build.js +0 -498
  79. package/dist/api/build.js.map +0 -1
  80. package/dist/api/create-npm-dirs.js +0 -64
  81. package/dist/api/create-npm-dirs.js.map +0 -1
  82. package/dist/api/load-wasi-template.d.ts +0 -1
  83. package/dist/api/load-wasi-template.js +0 -60
  84. package/dist/api/load-wasi-template.js.map +0 -1
  85. package/dist/api/new.js +0 -155
  86. package/dist/api/new.js.map +0 -1
  87. package/dist/api/pre-publish.js +0 -158
  88. package/dist/api/pre-publish.js.map +0 -1
  89. package/dist/api/rename.js +0 -29
  90. package/dist/api/rename.js.map +0 -1
  91. package/dist/api/templates/.gitignore.d.ts +0 -1
  92. package/dist/api/templates/.gitignore.js +0 -200
  93. package/dist/api/templates/.gitignore.js.map +0 -1
  94. package/dist/api/templates/.npmignore.d.ts +0 -1
  95. package/dist/api/templates/.npmignore.js +0 -15
  96. package/dist/api/templates/.npmignore.js.map +0 -1
  97. package/dist/api/templates/build.rs.d.ts +0 -1
  98. package/dist/api/templates/build.rs.js +0 -5
  99. package/dist/api/templates/build.rs.js.map +0 -1
  100. package/dist/api/templates/cargo.toml.d.ts +0 -6
  101. package/dist/api/templates/cargo.toml.js +0 -26
  102. package/dist/api/templates/cargo.toml.js.map +0 -1
  103. package/dist/api/templates/ci-template.d.ts +0 -1
  104. package/dist/api/templates/ci-template.js +0 -578
  105. package/dist/api/templates/ci-template.js.map +0 -1
  106. package/dist/api/templates/ci.yml.d.ts +0 -1
  107. package/dist/api/templates/ci.yml.js +0 -99
  108. package/dist/api/templates/ci.yml.js.map +0 -1
  109. package/dist/api/templates/index.js +0 -9
  110. package/dist/api/templates/index.js.map +0 -1
  111. package/dist/api/templates/js-binding.js +0 -293
  112. package/dist/api/templates/js-binding.js.map +0 -1
  113. package/dist/api/templates/lib.rs.d.ts +0 -1
  114. package/dist/api/templates/lib.rs.js +0 -8
  115. package/dist/api/templates/lib.rs.js.map +0 -1
  116. package/dist/api/templates/package.json.d.ts +0 -8
  117. package/dist/api/templates/package.json.js +0 -32
  118. package/dist/api/templates/package.json.js.map +0 -1
  119. package/dist/api/universalize.js +0 -39
  120. package/dist/api/universalize.js.map +0 -1
  121. package/dist/api/version.js +0 -17
  122. package/dist/api/version.js.map +0 -1
  123. package/dist/api/wasi-worker-template.d.ts +0 -1
  124. package/dist/api/wasi-worker-template.js +0 -53
  125. package/dist/api/wasi-worker-template.js.map +0 -1
  126. package/dist/cli.js.map +0 -1
  127. package/dist/commands/artifacts.js +0 -20
  128. package/dist/commands/artifacts.js.map +0 -1
  129. package/dist/commands/build.js +0 -35
  130. package/dist/commands/build.js.map +0 -1
  131. package/dist/commands/create-npm-dirs.js +0 -8
  132. package/dist/commands/create-npm-dirs.js.map +0 -1
  133. package/dist/commands/help.js +0 -13
  134. package/dist/commands/help.js.map +0 -1
  135. package/dist/commands/new.js +0 -110
  136. package/dist/commands/new.js.map +0 -1
  137. package/dist/commands/pre-publish.js +0 -9
  138. package/dist/commands/pre-publish.js.map +0 -1
  139. package/dist/commands/rename.js +0 -8
  140. package/dist/commands/rename.js.map +0 -1
  141. package/dist/commands/universalize.js +0 -8
  142. package/dist/commands/universalize.js.map +0 -1
  143. package/dist/commands/version.js +0 -8
  144. package/dist/commands/version.js.map +0 -1
  145. package/dist/def/artifacts.js +0 -39
  146. package/dist/def/artifacts.js.map +0 -1
  147. package/dist/def/build.js +0 -118
  148. package/dist/def/build.js.map +0 -1
  149. package/dist/def/create-npm-dirs.js +0 -39
  150. package/dist/def/create-npm-dirs.js.map +0 -1
  151. package/dist/def/new.js +0 -67
  152. package/dist/def/new.js.map +0 -1
  153. package/dist/def/pre-publish.js +0 -57
  154. package/dist/def/pre-publish.js.map +0 -1
  155. package/dist/def/rename.js +0 -59
  156. package/dist/def/rename.js.map +0 -1
  157. package/dist/def/universalize.js +0 -34
  158. package/dist/def/universalize.js.map +0 -1
  159. package/dist/def/version.js +0 -34
  160. package/dist/def/version.js.map +0 -1
  161. package/dist/index.js.map +0 -1
  162. package/dist/utils/__tests__/target.spec.js +0 -11
  163. package/dist/utils/__tests__/target.spec.js.map +0 -1
  164. package/dist/utils/__tests__/typegen.spec.js +0 -42
  165. package/dist/utils/__tests__/typegen.spec.js.map +0 -1
  166. package/dist/utils/__tests__/version.spec.js +0 -6
  167. package/dist/utils/__tests__/version.spec.js.map +0 -1
  168. package/dist/utils/cargo.js +0 -34
  169. package/dist/utils/cargo.js.map +0 -1
  170. package/dist/utils/ci.d.ts +0 -11
  171. package/dist/utils/ci.js +0 -96
  172. package/dist/utils/ci.js.map +0 -1
  173. package/dist/utils/config.js +0 -43
  174. package/dist/utils/config.js.map +0 -1
  175. package/dist/utils/index.js +0 -10
  176. package/dist/utils/index.js.map +0 -1
  177. package/dist/utils/log.js +0 -15
  178. package/dist/utils/log.js.map +0 -1
  179. package/dist/utils/metadata.js +0 -20
  180. package/dist/utils/metadata.js.map +0 -1
  181. package/dist/utils/misc.js +0 -41
  182. package/dist/utils/misc.js.map +0 -1
  183. package/dist/utils/target.js +0 -121
  184. package/dist/utils/target.js.map +0 -1
  185. package/dist/utils/typegen.js +0 -179
  186. package/dist/utils/typegen.js.map +0 -1
  187. package/dist/utils/version.js +0 -60
  188. package/dist/utils/version.js.map +0 -1
  189. package/src/api/load-wasi-template.ts +0 -62
  190. package/src/api/templates/.gitignore.ts +0 -199
  191. package/src/api/templates/.npmignore.ts +0 -14
  192. package/src/api/templates/build.rs.ts +0 -4
  193. package/src/api/templates/cargo.toml.ts +0 -35
  194. package/src/api/templates/ci-template.ts +0 -577
  195. package/src/api/templates/ci.yml.ts +0 -119
  196. package/src/api/templates/lib.rs.ts +0 -7
  197. package/src/api/templates/package.json.ts +0 -48
  198. package/src/api/wasi-worker-template.ts +0 -52
  199. package/src/utils/ci.ts +0 -111
@@ -0,0 +1,216 @@
1
+ export const createWasiBrowserBinding = (
2
+ wasiFilename: string,
3
+ initialMemory = 4000,
4
+ maximumMemory = 65536,
5
+ fs = false,
6
+ asyncInit = false,
7
+ buffer = false,
8
+ ) => {
9
+ const fsImport = fs ? `import { memfs } from '@napi-rs/wasm-runtime/fs'` : ''
10
+ const bufferImport = buffer
11
+ ? fs
12
+ ? ``
13
+ : `import { Buffer } from 'buffer'`
14
+ : ''
15
+ const wasiCreation = fs
16
+ ? `
17
+ export const { fs: __fs, vol: __volume } = memfs()
18
+
19
+ const __wasi = new __WASI({
20
+ version: 'preview1',
21
+ fs: __fs,
22
+ preopens: {
23
+ '/': '/',
24
+ },
25
+ })`
26
+ : `
27
+ const __wasi = new __WASI({
28
+ version: 'preview1',
29
+ })`
30
+
31
+ const workerFsHandler = fs
32
+ ? ` worker.addEventListener('message', __wasmCreateOnMessageForFsProxy(__fs))\n`
33
+ : ''
34
+
35
+ const emnapiInjectBuffer = buffer
36
+ ? '__emnapiContext.feature.Buffer = Buffer'
37
+ : ''
38
+ const emnapiInstantiateImport = asyncInit
39
+ ? `instantiateNapiModule as __emnapiInstantiateNapiModule`
40
+ : `instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync`
41
+ const emnapiInstantiateCall = asyncInit
42
+ ? `await __emnapiInstantiateNapiModule`
43
+ : `__emnapiInstantiateNapiModuleSync`
44
+
45
+ return `import {
46
+ createOnMessage as __wasmCreateOnMessageForFsProxy,
47
+ getDefaultContext as __emnapiGetDefaultContext,
48
+ ${emnapiInstantiateImport},
49
+ WASI as __WASI,
50
+ } from '@napi-rs/wasm-runtime'
51
+ ${fsImport}
52
+ ${bufferImport}
53
+ ${wasiCreation}
54
+
55
+ const __wasmUrl = new URL('./${wasiFilename}.wasm', import.meta.url).href
56
+ const __emnapiContext = __emnapiGetDefaultContext()
57
+ ${emnapiInjectBuffer}
58
+
59
+ const __sharedMemory = new WebAssembly.Memory({
60
+ initial: ${initialMemory},
61
+ maximum: ${maximumMemory},
62
+ shared: true,
63
+ })
64
+
65
+ const __wasmFile = await fetch(__wasmUrl).then((res) => res.arrayBuffer())
66
+
67
+ const {
68
+ instance: __napiInstance,
69
+ module: __wasiModule,
70
+ napiModule: __napiModule,
71
+ } = ${emnapiInstantiateCall}(__wasmFile, {
72
+ context: __emnapiContext,
73
+ asyncWorkPoolSize: 4,
74
+ wasi: __wasi,
75
+ onCreateWorker() {
76
+ const worker = new Worker(new URL('./wasi-worker-browser.mjs', import.meta.url), {
77
+ type: 'module',
78
+ })
79
+ ${workerFsHandler}
80
+ return worker
81
+ },
82
+ overwriteImports(importObject) {
83
+ importObject.env = {
84
+ ...importObject.env,
85
+ ...importObject.napi,
86
+ ...importObject.emnapi,
87
+ memory: __sharedMemory,
88
+ }
89
+ return importObject
90
+ },
91
+ beforeInit({ instance }) {
92
+ for (const name of Object.keys(instance.exports)) {
93
+ if (name.startsWith('__napi_register__')) {
94
+ instance.exports[name]()
95
+ }
96
+ }
97
+ },
98
+ })
99
+ `
100
+ }
101
+
102
+ export const createWasiBinding = (
103
+ wasmFileName: string,
104
+ packageName: string,
105
+ initialMemory = 4000,
106
+ maximumMemory = 65536,
107
+ ) => `/* eslint-disable */
108
+ /* prettier-ignore */
109
+
110
+ /* auto-generated by NAPI-RS */
111
+
112
+ const __nodeFs = require('node:fs')
113
+ const __nodePath = require('node:path')
114
+ const { WASI: __nodeWASI } = require('node:wasi')
115
+ const { Worker } = require('node:worker_threads')
116
+
117
+ const {
118
+ createOnMessage: __wasmCreateOnMessageForFsProxy,
119
+ getDefaultContext: __emnapiGetDefaultContext,
120
+ instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync,
121
+ } = require('@napi-rs/wasm-runtime')
122
+
123
+ const __rootDir = __nodePath.parse(process.cwd()).root
124
+
125
+ const __wasi = new __nodeWASI({
126
+ version: 'preview1',
127
+ env: process.env,
128
+ preopens: {
129
+ [__rootDir]: __rootDir,
130
+ }
131
+ })
132
+
133
+ const __emnapiContext = __emnapiGetDefaultContext()
134
+
135
+ const __sharedMemory = new WebAssembly.Memory({
136
+ initial: ${initialMemory},
137
+ maximum: ${maximumMemory},
138
+ shared: true,
139
+ })
140
+
141
+ let __wasmFilePath = __nodePath.join(__dirname, '${wasmFileName}.wasm')
142
+ const __wasmDebugFilePath = __nodePath.join(__dirname, '${wasmFileName}.debug.wasm')
143
+
144
+ if (__nodeFs.existsSync(__wasmDebugFilePath)) {
145
+ __wasmFilePath = __wasmDebugFilePath
146
+ } else if (!__nodeFs.existsSync(__wasmFilePath)) {
147
+ try {
148
+ __wasmFilePath = __nodePath.resolve('${packageName}-wasm32-wasi')
149
+ } catch {
150
+ throw new Error('Cannot find ${wasmFileName}.wasm file, and ${packageName}-wasm32-wasi package is not installed.')
151
+ }
152
+ }
153
+
154
+ const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule } = __emnapiInstantiateNapiModuleSync(__nodeFs.readFileSync(__wasmFilePath), {
155
+ context: __emnapiContext,
156
+ asyncWorkPoolSize: (function() {
157
+ const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE)
158
+ // NaN > 0 is false
159
+ if (threadsSizeFromEnv > 0) {
160
+ return threadsSizeFromEnv
161
+ } else {
162
+ return 4
163
+ }
164
+ })(),
165
+ reuseWorker: true,
166
+ wasi: __wasi,
167
+ onCreateWorker() {
168
+ const worker = new Worker(__nodePath.join(__dirname, 'wasi-worker.mjs'), {
169
+ env: process.env,
170
+ })
171
+ worker.onmessage = ({ data }) => {
172
+ __wasmCreateOnMessageForFsProxy(__nodeFs)(data)
173
+ }
174
+
175
+ // The main thread of Node.js waits for all the active handles before exiting.
176
+ // But Rust threads are never waited without \`thread::join\`.
177
+ // So here we hack the code of Node.js to prevent the workers from being referenced (active).
178
+ // According to https://github.com/nodejs/node/blob/19e0d472728c79d418b74bddff588bea70a403d0/lib/internal/worker.js#L415,
179
+ // a worker is consist of two handles: kPublicPort and kHandle.
180
+ {
181
+ const kPublicPort = Object.getOwnPropertySymbols(worker).find(s =>
182
+ s.toString().includes("kPublicPort")
183
+ );
184
+ if (kPublicPort) {
185
+ worker[kPublicPort].ref = () => {};
186
+ }
187
+
188
+ const kHandle = Object.getOwnPropertySymbols(worker).find(s =>
189
+ s.toString().includes("kHandle")
190
+ );
191
+ if (kHandle) {
192
+ worker[kHandle].ref = () => {};
193
+ }
194
+
195
+ worker.unref();
196
+ }
197
+ return worker
198
+ },
199
+ overwriteImports(importObject) {
200
+ importObject.env = {
201
+ ...importObject.env,
202
+ ...importObject.napi,
203
+ ...importObject.emnapi,
204
+ memory: __sharedMemory,
205
+ }
206
+ return importObject
207
+ },
208
+ beforeInit({ instance }) {
209
+ for (const name of Object.keys(instance.exports)) {
210
+ if (name.startsWith('__napi_register__')) {
211
+ instance.exports[name]()
212
+ }
213
+ }
214
+ },
215
+ })
216
+ `
@@ -0,0 +1,122 @@
1
+ export const WASI_WORKER_TEMPLATE = `import fs from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { parse } from "node:path";
4
+ import { WASI } from "node:wasi";
5
+ import { parentPort, Worker } from "node:worker_threads";
6
+
7
+ const require = createRequire(import.meta.url);
8
+
9
+ const { instantiateNapiModuleSync, MessageHandler, getDefaultContext } = require("@napi-rs/wasm-runtime");
10
+
11
+ if (parentPort) {
12
+ parentPort.on("message", (data) => {
13
+ globalThis.onmessage({ data });
14
+ });
15
+ }
16
+
17
+ Object.assign(globalThis, {
18
+ self: globalThis,
19
+ require,
20
+ Worker,
21
+ importScripts: function (f) {
22
+ ;(0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f);
23
+ },
24
+ postMessage: function (msg) {
25
+ if (parentPort) {
26
+ parentPort.postMessage(msg);
27
+ }
28
+ },
29
+ });
30
+
31
+ const emnapiContext = getDefaultContext();
32
+
33
+ const __rootDir = parse(process.cwd()).root;
34
+
35
+ const handler = new MessageHandler({
36
+ onLoad({ wasmModule, wasmMemory }) {
37
+ const wasi = new WASI({
38
+ version: 'preview1',
39
+ env: process.env,
40
+ preopens: {
41
+ [__rootDir]: __rootDir,
42
+ },
43
+ });
44
+
45
+ return instantiateNapiModuleSync(wasmModule, {
46
+ childThread: true,
47
+ wasi,
48
+ context: emnapiContext,
49
+ overwriteImports(importObject) {
50
+ importObject.env = {
51
+ ...importObject.env,
52
+ ...importObject.napi,
53
+ ...importObject.emnapi,
54
+ memory: wasmMemory
55
+ };
56
+ },
57
+ });
58
+ },
59
+ });
60
+
61
+ globalThis.onmessage = function (e) {
62
+ handler.handle(e);
63
+ };
64
+ `
65
+
66
+ export const createWasiBrowserWorkerBinding = (fs: boolean) => {
67
+ const fsImport = fs
68
+ ? `import { instantiateNapiModuleSync, MessageHandler, WASI, createFsProxy } from '@napi-rs/wasm-runtime'
69
+ import { memfsExported as __memfsExported } from '@napi-rs/wasm-runtime/fs'
70
+
71
+ const fs = createFsProxy(__memfsExported)`
72
+ : `import { instantiateNapiModuleSync, MessageHandler, WASI } from '@napi-rs/wasm-runtime'`
73
+ const wasiCreation = fs
74
+ ? `const wasi = new WASI({
75
+ fs,
76
+ preopens: {
77
+ '/': '/',
78
+ },
79
+ print: function () {
80
+ // eslint-disable-next-line no-console
81
+ console.log.apply(console, arguments)
82
+ },
83
+ printErr: function() {
84
+ // eslint-disable-next-line no-console
85
+ console.error.apply(console, arguments)
86
+ },
87
+ })`
88
+ : `const wasi = new WASI({
89
+ print: function () {
90
+ // eslint-disable-next-line no-console
91
+ console.log.apply(console, arguments)
92
+ },
93
+ printErr: function() {
94
+ // eslint-disable-next-line no-console
95
+ console.error.apply(console, arguments)
96
+ },
97
+ })`
98
+ return `${fsImport}
99
+
100
+ const handler = new MessageHandler({
101
+ onLoad({ wasmModule, wasmMemory }) {
102
+ ${wasiCreation}
103
+ return instantiateNapiModuleSync(wasmModule, {
104
+ childThread: true,
105
+ wasi,
106
+ overwriteImports(importObject) {
107
+ importObject.env = {
108
+ ...importObject.env,
109
+ ...importObject.napi,
110
+ ...importObject.emnapi,
111
+ memory: wasmMemory,
112
+ }
113
+ },
114
+ })
115
+ },
116
+ })
117
+
118
+ globalThis.onmessage = function (e) {
119
+ handler.handle(e)
120
+ }
121
+ `
122
+ }
@@ -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',
@@ -39,8 +42,12 @@ export async function universalizeBinaries(userOptions: UniversalizeOptions) {
39
42
  )
40
43
  }
41
44
 
42
- const srcFiles = UniArchsByPlatform[process.platform]?.map(
43
- (arch) => `${config.binaryName}.${process.platform}-${arch}.node`,
45
+ const srcFiles = UniArchsByPlatform[process.platform]?.map((arch) =>
46
+ resolve(
47
+ options.cwd,
48
+ options.outputDir,
49
+ `${config.binaryName}.${process.platform}-${arch}.node`,
50
+ ),
44
51
  )
45
52
 
46
53
  if (!srcFiles || !universalizers[process.platform]) {
@@ -52,9 +59,7 @@ export async function universalizeBinaries(userOptions: UniversalizeOptions) {
52
59
  debug(`Looking up source binaries to combine: `)
53
60
  debug(' %O', srcFiles)
54
61
 
55
- const srcFileLookup = await Promise.all(
56
- srcFiles.map((f) => fileExists(resolve(options.cwd, options.outputDir, f))),
57
- )
62
+ const srcFileLookup = await Promise.all(srcFiles.map((f) => fileExists(f)))
58
63
 
59
64
  const notFoundFiles = srcFiles.filter((_, i) => !srcFileLookup[i])
60
65
 
@@ -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
 
@@ -1,7 +1,7 @@
1
- import path from 'path'
1
+ import path from 'node:path'
2
2
 
3
+ import { input, select, checkbox, confirm } from '@inquirer/prompts'
3
4
  import { Option } from 'clipanion'
4
- import inquirer from 'inquirer'
5
5
 
6
6
  import { newProject } from '../api/new.js'
7
7
  import { BaseNewCommand } from '../def/new.js'
@@ -16,7 +16,7 @@ import { napiEngineRequirement } from '../utils/version.js'
16
16
  const debug = debugFactory('new')
17
17
 
18
18
  export class NewCommand extends BaseNewCommand {
19
- interactive = Option.Boolean('--interactive,-i', false, {
19
+ interactive = Option.Boolean('--interactive,-i', true, {
20
20
  description:
21
21
  'Ask project basic information interactively without just using the default.',
22
22
  })
@@ -37,9 +37,13 @@ export class NewCommand extends BaseNewCommand {
37
37
  const cmdOptions = super.getOptions()
38
38
 
39
39
  if (this.interactive) {
40
+ const targetPath: string = cmdOptions.path
41
+ ? cmdOptions.path
42
+ : await inquirerProjectPath()
43
+ cmdOptions.path = targetPath
40
44
  return {
41
45
  ...cmdOptions,
42
- name: await this.fetchName(path.parse(cmdOptions.path).base),
46
+ name: await this.fetchName(path.parse(targetPath).base),
43
47
  minNodeApiVersion: await this.fetchNapiVersion(),
44
48
  targets: await this.fetchTargets(),
45
49
  license: await this.fetchLicense(),
@@ -54,43 +58,31 @@ export class NewCommand extends BaseNewCommand {
54
58
  private async fetchName(defaultName: string): Promise<string> {
55
59
  return (
56
60
  this.$$name ??
57
- (await inquirer
58
- .prompt({
59
- type: 'input',
60
- name: 'name',
61
- message: 'Package name (the name field in your package.json file)',
62
- default: defaultName,
63
- })
64
- .then(({ name }) => name))
61
+ input({
62
+ message: 'Package name (the name field in your package.json file)',
63
+ default: defaultName,
64
+ })
65
65
  )
66
66
  }
67
67
 
68
68
  private async fetchLicense(): Promise<string> {
69
- return inquirer
70
- .prompt({
71
- type: 'input',
72
- name: 'license',
73
- message: 'License for open-sourced project',
74
- default: this.license,
75
- })
76
- .then(({ license }) => license)
69
+ return input({
70
+ message: 'License for open-sourced project',
71
+ default: this.license,
72
+ })
77
73
  }
78
74
 
79
75
  private async fetchNapiVersion(): Promise<number> {
80
- return inquirer
81
- .prompt({
82
- type: 'list',
83
- name: 'minNodeApiVersion',
84
- message: 'Minimum node-api version (with node version requirement)',
85
- loop: false,
86
- choices: new Array(8).fill(0).map((_, i) => ({
87
- name: `napi${i + 1} (${napiEngineRequirement(i + 1)})`,
88
- value: i + 1,
89
- })),
90
- // choice index
91
- default: this.minNodeApiVersion - 1,
92
- })
93
- .then(({ minNodeApiVersion }) => minNodeApiVersion)
76
+ return select({
77
+ message: 'Minimum node-api version (with node version requirement)',
78
+ loop: false,
79
+ choices: Array.from({ length: 8 }, (_, i) => ({
80
+ name: `napi${i + 1} (${napiEngineRequirement(i + 1)})`,
81
+ value: i + 1,
82
+ })),
83
+ // choice index
84
+ default: this.minNodeApiVersion - 1,
85
+ })
94
86
  }
95
87
 
96
88
  private async fetchTargets(): Promise<TargetTriple[]> {
@@ -98,22 +90,22 @@ export class NewCommand extends BaseNewCommand {
98
90
  return AVAILABLE_TARGETS.concat()
99
91
  }
100
92
 
101
- const { targets } = await inquirer.prompt({
102
- name: 'targets',
103
- type: 'checkbox',
93
+ const targets = await checkbox({
104
94
  loop: false,
105
95
  message: 'Choose target(s) your crate will be compiled to',
106
- default: this.enableDefaultTargets ? DEFAULT_TARGETS : [],
107
- choices: AVAILABLE_TARGETS,
96
+ choices: AVAILABLE_TARGETS.map((target) => ({
97
+ name: target,
98
+ value: target,
99
+ // @ts-expect-error
100
+ checked: DEFAULT_TARGETS.includes(target),
101
+ })),
108
102
  })
109
103
 
110
104
  return targets
111
105
  }
112
106
 
113
107
  private async fetchTypeDef(): Promise<boolean> {
114
- const { enableTypeDef } = await inquirer.prompt({
115
- name: 'enableTypeDef',
116
- type: 'confirm',
108
+ const enableTypeDef = await confirm({
117
109
  message: 'Enable type definition auto-generation',
118
110
  default: this.enableTypeDef,
119
111
  })
@@ -122,9 +114,7 @@ export class NewCommand extends BaseNewCommand {
122
114
  }
123
115
 
124
116
  private async fetchGithubActions(): Promise<boolean> {
125
- const { enableGithubActions } = await inquirer.prompt({
126
- name: 'enableGithubActions',
127
- type: 'confirm',
117
+ const enableGithubActions = await confirm({
128
118
  message: 'Enable Github Actions CI',
129
119
  default: this.enableGithubActions,
130
120
  })
@@ -132,3 +122,14 @@ export class NewCommand extends BaseNewCommand {
132
122
  return enableGithubActions
133
123
  }
134
124
  }
125
+
126
+ async function inquirerProjectPath(): Promise<string> {
127
+ return input({
128
+ message: 'Target path to create the project, relative to cwd.',
129
+ }).then((path) => {
130
+ if (!path) {
131
+ return inquirerProjectPath()
132
+ }
133
+ return path
134
+ })
135
+ }
@@ -15,11 +15,15 @@ export abstract class BaseArtifactsCommand extends Command {
15
15
  'The working directory of where napi command will be executed in, all other paths options are relative to this path',
16
16
  })
17
17
 
18
+ configPath?: string = Option.String('--config-path,-c', {
19
+ description: 'Path to `napi` config json file',
20
+ })
21
+
18
22
  packageJsonPath = Option.String('--package-json-path', 'package.json', {
19
23
  description: 'Path to `package.json`',
20
24
  })
21
25
 
22
- outputDir = Option.String('--output-dir,-o', './', {
26
+ outputDir = Option.String('--output-dir,-o,-d', './artifacts', {
23
27
  description:
24
28
  'Path to the folder where all built `.node` files put, same as `--output-dir` of build command',
25
29
  })
@@ -28,12 +32,19 @@ export abstract class BaseArtifactsCommand extends Command {
28
32
  description: 'Path to the folder where the npm packages put',
29
33
  })
30
34
 
35
+ buildOutputDir?: string = Option.String('--build-output-dir', {
36
+ description:
37
+ 'Path to the build output dir, only needed when targets contains `wasm32-wasi-*`',
38
+ })
39
+
31
40
  getOptions() {
32
41
  return {
33
42
  cwd: this.cwd,
43
+ configPath: this.configPath,
34
44
  packageJsonPath: this.packageJsonPath,
35
45
  outputDir: this.outputDir,
36
46
  npmDir: this.npmDir,
47
+ buildOutputDir: this.buildOutputDir,
37
48
  }
38
49
  }
39
50
  }
@@ -48,6 +59,10 @@ export interface ArtifactsOptions {
48
59
  * @default process.cwd()
49
60
  */
50
61
  cwd?: string
62
+ /**
63
+ * Path to `napi` config json file
64
+ */
65
+ configPath?: string
51
66
  /**
52
67
  * Path to `package.json`
53
68
  *
@@ -57,7 +72,7 @@ export interface ArtifactsOptions {
57
72
  /**
58
73
  * Path to the folder where all built `.node` files put, same as `--output-dir` of build command
59
74
  *
60
- * @default './'
75
+ * @default './artifacts'
61
76
  */
62
77
  outputDir?: string
63
78
  /**
@@ -66,13 +81,17 @@ export interface ArtifactsOptions {
66
81
  * @default 'npm'
67
82
  */
68
83
  npmDir?: string
84
+ /**
85
+ * Path to the build output dir, only needed when targets contains `wasm32-wasi-*`
86
+ */
87
+ buildOutputDir?: string
69
88
  }
70
89
 
71
90
  export function applyDefaultArtifactsOptions(options: ArtifactsOptions) {
72
91
  return {
73
92
  cwd: process.cwd(),
74
93
  packageJsonPath: 'package.json',
75
- outputDir: './',
94
+ outputDir: './artifacts',
76
95
  npmDir: 'npm',
77
96
  ...options,
78
97
  }