@rotki/eslint-config 6.2.0 → 7.0.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.
Files changed (3) hide show
  1. package/dist/index.d.mts +2975 -1175
  2. package/dist/index.mjs +312 -171
  3. package/package.json +30 -30
package/dist/index.mjs CHANGED
@@ -180,8 +180,19 @@ async function disables() {
180
180
  }
181
181
  //#endregion
182
182
  //#region src/configs/e18e.ts
183
- async function e18e(options = {}) {
183
+ function resolveE18eOptions(options) {
184
184
  const { isInEditor = false, modernization = true, type = "app", moduleReplacements = type === "lib" && isInEditor, overrides = {}, performanceImprovements = true } = options;
185
+ return {
186
+ isInEditor,
187
+ modernization,
188
+ moduleReplacements,
189
+ overrides,
190
+ performanceImprovements,
191
+ type
192
+ };
193
+ }
194
+ async function e18e(options = {}) {
195
+ const { modernization, moduleReplacements, overrides, performanceImprovements, type } = resolveE18eOptions(options);
185
196
  const configs = pluginE18e.configs;
186
197
  return [{
187
198
  name: "rotki/e18e/rules",
@@ -391,20 +402,17 @@ function mergePrettierOptions(options, overrides) {
391
402
  plugins: [...overrides.plugins || [], ...options.plugins || []]
392
403
  };
393
404
  }
394
- async function formatters(options = {}, stylistic = {}) {
395
- if (options === true) options = {
405
+ function resolveFormattersOptions(options) {
406
+ if (options === true) return {
396
407
  css: true,
397
408
  html: true,
398
409
  markdown: true,
399
410
  xml: isPackageInScope("@prettier/plugin-xml")
400
411
  };
401
- await ensurePackages(["eslint-plugin-format", options.xml ? "@prettier/plugin-xml" : void 0]);
402
- const { indent: rawIndent, quotes, semi } = {
403
- ...StylisticConfigDefaults,
404
- ...stylistic
405
- };
406
- const indent = Array.isArray(rawIndent) ? rawIndent[0] : rawIndent;
407
- const prettierOptions = Object.assign({
412
+ return options;
413
+ }
414
+ function buildPrettierOptions(indent, quotes, semi, options) {
415
+ return Object.assign({
408
416
  endOfLine: "auto",
409
417
  printWidth: 120,
410
418
  semi,
@@ -413,70 +421,95 @@ async function formatters(options = {}, stylistic = {}) {
413
421
  trailingComma: "all",
414
422
  useTabs: indent === "tab"
415
423
  }, options.prettierOptions || {});
416
- const dprintOptions = Object.assign({
424
+ }
425
+ function buildDprintOptions(indent, quotes, options) {
426
+ return Object.assign({
417
427
  indentWidth: typeof indent === "number" ? indent : 2,
418
428
  quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
419
429
  useTabs: indent === "tab"
420
430
  }, options.dprintOptions || {});
421
- const prettierXmlOptions = {
422
- xmlQuoteAttributes: "double",
423
- xmlSelfClosingSpace: true,
424
- xmlSortAttributesByKey: false,
425
- xmlWhitespaceSensitivity: "ignore"
426
- };
427
- const configs = [{
428
- name: "rotki/formatter/setup",
429
- plugins: { format: await interopDefault(import("eslint-plugin-format")) }
430
- }];
431
- if (options.css) configs.push({
432
- files: [GLOB_CSS, GLOB_POSTCSS],
433
- languageOptions: { parser: parserPlain },
434
- name: "rotki/formatter/css",
435
- rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "css" })] }
436
- }, {
437
- files: [GLOB_SCSS],
438
- languageOptions: { parser: parserPlain },
439
- name: "rotki/formatter/scss",
440
- rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "scss" })] }
441
- }, {
442
- files: [GLOB_LESS],
443
- languageOptions: { parser: parserPlain },
444
- name: "rotki/formatter/less",
445
- rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "less" })] }
446
- });
447
- if (options.html) configs.push({
431
+ }
432
+ function cssFormatters(options, prettierOptions) {
433
+ if (!options.css) return [];
434
+ return [
435
+ {
436
+ files: [GLOB_CSS, GLOB_POSTCSS],
437
+ languageOptions: { parser: parserPlain },
438
+ name: "rotki/formatter/css",
439
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "css" })] }
440
+ },
441
+ {
442
+ files: [GLOB_SCSS],
443
+ languageOptions: { parser: parserPlain },
444
+ name: "rotki/formatter/scss",
445
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "scss" })] }
446
+ },
447
+ {
448
+ files: [GLOB_LESS],
449
+ languageOptions: { parser: parserPlain },
450
+ name: "rotki/formatter/less",
451
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "less" })] }
452
+ }
453
+ ];
454
+ }
455
+ function htmlFormatter(options, prettierOptions) {
456
+ if (!options.html) return [];
457
+ return [{
448
458
  files: ["**/*.html"],
449
459
  languageOptions: { parser: parserPlain },
450
460
  name: "rotki/formatter/html",
451
461
  rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "html" })] }
