@napi-rs/cli 3.7.4 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +33 -0
  2. package/cli.mjs +9 -12
  3. package/dist/cli.js +9248 -1311
  4. package/dist/index.cjs +9268 -1331
  5. package/dist/index.d.cts +175 -157
  6. package/dist/index.d.ts +175 -157
  7. package/dist/index.js +9248 -1311
  8. package/docs/artifacts.md +33 -0
  9. package/docs/build.md +58 -0
  10. package/docs/create-npm-dirs.md +32 -0
  11. package/docs/new.md +39 -0
  12. package/docs/pre-publish.md +37 -0
  13. package/docs/rename.md +37 -0
  14. package/docs/universalize.md +31 -0
  15. package/docs/version.md +31 -0
  16. package/docs/wasi.md +161 -0
  17. package/package.json +11 -10
  18. package/src/api/__tests__/__snapshots__/templates.spec.ts.md +1019 -114
  19. package/src/api/__tests__/__snapshots__/templates.spec.ts.snap +0 -0
  20. package/src/api/__tests__/artifacts.spec.ts +17 -0
  21. package/src/api/__tests__/create-npm-dirs.spec.ts +14 -15
  22. package/src/api/__tests__/new.spec.ts +41 -5
  23. package/src/api/artifacts.ts +934 -108
  24. package/src/api/build.ts +1317 -188
  25. package/src/api/create-npm-dirs.ts +472 -101
  26. package/src/api/new.ts +354 -35
  27. package/src/api/pre-publish.ts +2845 -99
  28. package/src/api/rename.ts +1638 -124
  29. package/src/api/templates/js-binding.ts +216 -38
  30. package/src/api/templates/load-wasi-template.ts +1641 -111
  31. package/src/api/templates/wasi-worker-template.ts +32 -3
  32. package/src/commands/rename.ts +8 -3
  33. package/src/def/artifacts.ts +2 -2
  34. package/src/utils/__tests__/__snapshots__/target.spec.ts.md +2 -2
  35. package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
  36. package/src/utils/__tests__/misc.spec.ts +124 -3
  37. package/src/utils/__tests__/version.spec.ts +47 -1
  38. package/src/utils/config.ts +15 -2
  39. package/src/utils/metadata.ts +155 -47
  40. package/src/utils/misc.ts +6079 -0
  41. package/src/utils/target.ts +66 -8
  42. package/src/utils/typegen.ts +1223 -63
  43. package/src/utils/version.ts +96 -0
