@makinzm/mille 0.0.9 → 0.0.11

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 (4) hide show
  1. package/README.md +233 -123
  2. package/index.js +10 -0
  3. package/mille.wasm +0 -0
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -1,59 +1,51 @@
1
1
  # mille
2
2
 
3
- > Architecture Checkerstatic analysis CLI for layered architecture rules
3
+ > Like a mille crêpe your architecture, one clean layer at a time.
4
4
 
5
- `mille` is a CLI tool that enforces **dependency rules for layered architectures** (Clean Architecture, Onion Architecture, Hexagonal Architecture, etc.).
5
+ ```
6
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ presentation
7
+ · · · · · · · · · · · · · · · · · · (deps only flow inward)
8
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ infrastructure
9
+ · · · · · · · · · · · · · · · · · ·
10
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ usecase
11
+ · · · · · · · · · · · · · · · · · ·
12
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ domain
13
+ ```
6
14
 
7
- It is implemented in Rust, supports multiple languages from a single TOML config, and is designed to run in CI/CD pipelines.
15
+ `mille` is a static analysis CLI that enforces **dependency rules for layered architectures** Clean Architecture, Onion Architecture, Hexagonal Architecture, and more.
8
16
 
9
- ## Features
17
+ One TOML config. Rust-powered. CI-ready. Supports multiple languages from a single config file.
10
18
 
11
- | Feature | Status |
12
- |---|---|
13
- | Internal layer dependency check (`dependency_mode`) | ✅ |
14
- | External library dependency check (`external_mode`) | ✅ |
15
- | DI entrypoint method call check (`allow_call_patterns`) | ✅ |
16
- | Rust support | ✅ |
17
- | Go support | ✅ |
18
- | Python support | ✅ |
19
- | TypeScript / JavaScript support | ✅ |
19
+ ## What it checks
20
20
 
21
- ## How to Install
21
+ | Check | Rust | Go | TypeScript | JavaScript | Python |
22
+ |---|:---:|:---:|:---:|:---:|:---:|
23
+ | Layer dependency rules (`dependency_mode`) | ✅ | ✅ | ✅ | ✅ | ✅ |
24
+ | External library rules (`external_mode`) | ✅ | ✅ | ✅ | ✅ | ✅ |
25
+ | DI method call rules (`allow_call_patterns`) | ✅ | ✅ | ✅ | ✅ | ✅ |
22
26
 
23
- ### cargo (Rust users)
24
-
25
- ```sh
26
- cargo install mille
27
- ```
27
+ ## Install
28
28
 
29
- ### pip / uv (Python users)
29
+ ### cargo
30
30
 
31
31
  ```sh
32
- # uv (recommended)
33
- uv add --dev mille
34
- uv run mille check
35
-
36
- # pip
37
- pip install mille
38
- mille check
32
+ cargo install mille
39
33
  ```
40
34
 