452
- });
453
- if (options.xml) configs.push({
462
+ }];
463
+ }
464
+ function xmlFormatter(options, prettierOptions) {
465
+ if (!options.xml) return [];
466
+ return [{
454
467
  files: [GLOB_XML],
455
468
  languageOptions: { parser: parserPlain },
456
469
  name: "rotki/formatter/xml",
457
470
  rules: { "format/prettier": ["error", mergePrettierOptions({
458
- ...prettierXmlOptions,
471
+ xmlQuoteAttributes: "double",
472
+ xmlSelfClosingSpace: true,
473
+ xmlSortAttributesByKey: false,
474
+ xmlWhitespaceSensitivity: "ignore",
459
475
  ...prettierOptions
460
476
  }, {
461
477
  parser: "xml",
462
478
  plugins: ["@prettier/plugin-xml"]
463
479
  })] }
464
- });
465
- if (options.markdown) {
466
- const formater = options.markdown === true ? "prettier" : options.markdown;
467
- configs.push({
468
- files: [GLOB_MARKDOWN],
469
- languageOptions: { parser: parserPlain },
470
- name: "rotki/formatter/markdown",
471
- rules: { [`format/${formater}`]: ["error", formater === "prettier" ? mergePrettierOptions(prettierOptions, {
472
- embeddedLanguageFormatting: "off",
473
- parser: "markdown"
474
- }) : {
475
- ...dprintOptions,
476
- language: "markdown"
477
- }] }
478
- });
479
- }
480
+ }];
481
+ }
482
+ function markdownFormatter(options, prettierOptions, dprintOptions) {
483
+ if (!options.markdown) return [];
484
+ const formater = options.markdown === true ? "prettier" : options.markdown;
485
+ return [{
486
+ files: [GLOB_MARKDOWN],
487
+ languageOptions: { parser: parserPlain },
488
+ name: "rotki/formatter/markdown",
489
+ rules: { [`format/${formater}`]: ["error", formater === "prettier" ? mergePrettierOptions(prettierOptions, {
490
+ embeddedLanguageFormatting: "off",
491
+ parser: "markdown"
492
+ }) : {
493
+ ...dprintOptions,
494
+ language: "markdown"
495
+ }] }
496
+ }];
497
+ }
498
+ async function formatters(options = {}, stylistic = {}) {
499
+ const resolvedOptions = resolveFormattersOptions(options);
500
+ await ensurePackages(["eslint-plugin-format", resolvedOptions.xml ? "@prettier/plugin-xml" : void 0]);
501
+ const { indent: rawIndent, quotes, semi } = {
502
+ ...StylisticConfigDefaults,
503
+ ...stylistic
504
+ };
505
+ const indent = Array.isArray(rawIndent) ? rawIndent[0] : rawIndent;
506
+ const prettierOptions = buildPrettierOptions(indent, quotes, semi, resolvedOptions);
507
+ const dprintOptions = buildDprintOptions(indent, quotes, resolvedOptions);
508
+ const configs = [{
509
+ name: "rotki/formatter/setup",
510
+ plugins: { format: await interopDefault(import("eslint-plugin-format")) }
511
+ }];
512
+ configs.push(...cssFormatters(resolvedOptions, prettierOptions), ...htmlFormatter(resolvedOptions, prettierOptions), ...xmlFormatter(resolvedOptions, prettierOptions), ...markdownFormatter(resolvedOptions, prettierOptions, dprintOptions));
480
513
  return configs;
481
514
  }
482
515
  //#endregion
