oxlint-plugin-vize 0.501.0 → 0.503.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/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { m as loadBinding, n as prepareWorkaroundSource, p as isStandaloneHtmlFile, s as extractSfcBlocks, u as hasVueLikeExtension } from "./workaround-FRBXv1sV.mjs";
2
- import { spawn, spawnSync } from "node:child_process";
3
- import path from "node:path";
1
+ import { m as loadBinding, n as prepareWorkaroundSource, p as isStandaloneHtmlFile, s as extractSfcBlocks, u as hasVueLikeExtension } from "./workaround-Byh3ja-i.mjs";
4
2
  import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { spawn, spawnSync } from "node:child_process";
5
5
  import { createHash, randomUUID } from "node:crypto";
6
6
  import os from "node:os";
7
7
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -1,6 +1,8 @@
1
- import { a as validateWorkaroundAuthority, c as formatBlockLabel, d as isPatinaFile, f as isScriptLikeFile, i as resolveWorkaroundSource, l as getDiagnosticBlock, m as loadBinding, o as compareLineColumn, r as readOriginalWorkaroundSource, s as extractSfcBlocks, t as isLocationBridgeProgram } from "./workaround-FRBXv1sV.mjs";
1
+ import { a as validateWorkaroundAuthority, c as formatBlockLabel, d as isPatinaFile, f as isScriptLikeFile, i as resolveWorkaroundSource, l as getDiagnosticBlock, m as loadBinding, o as compareLineColumn, r as readOriginalWorkaroundSource, s as extractSfcBlocks, t as isLocationBridgeProgram } from "./workaround-Byh3ja-i.mjs";
2
+ import { createRequire } from "node:module";
2
3
  import { definePlugin, defineRule } from "@oxlint/plugins";
3
4
  import fs from "node:fs";
5
+ import path from "node:path";
4
6
  //#region src/plugin-option-guards.ts
