vize 0.48.0 → 0.52.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
@@ -1,46 +1,30 @@
1
1
  # Vize
2
2
 
3
- High-performance Vue.js toolchain in Rust.
3
+ The `vize` npm package provides:
4
4
 
5
- ## Installation
6
-
7
- ```bash
8
- # Install globally
9
- npm install -g vize
5
+ - shared config utilities (`defineConfig`, `loadConfig`)
6
+ - the native `vize lint` command
10
7
 
11
- # Or add it to a project
12
- npm install -D vize
8
+ For Vite integration, pair it with `@vizejs/vite-plugin`.
9
+ For the full Rust-native CLI (`build`, `fmt`, `check`, `lsp`, `ide`), install the Rust `vize`
10
+ binary with `cargo install vize`.
13
11
 
14
- # Or install from GitHub
15
- npm install -g github:ubugeeei/vize
16
- ```
17
-
18
- If you use `@vizejs/vite-plugin` and want one shared config for both the plugin and the `vize`
19
- CLI, install both packages in the project and put your config in `vize.config.*`.
20
-
21
- ## Usage
12
+ ## Installation
22
13
 
23
14
  ```bash
24
- vize [COMMAND] [OPTIONS]
15
+ pnpm add -D vize
25
16
  ```
26
17
 
27
- | Command | Description |
28
- | ------- | ------------------------------------- |
29
- | `build` | Compile Vue SFC files (default) |
30
- | `fmt` | Format Vue SFC files |
31
- | `lint` | Lint Vue SFC files |
32
- | `check` | Type check Vue SFC files |
33
- | `musea` | Start component gallery server |
34
- | `lsp` | Start Language Server Protocol server |
18
+ ## CLI
19
+
20
+ The npm CLI currently exposes `lint`:
35
21
 
36
22
  ```bash
37
- vize --help # Show help
38
- vize <command> --help # Show command-specific help
23
+ pnpm exec vize lint src
24
+ pnpm exec vize lint --preset opinionated --help-level short src
39
25
  ```
40
26
 
41
- ## Config
42
-
43
- `vize` looks for these files in the project root:
27
+ Shared config discovery is supported for the npm CLI:
44
28
 
45
29
  - `vize.config.ts`
46
30
  - `vize.config.js`
@@ -48,8 +32,6 @@ vize <command> --help # Show command-specific help
48
32
  - `vize.config.pkl`
49
33
  - `vize.config.json`
50
34
 
51
- TypeScript config:
52
-
53
35
  ```ts
54
36
  import { defineConfig } from "vize";
55
37
 
@@ -60,55 +42,29 @@ export default defineConfig({
60
42
  });
61
43
  ```
62
44
 
63
- PKL config:
64
-
65
- ```pkl
66
- amends "node_modules/vize/pkl/vize.pkl"
67
-
68
- linter {
69
- preset = "opinionated"
70
- }
71
- ```
45
+ Override config discovery with `--config`, or disable it with `--no-config`.
72
46
 
73
- JSON config with schema:
47
+ ## Programmatic Config Helpers
74
48
 
