@useinsider/eslint-config 1.13.0-beta.6 → 1.13.0-beta.7

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
@@ -244,6 +244,7 @@ Every scope entry shape also accepts two common fields:
244
244
  | `strict` | `boolean \| string[]` | Applies the strict preset globally (`true`) or scoped to globs. |
245
245
  | `spellChecker` | `{ ignoredPaths?: string[]; customWordListFile?: string }` | Cross-cutting cspell overrides. |
246
246
  | `silenceRules` | `string[]` | Rule IDs to demote to `'warn'` across every block. |
247
+ | `configFiles` | `false \| string[]` | Emits a dedicated block for root-level configuration files (`*.config.*`, `eslint.config.*`) that disables `import-x/no-extraneous-dependencies` and `import-x/prefer-default-export`. **Defaults are applied automatically** — omit the key (or pass `[]`) to use the built-in defaults only, pass a `string[]` to layer your own globs on top, or pass `false` to opt out entirely. |
247
248
 
248
249
  A scope entry with per-entry globals — declare project-specific bindings
249
250
  without spreading the `useInsider` return into your own array:
@@ -0,0 +1,12 @@
1
+ import type { Linter } from 'eslint';
2
+ /**
3
+ * Default globs treated as "configuration files" — root-level `*.config.*`
4
+ * variants plus the canonical `eslint.config.*` flat-config filenames.
5
+ *
6
+ * These are intentionally conservative: only the top-level matches that the
7
+ * v1 `config` preset was overwhelmingly applied to. Project-specific paths
8
+ * (subdirectories, custom names) must be opted into by passing them via the
9
+ * `configFiles: string[]` knob.
10
+ */
11
+ export declare const DEFAULT_CONFIG_FILE_GLOBS: readonly string[];
12
+ export declare function buildConfigFilesBlocks(value: false | string[] | undefined): Linter.Config[];
package/dist/cli.cjs CHANGED
@@ -722,7 +722,8 @@ function freshConfig$1() {
722
722
  scopes: /* @__PURE__ */ new Map(),
723
723
  strictGlobs: [],
724
724
  strictWholeFile: false,
725
- spellChecker: { ignoredPaths: [] }
725
+ spellChecker: { ignoredPaths: [] },
726
+ configFiles: []
726
727
  };
727
728
  }