@@ -526,7 +559,7 @@ async function javascript(options = {}) {
526
559
  const { isInEditor = false, overrides = {} } = options;
527
560
  const customRules = {
528
561
  "arrow-body-style": ["error", "as-needed"],
529
- "complexity": ["warn", { max: 10 }],
562
+ "complexity": ["error", { max: 10 }],
530
563
  "max-lines": ["error", { max: 400 }]
531
564
  };
532
565
  return [{
@@ -1143,24 +1176,26 @@ async function rotkiPlugin(options = {}) {
1143
1176
  },
1144
1177
  name: "rotki/rotki/rules",
1145
1178
  rules: {
1146
- "@rotki/composable-no-default-export": "warn",
1147
- "@rotki/composable-prefer-shallowref": "warn",
1148
- "@rotki/composable-require-cleanup": "warn",
1149
- "@rotki/composable-return-readonly": "warn",
1150
- "@rotki/composable-ssr-safety": "warn",
1179
+ "@rotki/composable-no-default-export": "error",
1180
+ "@rotki/composable-prefer-shallowref": "error",
1181
+ "@rotki/composable-require-cleanup": "error",
1182
+ "@rotki/composable-return-readonly": "error",
1183
+ "@rotki/composable-ssr-safety": "error",
1151
1184
  "@rotki/consistent-ref-type-annotation": ["error", { allowInference: true }],
1152
1185
  "@rotki/no-deprecated-classes": "error",
1153
1186
  "@rotki/no-deprecated-props": "error",
1154
1187
  "@rotki/no-dot-ts-imports": "error",
1188
+ "@rotki/no-redundant-flex-row": "error",
1189
+ "@rotki/no-shared-pinia": "error",
1155
1190
  "@rotki/no-unused-i18n-keys": ["error", {
1156
1191
  extensions: [".ts", ".vue"],
1157
1192
  ignoreKeys,
1158
1193
  src
1159
1194
  }],
1160
1195
  ...stylistic ? {
1161
- "@rotki/composable-input-flexibility": "warn",
1162
- "@rotki/composable-naming-convention": "warn",
1163
- "@rotki/require-jsdoc-on-composable-options": "warn"
1196
+ "@rotki/composable-input-flexibility": "error",
1197
+ "@rotki/composable-naming-convention": "error",
1198
+ "@rotki/require-jsdoc-on-composable-options": "error"
1164
1199
  } : {},
1165
1200
  ...overrides
1166
1201
  }
@@ -1210,6 +1245,7 @@ async function sortPackageJson() {
1210
1245
  "directories",
1211
1246
  "publishConfig",
1212
1247
  "scripts",
1248
+ "scripts-info",
1213
1249
  "peerDependencies",
1214
1250
  "peerDependenciesMeta",
1215
1251
  "optionalDependencies",
@@ -1466,24 +1502,86 @@ async function test(options = {}) {
1466
1502
  }
1467
1503
  //#endregion
1468
1504
  //#region src/configs/typescript.ts
1469
- async function typescript(options = {}) {
1505
+ const typeAwareCustom = {
1506
+ "@typescript-eslint/consistent-type-assertions": ["error", { assertionStyle: "never" }],
1507
+ "@typescript-eslint/naming-convention": [
1508
+ "error",
1509
+ {
1510
+ format: null,
1511
+ modifiers: ["destructured"],
1512
+ selector: "variable"
1513
+ },
1514
+ {
1515
+ format: ["camelCase"],
1516
+ leadingUnderscore: "allow",
1517
+ selector: "parameter"
1518
+ },
1519
+ {
1520
+ format: ["camelCase"],
1521
+ selector: "variable"
1522
+ },
1523
+ {
1524
+ format: [
1525
+ "camelCase",
1526
+ "UPPER_CASE",
1527
+ "PascalCase"
1528
+ ],
1529
+ modifiers: ["const"],
1530
+ selector: "variable"
1531
+ },
1532
+ {
1533
+ format: ["camelCase"],
1534
+ leadingUnderscore: "allow",
1535
+ modifiers: ["private"],
1536
+ selector: "memberLike"
1537
+ },
1538
+ {
1539
+ format: ["PascalCase"],
1540
+ selector: "typeLike"
1541
+ }
1542
+ ]
1543
+ };
1544
+ const customRules = {
1545
+ "@typescript-eslint/prefer-as-const": "error",
1546
+ "@typescript-eslint/prefer-literal-enum-member": ["warn", { allowBitwiseExpressions: true }],
1547
+ "max-lines": ["error", { max: 400 }]
1548
+ };
1549
+ function resolveTypeScriptFiles(options, componentExts) {
1550
+ return {
1551
+ files: options.files ?? [
1552
+ "**/*.?([cm])ts",
1553
+ "**/*.?([cm])tsx",
1554
+ ...componentExts.map((ext) => `**/*.${ext}`)
1555
+ ],
1556
+ filesTypeAware: options.filesTypeAware ?? ["**/*.?([cm])ts", "**/*.?([cm])tsx"],
1557
+ ignoresTypeAware: options.ignoresTypeAware ?? [`**/*.md/**`]
1558
+ };
1559
+ }
1560
+ function resolveTypeScriptOptions(options) {
1470
1561
  const { componentExts = [], isInEditor = false, overrides = {}, overridesTypeAware = {}, parserOptions = {}, type = "app" } = options;
1471
- const files = options.files ?? [
1472
- "**/*.?([cm])ts",
1473
- "**/*.?([cm])tsx",
1474
- ...componentExts.map((ext) => `**/*.${ext}`)
1475
- ];
1476
- const filesTypeAware = options.filesTypeAware ?? ["**/*.?([cm])ts", "**/*.?([cm])tsx"];
1477
- const ignoresTypeAware = options.ignoresTypeAware ?? [`**/*.md/**`];
1478
- const tsconfigPath = options?.tsconfigPath ? options.tsconfigPath : void 0;
1479
- const isTypeAware = !!tsconfigPath;
1480
- const typeAwareRules = {
1481
- "@typescript-eslint/await-thenable": "warn",
1562
+ const tsconfigPath = options.tsconfigPath ? options.tsconfigPath : void 0;
1563
+ return {
1564
+ componentExts,
1565
+ isInEditor,
1566
+ isTypeAware: !!tsconfigPath,
1567
+ overrides,
1568
+ overridesTypeAware,
1569
+ parserOptions,
1570
+ tsconfigPath,
1571
+ type,
1572
+ ...resolveTypeScriptFiles(options, componentExts)
1573
+ };
1574
+ }
1575
+ function buildTypeAwareRules(isInEditor) {
1576
+ return {
1577
+ "@typescript-eslint/await-thenable": "error",
1578
+ "@typescript-eslint/consistent-type-exports": "error",
1482
1579
  "@typescript-eslint/dot-notation": ["error", { allowKeywords: true }],
1483
1580
  "@typescript-eslint/no-floating-promises": ["error", { ignoreIIFE: true }],
1484
1581
  "@typescript-eslint/no-for-in-array": "error",
1485
1582
  "@typescript-eslint/no-implied-eval": "error",
1486
- "@typescript-eslint/no-misused-promises": "warn",
1583
+ "@typescript-eslint/no-misused-promises": "error",
1584
+ "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
1487
1585
  "@typescript-eslint/no-unnecessary-type-assertion": "error",
1488
1586
  "@typescript-eslint/no-unsafe-argument": isInEditor ? "warn" : "off",
1489
1587
  "@typescript-eslint/no-unsafe-assignment": isInEditor ? "warn" : "off",
@@ -1491,6 +1589,9 @@ async function typescript(options = {}) {
1491
1589
  "@typescript-eslint/no-unsafe-member-access": isInEditor ? "warn" : "off",
1492
1590
  "@typescript-eslint/no-unsafe-return": isInEditor ? "warn" : "off",
1493
1591
  "@typescript-eslint/only-throw-error": "error",
1592
+ "@typescript-eslint/prefer-nullish-coalescing": "error",
1593
+ "@typescript-eslint/prefer-optional-chain": "error",
1594
+ "@typescript-eslint/prefer-readonly": "error",
1494
1595
  "@typescript-eslint/promise-function-async": "error",
1495
1596
  "@typescript-eslint/restrict-plus-operands": "error",
1496
1597
  "@typescript-eslint/restrict-template-expressions": "error",
@@ -1500,49 +1601,18 @@ async function typescript(options = {}) {
1500
1601
  "dot-notation": "off",
1501
1602
  "no-implied-eval": "off",
1502
1603
  "no-throw-literal": "off",
1503
- "@typescript-eslint/consistent-type-assertions": ["error", { assertionStyle: "never" }],
1504
- "@typescript-eslint/naming-convention": [
1505
- "error",
1506
- {
1507
- format: null,
1508
- modifiers: ["destructured"],
1509
- selector: "variable"
1510
- },
1511
- {
1512
- format: ["camelCase"],
1513
- leadingUnderscore: "allow",
1514
- selector: "parameter"
1515
- },
1516
- {
1517
- format: ["camelCase"],
1518
- selector: "variable"
1519
- },
1520
- {
1521
- format: [
1522
- "camelCase",
1523
- "UPPER_CASE",
1524
- "PascalCase"
1525
- ],
1526
- modifiers: ["const"],
1527
- selector: "variable"
1528
- },
1529
- {
1530
- format: ["camelCase"],
1531
- leadingUnderscore: "allow",
1532
- modifiers: ["private"],
1533
- selector: "memberLike"
1534
- },
1535
- {
1536
- format: ["PascalCase"],
1537
- selector: "typeLike"
1538
- }
1539
- ]
1540
- };
1541
- const customRules = {
1542
- "@typescript-eslint/prefer-as-const": "warn",
1543
- "@typescript-eslint/prefer-literal-enum-member": ["warn", { allowBitwiseExpressions: true }],
1544
- "max-lines": ["error", { max: 400 }]
1604
+ ...typeAwareCustom
1545
1605
  };
1606
+ }
1607
+ function buildLibRules(type) {
1608
+ return type === "lib" ? { "@typescript-eslint/explicit-function-return-type": ["error", {
1609
+ allowExpressions: true,
1610
+ allowHigherOrderFunctions: true,
1611
+ allowIIFEs: true
1612
+ }] } : {};
1613
+ }
1614
+ async function typescript(options = {}) {
1615
+ const { componentExts, files, filesTypeAware, ignoresTypeAware, isInEditor, isTypeAware, overrides, overridesTypeAware, parserOptions, tsconfigPath, type } = resolveTypeScriptOptions(options);
1546
1616
  const [pluginTs, parserTs] = await Promise.all([interopDefault(import("@typescript-eslint/eslint-plugin")), interopDefault(import("@typescript-eslint/parser"))]);
1547
1617
  function makeParser(typeAware, files, ignores) {
1548
1618
  return {
@@ -1614,11 +1684,7 @@ async function typescript(options = {}) {
1614
1684
  "no-redeclare": "off",
1615
1685
  "no-use-before-define": "off",
1616
1686
  "no-useless-constructor": "off",
1617
- ...type === "lib" ? { "@typescript-eslint/explicit-function-return-type": ["error", {
1618
- allowExpressions: true,
1619
- allowHigherOrderFunctions: true,
1620
- allowIIFEs: true
1621
- }] } : {},
1687
+ ...buildLibRules(type),
1622
1688
  ...customRules,
1623
1689
  ...overrides
1624
1690
  }
@@ -1628,7 +1694,7 @@ async function typescript(options = {}) {
1628
1694
  ignores: ignoresTypeAware,
1629
1695
  name: "rotki/typescript/rules-type-aware",
1630
1696
  rules: {
1631
- ...typeAwareRules,
1697
+ ...buildTypeAwareRules(isInEditor),
1632
1698
  ...overridesTypeAware
1633
1699
  }
1634
1700
  }] : []
@@ -1639,11 +1705,12 @@ async function typescript(options = {}) {
1639
1705
  const FILENAME_CASE_IGNORE = /^[A-Z]+\..*$/;
1640
1706
  async function unicorn(options = {}) {
1641
1707
  return [{
1708
+ files: [GLOB_SRC, GLOB_VUE],
1642
1709
  name: "rotki/unicorn/rules",
1643
1710
  plugins: { unicorn: pluginUnicorn },
1644
1711
  rules: { ...options.allRecommended ? pluginUnicorn.configs.recommended.rules : {
1645
1712
  "unicorn/catch-error-name": "error",
1646
- "unicorn/consistent-destructuring": "warn",
1713
+ "unicorn/consistent-destructuring": "error",
1647
1714
  "unicorn/custom-error-definition": "error",
1648
1715
  "unicorn/error-message": "error",
1649
1716
  "unicorn/escape-case": "error",
@@ -1694,18 +1761,26 @@ async function unicorn(options = {}) {
1694
1761
  "unicorn/prefer-type-error": "error",
1695
1762
  "unicorn/throw-new-error": "error"
1696
1763
  } }
1697
- }, {
1698
- files: [".github/**/*.md"],
1699
- name: "rotki/unicorn/github-markdown",
1700
- rules: { "unicorn/filename-case": "off" }
1701
1764
  }];
1702
1765
  }
1703
1766
  //#endregion
1704
1767
  //#region src/configs/vue.ts
1705
- async function vue(options = {}) {
1768
+ function resolveVueOptions(options) {
1706
1769
  const { files = [GLOB_VUE], overrides = {}, stylistic = true, typescript } = options;
1707
1770
  const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1708
1771
  const { braceStyle = "stroustrup", indent = 2 } = typeof stylistic === "boolean" ? {} : stylistic;
1772
+ return {
1773
+ braceStyle,
1774
+ files,
1775
+ indent,
1776
+ overrides,
1777
+ sfcBlocks,
1778
+ stylistic,
1779
+ typescript
1780
+ };
1781
+ }
1782
+ async function vue(options = {}) {
1783
+ const { braceStyle, files, indent, overrides, sfcBlocks, stylistic, typescript } = resolveVueOptions(options);
1709
1784
  const [pluginVue, parserVue, processorVueBlocks] = await Promise.all([
1710
1785
  interopDefault(import("eslint-plugin-vue")),
1711
1786
  interopDefault(import("vue-eslint-parser")),
@@ -1713,10 +1788,11 @@ async function vue(options = {}) {
1713
1788
  ]);
1714
1789
  const customRules = {
1715
1790
  "max-lines": ["warn", { max: 800 }],
1791
+ "vue/block-lang": ["error", { script: { lang: "ts" } }],
1716
1792
  "vue/component-api-style": ["error", ["script-setup"]],
1717
1793
  "vue/define-emits-declaration": ["error", "type-literal"],
1718
1794
  "vue/define-props-declaration": ["error", "type-based"],
1719
- "vue/define-props-destructuring": "warn",
1795
+ "vue/define-props-destructuring": "error",
1720
1796
  "vue/first-attribute-linebreak": ["error", {
1721
1797
  multiline: "below",
1722
1798
  singleline: "ignore"
@@ -1731,14 +1807,14 @@ async function vue(options = {}) {
1731
1807
  math: "always",
1732
1808
  svg: "always"
1733
1809
  }],
1734
- "vue/max-props": ["warn", { maxProps: 6 }],
1735
- "vue/max-template-depth": ["warn", { maxDepth: 8 }],
1810
+ "vue/max-props": ["error", { maxProps: 8 }],
1811
+ "vue/max-template-depth": ["error", { maxDepth: 8 }],
1736
1812
  "vue/multiline-html-element-content-newline": ["error", {
1737
1813
  allowEmptyLines: false,
1738
1814
  ignores: ["pre", "textarea"],
1739
1815
  ignoreWhenEmpty: true
1740
1816
  }],
1741
- "vue/no-constant-condition": "warn",
1817
+ "vue/no-constant-condition": "error",
1742
1818
  "vue/no-deprecated-dollar-listeners-api": "error",
1743
1819
  "vue/no-deprecated-events-api": "error",
1744
1820
  "vue/no-deprecated-filter": "error",
@@ -1748,7 +1824,7 @@ async function vue(options = {}) {
1748
1824
  "vue/no-required-prop-with-default": ["error", { autofix: true }],
1749
1825
  "vue/no-static-inline-styles": ["error", { allowBinding: false }],
1750
1826
  "vue/no-unused-emit-declarations": "error",
1751
- "vue/no-unused-properties": ["warn", { groups: [
1827
+ "vue/no-unused-properties": ["error", { groups: [
1752
1828
  "props",
1753
1829
  "data",
1754
1830
  "computed",
@@ -1756,9 +1832,10 @@ async function vue(options = {}) {
1756
1832
  ] }],
1757
1833
  "vue/prefer-define-options": "error",
1758
1834
  "vue/prefer-import-from-vue": "error",
1759
- "vue/prefer-use-template-ref": "warn",
1835
+ "vue/prefer-true-attribute-shorthand": "error",
1836
+ "vue/prefer-use-template-ref": "error",
1760
1837
  "vue/require-explicit-emits": "error",
1761
- "vue/require-explicit-slots": "warn",
1838
+ "vue/require-explicit-slots": "error",
1762
1839
  "vue/require-expose": "error",
1763
1840
  "vue/require-macro-variable-name": ["error", {
1764
1841
  defineEmits: "emit",
@@ -1970,7 +2047,7 @@ async function vue(options = {}) {
1970
2047
  }
1971
2048
  //#endregion
1972
2049
  //#region src/configs/vue-i18n.ts
1973
- async function vueI18n(options = {}) {
2050
+ function resolveVueI18nOptions(options) {
1974
2051
  const { files = [GLOB_TS, GLOB_VUE], isInEditor = false, localesDirectory = "locales", noRawTextIgnores = {
1975
2052
  nodes: [
1976
2053
  "md-icon",
@@ -1984,6 +2061,18 @@ async function vueI18n(options = {}) {
1984
2061
  "USD"
1985
2062
  ]
1986
2063
  }, overrides = {}, src = "src", typescript } = options;
2064
+ return {
2065
+ files,
2066
+ isInEditor,
2067
+ localesDirectory,
2068
+ noRawTextIgnores,
2069
+ overrides,
2070
+ src,
2071
+ typescript
2072
+ };
2073
+ }
2074
+ async function vueI18n(options = {}) {
2075
+ const { files, isInEditor, localesDirectory, noRawTextIgnores, overrides, src, typescript } = resolveVueI18nOptions(options);
1987
2076
  const fileGlobs = files.map((x) => `**/${src}/${x}`);
1988
2077
  if (localesDirectory) fileGlobs.push(`**/${src}/${localesDirectory}/${GLOB_JSON}`, `**/${src}/${localesDirectory}/${GLOB_JSON5}`, `**/${src}/${localesDirectory}/${GLOB_YAML}`);
1989
2078
  const localeDir = path.resolve(path.join(process.cwd(), src, localesDirectory));
@@ -2035,10 +2124,19 @@ async function vueI18n(options = {}) {
2035
2124
  }
2036
2125
  //#endregion
2037
2126
  //#region src/configs/yaml.ts
2038
- async function yaml(options = {}) {
2127
+ function resolveYamlOptions(options) {
2039
2128
  const { files = [GLOB_YAML], overrides = {}, stylistic = true } = options;
2040
2129
  const { indent: rawIndent = 2, quotes = "single" } = typeof stylistic === "boolean" ? {} : stylistic;
2041
- const indent = Array.isArray(rawIndent) ? rawIndent[0] : rawIndent;
2130
+ return {
2131
+ files,
2132
+ indent: Array.isArray(rawIndent) ? rawIndent[0] : rawIndent,
2133
+ overrides,
2134
+ quotes,
2135
+ stylistic
2136
+ };
2137
+ }
2138
+ async function yaml(options = {}) {
2139
+ const { files, indent, overrides, quotes, stylistic } = resolveYamlOptions(options);
2042
2140
  const [pluginYaml, parserYaml] = await Promise.all([interopDefault(import("eslint-plugin-yml")), interopDefault(import("yaml-eslint-parser"))]);
2043
2141
  return [{
2044
2142
  name: "rotki/yaml/setup",
@@ -2100,24 +2198,49 @@ const defaultPluginRenaming = {
2100
2198
  "vitest": "test",
2101
2199
  "yml": "yaml"
2102
2200
  };
2103
- /**
2104
- * Construct an array of ESLint flat config items.
2105
- */
2106
- function rotki(options = {}, ...userConfigs) {
2107
- const { autoRenamePlugins = true, componentExts = [], e18e: enableE18e = true, gitignore: enableGitignore = true, jsx = true, perfectionist: enablePerfectionist = true, pnpm: enablePnpm = !!findUpSync("pnpm-workspace.yaml"), regexp: enableRegexp = false, rotki: enableRotki, storybook: enableStorybook, typescript: enableTypeScript = isPackageExists("typescript") || isPackageExists("@typescript/native-preview"), unicorn: enableUnicorn = true, vue: enableVue = VuePackages.some((i) => isPackageExists(i)), vueI18n: enableVueI18n } = options;
2201
+ function resolveStylisticOptions(options, jsx) {
2202
+ if (options.stylistic === false) return false;
2203
+ const stylisticOptions = typeof options.stylistic === "object" ? options.stylistic : {};
2204
+ if (!("jsx" in stylisticOptions)) stylisticOptions.jsx = jsx;
2205
+ return stylisticOptions;
2206
+ }
2207
+ function resolveEnableFlags(options) {
2208
+ return {
2209
+ autoRenamePlugins: options.autoRenamePlugins ?? true,
2210
+ enableE18e: options.e18e ?? true,
2211
+ enableGitignore: options.gitignore ?? true,
2212
+ enablePerfectionist: !!(options.perfectionist ?? true),
2213
+ enablePnpm: !!(options.pnpm ?? findUpSync("pnpm-workspace.yaml")),
2214
+ enableRegexp: options.regexp ?? false,
2215
+ enableRotki: options.rotki,
2216
+ enableStorybook: options.storybook,
2217
+ enableUnicorn: options.unicorn ?? true,
2218
+ enableVueI18n: options.vueI18n
2219
+ };
2220
+ }
2221
+ function resolveIsInEditor(options) {
2108
2222
  let isInEditor = options.isInEditor;
2109
2223
  if (isInEditor === null) {
2110
2224
  isInEditor = isInEditorEnv();
2111
2225
  if (isInEditor) console.log("[@rotki/eslint-config] Detected running in editor, some rules are disabled.");
2112
2226
  }
2113
- function resolveStylisticOptions() {
2114
- if (options.stylistic === false) return false;
2115
- if (typeof options.stylistic === "object") return options.stylistic;
2116
- return {};
2117
- }
2118
- const stylisticOptions = resolveStylisticOptions();
2119
- if (stylisticOptions && !("jsx" in stylisticOptions)) stylisticOptions.jsx = jsx;
2120
- const configs = [];
2227
+ return !!isInEditor;
2228
+ }
2229
+ function resolveOptions(options) {
2230
+ const jsx = options.jsx ?? true;
2231
+ const enableVue = !!(options.vue ?? VuePackages.some((i) => isPackageExists(i)));
2232
+ return {
2233
+ ...resolveEnableFlags(options),
2234
+ componentExts: [...options.componentExts ?? [], ...enableVue ? ["vue"] : []],
2235
+ enableTypeScript: options.typescript ?? (isPackageExists("typescript") || isPackageExists("@typescript/native-preview")),
2236
+ enableVue,
2237
+ isInEditor: resolveIsInEditor(options),
2238
+ stylisticOptions: resolveStylisticOptions(options, jsx),
2239
+ typescriptOptions: resolveSubOptions(options, "typescript")
2240
+ };
2241
+ }
2242
+ function buildLanguageConfigs(configs, options, resolved) {
2243
+ const { enableE18e, enableGitignore, enablePerfectionist, enableUnicorn, isInEditor, stylisticOptions } = resolved;
2121
2244
  if (enableGitignore) {
2122
2245
  const gitignoreOptions = typeof enableGitignore !== "boolean" ? enableGitignore : { strict: false };
2123
2246
  configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
@@ -2125,7 +2248,6 @@ function rotki(options = {}, ...userConfigs) {
2125
2248
  ...gitignoreOptions
2126
2249
  })]));
2127
2250
  }
2128
- const typescriptOptions = resolveSubOptions(options, "typescript");
2129
2251
  configs.push(ignores(options.ignores), javascript({
2130
2252
  isInEditor,
2131
2253
  overrides: getOverrides(options, "javascript")
@@ -2140,7 +2262,9 @@ function rotki(options = {}, ...userConfigs) {
2140
2262
  isInEditor,
2141
2263
  type: options.type
2142
2264
  }));
2143
- if (enableVue) componentExts.push("vue");
2265
+ }
2266
+ function buildTypeScriptAndStyleConfigs(configs, options, resolved) {
2267
+ const { componentExts, enableRegexp, enableTypeScript, isInEditor, stylisticOptions, typescriptOptions } = resolved;
2144
2268
  if (enableTypeScript) configs.push(typescript({
2145
2269
  ...typescriptOptions,
2146
2270
  componentExts,
@@ -2157,6 +2281,9 @@ function rotki(options = {}, ...userConfigs) {
2157
2281
  isInEditor,
2158
2282
  overrides: getOverrides(options, "test")
2159
2283
  }));
2284
+ }
2285
+ function buildFrameworkConfigs(configs, options, resolved) {
2286
+ const { enableRotki, enableStorybook, enableTypeScript, enableVue, enableVueI18n, stylisticOptions } = resolved;
2160
2287
  if (enableVue) configs.push(vue({
2161
2288
  ...resolveSubOptions(options, "vue"),
2162
2289
  overrides: getOverrides(options, "vue"),
@@ -2175,19 +2302,19 @@ function rotki(options = {}, ...userConfigs) {
2175
2302
  typescript: !!enableTypeScript
2176
2303
  }));
2177
2304
  if (enableStorybook) configs.push(storybook({ overrides: getOverrides(options, "storybook") }));
2305
+ }
2306
+ function buildFileFormatConfigs(configs, options, resolved) {
2307
+ const { componentExts, enablePnpm, isInEditor, stylisticOptions } = resolved;
2178
2308
  if (options.jsonc ?? true) configs.push(jsonc({
2179
2309
  overrides: getOverrides(options, "jsonc"),
2180
2310
  stylistic: stylisticOptions
2181
2311
  }), sortPackageJson(), sortTsconfig());
2182
- if (enablePnpm) {
2183
- const optionsPnpm = resolveSubOptions(options, "pnpm");
2184
- configs.push(pnpm({
2185
- isInEditor,
2186
- json: options.jsonc !== false,
2187
- yaml: options.yaml !== false,
2188
- ...optionsPnpm
2189
- }));
2190
- }
2312
+ if (enablePnpm) configs.push(pnpm({
2313
+ isInEditor,
2314
+ json: options.jsonc !== false,
2315
+ yaml: options.yaml !== false,
2316
+ ...resolveSubOptions(options, "pnpm")
2317
+ }));
2191
2318
  if (options.yaml ?? true) configs.push(yaml({
2192
2319
  overrides: getOverrides(options, "yaml"),
2193
2320
  stylistic: stylisticOptions
@@ -2197,8 +2324,8 @@ function rotki(options = {}, ...userConfigs) {
2197
2324
  overrides: getOverrides(options, "markdown")
2198
2325
  }));
2199
2326
  if (options.formatters) configs.push(formatters(options.formatters, typeof stylisticOptions === "boolean" ? {} : stylisticOptions));
2200
- configs.push(disables());
2201
- if ("files" in options) throw new Error("[@rotki/eslint-config] The first argument should not contain the \"files\" property as the options are supposed to be global. Place it in the second or later config instead.");
2327
+ }
2328
+ function finalizeComposer(configs, options, resolved, userConfigs) {
2202
2329
  const fusedConfig = flatConfigProps.reduce((acc, key) => {
2203
2330
  if (key in options) acc[key] = options[key];
2204
2331
  return acc;
@@ -2207,14 +2334,28 @@ function rotki(options = {}, ...userConfigs) {
2207
2334
  let composer = new FlatConfigComposer();
2208
2335
  composer = composer.append(...configs, ...userConfigs);
2209
2336
  if (options.markdown ?? true) composer = composer.setDefaultIgnores((prev) => [...prev, GLOB_MARKDOWN]);
2210
- if (autoRenamePlugins) composer = composer.renamePlugins(defaultPluginRenaming);
2211
- if (isInEditor) composer = composer.disableRulesFix([
2337
+ if (resolved.autoRenamePlugins) composer = composer.renamePlugins(defaultPluginRenaming);
2338
+ if (resolved.isInEditor) composer = composer.disableRulesFix([
2212
2339
  "unused-imports/no-unused-imports",
2213
2340
  "test/no-only-tests",
2214
2341
  "prefer-const"
2215
2342
  ], { builtinRules: () => import(["eslint", "use-at-your-own-risk"].join("/")).then((r) => r.builtinRules) });
2216
2343
  return composer;
2217
2344
  }
2345
+ /**
2346
+ * Construct an array of ESLint flat config items.
2347
+ */
2348
+ function rotki(options = {}, ...userConfigs) {
2349
+ if ("files" in options) throw new Error("[@rotki/eslint-config] The first argument should not contain the \"files\" property as the options are supposed to be global. Place it in the second or later config instead.");
2350
+ const resolved = resolveOptions(options);
2351
+ const configs = [];
2352
+ buildLanguageConfigs(configs, options, resolved);
2353
+ buildTypeScriptAndStyleConfigs(configs, options, resolved);
2354
+ buildFrameworkConfigs(configs, options, resolved);
2355
+ buildFileFormatConfigs(configs, options, resolved);
2356
+ configs.push(disables());
2357
+ return finalizeComposer(configs, options, resolved, userConfigs);
2358
+ }
2218
2359
  function resolveSubOptions(options, key) {
2219
2360
  return typeof options[key] === "boolean" ? {} : options[key] || {};
2220
2361
  }