@rotki/eslint-config 6.2.0 → 8.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 +5766 -1176
  2. package/dist/index.mjs +625 -212
  3. package/package.json +53 -37
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",
@@ -190,6 +201,10 @@ async function e18e(options = {}) {
190
201
  ...modernization ? { ...configs.modernization.rules } : {},
191
202
  ...moduleReplacements ? { ...configs.moduleReplacements.rules } : {},
192
203
  ...performanceImprovements ? { ...configs.performanceImprovements.rules } : {},
204
+ ...performanceImprovements ? {
205
+ "e18e/prefer-charcode-at-in-loop": "error",
206
+ "e18e/prefer-slice-over-split-index": "error"
207
+ } : {},
193
208
  ...type === "lib" ? {} : { "e18e/prefer-static-regex": "off" },
194
209
  "e18e/prefer-array-to-reversed": "off",
195
210
  "e18e/prefer-array-to-sorted": "off",
@@ -391,20 +406,17 @@ function mergePrettierOptions(options, overrides) {
391
406
  plugins: [...overrides.plugins || [], ...options.plugins || []]
392
407
  };
393
408
  }
394
- async function formatters(options = {}, stylistic = {}) {
395
- if (options === true) options = {
409
+ function resolveFormattersOptions(options) {
410
+ if (options === true) return {
396
411
  css: true,
397
412
  html: true,
398
413
  markdown: true,
399
414
  xml: isPackageInScope("@prettier/plugin-xml")
400
415
  };
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({
416
+ return options;
417
+ }
418
+ function buildPrettierOptions(indent, quotes, semi, options) {
419
+ return Object.assign({
408
420
  endOfLine: "auto",
409
421
  printWidth: 120,
410
422
  semi,
@@ -413,70 +425,95 @@ async function formatters(options = {}, stylistic = {}) {
413
425
  trailingComma: "all",
414
426
  useTabs: indent === "tab"
415
427
  }, options.prettierOptions || {});
416
- const dprintOptions = Object.assign({
428
+ }
429
+ function buildDprintOptions(indent, quotes, options) {
430
+ return Object.assign({
417
431
  indentWidth: typeof indent === "number" ? indent : 2,
418
432
  quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
419
433
  useTabs: indent === "tab"
420
434
  }, 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({
435
+ }
436
+ function cssFormatters(options, prettierOptions) {
437
+ if (!options.css) return [];
438
+ return [
439
+ {
440
+ files: [GLOB_CSS, GLOB_POSTCSS],
441
+ languageOptions: { parser: parserPlain },
442
+ name: "rotki/formatter/css",
443
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "css" })] }
444
+ },
445
+ {
446
+ files: [GLOB_SCSS],
447
+ languageOptions: { parser: parserPlain },
448
+ name: "rotki/formatter/scss",
449
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "scss" })] }
450
+ },
451
+ {
452
+ files: [GLOB_LESS],
453
+ languageOptions: { parser: parserPlain },
454
+ name: "rotki/formatter/less",
455
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "less" })] }
456
+ }
457
+ ];
458
+ }
459
+ function htmlFormatter(options, prettierOptions) {
460
+ if (!options.html) return [];
461
+ return [{
448
462
  files: ["**/*.html"],
449
463
  languageOptions: { parser: parserPlain },
450
464
  name: "rotki/formatter/html",
451
465
  rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "html" })] }
452
- });
453
- if (options.xml) configs.push({
466
+ }];
467
+ }
468
+ function xmlFormatter(options, prettierOptions) {
469
+ if (!options.xml) return [];
470
+ return [{
454
471
  files: [GLOB_XML],
455
472
  languageOptions: { parser: parserPlain },
456
473
  name: "rotki/formatter/xml",
457
474
  rules: { "format/prettier": ["error", mergePrettierOptions({
458
- ...prettierXmlOptions,
475
+ xmlQuoteAttributes: "double",
476
+ xmlSelfClosingSpace: true,
477
+ xmlSortAttributesByKey: false,
478
+ xmlWhitespaceSensitivity: "ignore",
459
479
  ...prettierOptions
460
480
  }, {
461
481
  parser: "xml",
462
482
  plugins: ["@prettier/plugin-xml"]
463
483
  })] }
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
- }
484
+ }];
485
+ }
486
+ function markdownFormatter(options, prettierOptions, dprintOptions) {
487
+ if (!options.markdown) return [];
488
+ const formater = options.markdown === true ? "prettier" : options.markdown;
489
+ return [{
490
+ files: [GLOB_MARKDOWN],
491
+ languageOptions: { parser: parserPlain },
492
+ name: "rotki/formatter/markdown",
493
+ rules: { [`format/${formater}`]: ["error", formater === "prettier" ? mergePrettierOptions(prettierOptions, {
494
+ embeddedLanguageFormatting: "off",
495
+ parser: "markdown"
496
+ }) : {
497
+ ...dprintOptions,
498
+ language: "markdown"
499
+ }] }
500
+ }];
501
+ }
502
+ async function formatters(options = {}, stylistic = {}) {
503
+ const resolvedOptions = resolveFormattersOptions(options);
504
+ await ensurePackages(["eslint-plugin-format", resolvedOptions.xml ? "@prettier/plugin-xml" : void 0]);
505
+ const { indent: rawIndent, quotes, semi } = {
506
+ ...StylisticConfigDefaults,
507
+ ...stylistic
508
+ };
509
+ const indent = Array.isArray(rawIndent) ? rawIndent[0] : rawIndent;
510
+ const prettierOptions = buildPrettierOptions(indent, quotes, semi, resolvedOptions);
511
+ const dprintOptions = buildDprintOptions(indent, quotes, resolvedOptions);
512
+ const configs = [{
513
+ name: "rotki/formatter/setup",
514
+ plugins: { format: await interopDefault(import("eslint-plugin-format")) }
515
+ }];
516
+ configs.push(...cssFormatters(resolvedOptions, prettierOptions), ...htmlFormatter(resolvedOptions, prettierOptions), ...xmlFormatter(resolvedOptions, prettierOptions), ...markdownFormatter(resolvedOptions, prettierOptions, dprintOptions));
480
517
  return configs;
481
518
  }
482
519
  //#endregion