41
- The Python package is a native extension built with [maturin](https://github.com/PyO3/maturin) (PyO3). It provides both a CLI (`mille check`) and a Python API (`import mille; mille.check(...)`).
42
-
43
- ### npm (Node.js users)
35
+ ### npm
44
36
 
45
37
  ```sh
46
38
  npm install -g @makinzm/mille
47
39
  mille check
48
40
  ```
49
41
 
50
- Or use it without installing globally:
42
+ Or without installing globally:
51
43
 
52
44
  ```sh
53
45
  npx @makinzm/mille check
54
46
  ```
55
47
 
56
- Requires Node.js ≥ 18. The npm package bundles `mille.wasm` (the compiled Rust core) and runs it via Node.js's built-in `node:wasi` module — no native compilation or network access required at install time.
48
+ Requires Node.js ≥ 18. Bundles `mille.wasm` — no native compilation needed.
57
49
 
58
50
  ### go install
59
51
 
@@ -61,11 +53,23 @@ Requires Node.js ≥ 18. The npm package bundles `mille.wasm` (the compiled Rust
61
53
  go install github.com/makinzm/mille/packages/go/mille@latest
62
54
  ```
63
55
 
64
- The Go wrapper embeds `mille.wasm` (the compiled Rust core) and runs it via [wazero](https://wazero.io/) — a zero-dependency WebAssembly runtime. No network access or caching required; the binary is fully self-contained.
56
+ Embeds `mille.wasm` via [wazero](https://wazero.io/) — fully self-contained binary.
65
57
 
66
- ### Direct binary download
58
+ ### pip / uv
67
59
 
68
- Pre-built binaries for each platform are available on [GitHub Releases](https://github.com/makinzm/mille/releases):
60
+ ```sh
61
+ # uv (recommended)
62
+ uv add --dev mille
63
+ uv run mille check
64
+
65
+ # pip
66
+ pip install mille
67
+ mille check
68
+ ```
69
+
70
+ ### Binary download
71
+
72
+ Pre-built binaries are on [GitHub Releases](https://github.com/makinzm/mille/releases):
69
73
 
70
74
  | Platform | Archive |
71
75
  |---|---|
@@ -75,19 +79,56 @@ Pre-built binaries for each platform are available on [GitHub Releases](https://
75
79
  | macOS arm64 | `mille-<version>-aarch64-apple-darwin.tar.gz` |
76
80
  | Windows x86_64 | `mille-<version>-x86_64-pc-windows-msvc.zip` |
77
81
 
82
+ ## Quick Start
83
+
84
+ ### 1. Generate `mille.toml` with `mille init`
85
+
78
86
  ```sh
79
- # Example: Linux x86_64
80
- curl -L https://github.com/makinzm/mille/releases/latest/download/mille-<version>-x86_64-unknown-linux-gnu.tar.gz | tar xz
81
- ./mille check
87
+ mille init
82
88
  ```
83
89
 
84
- ## Quick Start
90
+ `mille init` analyzes actual import statements in your source files to infer layer structure and dependencies — no predetermined naming conventions needed. It prints the inferred dependency graph before writing the config:
91
+
92
+ ```
93
+ Detected languages: rust
94
+ Scanning imports...
95
+ Using layer depth: 2
96
+
97
+ Inferred layer structure:
98
+ domain ← (no internal dependencies)
99
+ usecase → domain
100
+ external: anyhow
101
+ infrastructure → domain
102
+ external: serde, tokio
103
+
104
+ Generated 'mille.toml'
105
+ ```
106
+
107
+ | Flag | Default | Description |
108
+ |---|---|---|
109
+ | `--output <path>` | `mille.toml` | Write config to a custom path |
110
+ | `--force` | false | Overwrite an existing file without prompting |
111
+ | `--depth <N>` | auto | Layer detection depth from project root |
112
+
113
+ **`--depth` and auto-detection**: `mille init` automatically finds the right layer depth by trying depths 1–6, skipping common source-layout roots (`src`, `lib`, `app`, etc.), and selecting the first depth that yields 2–8 candidate layers. For a project with `src/domain/entity`, `src/domain/repository`, `src/usecase/` — depth 2 is chosen, rolling `entity` and `repository` up into `domain`. Use `--depth N` to override when auto-detection picks the wrong level.
114
+
115
+ The generated config includes `allow` (inferred internal dependencies) and `external_allow` (detected external packages) per layer. After generating, review the config and run `mille check` to see results.
116
+
117
+ **Naming in monorepos**: When multiple sub-projects contain a directory with the same name (e.g. `crawler/src/domain` and `server/src/domain`), `mille init` gives each its own layer with a distinguishing prefix (`crawler_domain`, `server_domain`). Merging is left to you.
118
+
119
+ **Excluded paths**: `mille check` automatically skips `.venv`, `venv`, `node_modules`, `target`, `dist`, `build`, and similar build/dependency directories, so generated `paths` patterns like `apps/**` are safe to use.
85
120
 
86
- ### 1. Create `mille.toml`
121
+ **Python submodule imports**: `external_allow = ["matplotlib"]` correctly allows both `import matplotlib` and `import matplotlib.pyplot`.
122
+
123
+ **Go projects**: `mille init` reads `go.mod` and generates `[resolve.go] module_name` automatically — internal module imports are classified correctly during `mille check`. External packages appear in `external_allow` with their full import paths (e.g. `"github.com/cilium/ebpf"`, `"fmt"`, `"net/http"`).
124
+
125
+ **TypeScript/JavaScript subpath imports**: `external_allow = ["vitest"]` correctly allows both `import "vitest"` and `import "vitest/config"`. Scoped packages (`@scope/name/sub`) are matched by `"@scope/name"`.
126
+
127
+ ### 2. (Or) Create `mille.toml` manually
87
128
 
88
129
  Place `mille.toml` in your project root:
89
130
 
90
- **Rust project example:**
131
+ **Rust:**
91
132
 
92
133
  ```toml
93
134
  [project]
@@ -132,17 +173,16 @@ external_allow = ["clap"]
132
173
  allow_methods = ["new", "build", "create", "init", "setup"]
133
174
  ```
134
175
 
135
- **Python project example:**
176
+ **TypeScript / JavaScript:**
136
177
 
137
178
  ```toml
138
179
  [project]
139
- name = "my-python-app"
180
+ name = "my-ts-app"
140
181
  root = "."
141
- languages = ["python"]
182
+ languages = ["typescript"]
142
183
 
143
- [resolve.python]
144
- src_root = "."
145
- package_names = ["domain", "usecase", "infrastructure"]
184
+ [resolve.typescript]
185
+ tsconfig = "./tsconfig.json"
146
186
 
147
187
  [[layers]]
148
188
  name = "domain"
@@ -157,8 +197,8 @@ name = "usecase"
157
197
  paths = ["usecase/**"]
158
198
  dependency_mode = "opt-in"
159
199
  allow = ["domain"]
160
- external_mode = "opt-out"
161
- external_deny = []
200
+ external_mode = "opt-in"
201
+ external_allow = ["zod"]
162
202
 
163
203
  [[layers]]
164
204
  name = "infrastructure"
@@ -169,92 +209,151 @@ external_mode = "opt-out"
169
209
  external_deny = []
170
210
  ```
171
211
 
172
- **TypeScript / JavaScript project example:**
212
+ > Use `languages = ["javascript"]` for plain `.js` / `.jsx` projects (no `[resolve.typescript]` needed).
213
+
214
+ **Go:**
173
215
 
174
216
  ```toml
175
217
  [project]
176
- name = "my-ts-app"
218
+ name = "my-go-app"
177
219
  root = "."
178
- languages = ["typescript"]
220
+ languages = ["go"]
179
221
 
180
- [resolve.typescript]
181
- tsconfig = "./tsconfig.json"
222
+ [resolve.go]
223
+ module_name = "github.com/myorg/my-go-app"
182
224
 
183
225
  [[layers]]
184
226
  name = "domain"
185
227
  paths = ["domain/**"]
186
228
  dependency_mode = "opt-in"
187
229
  allow = []
188
- external_mode = "opt-out"
189
- external_deny = []
190
230
 
191
231
  [[layers]]
192
232
  name = "usecase"
193
233
  paths = ["usecase/**"]
194
234
  dependency_mode = "opt-in"
195
235
  allow = ["domain"]
196
- external_mode = "opt-in"
197
- external_allow = ["zod"]
198
236
 
199
237
  [[layers]]
200
238
  name = "infrastructure"
201
239
  paths = ["infrastructure/**"]
202
240
  dependency_mode = "opt-out"
203
241
  deny = []
204
- external_mode = "opt-out"
205
- external_deny = []
206
- ```
207
242
 
208
- > Use `languages = ["javascript"]` for plain `.js` / `.jsx` projects (no `[resolve.typescript]` needed).
243
+ [[layers]]
244
+ name = "cmd"
245
+ paths = ["cmd/**"]
246
+ dependency_mode = "opt-in"
247
+ allow = ["domain", "usecase", "infrastructure"]
248
+ ```
209
249
 
210
- **Go project example:**
250
+ **Python:**
211
251
 
212
252
  ```toml
213
253
  [project]
214
- name = "my-go-app"
254
+ name = "my-python-app"
215
255
  root = "."
216
- languages = ["go"]
256
+ languages = ["python"]
217
257
 
218
- [resolve.go]
219
- module_name = "github.com/myorg/my-go-app"
258
+ [resolve.python]
259
+ src_root = "."
260
+ package_names = ["domain", "usecase", "infrastructure"]
220
261
 
221
262
  [[layers]]
222
263
  name = "domain"
223
264
  paths = ["domain/**"]
224
265
  dependency_mode = "opt-in"
225
266
  allow = []
267
+ external_mode = "opt-out"
268
+ external_deny = []
226
269
 
227
270
  [[layers]]
228
271
  name = "usecase"
229
272
  paths = ["usecase/**"]
230
273
  dependency_mode = "opt-in"
231
274
  allow = ["domain"]
275
+ external_mode = "opt-out"
276
+ external_deny = []
232
277
 
233
278
  [[layers]]
234
279
  name = "infrastructure"
235
280
  paths = ["infrastructure/**"]
236
281
  dependency_mode = "opt-out"
237
282
  deny = []
283
+ external_mode = "opt-out"
284
+ external_deny = []
285
+ ```
238
286
 
239
- [[layers]]
240
- name = "cmd"
241
- paths = ["cmd/**"]
242
- dependency_mode = "opt-in"
243
- allow = ["domain", "usecase", "infrastructure"]
287
+ ### 2. Visualize with `mille analyze`
288
+
289
+ Before enforcing rules, you can inspect the actual dependency graph:
290
+
291
+ ```sh
292
+ mille analyze # human-readable terminal output (default)
293
+ mille analyze --format json # machine-readable JSON graph
294
+ mille analyze --format dot # Graphviz DOT (pipe to: dot -Tsvg -o graph.svg)
295
+ mille analyze --format svg # self-contained SVG image (open in a browser)
296
+ ```
297
+
298
+ Example SVG output (dark theme, green edges):
299
+
300
+ ```sh
301
+ mille analyze --format svg > graph.svg && open graph.svg
302
+ ```
303
+
304
+ `mille analyze` always exits `0` — it only visualizes, never enforces rules.
305
+
306
+ ### 3. Inspect external dependencies with `mille report external`
307
+
308
+ ```sh
309
+ mille report external # human-readable table (default)
310
+ mille report external --format json # machine-readable JSON
311
+ mille report external --output report.json --format json # write to file
312
+ ```
313
+
314
+ Shows which external packages each layer actually imports — useful for auditing `external_allow` lists or documenting your dependency footprint.
315
+
316
+ Example output:
317
+
318
+ ```
319
+ External Dependencies by Layer
320
+
321
+ domain (none)
322
+ usecase (none)
323
+ infrastructure database/sql
324
+ cmd fmt, os
244
325
  ```
245
326
 
246
- ### 2. Run `mille check`
327
+ `mille report external` always exits `0` — it only reports, never enforces rules.
328
+
329
+ ### 4. Run `mille check`
247
330
 
248
331
  ```sh
249
332
  mille check
250
333
  ```
251
334
 
335
+ Output formats:
336
+
337
+ ```sh
338
+ mille check # human-readable terminal output (default)
339
+ mille check --format github-actions # GitHub Actions annotations (::error file=...)
340
+ mille check --format json # machine-readable JSON
341
+ ```
342
+
343
+ Fail threshold:
344
+
345
+ ```sh
346
+ mille check # exit 1 on error-severity violations only (default)
347
+ mille check --fail-on warning # exit 1 on any violation (error or warning)
348
+ mille check --fail-on error # explicit default — same as no flag
349
+ ```
350
+
252
351
  Exit codes:
253
352
 
254
353
  | Code | Meaning |
255
354
  |---|---|
256
- | `0` | No violations |
257
- | `1` | One or more errors detected |
355
+ | `0` | No violations (or only warnings without `--fail-on warning`) |
356
+ | `1` | One or more violations at the configured fail threshold |
258
357
  | `3` | Configuration file error |
259
358
 
260
359
  ## Configuration Reference
@@ -265,100 +364,111 @@ Exit codes:
265
364
  |---|---|
266
365
  | `name` | Project name |
267
366
  | `root` | Root directory for analysis |
268
- | `languages` | List of languages to check (e.g. `["rust", "go"]`) |
367
+ | `languages` | Languages to check: `"rust"`, `"go"`, `"typescript"`, `"javascript"`, `"python"` |
269
368
 
270
369
  ### `[[layers]]`
271
370
 
272
371
  | Key | Description |
273
372
  |---|---|
274
373
  | `name` | Layer name |
275
- | `paths` | Glob patterns for files belonging to this layer |
374
+ | `paths` | Glob patterns for files in this layer |
276
375
  | `dependency_mode` | `"opt-in"` (deny all except `allow`) or `"opt-out"` (allow all except `deny`) |
277
- | `allow` | Layers allowed as dependencies (when `dependency_mode = "opt-in"`) |
278
- | `deny` | Layers forbidden as dependencies (when `dependency_mode = "opt-out"`) |
376
+ | `allow` | Allowed layers (when `dependency_mode = "opt-in"`) |
377
+ | `deny` | Forbidden layers (when `dependency_mode = "opt-out"`) |
279
378
  | `external_mode` | `"opt-in"` or `"opt-out"` for external library usage |
280
- | `external_allow` | Regex patterns of allowed external packages (when `external_mode = "opt-in"`) |
281
- | `external_deny` | Regex patterns of forbidden external packages (when `external_mode = "opt-out"`) |
379
+ | `external_allow` | Allowed external packages (when `external_mode = "opt-in"`) |
380
+ | `external_deny` | Forbidden external packages (when `external_mode = "opt-out"`) |
282
381
 
283
382
  ### `[[layers.allow_call_patterns]]`
284
383
 
285
- Restricts which methods may be called on a given layer's types. Only valid on the `main` layer.
384
+ Restricts which methods may be called on a given layer's types. Only valid on the `main` layer (or equivalent DI entrypoint).
286
385
 
287
386
  | Key | Description |
288
387
  |---|---|
289
388
  | `callee_layer` | The layer whose methods are being restricted |
290
389
  | `allow_methods` | List of method names that are permitted |
291
390
 
391
+ ### `[ignore]`
392
+
393
+ Exclude files from the architecture check entirely, or suppress violations for test/mock files.
394
+
395
+ | Key | Description |
396
+ |---|---|
397
+ | `paths` | Glob patterns — matching files are excluded from collection and not counted in layer stats |
398
+ | `test_patterns` | Glob patterns — matching files are still counted in layer stats but their imports are not violation-checked |
399
+
400
+ ```toml
401
+ [ignore]
402
+ paths = ["**/mock/**", "**/generated/**", "**/testdata/**"]
403
+ test_patterns = ["**/*_test.go", "**/*.spec.ts", "**/*.test.ts"]
404
+ ```
405
+
406
+ **When to use `paths` vs `test_patterns`:**
407
+
408
+ - `paths`: Files that should not be analyzed at all (generated code, vendor directories, mocks)
409
+ - `test_patterns`: Test files that intentionally import across layers (e.g., integration tests that import both domain and infrastructure)
410
+
411
+ ### `[severity]`
412
+
413
+ Control the severity level of each violation type. Violations can be `"error"`, `"warning"`, or `"info"`.
414
+
415
+ | Key | Default | Description |
416
+ |---|---|---|
417
+ | `dependency_violation` | `"error"` | Layer dependency rule violated |
418
+ | `external_violation` | `"error"` | External library rule violated |
419
+ | `call_pattern_violation` | `"error"` | DI entrypoint method call rule violated |
420
+ | `unknown_import` | `"warning"` | Import that could not be classified |
421
+
422
+ ```toml
423
+ [severity]
424
+ dependency_violation = "warning" # treat as warning for gradual adoption
425
+ external_violation = "error"
426
+ call_pattern_violation = "error"
427
+ unknown_import = "warning"
428
+ ```
429
+
430
+ Use `--fail-on warning` to exit 1 even for warnings when integrating into CI gradually.
431
+
292
432
  ### `[resolve.typescript]`
293
433
 
294
434
  | Key | Description |
295
435
  |---|---|
296
- | `tsconfig` | Path to `tsconfig.json`. When specified, mille reads `compilerOptions.paths` and resolves path aliases (e.g. `@/*`) as internal imports. |
436
+ | `tsconfig` | Path to `tsconfig.json`. mille reads `compilerOptions.paths` and resolves path aliases (e.g. `@/*`) as internal imports. |
297
437
 
298
438
  **How TypeScript / JavaScript imports are classified:**
299
439
 
300
440
  | Import | Classification |
301
441
  |---|---|
302
- | `import X from "./module"` (starts with `./`) | Internal |
303
- | `import X from "../module"` (starts with `../`) | Internal |
442
+ | `import X from "./module"` | Internal |
443
+ | `import X from "../module"` | Internal |
304
444
  | `import X from "@/module"` (path alias in `tsconfig.json`) | Internal |
305
- | `import X from "react"` (npm package) | External |
306
- | `import fs from "node:fs"` (Node.js built-in) | External |
307
-
308
- For relative imports, mille resolves the path from the importing file and matches it against layer glob patterns. For example, `import { User } from "../domain/user"` in `usecase/user_usecase.ts` resolves to `domain/user`, matching the layer glob `domain/**`.
309
-
310
- For path aliases, mille expands the alias using `compilerOptions.paths` and treats the result as an internal import. For example, with `"@/*": ["./src/*"]`, `import { User } from "@/domain/user"` resolves to `src/domain/user`.
445
+ | `import X from "react"` | External |
446
+ | `import fs from "node:fs"` | External |
311
447
 
312
448
  ### `[resolve.go]`
313
449
 
314
450
  | Key | Description |
315
451
  |---|---|
316
- | `module_name` | Go module name (matches the module path in `go.mod`) |
452
+ | `module_name` | Go module name (matches `go.mod`). `mille init` generates this automatically from `go.mod`. |
317
453
 
318
454
  ### `[resolve.python]`
319
455
 
320
456
  | Key | Description |
321
457
  |---|---|
322
458
  | `src_root` | Root directory of the Python source tree (relative to `mille.toml`) |
323
- | `package_names` | List of your own package names (used to classify absolute imports as internal). e.g. `["domain", "usecase", "infrastructure"]` |
459
+ | `package_names` | Your package names imports starting with these are classified as internal. e.g. `["domain", "usecase"]` |
324
460
 
325
461
  **How Python imports are classified:**
326
462
 
327
463
  | Import | Classification |
328
464
  |---|---|
329
465
  | `from .sibling import X` (relative) | Internal |
330
- | `import domain.entity` (matches a `package_names` entry) | Internal |
331
- | `import os`, `import sqlalchemy` (others) | External |
332
-
333
- ## Python API
334
-
335
- In addition to the CLI, the Python package exposes a programmatic API:
336
-
337
- ```python
338
- import mille
339
-
340
- # Run architecture check and get a result object
341
- result = mille.check("path/to/mille.toml") # defaults to "mille.toml"
342
-
343
- print(f"violations: {len(result.violations)}")
344
- for v in result.violations:
345
- print(f" {v.file}:{v.line} {v.from_layer} -> {v.to_layer} ({v.import_path})")
346
-
347
- for stat in result.layer_stats:
348
- print(f" {stat.name}: {stat.file_count} file(s), {stat.violation_count} violation(s)")
349
- ```
350
-
351
- **Types exposed:**
352
-
353
- | Class | Attributes |
354
- |---|---|
355
- | `CheckResult` | `violations: list[Violation]`, `layer_stats: list[LayerStat]` |
356
- | `Violation` | `file`, `line`, `from_layer`, `to_layer`, `import_path`, `kind` |
357
- | `LayerStat` | `name`, `file_count`, `violation_count` |
466
+ | `import domain.entity` (matches `package_names`) | Internal |
467
+ | `import os`, `import sqlalchemy` | External |
358
468
 
359
469
  ## How it Works
360
470
 
361
- mille uses [tree-sitter](https://tree-sitter.github.io/) for AST-based import extraction — no regex heuristics. The core engine is language-agnostic; language-specific logic is isolated to the `parser` and `resolver` layers.
471
+ mille uses [tree-sitter](https://tree-sitter.github.io/) for AST-based import extraction — no regex heuristics.
362
472
 
363
473
  ```
364
474
  mille.toml
@@ -366,7 +476,7 @@ mille.toml
366
476
 
367
477
  Layer definitions
368
478
 
369
- Source files (*.rs, *.go, *.py, ...)
479
+ Source files (*.rs, *.go, *.py, *.ts, *.js, ...)
370
480
  │ tree-sitter parse
371
481
 
372
482
  RawImport list
package/index.js CHANGED
@@ -8,6 +8,16 @@ process.on('warning', (w) => {
8
8
  process.stderr.write(w.stack + '\n');
9
9
  });
10
10
 
11
+ // NOTE: Intercept --version/-V before forwarding to WASM so that the npm
12
+ // package version (updated by `npm version X.Y.Z` at release time) is shown,
13
+ // rather than the version baked into mille.wasm at WASM-build time.
14
+ const userArgs = process.argv.slice(2);
15
+ if (userArgs.includes('--version') || userArgs.includes('-V')) {
16
+ const { version } = require('./package.json');
17
+ process.stdout.write(`mille ${version}\n`);
18
+ process.exit(0);
19
+ }
20
+
11
21
  const { WASI } = require('node:wasi');
12
22
  const { readFileSync } = require('node:fs');
13
23
  const { join } = require('node:path');
package/mille.wasm CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makinzm/mille",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "Architecture Checker — Rust-based multi-language architecture linter",
5
5
  "main": "index.js",
6
6
  "bin": {