5
7
  function optionField(value) {
6
8
  return value === void 0 || value === "always" || value === "never" || value === "any";
@@ -24,13 +26,18 @@ function getRuleOptions(ruleName, options) {
24
26
  switch (ruleName) {
25
27
  case "vue/component-name-in-template-casing":
26
28
  if (isComponentNameInTemplateCasingOption(firstOption)) return { componentNameInTemplateCasing: firstOption };
29
+ if (isRecord(firstOption)) return cliRuleOptions(ruleName, firstOption);
27
30
  break;
28
31
  case "script/custom-event-name-casing":
29
32
  if (isCustomEventNameCasingOption(firstOption)) return { customEventNameCasing: firstOption };
33
+ if (isRecord(firstOption)) return cliRuleOptions(ruleName, firstOption);
30
34
  break;
31
35
  case "vue/no-mutating-props":
32
36
  if (isNoMutatingPropsOption(firstOption)) return { noMutatingProps: firstOption };
33
37
  break;
38
+ case "script/define-macros-order":
39
+ if (isDefineMacrosOrderOption(firstOption)) return { defineMacrosOrder: firstOption };
40
+ break;
34
41
  case "vue/sfc-element-order":
35
42
  if (isSfcElementOrderOption(firstOption)) return { sfcElementOrder: firstOption };
36
43
  break;
@@ -43,8 +50,27 @@ function getRuleOptions(ruleName, options) {
43
50
  case "vue/attribute-hyphenation":
44
51
  if (isHyphenationStyle(firstOption)) return { attributeHyphenation: firstOption };
45
52
  break;
53
+ case "script/define-props-destructuring":
54
+ case "html/no-empty-palpable-content":
55
+ case "type/strict-boolean-expressions":
56
+ case "script/no-restricted-globals":
57
+ case "script/no-restricted-members":
58
+ case "vue/require-component-registration":
59
+ case "vue/valid-v-on":
60
+ case "vue/valid-v-slot":
61
+ case "musea/prefer-design-tokens":
62
+ if (isRecord(firstOption)) return cliRuleOptions(ruleName, firstOption);
63
+ break;
46
64
  }
47
65
  }
66
+ function isDefineMacrosOrderOption(value) {
67
+ if (!isRecord(value) || !hasOnlyKeys(value, ["order"])) return false;
68
+ const order = value.order;
69
+ return order === void 0 || Array.isArray(order) && order.every((name, index) => isString(name) && name.length > 0 && order.indexOf(name) === index);
70
+ }
71
+ function cliRuleOptions(ruleName, option) {
72
+ return { ruleOptions: { [ruleName]: structuredClone(option) } };
73
+ }
48
74
  function isComponentNameInTemplateCasingOption(value) {
49
75
  return value === "PascalCase" || value === "kebab-case";
50
76
  }
@@ -110,7 +136,7 @@ function parseRuleSelection(rules) {
110
136
  function createRuleSelection(optionsByRule) {
111
137
  const names = [...optionsByRule.keys()].sort();
112
138
  const options = {};
113
- for (const name of names) Object.assign(options, optionsByRule.get(name));
139
+ for (const name of names) mergeRuleOptions(options, optionsByRule.get(name));
114
140
  return {
115
141
  names,
116
142
  options,
@@ -118,6 +144,15 @@ function createRuleSelection(optionsByRule) {
118
144
  cacheKey: JSON.stringify([names, ruleOptionsKey(options)])
119
145
  };
120
146
  }
147
+ function mergeRuleOptions(target, source) {
148
+ if (!source) return;
149
+ const { ruleOptions, ...direct } = source;
150
+ Object.assign(target, direct);
151
+ if (ruleOptions) target.ruleOptions = {
152
+ ...target.ruleOptions,
153
+ ...ruleOptions
154
+ };
155
+ }
121
156
  function normalizeRuleName(name) {
122
157
  return name.startsWith("vize/") ? name.slice(5) : name;
123
158
  }
@@ -190,8 +225,7 @@ function getActivePreset(settings) {
190
225
  function isIncrementalPreset(settings) {
191
226
  return getActivePreset(settings) === "incremental";
192
227
  }
193
- function getCacheKey(filename, settings) {
194
- const selection = parseRuleSelection(settings.rules);
228
+ function getCacheKey(filename, settings, selection = parseRuleSelection(settings.rules)) {
195
229
  return JSON.stringify([
196
230
  filename,
197
231
  settings.locale ?? "",
@@ -263,7 +297,10 @@ if (import.meta.vitest) {
263
297
  }
264
298
  //#endregion
265
299
  //#region src/binding.ts
300
+ const VUE_ROUTER_COMPONENTS = ["RouterLink", "RouterView"];
301
+ const COMPONENT_REGISTRATION_RULE = "vue/require-component-registration";
266
302
  function lintPatina(source, filename, settings, enabledRules, ruleOptions) {
303
+ const { ruleOptions: cliRuleOptions, ...directRuleOptions } = withVueRouterComponentGlobals(filename, ruleOptions) ?? {};
267
304
  return loadBinding().lintPatinaSfc(source, {
268
305
  filename,
269
306
  locale: settings.locale,
@@ -272,9 +309,33 @@ function lintPatina(source, filename, settings, enabledRules, ruleOptions) {
272
309
  enabledRules: enabledRules ? [...enabledRules] : void 0,
273
310
  typeAware: settings.typeAware,
274
311
  corsaPath: settings.corsaPath,
275
- ...ruleOptions
312
+ ruleOptionsJson: cliRuleOptions ? JSON.stringify(cliRuleOptions) : void 0,
313
+ ...directRuleOptions
276
314
  });
277
315
  }
316
+ function withVueRouterComponentGlobals(filename, options) {
317
+ if (!isVueRouterResolvableFrom(filename)) return options;
318
+ const ruleOptions = options?.ruleOptions ?? {};
319
+ const registration = ruleOptions[COMPONENT_REGISTRATION_RULE] ?? {};
320
+ return {
321
+ ...options,
322
+ ruleOptions: {
323
+ ...ruleOptions,
324
+ [COMPONENT_REGISTRATION_RULE]: {
325
+ ...registration,
326
+ globals: [...new Set([...registration.globals ?? [], ...VUE_ROUTER_COMPONENTS])]
327
+ }
328
+ }
329
+ };
330
+ }
331
+ function isVueRouterResolvableFrom(filename) {
332
+ try {
333
+ createRequire(path.resolve(filename)).resolve("vue-router");
334
+ return true;
335
+ } catch {
336
+ return false;
337
+ }
338
+ }
278
339
  function getPatinaRules() {
279
340
  return loadBinding().getPatinaRules();
280
341
  }
@@ -355,7 +416,8 @@ let fileStateCacheClock = 0;
355
416
  function getFileState(context) {
356
417
  const settings = getVizeSettings(context);
357
418
  const physicalSource = fs.readFileSync(context.physicalFilename, "utf8");
358
- const cacheKey = getCacheKey(context.physicalFilename, settings);
419
+ const ruleSelection = parseRuleSelection(settings.rules);
420
+ const cacheKey = getCacheKey(context.physicalFilename, settings, ruleSelection);
359
421
  const cached = fileStateCache.get(cacheKey);
360
422
  if (cached && cached.state.revision.physicalSource === physicalSource) {
361
423
  validateWorkaroundAuthority(cached.state, context.physicalFilename);
@@ -381,7 +443,7 @@ function getFileState(context) {
381
443
  partialDiagnosticsByRule: /* @__PURE__ */ new Map(),
382
444
  requestedRules: /* @__PURE__ */ new Set(),
383
445
  reportedTypeAwareRuntimeDiagnostic: false,
384
- ruleSelection: parseRuleSelection(settings.rules),
446
+ ruleSelection,
385
447
  selectedDiagnosticsByRule: null
386
448
  };
387
449
  fileStateCache.set(cacheKey, {
@@ -461,25 +523,22 @@ function diagnosticsForRule(state, diagnosticsByRule, ruleName) {
461
523
  const programs = /* @__PURE__ */ new WeakMap();
462
524
  const results = /* @__PURE__ */ new WeakMap();
463
525
  function collectActiveRule(context, program, ruleName, options) {
464
- const state = getFileState(context);
465
526
  let collection = programs.get(program);
466
527
  if (!collection || collection.selection) {
467
528
  collection = {
468
- state,
529
+ state: getFileState(context),
530
+ physicalIdentity: physicalIdentity(context.physicalFilename),
531
+ runtimeSettings: getVizeSettings(context),
469
532
  optionsByRule: /* @__PURE__ */ new Map()
470
533
  };
471
534
  programs.set(program, collection);
472
535
  }
473
- if (collection.state !== state) {
474
- programs.delete(program);
475
- throw new Error("Vize source or configuration changed during rule collection");
476
- }
477
536
  collection.optionsByRule.set(ruleName, options === void 0 ? void 0 : structuredClone(options));
478
537
  }
479
538
  function getActiveRuleDiagnostics(context, program, ruleName) {
480
539
  const collection = programs.get(program);
481
540
  if (!collection?.optionsByRule.has(ruleName)) return void 0;
482
- if (getFileState(context) !== collection.state) {
541
+ if (!hasCurrentProgramInputs(context, collection)) {
483
542
  programs.delete(program);
484
543
  throw new Error("Vize source or configuration changed before rule execution");
485
544
  }
@@ -513,6 +572,24 @@ function getActiveRuleDiagnostics(context, program, ruleName) {
513
572
  diagnostics
514
573
  };
515
574
  }
575
+ function physicalIdentity(filename) {
576
+ const stat = fs.statSync(filename, { bigint: true });
577
+ return {
578
+ dev: stat.dev,
579
+ ino: stat.ino,
580
+ size: stat.size,
581
+ mtimeNs: stat.mtimeNs,
582
+ ctimeNs: stat.ctimeNs
583
+ };
584
+ }
585
+ function hasCurrentProgramInputs(context, collection) {
586
+ const currentIdentity = physicalIdentity(context.physicalFilename);
587
+ const expectedIdentity = collection.physicalIdentity;
588
+ if (currentIdentity.dev !== expectedIdentity.dev || currentIdentity.ino !== expectedIdentity.ino || currentIdentity.size !== expectedIdentity.size || currentIdentity.mtimeNs !== expectedIdentity.mtimeNs || currentIdentity.ctimeNs !== expectedIdentity.ctimeNs || context.sourceCode.text !== collection.state.extractedScript) return false;
589
+ const current = getVizeSettings(context);
590
+ const expected = collection.runtimeSettings;
591
+ return current.locale === expected.locale && current.helpLevel === expected.helpLevel && current.preset === expected.preset && current.typeAware === expected.typeAware && current.corsaPath === expected.corsaPath;
592
+ }
516
593
  //#endregion
517
594
  //#region src/format.ts
518
595
  const helpTextCache = /* @__PURE__ */ new Map();
@@ -652,16 +729,108 @@ function createPatinaRule(ruleMeta) {
652
729
  }
653
730
  function ruleOptionsSchema(ruleName) {
654
731
  switch (ruleName) {
655
- case "vue/component-name-in-template-casing": return [{ enum: ["PascalCase", "kebab-case"] }];
656
- case "script/custom-event-name-casing": return [{ enum: ["camelCase", "kebab-case"] }];
732
+ case "vue/component-name-in-template-casing": return [{ oneOf: [{ enum: ["PascalCase", "kebab-case"] }, objectSchema({
733
+ casing: { enum: ["PascalCase", "kebab-case"] },
734
+ registeredComponentsOnly: { type: "boolean" },
735
+ globals: stringArraySchema()
736
+ })] }];
737
+ case "script/custom-event-name-casing": return [{ oneOf: [{ enum: ["camelCase", "kebab-case"] }, objectSchema({ casing: { enum: ["camelCase", "kebab-case"] } })] }];
738
+ case "script/define-props-destructuring": return [objectSchema({ destructure: { enum: [
739
+ "only-when-assigned",
740
+ "always",
741
+ "never"
742
+ ] } })];
743
+ case "html/no-empty-palpable-content": return [objectSchema({ contentDirectives: stringArraySchema() })];
744
+ case "type/strict-boolean-expressions": return [strictBooleanExpressionsSchema()];
745
+ case "script/no-restricted-globals": return [restrictedGlobalsSchema()];
746
+ case "script/no-restricted-members": return [restrictedMembersSchema()];
657
747
  case "vue/no-mutating-props": return [noMutatingPropsSchema()];
748
+ case "script/define-macros-order": return [defineMacrosOrderSchema()];
658
749
  case "vue/sfc-element-order": return [sfcElementOrderSchema()];
659
750
  case "vue/html-self-closing": return [htmlSelfClosingSchema()];
660
751
  case "vue/v-on-event-hyphenation":
661
752
  case "vue/attribute-hyphenation": return [{ enum: ["always", "never"] }];
753
+ case "vue/require-component-registration": return [objectSchema({ globals: stringArraySchema() })];
754
+ case "vue/valid-v-on": return [objectSchema({ modifiers: stringArraySchema() })];
755
+ case "vue/valid-v-slot": return [objectSchema({ allowModifiers: { type: "boolean" } })];
756
+ case "musea/prefer-design-tokens": return [designTokensSchema()];
662
757
  default: return [];
663
758
  }
664
759
  }
760
+ function defineMacrosOrderSchema() {
761
+ return objectSchema({ order: {
762
+ type: "array",
763
+ items: {
764
+ type: "string",
765
+ minLength: 1
766
+ },
767
+ uniqueItems: true
768
+ } });
769
+ }
770
+ function objectSchema(properties) {
771
+ return {
772
+ type: "object",
773
+ properties,
774
+ additionalProperties: false
775
+ };
776
+ }
777
+ function stringArraySchema() {
778
+ return {
779
+ type: "array",
780
+ items: { type: "string" }
781
+ };
782
+ }
783
+ function strictBooleanExpressionsSchema() {
784
+ const boolean = { type: "boolean" };
785
+ return objectSchema({
786
+ allowString: boolean,
787
+ allowNumber: boolean,
788
+ allowNullableObject: boolean,
789
+ allowNullableBoolean: boolean,
790
+ allowNullableString: boolean,
791
+ allowNullableNumber: boolean,
792
+ allowNullableEnum: boolean,
793
+ allowAny: boolean
794
+ });
795
+ }
796
+ function restrictedGlobalsSchema() {
797
+ return objectSchema({ globals: {
798
+ type: "array",
799
+ items: {
800
+ ...objectSchema({
801
+ name: { type: "string" },
802
+ message: { type: "string" }
803
+ }),
804
+ required: ["name"]
805
+ }
806
+ } });
807
+ }
808
+ function restrictedMembersSchema() {
809
+ return objectSchema({ members: {
810
+ type: "array",
811
+ items: {
812
+ ...objectSchema({
813
+ object: { type: "string" },
814
+ property: { type: "string" },
815
+ message: { type: "string" }
816
+ }),
817
+ required: ["object", "property"]
818
+ }
819
+ } });
820
+ }
821
+ function designTokensSchema() {
822
+ return objectSchema({ tokens: {
823
+ type: "array",
824
+ items: {
825
+ ...objectSchema({
826
+ path: { type: "string" },
827
+ value: { type: "string" },
828
+ tier: { type: "string" }
829
+ }),
830
+ required: ["path", "value"]
831
+ }
832
+ } });
833
+ }
665
834
  function noMutatingPropsSchema() {
666
835
  return {
667
836
  type: "object",
@@ -0,0 +1,120 @@
1
+ //#region src/model.d.ts
2
+ type HelpLevel = "none" | "short" | "full";
3
+ type PatinaPreset = "general-recommended" | "essential" | "ecosystem" | "incremental" | "opinionated" | "nuxt";
4
+ interface PatinaSettings {
5
+ locale?: string;
6
+ helpLevel?: HelpLevel;
7
+ preset?: PatinaPreset;
8
+ typeAware?: boolean;
9
+ corsaPath?: string;
10
+ /** Rules to evaluate together. Oxlint's own rules still control reporting. */
11
+ rules?: readonly string[] | Record<string, unknown>;
12
+ }
13
+ interface VizeRuleOptions {
14
+ "script/define-props-destructuring"?: {
15
+ destructure?: "only-when-assigned" | "always" | "never";
16
+ };
17
+ "html/no-empty-palpable-content"?: {
18
+ contentDirectives?: string[];
19
+ };
20
+ "type/strict-boolean-expressions"?: {
21
+ allowString?: boolean;
22
+ allowNumber?: boolean;
23
+ allowNullableObject?: boolean;
24
+ allowNullableBoolean?: boolean;
25
+ allowNullableString?: boolean;
26
+ allowNullableNumber?: boolean;
27
+ allowNullableEnum?: boolean;
28
+ allowAny?: boolean;
29
+ };
30
+ "script/no-restricted-globals"?: {
31
+ globals?: Array<{
32
+ name: string;
33
+ message?: string;
34
+ }>;
35
+ };
36
+ "script/no-restricted-members"?: {
37
+ members?: Array<{
38
+ object: string;
39
+ property: string;
40
+ message?: string;
41
+ }>;
42
+ };
43
+ "vue/component-name-in-template-casing"?: {
44
+ casing?: ComponentNameInTemplateCasingOption;
45
+ registeredComponentsOnly?: boolean;
46
+ globals?: string[];
47
+ };
48
+ "script/custom-event-name-casing"?: {
49
+ casing?: CustomEventNameCasingOption;
50
+ };
51
+ "vue/no-mutating-props"?: NoMutatingPropsOption;
52
+ "vue/require-component-registration"?: {
53
+ globals?: string[];
54
+ };
55
+ "vue/sfc-element-order"?: SfcElementOrderOption;
56
+ "vue/html-self-closing"?: HtmlSelfClosingOption;
57
+ "vue/v-on-event-hyphenation"?: HyphenationStyle;
58
+ "vue/attribute-hyphenation"?: HyphenationStyle;
59
+ "vue/valid-v-on"?: {
60
+ modifiers?: string[];
61
+ };
62
+ "vue/valid-v-slot"?: {
63
+ allowModifiers?: boolean;
64
+ };
65
+ "musea/prefer-design-tokens"?: {
66
+ tokens?: Array<{
67
+ path: string;
68
+ value: string;
69
+ tier?: string;
70
+ }>;
71
+ };
72
+ }
73
+ type ComponentNameInTemplateCasingOption = "PascalCase" | "kebab-case";
74
+ type CustomEventNameCasingOption = "camelCase" | "kebab-case";
75
+ interface NoMutatingPropsOption {
76
+ shallowOnly?: boolean;
77
+ }
78
+ type SfcElementOrderGroup = string | string[];
79
+ interface SfcElementOrderOption {
80
+ order?: SfcElementOrderGroup[];
81
+ }
82
+ type HtmlSelfClosingStyle = "always" | "never" | "any";
83
+ interface HtmlSelfClosingOption {
84
+ html?: {
85
+ void?: HtmlSelfClosingStyle;
86
+ normal?: HtmlSelfClosingStyle;
87
+ component?: HtmlSelfClosingStyle;
88
+ };
89
+ svg?: HtmlSelfClosingStyle;
90
+ math?: HtmlSelfClosingStyle;
91
+ }
92
+ type HyphenationStyle = "always" | "never";
93
+ //#endregion
94
+ //#region src/configs.d.ts
95
+ type OxlintRuleSeverity = "error" | "warn" | "off";
96
+ type OxlintRuleEntry = OxlintRuleSeverity | [OxlintRuleSeverity, ...unknown[]];
97
+ type OxlintRuleConfig = Record<string, OxlintRuleEntry>;
98
+ type VizeRuleConfigPreset = Exclude<PatinaPreset, "incremental"> | "happy-path" | "all";
99
+ type VizeRuleConfigPresetInput = VizeRuleConfigPreset | readonly VizeRuleConfigPreset[];
100
+ interface VizeRuleConfigOptions {
101
+ includeTypeAware?: boolean;
102
+ preset?: VizeRuleConfigPresetInput;
103
+ presets?: readonly VizeRuleConfigPreset[];
104
+ }
105
+ declare function createVizeRuleConfig(options?: VizeRuleConfigOptions): OxlintRuleConfig;
106
+ declare const configs: {
107
+ readonly all: OxlintRuleConfig;
108
+ readonly ecosystem: OxlintRuleConfig;
109
+ readonly ecosystemWithTypeAware: OxlintRuleConfig;
110
+ readonly essential: OxlintRuleConfig;
111
+ readonly happyPath: OxlintRuleConfig;
112
+ readonly happyPathWithTypeAware: OxlintRuleConfig;
113
+ readonly nuxt: OxlintRuleConfig;
114
+ readonly opinionated: OxlintRuleConfig;
115
+ readonly opinionatedWithTypeAware: OxlintRuleConfig;
116
+ readonly recommended: OxlintRuleConfig;
117
+ readonly recommendedWithTypeAware: OxlintRuleConfig;
118
+ };
119
+ //#endregion
120
+ export { VizeRuleConfigPreset as a, createVizeRuleConfig as c, VizeRuleOptions as d, VizeRuleConfigOptions as i, PatinaPreset as l, OxlintRuleEntry as n, VizeRuleConfigPresetInput as o, OxlintRuleSeverity as r, configs as s, OxlintRuleConfig as t, PatinaSettings as u };
package/dist/eslint.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { c as createVizeRuleConfig, s as configs } from "./configs-BuOTHAnm.mjs";
1
+ import { c as createVizeRuleConfig, s as configs } from "./configs-U-ykt2bi.mjs";
2
2
 
3
3
  //#region src/eslint.d.ts
4
4
  /** ESLint rules over the complete source supplied by the configured parser. */
package/dist/eslint.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { a as getPatinaRules, c as isTypeAwareRuleName, d as getRuleOptions, i as formatPatinaMessage, l as createRuleSelection, n as createVizeRuleConfig, o as getActivePreset, r as plugin_default, s as getVizeSettings, t as configs } from "./configs-CcanGVPM.mjs";
2
- import { d as isPatinaFile, m as loadBinding } from "./workaround-FRBXv1sV.mjs";
1
+ import { a as getPatinaRules, c as isTypeAwareRuleName, d as getRuleOptions, i as formatPatinaMessage, l as createRuleSelection, n as createVizeRuleConfig, o as getActivePreset, r as plugin_default, s as getVizeSettings, t as configs } from "./configs-BjsIAx6F.mjs";
2
+ import { d as isPatinaFile, m as loadBinding } from "./workaround-Byh3ja-i.mjs";
3
3
  import { definePlugin, defineRule, eslintCompatPlugin } from "@oxlint/plugins";
4
4
  //#region src/eslint-source.ts
5
5
  /** Native UTF-8 text cannot preserve an unpaired UTF-16 surrogate. */
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as VizeRuleConfigPreset, c as createVizeRuleConfig, i as VizeRuleConfigOptions, l as PatinaPreset, n as OxlintRuleEntry, o as VizeRuleConfigPresetInput, r as OxlintRuleSeverity, s as configs, t as OxlintRuleConfig, u as PatinaSettings } from "./configs-BuOTHAnm.mjs";
1
+ import { a as VizeRuleConfigPreset, c as createVizeRuleConfig, d as VizeRuleOptions, i as VizeRuleConfigOptions, l as PatinaPreset, n as OxlintRuleEntry, o as VizeRuleConfigPresetInput, r as OxlintRuleSeverity, s as configs, t as OxlintRuleConfig, u as PatinaSettings } from "./configs-U-ykt2bi.mjs";
2
2
 
3
3
  //#region src/plugin.d.ts
4
4
  declare const _default: import("@oxlint/plugins").Plugin;
@@ -55,6 +55,11 @@ interface VizeLintConfigOptions {
55
55
  * bridge registers and, for a single gated preset, against the resolved preset.
56
56
  */
57
57
  rules?: OxlintRuleConfig;
58
+ /**
59
+ * CLI-compatible `vue.linter.ruleOptions`. Options are attached to rules
60
+ * already enabled by a preset or by `rules`; options never enable a rule.
61
+ */
62
+ ruleOptions?: VizeRuleOptions;
58
63
  /**
59
64
  * Patina runtime settings forwarded through `settings.vize`. `preset` and
60
65
  * `rules` are derived from the selected presets and final rule map,
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as getPatinaRules, n as createVizeRuleConfig, r as plugin_default, t as configs, u as selectVizeRuleConfig } from "./configs-CcanGVPM.mjs";
1
+ import { a as getPatinaRules, n as createVizeRuleConfig, r as plugin_default, t as configs, u as selectVizeRuleConfig } from "./configs-BjsIAx6F.mjs";
2
2
  //#region src/vite-plus.ts
3
3
  /**
4
4
  * Bare specifier Oxlint uses to load this bridge as a JS plugin.
@@ -51,10 +51,10 @@ function buildVizeLintConfig(options, buildOptions) {
51
51
  const runtimePreset = buildOptions.forceIncrementalRuntime ? "incremental" : toRuntimePreset(presets);
52
52
  const extraRules = options.rules ?? {};
53
53
  assertUsableVizeRules(extraRules, presets, runtimePreset);
54
- const rules = {
54
+ const rules = applyRuleOptions({
55
55
  ...createPresetRules(presets, options.includeTypeAware),
56
56
  ...extraRules
57
- };
57
+ }, options.ruleOptions);
58
58
  return {
59
59
  jsPlugins: [VIZE_JS_PLUGIN_SPECIFIER],
60
60
  plugins: [...new Set(["vue", ...options.plugins ?? []])],
@@ -66,6 +66,17 @@ function buildVizeLintConfig(options, buildOptions) {
66
66
  } }
67
67
  };
68
68
  }
69
+ function applyRuleOptions(rules, ruleOptions) {
70
+ if (!ruleOptions) return rules;
71
+ const resolved = { ...rules };
72
+ for (const [name, option] of Object.entries(ruleOptions)) {
73
+ const id = `${VIZE_RULE_PREFIX}${name}`;
74
+ const entry = resolved[id];
75
+ if (entry === void 0 || entry === "off") continue;
76
+ resolved[id] = [Array.isArray(entry) ? entry[0] : entry, option];
77
+ }
78
+ return resolved;
79
+ }
69
80
  function createPresetRules(presets, includeTypeAware) {
70
81
  const ruleConfigPresets = presets.filter(isRuleConfigPreset);
71
82
  if (ruleConfigPresets.length === 0) return {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oxlint-plugin-vize",
3
- "version": "0.501.0",
3
+ "version": "0.503.0",
4
4
  "description": "Oxlint JS plugin bridge for Vize Patina",
5
5
  "keywords": [
6
6
  "lint",
@@ -48,21 +48,21 @@
48
48
  "devDependencies": {
49
49
  "@tsdown/css": "0.22.14",
50
50
  "@types/node": "25.9.2",
51
- "@vizejs/native": "0.501.0",
51
+ "@vizejs/native": "0.503.0",
52
52
  "tsdown": "0.22.14",
53
53
  "typescript": "6.0.3",
54
54
  "vite": "npm:@voidzero-dev/vite-plus-core@0.1.24",
55
55
  "vite-plus": "0.1.24"
56
56
  },
57
57
  "optionalDependencies": {
58
- "@vizejs/native-darwin-arm64": "0.501.0",
59
- "@vizejs/native-darwin-x64": "0.501.0",
60
- "@vizejs/native-linux-arm64-gnu": "0.501.0",
61
- "@vizejs/native-linux-arm64-musl": "0.501.0",
62
- "@vizejs/native-linux-x64-gnu": "0.501.0",
63
- "@vizejs/native-linux-x64-musl": "0.501.0",
64
- "@vizejs/native-win32-arm64-msvc": "0.501.0",
65
- "@vizejs/native-win32-x64-msvc": "0.501.0"
58
+ "@vizejs/native-darwin-arm64": "0.503.0",
59
+ "@vizejs/native-darwin-x64": "0.503.0",
60
+ "@vizejs/native-linux-arm64-gnu": "0.503.0",
61
+ "@vizejs/native-linux-arm64-musl": "0.503.0",
62
+ "@vizejs/native-linux-x64-gnu": "0.503.0",
63
+ "@vizejs/native-linux-x64-musl": "0.503.0",
64
+ "@vizejs/native-win32-arm64-msvc": "0.503.0",
65
+ "@vizejs/native-win32-x64-msvc": "0.503.0"
66
66
  },
67
67
  "engines": {
68
68
  "node": "^22 || >= 24"
@@ -75,7 +75,7 @@
75
75
  },
76
76
  "scripts": {
77
77
  "build": "vp pack",
78
- "test": "vp pack && vp test run src/file-state.test.ts src/batched-rules.test.ts src/script-safe-source.test.ts src/active-rule-collection.test.ts && node src/test.ts && node src/script-location.test.ts && node src/casing-options.test.ts && node src/template-style-fixes.test.mjs && node src/html-binding.test.mjs && node --test src/eslint-source.test.ts && node src/eslint-acceptance.test.mjs",
78
+ "test": "vp pack && vp test run src/file-state.test.ts src/batched-rules.test.ts src/script-safe-source.test.ts src/active-rule-collection.test.ts && node src/test.ts && node src/script-location.test.ts && node src/casing-options.test.ts && node src/router-globals.test.ts && node src/template-style-fixes.test.mjs && node src/html-binding.test.mjs && node --test src/eslint-source.test.ts && node src/eslint-acceptance.test.mjs",
79
79
  "check": "vp check src vite.config.ts",
80
80
  "check:fix": "vp check --fix src vite.config.ts",
81
81
  "fmt": "vp fmt --write src vite.config.ts"
@@ -1,40 +0,0 @@
1
- //#region src/model.d.ts
2
- type HelpLevel = "none" | "short" | "full";
3
- type PatinaPreset = "general-recommended" | "essential" | "ecosystem" | "incremental" | "opinionated" | "nuxt";
4
- interface PatinaSettings {
5
- locale?: string;
6
- helpLevel?: HelpLevel;
7
- preset?: PatinaPreset;
8
- typeAware?: boolean;
9
- corsaPath?: string;
10
- /** Rules to evaluate together. Oxlint's own rules still control reporting. */
11
- rules?: readonly string[] | Record<string, unknown>;
12
- }
13
- //#endregion
14
- //#region src/configs.d.ts
15
- type OxlintRuleSeverity = "error" | "warn" | "off";
16
- type OxlintRuleEntry = OxlintRuleSeverity | [OxlintRuleSeverity, ...unknown[]];
17
- type OxlintRuleConfig = Record<string, OxlintRuleEntry>;
18
- type VizeRuleConfigPreset = Exclude<PatinaPreset, "incremental"> | "happy-path" | "all";
19
- type VizeRuleConfigPresetInput = VizeRuleConfigPreset | readonly VizeRuleConfigPreset[];
20
- interface VizeRuleConfigOptions {
21
- includeTypeAware?: boolean;
22
- preset?: VizeRuleConfigPresetInput;
23
- presets?: readonly VizeRuleConfigPreset[];
24
- }
25
- declare function createVizeRuleConfig(options?: VizeRuleConfigOptions): OxlintRuleConfig;
26
- declare const configs: {
27
- readonly all: OxlintRuleConfig;
28
- readonly ecosystem: OxlintRuleConfig;
29
- readonly ecosystemWithTypeAware: OxlintRuleConfig;
30
- readonly essential: OxlintRuleConfig;
31
- readonly happyPath: OxlintRuleConfig;
32
- readonly happyPathWithTypeAware: OxlintRuleConfig;
33
- readonly nuxt: OxlintRuleConfig;
34
- readonly opinionated: OxlintRuleConfig;
35
- readonly opinionatedWithTypeAware: OxlintRuleConfig;
36
- readonly recommended: OxlintRuleConfig;
37
- readonly recommendedWithTypeAware: OxlintRuleConfig;
38
- };
39
- //#endregion
40
- export { VizeRuleConfigPreset as a, createVizeRuleConfig as c, VizeRuleConfigOptions as i, PatinaPreset as l, OxlintRuleEntry as n, VizeRuleConfigPresetInput as o, OxlintRuleSeverity as r, configs as s, OxlintRuleConfig as t, PatinaSettings as u };
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
- import { spawnSync } from "node:child_process";
3
- import path from "node:path";
4
2
  import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { spawnSync } from "node:child_process";
5
5
  import { isUtf8 } from "node:buffer";
6
6
  import { createHash } from "node:crypto";
7
7
  //#region src/native.ts