75
- ```json
76
- {
77
- "$schema": "./node_modules/vize/schemas/vize.config.schema.json",
78
- "linter": {
79
- "preset": "opinionated"
80
- }
81
- }
82
- ```
83
-
84
- The npm CLI currently applies shared config to the `lint` command. You can override discovery with
85
- `vize lint --config path/to/vize.config.ts` or skip config loading with `vize lint --no-config`.
49
+ ```ts
50
+ import { defineConfig, loadConfig } from "vize";
86
51
 
87
- ## Examples
52
+ export default defineConfig({
53
+ linter: {
54
+ preset: "happy-path",
55
+ },
56
+ });
88
57
 
89
- ```bash
90
- vize # Compile ./**/*.vue to ./dist
91
- vize build src/**/*.vue -o out # Custom input/output
92
- vize build --ssr # SSR mode
93
- vize build --profile # Parse, transform, codegen, and I/O profile
94
- vize fmt --check # Check formatting
95
- vize fmt --check --profile # Formatter timing profile
96
- vize lint --fix # Auto-fix lint issues
97
- vize lint --profile # Rule hook, Croquis, and type-aware timing profile
98
- vize check --strict # Strict type checking
99
- vize check --profile src # Virtual TS, Croquis, and Corsa timing profile
58
+ const config = await loadConfig(process.cwd());
100
59
  ```
101
60
 
102
- Profile output includes hot files and internal operation timings, so compiler, linter, typecheck,
103
- Croquis, and Corsa costs are visible in the same report style.
104
-
105
- ## Alternative Installation
61
+ ## Related Packages
106
62
 
107
- If npm installation fails, you can install via Cargo:
108
-
109
- ```bash
110
- cargo install vize
111
- ```
63
+ - `@vizejs/vite-plugin`
64
+ - `@vizejs/native`
65
+ - `@vizejs/wasm`
66
+ - `@vizejs/nuxt`
67
+ - `@vizejs/vite-plugin-musea`
112
68
 
113
69
  ## License
114
70
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vize",
3
- "version": "0.48.0",
3
+ "version": "0.52.0",
4
4
  "description": "Vize - High-performance Vue.js toolchain in Rust",
5
5
  "keywords": [
6
6
  "cli",
@@ -53,22 +53,23 @@
53
53
  "vite-plus": "latest"
54
54
  },
55
55
  "optionalDependencies": {
56
- "@vizejs/native-darwin-arm64": "0.48.0",
57
- "@vizejs/native-darwin-x64": "0.48.0",
58
- "@vizejs/native-linux-arm64-gnu": "0.48.0",
59
- "@vizejs/native-linux-arm64-musl": "0.48.0",
60
- "@vizejs/native-linux-x64-gnu": "0.48.0",
61
- "@vizejs/native-linux-x64-musl": "0.48.0",
62
- "@vizejs/native-win32-arm64-msvc": "0.48.0",
63
- "@vizejs/native-win32-x64-msvc": "0.48.0"
56
+ "@vizejs/native-darwin-arm64": "0.52.0",
57
+ "@vizejs/native-darwin-x64": "0.52.0",
58
+ "@vizejs/native-linux-arm64-gnu": "0.52.0",
59
+ "@vizejs/native-linux-arm64-musl": "0.52.0",
60
+ "@vizejs/native-linux-x64-gnu": "0.52.0",
61
+ "@vizejs/native-linux-x64-musl": "0.52.0",
62
+ "@vizejs/native-win32-arm64-msvc": "0.52.0",
63
+ "@vizejs/native-win32-x64-msvc": "0.52.0"
64
64
  },
65
65
  "engines": {
66
66
  "node": ">=18"
67
67
  },
68
68
  "scripts": {
69
- "build": "vp pack",
69
+ "build": "vp run generate:rule-types && vp pack",
70
70
  "check": "vp check src vite.config.ts",
71
71
  "check:fix": "vp check --fix src vite.config.ts",
72
- "fmt": "vp fmt --write src vite.config.ts"
72
+ "fmt": "vp fmt --write src vite.config.ts",
73
+ "generate:rule-types": "node --experimental-strip-types ../../scripts/generate-vize-rule-types.ts"
73
74
  }
74
75
  }
package/pkl/vize.pkl CHANGED
@@ -65,12 +65,26 @@ class FormatterConfig {
65
65
 
66
66
  class LspConfig {
67
67
  enabled: Boolean? = null
68
+ lint: Boolean? = null
69
+ /// Deprecated: use `lint`.
68
70
  diagnostics: Boolean? = null
71
+ typecheck: Boolean? = null
72
+ editor: Boolean? = null
69
73
  completion: Boolean? = null
70
74
  hover: Boolean? = null
71
75
  definition: Boolean? = null
76
+ references: Boolean? = null
77
+ documentSymbols: Boolean? = null
78
+ workspaceSymbols: Boolean? = null
72
79
  formatting: Boolean? = null
73
80
  codeActions: Boolean? = null
81
+ rename: Boolean? = null
82
+ codeLens: Boolean? = null
83
+ semanticTokens: Boolean? = null
84
+ documentLinks: Boolean? = null
85
+ foldingRanges: Boolean? = null
86
+ inlayHints: Boolean? = null
87
+ fileRename: Boolean? = null
74
88
  corsa: Boolean? = null
75
89
  }
76
90
 
@@ -210,8 +210,21 @@
210
210
  "enabled": {
211
211
  "type": "boolean"
212
212
  },
213
+ "lint": {
214
+ "type": "boolean",
215
+ "description": "Enable Vize linter diagnostics in the LSP. Defaults to false."
216
+ },
213
217
  "diagnostics": {
214
- "type": "boolean"
218
+ "type": "boolean",
219
+ "description": "Deprecated alias for lint. Defaults to false."
220
+ },
221
+ "typecheck": {
222
+ "type": "boolean",
223
+ "description": "Enable type checking diagnostics and type-aware LSP integration. Defaults to false."
224
+ },
225
+ "editor": {
226
+ "type": "boolean",
227
+ "description": "Enable the editor assistance bundle: completion, hover, navigation, symbols, rename, code lens, semantic tokens, links, folding, inlay hints, and file rename handling. Formatting remains separately opt-in."
215
228
  },
216
229
  "completion": {
217
230
  "type": "boolean"
@@ -222,12 +235,42 @@
222
235
  "definition": {
223
236
  "type": "boolean"
224
237
  },
238
+ "references": {
239
+ "type": "boolean"
240
+ },
241
+ "documentSymbols": {
242
+ "type": "boolean"
243
+ },
244
+ "workspaceSymbols": {
245
+ "type": "boolean"
246
+ },
225
247
  "formatting": {
226
248
  "type": "boolean"
227
249
  },
228
250
  "codeActions": {
229
251
  "type": "boolean"
230
252
  },
253
+ "rename": {
254
+ "type": "boolean"
255
+ },
256
+ "codeLens": {
257
+ "type": "boolean"
258
+ },
259
+ "semanticTokens": {
260
+ "type": "boolean"
261
+ },
262
+ "documentLinks": {
263
+ "type": "boolean"
264
+ },
265
+ "foldingRanges": {
266
+ "type": "boolean"
267
+ },
268
+ "inlayHints": {
269
+ "type": "boolean"
270
+ },
271
+ "fileRename": {
272
+ "type": "boolean"
273
+ },
231
274
  "corsa": {
232
275
  "type": "boolean"
233
276
  }
@@ -342,10 +385,7 @@
342
385
  "globalTypesConfig": {
343
386
  "type": "object",
344
387
  "additionalProperties": {
345
- "oneOf": [
346
- { "type": "string" },
347
- { "$ref": "#/$defs/globalTypeDeclaration" }
348
- ]
388
+ "oneOf": [{ "type": "string" }, { "$ref": "#/$defs/globalTypeDeclaration" }]
349
389
  }
350
390
  }
351
391
  }
package/src/cli.ts CHANGED
@@ -1,8 +1,12 @@
1
- import { createRequire } from "module";
2
- import { readFileSync } from "fs";
1
+ import { readFileSync } from "node:fs";
2
+ import { spawnSync } from "node:child_process";
3
+ import * as path from "node:path";
4
+ import { createRequire } from "node:module";
5
+ import { pathToFileURL } from "node:url";
3
6
  import { loadConfig } from "./config.js";
4
7
 
5
8
  const require = createRequire(import.meta.url);
9
+ const WORKSPACE_BINDING_PATH = "../../vize-native";
6
10
 
7
11
  // ============================================================================
8
12
  // Native binding loader (oxlint pattern)
@@ -73,14 +77,54 @@ interface NativeBinding {
73
77
  }
74
78
 
75
79
  function loadNative(): NativeBinding {
76
- const pkg = getBindingPackageName();
80
+ const attemptedPackages = getAttemptedPackages();
81
+ let lastError: unknown = null;
82
+
83
+ for (const packageName of attemptedPackages) {
84
+ try {
85
+ const binding = require(packageName) as Partial<NativeBinding>;
86
+ if (typeof binding.lint !== "function") {
87
+ throw new Error(`${packageName} does not expose the lint binding.`);
88
+ }
89
+ return binding as NativeBinding;
90
+ } catch (error) {
91
+ lastError = error;
92
+ }
93
+ }
94
+
95
+ console.error(`Failed to load native binding. Tried: ${attemptedPackages.join(", ")}`);
96
+ console.error("Try reinstalling: npm install vize");
97
+ throw lastError instanceof Error ? lastError : new Error("Failed to load native binding");
98
+ }
99
+
100
+ function getAttemptedPackages(): readonly string[] {
101
+ const platformBindingPackage = getBindingPackageName();
102
+ return shouldPreferWorkspaceBinding(resolveWorkspaceBindingPath())
103
+ ? [WORKSPACE_BINDING_PATH, platformBindingPackage]
104
+ : [platformBindingPackage, WORKSPACE_BINDING_PATH];
105
+ }
106
+
107
+ function resolveWorkspaceBindingPath(): string | null {
77
108
  try {
78
- return require(pkg);
79
- } catch (e) {
80
- console.error(`Failed to load native binding: ${pkg}`);
81
- console.error("Try reinstalling: npm install vize");
82
- throw e;
109
+ return require.resolve(WORKSPACE_BINDING_PATH);
110
+ } catch {
111
+ return null;
112
+ }
113
+ }
114
+
115
+ function shouldPreferWorkspaceBinding(resolvedPath: string | null): boolean {
116
+ const override = process.env.VIZE_PREFER_WORKSPACE_BINDING;
117
+ if (override === "1" || override === "true") {
118
+ return true;
119
+ }
120
+ if (override === "0" || override === "false") {
121
+ return false;
83
122
  }
123
+ if (resolvedPath == null) {
124
+ return false;
125
+ }
126
+
127
+ return resolvedPath.includes(`${path.sep}npm${path.sep}vize-native${path.sep}`);
84
128
  }
85
129
 
86
130
  // ============================================================================
@@ -115,6 +159,52 @@ interface ParsedLintCommand {
115
159
  sharedConfig: SharedConfigOptions;
116
160
  }
117
161
 
162
+ function printUsage(): void {
163
+ console.error("Usage: vize <command> [options]");
164
+ console.error("Commands: lint, musea");
165
+ }
166
+
167
+ function resolvePackageBinaryFromCwd(packageName: string, binName: string = packageName): string {
168
+ const cwdRequire = createRequire(pathToFileURL(path.join(process.cwd(), "package.json")).href);
169
+ const packageJsonPath = cwdRequire.resolve(`${packageName}/package.json`);
170
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")) as {
171
+ bin?: string | Record<string, string>;
172
+ };
173
+
174
+ const bin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.[binName];
175
+
176
+ if (!bin) {
177
+ throw new Error(`Could not resolve binary '${binName}' from package '${packageName}'`);
178
+ }
179
+
180
+ return path.resolve(path.dirname(packageJsonPath), bin);
181
+ }
182
+
183
+ function runMusea(args: string[]): void {
184
+ const isHelp = args.includes("--help") || args.includes("-h");
185
+ if (isHelp) {
186
+ console.error("Usage: vize musea [--build] [...vite options]");
187
+ console.error(" --build Run `vite build` instead of `vite dev`");
188
+ return;
189
+ }
190
+
191
+ const isBuild = args.includes("--build");
192
+ const viteArgs = args.filter((arg) => arg !== "--build");
193
+ const viteCommand = isBuild ? "build" : "dev";
194
+ const viteBin = resolvePackageBinaryFromCwd("vite");
195
+ const result = spawnSync(process.execPath, [viteBin, viteCommand, ...viteArgs], {
196
+ stdio: "inherit",
197
+ cwd: process.cwd(),
198
+ env: process.env,
199
+ });
200
+
201
+ if (result.error) {
202
+ throw result.error;
203
+ }
204
+
205
+ process.exit(result.status ?? 1);
206
+ }
207
+
118
208
  function parseLintCommand(args: string[]): ParsedLintCommand {
119
209
  const patterns: string[] = [];
120
210
  const options: LintOptions = {};
@@ -216,14 +306,14 @@ async function runLint(args: string[]): Promise<void> {
216
306
  // ============================================================================
217
307
 
218
308
  const NAPI_COMMANDS = new Set(["lint"]);
309
+ const JS_COMMANDS = new Set(["musea"]);
219
310
 
220
311
  async function main(): Promise<void> {
221
312
  const args = process.argv.slice(2);
222
313
  const command = args[0];
223
314
 
224
- if (!command) {
225
- console.error("Usage: vize <command> [options]");
226
- console.error("Commands: lint");
315
+ if (!command || command === "--help" || command === "-h") {
316
+ printUsage();
227
317
  process.exit(1);
228
318
  }
229
319
 
@@ -234,7 +324,15 @@ async function main(): Promise<void> {
234
324
  await runLint(commandArgs);
235
325
  break;
236
326
  }
327
+ } else if (JS_COMMANDS.has(command)) {
328
+ const commandArgs = args.slice(1);
329
+ switch (command) {
330
+ case "musea":
331
+ runMusea(commandArgs);
332
+ break;
333
+ }
237
334
  } else {
335
+ printUsage();
238
336
  console.error(`Unknown command: ${command}`);
239
337
  console.error(
240
338
  "For commands not yet available via NAPI, install from source: cargo install vize",
@@ -243,7 +341,35 @@ async function main(): Promise<void> {
243
341
  }
244
342
  }
245
343
 
246
- void main().catch((error) => {
247
- console.error(error instanceof Error ? error.message : String(error));
248
- process.exit(1);
249
- });
344
+ if (!import.meta.vitest) {
345
+ void main().catch((error) => {
346
+ console.error(error instanceof Error ? error.message : String(error));
347
+ process.exit(1);
348
+ });
349
+ }
350
+
351
+ if (import.meta.vitest) {
352
+ const { describe, expect, it } = import.meta.vitest;
353
+
354
+ describe("shouldPreferWorkspaceBinding", () => {
355
+ it("detects the local workspace native package", () => {
356
+ expect(
357
+ shouldPreferWorkspaceBinding(
358
+ `${path.sep}Users${path.sep}example${path.sep}repo${path.sep}npm${path.sep}vize-native${path.sep}index.js`,
359
+ ),
360
+ ).toBe(true);
361
+ });
362
+
363
+ it("ignores published platform packages", () => {
364
+ expect(
365
+ shouldPreferWorkspaceBinding(
366
+ `${path.sep}repo${path.sep}node_modules${path.sep}.pnpm${path.sep}@vizejs+native-darwin-arm64${path.sep}node_modules${path.sep}@vizejs${path.sep}native-darwin-arm64${path.sep}index.js`,
367
+ ),
368
+ ).toBe(false);
369
+ });
370
+
371
+ it("returns false when the fallback package cannot be resolved", () => {
372
+ expect(shouldPreferWorkspaceBinding(null)).toBe(false);
373
+ });
374
+ });
375
+ }
package/src/index.ts CHANGED
@@ -28,6 +28,8 @@ export type {
28
28
  LintPreset,
29
29
  RuleSeverity,
30
30
  RuleCategory,
31
+ LintRuleName,
32
+ LintRulesConfig,
31
33
  } from "./types/index.js";
32
34
 
33
35
  // Config utilities
@@ -8,6 +8,8 @@ export type {
8
8
  VizeConfig,
9
9
  } from "./core.js";
10
10
 
11
+ export type { LintRuleName, LintRulesConfig } from "./rules.js";
12
+
11
13
  export type { CompilerConfig, VitePluginConfig } from "./compiler.js";
12
14
 
13
15
  export type { LinterConfig, TypeCheckerConfig, FormatterConfig, LspConfig } from "./tools.js";
@@ -0,0 +1,121 @@
1
+ // This file is generated by scripts/generate-vize-rule-types.ts.
2
+ // Do not edit it by hand.
3
+
4
+ import type { RuleSeverity } from "./core.js";
5
+
6
+ export const LINT_RULE_NAMES = [
7
+ "a11y/alt-text",
8
+ "a11y/anchor-has-content",
9
+ "a11y/anchor-is-valid",
10
+ "a11y/aria-props",
11
+ "a11y/aria-role",
12
+ "a11y/aria-unsupported-elements",
13
+ "a11y/click-events-have-key-events",
14
+ "a11y/form-control-has-label",
15
+ "a11y/heading-has-content",
16
+ "a11y/heading-levels",
17
+ "a11y/iframe-has-title",
18
+ "a11y/img-alt",
19
+ "a11y/interactive-supports-focus",
20
+ "a11y/label-has-for",
21
+ "a11y/landmark-roles",
22
+ "a11y/media-has-caption",
23
+ "a11y/mouse-events-have-key-events",
24
+ "a11y/no-access-key",
25
+ "a11y/no-aria-hidden-on-focusable",
26
+ "a11y/no-autofocus",
27
+ "a11y/no-distracting-elements",
28
+ "a11y/no-i-for-icon",
29
+ "a11y/no-redundant-roles",
30
+ "a11y/no-refer-to-non-existent-id",
31
+ "a11y/no-role-presentation-on-focusable",
32
+ "a11y/no-static-element-interactions",
33
+ "a11y/placeholder-label-option",
34
+ "a11y/role-has-required-aria-props",
35
+ "a11y/tabindex-no-positive",
36
+ "a11y/use-list",
37
+ "html/deprecated-attr",
38
+ "html/deprecated-element",
39
+ "html/id-duplication",
40
+ "html/no-consecutive-br",
41
+ "html/no-duplicate-dt",
42
+ "html/no-empty-palpable-content",
43
+ "html/require-datetime",
44
+ "script/no-get-current-instance",
45
+ "script/no-next-tick",
46
+ "script/no-options-api",
47
+ "ssr/no-browser-globals-in-ssr",
48
+ "ssr/no-hydration-mismatch",
49
+ "type/no-floating-promises",
50
+ "type/no-unsafe-template-binding",
51
+ "type/require-typed-emits",
52
+ "type/require-typed-props",
53
+ "vapor/no-inline-template",
54
+ "vapor/no-suspense",
55
+ "vapor/no-vue-lifecycle-events",
56
+ "vapor/prefer-static-class",
57
+ "vapor/require-vapor-attribute",
58
+ "vue/attribute-hyphenation",
59
+ "vue/attribute-order",
60
+ "vue/component-definition-name-casing",
61
+ "vue/component-name-in-template-casing",
62
+ "vue/html-quotes",
63
+ "vue/html-self-closing",
64
+ "vue/multi-word-component-names",
65
+ "vue/mustache-interpolation-spacing",
66
+ "vue/no-boolean-attr-value",
67
+ "vue/no-child-content",
68
+ "vue/no-dupe-v-else-if",
69
+ "vue/no-duplicate-attributes",
70
+ "vue/no-inline-style",
71
+ "vue/no-lone-template",
72
+ "vue/no-multi-spaces",
73
+ "vue/no-mutating-props",
74
+ "vue/no-preprocessor-lang",
75
+ "vue/no-reserved-component-names",
76
+ "vue/no-script-non-standard-lang",
77
+ "vue/no-src-attribute",
78
+ "vue/no-template-key",
79
+ "vue/no-template-lang",
80
+ "vue/no-template-shadow",
81
+ "vue/no-textarea-mustache",
82
+ "vue/no-unsafe-url",
83
+ "vue/no-unused-components",
84
+ "vue/no-unused-properties",
85
+ "vue/no-unused-vars",
86
+ "vue/no-use-v-if-with-v-for",
87
+ "vue/no-useless-template-attributes",
88
+ "vue/no-v-html",
89
+ "vue/no-v-text-v-html-on-component",
90
+ "vue/permitted-contents",
91
+ "vue/prefer-props-shorthand",
92
+ "vue/prop-name-casing",
93
+ "vue/require-component-is",
94
+ "vue/require-component-registration",
95
+ "vue/require-scoped-style",
96
+ "vue/require-v-for-key",
97
+ "vue/scoped-event-names",
98
+ "vue/sfc-element-order",
99
+ "vue/single-style-block",
100
+ "vue/use-unique-element-ids",
101
+ "vue/use-v-on-exact",
102
+ "vue/v-bind-style",
103
+ "vue/v-on-style",
104
+ "vue/v-slot-style",
105
+ "vue/valid-attribute-name",
106
+ "vue/valid-v-bind",
107
+ "vue/valid-v-else",
108
+ "vue/valid-v-for",
109
+ "vue/valid-v-if",
110
+ "vue/valid-v-memo",
111
+ "vue/valid-v-model",
112
+ "vue/valid-v-on",
113
+ "vue/valid-v-show",
114
+ "vue/valid-v-slot",
115
+ "vue/warn-custom-block",
116
+ "vue/warn-custom-directive",
117
+ ] as const;
118
+
119
+ export type LintRuleName = (typeof LINT_RULE_NAMES)[number];
120
+
121
+ export type LintRulesConfig = Partial<Record<LintRuleName, RuleSeverity>>;