skif-cli 0.0.0 → 0.1.1

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.
@@ -0,0 +1,178 @@
1
+ # Attributions
2
+
3
+ This document acknowledges sources of forked or copied code used in the skif project. Ordinary
4
+ crates.io dependencies are tracked in `Cargo.toml` / `Cargo.lock` and governed by `deny.toml`; this
5
+ file covers code that was **copied or derived** into the repository from other projects.
6
+
7
+ ## sherif
8
+
9
+ A zero-config linter for TypeScript and JavaScript monorepos. skif began as a fork of sherif and was
10
+ rebuilt as a clean, restructured codebase; the workspace and manifest rules are ported from it.
11
+
12
+ - **Source**: <https://github.com/QuiiBz/sherif>
13
+ - **Upstream commit**: `1eeac7104af1a6143d7f5d17d18d11635222ca8d`
14
+ - **License**: MIT
15
+ - **Authors**: Tom Lienard and the sherif contributors
16
+ - **Copyright**: Copyright (c) 2023 Tom Lienard
17
+ - **Location**: `crates/skif-rules` and `crates/skif-workspace` (rule logic, package and workspace collection)
18
+ - **Purpose**: Monorepo workspace rules (dependency hygiene, root and member `package.json`
19
+ checks, workspace discovery for npm, yarn and pnpm) and their autofixes.
20
+
21
+ ### Modifications
22
+
23
+ - Renamed from sherif to skif; the crate, binary, repository, and distribution surface are new.
24
+ - Restructured from a single binary crate into a library-first workspace of `skif-*` crates.
25
+ - Rules are rewritten and renamed to stable rule IDs, with structured diagnostics instead of
26
+ pre-rendered messages.
27
+ - Configuration comes from `skif.toml` / `.skif.toml` and CLI flags; the `sherif` key in
28
+ `package.json` and the `sherif.config.jsonc` / `.sherifrc.jsonc` files are not supported.
29
+ - The upstream GitHub Action, npm packaging, and website assets were removed.
30
+
31
+ ### License Compatibility
32
+
33
+ MIT is permissive and compatible with skif's MIT license. The upstream license text follows.
34
+
35
+ ```text
36
+ MIT License
37
+
38
+ Copyright (c) 2023 Tom Lienard
39
+
40
+ Permission is hereby granted, free of charge, to any person obtaining a copy
41
+ of this software and associated documentation files (the "Software"), to deal
42
+ in the Software without restriction, including without limitation the rights
43
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44
+ copies of the Software, and to permit persons to whom the Software is
45
+ furnished to do so, subject to the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be included in all
48
+ copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
56
+ SOFTWARE.
57
+ ```
58
+
59
+ ## syncpack specifier
60
+
61
+ The npm dependency specifier parser and comparator from syncpack, a consistent-versions tool for
62
+ JavaScript monorepos.
63
+
64
+ - **Source**: <https://github.com/JamieMason/syncpack>
65
+ - **Upstream path**: `crates/syncpack-specifier`
66
+ - **Upstream commit**: `958d30689ac24b60623258630242330bd6d0264b`
67
+ - **License**: MIT
68
+ - **Copyright**: Copyright (c) 2017-2023 Jamie Mason
69
+ - **Location**: `crates/skif-specifier`
70
+ - **Purpose**: Parsing, classification, ordering, and semver comparison of npm dependency
71
+ specifiers (exact, ranges, workspace protocol, aliases, git, tags, and so on).
72
+
73
+ ### Modifications
74
+
75
+ 1. Every vendored source file carries a header comment naming its upstream path and commit.
76
+ 2. Thread safety: `Rc` is replaced with `Arc` and `OnceCell` with `OnceLock`, and the
77
+ `thread_local!` caches are removed. `Specifier::new` and `Specifier::create` parse without
78
+ caching; the caller-owned `SpecifierCache` (`RwLock<HashMap>`, `get_or_parse`) provides
79
+ interning. Static assertions check that `Specifier` and `SpecifierCache` are `Send + Sync`.
80
+ 3. `node-semver` 2.2.0 is replaced with `nodejs-semver` 7.0.0 (Apache-2.0). `Range` and `Version`
81
+ parsing, `satisfies`, and `allows_any` map one to one; the only adaptation is that version
82
+ components are read through accessor methods (`major()`, `minor()`, `patch()`,
83
+ `pre_release()`) instead of public fields.
84
+ 4. The upstream tests and test data are kept. `eq_hash_test::specifier_eq_by_raw_string` now
85
+ obtains pointer-equal specifiers through `SpecifierCache` because `Specifier::new` no longer
86
+ interns. The upstream `#[ignore]`d prerelease test stays ignored, with a reason attached.
87
+ 5. Lint fixes to the skif workspace standard (clippy pedantic, no `unwrap`/`expect` in non-test
88
+ code where avoidable); two crate-level lint allowances and a per-function `expect_used`
89
+ allowance are documented in place. The code is formatted with the workspace `rustfmt.toml`,
90
+ and the benchmark crate name is updated.
91
+ 6. Hardening: `Major`, `Minor`, `RangeMajor`, `RangeMinor` and `Latest` parse their padded
92
+ versions and ranges eagerly (no `OnceLock`, no `expect`); numbers that `nodejs-semver` rejects
93
+ (for example `99999999999999999999`, above 2^53 - 1) now yield `Specifier::Unsupported`
94
+ instead of panicking later. `Ord` breaks semantic ties on the raw string so that
95
+ `cmp == Equal` exactly when `==` does (`1.2.3` and `=1.2.3` no longer compare equal).
96
+ `is_complex_range` accepts unspaced `||` unions, prerelease tags and x-range operands
97
+ (`1.x || 2.x`), and only a bare `*`, `x` or `X` is `Latest` (`*foo` is `Unsupported`, `xyz` is
98
+ a `Tag`). Property tests cover panic freedom and the `Ord`/`Eq` law.
99
+ 7. The version-group state machine in `crates/skif-rules/src/policy/visit.rs` is a Rust re-implementation of
100
+ the visitors in syncpack's `src/version_group/*.rs` (preferred-semver, pinned, banned, ignored, same-range,
101
+ same-minor, snapped-to) at the same commit, on skif's own instance model; no syncpack code is copied. It differs
102
+ in having no strict mode, leaving `catalog:` references to the catalog rules, and treating specifiers that
103
+ cannot carry a semver range as having no preferred range.
104
+
105
+ ### License Compatibility
106
+
107
+ MIT is permissive and compatible with skif's MIT license. The upstream license text follows.
108
+
109
+ ```text
110
+ MIT License
111
+
112
+ Copyright (c) 2017-2023 Jamie Mason
113
+
114
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
115
+ this software and associated documentation files (the "Software"), to deal in
116
+ the Software without restriction, including without limitation the rights to
117
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
118
+ the Software, and to permit persons to whom the Software is furnished to do so,
119
+ subject to the following conditions:
120
+
121
+ The above copyright notice and this permission notice shall be included in all
122
+ copies or substantial portions of the Software.
123
+
124
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
125
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
126
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
127
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
128
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
129
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
130
+ ```
131
+
132
+ ## knip
133
+
134
+ A tool that finds unused files, exports and dependencies in JavaScript and TypeScript projects. skif's JS
135
+ analysis follows its semantics and its plugin set; the behaviour is re-implemented in Rust on oxc, and no knip
136
+ source file is copied, apart from the data noted below.
137
+
138
+ - **Source**: <https://github.com/webpro-nl/knip>
139
+ - **Upstream commit**: `da07b6e9887f9a1eb08545da29755b7f9d309bca`
140
+ - **License**: ISC
141
+ - **Authors**: Lars Kappert and the knip contributors
142
+ - **Copyright**: Copyright (c) 2022-2026 Lars Kappert
143
+ - **Location**: `crates/skif-js` (issue types, module graph and usage rules) and `crates/skif-js-plugins` (the
144
+ plugin table, entry patterns and configuration readers)
145
+ - **Purpose**: Unused and unlisted dependency, unused export, unresolved import and dead file analysis.
146
+
147
+ ### Modifications
148
+
149
+ - The behaviour of knip's issue types, plugins and production mode is re-implemented in Rust; no TypeScript
150
+ source is translated line by line.
151
+ - Analysis is static: configuration files are read with oxc, never executed, and tools are not run to ask for
152
+ their entries.
153
+ - The list of binaries that are never reported as unlisted is adapted from knip's `constants.ts`.
154
+ - The plugin table is declarative data with optional resolvers, keyed by knip's plugin names. `aws-cdk` and
155
+ `browser-extension` are skif's own: knip has no plugin of either name at the pinned commit.
156
+ - Rule ids, severities and configuration (`skif.toml`) are skif's own.
157
+
158
+ ### License Compatibility
159
+
160
+ ISC is permissive and compatible with skif's MIT license. The upstream license text follows.
161
+
162
+ ```text
163
+ ISC License
164
+
165
+ Copyright (c) 2022-2026 Lars Kappert
166
+
167
+ Permission to use, copy, modify, and/or distribute this software for any
168
+ purpose with or without fee is hereby granted, provided that the above
169
+ copyright notice and this permission notice appear in all copies.
170
+
171
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
172
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
173
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
174
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
175
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
176
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
177
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
178
+ ```
package/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # skif
2
+
3
+ [skif](https://github.com/Goldziher/skif) is a dependency and package-manager linter, auditor and enforcer for
4
+ JavaScript and TypeScript, with first-class monorepo support: workspace rules and version and catalog policies,
5
+ for npm, pnpm, Yarn and Bun. It also finds unused, unlisted and unresolved dependencies, unused files and
6
+ exports.
7
+
8
+ ## Requirements
9
+
10
+ Node.js versions that are not end-of-life (22, 24 and 26 today; see the
11
+ [Node.js release schedule](https://nodejs.org/en/about/previous-releases)) or Bun 1.x. Older versions may work but are not
12
+ supported. The package is ESM only; from CommonJS use `import()`, or `require()` on
13
+ Node.js 22.12 or newer.
14
+
15
+ ## Install
16
+
17
+ ```sh
18
+ pnpm add --save-dev skif-cli
19
+ # or: npm install --save-dev skif-cli / yarn add --dev skif-cli / bun add --dev skif-cli
20
+ ```
21
+
22
+ Run it without installing:
23
+
24
+ ```sh
25
+ pnpm dlx skif-cli
26
+ npx skif-cli
27
+ bunx -p skif-cli skif
28
+ ```
29
+
30
+ ## Use from code
31
+
32
+ ```js
33
+ import { lint, lintAsync, run } from "skif-cli";
34
+
35
+ const report = JSON.parse(lint("./my-monorepo", { production: true }));
36
+ console.log(report.summary);
37
+
38
+ const outcome = await lintAsync("./my-monorepo");
39
+ if (outcome.error) console.error(outcome.error.kind, outcome.error.message, outcome.error.path);
40
+ else console.log(JSON.parse(outcome.report).summary);
41
+
42
+ const exitCode = run(["--format", "json", "./my-monorepo"]);
43
+ ```
44
+
45
+ - `lint(path, options?)` lints the project containing `path` and returns the JSON report as a string. With
46
+ `{ recursive: true }` it lints every workspace and standalone package at or below `path`, like `skif -r`, and
47
+ the report gains a `roots` array, an `errors` array listing the roots that could not be loaded (the others are still
48
+ linted) and, when the depth limit stopped the search, a `truncated` array of the directories it did not enter. It
49
+ prints nothing and writes no files. When the lint cannot run it throws an `Error` with `kind` and, when there is one,
50
+ `path` properties, the fields `lintAsync` returns in `error`. It blocks the event loop, so use `lintAsync` in a server. `{ config: "path/to/skif.toml" }`
51
+ uses that file (and the files it extends) instead of discovering configuration files, like `--config`, and
52
+ `{ noConfig: true }` reads none, like `--no-config`.
53
+ - `lintAsync(path, options?)` does the same on a worker thread and resolves with `{ report }` or, when the lint
54
+ cannot run, `{ error: { kind, message, path? } }` (`kind` is `config`, `workspace`, `io` or `internal`). Both
55
+ functions read the configuration file the way the command line does.
56
+ - `run(argv)` runs the full command line (`argv` excludes the program name) and returns its exit code. Output
57
+ streams to the process's stdout and stderr.
58
+
59
+ Types ship in `index.d.ts`.
60
+
61
+ ## How the native code gets here
62
+
63
+ skif is a native addon built with [napi-rs](https://napi.rs). There is no install script and nothing is
64
+ downloaded at install time or at first run. This package lists one platform package per target as
65
+ `optionalDependencies`, each carrying the prebuilt addon and declaring the `os`, `cpu` and, on Linux, `libc` it is
66
+ for. Your package manager installs only the one that matches the machine, so installs work offline and are
67
+ covered by the registry's integrity hashes.
68
+
69
+ | Platform | Package |
70
+ | --- | --- |
71
+ | macOS (Apple silicon) | `skif-darwin-arm64` |
72
+ | macOS (Intel) | `skif-darwin-x64` |
73
+ | Linux arm64 (glibc) | `skif-linux-arm64-gnu` |
74
+ | Linux arm64 (musl, Alpine) | `skif-linux-arm64-musl` |
75
+ | Linux x64 (glibc) | `skif-linux-x64-gnu` |
76
+ | Linux x64 (musl, Alpine) | `skif-linux-x64-musl` |
77
+
78
+ Windows is not supported by this package. If no platform package is installed (for example because optional
79
+ dependencies were disabled), importing `skif` fails with an error naming the missing package.
80
+
81
+ ## Links
82
+
83
+ - [Documentation](https://github.com/Goldziher/skif#readme)
84
+ - [Changelog](https://github.com/Goldziher/skif/blob/main/CHANGELOG.md)
85
+ - [Issues](https://github.com/Goldziher/skif/issues)
package/bin/skif.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { run } from "../index.js";
3
+
4
+ // Set the exit code instead of calling process.exit so the runtime drains stdout and stderr itself.
5
+ process.exitCode = run(process.argv.slice(2));
package/index.d.ts ADDED
@@ -0,0 +1,79 @@
1
+ /* auto-generated by NAPI-RS */
2
+ /* eslint-disable */
3
+
4
+ /**
5
+ * Which binding artifact the generated loader actually loaded: `'native'` for
6
+ * a native addon, otherwise the `platformArchABI` of the WASI flavor. Every
7
+ * flavor napi-rs can build is listed, because `NAPI_RS_NATIVE_LIBRARY_PATH`
8
+ * can point the loader at a WASI artifact this package does not build itself.
9
+ */
10
+ export declare const __napiBindingTarget: 'native' | 'wasm32-wasi' | 'wasm32-wasip1'
11
+
12
+ /**
13
+ * Lints the workspace containing `path` (or, with `recursive`, every root at or below it) and returns the report as
14
+ * the versioned JSON document the CLI prints for `--format json`. Nothing is printed and no file is written. The
15
+ * call blocks the event loop; use [`lint_async`] in a server.
16
+ *
17
+ * # Errors
18
+ * Throws an `Error` with the failure's message, and with its `kind` and, when there is one, `path` as properties
19
+ * (the same fields [`lint_async`] returns in `error`) when no workspace is found, the configuration is invalid or
20
+ * discovery fails.
21
+ */
22
+ export declare function lint(path: string, options?: LintOptions | undefined | null): string
23
+
24
+ /**
25
+ * Like [`lint`], without blocking the event loop. Resolves with a [`LintOutcome`]: `report` on success, or a
26
+ * structured `error` (kind, message, path) instead of a rejection when the lint cannot run.
27
+ */
28
+ export declare function lintAsync(path: string, options?: LintOptions | undefined | null): Promise<LintOutcome>
29
+
30
+ /** Why a lint could not run. */
31
+ export interface LintFailure {
32
+ /** `config`, `workspace`, `io`, `usage`, `ci-refusal` or `internal` (a bug in skif). */
33
+ kind: string
34
+ /** What went wrong. */
35
+ message: string
36
+ /** The file the failure is about, with `/` separators, when there is one. */
37
+ path?: string
38
+ }
39
+
40
+ /** Options for [`lint`] and [`lint_async`]; each mirrors the CLI flag of the same name. */
41
+ export interface LintOptions {
42
+ /** Skip JavaScript and TypeScript source analysis (`--no-js`). */
43
+ noJs?: boolean
44
+ /** Lint production dependencies only (`--production`). */
45
+ production?: boolean
46
+ /** Treat warnings as failures (`--fail-on-warnings`). */
47
+ failOnWarnings?: boolean
48
+ /** Rule ids to turn off (`--ignore-rule`). */
49
+ ignoreRules?: Array<string>
50
+ /** Lint every workspace and standalone package at or below the path (`--recursive`). */
51
+ recursive?: boolean
52
+ /** Package names to skip (`--ignore-package`). */
53
+ ignorePackages?: Array<string>
54
+ /** Dependency names to skip (`--ignore-dependency`). */
55
+ ignoreDependencies?: Array<string>
56
+ /**
57
+ * Use this configuration file (and the files it extends) instead of discovering `skif.toml` files
58
+ * (`--config`). Ignored when `noConfig` is set.
59
+ */
60
+ config?: string
61
+ /** Read no configuration file: the defaults plus the other options (`--no-config`). */
62
+ noConfig?: boolean
63
+ }
64
+
65
+ /** The result of [`lint_async`]: exactly one of `report` and `error` is set. */
66
+ export interface LintOutcome {
67
+ /** The versioned JSON document the CLI prints for `--format json`. */
68
+ report?: string
69
+ /** Why no report could be produced. */
70
+ error?: LintFailure
71
+ }
72
+
73
+ /**
74
+ * Runs the skif command line with `argv` (the arguments after the program name) and returns its exit code.
75
+ *
76
+ * Output streams to the process's stdout and stderr exactly as the native binary does. It is written by Rust, not
77
+ * through `process.stdout`, so on a pipe it is not ordered with what Node writes in the same tick.
78
+ */
79
+ export declare function run(argv: Array<string>): number
package/index.js ADDED
@@ -0,0 +1,780 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ /* auto-generated by NAPI-RS */
4
+
5
+ import { createRequire } from 'module'
6
+ const require = createRequire(import.meta.url)
7
+
8
+ const { readFileSync } = require('fs')
9
+ let nativeBinding = null
10
+ // Which artifact actually loaded. The WASI fallback chain overwrites it with
11
+ // the flavor it resolved; the late native retry below leaves it alone because
12
+ // it only runs while no WASI candidate has been loaded. The take-over check
13
+ // after the load-failure block can also set it.
14
+ let __napiLoadedBindingTarget = 'native'
15
+ // What this loader's own `requireNative()` calls returned. The check after
16
+ // the load-failure block compares it with `nativeBinding` to tell a binding
17
+ // this loader loaded from one that code outside it put in its place.
18
+ let __napiRequiredNativeBinding = null
19
+ const loadErrors = []
20
+
21
+ const isMusl = () => {
22
+ let musl = false
23
+ if (process.platform === 'linux') {
24
+ musl = isMuslFromFilesystem()
25
+ if (musl === null) {
26
+ musl = isMuslFromReport()
27
+ }
28
+ if (musl === null) {
29
+ musl = isMuslFromChildProcess()
30
+ }
31
+ }
32
+ return musl
33
+ }
34
+
35
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
36
+
37
+ const isMuslFromFilesystem = () => {
38
+ try {
39
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
40
+ } catch {
41
+ return null
42
+ }
43
+ }
44
+
45
+ const isMuslFromReport = () => {
46
+ let report = null
47
+ if (process.report && typeof process.report.getReport === 'function') {
48
+ process.report.excludeNetwork = true
49
+ report = process.report.getReport()
50
+ }
51
+ if (!report) {
52
+ return null
53
+ }
54
+ if (report.header && report.header.glibcVersionRuntime) {
55
+ return false
56
+ }
57
+ if (Array.isArray(report.sharedObjects)) {
58
+ if (report.sharedObjects.some(isFileMusl)) {
59
+ return true
60
+ }
61
+ }
62
+ return false
63
+ }
64
+
65
+ const isMuslFromChildProcess = () => {
66
+ try {
67
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
68
+ } catch (e) {
69
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
70
+ return false
71
+ }
72
+ }
73
+
74
+ function requireNative() {
75
+ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
76
+ try {
77
+ const overrideBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH)
78
+ // The override may be a generated WASI loader, which already reports its
79
+ // own flavor. Adopt it: `module.exports` aliases this object, so claiming
80
+ // 'native' would both misreport the artifact and overwrite the loader's
81
+ // marker through the alias.
82
+ __napiLoadedBindingTarget =
83
+ overrideBinding && typeof overrideBinding.__napiBindingTarget === 'string'
84
+ ? overrideBinding.__napiBindingTarget
85
+ : 'native'
86
+ return overrideBinding
87
+ } catch (err) {
88
+ loadErrors.push(err)
89
+ }
90
+ } else if (process.platform === 'android') {
91
+ if (process.arch === 'arm64') {
92
+ try {
93
+ return require('./skif.android-arm64.node')
94
+ } catch (e) {
95
+ loadErrors.push(e)
96
+ }
97
+ try {
98
+ const binding = require('skif-android-arm64')
99
+ const bindingPackageVersion = require('skif-android-arm64/package.json').version
100
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
101
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
102
+ }
103
+ return binding
104
+ } catch (e) {
105
+ loadErrors.push(e)
106
+ }
107
+ } else if (process.arch === 'arm') {
108
+ try {
109
+ return require('./skif.android-arm-eabi.node')
110
+ } catch (e) {
111
+ loadErrors.push(e)
112
+ }
113
+ try {
114
+ const binding = require('skif-android-arm-eabi')
115
+ const bindingPackageVersion = require('skif-android-arm-eabi/package.json').version
116
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
117
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
118
+ }
119
+ return binding
120
+ } catch (e) {
121
+ loadErrors.push(e)
122
+ }
123
+ } else {
124
+ loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
125
+ }
126
+ } else if (process.platform === 'win32') {
127
+ if (process.arch === 'x64') {
128
+ if ((process.config && process.config.variables && process.config.variables.shlib_suffix === 'dll.a') || (process.config && process.config.variables && process.config.variables.node_target_type === 'shared_library')) {
129
+ try {
130
+ return require('./skif.win32-x64-gnu.node')
131
+ } catch (e) {
132
+ loadErrors.push(e)
133
+ }
134
+ try {
135
+ const binding = require('skif-win32-x64-gnu')
136
+ const bindingPackageVersion = require('skif-win32-x64-gnu/package.json').version
137
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
138
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
139
+ }
140
+ return binding
141
+ } catch (e) {
142
+ loadErrors.push(e)
143
+ }
144
+ } else {
145
+ try {
146
+ return require('./skif.win32-x64-msvc.node')
147
+ } catch (e) {
148
+ loadErrors.push(e)
149
+ }
150
+ try {
151
+ const binding = require('skif-win32-x64-msvc')
152
+ const bindingPackageVersion = require('skif-win32-x64-msvc/package.json').version
153
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
154
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
155
+ }
156
+ return binding
157
+ } catch (e) {
158
+ loadErrors.push(e)
159
+ }
160
+ }
161
+ } else if (process.arch === 'ia32') {
162
+ try {
163
+ return require('./skif.win32-ia32-msvc.node')
164
+ } catch (e) {
165
+ loadErrors.push(e)
166
+ }
167
+ try {
168
+ const binding = require('skif-win32-ia32-msvc')
169
+ const bindingPackageVersion = require('skif-win32-ia32-msvc/package.json').version
170
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
171
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
172
+ }
173
+ return binding
174
+ } catch (e) {
175
+ loadErrors.push(e)
176
+ }
177
+ } else if (process.arch === 'arm64') {
178
+ try {
179
+ return require('./skif.win32-arm64-msvc.node')
180
+ } catch (e) {
181
+ loadErrors.push(e)
182
+ }
183
+ try {
184
+ const binding = require('skif-win32-arm64-msvc')
185
+ const bindingPackageVersion = require('skif-win32-arm64-msvc/package.json').version
186
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
187
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
188
+ }
189
+ return binding
190
+ } catch (e) {
191
+ loadErrors.push(e)
192
+ }
193
+ } else {
194
+ loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
195
+ }
196
+ } else if (process.platform === 'darwin') {
197
+ try {
198
+ return require('./skif.darwin-universal.node')
199
+ } catch (e) {
200
+ loadErrors.push(e)
201
+ }
202
+ try {
203
+ const binding = require('skif-darwin-universal')
204
+ const bindingPackageVersion = require('skif-darwin-universal/package.json').version
205
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
206
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
207
+ }
208
+ return binding
209
+ } catch (e) {
210
+ loadErrors.push(e)
211
+ }
212
+ if (process.arch === 'x64') {
213
+ try {
214
+ return require('./skif.darwin-x64.node')
215
+ } catch (e) {
216
+ loadErrors.push(e)
217
+ }
218
+ try {
219
+ const binding = require('skif-darwin-x64')
220
+ const bindingPackageVersion = require('skif-darwin-x64/package.json').version
221
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
222
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
223
+ }
224
+ return binding
225
+ } catch (e) {
226
+ loadErrors.push(e)
227
+ }
228
+ } else if (process.arch === 'arm64') {
229
+ try {
230
+ return require('./skif.darwin-arm64.node')
231
+ } catch (e) {
232
+ loadErrors.push(e)
233
+ }
234
+ try {
235
+ const binding = require('skif-darwin-arm64')
236
+ const bindingPackageVersion = require('skif-darwin-arm64/package.json').version
237
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
238
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
239
+ }
240
+ return binding
241
+ } catch (e) {
242
+ loadErrors.push(e)
243
+ }
244
+ } else {
245
+ loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
246
+ }
247
+ } else if (process.platform === 'freebsd') {
248
+ if (process.arch === 'x64') {
249
+ try {
250
+ return require('./skif.freebsd-x64.node')
251
+ } catch (e) {
252
+ loadErrors.push(e)
253
+ }
254
+ try {
255
+ const binding = require('skif-freebsd-x64')
256
+ const bindingPackageVersion = require('skif-freebsd-x64/package.json').version
257
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
258
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
259
+ }
260
+ return binding
261
+ } catch (e) {
262
+ loadErrors.push(e)
263
+ }
264
+ } else if (process.arch === 'arm64') {
265
+ try {
266
+ return require('./skif.freebsd-arm64.node')
267
+ } catch (e) {
268
+ loadErrors.push(e)
269
+ }
270
+ try {
271
+ const binding = require('skif-freebsd-arm64')
272
+ const bindingPackageVersion = require('skif-freebsd-arm64/package.json').version
273
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
274
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
275
+ }
276
+ return binding
277
+ } catch (e) {
278
+ loadErrors.push(e)
279
+ }
280
+ } else if (process.arch === 'ppc64') {
281
+ try {
282
+ return require('./skif.freebsd-ppc64.node')
283
+ } catch (e) {
284
+ loadErrors.push(e)
285
+ }
286
+ try {
287
+ const binding = require('skif-freebsd-ppc64')
288
+ const bindingPackageVersion = require('skif-freebsd-ppc64/package.json').version
289
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
290
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
291
+ }
292
+ return binding
293
+ } catch (e) {
294
+ loadErrors.push(e)
295
+ }
296
+ } else {
297
+ loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
298
+ }
299
+ } else if (process.platform === 'linux') {
300
+ if (process.arch === 'x64') {
301
+ if (isMusl()) {
302
+ try {
303
+ return require('./skif.linux-x64-musl.node')
304
+ } catch (e) {
305
+ loadErrors.push(e)
306
+ }
307
+ try {
308
+ const binding = require('skif-linux-x64-musl')
309
+ const bindingPackageVersion = require('skif-linux-x64-musl/package.json').version
310
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
311
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
312
+ }
313
+ return binding
314
+ } catch (e) {
315
+ loadErrors.push(e)
316
+ }
317
+ } else {
318
+ try {
319
+ return require('./skif.linux-x64-gnu.node')
320
+ } catch (e) {
321
+ loadErrors.push(e)
322
+ }
323
+ try {
324
+ const binding = require('skif-linux-x64-gnu')
325
+ const bindingPackageVersion = require('skif-linux-x64-gnu/package.json').version
326
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
327
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
328
+ }
329
+ return binding
330
+ } catch (e) {
331
+ loadErrors.push(e)
332
+ }
333
+ }
334
+ } else if (process.arch === 'arm64') {
335
+ if (isMusl()) {
336
+ try {
337
+ return require('./skif.linux-arm64-musl.node')
338
+ } catch (e) {
339
+ loadErrors.push(e)
340
+ }
341
+ try {
342
+ const binding = require('skif-linux-arm64-musl')
343
+ const bindingPackageVersion = require('skif-linux-arm64-musl/package.json').version
344
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
345
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
346
+ }
347
+ return binding
348
+ } catch (e) {
349
+ loadErrors.push(e)
350
+ }
351
+ } else {
352
+ try {
353
+ return require('./skif.linux-arm64-gnu.node')
354
+ } catch (e) {
355
+ loadErrors.push(e)
356
+ }
357
+ try {
358
+ const binding = require('skif-linux-arm64-gnu')
359
+ const bindingPackageVersion = require('skif-linux-arm64-gnu/package.json').version
360
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
361
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
362
+ }
363
+ return binding
364
+ } catch (e) {
365
+ loadErrors.push(e)
366
+ }
367
+ }
368
+ } else if (process.arch === 'arm') {
369
+ if (isMusl()) {
370
+ try {
371
+ return require('./skif.linux-arm-musleabihf.node')
372
+ } catch (e) {
373
+ loadErrors.push(e)
374
+ }
375
+ try {
376
+ const binding = require('skif-linux-arm-musleabihf')
377
+ const bindingPackageVersion = require('skif-linux-arm-musleabihf/package.json').version
378
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
379
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
380
+ }
381
+ return binding
382
+ } catch (e) {
383
+ loadErrors.push(e)
384
+ }
385
+ } else {
386
+ try {
387
+ return require('./skif.linux-arm-gnueabihf.node')
388
+ } catch (e) {
389
+ loadErrors.push(e)
390
+ }
391
+ try {
392
+ const binding = require('skif-linux-arm-gnueabihf')
393
+ const bindingPackageVersion = require('skif-linux-arm-gnueabihf/package.json').version
394
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
395
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
396
+ }
397
+ return binding
398
+ } catch (e) {
399
+ loadErrors.push(e)
400
+ }
401
+ }
402
+ } else if (process.arch === 'loong64') {
403
+ if (isMusl()) {
404
+ try {
405
+ return require('./skif.linux-loong64-musl.node')
406
+ } catch (e) {
407
+ loadErrors.push(e)
408
+ }
409
+ try {
410
+ const binding = require('skif-linux-loong64-musl')
411
+ const bindingPackageVersion = require('skif-linux-loong64-musl/package.json').version
412
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
413
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
414
+ }
415
+ return binding
416
+ } catch (e) {
417
+ loadErrors.push(e)
418
+ }
419
+ } else {
420
+ try {
421
+ return require('./skif.linux-loong64-gnu.node')
422
+ } catch (e) {
423
+ loadErrors.push(e)
424
+ }
425
+ try {
426
+ const binding = require('skif-linux-loong64-gnu')
427
+ const bindingPackageVersion = require('skif-linux-loong64-gnu/package.json').version
428
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
429
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
430
+ }
431
+ return binding
432
+ } catch (e) {
433
+ loadErrors.push(e)
434
+ }
435
+ }
436
+ } else if (process.arch === 'riscv64') {
437
+ if (isMusl()) {
438
+ try {
439
+ return require('./skif.linux-riscv64-musl.node')
440
+ } catch (e) {
441
+ loadErrors.push(e)
442
+ }
443
+ try {
444
+ const binding = require('skif-linux-riscv64-musl')
445
+ const bindingPackageVersion = require('skif-linux-riscv64-musl/package.json').version
446
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
447
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
448
+ }
449
+ return binding
450
+ } catch (e) {
451
+ loadErrors.push(e)
452
+ }
453
+ } else {
454
+ try {
455
+ return require('./skif.linux-riscv64-gnu.node')
456
+ } catch (e) {
457
+ loadErrors.push(e)
458
+ }
459
+ try {
460
+ const binding = require('skif-linux-riscv64-gnu')
461
+ const bindingPackageVersion = require('skif-linux-riscv64-gnu/package.json').version
462
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
463
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
464
+ }
465
+ return binding
466
+ } catch (e) {
467
+ loadErrors.push(e)
468
+ }
469
+ }
470
+ } else if (process.arch === 'ppc64') {
471
+ try {
472
+ return require('./skif.linux-ppc64-gnu.node')
473
+ } catch (e) {
474
+ loadErrors.push(e)
475
+ }
476
+ try {
477
+ const binding = require('skif-linux-ppc64-gnu')
478
+ const bindingPackageVersion = require('skif-linux-ppc64-gnu/package.json').version
479
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
480
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
481
+ }
482
+ return binding
483
+ } catch (e) {
484
+ loadErrors.push(e)
485
+ }
486
+ } else if (process.arch === 's390x') {
487
+ try {
488
+ return require('./skif.linux-s390x-gnu.node')
489
+ } catch (e) {
490
+ loadErrors.push(e)
491
+ }
492
+ try {
493
+ const binding = require('skif-linux-s390x-gnu')
494
+ const bindingPackageVersion = require('skif-linux-s390x-gnu/package.json').version
495
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
496
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
497
+ }
498
+ return binding
499
+ } catch (e) {
500
+ loadErrors.push(e)
501
+ }
502
+ } else {
503
+ loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
504
+ }
505
+ } else if (process.platform === 'openharmony') {
506
+ if (process.arch === 'arm64') {
507
+ try {
508
+ return require('./skif.openharmony-arm64.node')
509
+ } catch (e) {
510
+ loadErrors.push(e)
511
+ }
512
+ try {
513
+ const binding = require('skif-openharmony-arm64')
514
+ const bindingPackageVersion = require('skif-openharmony-arm64/package.json').version
515
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
516
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
517
+ }
518
+ return binding
519
+ } catch (e) {
520
+ loadErrors.push(e)
521
+ }
522
+ } else if (process.arch === 'x64') {
523
+ try {
524
+ return require('./skif.openharmony-x64.node')
525
+ } catch (e) {
526
+ loadErrors.push(e)
527
+ }
528
+ try {
529
+ const binding = require('skif-openharmony-x64')
530
+ const bindingPackageVersion = require('skif-openharmony-x64/package.json').version
531
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
532
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
533
+ }
534
+ return binding
535
+ } catch (e) {
536
+ loadErrors.push(e)
537
+ }
538
+ } else if (process.arch === 'arm') {
539
+ try {
540
+ return require('./skif.openharmony-arm.node')
541
+ } catch (e) {
542
+ loadErrors.push(e)
543
+ }
544
+ try {
545
+ const binding = require('skif-openharmony-arm')
546
+ const bindingPackageVersion = require('skif-openharmony-arm/package.json').version
547
+ if (bindingPackageVersion !== '0.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
548
+ throw new Error(`Native binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
549
+ }
550
+ return binding
551
+ } catch (e) {
552
+ loadErrors.push(e)
553
+ }
554
+ } else {
555
+ loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
556
+ }
557
+ } else {
558
+ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
559
+ }
560
+ }
561
+
562
+ function createLoadErrorChain(errors) {
563
+ return errors.reduce((previous, current) => {
564
+ let message
565
+ try {
566
+ message =
567
+ current && typeof current.message === 'string'
568
+ ? current.message
569
+ : String(current)
570
+ } catch {
571
+ message = 'Unknown error'
572
+ }
573
+ const error = new Error(message)
574
+ error.cause = previous
575
+ return error
576
+ }, null)
577
+ }
578
+
579
+ // NAPI_RS_FORCE_WASI is a tri-state flag:
580
+ // unset / any other value → native binding preferred, WASI is only a fallback
581
+ // 'true' → prefer WASI, but retain native as a lazy fallback
582
+ // 'error' → require WASI without initializing a native fallback
583
+ // Treating any non-empty string as truthy (the historical behavior) meant
584
+ // NAPI_RS_FORCE_WASI=false, NAPI_RS_FORCE_WASI=0, etc. inadvertently triggered
585
+ // the WASI path, causing ENOENT for packages shipped without a .wasi.cjs file.
586
+ //
587
+ // NAPI_RS_WASI_FLAVOR selects one exact generated flavor and implies strict
588
+ // WASI loading. It never crosses into another flavor or falls back to native.
589
+ const __napiWasiFlavors = ['wasm32-wasi']
590
+ const __napiWasiFlavor = process.env.NAPI_RS_WASI_FLAVOR
591
+ const __napiWasiFlavorRequested =
592
+ typeof __napiWasiFlavor === 'string' && __napiWasiFlavor.length > 0
593
+ if (
594
+ __napiWasiFlavorRequested &&
595
+ __napiWasiFlavors.indexOf(__napiWasiFlavor) === -1
596
+ ) {
597
+ throw new Error(
598
+ 'Unsupported WASI flavor "' +
599
+ __napiWasiFlavor +
600
+ '". Available flavors: ' +
601
+ __napiWasiFlavors.join(', '),
602
+ )
603
+ }
604
+ const forceWasiError = process.env.NAPI_RS_FORCE_WASI === 'error'
605
+ const forceWasi =
606
+ process.env.NAPI_RS_FORCE_WASI === 'true' ||
607
+ forceWasiError ||
608
+ __napiWasiFlavorRequested
609
+
610
+ if (!forceWasi) {
611
+ nativeBinding = requireNative()
612
+ __napiRequiredNativeBinding = nativeBinding
613
+ }
614
+
615
+ if (!nativeBinding || forceWasi) {
616
+ let wasiBinding = null
617
+ let wasiBindingLoaded = false
618
+ const wasiBindingErrors = []
619
+ const __napiWasiResolveCandidate = (specifier, isPackage, localArtifacts) => {
620
+ try {
621
+ require.resolve(specifier)
622
+ } catch (resolveError) {
623
+ if (!resolveError || resolveError.code !== 'MODULE_NOT_FOUND') {
624
+ throw resolveError
625
+ }
626
+ if (isPackage) {
627
+ try {
628
+ require.resolve(specifier + '/package.json')
629
+ } catch (packageError) {
630
+ if (packageError && packageError.code === 'MODULE_NOT_FOUND') {
631
+ return resolveError
632
+ }
633
+ // An exports restriction proves the package exists even when its
634
+ // package.json is not public. Preserve the root resolution failure.
635
+ throw resolveError
636
+ }
637
+ // The package exists but its main/export target is broken.
638
+ throw resolveError
639
+ }
640
+ return resolveError
641
+ }
642
+ if (localArtifacts) {
643
+ let artifactError = null
644
+ for (let i = 0; i < localArtifacts.length; i++) {
645
+ try {
646
+ require.resolve(localArtifacts[i])
647
+ return null
648
+ } catch (resolveError) {
649
+ if (!resolveError || resolveError.code !== 'MODULE_NOT_FOUND') {
650
+ throw resolveError
651
+ }
652
+ artifactError = resolveError
653
+ }
654
+ }
655
+ return artifactError
656
+ }
657
+ return null
658
+ }
659
+ if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === 'wasm32-wasi')) {
660
+ let candidateError = null
661
+ let candidateFailed = false
662
+ try {
663
+ candidateError = __napiWasiResolveCandidate('./skif.wasi.cjs', false, ['./skif.wasm32-wasi.debug.wasm', './skif.wasm32-wasi.wasm'])
664
+ candidateFailed = candidateError !== null
665
+ if (!candidateFailed) {
666
+ wasiBinding = require('./skif.wasi.cjs')
667
+ nativeBinding = wasiBinding
668
+ __napiLoadedBindingTarget = 'wasm32-wasi'
669
+ wasiBindingLoaded = true
670
+ }
671
+ } catch (err) {
672
+ candidateError = err
673
+ candidateFailed = true
674
+ }
675
+ if (candidateFailed) {
676
+ wasiBindingErrors.push(candidateError)
677
+ loadErrors.push(candidateError)
678
+ }
679
+ }
680
+ if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === 'wasm32-wasi')) {
681
+ let candidateError = null
682
+ let candidateFailed = false
683
+ try {
684
+ candidateError = __napiWasiResolveCandidate('skif-wasm32-wasi', true, undefined)
685
+ candidateFailed = candidateError !== null
686
+ if (!candidateFailed) {
687
+ if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
688
+ const bindingPackageVersion = require('skif-wasm32-wasi/package.json').version
689
+ if (bindingPackageVersion !== '0.1.1') {
690
+ throw new Error(`WASI binding package version mismatch, expected 0.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
691
+ }
692
+ }
693
+ wasiBinding = require('skif-wasm32-wasi')
694
+ nativeBinding = wasiBinding
695
+ __napiLoadedBindingTarget = 'wasm32-wasi'
696
+ wasiBindingLoaded = true
697
+ }
698
+ } catch (err) {
699
+ candidateError = err
700
+ candidateFailed = true
701
+ }
702
+ if (candidateFailed) {
703
+ wasiBindingErrors.push(candidateError)
704
+ loadErrors.push(candidateError)
705
+ }
706
+ }
707
+ if (
708
+ !wasiBindingLoaded &&
709
+ forceWasi &&
710
+ !forceWasiError &&
711
+ !__napiWasiFlavorRequested
712
+ ) {
713
+ nativeBinding = requireNative()
714
+ __napiRequiredNativeBinding = nativeBinding
715
+ }
716
+ if ((forceWasiError || __napiWasiFlavorRequested) && !wasiBindingLoaded) {
717
+ const error = new Error(
718
+ __napiWasiFlavorRequested
719
+ ? 'WASI binding for flavor "' + __napiWasiFlavor + '" not found'
720
+ : 'WASI binding not found and NAPI_RS_FORCE_WASI is set to error',
721
+ )
722
+ error.cause = createLoadErrorChain(wasiBindingErrors)
723
+ throw error
724
+ }
725
+ }
726
+
727
+ if (!nativeBinding) {
728
+ if (loadErrors.length > 0) {
729
+ const error = new Error(
730
+ `Cannot find native binding. ` +
731
+ `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
732
+ 'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
733
+ )
734
+ // assign instead of the `new Error(message, { cause })` options form,
735
+ // which Node < 16.9 silently ignores
736
+ error.cause = createLoadErrorChain(loadErrors)
737
+ throw error
738
+ }
739
+ throw new Error(`Failed to load native binding`)
740
+ }
741
+
742
+ // A package can patch its own fallback in front of the load-failure check
743
+ // above, e.g. a WebContainer download through `napi-postinstall/fallback`.
744
+ // That fallback swaps `nativeBinding` for a generated WASI loader, which has
745
+ // already stamped its own flavor, while the target above still says 'native'.
746
+ // Take that flavor over, or the CommonJS stamp throws a conflict and the ESM
747
+ // export reports the wrong artifact. Three limits keep the conflict check:
748
+ // - only a binding this loader did not load itself, so a native addon whose
749
+ // `#[napi(module_exports)]` hook claims the name is still rejected;
750
+ // - only an own data property, read through its descriptor, so no addon
751
+ // getter runs here, and it must read back the same, as the stamp reads it;
752
+ // - only a flavor in `__napiWasiFlavors`, the ones this loader's own WASI
753
+ // chain can report ('wasm32-wasi' for a package without a WASI target).
754
+ // This is metadata and never fails a load: a throwing Proxy trap keeps 'native'.
755
+ if (
756
+ __napiLoadedBindingTarget === 'native' &&
757
+ nativeBinding !== __napiRequiredNativeBinding
758
+ ) {
759
+ try {
760
+ const __napiBindingTargetDescriptor = Object.getOwnPropertyDescriptor(
761
+ nativeBinding,
762
+ '__napiBindingTarget',
763
+ )
764
+ if (
765
+ __napiBindingTargetDescriptor &&
766
+ __napiWasiFlavors.indexOf(__napiBindingTargetDescriptor.value) !== -1 &&
767
+ nativeBinding.__napiBindingTarget === __napiBindingTargetDescriptor.value
768
+ ) {
769
+ __napiLoadedBindingTarget = __napiBindingTargetDescriptor.value
770
+ }
771
+ } catch {
772
+ // keep 'native'
773
+ }
774
+ }
775
+
776
+ const { lint, lintAsync, run } = nativeBinding
777
+ export { lint }
778
+ export { lintAsync }
779
+ export { run }
780
+ export const __napiBindingTarget = __napiLoadedBindingTarget
package/package.json CHANGED
@@ -1,7 +1,85 @@
1
1
  {
2
2
  "name": "skif-cli",
3
- "version": "0.0.0",
4
- "description": "Name reservation for skif. Real releases start at 0.1.0.",
3
+ "version": "0.1.1",
4
+ "description": "A dependency and package-manager linter, auditor and enforcer for JavaScript and TypeScript, with first-class monorepo support.",
5
+ "keywords": [
6
+ "dependencies",
7
+ "linter",
8
+ "monorepo",
9
+ "workspaces",
10
+ "pnpm",
11
+ "npm",
12
+ "yarn",
13
+ "bun",
14
+ "catalog",
15
+ "audit"
16
+ ],
17
+ "homepage": "https://github.com/Goldziher/skif#readme",
18
+ "bugs": {
19
+ "url": "https://github.com/Goldziher/skif/issues"
20
+ },
5
21
  "license": "MIT",
6
- "repository": { "type": "git", "url": "git+https://github.com/Goldziher/skif.git" }
7
- }
22
+ "author": "Na'aman Hirschfeld <nhirschfeld@gmail.com>",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/Goldziher/skif.git",
26
+ "directory": "npm-package"
27
+ },
28
+ "type": "module",
29
+ "main": "index.js",
30
+ "types": "index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./index.d.ts",
34
+ "default": "./index.js"
35
+ },
36
+ "./package.json": "./package.json"
37
+ },
38
+ "bin": {
39
+ "skif": "bin/skif.js"
40
+ },
41
+ "files": [
42
+ "LICENSE",
43
+ "ATTRIBUTIONS.md",
44
+ "README.md",
45
+ "index.js",
46
+ "index.d.ts",
47
+ "bin/skif.js"
48
+ ],
49
+ "napi": {
50
+ "binaryName": "skif",
51
+ "packageName": "skif",
52
+ "targets": [
53
+ "aarch64-apple-darwin",
54
+ "x86_64-apple-darwin",
55
+ "x86_64-unknown-linux-gnu",
56
+ "aarch64-unknown-linux-gnu",
57
+ "x86_64-unknown-linux-musl",
58
+ "aarch64-unknown-linux-musl"
59
+ ]
60
+ },
61
+ "devDependencies": {
62
+ "@napi-rs/cli": "3.10.12"
63
+ },
64
+ "engines": {
65
+ "node": ">=22",
66
+ "bun": ">=1"
67
+ },
68
+ "publishConfig": {
69
+ "access": "public",
70
+ "provenance": true
71
+ },
72
+ "optionalDependencies": {
73
+ "skif-darwin-arm64": "0.1.1",
74
+ "skif-darwin-x64": "0.1.1",
75
+ "skif-linux-x64-gnu": "0.1.1",
76
+ "skif-linux-arm64-gnu": "0.1.1",
77
+ "skif-linux-x64-musl": "0.1.1",
78
+ "skif-linux-arm64-musl": "0.1.1"
79
+ },
80
+ "scripts": {
81
+ "build": "napi build --platform --profile node --esm --manifest-path ../crates/skif-node/Cargo.toml --output-dir . --package skif-node",
82
+ "build:debug": "napi build --platform --esm --manifest-path ../crates/skif-node/Cargo.toml --output-dir . --package skif-node",
83
+ "version": "napi version"
84
+ }
85
+ }