@rslint/core 0.6.4 → 0.7.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.
@@ -1,10 +1,10 @@
1
1
  import { Worker } from "node:worker_threads";
2
2
  import { fileURLToPath, pathToFileURL } from "node:url";
3
3
  import { StringDecoder } from "node:string_decoder";
4
- import { createRequire } from "node:module";
4
+ import node_path from "node:path";
5
+ import node_module, { createRequire } from "node:module";
5
6
  import { readFileSync } from "node:fs";
6
7
  import { execSync } from "node:child_process";
7
- import node_path from "node:path";
8
8
  import { __webpack_require__ } from "./612.js";
9
9
  __webpack_require__.add({
10
10
  "../../node_modules/.pnpm/esrecurse@4.3.0/node_modules/esrecurse/esrecurse.js" (__unused_rspack_module, exports, __webpack_require__) {
@@ -20396,6 +20396,34 @@ class CancelFlagPool {
20396
20396
  let testWorkerEntry;
20397
20397
  const resolveWorkerFile = ()=>testWorkerEntry ?? fileURLToPath(new URL('./lint-worker.js', import.meta.url));
20398
20398
  const WORKER_EXIT_GRACE_MS = 5000;
20399
+ let nodeCompileCacheDir;
20400
+ let nodeCompileCacheDirResolved = false;
20401
+ function getNodeCompileCacheDir() {
20402
+ if (nodeCompileCacheDirResolved) return nodeCompileCacheDir;
20403
+ nodeCompileCacheDirResolved = true;
20404
+ if (process.env.NODE_DISABLE_COMPILE_CACHE) return;
20405
+ if (process.env.NODE_COMPILE_CACHE) {
20406
+ nodeCompileCacheDir = process.env.NODE_COMPILE_CACHE;
20407
+ return nodeCompileCacheDir;
20408
+ }
20409
+ const { enableCompileCache, getCompileCacheDir } = node_module;
20410
+ if (!enableCompileCache || !getCompileCacheDir) return;
20411
+ try {
20412
+ enableCompileCache();
20413
+ const cacheDirectory = getCompileCacheDir();
20414
+ nodeCompileCacheDir = cacheDirectory ? node_path.dirname(cacheDirectory) : void 0;
20415
+ return nodeCompileCacheDir;
20416
+ } catch {
20417
+ return;
20418
+ }
20419
+ }
20420
+ function workerEnvWithCompileCache() {
20421
+ const directory = getNodeCompileCacheDir();
20422
+ return directory ? {
20423
+ ...process.env,
20424
+ NODE_COMPILE_CACHE: directory
20425
+ } : void 0;
20426
+ }
20399
20427
  async function terminateWorker(worker) {
20400
20428
  worker.stdout?.destroy();
20401
20429
  worker.stderr?.destroy();
@@ -20590,6 +20618,7 @@ class WorkerPool {
20590
20618
  cancelSab: this.cancelPool.sharedBuffer,
20591
20619
  configs: this.opts.configs
20592
20620
  },
20621
+ env: workerEnvWithCompileCache(),
20593
20622
  stdout: true,
20594
20623
  stderr: true
20595
20624
  };
@@ -23140,9 +23169,11 @@ function scope_factory_analyze(ast, opts) {
23140
23169
  childVisitorKeys: VISITOR_KEYS
23141
23170
  });
23142
23171
  }
23172
+ const syntheticGlobals = new WeakSet();
23143
23173
  function ensureGlobal(gs, name, mode) {
23144
23174
  const existing = gs.set?.get(name);
23145
23175
  if (existing) {
23176
+ if (!syntheticGlobals.has(existing)) return existing;
23146
23177
  existing.writeable = 'writable' === mode;
23147
23178
  existing.eslintImplicitGlobalSetting = mode;
23148
23179
  return existing;
@@ -23156,6 +23187,7 @@ function ensureGlobal(gs, name, mode) {
23156
23187
  eslintImplicitGlobalSetting: mode,
23157
23188
  scope: gs
23158
23189
  };
23190
+ syntheticGlobals.add(v);
23159
23191
  gs.variables.push(v);
23160
23192
  gs.set?.set(name, v);
23161
23193
  return v;
@@ -23193,28 +23225,50 @@ function seedGlobals(scopeManager, globals) {
23193
23225
  const gs = sm.globalScope;
23194
23226
  if (!gs) return;
23195
23227
  if (!globals) return void resolveThroughReferences(gs);
23196
- for (const [name, mode] of Object.entries(globals)){
23197
- if ('off' === mode) {
23198
- if (gs.set?.has(name)) {
23199
- const v = gs.set.get(name);
23200
- if (Array.isArray(v.references) && v.references.length > 0) {
23201
- const through = gs.through ?? (gs.through = []);
23202
- for (const ref of v.references){
23203
- ref.resolved = null;
23204
- through.push(ref);
23228
+ for (const [name, access] of Object.entries(globals)){
23229
+ const mode = normalizeGlobalAccess(access);
23230
+ if (null != mode) {
23231
+ if ('off' === mode) {
23232
+ const v = gs.set?.get(name);
23233
+ if (v && syntheticGlobals.has(v)) {
23234
+ if (Array.isArray(v.references) && v.references.length > 0) {
23235
+ const through = gs.through ?? (gs.through = []);
23236
+ for (const ref of v.references){
23237
+ ref.resolved = null;
23238
+ through.push(ref);
23239
+ }
23240
+ v.references = [];
23205
23241
  }
23206
- v.references = [];
23242
+ const idx = gs.variables.indexOf(v);
23243
+ if (idx >= 0) gs.variables.splice(idx, 1);
23244
+ gs.set?.delete(name);
23207
23245
  }
23208
- const idx = gs.variables.indexOf(v);
23209
- if (idx >= 0) gs.variables.splice(idx, 1);
23210
- gs.set.delete(name);
23246
+ continue;
23211
23247
  }
23212
- continue;
23248
+ ensureGlobal(gs, name, mode);
23213
23249
  }
23214
- ensureGlobal(gs, name, mode);
23215
23250
  }
23216
23251
  resolveThroughReferences(gs);
23217
23252
  }
23253
+ function normalizeGlobalAccess(access) {
23254
+ switch(access){
23255
+ case true:
23256
+ case 'true':
23257
+ case 'writable':
23258
+ case 'writeable':
23259
+ return 'writable';
23260
+ case false:
23261
+ case null:
23262
+ case 'false':
23263
+ case 'readonly':
23264
+ case 'readable':
23265
+ return 'readonly';
23266
+ case 'off':
23267
+ return 'off';
23268
+ default:
23269
+ return;
23270
+ }
23271
+ }
23218
23272
  function esquery_esm_min_e(e, t) {
23219
23273
  (null == t || t > e.length) && (t = e.length);
23220
23274
  for(var r = 0, n = Array(t); r < t; r++)n[r] = e[r];
@@ -26652,7 +26706,6 @@ function unwrapPluginModule(mod) {
26652
26706
  }
26653
26707
  async function importConfigFile(configFilePath) {
26654
26708
  const ext = node_path.extname(configFilePath);
26655
- if ('.js' === ext || '.mjs' === ext || '.cjs' === ext) return import(pathToFileURL(configFilePath).href);
26656
26709
  if ('.ts' === ext || '.mts' === ext || '.cts' === ext) {
26657
26710
  const useNative = Boolean(process.features.typescript);
26658
26711
  if (useNative) return import(pathToFileURL(configFilePath).href);
@@ -26668,7 +26721,7 @@ async function importConfigFile(configFilePath) {
26668
26721
  const resolved = await jiti.import(configFilePath);
26669
26722
  return resolved;
26670
26723
  }
26671
- throw new Error(`Unsupported config file extension: ${ext}`);
26724
+ return import(pathToFileURL(configFilePath).href);
26672
26725
  }
26673
26726
  const MIN_NODE_MAJOR = 20;
26674
26727
  class PluginLoaderError extends Error {
@@ -26723,25 +26776,35 @@ async function loadPluginsFromConfigs(configs) {
26723
26776
  for(let i = 0; i < configs.length; i++){
26724
26777
  const dir = configs[i].configDirectory;
26725
26778
  const existing = out.get(dir);
26726
- out.set(dir, existing ? mergeLoadedPlugins(existing, loadedList[i], dir) : loadedList[i]);
26779
+ out.set(dir, existing ? mergeLoadedPlugins(existing, loadedList[i], dir, configs[i].configPath) : loadedList[i]);
26727
26780
  }
26728
26781
  return out;
26729
26782
  }
26730
- function mergeLoadedPlugins(a, b, dir) {
26783
+ function mergeLoadedPlugins(a, b, dir, configPath) {
26784
+ const plugins = [
26785
+ ...a.plugins
26786
+ ];
26787
+ const pluginsByPrefix = new Map(plugins.map((loaded)=>[
26788
+ loaded.prefix,
26789
+ loaded
26790
+ ]));
26791
+ for (const loaded of b.plugins){
26792
+ const existing = pluginsByPrefix.get(loaded.prefix);
26793
+ if (existing) {
26794
+ if (existing.plugin !== loaded.plugin) throw new PluginLoaderError(configPath, `Cannot redefine plugin "${loaded.prefix}" for routing key "${dir}".`);
26795
+ continue;
26796
+ }
26797
+ pluginsByPrefix.set(loaded.prefix, loaded);
26798
+ plugins.push(loaded);
26799
+ }
26731
26800
  const rules = new Map(a.rules);
26732
26801
  for (const [key, rule] of b.rules){
26733
26802
  const existing = rules.get(key);
26734
- if (void 0 !== existing && existing !== rule) {
26735
- process.stderr.write(`[rslint] plugin rule "${key}" is defined by more than one config in the same directory (${dir}); keeping the first. Deduplicate the rslint.config.* files for this directory.\n`);
26736
- continue;
26737
- }
26803
+ if (void 0 !== existing && existing !== rule) throw new PluginLoaderError(configPath, `[rslint] plugin rule "${key}" is defined by different plugin instances for the same config key (${dir})`);
26738
26804
  rules.set(key, rule);
26739
26805
  }
26740
26806
  return {
26741
- plugins: [
26742
- ...a.plugins,
26743
- ...b.plugins
26744
- ],
26807
+ plugins,
26745
26808
  rules
26746
26809
  };
26747
26810
  }
@@ -22572,9 +22572,11 @@ function scope_factory_analyze(ast, opts) {
22572
22572
  childVisitorKeys: VISITOR_KEYS
22573
22573
  });
22574
22574
  }
22575
+ const syntheticGlobals = new WeakSet();
22575
22576
  function ensureGlobal(gs, name, mode) {
22576
22577
  const existing = gs.set?.get(name);
22577
22578
  if (existing) {
22579
+ if (!syntheticGlobals.has(existing)) return existing;
22578
22580
  existing.writeable = 'writable' === mode;
22579
22581
  existing.eslintImplicitGlobalSetting = mode;
22580
22582
  return existing;
@@ -22588,6 +22590,7 @@ function ensureGlobal(gs, name, mode) {
22588
22590
  eslintImplicitGlobalSetting: mode,
22589
22591
  scope: gs
22590
22592
  };
22593
+ syntheticGlobals.add(v);
22591
22594
  gs.variables.push(v);
22592
22595
  gs.set?.set(name, v);
22593
22596
  return v;
@@ -22625,28 +22628,50 @@ function seedGlobals(scopeManager, globals) {
22625
22628
  const gs = sm.globalScope;
22626
22629
  if (!gs) return;
22627
22630
  if (!globals) return void resolveThroughReferences(gs);
22628
- for (const [name, mode] of Object.entries(globals)){
22629
- if ('off' === mode) {
22630
- if (gs.set?.has(name)) {
22631
- const v = gs.set.get(name);
22632
- if (Array.isArray(v.references) && v.references.length > 0) {
22633
- const through = gs.through ?? (gs.through = []);
22634
- for (const ref of v.references){
22635
- ref.resolved = null;
22636
- through.push(ref);
22631
+ for (const [name, access] of Object.entries(globals)){
22632
+ const mode = normalizeGlobalAccess(access);
22633
+ if (null != mode) {
22634
+ if ('off' === mode) {
22635
+ const v = gs.set?.get(name);
22636
+ if (v && syntheticGlobals.has(v)) {
22637
+ if (Array.isArray(v.references) && v.references.length > 0) {
22638
+ const through = gs.through ?? (gs.through = []);
22639
+ for (const ref of v.references){
22640
+ ref.resolved = null;
22641
+ through.push(ref);
22642
+ }
22643
+ v.references = [];
22637
22644
  }
22638
- v.references = [];
22645
+ const idx = gs.variables.indexOf(v);
22646
+ if (idx >= 0) gs.variables.splice(idx, 1);
22647
+ gs.set?.delete(name);
22639
22648
  }
22640
- const idx = gs.variables.indexOf(v);
22641
- if (idx >= 0) gs.variables.splice(idx, 1);
22642
- gs.set.delete(name);
22649
+ continue;
22643
22650
  }
22644
- continue;
22651
+ ensureGlobal(gs, name, mode);
22645
22652
  }
22646
- ensureGlobal(gs, name, mode);
22647
22653
  }
22648
22654
  resolveThroughReferences(gs);
22649
22655
  }
22656
+ function normalizeGlobalAccess(access) {
22657
+ switch(access){
22658
+ case true:
22659
+ case 'true':
22660
+ case 'writable':
22661
+ case 'writeable':
22662
+ return 'writable';
22663
+ case false:
22664
+ case null:
22665
+ case 'false':
22666
+ case 'readonly':
22667
+ case 'readable':
22668
+ return 'readonly';
22669
+ case 'off':
22670
+ return 'off';
22671
+ default:
22672
+ return;
22673
+ }
22674
+ }
22650
22675
  function esquery_esm_min_e(e, t) {
22651
22676
  (null == t || t > e.length) && (t = e.length);
22652
22677
  for(var r = 0, n = Array(t); r < t; r++)n[r] = e[r];
@@ -26084,7 +26109,6 @@ function unwrapPluginModule(mod) {
26084
26109
  }
26085
26110
  async function importConfigFile(configFilePath) {
26086
26111
  const ext = node_path.extname(configFilePath);
26087
- if ('.js' === ext || '.mjs' === ext || '.cjs' === ext) return import(pathToFileURL(configFilePath).href);
26088
26112
  if ('.ts' === ext || '.mts' === ext || '.cts' === ext) {
26089
26113
  const useNative = Boolean(process.features.typescript);
26090
26114
  if (useNative) return import(pathToFileURL(configFilePath).href);
@@ -26100,7 +26124,7 @@ async function importConfigFile(configFilePath) {
26100
26124
  const resolved = await jiti.import(configFilePath);
26101
26125
  return resolved;
26102
26126
  }
26103
- throw new Error(`Unsupported config file extension: ${ext}`);
26127
+ return import(pathToFileURL(configFilePath).href);
26104
26128
  }
26105
26129
  const MIN_NODE_MAJOR = 20;
26106
26130
  class PluginLoaderError extends Error {
@@ -26155,25 +26179,35 @@ async function loadPluginsFromConfigs(configs) {
26155
26179
  for(let i = 0; i < configs.length; i++){
26156
26180
  const dir = configs[i].configDirectory;
26157
26181
  const existing = out.get(dir);
26158
- out.set(dir, existing ? mergeLoadedPlugins(existing, loadedList[i], dir) : loadedList[i]);
26182
+ out.set(dir, existing ? mergeLoadedPlugins(existing, loadedList[i], dir, configs[i].configPath) : loadedList[i]);
26159
26183
  }
26160
26184
  return out;
26161
26185
  }
26162
- function mergeLoadedPlugins(a, b, dir) {
26186
+ function mergeLoadedPlugins(a, b, dir, configPath) {
26187
+ const plugins = [
26188
+ ...a.plugins
26189
+ ];
26190
+ const pluginsByPrefix = new Map(plugins.map((loaded)=>[
26191
+ loaded.prefix,
26192
+ loaded
26193
+ ]));
26194
+ for (const loaded of b.plugins){
26195
+ const existing = pluginsByPrefix.get(loaded.prefix);
26196
+ if (existing) {
26197
+ if (existing.plugin !== loaded.plugin) throw new PluginLoaderError(configPath, `Cannot redefine plugin "${loaded.prefix}" for routing key "${dir}".`);
26198
+ continue;
26199
+ }
26200
+ pluginsByPrefix.set(loaded.prefix, loaded);
26201
+ plugins.push(loaded);
26202
+ }
26163
26203
  const rules = new Map(a.rules);
26164
26204
  for (const [key, rule] of b.rules){
26165
26205
  const existing = rules.get(key);
26166
- if (void 0 !== existing && existing !== rule) {
26167
- process.stderr.write(`[rslint] plugin rule "${key}" is defined by more than one config in the same directory (${dir}); keeping the first. Deduplicate the rslint.config.* files for this directory.\n`);
26168
- continue;
26169
- }
26206
+ if (void 0 !== existing && existing !== rule) throw new PluginLoaderError(configPath, `[rslint] plugin rule "${key}" is defined by different plugin instances for the same config key (${dir})`);
26170
26207
  rules.set(key, rule);
26171
26208
  }
26172
26209
  return {
26173
- plugins: [
26174
- ...a.plugins,
26175
- ...b.plugins
26176
- ],
26210
+ plugins,
26177
26211
  rules
26178
26212
  };
26179
26213
  }
@@ -1,9 +1,3 @@
1
- /**
2
- * Types shared between the eslint-plugin host and its lint workers.
3
- *
4
- * Wire-format / IPC frame types (the Go↔Node frame contract) live in
5
- * `src/ipc/protocol.ts` — the single source the CLI host consumes.
6
- */
7
1
  /**
8
2
  * Per-config descriptor handed to the worker pool. Each worker imports
9
3
  * every descriptor's `configPath` once at init, then routes per-file
@@ -13,11 +7,27 @@
13
7
  * it as a Map key for per-file dispatch.
14
8
  */
15
9
  export declare interface ConfigDescriptor {
16
- /** Absolute filesystem path of the rslint config file (`rslint.config.{js,mjs,ts,mts}`). */
10
+ /** Absolute filesystem path of the selected JS/TS config file. */
17
11
  configPath: string;
18
- /** Absolute filesystem path of the directory holding the config file.
19
- * Matches the `ConfigKey` Go emits per file during plugin-lint dispatch. */
12
+ /** Go-authoritative absolute matching/routing directory. In explicit mode
13
+ * this can differ from the config file's parent and MUST byte-match the
14
+ * `ConfigKey` Go emits during plugin-lint dispatch. */
20
15
  configDirectory: string;
21
16
  }
22
17
 
18
+ /**
19
+ * Types shared between the eslint-plugin host and its lint workers.
20
+ *
21
+ * Wire-format / IPC frame types (the Go↔Node frame contract) live in
22
+ * `src/ipc/protocol.ts` — the single source the CLI host consumes.
23
+ */
24
+ /**
25
+ * ESLint-compatible access values carried to the plugin worker. This mirrors
26
+ * the public config authoring type without coupling the worker build project to
27
+ * the config-loader build project.
28
+ */
29
+ export declare type GlobalAccess = boolean | null | 'true' | 'false' | 'readonly' | 'readable' | 'writable' | 'writeable' | 'off';
30
+
31
+ export declare type GlobalsConfig = Record<string, GlobalAccess>;
32
+
23
33
  export { }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ /// <reference lib="esnext.disposable" />
2
+
1
3
  /**
2
4
  * Type-safe config helper. Returns the config array as-is (identity function).
3
5
  */
@@ -19,6 +21,11 @@ export declare interface ESLintPlugin {
19
21
  [key: string]: unknown;
20
22
  }
21
23
 
24
+ /**
25
+ * Access level for a declared global variable.
26
+ */
27
+ declare type GlobalAccess = boolean | null | 'true' | 'false' | 'readonly' | 'readable' | 'writable' | 'writeable' | 'off';
28
+
22
29
  /**
23
30
  * Define a global-ignores config entry.
24
31
  *
@@ -35,6 +42,14 @@ export declare interface ESLintPlugin {
35
42
  */
36
43
  export declare function globalIgnores(ignorePatterns: string[]): RslintConfigEntry;
37
44
 
45
+ /**
46
+ * Map of global variable name to its access level.
47
+ *
48
+ * @example
49
+ * globals: { myGlobal: 'readonly' }
50
+ */
51
+ declare type GlobalsConfig = Record<string, GlobalAccess>;
52
+
38
53
  export declare const importPlugin: {
39
54
  configs: {
40
55
  recommended: RslintConfigEntry;
@@ -70,6 +85,16 @@ declare type KnownPlugin = (typeof NATIVE_PLUGINS)[number];
70
85
  */
71
86
  declare interface LanguageOptions {
72
87
  parserOptions?: ParserOptions;
88
+ /**
89
+ * Global variables available in this file's scope, e.g. from a browser
90
+ * or Node.js runtime. `'readonly'`, `false`, and `null` allow reading;
91
+ * `'writable'` and `true` allow reassignment. Only the string `'off'`
92
+ * un-declares a global inherited from an earlier entry.
93
+ *
94
+ * @example
95
+ * globals: { myGlobal: 'readonly' }
96
+ */
97
+ globals?: GlobalsConfig;
73
98
  }
74
99
 
75
100
  export declare interface LintMessage {
@@ -194,20 +219,24 @@ export declare class Rslint {
194
219
  }
195
220
 
196
221
  /** Top-level rslint config: an array of entries. */
197
- declare type RslintConfig = RslintConfigEntry[];
222
+ export declare type RslintConfig = RslintConfigEntry[];
198
223
 
199
224
  /**
200
225
  * A single entry in an rslint config array. Multiple entries may target
201
226
  * different file globs and are merged at lint time.
202
227
  */
203
228
  export declare interface RslintConfigEntry {
229
+ /** Optional human-readable name for this config entry. */
230
+ name?: string;
204
231
  /**
205
- * Glob patterns for files this entry applies to.
232
+ * Glob selectors for files this entry applies to. Top-level selectors are
233
+ * ORed; strings inside one nested array are ANDed, matching ESLint flat
234
+ * config semantics.
206
235
  *
207
236
  * @example
208
237
  * files: ['src/**', 'tests/**']
209
238
  */
210
- files?: string[];
239
+ files?: Array<string | string[]>;
211
240
  /**
212
241
  * Glob patterns excluded from this entry.
213
242
  *
@@ -260,7 +289,7 @@ export declare interface RslintOptions {
260
289
  /** Extra config appended after the resolved/discovered config (ESLint's overrideConfig). */
261
290
  overrideConfig?: RslintConfigEntry | RslintConfigEntry[] | null;
262
291
  /**
263
- * `string` — use this config file (no discovery).
292
+ * `string` — use this JS/TS config module (no discovery).
264
293
  * `true` — use only `overrideConfig` (no file, no discovery).
265
294
  * `null`/absent — auto-discover the nearest config (ESLint v10 semantics; no `false`).
266
295
  */
@@ -268,15 +297,15 @@ export declare interface RslintOptions {
268
297
  /** Apply rule auto-fixes; results carry `output` (the JS side persists via outputFixes). */
269
298
  fix?: boolean;
270
299
  /**
271
- * In-memory file overlay (path → content) for fully in-memory linting (issue
272
- * #1106): put the `tsconfig.json` that `parserOptions.project` names plus any
300
+ * In-memory file overlay (path → content) for project inputs (issue #1106):
301
+ * put the `tsconfig.json` that `parserOptions.project` names plus any
273
302
  * dependency files here, then lint a buffer with `lintText`. Keys resolve
274
303
  * against `cwd` like a linted path (relative or absolute both work); a
275
304
  * same-path `lintText` code entry wins. Inside the tsconfig (`files`) and
276
305
  * `parserOptions.project`, use relative paths — the TS compiler resolves
277
306
  * those, and a bare POSIX-absolute path there has no drive letter on Windows,
278
- * so it won't match the overlay. rslint-only ESLint has no in-memory file
279
- * map.
307
+ * so it won't match the overlay. The overlay permits filesystem fallback and
308
+ * is not a sandbox. rslint-only — ESLint has no in-memory file map.
280
309
  *
281
310
  * Give the tsconfig explicit `files`, not a broad `include` glob: a glob is
282
311
  * expanded against the real filesystem and would scan `cwd` on disk.
@@ -285,29 +314,20 @@ export declare interface RslintOptions {
285
314
  }
286
315
 
287
316
  /**
288
- * Configuration value accepted for a single rule.
317
+ * Configuration value accepted for a single rule. Aligned with ESLint —
318
+ * rslint's own `{ level, options }` object form has been removed.
289
319
  *
290
320
  * - `RuleSeverity` — just toggle the rule.
291
321
  * - `[RuleSeverity, ...args]` — ESLint-style array form. Most rules take a
292
322
  * single options object (`[severity, { ... }]`); some accept positional
293
323
  * string/object args (`[severity, "always", { ... }]`).
294
- * - `{ level, options }` — object form supported by the loader.
295
- */
296
- declare type RuleEntry = RuleSeverity | readonly [RuleSeverity, ...any[]] | {
297
- level: RuleSeverity;
298
- options?: RuleOptions;
299
- };
300
-
301
- /**
302
- * Rule-specific options object. Each rule defines its own shape; until per-rule
303
- * types are generated, options are accepted as an open record.
304
324
  */
305
- declare type RuleOptions = Record<string, any>;
325
+ declare type RuleEntry = RuleSeverity | readonly [RuleSeverity, ...any[]];
306
326
 
307
327
  /**
308
328
  * Severity level for a rule.
309
329
  */
310
- declare type RuleSeverity = 'off' | 'warn' | 'error';
330
+ declare type RuleSeverity = 'off' | 'warn' | 'error' | 0 | 1 | 2;
311
331
 
312
332
  /**
313
333
  * Map of rule name → rule configuration. Rule names are `string` (no
@@ -316,6 +336,16 @@ declare type RuleSeverity = 'off' | 'warn' | 'error';
316
336
  */
317
337
  declare type RulesRecord = Record<string, RuleEntry>;
318
338
 
339
+ export declare function runCLI({ argv, }?: RunCLIOptions): Promise<void>;
340
+
341
+ export declare type RunCLIOptions = {
342
+ /**
343
+ * The command-line arguments to parse, matching the shape of Node.js `process.argv`
344
+ * @default process.argv
345
+ */
346
+ argv?: string[];
347
+ };
348
+
319
349
  export declare const ts: {
320
350
  configs: {
321
351
  base: RslintConfigEntry;