728
729
  function appendScope$1(config, scope, entry) {
@@ -762,6 +763,11 @@ function mapInsiderPreset(preset) {
762
763
  if (preset === "config") return "config";
763
764
  return presetToScope$1[preset] ?? null;
764
765
  }
766
+ function captureConfigPresetFiles$1(input, context) {
767
+ input.files.forEach((file) => {
768
+ if (!context.config.configFiles.includes(file)) context.config.configFiles.push(file);
769
+ });
770
+ }
765
771
  function emitInsiderScopes(presets, input, context) {
766
772
  let emitted = false;
767
773
  presets.forEach((preset) => {
@@ -774,7 +780,10 @@ function emitInsiderScopes(presets, input, context) {
774
780
  });
775
781
  return;
776
782
  }
777
- if (mapped === "config") return;
783
+ if (mapped === "config") {
784
+ captureConfigPresetFiles$1(input, context);
785
+ return;
786
+ }
778
787
  const entry = buildEntry$1({
779
788
  files: input.files,
780
789
  scope: mapped,
@@ -1307,17 +1316,34 @@ function parseV1Config(source, filePath) {
1307
1316
  //#endregion
1308
1317
  //#region src/cli/migrate/render.ts
1309
1318
  var indent$1 = " ";
1319
+ var MAX_LINE_LENGTH = 120;
1310
1320
  function quote$1(value) {
1311
1321
  return `'${value.replace(/'/g, "\\'")}'`;
1312
1322
  }
1313
- function formatStringArray$1(values) {
1323
+ function formatStringArrayInline(values) {
1314
1324
  return `[${values.map(quote$1).join(", ")}]`;
1315
1325
  }
1326
+ function formatStringArrayMultiline(values, baseIndent) {
1327
+ const childIndent = `${baseIndent}${indent$1}`;
1328
+ return [
1329
+ "[",
1330
+ ...values.map((value) => `${childIndent}${quote$1(value)},`),
1331
+ `${baseIndent}]`
1332
+ ].join("\n");
1333
+ }
1334
+ function renderStringArrayField(label, values, baseIndent) {
1335
+ const inline = `${baseIndent}${label}: ${formatStringArrayInline(values)},`;
1336
+ if (inline.length <= MAX_LINE_LENGTH) return inline;
1337
+ return `${baseIndent}${label}: ${formatStringArrayMultiline(values, baseIndent)},`;
1338
+ }
1316
1339
  function formatGlobalValue(value) {
1317
1340
  if (typeof value === "string") return quote$1(value);
1318
1341
  return String(value);
1319
1342
  }
1320
- function formatGlobalsObject(globals, baseIndent) {
1343
+ function formatGlobalsInline(globals) {
1344
+ return `{ ${Object.entries(globals).map(([key, value]) => `${key}: ${formatGlobalValue(value)}`).join(", ")} }`;
1345
+ }
1346
+ function formatGlobalsMultiline(globals, baseIndent) {
1321
1347
  const childIndent = `${baseIndent}${indent$1}`;
1322
1348
  return [
1323
1349
  "{",
@@ -1325,19 +1351,19 @@ function formatGlobalsObject(globals, baseIndent) {
1325
1351
  `${baseIndent}}`
1326
1352
  ].join("\n");
1327
1353
  }
1328
- function formatEntryField(label, value, baseIndent) {
1329
- return `${baseIndent}${indent$1}${label}: ${value},`;
1354
+ function renderGlobalsField(globals, baseIndent) {
1355
+ const inline = `${baseIndent}globals: ${formatGlobalsInline(globals)},`;
1356
+ if (inline.length <= MAX_LINE_LENGTH) return inline;
1357
+ return `${baseIndent}globals: ${formatGlobalsMultiline(globals, baseIndent)},`;
1330
1358
  }
1331
1359
  function formatEntry$1(entry, baseIndent) {
1360
+ const fieldIndent = `${baseIndent}${indent$1}`;
1332
1361
  const lines = [`${baseIndent}{`];
1333
- lines.push(formatEntryField("files", formatStringArray$1(entry.files), baseIndent));
1334
- if (entry.tsconfigPaths && entry.tsconfigPaths.length > 0) lines.push(formatEntryField("tsconfigPaths", formatStringArray$1(entry.tsconfigPaths), baseIndent));
1335
- if (entry.globalComponents && entry.globalComponents.length > 0) lines.push(formatEntryField("globalComponents", formatStringArray$1(entry.globalComponents), baseIndent));
1336
- if (entry.ignores && entry.ignores.length > 0) lines.push(formatEntryField("ignores", formatStringArray$1(entry.ignores), baseIndent));
1337
- if (entry.globals && Object.keys(entry.globals).length > 0) {
1338
- const globalsBlock = formatGlobalsObject(entry.globals, `${baseIndent}${indent$1}`);
1339
- lines.push(`${baseIndent}${indent$1}globals: ${globalsBlock},`);
1340
- }
1362
+ lines.push(renderStringArrayField("files", entry.files, fieldIndent));
1363
+ if (entry.tsconfigPaths && entry.tsconfigPaths.length > 0) lines.push(renderStringArrayField("tsconfigPaths", entry.tsconfigPaths, fieldIndent));
1364
+ if (entry.globalComponents && entry.globalComponents.length > 0) lines.push(renderStringArrayField("globalComponents", entry.globalComponents, fieldIndent));
1365
+ if (entry.ignores && entry.ignores.length > 0) lines.push(renderStringArrayField("ignores", entry.ignores, fieldIndent));
1366
+ if (entry.globals && Object.keys(entry.globals).length > 0) lines.push(renderGlobalsField(entry.globals, fieldIndent));
1341
1367
  lines.push(`${baseIndent}},`);
1342
1368
  return lines.join("\n");
1343
1369
  }
@@ -1354,6 +1380,8 @@ function renderImports(plan) {
1354
1380
  return `import { ${(plan.needsSilenceRulesImport ? ["silenceRules", "useInsider"] : ["useInsider"]).slice().sort((left, right) => left.localeCompare(right)).join(", ")} } from '@useinsider/eslint-config';`;
1355
1381
  }
1356
1382
  function renderSilenceRulesCall(rules) {
1383
+ const inline = `silenceRules(${formatStringArrayInline(rules)});`;
1384
+ if (inline.length <= MAX_LINE_LENGTH) return inline;
1357
1385
  return [
1358
1386
  "silenceRules([",
1359
1387
  rules.map((rule) => `${indent$1}${quote$1(rule)},`).join("\n"),
@@ -1366,28 +1394,35 @@ function renderSilenceRulesCalls(plan) {
1366
1394
  }
1367
1395
  function hasAnyContent(plan) {
1368
1396
  const { config } = plan;
1369
- return config.scopes.size > 0 || config.ignores.length > 0 || config.strictGlobs.length > 0 || config.strictWholeFile || config.spellChecker.ignoredPaths.length > 0;
1397
+ return config.scopes.size > 0 || config.ignores.length > 0 || config.strictGlobs.length > 0 || config.strictWholeFile || config.spellChecker.ignoredPaths.length > 0 || config.configFiles.length > 0;
1370
1398
  }
1371
1399
  function renderStrict(plan) {
1372
1400
  if (plan.config.strictWholeFile) return `${indent$1}strict: true,`;
1373
- if (plan.config.strictGlobs.length > 0) return `${indent$1}strict: ${formatStringArray$1(plan.config.strictGlobs)},`;
1401
+ if (plan.config.strictGlobs.length > 0) return renderStringArrayField("strict", plan.config.strictGlobs, indent$1);
1374
1402
  return null;
1375
1403
  }
1376
1404
  function renderSpellChecker(plan) {
1377
1405
  if (plan.config.spellChecker.ignoredPaths.length === 0) return null;
1406
+ const innerIndent = `${indent$1}${indent$1}`;
1378
1407
  return [
1379
1408
  `${indent$1}spellChecker: {`,
1380
- `${indent$1}${indent$1}ignoredPaths: ${formatStringArray$1(plan.config.spellChecker.ignoredPaths)},`,
1409
+ renderStringArrayField("ignoredPaths", plan.config.spellChecker.ignoredPaths, innerIndent),
1381
1410
  `${indent$1}},`
1382
1411
  ].join("\n");
1383
1412
  }
1384
1413
  function renderScopes(plan) {
1385
1414
  return [...plan.config.scopes.entries()].map(([scope, entries]) => formatScope$1(scope, entries, indent$1));
1386
1415
  }
1416
+ function renderConfigFiles(plan) {
1417
+ if (plan.config.configFiles.length === 0) return null;
1418
+ return renderStringArrayField("configFiles", plan.config.configFiles, indent$1);
1419
+ }
1387
1420
  function renderConfigBody(plan) {
1388
1421
  const lines = [];
1389
- if (plan.config.ignores.length > 0) lines.push(`${indent$1}ignores: ${formatStringArray$1(plan.config.ignores)},`);
1422
+ if (plan.config.ignores.length > 0) lines.push(renderStringArrayField("ignores", plan.config.ignores, indent$1));
1390
1423
  lines.push(...renderScopes(plan));
1424
+ const configFilesLine = renderConfigFiles(plan);
1425
+ if (configFilesLine) lines.push(configFilesLine);
1391
1426
  const strictLine = renderStrict(plan);
1392
1427
  if (strictLine) lines.push(strictLine);
1393
1428
  const spellCheckerSection = renderSpellChecker(plan);
@@ -1450,7 +1485,8 @@ function freshConfig() {
1450
1485
  scopes: /* @__PURE__ */ new Map(),
1451
1486
  strictGlobs: [],
1452
1487
  strictWholeFile: false,
1453
- spellChecker: { ignoredPaths: [] }
1488
+ spellChecker: { ignoredPaths: [] },
1489
+ configFiles: []
1454
1490
  };
1455
1491
  }
1456
1492
  function appendScope(config, scope, entry) {
@@ -1515,7 +1551,14 @@ function handlePreset(preset, call, config, warnings) {
1515
1551
  const entry = buildEntry(call, scope, warnings);
1516
1552
  if (entry) appendScope(config, scope, entry);
1517
1553
  }
1554
+ function captureConfigPresetFiles(call, config) {
1555
+ if (!call.presets.includes("config") || !call.files) return;
1556
+ call.files.forEach((file) => {
1557
+ if (!config.configFiles.includes(file)) config.configFiles.push(file);
1558
+ });
1559
+ }
1518
1560
  function processUseInsiderCall(call, config, warnings) {
1561
+ captureConfigPresetFiles(call, config);
1519
1562
  const filteredPresets = call.presets.filter((preset) => preset !== "config");
1520
1563
  const droppedRules = call.extraRuleCount > 0 ? call.extraRuleCount : 0;
1521
1564
  const droppedRuleBlocks = call.extraRuleCount > 0 ? 1 : 0;