vite-plugin-nudo 0.3.4 → 0.4.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.
package/README.md CHANGED
@@ -25,14 +25,28 @@ import nudo from 'vite-plugin-nudo'
25
25
  export default {
26
26
  plugins: [
27
27
  nudo({
28
- include: '**/*.js', // default
29
- exclude: '**/node_modules/**', // default
30
- failOnError: false, // default
28
+ // include / exclude accept `string | string[]` (normalized to string[] at runtime)
29
+ include: ['**/*.js', '**/*.mjs', '**/*.ts'], // default — matches isNudoTargetPath (.js/.mjs/.ts)
30
+ exclude: ['**/node_modules/**', '**/*.d.ts'], // default
31
+ failOnError: false, // default — contract errors warn, do not fail the build
31
32
  }),
32
33
  ],
33
34
  }
34
35
  ```
35
36
 
37
+ ## Analysis gating
38
+
39
+ File selection is two-stage:
40
+
41
+ 1. **Path globs** (`include` / `exclude`) — defaults cover `**/*.js`, `**/*.mjs`, `**/*.ts` (the same extensions `isNudoTargetPath` accepts; `.cjs` / `.cts` / `.mts` / `.tsx` / `.d.ts` / `*.nudo.js` are not analysis targets).
42
+ 2. **`nudo.analysis.mode`** via `shouldAnalyzeFile` — same gate as the LSP/CLI. Shipped default is `"exports"` (files with `@nudo:`, `export`, or a sidecar are analyzed). Set `"all"` or `"directives"` in `package.json#nudo.analysis` to widen or tighten the gate.
43
+
44
+ ## Diagnostics & failOnError
45
+
46
+ - **Diagnostics tier** follows `package.json#nudo.analysis.diagnostics` when set. With a project `nudo` config present but no explicit tier, the plugin uses the same `analysisConfig` default as the LSP (`mode=directives` → `errors`; `exports`/`all` → `default`). Without a project config the plugin keeps its historical `default` tier (errors + warnings) so ad-hoc files still surface warnings in build logs.
47
+ - **`failOnError`** defaults to **false** (intentional, E3): build-time diagnostics warn rather than fail, so broad analysis modes do not break CI on false positives. Use `nudo check` as the contract CI gate, or pass `failOnError: true` to block the build on error-severity contract diagnostics.
48
+ - Display filtering via `nudo.analysis.diagnostics: "off"` silences plugin diagnostics; it does **not** replace `nudo check`.
49
+
36
50
  ## License
37
51
 
38
52
  [MIT](https://github.com/nudojs/nudo/blob/main/LICENSE)
package/dist/index.d.ts CHANGED
@@ -1,6 +1,12 @@
1
1
  type NudoPluginOptions = {
2
- include?: string[];
3
- exclude?: string[];
2
+ include?: string[] | string;
3
+ exclude?: string[] | string;
4
+ /**
5
+ * error 级诊断是否让构建失败。
6
+ * 默认 false(E3 / docs):构建期诊断先 warn,避免无指令/隐式推断误伤 CI。
7
+ * 契约门禁请用 `nudo check`(CI gate)或显式 `failOnError: true`。
8
+ * 项目可用 `nudo.analysis.diagnostics` 控制噪声档;显式契约 error 仍会打出。
9
+ */
4
10
  failOnError?: boolean;
5
11
  };
6
12
  declare function nudoPlugin(options?: NudoPluginOptions): any;
package/dist/index.js CHANGED
@@ -1,14 +1,24 @@
1
1
  // src/index.ts
2
2
  import {
3
3
  analyzeFileAsync,
4
+ analysisConfig,
4
5
  defaultLoadModule as loadModule,
5
- clearAnalysisSessionCaches
6
+ clearAnalysisSessionCaches,
7
+ shouldAnalyzeFile,
8
+ filterDiagnosticsByLevel,
9
+ findProjectConfig,
10
+ interfaceConfig
6
11
  } from "@nudojs/service";
12
+ import { dirname } from "path";
7
13
  import { checkSource, pTrue } from "@nudojs/core";
