dslinter 0.0.16 → 0.0.27

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,104 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.0.27
4
+
5
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.26...v0.0.27)
6
+
7
+ ### 🩹 Fixes
8
+
9
+ - **ci:** Prepublish skip optional npm publish ([b69b368](https://github.com/jrmybtlr/DSLinter/commit/b69b368))
10
+ - **ci:** Disable npm provenance on publish (retry-safe) ([5aaece8](https://github.com/jrmybtlr/DSLinter/commit/5aaece8))
11
+
12
+ ### ❤️ Contributors
13
+
14
+ - Jeremy Butler <jeremy.butler@laravel.com>
15
+
16
+ ## v0.0.26
17
+
18
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.25...v0.0.26)
19
+
20
+ ### 🩹 Fixes
21
+
22
+ - **ci:** Skip gh-release in napi prepublish ([cdcda0e](https://github.com/jrmybtlr/DSLinter/commit/cdcda0e))
23
+
24
+ ### ❤️ Contributors
25
+
26
+ - Jeremy Butler <jeremy.butler@laravel.com>
27
+
28
+ ## v0.0.25
29
+
30
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.24...v0.0.25)
31
+
32
+ ### 🩹 Fixes
33
+
34
+ - **ci:** Single macos job + mold on publish ([b2a193d](https://github.com/jrmybtlr/DSLinter/commit/b2a193d))
35
+
36
+ ### ❤️ Contributors
37
+
38
+ - Jeremy Butler <jeremy.butler@laravel.com>
39
+
40
+ ## v0.0.24
41
+
42
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.23...v0.0.24)
43
+
44
+ ### 🩹 Fixes
45
+
46
+ - **ci:** Skip lifecycle scripts and install mold for Rust job ([e85d8d9](https://github.com/jrmybtlr/DSLinter/commit/e85d8d9))
47
+ - **ci:** Build x86_64-apple-darwin on macos-latest ([bcc1af8](https://github.com/jrmybtlr/DSLinter/commit/bcc1af8))
48
+
49
+ ### ❤️ Contributors
50
+
51
+ - Jeremy Butler <jeremy.butler@laravel.com>
52
+
53
+ ## v0.0.23
54
+
55
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.22...v0.0.23)
56
+
57
+ ## v0.0.22
58
+
59
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.21...v0.0.22)
60
+
61
+ ## v0.0.21
62
+
63
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.19...v0.0.21)
64
+
65
+ ### 🏡 Chore
66
+
67
+ - **release:** V0.0.20 ([c07bb96](https://github.com/jrmybtlr/DSLinter/commit/c07bb96))
68
+
69
+ ### ❤️ Contributors
70
+
71
+ - Jeremy Butler <jeremy.butler@laravel.com>
72
+
73
+ ## v0.0.20
74
+
75
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.19...v0.0.20)
76
+
77
+ ## v0.0.19
78
+
79
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.18...v0.0.19)
80
+
81
+ ## v0.0.18
82
+
83
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.17...v0.0.18)
84
+
85
+ ## v0.0.17
86
+
87
+ [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.16...v0.0.17)
88
+
89
+ ### 🚀 Enhancements
90
+
91
+ - Refactor release process and update workflows ([20af684](https://github.com/jrmybtlr/DSLinter/commit/20af684))
92
+ - Add contributing guidelines and enhance documentation ([ac14afc](https://github.com/jrmybtlr/DSLinter/commit/ac14afc))
93
+
94
+ ### 🏡 Chore
95
+
96
+ - Update Node version and GitHub Actions workflows ([612a9b0](https://github.com/jrmybtlr/DSLinter/commit/612a9b0))
97
+
98
+ ### ❤️ Contributors
99
+
100
+ - Jeremy Butler <jeremy.butler@laravel.com>
101
+
3
102
  ## v0.0.16
4
103
 
5
104
  [compare changes](https://github.com/jrmybtlr/DSLinter/compare/v0.0.15...v0.0.16)
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dslinter
2
2
 
3
- React UI for the **DSLinter dashboard**: component playground shell, token wall, and governance panels. It expects a **`dslint-report.json`** file produced by the **`dslint`** CLI (Rust scanner in this repo).
3
+ React UI for the **DSLinter dashboard**: component playground shell, token wall, and governance panels. It expects a **`dslint-report.json`** file produced by the **`dslinter`** CLI (Rust scanner powered by [Oxc](https://oxc.rs) in this repo).
4
4
 
5
5
  **Previously published as `@dslinter/dashboard`.** Migrate with `npm install dslinter` and replace imports `@dslinter/dashboard` → `dslinter`, and `@dslinter/dashboard/theme.css` → `dslinter/theme.css`.
6
6
 
@@ -19,56 +19,27 @@ This package is **source-first**: entry points resolve to TypeScript/TSX under `
19
19
 
20
20
  ## CLI (`npx dslinter`)
21
21
 
22
- The **`dslinter` binary** runs the **`dslint`** scanner with the same flags as the Rust CLI (`--json`, `-o`, `--serve`, etc.).
22
+ The **`dslinter`** command runs the design-system scanner with the same flags as the Rust CLI (`--json`, `-o`, `--serve`, etc.) via a **napi-rs** native binding (same distribution model as **`oxlint`**).
23
23
 
24
24
  ### Without installing Rust
25
25
 
26
- On **`npm install dslinter`**, a **`postinstall`** script tries to download a **prebuilt `dslint`** for your OS/arch from this repo’s **GitHub Releases**, using the **same tag as the npm version** (for example npm `dslinter@0.0.6` → release **`v0.0.6`** and assets like `dslint-x86_64-unknown-linux-gnu`). The binary is stored under `node_modules/dslinter/vendor/` and `dslinter` / `npx dslinter` prefer it over `PATH`.
27
-
28
- **Release workflow:** push git tag `v*` (after bumping the npm version) so [.github/workflows/release-dslint-binaries.yml](https://github.com/jrmybtlr/DSLinter/blob/main/.github/workflows/release-dslint-binaries.yml) uploads the platform binaries, **then** publish `dslinter` to npm (or publish after the workflow finishes so installs resolve the assets).
29
-
30
- Environment variables:
26
+ On **`npm install dslinter`**, npm installs the platform **`@dslinter/binding-*`** optional dependency (darwin/linux/windows). No postinstall download or GitHub Releases API is required.
31
27
 
32
28
  | Variable | Purpose |
33
29
  |----------|---------|
34
- | `DSLINT_SKIP_DOWNLOAD=1` | Skip postinstall download (air-gapped / you only use `PATH`). |
35
- | `DSLINT_RELEASE_TAG` | Override release tag (default `v` + `dslinter` version from `package.json`). |
36
- | `DSLINT_GITHUB_REPO` | Override `owner/repo` for downloads (default from `package.json` `jrmybtlr/DSLinter`). |
37
- | `DSLINT_VERBOSE=1` | Log which GitHub releases/assets were tried when downloading. |
38
- | `GITHUB_TOKEN` / `GH_TOKEN` | **Required for private repos** (`jrmybtlr/DSLinter`). Token needs read access to releases. |
39
-
40
- ### How this differs from `oxlint`
41
-
42
- **`oxlint`** on npm ships **Node native addons** as **`optionalDependencies`** (`@oxlint/binding-darwin-arm64`, …) built with **napi-rs** — each package is a small prebuilt library loaded by Node.
43
-
44
- **`dslinter`** is a **standalone executable**. The practical pattern here is **download on install** from **GitHub Releases** (similar in spirit to tools that pull a platform binary once), instead of publishing dozens of `@dslinter/binding-*` packages.
30
+ | `DSLINT_BIN` | Use a cargo-built `dslinter` binary instead of the NAPI binding. |
31
+ | `DSLINT_ALLOW_PATH=1` | Allow `dslinter` on `PATH` when the binding is missing. |
32
+ | `NAPI_RS_NATIVE_LIBRARY_PATH` | Point at a specific `.node` file (napi-rs escape hatch). |
45
33
 
46
34
  ### Do not `cargo install dslint`
47
35
 
48
- The crates.io crate **`dslint`** (v0.0.x) is a **different project** (design-file linting). It is **not** this design-system scanner. Installing it will break `npx dslinter` if it ends up on your `PATH`.
49
-
50
- Use **`cargo install --git https://github.com/jrmybtlr/DSLinter dslinter --locked`** or set **`DSLINT_BIN`** to a local `target/release/dslinter` build.
51
-
52
- ### If there is no matching release asset yet
53
-
54
- You’ll see a **warning** during install (install still succeeds). **`dslinter`** will try to download on first run; if no GitHub release exists yet, you get a clear error (not a silent fallback to the wrong `dslint` on crates.io):
55
-
56
- ```bash
57
- npx dslinter /path/to/repo --json -o dslint-report.json
58
- ```
59
-
60
- | Distribution | How users get the scanner |
61
- |--------------|-------------------------|
62
- | **npm + GitHub Releases** | Default: download when release `vX.Y.Z` includes your platform asset. |
63
- | **GitHub Releases** | Manual download of `dslinter-*` from the release; run directly or set `DSLINT_BIN`. |
64
- | **From source** | `cargo install --git https://github.com/jrmybtlr/DSLinter dslinter --locked` (not `cargo install dslint`). |
36
+ The crates.io crate **`dslint`** is a **different project**. Use **`cargo install --git https://github.com/jrmybtlr/DSLinter dslinter --locked`** or **`DSLINT_BIN`** for local Rust builds.
65
37
 
66
38
  Typical usage:
67
39
 
68
40
  ```bash
69
41
  dslinter /path/to/repo --json -o dslint-report.json
70
42
  # or --serve for live reload while developing a dashboard
71
- # (npm `npx dslinter` runs the same binary)
72
43
  ```
73
44
 
74
45
  ## Styles (Tailwind v4)
package/bin/dslinter.mjs CHANGED
@@ -1,72 +1,77 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Runs the design-system scanner (`dslinter` binary from GitHub Releases or DSLINT_BIN).
4
- * Does NOT use bare `dslint` on PATH — that name is a different crate on crates.io.
3
+ * Runs the design-system scanner via the NAPI native binding (oxlint-style).
4
+ * Falls back to DSLINT_BIN (cargo-built binary) when set.
5
5
  */
6
6
  import { spawnSync } from "node:child_process";
7
+ import { createRequire } from "node:module";
7
8
  import { existsSync } from "node:fs";
8
9
  import { dirname, join } from "node:path";
9
10
  import { fileURLToPath } from "node:url";
10
- import { ensureDslintBinary } from "../scripts/ensure-dslint.mjs";
11
- import {
12
- SCANNER_VERSION_MARKER,
13
- vendorBinaryPath,
14
- } from "../scripts/resolve-dslint-binary.mjs";
15
11
 
16
12
  const __dirname = dirname(fileURLToPath(import.meta.url));
17
13
  const packageRoot = join(__dirname, "..");
14
+ const require = createRequire(import.meta.url);
18
15
 
19
16
  const args = process.argv.slice(2);
20
17
 
18
+ const SCANNER_VERSION_MARKER = "design system linting";
19
+
21
20
  function isOurScanner(binary) {
22
21
  const help = spawnSync(binary, ["--help"], { encoding: "utf8" });
23
22
  const out = `${help.stdout ?? ""}${help.stderr ?? ""}`;
24
23
  return out.includes(SCANNER_VERSION_MARKER);
25
24
  }
26
25
 
27
- async function resolveCommand() {
28
- const fromEnv = process.env.DSLINT_BIN?.trim();
29
- if (fromEnv) {
30
- if (!existsSync(fromEnv)) {
31
- process.stderr.write(`dslinter: DSLINT_BIN not found: ${fromEnv}\n`);
32
- process.exit(127);
33
- }
34
- if (!isOurScanner(fromEnv)) {
35
- process.stderr.write(
36
- `dslinter: DSLINT_BIN does not look like the DSLint design-system scanner.\n` +
37
- ` Expected output containing "${SCANNER_VERSION_MARKER}".\n`,
38
- );
39
- process.exit(1);
40
- }
41
- return fromEnv;
26
+ function runViaNapi() {
27
+ let runCli;
28
+ try {
29
+ ({ runCli } = require(join(packageRoot, "index.cjs")));
30
+ } catch (err) {
31
+ process.stderr.write(
32
+ `dslinter: failed to load native binding.\n` +
33
+ ` Run \`pnpm --filter dslinter run build:napi\` from the repo root, or reinstall dslinter.\n` +
34
+ ` ${err instanceof Error ? err.message : err}\n`,
35
+ );
36
+ process.exit(127);
42
37
  }
43
38
 
44
- const vendored = vendorBinaryPath(packageRoot);
45
- if (!existsSync(vendored)) {
46
- await ensureDslintBinary(packageRoot, { quiet: false });
47
- }
48
- if (existsSync(vendored)) {
49
- return vendored;
50
- }
39
+ const argv = ["dslinter", ...args];
40
+ const code = runCli(argv);
41
+ process.exit(code);
42
+ }
51
43
 
52
- if (process.env.DSLINT_ALLOW_PATH === "1") {
53
- const onPath = spawnSync("dslinter", ["--version"], { encoding: "utf8" });
54
- if (onPath.status === 0 && `${onPath.stdout}`.includes(SCANNER_VERSION_MARKER)) {
55
- return "dslinter";
56
- }
44
+ function runViaBinary(binary) {
45
+ const child = spawnSync(binary, args, { stdio: "inherit" });
46
+ if (child.error && "code" in child.error && child.error.code === "ENOENT") {
47
+ process.stderr.write(`dslinter: failed to execute ${binary}\n`);
48
+ process.exit(127);
57
49
  }
58
-
59
- await import("../scripts/print-missing-scanner.mjs");
60
- process.exit(127);
50
+ process.exit(child.status === null ? 1 : child.status);
61
51
  }
62
52
 
63
- const cmd = await resolveCommand();
64
- const child = spawnSync(cmd, args, { stdio: "inherit" });
53
+ const fromEnv = process.env.DSLINT_BIN?.trim();
54
+ if (fromEnv) {
55
+ if (!existsSync(fromEnv)) {
56
+ process.stderr.write(`dslinter: DSLINT_BIN not found: ${fromEnv}\n`);
57
+ process.exit(127);
58
+ }
59
+ if (!isOurScanner(fromEnv)) {
60
+ process.stderr.write(
61
+ `dslinter: DSLINT_BIN does not look like the DSLint design-system scanner.\n` +
62
+ ` Expected output containing "${SCANNER_VERSION_MARKER}".\n`,
63
+ );
64
+ process.exit(1);
65
+ }
66
+ runViaBinary(fromEnv);
67
+ }
65
68
 
66
- if (child.error && "code" in child.error && child.error.code === "ENOENT") {
67
- process.stderr.write(`dslinter: failed to execute ${cmd}\n`);
68
- process.exit(127);
69
+ if (process.env.DSLINT_ALLOW_PATH === "1") {
70
+ const onPath = spawnSync("dslinter", ["--help"], { encoding: "utf8" });
71
+ const out = `${onPath.stdout ?? ""}${onPath.stderr ?? ""}`;
72
+ if (onPath.status === 0 && out.includes(SCANNER_VERSION_MARKER)) {
73
+ runViaBinary("dslinter");
74
+ }
69
75
  }
70
76
 
71
- const code = child.status === null ? 1 : child.status;
72
- process.exit(code);
77
+ runViaNapi();