oxlint-plugin-vize 0.303.0 → 0.310.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 +62 -0
- package/dist/index.d.mts +102 -1
- package/dist/index.mjs +97 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ This package lets Oxlint execute Patina through Vize's native binding while stil
|
|
|
13
13
|
- Runs Vize Patina rules inside Oxlint as `vize/*` diagnostics, so Vue-specific findings can live beside Oxlint core rules in one command.
|
|
14
14
|
- Keeps Oxlint's existing rules and built-in `vue` plugin active. The bridge adds Vize rules; it does not replace `eqeqeq`, `no-console`, or your existing `vue/*` setup.
|
|
15
15
|
- Ships preset rule maps for JS/TS Oxlint configs: `configs.recommended`, `configs.essential`, `configs.ecosystem`, `configs.opinionated`, `configs.nuxt`, `configs.all`, and type-aware opt-in variants.
|
|
16
|
+
- Ships `createVizeLintConfig()` for the Vite+ `lint` block in `vite.config.ts`, which is the only Oxlint configuration `vp lint` and `vp check` read.
|
|
16
17
|
- Supports runtime settings through `settings.vize`, including `locale`, `preset`, and `helpLevel`.
|
|
17
18
|
- Provides the `oxlint-vize` CLI wrapper, which runs Oxlint with a scriptless-SFC workaround and rewrites temporary paths back to the original `.vue` files.
|
|
18
19
|
- Resolves Vize native bindings through platform-specific optional dependencies, so published installs do not need a separate `@vizejs/native` package.
|
|
@@ -46,6 +47,67 @@ vp install -D oxlint oxlint-plugin-vize
|
|
|
46
47
|
|
|
47
48
|
## Usage
|
|
48
49
|
|
|
50
|
+
Which file you configure depends on which command you run.
|
|
51
|
+
|
|
52
|
+
| Command | Reads |
|
|
53
|
+
| ----------------------- | ------------------------------------ |
|
|
54
|
+
| `vp lint`, `vp check` | the `lint` block in `vite.config.ts` |
|
|
55
|
+
| `oxlint`, `oxlint-vize` | `.oxlintrc.json` (or `-c <path>`) |
|
|
56
|
+
|
|
57
|
+
> [!IMPORTANT]
|
|
58
|
+
> Vite+ never reads `.oxlintrc.json`. A `.oxlintrc.json` carrying `jsPlugins` and `vize/*` rules
|
|
59
|
+
> looks configured, but `vp lint` ignores the file, so Oxlint never sees a `vize/*` rule id and
|
|
60
|
+
> reports **zero** Vize diagnostics while exiting `0`. `vp lint --init` does not migrate an existing
|
|
61
|
+
> `.oxlintrc.json` either: it writes a fresh `lint` block and leaves the old file in place.
|
|
62
|
+
> If you use `vp lint`, configure the `lint` block.
|
|
63
|
+
|
|
64
|
+
### With `vp lint` (Vite+)
|
|
65
|
+
|
|
66
|
+
`createVizeLintConfig()` returns the whole `lint` block, so the `jsPlugins` entry cannot go missing:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
// vite.config.ts
|
|
70
|
+
import { defineConfig } from "vite-plus";
|
|
71
|
+
import { createVizeLintConfig } from "oxlint-plugin-vize";
|
|
72
|
+
|
|
73
|
+
export default defineConfig({
|
|
74
|
+
lint: createVizeLintConfig({
|
|
75
|
+
preset: "essential",
|
|
76
|
+
rules: {
|
|
77
|
+
"no-console": "warn",
|
|
78
|
+
},
|
|
79
|
+
settings: {
|
|
80
|
+
helpLevel: "short",
|
|
81
|
+
},
|
|
82
|
+
}),
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`preset` drives both the emitted rule map and `settings.vize.preset`, so the two can never disagree.
|
|
87
|
+
That matters because the bridge silently drops any `vize/*` rule outside the active preset: listing
|
|
88
|
+
`vize/ecosystem/router-link-require-to` while the active preset is `general-recommended` reports
|
|
89
|
+
nothing at all. `createVizeLintConfig` throws for that case, and for unknown `vize/*` ids, instead of
|
|
90
|
+
leaving you with a config that looks enabled and reports nothing. Use `preset: "incremental"` when
|
|
91
|
+
you want only the rules you list, and `preset: "all"` for every bundle at once.
|
|
92
|
+
|
|
93
|
+
The emitted block always enables Oxlint's built-in `vue` plugin. Pass `plugins` to keep the rest of
|
|
94
|
+
your project's plugin list; they are merged with `vue`, never replaced, because narrowing the list
|
|
95
|
+
would silently drop everything those plugins report. A `create-vue` project keeps its generated set
|
|
96
|
+
like this:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
export default defineConfig({
|
|
100
|
+
lint: {
|
|
101
|
+
...createVizeLintConfig({
|
|
102
|
+
plugins: ["eslint", "typescript", "unicorn", "oxc"],
|
|
103
|
+
}),
|
|
104
|
+
ignorePatterns: ["dist/**"],
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### With `oxlint` or `oxlint-vize`
|
|
110
|
+
|
|
49
111
|
Enable Oxlint's built-in `vue` plugin as well as this JS plugin:
|
|
50
112
|
|
|
51
113
|
```json
|
package/dist/index.d.mts
CHANGED
|
@@ -4,7 +4,15 @@ import * as _$_oxlint_plugins0 from "@oxlint/plugins";
|
|
|
4
4
|
declare const _default: _$_oxlint_plugins0.Plugin;
|
|
5
5
|
//#endregion
|
|
6
6
|
//#region src/model.d.ts
|
|
7
|
+
type HelpLevel = "none" | "short" | "full";
|
|
7
8
|
type PatinaPreset = "general-recommended" | "essential" | "ecosystem" | "incremental" | "opinionated" | "nuxt";
|
|
9
|
+
interface PatinaSettings {
|
|
10
|
+
locale?: string;
|
|
11
|
+
helpLevel?: HelpLevel;
|
|
12
|
+
preset?: PatinaPreset;
|
|
13
|
+
typeAware?: boolean;
|
|
14
|
+
corsaPath?: string;
|
|
15
|
+
}
|
|
8
16
|
//#endregion
|
|
9
17
|
//#region src/configs.d.ts
|
|
10
18
|
type OxlintRuleSeverity = "error" | "warn";
|
|
@@ -27,4 +35,97 @@ declare const configs: {
|
|
|
27
35
|
readonly recommendedWithTypeAware: OxlintRuleConfig;
|
|
28
36
|
};
|
|
29
37
|
//#endregion
|
|
30
|
-
|
|
38
|
+
//#region src/vite-plus.d.ts
|
|
39
|
+
/**
|
|
40
|
+
* Bare specifier Oxlint uses to load this bridge as a JS plugin.
|
|
41
|
+
*
|
|
42
|
+
* Vite+ hands the `lint` block to Oxlint unchanged, so the same specifier works
|
|
43
|
+
* in `vite.config.ts` and in a hand-written `.oxlintrc.json`.
|
|
44
|
+
*/
|
|
45
|
+
declare const VIZE_JS_PLUGIN_SPECIFIER = "oxlint-plugin-vize";
|
|
46
|
+
/**
|
|
47
|
+
* Rule bundles `createVizeLintConfig` accepts.
|
|
48
|
+
*
|
|
49
|
+
* `"all"` and `"incremental"` both disable preset gating in the bridge, which is
|
|
50
|
+
* what makes them usable: `"all"` needs every bundle's rules to run at once, and
|
|
51
|
+
* `"incremental"` needs only the rules the caller lists to run.
|
|
52
|
+
*/
|
|
53
|
+
type VizeLintPreset = PatinaPreset | "all";
|
|
54
|
+
interface VizeLintConfigOptions {
|
|
55
|
+
/**
|
|
56
|
+
* Include Vize's unstable `vize/type/*` rules in the preset rule map. Off by
|
|
57
|
+
* default, matching `createVizeRuleConfig`.
|
|
58
|
+
*/
|
|
59
|
+
includeTypeAware?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Built-in Oxlint plugins to keep enabled alongside `vue`.
|
|
62
|
+
*
|
|
63
|
+
* The emitted block always lists `vue`, and narrowing a project's plugin list
|
|
64
|
+
* would silently drop the diagnostics those plugins produce, so anything passed
|
|
65
|
+
* here is merged rather than replaced. A `create-vue` project, for example,
|
|
66
|
+
* needs `["eslint", "typescript", "unicorn", "oxc"]` carried over.
|
|
67
|
+
*/
|
|
68
|
+
plugins?: readonly string[];
|
|
69
|
+
/**
|
|
70
|
+
* Rule bundle to enable. Defaults to `"general-recommended"`, the bridge's own
|
|
71
|
+
* default. `"incremental"` emits no preset rules, so only `rules` run.
|
|
72
|
+
*/
|
|
73
|
+
preset?: VizeLintPreset;
|
|
74
|
+
/**
|
|
75
|
+
* Extra Oxlint rules merged after the preset rules. Core Oxlint rule ids pass
|
|
76
|
+
* through untouched; `vize/*` ids are validated against the rules the native
|
|
77
|
+
* bridge registers and against the resolved preset.
|
|
78
|
+
*/
|
|
79
|
+
rules?: OxlintRuleConfig;
|
|
80
|
+
/**
|
|
81
|
+
* Patina runtime settings forwarded through `settings.vize`. `preset` is
|
|
82
|
+
* intentionally absent: it is derived from `options.preset` so the rule map and
|
|
83
|
+
* the bridge's runtime gate can never disagree.
|
|
84
|
+
*/
|
|
85
|
+
settings?: Omit<PatinaSettings, "preset">;
|
|
86
|
+
}
|
|
87
|
+
interface VizeLintConfig {
|
|
88
|
+
jsPlugins: string[];
|
|
89
|
+
plugins: string[];
|
|
90
|
+
rules: OxlintRuleConfig;
|
|
91
|
+
settings: {
|
|
92
|
+
vize: PatinaSettings;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Builds the Oxlint configuration block that runs Patina through this bridge.
|
|
97
|
+
*
|
|
98
|
+
* Vite+ (`vp lint` / `vp check`) reads its Oxlint configuration from the `lint`
|
|
99
|
+
* key of `vite.config.ts` and never reads `.oxlintrc.json`. Wiring the bridge by
|
|
100
|
+
* hand therefore has a silent failure mode: a `.oxlintrc.json` carrying
|
|
101
|
+
* `jsPlugins` and `vize/*` rules looks configured, Vite+ ignores the file, Oxlint
|
|
102
|
+
* never sees a `vize/*` rule id, and `vp lint` reports zero Vize diagnostics
|
|
103
|
+
* while exiting `0`. Spreading this object into `lint` removes the chance to get
|
|
104
|
+
* that wrong:
|
|
105
|
+
*
|
|
106
|
+
* ```ts
|
|
107
|
+
* import { defineConfig } from "vite-plus";
|
|
108
|
+
* import { createVizeLintConfig } from "oxlint-plugin-vize";
|
|
109
|
+
*
|
|
110
|
+
* export default defineConfig({
|
|
111
|
+
* lint: createVizeLintConfig({ preset: "essential" }),
|
|
112
|
+
* });
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* Both validations below exist because the bridge's normal failure modes are
|
|
116
|
+
* silent rather than loud:
|
|
117
|
+
*
|
|
118
|
+
* - An unknown `vize/*` id only produces Oxlint's
|
|
119
|
+
* `Rule '...' not found in plugin 'vize'` error when Oxlint actually reads the
|
|
120
|
+
* config. A typo in a config Oxlint never reads reports nothing at all.
|
|
121
|
+
* - A `vize/*` id that is outside the active preset is dropped by the bridge's
|
|
122
|
+
* runtime preset gate (`plugin.ts`), so it stays listed in `rules` and reports
|
|
123
|
+
* nothing. `preset: "incremental"` is the supported way to run an arbitrary
|
|
124
|
+
* subset.
|
|
125
|
+
*
|
|
126
|
+
* @throws {Error} When `options.rules` names a `vize/*` id the native bridge does
|
|
127
|
+
* not register, or one the resolved preset would silently suppress.
|
|
128
|
+
*/
|
|
129
|
+
declare function createVizeLintConfig(options?: VizeLintConfigOptions): VizeLintConfig;
|
|
130
|
+
//#endregion
|
|
131
|
+
export { type OxlintRuleConfig, type OxlintRuleSeverity, VIZE_JS_PLUGIN_SPECIFIER, type VizeLintConfig, type VizeLintConfigOptions, type VizeLintPreset, type VizeRuleConfigOptions, configs, createVizeLintConfig, createVizeRuleConfig, _default as default };
|
package/dist/index.mjs
CHANGED
|
@@ -623,4 +623,100 @@ if (import.meta.vitest) {
|
|
|
623
623
|
});
|
|
624
624
|
}
|
|
625
625
|
//#endregion
|
|
626
|
-
|
|
626
|
+
//#region src/vite-plus.ts
|
|
627
|
+
/**
|
|
628
|
+
* Bare specifier Oxlint uses to load this bridge as a JS plugin.
|
|
629
|
+
*
|
|
630
|
+
* Vite+ hands the `lint` block to Oxlint unchanged, so the same specifier works
|
|
631
|
+
* in `vite.config.ts` and in a hand-written `.oxlintrc.json`.
|
|
632
|
+
*/
|
|
633
|
+
const VIZE_JS_PLUGIN_SPECIFIER = "oxlint-plugin-vize";
|
|
634
|
+
const VIZE_RULE_PREFIX = "vize/";
|
|
635
|
+
/**
|
|
636
|
+
* Builds the Oxlint configuration block that runs Patina through this bridge.
|
|
637
|
+
*
|
|
638
|
+
* Vite+ (`vp lint` / `vp check`) reads its Oxlint configuration from the `lint`
|
|
639
|
+
* key of `vite.config.ts` and never reads `.oxlintrc.json`. Wiring the bridge by
|
|
640
|
+
* hand therefore has a silent failure mode: a `.oxlintrc.json` carrying
|
|
641
|
+
* `jsPlugins` and `vize/*` rules looks configured, Vite+ ignores the file, Oxlint
|
|
642
|
+
* never sees a `vize/*` rule id, and `vp lint` reports zero Vize diagnostics
|
|
643
|
+
* while exiting `0`. Spreading this object into `lint` removes the chance to get
|
|
644
|
+
* that wrong:
|
|
645
|
+
*
|
|
646
|
+
* ```ts
|
|
647
|
+
* import { defineConfig } from "vite-plus";
|
|
648
|
+
* import { createVizeLintConfig } from "oxlint-plugin-vize";
|
|
649
|
+
*
|
|
650
|
+
* export default defineConfig({
|
|
651
|
+
* lint: createVizeLintConfig({ preset: "essential" }),
|
|
652
|
+
* });
|
|
653
|
+
* ```
|
|
654
|
+
*
|
|
655
|
+
* Both validations below exist because the bridge's normal failure modes are
|
|
656
|
+
* silent rather than loud:
|
|
657
|
+
*
|
|
658
|
+
* - An unknown `vize/*` id only produces Oxlint's
|
|
659
|
+
* `Rule '...' not found in plugin 'vize'` error when Oxlint actually reads the
|
|
660
|
+
* config. A typo in a config Oxlint never reads reports nothing at all.
|
|
661
|
+
* - A `vize/*` id that is outside the active preset is dropped by the bridge's
|
|
662
|
+
* runtime preset gate (`plugin.ts`), so it stays listed in `rules` and reports
|
|
663
|
+
* nothing. `preset: "incremental"` is the supported way to run an arbitrary
|
|
664
|
+
* subset.
|
|
665
|
+
*
|
|
666
|
+
* @throws {Error} When `options.rules` names a `vize/*` id the native bridge does
|
|
667
|
+
* not register, or one the resolved preset would silently suppress.
|
|
668
|
+
*/
|
|
669
|
+
function createVizeLintConfig(options = {}) {
|
|
670
|
+
const preset = options.preset ?? "general-recommended";
|
|
671
|
+
const extraRules = options.rules ?? {};
|
|
672
|
+
assertUsableVizeRules(extraRules, preset);
|
|
673
|
+
return {
|
|
674
|
+
jsPlugins: [VIZE_JS_PLUGIN_SPECIFIER],
|
|
675
|
+
plugins: [...new Set(["vue", ...options.plugins ?? []])],
|
|
676
|
+
rules: {
|
|
677
|
+
...createPresetRules(preset, options.includeTypeAware),
|
|
678
|
+
...extraRules
|
|
679
|
+
},
|
|
680
|
+
settings: { vize: {
|
|
681
|
+
...options.settings,
|
|
682
|
+
preset: toRuntimePreset(preset)
|
|
683
|
+
} }
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
function createPresetRules(preset, includeTypeAware) {
|
|
687
|
+
return preset === "incremental" ? {} : createVizeRuleConfig({
|
|
688
|
+
includeTypeAware,
|
|
689
|
+
preset
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Maps a rule bundle to the `settings.vize.preset` the bridge must run with.
|
|
694
|
+
*
|
|
695
|
+
* `"all"` becomes `"incremental"` because the bridge gates each rule on preset
|
|
696
|
+
* membership; gating an all-bundles rule map by any single preset would suppress
|
|
697
|
+
* the rules that only belong to the other bundles.
|
|
698
|
+
*/
|
|
699
|
+
function toRuntimePreset(preset) {
|
|
700
|
+
return preset === "all" ? "incremental" : preset;
|
|
701
|
+
}
|
|
702
|
+
function assertUsableVizeRules(rules, preset) {
|
|
703
|
+
const ruleMetaById = new Map(getPatinaRules().map((ruleMeta) => [`${VIZE_RULE_PREFIX}${ruleMeta.name}`, ruleMeta]));
|
|
704
|
+
const configuredIds = Object.keys(rules).filter((ruleId) => ruleId.startsWith(VIZE_RULE_PREFIX)).sort();
|
|
705
|
+
const unknownIds = configuredIds.filter((ruleId) => !ruleMetaById.has(ruleId));
|
|
706
|
+
if (unknownIds.length > 0) throw new Error(`Unknown Vize rule ${pluralizeIds(unknownIds)}: ${unknownIds.join(", ")}. Check the id against the rules oxlint-plugin-vize registers.`);
|
|
707
|
+
const runtimePreset = toRuntimePreset(preset);
|
|
708
|
+
const suppressedIds = configuredIds.filter((ruleId) => isSuppressedByPreset(ruleMetaById.get(ruleId), runtimePreset));
|
|
709
|
+
if (suppressedIds.length > 0) throw new Error(`Vize rule ${pluralizeIds(suppressedIds)} outside the "${preset}" preset: ${suppressedIds.join(", ")}. Use preset: "incremental" to run an explicit rule subset, or pick the preset that owns these rules.`);
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Mirrors the runtime gate in `plugin.ts`: rules with no preset membership are
|
|
713
|
+
* never gated, and `"incremental"` skips gating entirely.
|
|
714
|
+
*/
|
|
715
|
+
function isSuppressedByPreset(ruleMeta, runtimePreset) {
|
|
716
|
+
return ruleMeta.presets.length > 0 && runtimePreset !== "incremental" && !ruleMeta.presets.includes(runtimePreset);
|
|
717
|
+
}
|
|
718
|
+
function pluralizeIds(ids) {
|
|
719
|
+
return ids.length === 1 ? "id" : "ids";
|
|
720
|
+
}
|
|
721
|
+
//#endregion
|
|
722
|
+
export { VIZE_JS_PLUGIN_SPECIFIER, configs, createVizeLintConfig, createVizeRuleConfig, plugin_default as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oxlint-plugin-vize",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.310.0",
|
|
4
4
|
"description": "Oxlint JS plugin bridge for Vize Patina",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lint",
|
|
@@ -44,21 +44,21 @@
|
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@tsdown/css": "0.22.0",
|
|
46
46
|
"@types/node": "25.9.2",
|
|
47
|
-
"@vizejs/native": "0.
|
|
47
|
+
"@vizejs/native": "0.310.0",
|
|
48
48
|
"tsdown": "0.22.0",
|
|
49
49
|
"typescript": "6.0.3",
|
|
50
50
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.1.21",
|
|
51
51
|
"vite-plus": "0.1.21"
|
|
52
52
|
},
|
|
53
53
|
"optionalDependencies": {
|
|
54
|
-
"@vizejs/native-darwin-arm64": "0.
|
|
55
|
-
"@vizejs/native-darwin-x64": "0.
|
|
56
|
-
"@vizejs/native-linux-arm64-gnu": "0.
|
|
57
|
-
"@vizejs/native-linux-arm64-musl": "0.
|
|
58
|
-
"@vizejs/native-linux-x64-gnu": "0.
|
|
59
|
-
"@vizejs/native-linux-x64-musl": "0.
|
|
60
|
-
"@vizejs/native-win32-arm64-msvc": "0.
|
|
61
|
-
"@vizejs/native-win32-x64-msvc": "0.
|
|
54
|
+
"@vizejs/native-darwin-arm64": "0.310.0",
|
|
55
|
+
"@vizejs/native-darwin-x64": "0.310.0",
|
|
56
|
+
"@vizejs/native-linux-arm64-gnu": "0.310.0",
|
|
57
|
+
"@vizejs/native-linux-arm64-musl": "0.310.0",
|
|
58
|
+
"@vizejs/native-linux-x64-gnu": "0.310.0",
|
|
59
|
+
"@vizejs/native-linux-x64-musl": "0.310.0",
|
|
60
|
+
"@vizejs/native-win32-arm64-msvc": "0.310.0",
|
|
61
|
+
"@vizejs/native-win32-x64-msvc": "0.310.0"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": "^22 || >= 24"
|