8
- var NUDO_DIRECTIVE_RE = /@nudo:(case|mock|pure|skip|sample|refine|interface|import|env|mock-module|as|replace)\b/;
9
14
  function checkIssuesToDiagnostics(id, code) {
10
15
  try {
11
- const report = checkSource(id, code, pTrue, { loadModule, fromFile: id });
16
+ const autoBind = interfaceConfig(findProjectConfig(dirname(id))?.config).autoBind;
17
+ const report = checkSource(id, code, pTrue, {
18
+ loadModule,
19
+ fromFile: id,
20
+ ...autoBind === false ? { autoBind: false } : {}
21
+ });
12
22
  return report.issues.filter((i) => i.severity === "error" || i.severity === "warning").map((i) => {
13
23
  const line = i.line ?? 1;
14
24
  const column = i.column ?? 0;
@@ -31,7 +41,16 @@ function checkIssuesToDiagnostics(id, code) {
31
41
  return [];
32
42
  }
33
43
  }
34
- var DEFAULT_INCLUDE = ["**/*.js", "**/*.mjs", "**/*.ts", "**/*.mts"];
44
+ function viteDiagnosticsLevel(id) {
45
+ const proj = findProjectConfig(dirname(id));
46
+ const raw = proj?.config?.analysis?.diagnostics;
47
+ if (raw === "off" || raw === "errors" || raw === "default" || raw === "verbose") {
48
+ return raw;
49
+ }
50
+ if (proj) return analysisConfig(proj.config).diagnostics;
51
+ return "default";
52
+ }
53
+ var DEFAULT_INCLUDE = ["**/*.js", "**/*.mjs", "**/*.ts"];
35
54
  var DEFAULT_EXCLUDE = ["**/node_modules/**", "**/*.d.ts"];
36
55
  var REGEX_SPECIALS = /[\\^$.|?*+(){}\[\]]/;
37
56
  function escapeRegExpChar(ch) {
@@ -71,7 +90,8 @@ function compilePattern(pattern) {
71
90
  return (id) => regExp.test(id);
72
91
  }
73
92
  function compileAnyMatcher(patterns) {
74
- const matchers = patterns.map(compilePattern);
93
+ const list = Array.isArray(patterns) ? patterns : [patterns];
94
+ const matchers = list.map(compilePattern);
75
95
  return (id) => matchers.some((match) => match(id));
76
96
  }
77
97
  function nudoPlugin(options = {}) {
@@ -93,11 +113,18 @@ function nudoPlugin(options = {}) {
93
113
  async transform(code, id) {
94
114
  if (excludeMatch(id)) return null;
95
115
  if (!includeMatch(id)) return null;
96
- if (!NUDO_DIRECTIVE_RE.test(code)) return null;
116
+ if (!shouldAnalyzeFile(id, code)) return null;
97
117
  try {
98
118
  const result = await analyzeFileAsync(id, code);
99
119
  const checkDiags = checkIssuesToDiagnostics(id, code);
100
- const merged = { ...result, diagnostics: [...result.diagnostics, ...checkDiags] };
120
+ const level = viteDiagnosticsLevel(id);
121
+ const merged = {
122
+ ...result,
123
+ diagnostics: filterDiagnosticsByLevel(
124
+ [...result.diagnostics, ...checkDiags],
125
+ level
126
+ )
127
+ };
101
128
  analysisCache.set(id, merged);
102
129
  for (const diag of merged.diagnostics) {
103
130
  const loc = `${id}:${diag.range.start.line}:${diag.range.start.column}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-nudo",
3
- "version": "0.3.4",
3
+ "version": "0.4.0",
4
4
  "engines": {
5
5
  "node": ">=20"
6
6
  },
@@ -38,8 +38,8 @@
38
38
  "registry": "https://registry.npmjs.org"
39
39
  },
40
40
  "dependencies": {
41
- "@nudojs/core": "1.0.1",
42
- "@nudojs/service": "1.0.1"
41
+ "@nudojs/core": "2.0.0",
42
+ "@nudojs/service": "2.0.0"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "vite": ">=5.0.0"