@@ -526,7 +563,7 @@ async function javascript(options = {}) {
526
563
  const { isInEditor = false, overrides = {} } = options;
527
564
  const customRules = {
528
565
  "arrow-body-style": ["error", "as-needed"],
529
- "complexity": ["warn", { max: 10 }],
566
+ "complexity": ["error", { max: 10 }],
530
567
  "max-lines": ["error", { max: 400 }]
531
568
  };
532
569
  return [{
@@ -764,6 +801,55 @@ async function javascript(options = {}) {
764
801
  }];
765
802
  }
766
803
  //#endregion
804
+ //#region src/configs/jsdoc.ts
805
+ async function jsdoc(options = {}) {
806
+ const { overrides = {}, stylistic = true, tsdoc = true } = options;
807
+ await ensurePackages([tsdoc ? "eslint-plugin-tsdoc" : void 0]);
808
+ const [pluginJsdoc, pluginTsdoc] = await Promise.all([interopDefault(import("eslint-plugin-jsdoc")), tsdoc ? interopDefault(import("eslint-plugin-tsdoc")) : void 0]);
809
+ const configs = [{
810
+ name: "rotki/jsdoc/setup",
811
+ plugins: { jsdoc: pluginJsdoc }
812
+ }, {
813
+ files: [GLOB_SRC, GLOB_VUE],
814
+ name: "rotki/jsdoc/rules",
815
+ rules: {
816
+ "jsdoc/check-access": "error",
817
+ "jsdoc/check-param-names": ["error", { checkDestructured: false }],
818
+ "jsdoc/check-property-names": "error",
819
+ "jsdoc/empty-tags": "error",
820
+ "jsdoc/escape-inline-tags": "error",
821
+ "jsdoc/implements-on-classes": "error",
822
+ "jsdoc/informative-docs": "error",
823
+ "jsdoc/no-bad-blocks": "error",
824
+ "jsdoc/no-blank-block-descriptions": "error",
825
+ "jsdoc/no-blank-blocks": "error",
826
+ "jsdoc/no-multi-asterisks": "error",
827
+ "jsdoc/no-types": "error",
828
+ "jsdoc/require-param-description": "error",
829
+ "jsdoc/require-param-name": "error",
830
+ "jsdoc/require-property": "error",
831
+ "jsdoc/require-property-description": "error",
832
+ "jsdoc/require-property-name": "error",
833
+ "jsdoc/require-returns-check": "error",
834
+ "jsdoc/require-returns-description": "error",
835
+ "jsdoc/require-yields-check": "error",
836
+ ...stylistic ? {
837
+ "jsdoc/check-alignment": "error",
838
+ "jsdoc/require-asterisk-prefix": "error",
839
+ "jsdoc/require-hyphen-before-param-description": "error"
840
+ } : {},
841
+ ...overrides
842
+ }
843
+ }];
844
+ if (tsdoc) configs.push({
845
+ files: [GLOB_TS, GLOB_VUE],
846
+ name: "rotki/jsdoc/tsdoc",
847
+ plugins: { tsdoc: pluginTsdoc },
848
+ rules: { "tsdoc/syntax": "error" }
849
+ });
850
+ return configs;
851
+ }
852
+ //#endregion
767
853
  //#region src/configs/jsonc.ts
768
854
  async function jsonc(options = {}) {
769
855
  const { files = [
@@ -1011,6 +1097,7 @@ async function pnpm(options) {
1011
1097
  plugins: { pnpm: pluginPnpm },
1012
1098
  rules: {
1013
1099
  "pnpm/yaml-enforce-settings": ["error", { settings: {
1100
+ minimumReleaseAgeExcludePrune: true,
1014
1101
  shellEmulator: true,
1015
1102
  trustPolicy: "no-downgrade"
1016
1103
  } }],
@@ -1028,65 +1115,190 @@ async function pnpm(options) {
1028
1115
  {
1029
1116
  order: [
1030
1117
  ...[
1031
- "cacheDir",
1118
+ "dedupeInjectedDeps",
1119
+ "disallowWorkspaceCycles",
1120
+ "failIfNoMatch",
1121
+ "ignoreWorkspaceCycles",
1122
+ "ignoreWorkspaceRootCheck",
1123
+ "includeWorkspaceRoot",
1124
+ "injectWorkspacePackages",
1125
+ "legacyDirFiltering",
1126
+ "linkWorkspacePackages",
1127
+ "preferWorkspacePackages",
1128
+ "saveWorkspaceProtocol",
1129
+ "sharedWorkspaceLockfile",
1130
+ "syncInjectedDepsAfterScripts"
1131
+ ],
1132
+ ...[
1032
1133
  "catalogMode",
1033
- "cleanupUnusedCatalogs",
1034
- "dedupeDirectDeps",
1035
- "deployAllFiles",
1036
- "enablePrePostScripts",
1037
- "engineStrict",
1134
+ "catalogPrune",
1135
+ "cleanupUnusedCatalogs"
1136
+ ],
1137
+ ...[
1138
+ "allowedDeprecatedVersions",
1139
+ "blockExoticSubdeps",
1140
+ "ignoredOptionalDependencies",
1141
+ "minimumReleaseAge",
1142
+ "minimumReleaseAgeIgnoreMissingTime",
1143
+ "minimumReleaseAgeStrict",
1144
+ "minimumReleaseAgeExcludePrune",
1145
+ "minimumReleaseAgeExclude",
1146
+ "registrySupportsTimeField",
1147
+ "resolutionMode",
1148
+ "supportedArchitectures",
1149
+ "trustLockfile",
1150
+ "trustPolicy",
1151
+ "trustPolicyIgnoreAfter",
1152
+ "trustPolicyExclude",
1153
+ "update"
1154
+ ],
1155
+ ...[
1156
+ "autoInstallPeers",
1157
+ "dedupePeerDependents",
1158
+ "dedupePeers",
1159
+ "peerDependencyRules",
1160
+ "resolvePeersFromWorkspaceRoot",
1161
+ "strictPeerDependencies"
1162
+ ],
1163
+ ...[
1164
+ "fetchMinSpeedKiBps",
1165
+ "fetchRetries",
1166
+ "fetchRetryFactor",
1167
+ "fetchRetryMaxtimeout",
1168
+ "fetchRetryMintimeout",
1169
+ "fetchTimeout",
1170
+ "fetchWarnTimeoutMs",
1171
+ "gitShallowHosts",
1172
+ "httpProxy",
1173
+ "httpsProxy",
1174
+ "localAddress",
1175
+ "maxsockets",
1176
+ "namedRegistries",
1177
+ "networkConcurrency",
1178
+ "noProxy",
1179
+ "registries",
1180
+ "registry",
1181
+ "strictSsl"
1182
+ ],
1183
+ ...[
1184
+ "dlxCacheMaxAge",
1185
+ "enableGlobalVirtualStore",
1186
+ "enableModulesDir",
1038
1187
  "extendNodePath",
1188
+ "modulesCacheMaxAge",
1189
+ "modulesDir",
1190
+ "nodeExperimentalPackageMap",
1191
+ "nodeLinker",
1192
+ "nodePackageMapType",
1193
+ "packageImportMethod",
1194
+ "preferSymlinkedExecutables",
1195
+ "symlink",
1196
+ "virtualStoreDir",
1197
+ "virtualStoreDirMaxLength",
1198
+ "virtualStoreOnly",
1199
+ "virtualStoreType"
1200
+ ],
1201
+ ...[
1039
1202
  "hoist",
1203
+ "hoistingLimits",
1040
1204
  "hoistPattern",
1041
1205
  "hoistWorkspacePackages",
1042
- "ignoreCompatibilityDb",
1206
+ "publicHoistPattern",
1207
+ "shamefullyHoist"
1208
+ ],
1209
+ ...[
1210
+ "frozenStore",
1211
+ "storeDir",
1212
+ "strictStorePkgContentCheck",
1213
+ "useRunningStoreServer",
1214
+ "verifyStoreIntegrity"
1215
+ ],
1216
+ ...[
1217
+ "gitBranchLockfile",
1218
+ "lockfile",
1219
+ "lockfileIncludeTarballUrl",
1220
+ "mergeGitBranchLockfilesBranchPattern",
1221
+ "peersSuffixMaxLength",
1222
+ "preferFrozenLockfile"
1223
+ ],
1224
+ ...[
1225
+ "childConcurrency",
1226
+ "dangerouslyAllowAllBuilds",
1227
+ "enablePrePostScripts",
1043
1228
  "ignoreDepScripts",
1044
1229
  "ignoreScripts",
1045
- "ignoreWorkspaceRootCheck",
1230
+ "nodeOptions",
1231
+ "requiredScripts",
1232
+ "scriptShell",
1233
+ "shellEmulator",
1234
+ "sideEffectsCache",
1235
+ "sideEffectsCacheReadonly",
1236
+ "strictDepBuilds",
1237
+ "unsafePerm",
1238
+ "verifyDepsBeforeRun"
1239
+ ],
1240
+ ...[
1046
1241
  "managePackageManagerVersions",
1047
- "minimumReleaseAge",
1048
- "minimumReleaseAgeExclude",
1049
- "modulesDir",
1050
- "nodeLinker",
1242
+ "nodeDownloadMirrors",
1051
1243
  "nodeVersion",
1052
- "optimisticRepeatInstall",
1053
1244
  "packageManagerStrict",
1054
1245
  "packageManagerStrictVersion",
1055
- "preferSymlinkedExecutables",
1056
- "preferWorkspacePackages",
1057
- "publicHoistPattern",
1058
- "registrySupportsTimeField",
1059
- "requiredScripts",
1060
- "resolutionMode",
1246
+ "pmOnFail",
1247
+ "runtimeOnFail"
1248
+ ],
1249
+ ...[
1250
+ "ci",
1251
+ "color",
1252
+ "engineStrict",
1253
+ "loglevel",
1254
+ "npmPath",
1255
+ "recursiveInstall",
1256
+ "updateNotifier",
1257
+ "useBetaCli",
1258
+ "useStderr"
1259
+ ],
1260
+ ...[
1261
+ "cacheDir",
1262
+ "globalBinDir",
1263
+ "globalDir",
1264
+ "globalPnpmfile",
1265
+ "globalShims",
1266
+ "ignorePnpmfile",
1267
+ "npmrcAuthFile",
1268
+ "pnpmfile",
1269
+ "stateDir"
1270
+ ],
1271
+ ...["audit", "versioning"],
1272
+ ...[
1273
+ "allowNonAppliedPatches",
1274
+ "dedupeDirectDeps",
1275
+ "deployAllFiles",
1276
+ "ignoreCompatibilityDb",
1277
+ "initAuthorEmail",
1278
+ "initAuthorName",
1279
+ "initAuthorUrl",
1280
+ "initLicense",
1281
+ "initVersion",
1282
+ "optimisticRepeatInstall",
1283
+ "saveExact",
1061
1284
  "savePrefix",
1062
- "scriptShell",
1063
- "shamefullyHoist",
1064
- "shellEmulator",
1065
- "stateDir",
1066
- "supportedArchitectures",
1067
- "symlink",
1068
- "tag",
1069
- "trustPolicy",
1070
- "trustPolicyExclude",
1071
- "updateNotifier"
1285
+ "tag"
1072
1286
  ],
1073
1287
  "packages",
1288
+ "packageConfigs",
1074
1289
  "overrides",
1290
+ "packageExtensions",
1075
1291
  "patchedDependencies",
1076
- "catalog",
1077
- "catalogs",
1292
+ "configDependencies",
1293
+ "allowBuilds",
1078
1294
  ...[
1079
- "allowedDeprecatedVersions",
1080
- "allowNonAppliedPatches",
1081
- "configDependencies",
1082
1295
  "ignoredBuiltDependencies",
1083
- "ignoredOptionalDependencies",
1084
1296
  "neverBuiltDependencies",
1085
1297
  "onlyBuiltDependencies",
1086
- "onlyBuiltDependenciesFile",
1087
- "packageExtensions",
1088
- "peerDependencyRules"
1089
- ]
1298
+ "onlyBuiltDependenciesFile"
1299
+ ],
1300
+ "catalog",
1301
+ "catalogs"
1090
1302
  ],
1091
1303
  pathPattern: "^$"
1092
1304
  },
@@ -1143,25 +1355,91 @@ async function rotkiPlugin(options = {}) {
1143
1355
  },
1144
1356
  name: "rotki/rotki/rules",
1145
1357
  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",
1358
+ "@rotki/composable-no-default-export": "error",
1359
+ "@rotki/composable-prefer-shallowref": "error",
1360
+ "@rotki/composable-require-cleanup": "error",
1361
+ "@rotki/composable-return-readonly": "error",
1362
+ "@rotki/composable-ssr-safety": "error",
1151
1363
  "@rotki/consistent-ref-type-annotation": ["error", { allowInference: true }],
1152
1364
  "@rotki/no-deprecated-classes": "error",
1153
1365
  "@rotki/no-deprecated-props": "error",
1154
1366
  "@rotki/no-dot-ts-imports": "error",
1367
+ "@rotki/no-redundant-flex-row": "error",
1368
+ "@rotki/no-shared-pinia": "error",
1155
1369
  "@rotki/no-unused-i18n-keys": ["error", {
1156
1370
  extensions: [".ts", ".vue"],
1157
1371
  ignoreKeys,
1158
1372
  src
1159
1373
  }],
1160
1374
  ...stylistic ? {
1161
- "@rotki/composable-input-flexibility": "warn",
1162
- "@rotki/composable-naming-convention": "warn",
1163
- "@rotki/require-jsdoc-on-composable-options": "warn"
1375
+ "@rotki/composable-input-flexibility": "error",
1376
+ "@rotki/composable-naming-convention": "error",
1377
+ "@rotki/require-jsdoc-on-composable-options": "error"
1378
+ } : {},
1379
+ ...overrides
1380
+ }
1381
+ }];
1382
+ }
1383
+ //#endregion
1384
+ //#region src/configs/slop.ts
1385
+ async function slop(options = {}) {
1386
+ const { cwd, inspection, jargon = true, maximumWords = 50, overrides = {} } = options;
1387
+ await ensurePackages(["eslint-plugin-slop"]);
1388
+ const [pluginSlop] = await Promise.all([interopDefault(import("eslint-plugin-slop"))]);
1389
+ const settings = {
1390
+ ...cwd ? { cwd } : {},
1391
+ ...inspection ? { inspection } : {}
1392
+ };
1393
+ return [{
1394
+ files: [GLOB_SRC, GLOB_VUE],
1395
+ name: "rotki/slop/rules",
1396
+ plugins: { slop: pluginSlop },
1397
+ ...Object.keys(settings).length > 0 ? { settings: { slop: settings } } : {},
1398
+ rules: {
1399
+ "slop/max-comment-length": ["error", {
1400
+ ignoreJSDoc: true,
1401
+ maximumWords
1402
+ }],
1403
+ "slop/no-chained-type-assertions": "error",
1404
+ "slop/no-em-dash": "error",
1405
+ "slop/no-trivial-type-aliases": "error",
1406
+ ...jargon ? { "slop/no-jargon": "error" } : {},
1407
+ ...overrides
1408
+ }
1409
+ }];
1410
+ }
1411
+ //#endregion
1412
+ //#region src/configs/sonarjs.ts
1413
+ async function sonarjs(options = {}) {
1414
+ const { cognitiveComplexity = false, overrides = {}, simplification = true } = options;
1415
+ await ensurePackages(["eslint-plugin-sonarjs"]);
1416
+ const [pluginSonarjs] = await Promise.all([interopDefault(import("eslint-plugin-sonarjs"))]);
1417
+ return [{
1418
+ files: [GLOB_SRC, GLOB_VUE],
1419
+ name: "rotki/sonarjs/rules",
1420
+ plugins: { sonarjs: pluginSonarjs },
1421
+ rules: {
1422
+ "sonarjs/no-all-duplicated-branches": "error",
1423
+ "sonarjs/no-commented-code": "error",
1424
+ "sonarjs/no-dead-store": "error",
1425
+ "sonarjs/no-element-overwrite": "error",
1426
+ "sonarjs/no-empty-collection": "error",
1427
+ "sonarjs/no-identical-conditions": "error",
1428
+ "sonarjs/no-identical-expressions": "error",
1429
+ "sonarjs/no-identical-functions": "error",
1430
+ "sonarjs/no-invariant-returns": "error",
1431
+ "sonarjs/no-unused-collection": "error",
1432
+ "sonarjs/no-use-of-empty-return-value": "error",
1433
+ ...simplification ? {
1434
+ "sonarjs/no-collapsible-if": "error",
1435
+ "sonarjs/no-duplicated-branches": "error",
1436
+ "sonarjs/no-gratuitous-expressions": "error",
1437
+ "sonarjs/no-inverted-boolean-check": "error",
1438
+ "sonarjs/no-redundant-boolean": "error",
1439
+ "sonarjs/no-redundant-jump": "error",
1440
+ "sonarjs/prefer-single-boolean-return": "error"
1164
1441
  } : {},
1442
+ ...cognitiveComplexity === false ? {} : { "sonarjs/cognitive-complexity": ["error", cognitiveComplexity] },
1165
1443
  ...overrides
1166
1444
  }
1167
1445
  }];
@@ -1210,6 +1488,7 @@ async function sortPackageJson() {
1210
1488
  "directories",
1211
1489
  "publishConfig",
1212
1490
  "scripts",
1491
+ "scripts-info",
1213
1492
  "peerDependencies",
1214
1493
  "peerDependenciesMeta",
1215
1494
  "optionalDependencies",
@@ -1466,24 +1745,86 @@ async function test(options = {}) {
1466
1745
  }
1467
1746
  //#endregion
1468
1747
  //#region src/configs/typescript.ts
1469
- async function typescript(options = {}) {
1748
+ const typeAwareCustom = {
1749
+ "@typescript-eslint/consistent-type-assertions": ["error", { assertionStyle: "never" }],
1750
+ "@typescript-eslint/naming-convention": [
1751
+ "error",
1752
+ {
1753
+ format: null,
1754
+ modifiers: ["destructured"],
1755
+ selector: "variable"
1756
+ },
1757
+ {
1758
+ format: ["camelCase"],
1759
+ leadingUnderscore: "allow",
1760
+ selector: "parameter"
1761
+ },
1762
+ {
1763
+ format: ["camelCase"],
1764
+ selector: "variable"
1765
+ },
1766
+ {
1767
+ format: [
1768
+ "camelCase",
1769
+ "UPPER_CASE",
1770
+ "PascalCase"
1771
+ ],
1772
+ modifiers: ["const"],
1773
+ selector: "variable"
1774
+ },
1775
+ {
1776
+ format: ["camelCase"],
1777
+ leadingUnderscore: "allow",
1778
+ modifiers: ["private"],
1779
+ selector: "memberLike"
1780
+ },
1781
+ {
1782
+ format: ["PascalCase"],
1783
+ selector: "typeLike"
1784
+ }
1785
+ ]
1786
+ };
1787
+ const customRules = {
1788
+ "@typescript-eslint/prefer-as-const": "error",
1789
+ "@typescript-eslint/prefer-literal-enum-member": ["warn", { allowBitwiseExpressions: true }],
1790
+ "max-lines": ["error", { max: 400 }]
1791
+ };
1792
+ function resolveTypeScriptFiles(options, componentExts) {
1793
+ return {
1794
+ files: options.files ?? [
1795
+ "**/*.?([cm])ts",
1796
+ "**/*.?([cm])tsx",
1797
+ ...componentExts.map((ext) => `**/*.${ext}`)
1798
+ ],
1799
+ filesTypeAware: options.filesTypeAware ?? ["**/*.?([cm])ts", "**/*.?([cm])tsx"],
1800
+ ignoresTypeAware: options.ignoresTypeAware ?? [`**/*.md/**`]
1801
+ };
1802
+ }
1803
+ function resolveTypeScriptOptions(options) {
1470
1804
  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",
1805
+ const tsconfigPath = options.tsconfigPath ? options.tsconfigPath : void 0;
1806
+ return {
1807
+ componentExts,
1808
+ isInEditor,
1809
+ isTypeAware: !!tsconfigPath,
1810
+ overrides,
1811
+ overridesTypeAware,
1812
+ parserOptions,
1813
+ tsconfigPath,
1814
+ type,
1815
+ ...resolveTypeScriptFiles(options, componentExts)
1816
+ };
1817
+ }
1818
+ function buildTypeAwareRules(isInEditor) {
1819
+ return {
1820
+ "@typescript-eslint/await-thenable": "error",
1821
+ "@typescript-eslint/consistent-type-exports": "error",
1482
1822
  "@typescript-eslint/dot-notation": ["error", { allowKeywords: true }],
1483
1823
  "@typescript-eslint/no-floating-promises": ["error", { ignoreIIFE: true }],
1484
1824
  "@typescript-eslint/no-for-in-array": "error",
1485
1825
  "@typescript-eslint/no-implied-eval": "error",
1486
- "@typescript-eslint/no-misused-promises": "warn",
1826
+ "@typescript-eslint/no-misused-promises": "error",
1827
+ "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
1487
1828
  "@typescript-eslint/no-unnecessary-type-assertion": "error",
1488
1829
  "@typescript-eslint/no-unsafe-argument": isInEditor ? "warn" : "off",
1489
1830
  "@typescript-eslint/no-unsafe-assignment": isInEditor ? "warn" : "off",
@@ -1491,6 +1832,9 @@ async function typescript(options = {}) {
1491
1832
  "@typescript-eslint/no-unsafe-member-access": isInEditor ? "warn" : "off",
1492
1833
  "@typescript-eslint/no-unsafe-return": isInEditor ? "warn" : "off",
1493
1834
  "@typescript-eslint/only-throw-error": "error",
1835
+ "@typescript-eslint/prefer-nullish-coalescing": "error",
1836
+ "@typescript-eslint/prefer-optional-chain": "error",
1837
+ "@typescript-eslint/prefer-readonly": "error",
1494
1838
  "@typescript-eslint/promise-function-async": "error",
1495
1839
  "@typescript-eslint/restrict-plus-operands": "error",
1496
1840
  "@typescript-eslint/restrict-template-expressions": "error",
@@ -1500,49 +1844,18 @@ async function typescript(options = {}) {
1500
1844
  "dot-notation": "off",
1501
1845
  "no-implied-eval": "off",
1502
1846
  "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 }]
1847
+ ...typeAwareCustom
1545
1848
  };
1849
+ }
1850
+ function buildLibRules(type) {
1851
+ return type === "lib" ? { "@typescript-eslint/explicit-function-return-type": ["error", {
1852
+ allowExpressions: true,
1853
+ allowHigherOrderFunctions: true,
1854
+ allowIIFEs: true
1855
+ }] } : {};
1856
+ }
1857
+ async function typescript(options = {}) {
1858
+ const { componentExts, files, filesTypeAware, ignoresTypeAware, isInEditor, isTypeAware, overrides, overridesTypeAware, parserOptions, tsconfigPath, type } = resolveTypeScriptOptions(options);
1546
1859
  const [pluginTs, parserTs] = await Promise.all([interopDefault(import("@typescript-eslint/eslint-plugin")), interopDefault(import("@typescript-eslint/parser"))]);
1547
1860
  function makeParser(typeAware, files, ignores) {
1548
1861
  return {
@@ -1614,11 +1927,7 @@ async function typescript(options = {}) {
1614
1927
  "no-redeclare": "off",
1615
1928
  "no-use-before-define": "off",
1616
1929
  "no-useless-constructor": "off",
1617
- ...type === "lib" ? { "@typescript-eslint/explicit-function-return-type": ["error", {
1618
- allowExpressions: true,
1619
- allowHigherOrderFunctions: true,
1620
- allowIIFEs: true
1621
- }] } : {},
1930
+ ...buildLibRules(type),
1622
1931
  ...customRules,
1623
1932
  ...overrides
1624
1933
  }
@@ -1628,7 +1937,7 @@ async function typescript(options = {}) {
1628
1937
  ignores: ignoresTypeAware,
1629
1938
  name: "rotki/typescript/rules-type-aware",
1630
1939
  rules: {
1631
- ...typeAwareRules,
1940
+ ...buildTypeAwareRules(isInEditor),
1632
1941
  ...overridesTypeAware
1633
1942
  }
1634
1943
  }] : []
@@ -1636,14 +1945,15 @@ async function typescript(options = {}) {
1636
1945
  }
1637
1946
  //#endregion
1638
1947
  //#region src/configs/unicorn.ts
1639
- const FILENAME_CASE_IGNORE = /^[A-Z]+\..*$/;
1948
+ const FILENAME_CASE_IGNORE = "^[A-Z]+\\..*$";
1640
1949
  async function unicorn(options = {}) {
1641
1950
  return [{
1951
+ files: [GLOB_SRC, GLOB_VUE],
1642
1952
  name: "rotki/unicorn/rules",
1643
1953
  plugins: { unicorn: pluginUnicorn },
1644
1954
  rules: { ...options.allRecommended ? pluginUnicorn.configs.recommended.rules : {
1645
1955
  "unicorn/catch-error-name": "error",
1646
- "unicorn/consistent-destructuring": "warn",
1956
+ "unicorn/consistent-destructuring": "error",
1647
1957
  "unicorn/custom-error-definition": "error",
1648
1958
  "unicorn/error-message": "error",
1649
1959
  "unicorn/escape-case": "error",
@@ -1658,6 +1968,7 @@ async function unicorn(options = {}) {
1658
1968
  "unicorn/new-for-builtins": "error",
1659
1969
  "unicorn/no-array-method-this-argument": "error",
1660
1970
  "unicorn/no-array-push-push": "error",
1971
+ "unicorn/no-barrel-files": "error",
1661
1972
  "unicorn/no-console-spaces": "error",
1662
1973
  "unicorn/no-for-loop": "error",
1663
1974
  "unicorn/no-hex-escape": "error",
@@ -1692,20 +2003,29 @@ async function unicorn(options = {}) {
1692
2003
  "unicorn/prefer-string-trim-start-end": "error",
1693
2004
  "unicorn/prefer-top-level-await": "error",
1694
2005
  "unicorn/prefer-type-error": "error",
2006
+ "unicorn/single-line-block-comment-style": ["error", "single-line"],
1695
2007
  "unicorn/throw-new-error": "error"
1696
2008
  } }
1697
- }, {
1698
- files: [".github/**/*.md"],
1699
- name: "rotki/unicorn/github-markdown",
1700
- rules: { "unicorn/filename-case": "off" }
1701
2009
  }];
1702
2010
  }
1703
2011
  //#endregion
1704
2012
  //#region src/configs/vue.ts
1705
- async function vue(options = {}) {
2013
+ function resolveVueOptions(options) {
1706
2014
  const { files = [GLOB_VUE], overrides = {}, stylistic = true, typescript } = options;
1707
2015
  const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1708
2016
  const { braceStyle = "stroustrup", indent = 2 } = typeof stylistic === "boolean" ? {} : stylistic;
2017
+ return {
2018
+ braceStyle,
2019
+ files,
2020
+ indent,
2021
+ overrides,
2022
+ sfcBlocks,
2023
+ stylistic,
2024
+ typescript
2025
+ };
2026
+ }
2027
+ async function vue(options = {}) {
2028
+ const { braceStyle, files, indent, overrides, sfcBlocks, stylistic, typescript } = resolveVueOptions(options);
1709
2029
  const [pluginVue, parserVue, processorVueBlocks] = await Promise.all([
1710
2030
  interopDefault(import("eslint-plugin-vue")),
1711
2031
  interopDefault(import("vue-eslint-parser")),
@@ -1713,10 +2033,11 @@ async function vue(options = {}) {
1713
2033
  ]);
1714
2034
  const customRules = {
1715
2035
  "max-lines": ["warn", { max: 800 }],
2036
+ "vue/block-lang": ["error", { script: { lang: "ts" } }],
1716
2037
  "vue/component-api-style": ["error", ["script-setup"]],
1717
2038
  "vue/define-emits-declaration": ["error", "type-literal"],
1718
2039
  "vue/define-props-declaration": ["error", "type-based"],
1719
- "vue/define-props-destructuring": "warn",
2040
+ "vue/define-props-destructuring": "error",
1720
2041
  "vue/first-attribute-linebreak": ["error", {
1721
2042
  multiline: "below",
1722
2043
  singleline: "ignore"
@@ -1731,14 +2052,14 @@ async function vue(options = {}) {
1731
2052
  math: "always",
1732
2053
  svg: "always"
1733
2054
  }],
1734
- "vue/max-props": ["warn", { maxProps: 6 }],
1735
- "vue/max-template-depth": ["warn", { maxDepth: 8 }],
2055
+ "vue/max-props": ["error", { maxProps: 8 }],
2056
+ "vue/max-template-depth": ["error", { maxDepth: 8 }],
1736
2057
  "vue/multiline-html-element-content-newline": ["error", {
1737
2058
  allowEmptyLines: false,
1738
2059
  ignores: ["pre", "textarea"],
1739
2060
  ignoreWhenEmpty: true
1740
2061
  }],
1741
- "vue/no-constant-condition": "warn",
2062
+ "vue/no-constant-condition": "error",
1742
2063
  "vue/no-deprecated-dollar-listeners-api": "error",
1743
2064
  "vue/no-deprecated-events-api": "error",
1744
2065
  "vue/no-deprecated-filter": "error",
@@ -1748,7 +2069,7 @@ async function vue(options = {}) {
1748
2069
  "vue/no-required-prop-with-default": ["error", { autofix: true }],
1749
2070
  "vue/no-static-inline-styles": ["error", { allowBinding: false }],
1750
2071
  "vue/no-unused-emit-declarations": "error",
1751
- "vue/no-unused-properties": ["warn", { groups: [
2072
+ "vue/no-unused-properties": ["error", { groups: [
1752
2073
  "props",
1753
2074
  "data",
1754
2075
  "computed",
@@ -1756,9 +2077,10 @@ async function vue(options = {}) {
1756
2077
  ] }],
1757
2078
  "vue/prefer-define-options": "error",
1758
2079
  "vue/prefer-import-from-vue": "error",
1759
- "vue/prefer-use-template-ref": "warn",
2080
+ "vue/prefer-true-attribute-shorthand": "error",
2081
+ "vue/prefer-use-template-ref": "error",
1760
2082
  "vue/require-explicit-emits": "error",
1761
- "vue/require-explicit-slots": "warn",
2083
+ "vue/require-explicit-slots": "error",
1762
2084
  "vue/require-expose": "error",
1763
2085
  "vue/require-macro-variable-name": ["error", {
1764
2086
  defineEmits: "emit",
@@ -1970,7 +2292,7 @@ async function vue(options = {}) {
1970
2292
  }
1971
2293
  //#endregion
1972
2294
  //#region src/configs/vue-i18n.ts
1973
- async function vueI18n(options = {}) {
2295
+ function resolveVueI18nOptions(options) {
1974
2296
  const { files = [GLOB_TS, GLOB_VUE], isInEditor = false, localesDirectory = "locales", noRawTextIgnores = {
1975
2297
  nodes: [
1976
2298
  "md-icon",
@@ -1984,6 +2306,18 @@ async function vueI18n(options = {}) {
1984
2306
  "USD"
1985
2307
  ]
1986
2308
  }, overrides = {}, src = "src", typescript } = options;
2309
+ return {
2310
+ files,
2311
+ isInEditor,
2312
+ localesDirectory,
2313
+ noRawTextIgnores,
2314
+ overrides,
2315
+ src,
2316
+ typescript
2317
+ };
2318
+ }
2319
+ async function vueI18n(options = {}) {
2320
+ const { files, isInEditor, localesDirectory, noRawTextIgnores, overrides, src, typescript } = resolveVueI18nOptions(options);
1987
2321
  const fileGlobs = files.map((x) => `**/${src}/${x}`);
1988
2322
  if (localesDirectory) fileGlobs.push(`**/${src}/${localesDirectory}/${GLOB_JSON}`, `**/${src}/${localesDirectory}/${GLOB_JSON5}`, `**/${src}/${localesDirectory}/${GLOB_YAML}`);
1989
2323
  const localeDir = path.resolve(path.join(process.cwd(), src, localesDirectory));
@@ -2035,10 +2369,19 @@ async function vueI18n(options = {}) {
2035
2369
  }
2036
2370
  //#endregion
2037
2371
  //#region src/configs/yaml.ts
2038
- async function yaml(options = {}) {
2372
+ function resolveYamlOptions(options) {
2039
2373
  const { files = [GLOB_YAML], overrides = {}, stylistic = true } = options;
2040
2374
  const { indent: rawIndent = 2, quotes = "single" } = typeof stylistic === "boolean" ? {} : stylistic;
2041
- const indent = Array.isArray(rawIndent) ? rawIndent[0] : rawIndent;
2375
+ return {
2376
+ files,
2377
+ indent: Array.isArray(rawIndent) ? rawIndent[0] : rawIndent,
2378
+ overrides,
2379
+ quotes,
2380
+ stylistic
2381
+ };
2382
+ }
2383
+ async function yaml(options = {}) {
2384
+ const { files, indent, overrides, quotes, stylistic } = resolveYamlOptions(options);
2042
2385
  const [pluginYaml, parserYaml] = await Promise.all([interopDefault(import("eslint-plugin-yml")), interopDefault(import("yaml-eslint-parser"))]);
2043
2386
  return [{
2044
2387
  name: "rotki/yaml/setup",
@@ -2065,6 +2408,11 @@ async function yaml(options = {}) {
2065
2408
  "yaml/flow-sequence-bracket-spacing": "error",
2066
2409
  "yaml/indent": ["error", typeof indent === "number" ? indent : 2],
2067
2410
  "yaml/key-spacing": "error",
2411
+ "yaml/no-multiple-empty-lines": ["error", {
2412
+ max: 1,
2413
+ maxBOF: 0,
2414
+ maxEOF: 0
2415
+ }],
2068
2416
  "yaml/no-tab-indent": "error",
2069
2417
  "yaml/quotes": ["error", {
2070
2418
  avoidEscape: true,
@@ -2100,24 +2448,49 @@ const defaultPluginRenaming = {
2100
2448
  "vitest": "test",
2101
2449
  "yml": "yaml"
2102
2450
  };
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;
2451
+ function resolveStylisticOptions(options, jsx) {
2452
+ if (options.stylistic === false) return false;
2453
+ const stylisticOptions = typeof options.stylistic === "object" ? options.stylistic : {};
2454
+ if (!("jsx" in stylisticOptions)) stylisticOptions.jsx = jsx;
2455
+ return stylisticOptions;
2456
+ }
2457
+ function resolveEnableFlags(options) {
2458
+ return {
2459
+ autoRenamePlugins: options.autoRenamePlugins ?? true,
2460
+ enableE18e: options.e18e ?? true,
2461
+ enableGitignore: options.gitignore ?? true,
2462
+ enablePerfectionist: !!(options.perfectionist ?? true),
2463
+ enablePnpm: !!(options.pnpm ?? findUpSync("pnpm-workspace.yaml")),
2464
+ enableRegexp: options.regexp ?? false,
2465
+ enableRotki: options.rotki,
2466
+ enableStorybook: options.storybook,
2467
+ enableUnicorn: options.unicorn ?? true,
2468
+ enableVueI18n: options.vueI18n
2469
+ };
2470
+ }
2471
+ function resolveIsInEditor(options) {
2108
2472
  let isInEditor = options.isInEditor;
2109
2473
  if (isInEditor === null) {
2110
2474
  isInEditor = isInEditorEnv();
2111
2475
  if (isInEditor) console.log("[@rotki/eslint-config] Detected running in editor, some rules are disabled.");
2112
2476
  }
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 = [];
2477
+ return !!isInEditor;
2478
+ }
2479
+ function resolveOptions(options) {
2480
+ const jsx = options.jsx ?? true;
2481
+ const enableVue = !!(options.vue ?? VuePackages.some((i) => isPackageExists(i)));
2482
+ return {
2483
+ ...resolveEnableFlags(options),
2484
+ componentExts: [...options.componentExts ?? [], ...enableVue ? ["vue"] : []],
2485
+ enableTypeScript: options.typescript ?? (isPackageExists("typescript") || isPackageExists("@typescript/native-preview")),
2486
+ enableVue,
2487
+ isInEditor: resolveIsInEditor(options),
2488
+ stylisticOptions: resolveStylisticOptions(options, jsx),
2489
+ typescriptOptions: resolveSubOptions(options, "typescript")
2490
+ };
2491
+ }
2492
+ function buildLanguageConfigs(configs, options, resolved) {
2493
+ const { enableE18e, enableGitignore, enablePerfectionist, enableUnicorn, isInEditor, stylisticOptions } = resolved;
2121
2494
  if (enableGitignore) {
2122
2495
  const gitignoreOptions = typeof enableGitignore !== "boolean" ? enableGitignore : { strict: false };
2123
2496
  configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
@@ -2125,7 +2498,6 @@ function rotki(options = {}, ...userConfigs) {
2125
2498
  ...gitignoreOptions
2126
2499
  })]));
2127
2500
  }
2128
- const typescriptOptions = resolveSubOptions(options, "typescript");
2129
2501
  configs.push(ignores(options.ignores), javascript({
2130
2502
  isInEditor,
2131
2503
  overrides: getOverrides(options, "javascript")
@@ -2140,7 +2512,24 @@ function rotki(options = {}, ...userConfigs) {
2140
2512
  isInEditor,
2141
2513
  type: options.type
2142
2514
  }));
2143
- if (enableVue) componentExts.push("vue");
2515
+ }
2516
+ function buildQualityConfigs(configs, options, resolved) {
2517
+ if (options.jsdoc ?? true) configs.push(jsdoc({
2518
+ ...resolveSubOptions(options, "jsdoc"),
2519
+ overrides: getOverrides(options, "jsdoc"),
2520
+ stylistic: !!resolved.stylisticOptions
2521
+ }));
2522
+ if (options.slop) configs.push(slop({
2523
+ ...resolveSubOptions(options, "slop"),
2524
+ overrides: getOverrides(options, "slop")
2525
+ }));
2526
+ if (options.sonarjs) configs.push(sonarjs({
2527
+ ...resolveSubOptions(options, "sonarjs"),
2528
+ overrides: getOverrides(options, "sonarjs")
2529
+ }));
2530
+ }
2531
+ function buildTypeScriptAndStyleConfigs(configs, options, resolved) {
2532
+ const { componentExts, enableRegexp, enableTypeScript, isInEditor, stylisticOptions, typescriptOptions } = resolved;
2144
2533
  if (enableTypeScript) configs.push(typescript({
2145
2534
  ...typescriptOptions,
2146
2535
  componentExts,
@@ -2157,6 +2546,9 @@ function rotki(options = {}, ...userConfigs) {
2157
2546
  isInEditor,
2158
2547
  overrides: getOverrides(options, "test")
2159
2548
  }));
2549
+ }
2550
+ function buildFrameworkConfigs(configs, options, resolved) {
2551
+ const { enableRotki, enableStorybook, enableTypeScript, enableVue, enableVueI18n, stylisticOptions } = resolved;
2160
2552
  if (enableVue) configs.push(vue({
2161
2553
  ...resolveSubOptions(options, "vue"),
2162
2554
  overrides: getOverrides(options, "vue"),
@@ -2175,19 +2567,19 @@ function rotki(options = {}, ...userConfigs) {
2175
2567
  typescript: !!enableTypeScript
2176
2568
  }));
2177
2569
  if (enableStorybook) configs.push(storybook({ overrides: getOverrides(options, "storybook") }));
2570
+ }
2571
+ function buildFileFormatConfigs(configs, options, resolved) {
2572
+ const { componentExts, enablePnpm, isInEditor, stylisticOptions } = resolved;
2178
2573
  if (options.jsonc ?? true) configs.push(jsonc({
2179
2574
  overrides: getOverrides(options, "jsonc"),
2180
2575
  stylistic: stylisticOptions
2181
2576
  }), 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
- }
2577
+ if (enablePnpm) configs.push(pnpm({
2578
+ isInEditor,
2579
+ json: options.jsonc !== false,
2580
+ yaml: options.yaml !== false,
2581
+ ...resolveSubOptions(options, "pnpm")
2582
+ }));
2191
2583
  if (options.yaml ?? true) configs.push(yaml({
2192
2584
  overrides: getOverrides(options, "yaml"),
2193
2585
  stylistic: stylisticOptions
@@ -2197,8 +2589,8 @@ function rotki(options = {}, ...userConfigs) {
2197
2589
  overrides: getOverrides(options, "markdown")
2198
2590
  }));
2199
2591
  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.");
2592
+ }
2593
+ function finalizeComposer(configs, options, resolved, userConfigs) {
2202
2594
  const fusedConfig = flatConfigProps.reduce((acc, key) => {
2203
2595
  if (key in options) acc[key] = options[key];
2204
2596
  return acc;
@@ -2207,14 +2599,29 @@ function rotki(options = {}, ...userConfigs) {
2207
2599
  let composer = new FlatConfigComposer();
2208
2600
  composer = composer.append(...configs, ...userConfigs);
2209
2601
  if (options.markdown ?? true) composer = composer.setDefaultIgnores((prev) => [...prev, GLOB_MARKDOWN]);
2210
- if (autoRenamePlugins) composer = composer.renamePlugins(defaultPluginRenaming);
2211
- if (isInEditor) composer = composer.disableRulesFix([
2602
+ if (resolved.autoRenamePlugins) composer = composer.renamePlugins(defaultPluginRenaming);
2603
+ if (resolved.isInEditor) composer = composer.disableRulesFix([
2212
2604
  "unused-imports/no-unused-imports",
2213
2605
  "test/no-only-tests",
2214
2606
  "prefer-const"
2215
2607
  ], { builtinRules: () => import(["eslint", "use-at-your-own-risk"].join("/")).then((r) => r.builtinRules) });
2216
2608
  return composer;
2217
2609
  }
2610
+ /**
2611
+ * Construct an array of ESLint flat config items.
2612
+ */
2613
+ function rotki(options = {}, ...userConfigs) {
2614
+ 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.");
2615
+ const resolved = resolveOptions(options);
2616
+ const configs = [];
2617
+ buildLanguageConfigs(configs, options, resolved);
2618
+ buildQualityConfigs(configs, options, resolved);
2619
+ buildTypeScriptAndStyleConfigs(configs, options, resolved);
2620
+ buildFrameworkConfigs(configs, options, resolved);
2621
+ buildFileFormatConfigs(configs, options, resolved);
2622
+ configs.push(disables());
2623
+ return finalizeComposer(configs, options, resolved, userConfigs);
2624
+ }
2218
2625
  function resolveSubOptions(options, key) {
2219
2626
  return typeof options[key] === "boolean" ? {} : options[key] || {};
2220
2627
  }
@@ -2228,11 +2635,14 @@ const CONFIG_PRESET_FULL_ON = {
2228
2635
  formatters: true,
2229
2636
  gitignore: true,
2230
2637
  imports: {},
2638
+ jsdoc: true,
2231
2639
  jsonc: true,
2232
2640
  jsx: true,
2233
2641
  markdown: true,
2234
2642
  pnpm: true,
2235
2643
  regexp: true,
2644
+ slop: true,
2645
+ sonarjs: true,
2236
2646
  stylistic: true,
2237
2647
  test: true,
2238
2648
  typescript: true,
@@ -2243,11 +2653,14 @@ const CONFIG_PRESET_FULL_ON = {
2243
2653
  const CONFIG_PRESET_FULL_OFF = {
2244
2654
  formatters: false,
2245
2655
  gitignore: false,
2656
+ jsdoc: false,
2246
2657
  jsonc: false,
2247
2658
  jsx: false,
2248
2659
  markdown: false,
2249
2660
  pnpm: false,
2250
2661
  regexp: false,
2662
+ slop: false,
2663
+ sonarjs: false,
2251
2664
  stylistic: false,
2252
2665
  test: false,
2253
2666
  typescript: false,
@@ -2259,4 +2672,4 @@ const CONFIG_PRESET_FULL_OFF = {
2259
2672
  //#region src/index.ts
2260
2673
  var src_default = rotki;
2261
2674
  //#endregion
2262
- export { CONFIG_PRESET_FULL_OFF, CONFIG_PRESET_FULL_ON, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, StylisticConfigDefaults, combine, comments, src_default as default, defaultPluginRenaming, disables, e18e, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsonc, markdown, node, parserPlain, perfectionist, pnpm, regexp, renamePluginInConfigs, renameRules, resolveSubOptions, rotki, rotkiPlugin, sortPackageJson, sortTsconfig, storybook, stylistic, test, toArray, typescript, unicorn, vue, vueI18n, yaml };
2675
+ export { CONFIG_PRESET_FULL_OFF, CONFIG_PRESET_FULL_ON, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, StylisticConfigDefaults, combine, comments, src_default as default, defaultPluginRenaming, disables, e18e, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsdoc, jsonc, markdown, node, parserPlain, perfectionist, pnpm, regexp, renamePluginInConfigs, renameRules, resolveSubOptions, rotki, rotkiPlugin, slop, sonarjs, sortPackageJson, sortTsconfig, storybook, stylistic, test, toArray, typescript, unicorn, vue, vueI18n, yaml };