@@ -0,0 +1,33 @@
1
+ # Artifacts
2
+
3
+ > This file is generated by cli/codegen. Do not edit this file manually.
4
+
5
+ Copy artifacts from Github Actions into npm packages and ready to publish
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ # CLI
11
+ napi artifacts [--options]
12
+ ```
13
+
14
+ ```typescript
15
+ // Programatically
16
+ import { NapiCli } from '@napi-rs/cli'
17
+
18
+ new NapiCli().artifacts({
19
+ // options
20
+ })
21
+ ```
22
+
23
+ ## Options
24
+
25
+ | Options | CLI Options | type | required | default | description |
26
+ | --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ |
27
+ | | --help,-h | | | | get help |
28
+ | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path |
29
+ | configPath | --config-path,-c | string | false | | Path to `napi` config json file |
30
+ | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` |
31
+ | outputDir | --output-dir,-o,-d | string | false | './artifacts' | Path to the folder where all built `.node` files put, same as `--output-dir` of build command |
32
+ | npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put |
33
+ | buildOutputDir | --build-output-dir | string | false | | Path to the build output dir, only needed when targets contain a WASI target |
package/docs/build.md ADDED
@@ -0,0 +1,58 @@
1
+ # Build
2
+
3
+ > This file is generated by cli/codegen. Do not edit this file manually.
4
+
5
+ Build the NAPI-RS project
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ # CLI
11
+ napi build [--options]
12
+ ```
13
+
14
+ ```typescript
15
+ // Programatically
16
+ import { NapiCli } from '@napi-rs/cli'
17
+
18
+ new NapiCli().build({
19
+ // options
20
+ })
21
+ ```
22
+
23
+ ## Options
24
+
25
+ | Options | CLI Options | type | required | default | description |
26
+ | ----------------- | --------------------- | -------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
27
+ | | --help,-h | | | | get help |
28
+ | target | --target,-t | string | false | | Build for the target triple, bypassed to `cargo build --target` |
29
+ | cwd | --cwd | string | false | | The working directory of where napi command will be executed in, all other paths options are relative to this path |
30
+ | manifestPath | --manifest-path | string | false | | Path to `Cargo.toml` |
31
+ | configPath | --config-path,-c | string | false | | Path to `napi` config json file |
32
+ | packageJsonPath | --package-json-path | string | false | | Path to `package.json` |
33
+ | targetDir | --target-dir | string | false | | Directory for all crate generated artifacts, see `cargo build --target-dir` |
34
+ | outputDir | --output-dir,-o | string | false | | Path to where all the built files would be put. Default to the crate folder |
35
+ | platform | --platform | boolean | false | | Add platform triple to the generated nodejs binding file, eg: `[name].linux-x64-gnu.node` |
36
+ | jsPackageName | --js-package-name | string | false | | Package name in generated js binding file. Only works with `--platform` flag |
37
+ | constEnum | --const-enum | boolean | false | | Whether generate const enum for typescript bindings |
38
+ | runtimeStringEnum | --runtime-string-enum | boolean | false | | Emit `#[napi(string_enum)]` enums as runtime enums (`export declare enum`) under `--no-const-enum`. Default: type-only union. |
39
+ | jsBinding | --js | string | false | | Path and filename of generated JS binding file. Only works with `--platform` flag. Relative to `--output-dir`. |
40
+ | noJsBinding | --no-js | boolean | false | | Whether to disable the generation JS binding file. Only works with `--platform` flag. |
41
+ | dts | --dts | string | false | | Path and filename of generated type def file. Relative to `--output-dir` |
42
+ | dtsHeader | --dts-header | string | false | | Custom file header for generated type def file. Only works when `typedef` feature enabled. |
43
+ | noDtsHeader | --no-dts-header | boolean | false | | Whether to disable the default file header for generated type def file. Only works when `typedef` feature enabled. |
44
+ | dtsCache | --dts-cache | boolean | false | true | Whether to enable the dts cache, default to true |
45
+ | esm | --esm | boolean | false | | Whether to emit an ESM JS binding file instead of CJS format. Only works with `--platform` flag. |
46
+ | strip | --strip,-s | boolean | false | | Whether strip the library to achieve the minimum file size |
47
+ | release | --release,-r | boolean | false | | Build in release mode |
48
+ | verbose | --verbose,-v | boolean | false | | Verbosely log build command trace |
49
+ | bin | --bin | string | false | | Build only the specified binary |
50
+ | package | --package,-p | string | false | | Build the specified library or the one at cwd |
51
+ | profile | --profile | string | false | | Build artifacts with the specified profile |
52
+ | crossCompile | --cross-compile,-x | boolean | false | | [experimental] cross compile by replacing the cargo subcommand: Windows MSVC targets from a non-Windows host build with `cargo-xwin` (`windows-gnu` targets are rejected, `cargo-xwin` cannot handle them), non-Windows targets build with `cargo-zigbuild` (requires `zig` on PATH). The selected subcommand is auto-installed on first use. Cannot be combined with `--use-cross`, `--use-napi-cross` or `--watch` |
53
+ | useCross | --use-cross | boolean | false | | [experimental] not recommended, prefer `--cross-compile` or `--use-napi-cross`: build in a Docker or Podman container with [cross](https://github.com/cross-rs/cross), which must be installed manually and needs a running container engine. Cannot be combined with `--cross-compile`, `--use-napi-cross` or `--watch` |
54
+ | useNapiCross | --use-napi-cross | boolean | false | | [experimental] download a prebuilt gcc cross toolchain from `@napi-rs/cross-toolchain` (glibc 2.17) and set linker and C compiler environment variables. Linux glibc targets only (x64, arm64, armv7, ppc64le, s390x) on a Linux x64 or arm64 host, any other target or host errors. Cannot be combined with `--cross-compile` or `--use-cross` |
55
+ | watch | --watch,-w | boolean | false | | watch the crate changes and build continuously with `cargo-watch` crates |
56
+ | features | --features,-F | string[] | false | | Space-separated list of features to activate |
57
+ | allFeatures | --all-features | boolean | false | | Activate all available features |
58
+ | noDefaultFeatures | --no-default-features | boolean | false | | Do not activate the `default` feature |
@@ -0,0 +1,32 @@
1
+ # Create Npm Dirs
2
+
3
+ > This file is generated by cli/codegen. Do not edit this file manually.
4
+
5
+ Create npm package dirs for different platforms
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ # CLI
11
+ napi create-npm-dirs [--options]
12
+ ```
13
+
14
+ ```typescript
15
+ // Programatically
16
+ import { NapiCli } from '@napi-rs/cli'
17
+
18
+ new NapiCli().createNpmDirs({
19
+ // options
20
+ })
21
+ ```
22
+
23
+ ## Options
24
+
25
+ | Options | CLI Options | type | required | default | description |
26
+ | --------------- | ------------------- | ------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ |
27
+ | | --help,-h | | | | get help |
28
+ | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path |
29
+ | configPath | --config-path,-c | string | false | | Path to `napi` config json file |
30
+ | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` |
31
+ | npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put |
32
+ | dryRun | --dry-run | boolean | false | false | Dry run without touching file system |
package/docs/new.md ADDED
@@ -0,0 +1,39 @@
1
+ # New
2
+
3
+ > This file is generated by cli/codegen. Do not edit this file manually.
4
+
5
+ Create a new project with pre-configured boilerplate
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ # CLI
11
+ napi new <path> [--options]
12
+ ```
13
+
14
+ ```typescript
15
+ // Programatically
16
+ import { NapiCli } from '@napi-rs/cli'
17
+
18
+ new NapiCli().new({
19
+ // options
20
+ })
21
+ ```
22
+
23
+ ## Options
24
+
25
+ | Options | CLI Options | type | required | default | description |
26
+ | -------------------- | ------------------------ | -------- | -------- | ------- | -------------------------------------------------------------------------------- |
27
+ | | --help,-h | | | | get help |
28
+ | path | <path> | false | string | | The path where the NAPI-RS project will be created. |
29
+ | name | --name,-n | string | false | | The name of the project, default to the name of the directory if not provided |
30
+ | minNodeApiVersion | --min-node-api,-v | number | false | 4 | The minimum Node-API version to support |
31
+ | packageManager | --package-manager | string | false | 'yarn' | The package manager to use. Only support yarn 4.x for now. |
32
+ | license | --license,-l | string | false | 'MIT' | License for open-sourced project |
33
+ | targets | --targets,-t | string[] | false | [] | All targets the crate will be compiled for. |
34
+ | enableDefaultTargets | --enable-default-targets | boolean | false | true | Whether enable default targets |
35
+ | enableAllTargets | --enable-all-targets | boolean | false | false | Whether enable all targets |
36
+ | enableTypeDef | --enable-type-def | boolean | false | true | Whether enable the `type-def` feature for typescript definitions auto-generation |
37
+ | enableGithubActions | --enable-github-actions | boolean | false | true | Whether generate preconfigured GitHub Actions workflow |
38
+ | testFramework | --test-framework | string | false | 'ava' | The JavaScript test framework to use, only support `ava` for now |
39
+ | dryRun | --dry-run | boolean | false | false | Whether to run the command in dry-run mode |
@@ -0,0 +1,37 @@
1
+ # Pre Publish
2
+
3
+ > This file is generated by cli/codegen. Do not edit this file manually.
4
+
5
+ Update package.json and copy addons into per platform packages
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ # CLI
11
+ napi pre-publish [--options]
12
+ ```
13
+
14
+ ```typescript
15
+ // Programatically
16
+ import { NapiCli } from '@napi-rs/cli'
17
+
18
+ new NapiCli().prePublish({
19
+ // options
20
+ })
21
+ ```
22
+
23
+ ## Options
24
+
25
+ | Options | CLI Options | type | required | default | description |
26
+ | ------------------- | ------------------------- | ---------------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ |
27
+ | | --help,-h | | | | get help |
28
+ | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path |
29
+ | configPath | --config-path,-c | string | false | | Path to `napi` config json file |
30
+ | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` |
31
+ | npmDir | --npm-dir,-p | string | false | 'npm' | Path to the folder where the npm packages put |
32
+ | tagStyle | --tag-style,--tagstyle,-t | 'npm' \| 'lerna' | false | 'lerna' | git tag style, `npm` or `lerna` |
33
+ | ghRelease | --gh-release | boolean | false | true | Whether create GitHub release |
34
+ | ghReleaseName | --gh-release-name | string | false | | GitHub release name |
35
+ | ghReleaseId | --gh-release-id | string | false | | Existing GitHub release id |
36
+ | skipOptionalPublish | --skip-optional-publish | boolean | false | false | Whether skip optionalDependencies packages publish |
37
+ | dryRun | --dry-run | boolean | false | false | Dry run without touching file system |
package/docs/rename.md ADDED
@@ -0,0 +1,37 @@
1
+ # Rename
2
+
3
+ > This file is generated by cli/codegen. Do not edit this file manually.
4
+
5
+ Rename the NAPI-RS project
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ # CLI
11
+ napi rename [--options]
12
+ ```
13
+
14
+ ```typescript
15
+ // Programatically
16
+ import { NapiCli } from '@napi-rs/cli'
17
+
18
+ new NapiCli().rename({
19
+ // options
20
+ })
21
+ ```
22
+
23
+ ## Options
24
+
25
+ | Options | CLI Options | type | required | default | description |
26
+ | --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ |
27
+ | | --help,-h | | | | get help |
28
+ | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path |
29
+ | configPath | --config-path,-c | string | false | | Path to `napi` config json file |
30
+ | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` |
31
+ | npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put |
32
+ | name | --name,-n | string | false | | The new name of the project |
33
+ | binaryName | --binary-name,-b | string | false | | The new binary name *.node files |
34
+ | packageName | --package-name | string | false | | The new package name of the project |
35
+ | manifestPath | --manifest-path | string | false | 'Cargo.toml' | Path to `Cargo.toml` |
36
+ | repository | --repository | string | false | | The new repository of the project |
37
+ | description | --description | string | false | | The new description of the project |
@@ -0,0 +1,31 @@
1
+ # Universalize
2
+
3
+ > This file is generated by cli/codegen. Do not edit this file manually.
4
+
5
+ Combile built binaries into one universal binary
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ # CLI
11
+ napi universalize [--options]
12
+ ```
13
+
14
+ ```typescript
15
+ // Programatically
16
+ import { NapiCli } from '@napi-rs/cli'
17
+
18
+ new NapiCli().universalize({
19
+ // options
20
+ })
21
+ ```
22
+
23
+ ## Options
24
+
25
+ | Options | CLI Options | type | required | default | description |
26
+ | --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ |
27
+ | | --help,-h | | | | get help |
28
+ | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path |
29
+ | configPath | --config-path,-c | string | false | | Path to `napi` config json file |
30
+ | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` |
31
+ | outputDir | --output-dir,-o | string | false | './' | Path to the folder where all built `.node` files put, same as `--output-dir` of build command |
@@ -0,0 +1,31 @@
1
+ # Version
2
+
3
+ > This file is generated by cli/codegen. Do not edit this file manually.
4
+
5
+ Update version in created npm packages
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ # CLI
11
+ napi version [--options]
12
+ ```
13
+
14
+ ```typescript
15
+ // Programatically
16
+ import { NapiCli } from '@napi-rs/cli'
17
+
18
+ new NapiCli().version({
19
+ // options
20
+ })
21
+ ```
22
+
23
+ ## Options
24
+
25
+ | Options | CLI Options | type | required | default | description |
26
+ | --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ |
27
+ | | --help,-h | | | | get help |
28
+ | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path |
29
+ | configPath | --config-path,-c | string | false | | Path to `napi` config json file |
30
+ | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` |
31
+ | npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put |
package/docs/wasi.md ADDED
@@ -0,0 +1,161 @@
1
+ # WASI targets and loaders
2
+
3
+ Use `wasm32-wasip1-threads` for the threaded runtime and `wasm32-wasip1` for
4
+ the threadless runtime. The historical `wasm32-wasi` and
5
+ `wasm32-wasi-preview1-threads` spellings are accepted as aliases for
6
+ `wasm32-wasip1-threads`; they retain the existing `<package>-wasm32-wasi`
7
+ package and artifact identity. Configuring more than one alias for the same
8
+ artifact set is an error.
9
+
10
+ WASI packages use emnapi v2, whose runtime is ESM-only. The generated
11
+ CommonJS entry therefore supports Node.js `^20.19.0`, `^22.13.0`, and
12
+ `>=23.5.0`, where `require()` can load ESM without an experimental warning.
13
+ Browser and workerd entries use ESM directly, but share the same package
14
+ engine contract.
15
+
16
+ ## Selecting a WASI flavor in Node.js
17
+
18
+ The root Node.js entry prefers a native addon. When native loading is
19
+ unavailable, it tries local WASI loaders and then installed flavor packages.
20
+ Within each group the default order is threaded (`wasm32-wasi`) and then
21
+ threadless (`wasm32-wasip1`).
22
+
23
+ Set `NAPI_RS_WASI_FLAVOR` to a generated flavor identity to select it through
24
+ the root package:
25
+
26
+ ```sh
27
+ NAPI_RS_WASI_FLAVOR=wasm32-wasip1 node app.js
28
+ ```
29
+
30
+ The selector enters the WASI path without requiring
31
+ `NAPI_RS_FORCE_WASI`, skips every other WASI flavor, and does not fall back to
32
+ a native addon if the selected flavor cannot load. This makes the result
33
+ deterministic when both optional flavor packages are installed, including
34
+ isolated pnpm and Yarn PnP layouts. Use `wasm32-wasi` to select the threaded
35
+ flavor. An unsupported value reports the flavor identities generated for that
36
+ package.
37
+
38
+ Without `NAPI_RS_WASI_FLAVOR`, existing behavior is unchanged.
39
+ `NAPI_RS_FORCE_WASI=true` prefers the default WASI fallback chain but retains a
40
+ lazy native fallback, while `NAPI_RS_FORCE_WASI=error` requires some generated
41
+ WASI flavor to load.
42
+
43
+ The root package exposes deferred workerd and Wasm entries. In a Workers
44
+ project built by Wrangler:
45
+
46
+ ```js
47
+ import { createInstance, dispose, instantiate } from '<package>/workerd'
48
+ import wasmModule from '<package>/wasm.wasm'
49
+
50
+ const binding = await instantiate(wasmModule)
51
+ ```
52
+
53
+ Prefer these root-package imports. They resolve through the root package's
54
+ optional dependency and work with isolated package-manager layouts such as
55
+ pnpm and Yarn PnP. The existing
56
+ `<package>-wasm32-wasip1/workerd`, `./wasm`, and `./wasm.wasm` flavor-package
57
+ exports remain available when that flavor package is installed directly.
58
+
59
+ Wrangler's built-in Wasm loader selects module handling from the import
60
+ specifier's `.wasm` suffix, so Workers projects should use the extensionful
61
+ `./wasm.wasm` export shown above. This ordinary default-import form is
62
+ Wrangler/bundler behavior, not a portable Node.js Wasm import.
63
+
64
+ Node.js 24 and later can load the same export as a `WebAssembly.Module` with a
65
+ source-phase import:
66
+
67
+ ```js
68
+ import source wasmModule from '<package>/wasm.wasm'
69
+ import { instantiate } from '<package>/workerd'
70
+
71
+ const binding = await instantiate(wasmModule)
72
+ ```
73
+
74
+ On older Node.js versions, or when source-phase imports are unavailable,
75
+ compile the exported bytes explicitly:
76
+
77
+ ```js
78
+ import { readFile } from 'node:fs/promises'
79
+ import { createRequire } from 'node:module'
80
+ import { instantiate } from '<package>/workerd'
81
+
82
+ const require = createRequire(import.meta.url)
83
+ const wasmPath = require.resolve('<package>/wasm.wasm')
84
+ const wasmModule = await WebAssembly.compile(await readFile(wasmPath))
85
+ const binding = await instantiate(wasmModule)
86
+ ```
87
+
88
+ The packages also expose `./wasm` for bundlers that explicitly configure the
89
+ resolved file as a compiled `WebAssembly.Module`. Both Wasm aliases include
90
+ TypeScript declarations whose default export is `WebAssembly.Module`.
91
+
92
+ `instantiate()` owns a module-local singleton and deduplicates concurrent calls
93
+ for the same `WebAssembly.Module`. Call `dispose()` before replacing that
94
+ module. Calls that begin while disposal is in progress wait for it and create a
95
+ fresh singleton after cleanup succeeds. The deferred loader automatically
96
+ starts singleton disposal when Node.js emits `beforeExit`; a later listener
97
+ that calls `instantiate()` observes that state immediately and receives a
98
+ fresh singleton after cleanup rather than exports that are being destroyed. If
99
+ the first singleton is still initializing, cleanup waits for that initialization
100
+ to settle before destroying its context.
101
+ `createInstance()` creates an independent instance and returns
102
+ `{ exports, dispose }`; call and await the returned `dispose()` when that
103
+ instance is no longer needed. It consistently returns a promise, including
104
+ when emnapi cleanup completes synchronously. Independent instances are not
105
+ automatically disposed at
106
+ `beforeExit`, while initializing or after success, so retained exports remain
107
+ usable if a listener schedules more work; their cleanup ownership stays
108
+ explicit. The `./workerd` package export includes TypeScript declarations;
109
+ `exports` is typed from the addon's root package when napi-rs type generation is
110
+ enabled. Intentionally untyped packages expose it as
111
+ `Record<string, unknown>`, so strict TypeScript consumers can use the lifecycle
112
+ API without a broken import of the declaration-less root package. If
113
+ initialization fails and immediate context rollback also fails, the loader
114
+ retains that cleanup ownership so a later `beforeExit` pass can retry it.
115
+ `dispose()` still attempts those retained rollbacks when singleton cleanup
116
+ fails, while preserving the singleton error as the primary rejection.
117
+
118
+ `Context.destroy()` is synchronous in emnapi's public contract. The deferred
119
+ loader also contains nonconforming promise-like results defensively. Keep and
120
+ await the first `dispose()` promise. Direct instance-disposal recursion and
121
+ module lifecycle calls that re-enter from a pending module-owned destroy reject
122
+ with `ERR_NAPI_WASI_LIFECYCLE_REENTRY` instead of joining a promise cycle.
123
+ This guard lasts until a nonconforming async destroy settles; successful
124
+ independent-instance cleanup does not block singleton lifecycle calls.
125
+ Conforming synchronous emnapi cleanup coalesces concurrent `dispose()` calls.
126
+ Replacement `instantiate()` calls wait for the complete public cleanup,
127
+ including every retained failed-initialization rollback present before cleanup
128
+ finishes.
129
+
130
+ The eager CommonJS WASI loader keeps its emnapi context alive for the process
131
+ lifetime. Node.js can emit `beforeExit` repeatedly when a listener schedules
132
+ more work, and cached eager exports must remain usable after every such cycle.
133
+ For threaded targets, initialization owns every worker returned by
134
+ `onCreateWorker`. If initialization fails, the loader rolls the context back
135
+ while those workers remain alive so the Rust runtime can quiesce, then starts
136
+ each remaining worker's termination exactly once after cleanup settles.
137
+ At the actual `exit` event, the loader makes one synchronous best-effort
138
+ `Context.destroy()` call so emnapi's synchronous cleanup queue can run.
139
+ Consumers that need deterministic cleanup before process exit should use the
140
+ deferred loader and call its `dispose()` function, or the `dispose` returned by
141
+ `createInstance()`.
142
+
143
+ When type generation is disabled, the generated browser root exposes the
144
+ binding as its default export. `napi new` also removes the template's
145
+ `index.d.ts` and declaration metadata instead of publishing stale template
146
+ types.
147
+
148
+ The deferred loader accepts only a precompiled `WebAssembly.Module`. It does
149
+ not fetch or compile bytes at runtime.
150
+
151
+ Generated WASI packages intentionally omit npm's `cpu` and `os` fields. The
152
+ module runs inside the host process, so `wasm32` or host-OS restrictions would
153
+ make npm reject a direct install or skip the optional dependency on otherwise
154
+ supported hosts.
155
+
156
+ `napi.wasm.initialMemory` is measured in 64 KiB WebAssembly pages. The regular
157
+ Node and browser loaders retain the historical 4,000-page (250 MiB) default.
158
+ The deferred `./workerd` loader defaults to 1,024 pages (64 MiB), leaving
159
+ headroom under workerd's 128 MiB isolate limit. An explicit
160
+ `napi.wasm.initialMemory` value applies to every loader, so keep it within the
161
+ target isolate's limit after measuring the addon's actual requirements.
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@napi-rs/cli",
3
- "version": "3.7.4",
3
+ "version": "3.8.0",
4
4
  "description": "Cli tools for napi-rs",
5
5
  "author": "LongYinan <lynweklm@gmail.com>",
6
6
  "homepage": "https://napi.rs/",
7
7
  "license": "MIT",
8
8
  "type": "module",
9
9
  "engines": {
10
- "node": ">= 16"
10
+ "node": "^20.17.0 || ^22.13.0 || >= 23.5.0"
11
11
  },
12
12
  "bin": {
13
13
  "napi": "./dist/cli.js",
@@ -25,6 +25,7 @@
25
25
  },
26
26
  "files": [
27
27
  "dist",
28
+ "docs",
28
29
  "src",
29
30
  "!__tests__"
30
31
  ],
@@ -66,15 +67,16 @@
66
67
  "@octokit/rest": "^22.0.1",
67
68
  "clipanion": "^4.0.0-rc.4",
68
69
  "colorette": "^2.0.20",
69
- "emnapi": "^1.11.1",
70
+ "emnapi": "2.0.0-alpha.3",
70
71
  "es-toolkit": "^1.47.0",
71
72
  "js-yaml": "^4.2.0",
72
73
  "obug": "^2.1.2",
73
74
  "semver": "^7.8.2",
74
- "typanion": "^3.14.0"
75
+ "typanion": "^3.14.0",
76
+ "typescript": "^6.0.3"
75
77
  },
76
78
  "devDependencies": {
77
- "@emnapi/runtime": "^1.11.0",
79
+ "@emnapi/runtime": "2.0.0-alpha.3",
78
80
  "@oxc-node/core": "^0.1.0",
79
81
  "@std/toml": "npm:@jsr/std__toml@^1.0.11",
80
82
  "@types/inquirer": "^9.0.9",
@@ -84,14 +86,13 @@
84
86
  "ava": "^8.0.1",
85
87
  "empathic": "^2.0.1",
86
88
  "env-paths": "^4.0.0",
87
- "oxc-parser": "^0.140.0",
89
+ "oxc-parser": "^0.142.0",
88
90
  "prettier": "^3.8.3",
89
91
  "tsdown": "^0.22.2",
90
- "tslib": "^2.8.1",
91
- "typescript": "^6.0.3"
92
+ "tslib": "^2.8.1"
92
93
  },
93
94
  "peerDependencies": {
94
- "@emnapi/runtime": "^1.7.1"
95
+ "@emnapi/runtime": "2.0.0-alpha.3"
95
96
  },
96
97
  "peerDependenciesMeta": {
97
98
  "@emnapi/runtime": {
@@ -105,7 +106,7 @@
105
106
  "scripts": {
106
107
  "codegen": "node --import @oxc-node/core/register ./codegen/index.ts",
107
108
  "build": "tsdown",
108
- "test": "node --import @oxc-node/core/register ../node_modules/ava/entrypoints/cli.js"
109
+ "test": "yarn run build && node --import @oxc-node/core/register ../node_modules/ava/entrypoints/cli.js"
109
110
  },
110
111
  "ava": {
111
112
  "extensions": [