@isentinel/eslint-config 0.10.0 → 1.0.0-beta.1

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
@@ -68,8 +68,8 @@ For example:
68
68
  ```json
69
69
  {
70
70
  "scripts": {
71
- "lint": "eslint .",
72
- "lint:fix": "eslint . --fix"
71
+ "lint": "eslint",
72
+ "lint:fix": "eslint --fix"
73
73
  }
74
74
  }
75
75
  ```
package/dist/cli.js CHANGED
@@ -19,7 +19,7 @@ init_esm_shims();
19
19
  // package.json
20
20
  var package_default = {
21
21
  name: "@isentinel/eslint-config",
22
- version: "0.10.0",
22
+ version: "1.0.0-beta.1",
23
23
  description: "iSentinel's ESLint config",
24
24
  keywords: [
25
25
  "eslint-config",
@@ -48,7 +48,7 @@ var package_default = {
48
48
  build: "nr typegen && tsup --clean --dts",
49
49
  "build:inspector": "pnpm build && npx @eslint/config-inspector build",
50
50
  dev: "npx @eslint/config-inspector --config eslint.config.ts",
51
- lint: "eslint .",
51
+ lint: "eslint",
52
52
  prepack: "nr build",
53
53
  prepare: "simple-git-hooks",
54
54
  release: "bumpp && pnpm publish --p",
@@ -69,6 +69,7 @@ var package_default = {
69
69
  "@cspell/eslint-plugin": "8.17.5",
70
70
  "@eslint-community/eslint-plugin-eslint-comments": "4.4.1",
71
71
  "@eslint/compat": "1.2.7",
72
+ "@eslint/markdown": "6.2.2",
72
73
  "@isentinel/dict-rbxts": "1.0.1",
73
74
  "@isentinel/dict-roblox": "1.0.3",
74
75
  "@shopify/eslint-plugin": "47.0.1",
@@ -77,7 +78,7 @@ var package_default = {
77
78
  "@typescript-eslint/parser": "8.25.0",
78
79
  ansis: "3.16.0",
79
80
  "eslint-config-flat-gitignore": "2.1.0",
80
- "eslint-config-prettier": "10.0.1",
81
+ "eslint-config-prettier": "10.0.2",
81
82
  "eslint-flat-config-utils": "2.0.1",
82
83
  "eslint-merge-processors": "2.0.0",
83
84
  "eslint-plugin-antfu": "3.1.0",
@@ -90,7 +91,6 @@ var package_default = {
90
91
  "eslint-plugin-import-x": "4.6.1",
91
92
  "eslint-plugin-jsdoc": "50.6.3",
92
93
  "eslint-plugin-jsonc": "2.19.1",
93
- "eslint-plugin-markdown": "5.1.0",
94
94
  "eslint-plugin-no-only-tests": "3.3.0",
95
95
  "eslint-plugin-package-json": "0.26.0",
96
96
  "eslint-plugin-perfectionist": "4.9.0",
@@ -134,7 +134,7 @@ var package_default = {
134
134
  "lint-staged": "15.4.3",
135
135
  rimraf: "6.0.1",
136
136
  "simple-git-hooks": "2.11.1",
137
- tsup: "8.3.6",
137
+ tsup: "8.4.0",
138
138
  typescript: "5.7.3"
139
139
  },
140
140
  peerDependencies: {
@@ -240,7 +240,7 @@ async function addTsconfigBuild() {
240
240
  }
241
241
  `;
242
242
  await fsp.writeFile(pathTsconfigBuild, tsconfigBuildContent, "utf-8");
243
- log.success(ansis.green(`Created tsconfig.build.json`));
243
+ log.success(ansis.green("Created tsconfig.build.json"));
244
244
  log.info(
245
245
  ansis.yellow(
246
246
  `You must add '"exclude": ["./eslint.config.ts"]' to your tsconfig.json. In the future, this will be done automatically.`
@@ -292,7 +292,7 @@ async function updateEslintFiles() {
292
292
  const pathFlatConfig = path2.join(cwd, configFileName);
293
293
  const eslintIgnores = [];
294
294
  if (fs2.existsSync(pathESLintIgnore)) {
295
- log2.step(ansis2.cyan(`Migrating existing .eslintignore`));
295
+ log2.step(ansis2.cyan("Migrating existing .eslintignore"));
296
296
  const content = await fsp2.readFile(pathESLintIgnore, "utf-8");
297
297
  const parsed = parse(content);
298
298
  const globs = parsed.globs();
@@ -358,7 +358,7 @@ async function updatePackageJson() {
358
358
  note2(`${ansis3.dim(addedPackages.join(", "))}`, "Added packages");
359
359
  }
360
360
  await fsp3.writeFile(pathPackageJSON, JSON.stringify(package_, null, 2));
361
- log3.success(ansis3.green(`Changes wrote to package.json`));
361
+ log3.success(ansis3.green("Changes wrote to package.json"));
362
362
  }
363
363
 
364
364
  // src/cli/stages/update-vscode-settings.ts
@@ -382,7 +382,7 @@ async function updateVscodeSettings(result) {
382
382
  if (!fs3.existsSync(settingsPath)) {
383
383
  await fsp4.writeFile(settingsPath, `{${vscodeSettingsString}}
384
384
  `, "utf-8");
385
- log4.success(ansis4.green(`Created .vscode/settings.json`));
385
+ log4.success(ansis4.green("Created .vscode/settings.json"));
386
386
  return;
387
387
  }
388
388
  let settingsContent = await fsp4.readFile(settingsPath, "utf8");
@@ -391,7 +391,7 @@ async function updateVscodeSettings(result) {
391
391
  settingsContent += `${vscodeSettingsString}}
392
392
  `;
393
393
  await fsp4.writeFile(settingsPath, settingsContent, "utf-8");
394
- log4.success(ansis4.green(`Updated .vscode/settings.json`));
394
+ log4.success(ansis4.green("Updated .vscode/settings.json"));
395
395
  }
396
396
 
397
397
  // src/cli/run.ts
@@ -399,7 +399,7 @@ async function run(options = {}) {
399
399
  const argumentSkipPrompt = !!process5.env.SKIP_PROMPT || options.yes;
400
400
  const argumentTemplate = ["react"];
401
401
  if (fs4.existsSync(path5.join(process5.cwd(), "eslint.config.js"))) {
402
- log5.warn(ansis5.yellow(`eslint.config.js already exists, migration wizard exited.`));
402
+ log5.warn(ansis5.yellow("eslint.config.js already exists, migration wizard exited."));
403
403
  return process5.exit(1);
404
404
  }
405
405
  let result = {
@@ -444,8 +444,8 @@ async function run(options = {}) {
444
444
  await updateEslintFiles();
445
445
  await updateVscodeSettings(result);
446
446
  await addTsconfigBuild();
447
- log5.success(ansis5.green(`Setup completed`));
448
- outro(`Now you can update the dependencies and run ${ansis5.blue("eslint . --fix")}
447
+ log5.success(ansis5.green("Setup completed"));
448
+ outro(`Now you can update the dependencies and run ${ansis5.blue("eslint --fix")}
449
449
  `);
450
450
  }
451
451
 
package/dist/index.d.ts CHANGED
@@ -1239,6 +1239,34 @@ interface RuleOptions {
1239
1239
  * @see https://eslint.org/docs/latest/rules/logical-assignment-operators
1240
1240
  */
1241
1241
  'logical-assignment-operators'?: Linter.RuleEntry<LogicalAssignmentOperators>
1242
+ /**
1243
+ * Require languages for fenced code blocks
1244
+ */
1245
+ 'markdownPlugin/fenced-code-language'?: Linter.RuleEntry<MarkdownPluginFencedCodeLanguage>
1246
+ /**
1247
+ * Enforce heading levels increment by one
1248
+ */
1249
+ 'markdownPlugin/heading-increment'?: Linter.RuleEntry<[]>
1250
+ /**
1251
+ * Disallow duplicate headings in the same document
1252
+ */
1253
+ 'markdownPlugin/no-duplicate-headings'?: Linter.RuleEntry<[]>
1254
+ /**
1255
+ * Disallow empty links
1256
+ */
1257
+ 'markdownPlugin/no-empty-links'?: Linter.RuleEntry<[]>
1258
+ /**
1259
+ * Disallow HTML tags
1260
+ */
1261
+ 'markdownPlugin/no-html'?: Linter.RuleEntry<MarkdownPluginNoHtml>
1262
+ /**
1263
+ * Disallow invalid label references
1264
+ */
1265
+ 'markdownPlugin/no-invalid-label-refs'?: Linter.RuleEntry<[]>
1266
+ /**
1267
+ * Disallow missing label references
1268
+ */
1269
+ 'markdownPlugin/no-missing-label-refs'?: Linter.RuleEntry<[]>
1242
1270
  /**
1243
1271
  * Enforce a maximum number of classes per file
1244
1272
  * @see https://eslint.org/docs/latest/rules/max-classes-per-file
@@ -8638,6 +8666,14 @@ type LinesBetweenClassMembers = []|[({
8638
8666
  type LogicalAssignmentOperators = (([]|["always"]|["always", {
8639
8667
  enforceForIfStatements?: boolean
8640
8668
  }] | ["never"]) & unknown[])
8669
+ // ----- markdownPlugin/fenced-code-language -----
8670
+ type MarkdownPluginFencedCodeLanguage = []|[{
8671
+ required?: string[]
8672
+ }]
8673
+ // ----- markdownPlugin/no-html -----
8674
+ type MarkdownPluginNoHtml = []|[{
8675
+ allowed?: string[]
8676
+ }]
8641
8677
  // ----- max-classes-per-file -----
8642
8678
  type MaxClassesPerFile = []|[(number | {
8643
8679
  ignoreExpressions?: boolean
@@ -14321,7 +14357,7 @@ type Yoda = []|[("always" | "never")]|[("always" | "never"), {
14321
14357
  onlyEquality?: boolean
14322
14358
  }]
14323
14359
  // Names of all the configs
14324
- type ConfigNames = 'style/eslint/comments' | 'style/formatters/setup' | 'style/ignores' | 'style/imports' | 'style/import-sort' | 'style/jsdoc' | 'style/jsonc/setup' | 'style/jsonc/rules' | 'style/markdown/setup' | 'style/markdown/processor' | 'style/markdown/parser' | 'style/markdown/disables' | 'style/package-json' | 'style/perfectionist' | 'style/prettier' | 'style/promise' | 'style/react:setup' | 'style/react:rules' | 'style/roblox' | 'style/shopify' | 'style/sonarjs' | 'style/sort-tsconfig' | 'style/spelling' | 'style/stylistic' | 'style/test/setup' | 'style/test/rules' | 'style/typescript:setup' | 'style/typescript:rules' | 'style/typescript:dts-overrides' | 'style/unicorn' | 'style/yaml:setup' | 'style/yaml:rules'
14360
+ type ConfigNames = 'style/eslint/comments' | 'style/formatters/setup' | 'style/ignores' | 'style/imports' | 'style/import-sort' | 'style/jsdoc' | 'style/jsonc/setup' | 'style/jsonc/rules' | 'style/markdown/setup' | 'style/markdown/processor' | 'style/markdown/parser' | 'style/markdown/disables' | 'style/package-json' | 'style/perfectionist' | 'style/prettier' | 'style/promise' | 'style/react/setup' | 'style/react/rules' | 'style/roblox' | 'style/shopify' | 'style/sonarjs' | 'style/sort-tsconfig' | 'style/spelling' | 'style/stylistic' | 'style/test/setup' | 'style/test/rules' | 'style/typescript/setup' | 'style/typescript/rules' | 'style/unicorn' | 'style/yaml:setup' | 'style/yaml/rules'
14325
14361
 
14326
14362
  type Awaitable<T> = Promise<T> | T;
14327
14363
  type Rules = RuleOptions;
@@ -14437,6 +14473,14 @@ interface OptionsOverrides {
14437
14473
  interface OptionsIsInEditor {
14438
14474
  isInEditor?: boolean;
14439
14475
  }
14476
+ interface JsDocOptions {
14477
+ /**
14478
+ * By default we have different rules enabled for different project types.
14479
+ * This option allows you to enable the package rules regardless of the
14480
+ * project type.
14481
+ */
14482
+ full?: boolean;
14483
+ }
14440
14484
  interface OptionsConfig extends OptionsComponentExtensions, OptionsProjectType {
14441
14485
  /**
14442
14486
  * Automatically rename plugins in the config.
@@ -14467,6 +14511,12 @@ interface OptionsConfig extends OptionsComponentExtensions, OptionsProjectType {
14467
14511
  * @default auto-detect based on the process.env
14468
14512
  */
14469
14513
  isInEditor?: boolean;
14514
+ /**
14515
+ * Enable JSDoc support.
14516
+ *
14517
+ * @default true
14518
+ */
14519
+ jsdoc?: boolean | JsDocOptions;
14470
14520
  /**
14471
14521
  * Enable JSONC support.
14472
14522
  *
@@ -14554,7 +14604,7 @@ interface OptionsConfig extends OptionsComponentExtensions, OptionsProjectType {
14554
14604
  yaml?: boolean | OptionsOverrides;
14555
14605
  }
14556
14606
 
14557
- declare function comments(): Promise<Array<TypedFlatConfigItem>>;
14607
+ declare function comments(options?: OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
14558
14608
 
14559
14609
  declare function disables(): Promise<Array<TypedFlatConfigItem>>;
14560
14610
 
@@ -14564,7 +14614,7 @@ declare function ignores(): Promise<Array<TypedFlatConfigItem>>;
14564
14614
 
14565
14615
  declare function imports(options?: OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
14566
14616
 
14567
- declare function jsdoc(options?: OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
14617
+ declare function jsdoc(options?: JsDocOptions & OptionsProjectType & OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
14568
14618
 
14569
14619
  declare function jsonc(options?: OptionsFiles & OptionsOverrides & OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
14570
14620
 
@@ -14587,11 +14637,11 @@ declare function prettier(options?: OptionsComponentExtensions & OptionsFiles &
14587
14637
 
14588
14638
  declare function promise(): Promise<Array<TypedFlatConfigItem>>;
14589
14639
 
14590
- declare function react(options?: OptionsFiles & OptionsTypeScriptWithTypes & ReactConfig): Promise<Array<TypedFlatConfigItem>>;
14640
+ declare function react(options?: OptionsFiles & OptionsStylistic & OptionsTypeScriptWithTypes & ReactConfig): Promise<Array<TypedFlatConfigItem>>;
14591
14641
 
14592
14642
  declare function roblox(options?: OptionsComponentExtensions & OptionsFiles & OptionsOverrides & OptionsTypeScriptParserOptions & OptionsTypeScriptWithTypes, formatLua?: boolean): Promise<Array<TypedFlatConfigItem>>;
14593
14643
 
14594
- declare function shopify(): Promise<Array<TypedFlatConfigItem>>;
14644
+ declare function shopify(options?: OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
14595
14645
 
14596
14646
  declare function sonarjs(): Promise<Array<TypedFlatConfigItem>>;
14597
14647
 
@@ -14611,9 +14661,9 @@ declare function stylistic(options?: StylisticConfig): Promise<Array<TypedFlatCo
14611
14661
 
14612
14662
  declare function toml(options?: OptionsFiles & OptionsOverrides & OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
14613
14663
 
14614
- declare function typescript(options?: OptionsComponentExtensions & OptionsFiles & OptionsIsInEditor & OptionsOverrides & OptionsTypeScriptParserOptions & OptionsTypeScriptWithTypes): Promise<Array<TypedFlatConfigItem>>;
14664
+ declare function typescript(options?: OptionsComponentExtensions & OptionsFiles & OptionsIsInEditor & OptionsOverrides & OptionsStylistic & OptionsTypeScriptParserOptions & OptionsTypeScriptWithTypes): Promise<Array<TypedFlatConfigItem>>;
14615
14665
 
14616
- declare function unicorn(): Promise<Array<TypedFlatConfigItem>>;
14666
+ declare function unicorn(options?: OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
14617
14667
 
14618
14668
  declare function yaml(options?: OptionsFiles & OptionsOverrides & OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
14619
14669
 
@@ -14748,4 +14798,4 @@ declare function getOverrides<K extends keyof OptionsConfig>(options: OptionsCon
14748
14798
  declare function isInEditorEnvironment(): boolean;
14749
14799
  declare function isInGitHooksOrLintStaged(): boolean;
14750
14800
 
14751
- export { type Awaitable, type ConfigNames, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_LUA, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_YAML, type OptionsComponentExtensions, type OptionsConfig, type OptionsFiles, type OptionsFormatters, type OptionsHasTypeScript, type OptionsIsInEditor, type OptionsOverrides, type OptionsProjectType, type OptionsStylistic, type OptionsTypeScriptParserOptions, type OptionsTypeScriptWithTypes, type OptionsTypescript, type PerfectionistConfig, type ReactConfig, type ResolvedOptions, type Rules, type SpellCheckConfig, type StylisticConfig, StylisticConfigDefaults, type TypedFlatConfigItem, combine, comments, style as default, defaultPluginRenaming, disables, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnvironment, isInGitHooksOrLintStaged, jsdoc, jsonc, markdown, packageJson, parserPlain, perfectionist, prettier, promise, react, renamePluginInConfigs, renameRules, resolveSubOptions, roblox, shopify, sonarjs, sortTsconfig, spelling, style, stylistic, toArray, toml, typescript, unicorn, yaml };
14801
+ export { type Awaitable, type ConfigNames, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_LUA, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_YAML, type JsDocOptions, type OptionsComponentExtensions, type OptionsConfig, type OptionsFiles, type OptionsFormatters, type OptionsHasTypeScript, type OptionsIsInEditor, type OptionsOverrides, type OptionsProjectType, type OptionsStylistic, type OptionsTypeScriptParserOptions, type OptionsTypeScriptWithTypes, type OptionsTypescript, type PerfectionistConfig, type ReactConfig, type ResolvedOptions, type Rules, type SpellCheckConfig, type StylisticConfig, StylisticConfigDefaults, type TypedFlatConfigItem, combine, comments, style as default, defaultPluginRenaming, disables, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnvironment, isInGitHooksOrLintStaged, jsdoc, jsonc, markdown, packageJson, parserPlain, perfectionist, prettier, promise, react, renamePluginInConfigs, renameRules, resolveSubOptions, roblox, shopify, sonarjs, sortTsconfig, spelling, style, stylistic, toArray, toml, typescript, unicorn, yaml };
package/dist/index.js CHANGED
@@ -901,7 +901,8 @@ import { default as default18 } from "eslint-plugin-unicorn";
901
901
  import { default as default19 } from "isentinel-eslint-plugin-roblox-ts";
902
902
 
903
903
  // src/configs/comments.ts
904
- async function comments() {
904
+ async function comments(options = {}) {
905
+ const { stylistic: stylistic2 = true } = options;
905
906
  return [
906
907
  {
907
908
  name: "style/eslint/comments",
@@ -924,8 +925,10 @@ async function comments() {
924
925
  ignore: ["eslint-enable"]
925
926
  }
926
927
  ],
927
- "no-inline-comments": "error",
928
- "style/multiline-comment-style": ["error", "separate-lines"]
928
+ ...stylistic2 ? {
929
+ "no-inline-comments": "error",
930
+ "style/multiline-comment-style": ["error", "separate-lines"]
931
+ } : {}
929
932
  }
930
933
  },
931
934
  {
@@ -974,6 +977,7 @@ async function disables() {
974
977
  rules: {
975
978
  "eslint-comments/no-unlimited-disable": "off",
976
979
  "import/no-duplicates": "off",
980
+ "max-lines": "off",
977
981
  "no-restricted-syntax": "off",
978
982
  "unused-imports/no-unused-vars": "off"
979
983
  }
@@ -1120,14 +1124,14 @@ var StylisticConfigDefaults = {
1120
1124
  semi: true
1121
1125
  };
1122
1126
  async function stylistic(options = {}) {
1123
- const { indent, jsx, quotes, semi } = {
1127
+ const { indent, jsx: jsx2, quotes, semi } = {
1124
1128
  ...StylisticConfigDefaults,
1125
1129
  ...options
1126
1130
  };
1127
1131
  const pluginStylistic = await interopDefault(import("@stylistic/eslint-plugin"));
1128
1132
  const config = pluginStylistic.configs.customize({
1129
1133
  indent,
1130
- jsx,
1134
+ jsx: jsx2,
1131
1135
  pluginName: "style",
1132
1136
  quotes,
1133
1137
  semi
@@ -1136,9 +1140,9 @@ async function stylistic(options = {}) {
1136
1140
  {
1137
1141
  name: "style/stylistic",
1138
1142
  plugins: {
1139
- antfu: default6,
1143
+ "antfu": default6,
1140
1144
  "arrow-style": default7,
1141
- style: pluginStylistic
1145
+ "style": pluginStylistic
1142
1146
  },
1143
1147
  rules: {
1144
1148
  ...config.rules,
@@ -1153,7 +1157,7 @@ async function stylistic(options = {}) {
1153
1157
  }
1154
1158
  ],
1155
1159
  "arrow-style/no-export-default-arrow": "warn",
1156
- curly: ["error", "all"],
1160
+ "curly": ["error", "all"],
1157
1161
  "style/lines-between-class-members": [
1158
1162
  "error",
1159
1163
  {
@@ -1184,7 +1188,14 @@ async function stylistic(options = {}) {
1184
1188
  prev: ["do"]
1185
1189
  }
1186
1190
  ],
1187
- "style/quotes": ["error", "double"],
1191
+ "style/quotes": [
1192
+ "error",
1193
+ "double",
1194
+ {
1195
+ allowTemplateLiterals: false,
1196
+ avoidEscape: true
1197
+ }
1198
+ ],
1188
1199
  "style/spaced-comment": ["error", "always", { markers: ["!native", "!optimize"] }]
1189
1200
  }
1190
1201
  }
@@ -1388,7 +1399,7 @@ async function imports(options = {}) {
1388
1399
  } : {}
1389
1400
  }
1390
1401
  },
1391
- {
1402
+ stylistic2 ? {
1392
1403
  languageOptions: {
1393
1404
  parserOptions: {
1394
1405
  sourceType: "script"
@@ -1407,14 +1418,15 @@ async function imports(options = {}) {
1407
1418
  }
1408
1419
  ]
1409
1420
  }
1410
- }
1421
+ } : {}
1411
1422
  ];
1412
1423
  }
1413
1424
 
1414
1425
  // src/configs/jsdoc.ts
1415
1426
  init_esm_shims();
1416
1427
  async function jsdoc(options = {}) {
1417
- const { stylistic: stylistic2 = true } = options;
1428
+ const { full = "false", stylistic: stylistic2 = true, type = "game" } = options;
1429
+ const isPackage = type === "package" || full;
1418
1430
  return [
1419
1431
  {
1420
1432
  name: "style/jsdoc",
@@ -1426,40 +1438,42 @@ async function jsdoc(options = {}) {
1426
1438
  "jsdoc/check-param-names": ["warn", { checkDestructured: false }],
1427
1439
  "jsdoc/check-property-names": "warn",
1428
1440
  "jsdoc/check-types": "warn",
1429
- "jsdoc/convert-to-jsdoc-comments": "warn",
1430
1441
  "jsdoc/empty-tags": "warn",
1431
1442
  "jsdoc/implements-on-classes": "warn",
1432
1443
  "jsdoc/informative-docs": "warn",
1433
- "jsdoc/no-blank-block-descriptions": "warn",
1434
- "jsdoc/no-blank-blocks": "warn",
1435
1444
  "jsdoc/no-defaults": "warn",
1436
- "jsdoc/no-multi-asterisks": "warn",
1437
1445
  "jsdoc/no-types": "warn",
1438
- "jsdoc/require-asterisk-prefix": "warn",
1439
1446
  "jsdoc/require-description": [
1440
1447
  "warn",
1441
1448
  { exemptedBy: ["hidden, ignore", "inheritdoc", "client", "server", "see"] }
1442
1449
  ],
1443
1450
  "jsdoc/require-description-complete-sentence": "warn",
1444
- "jsdoc/require-hyphen-before-param-description": "warn",
1445
- "jsdoc/require-param": [
1446
- "warn",
1447
- { checkDestructured: false, exemptedBy: ["ignore"] }
1448
- ],
1449
1451
  "jsdoc/require-param-description": "warn",
1450
1452
  "jsdoc/require-param-name": "warn",
1451
1453
  "jsdoc/require-property": "warn",
1452
1454
  "jsdoc/require-property-description": "warn",
1453
1455
  "jsdoc/require-property-name": "warn",
1454
- "jsdoc/require-returns": ["warn", { exemptedBy: ["hidden"] }],
1455
1456
  "jsdoc/require-returns-check": "warn",
1456
1457
  "jsdoc/require-returns-description": "warn",
1457
- "jsdoc/require-template": "warn",
1458
1458
  "jsdoc/require-yields-check": "warn",
1459
1459
  "jsdoc/sort-tags": "off",
1460
+ ...isPackage ? {
1461
+ "jsdoc/require-param": [
1462
+ "warn",
1463
+ { checkDestructured: false, exemptedBy: ["ignore"] }
1464
+ ],
1465
+ "jsdoc/require-returns": ["warn", { exemptedBy: ["hidden"] }],
1466
+ "jsdoc/require-template": "warn"
1467
+ } : {},
1460
1468
  ...stylistic2 ? {
1461
1469
  "jsdoc/check-alignment": "warn",
1462
- "jsdoc/multiline-blocks": "warn"
1470
+ "jsdoc/convert-to-jsdoc-comments": "warn",
1471
+ "jsdoc/multiline-blocks": "warn",
1472
+ "jsdoc/no-blank-block-descriptions": "warn",
1473
+ "jsdoc/no-blank-blocks": "warn",
1474
+ "jsdoc/no-multi-asterisks": "warn",
1475
+ "jsdoc/require-asterisk-prefix": "warn",
1476
+ "jsdoc/require-hyphen-before-param-description": "warn"
1463
1477
  } : {}
1464
1478
  }
1465
1479
  }
@@ -1554,7 +1568,7 @@ async function markdown(options = {}) {
1554
1568
  files = [GLOB_MARKDOWN],
1555
1569
  overrides = {}
1556
1570
  } = options;
1557
- const markdownPlugin = await interopDefault(import("eslint-plugin-markdown"));
1571
+ const markdownPlugin = await interopDefault(import("@eslint/markdown"));
1558
1572
  return [
1559
1573
  {
1560
1574
  name: "style/markdown/setup",
@@ -1592,6 +1606,7 @@ async function markdown(options = {}) {
1592
1606
  },
1593
1607
  name: "style/markdown/disables",
1594
1608
  rules: {
1609
+ "antfu/no-top-level-await": "off",
1595
1610
  "import/newline-after-import": "off",
1596
1611
  "no-alert": "off",
1597
1612
  "no-console": "off",
@@ -1800,6 +1815,7 @@ async function prettier(options) {
1800
1815
  jsdocPrintWidth: 80,
1801
1816
  plugins: [require2.resolve("prettier-plugin-jsdoc")],
1802
1817
  printWidth: 100,
1818
+ quoteProps: "consistent",
1803
1819
  semi: true,
1804
1820
  singleQuote: false,
1805
1821
  tabWidth: 4,
@@ -1808,6 +1824,11 @@ async function prettier(options) {
1808
1824
  useTabs: true,
1809
1825
  ...prettierOptions
1810
1826
  };
1827
+ const rulesToIgnore = ["curly", "style/quotes"];
1828
+ const rules = renameRules(default5.rules, defaultPluginRenaming);
1829
+ for (const rule of rulesToIgnore) {
1830
+ delete rules[rule];
1831
+ }
1811
1832
  return [
1812
1833
  {
1813
1834
  files,
@@ -1816,9 +1837,8 @@ async function prettier(options) {
1816
1837
  format: default11
1817
1838
  },
1818
1839
  rules: {
1819
- ...default5.rules,
1840
+ ...rules,
1820
1841
  "arrow-body-style": "off",
1821
- curly: ["error", "all"],
1822
1842
  "format/prettier": [
1823
1843
  "error",
1824
1844
  {
@@ -1826,96 +1846,7 @@ async function prettier(options) {
1826
1846
  parser: "typescript"
1827
1847
  }
1828
1848
  ],
1829
- "no-unexpected-multiline": "off",
1830
- "prefer-arrow-callback": "off",
1831
- "standard/array-bracket-even-spacing": "off",
1832
- "standard/computed-property-even-spacing": "off",
1833
- "standard/object-curly-even-spacing": "off",
1834
- "style/array-bracket-newline": "off",
1835
- "style/array-bracket-spacing": "off",
1836
- "style/array-element-newline": "off",
1837
- "style/arrow-parens": "off",
1838
- "style/arrow-spacing": "off",
1839
- "style/block-spacing": "off",
1840
- "style/brace-style": "off",
1841
- "style/comma-dangle": "off",
1842
- "style/comma-spacing": "off",
1843
- "style/comma-style": "off",
1844
- "style/computed-property-spacing": "off",
1845
- "style/dot-location": "off",
1846
- "style/eol-last": "off",
1847
- "style/func-call-spacing": "off",
1848
- "style/function-call-argument-newline": "off",
1849
- "style/function-paren-newline": "off",
1850
- "style/generator-star-spacing": "off",
1851
- "style/implicit-arrow-linebreak": "off",
1852
- "style/indent": "off",
1853
- "style/indent-binary-ops": "off",
1854
- "style/jsx-child-element-spacing": "off",
1855
- "style/jsx-closing-bracket-location": "off",
1856
- "style/jsx-closing-tag-location": "off",
1857
- "style/jsx-curly-newline": "off",
1858
- "style/jsx-curly-spacing": "off",
1859
- "style/jsx-equals-spacing": "off",
1860
- "style/jsx-first-prop-new-line": "off",
1861
- "style/jsx-indent": "off",
1862
- "style/jsx-indent-props": "off",
1863
- "style/jsx-max-props-per-line": "off",
1864
- "style/jsx-newline": "off",
1865
- "style/jsx-one-expression-per-line": "off",
1866
- "style/jsx-props-no-multi-spaces": "off",
1867
- "style/jsx-quotes": "off",
1868
- "style/jsx-tag-spacing": "off",
1869
- "style/jsx-wrap-multilines": "off",
1870
- "style/key-spacing": "off",
1871
- "style/keyword-spacing": "off",
1872
- "style/linebreak-style": "off",
1873
- "style/lines-around-comment": "off",
1874
- "style/max-len": "off",
1875
- "style/max-statements-per-line": "off",
1876
- "style/member-delimiter-style": "off",
1877
- "style/multiline-ternary": "off",
1878
- "style/new-parens": "off",
1879
- "style/newline-per-chained-call": "off",
1880
- "style/no-confusing-arrow": "off",
1881
- "style/no-extra-parens": "off",
1882
- "style/no-extra-semi": "off",
1883
- "style/no-floating-decimal": "off",
1884
- "style/no-mixed-operators": "off",
1885
- "style/no-mixed-spaces-and-tabs": "off",
1886
- "style/no-multi-spaces": "off",
1887
- "style/no-multiple-empty-lines": "off",
1888
- "style/no-tabs": "off",
1889
- "style/no-trailing-spaces": "off",
1890
- "style/no-whitespace-before-property": "off",
1891
- "style/nonblock-statement-body-position": "off",
1892
- "style/object-curly-newline": "off",
1893
- "style/object-curly-spacing": "off",
1894
- "style/object-property-newline": "off",
1895
- "style/one-var-declaration-per-line": "off",
1896
- "style/operator-linebreak": "off",
1897
- "style/padded-blocks": "off",
1898
- "style/quote-props": "off",
1899
- "style/quotes": "off",
1900
- "style/rest-spread-spacing": "off",
1901
- "style/semi": "off",
1902
- "style/semi-spacing": "off",
1903
- "style/semi-style": "off",
1904
- "style/space-before-blocks": "off",
1905
- "style/space-before-function-paren": "off",
1906
- "style/space-in-parens": "off",
1907
- "style/space-infix-ops": "off",
1908
- "style/space-unary-ops": "off",
1909
- "style/switch-colon-spacing": "off",
1910
- "style/template-curly-spacing": "off",
1911
- "style/template-tag-spacing": "off",
1912
- "style/type-annotation-spacing": "off",
1913
- "style/wrap-iife": "off",
1914
- "style/wrap-regex": "off",
1915
- "style/yield-star-spacing": "off",
1916
- "unicorn/empty-brace-spaces": "off",
1917
- "unicorn/number-literal-case": "off",
1918
- "unicorn/template-indent": "off"
1849
+ "prefer-arrow-callback": "off"
1919
1850
  }
1920
1851
  }
1921
1852
  ];
@@ -1970,7 +1901,8 @@ async function react(options = {}) {
1970
1901
  files = [GLOB_TS, GLOB_TSX],
1971
1902
  importSource,
1972
1903
  jsxPragma,
1973
- overrides = {}
1904
+ overrides = {},
1905
+ stylistic: stylistic2 = true
1974
1906
  } = options;
1975
1907
  await ensurePackages(["@eslint-react/eslint-plugin", "eslint-plugin-react-roblox-hooks"]);
1976
1908
  const [pluginReact, pluginReactHooks, pluginStylistic, parserTs, pluginTs] = await Promise.all([
@@ -1985,15 +1917,15 @@ async function react(options = {}) {
1985
1917
  const isTypeAware = !!tsconfigPath;
1986
1918
  return [
1987
1919
  {
1988
- name: "style/react:setup",
1920
+ name: "style/react/setup",
1989
1921
  plugins: {
1990
- react: plugins["@eslint-react"],
1922
+ "react": plugins["@eslint-react"],
1991
1923
  "react-hooks-extra": plugins["@eslint-react/hooks-extra"],
1992
1924
  "react-hooks-roblox": fixupPluginRules(pluginReactHooks),
1993
1925
  "react-naming-convention": plugins["@eslint-react/naming-convention"],
1994
- style: pluginStylistic,
1995
- ts: pluginTs,
1996
- unicorn: default18
1926
+ "style": pluginStylistic,
1927
+ "ts": pluginTs,
1928
+ "unicorn": default18
1997
1929
  }
1998
1930
  },
1999
1931
  {
@@ -2008,7 +1940,7 @@ async function react(options = {}) {
2008
1940
  },
2009
1941
  sourceType: "module"
2010
1942
  },
2011
- name: "style/react:rules",
1943
+ name: "style/react/rules",
2012
1944
  rules: {
2013
1945
  // recommended rules from @eslint-react/hooks-extra
2014
1946
  // react-lua does not seem to fully support the patterns that this rule enforces.
@@ -2059,30 +1991,33 @@ async function react(options = {}) {
2059
1991
  "react/no-unstable-default-props": "off",
2060
1992
  "react/no-unused-class-component-members": "warn",
2061
1993
  "react/no-unused-state": "warn",
2062
- "react/no-useless-fragment": "warn",
2063
- "react/prefer-destructuring-assignment": "warn",
2064
1994
  "react/prefer-read-only-props": "error",
2065
1995
  "react/prefer-shorthand-boolean": "off",
2066
- "react/prefer-shorthand-fragment": "warn",
2067
- "style/jsx-curly-brace-presence": [
2068
- "error",
2069
- {
2070
- children: "never",
2071
- propElementValues: "always",
2072
- props: "never"
2073
- }
2074
- ],
2075
- "style/jsx-newline": "error",
2076
- "style/jsx-self-closing-comp": "error",
2077
- "style/jsx-sort-props": [
2078
- "error",
2079
- {
2080
- callbacksLast: true,
2081
- ignoreCase: true,
2082
- reservedFirst: true,
2083
- shorthandFirst: true
2084
- }
2085
- ],
1996
+ ...stylistic2 ? {
1997
+ "one-var": "off",
1998
+ "react/no-useless-fragment": "warn",
1999
+ "react/prefer-destructuring-assignment": "warn",
2000
+ "react/prefer-shorthand-fragment": "warn",
2001
+ "style/jsx-curly-brace-presence": [
2002
+ "error",
2003
+ {
2004
+ children: "never",
2005
+ propElementValues: "always",
2006
+ props: "never"
2007
+ }
2008
+ ],
2009
+ "style/jsx-newline": "error",
2010
+ "style/jsx-self-closing-comp": "error",
2011
+ "style/jsx-sort-props": [
2012
+ "error",
2013
+ {
2014
+ callbacksLast: true,
2015
+ ignoreCase: true,
2016
+ reservedFirst: true,
2017
+ shorthandFirst: true
2018
+ }
2019
+ ]
2020
+ } : {},
2086
2021
  ...isTypeAware ? {
2087
2022
  "react/no-leaked-conditional-rendering": "warn"
2088
2023
  } : {},
@@ -2189,7 +2124,8 @@ async function roblox(options = {}, formatLua = true) {
2189
2124
 
2190
2125
  // src/configs/shopify.ts
2191
2126
  init_esm_shims();
2192
- async function shopify() {
2127
+ async function shopify(options = {}) {
2128
+ const { stylistic: stylistic2 = true } = options;
2193
2129
  return [
2194
2130
  {
2195
2131
  name: "style/shopify",
@@ -2199,11 +2135,13 @@ async function shopify() {
2199
2135
  rules: {
2200
2136
  "shopify/prefer-class-properties": "error",
2201
2137
  "shopify/prefer-early-return": ["error", { maximumStatements: 1 }],
2202
- "shopify/prefer-module-scope-constants": "error",
2203
2138
  "shopify/react-hooks-strict-return": "error",
2204
2139
  "shopify/strict-component-boundaries": "error",
2205
- "shopify/typescript-prefer-pascal-case-enums": "error",
2206
- "shopify/typescript-prefer-singular-enums": "error"
2140
+ ...stylistic2 ? {
2141
+ "shopify/prefer-module-scope-constants": "error",
2142
+ "shopify/typescript-prefer-pascal-case-enums": "error",
2143
+ "shopify/typescript-prefer-singular-enums": "error"
2144
+ } : {}
2207
2145
  },
2208
2146
  // Shopify has a dependency on 'eslint-plugin-react' so we need to
2209
2147
  // set the react version to avoid the warning.
@@ -2414,7 +2352,7 @@ async function spelling(options = {}) {
2414
2352
  files,
2415
2353
  name: "style/spelling",
2416
2354
  plugins: {
2417
- ["@cspell"]: default2
2355
+ "@cspell": default2
2418
2356
  },
2419
2357
  rules: {
2420
2358
  "@cspell/spellchecker": [
@@ -2477,7 +2415,6 @@ async function toml(options = {}) {
2477
2415
  "toml/precision-of-fractional-seconds": "error",
2478
2416
  "toml/precision-of-integer": "error",
2479
2417
  "toml/tables-order": "error",
2480
- "toml/vue-custom-block/no-parsing-error": "error",
2481
2418
  ...stylistic2 ? {
2482
2419
  "toml/array-bracket-newline": "error",
2483
2420
  "toml/array-bracket-spacing": "error",
@@ -2505,7 +2442,8 @@ async function typescript(options = {}) {
2505
2442
  componentExts: componentExtensions = [],
2506
2443
  isInEditor = false,
2507
2444
  overrides = {},
2508
- parserOptions = {}
2445
+ parserOptions = {},
2446
+ stylistic: stylistic2 = true
2509
2447
  } = options;
2510
2448
  const files = options.files ?? [
2511
2449
  GLOB_SRC,
@@ -2559,8 +2497,10 @@ async function typescript(options = {}) {
2559
2497
  "ts/no-unsafe-argument": "error",
2560
2498
  "ts/no-unsafe-assignment": "error",
2561
2499
  "ts/no-unsafe-call": "error",
2500
+ "ts/no-unsafe-enum-comparison": "error",
2562
2501
  "ts/no-unsafe-member-access": "error",
2563
2502
  "ts/no-unsafe-return": "error",
2503
+ "ts/no-unsafe-unary-minus": "error",
2564
2504
  "ts/non-nullable-type-assertion-style": "error",
2565
2505
  "ts/prefer-destructuring": "error",
2566
2506
  "ts/prefer-find": "error",
@@ -2576,7 +2516,8 @@ async function typescript(options = {}) {
2576
2516
  "ts/return-await": "error",
2577
2517
  "ts/strict-boolean-expressions": "error",
2578
2518
  "ts/switch-exhaustiveness-check": "error",
2579
- "ts/unbound-method": "error"
2519
+ "ts/unbound-method": "error",
2520
+ "ts/use-unknown-in-catch-callback-variable": "error"
2580
2521
  };
2581
2522
  const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
2582
2523
  const [pluginTs, parserTs] = await Promise.all([
@@ -2587,12 +2528,12 @@ async function typescript(options = {}) {
2587
2528
  {
2588
2529
  // Install the plugins without globs, so they can be configured
2589
2530
  // separately.
2590
- name: "style/typescript:setup",
2531
+ name: "style/typescript/setup",
2591
2532
  plugins: {
2592
- antfu: default6,
2533
+ "antfu": default6,
2593
2534
  "better-max-params": default8,
2594
- ["de-morgan"]: default10,
2595
- ts: pluginTs
2535
+ "de-morgan": default10,
2536
+ "ts": pluginTs
2596
2537
  }
2597
2538
  },
2598
2539
  {
@@ -2602,7 +2543,6 @@ async function typescript(options = {}) {
2602
2543
  parserOptions: {
2603
2544
  ecmaVersion: 2018,
2604
2545
  extraFileExtensions: componentExtensions.map((extension) => `.${extension}`),
2605
- jsx: true,
2606
2546
  sourceType: "module",
2607
2547
  useJSXTextNode: true,
2608
2548
  ...tsconfigPath ? {
@@ -2612,7 +2552,7 @@ async function typescript(options = {}) {
2612
2552
  ...parserOptions
2613
2553
  }
2614
2554
  },
2615
- name: "style/typescript:rules",
2555
+ name: "style/typescript/rules",
2616
2556
  rules: {
2617
2557
  ...renameRules(pluginTs.configs["eslint-recommended"].overrides?.[0].rules ?? {}, {
2618
2558
  "@typescript-eslint": "ts"
@@ -2631,57 +2571,55 @@ async function typescript(options = {}) {
2631
2571
  func: 4
2632
2572
  }
2633
2573
  ],
2634
- camelcase: "error",
2635
2574
  "de-morgan/no-negated-conjunction": "error",
2636
2575
  "de-morgan/no-negated-disjunction": "error",
2637
- eqeqeq: "error",
2638
- "id-length": [
2639
- "error",
2640
- {
2641
- exceptions: ["_", "x", "y", "z", "a", "b", "e"],
2642
- max: 30,
2643
- min: 2,
2644
- properties: "never"
2645
- }
2646
- ],
2576
+ "eqeqeq": "error",
2577
+ "for-direction": "error",
2647
2578
  "logical-assignment-operators": "error",
2648
2579
  "max-classes-per-file": "error",
2649
2580
  "max-depth": "error",
2650
- "max-lines": ["warn", { max: 300, skipBlankLines: true, skipComments: true }],
2651
- "max-lines-per-function": [
2652
- "warn",
2653
- { max: 30, skipBlankLines: true, skipComments: true }
2654
- ],
2581
+ "no-async-promise-executor": "error",
2582
+ "no-cond-assign": ["error", "always"],
2655
2583
  "no-constant-condition": [
2656
2584
  "error",
2657
2585
  {
2658
2586
  checkLoops: false
2659
2587
  }
2660
2588
  ],
2589
+ "no-control-regex": "error",
2661
2590
  "no-dupe-class-members": "off",
2662
2591
  "no-else-return": "error",
2592
+ "no-empty": ["error", { allowEmptyCatch: true }],
2593
+ "no-empty-character-class": "error",
2663
2594
  "no-empty-function": "off",
2595
+ "no-empty-pattern": "error",
2596
+ "no-empty-static-block": "error",
2597
+ "no-ex-assign": "error",
2598
+ "no-extra-boolean-cast": "error",
2599
+ "no-irregular-whitespace": "error",
2664
2600
  "no-lonely-if": "error",
2665
2601
  "no-loss-of-precision": "off",
2666
- "no-param-reassign": ["error", { props: false }],
2667
2602
  "no-redeclare": "off",
2603
+ "no-regex-spaces": "error",
2668
2604
  "no-return-assign": ["error", "always"],
2605
+ "no-self-assign": "error",
2606
+ "no-self-compare": "error",
2669
2607
  "no-shadow": "off",
2608
+ "no-sparse-arrays": "error",
2609
+ "no-template-curly-in-string": "error",
2610
+ "no-undef-init": "error",
2611
+ "no-unmodified-loop-condition": "error",
2670
2612
  "no-unneeded-ternary": "error",
2671
- "no-unused-expressions": [
2672
- "error",
2673
- {
2674
- allowShortCircuit: true,
2675
- allowTaggedTemplates: true,
2676
- allowTernary: true
2677
- }
2678
- ],
2679
- "no-unused-private-class-members": "error",
2613
+ "no-unsafe-finally": "error",
2614
+ "no-unused-expressions": "off",
2615
+ "no-unused-private-class-members": "off",
2616
+ "no-unused-vars": "off",
2680
2617
  "no-use-before-define": "off",
2618
+ "no-useless-backreference": "error",
2619
+ "no-useless-computed-key": "error",
2681
2620
  "no-useless-constructor": "off",
2682
2621
  "no-useless-rename": "error",
2683
2622
  "no-useless-return": "error",
2684
- "object-shorthand": "error",
2685
2623
  "prefer-const": [
2686
2624
  isInEditor ? "warn" : "error",
2687
2625
  {
@@ -2691,21 +2629,7 @@ async function typescript(options = {}) {
2691
2629
  ],
2692
2630
  "prefer-destructuring": "off",
2693
2631
  "ts/adjacent-overload-signatures": "off",
2694
- "ts/array-type": [
2695
- "error",
2696
- {
2697
- default: "generic",
2698
- readonly: "generic"
2699
- }
2700
- ],
2701
2632
  "ts/ban-ts-comment": ["error", { "ts-ignore": "allow-with-description" }],
2702
- "ts/consistent-generic-constructors": ["error", "constructor"],
2703
- "ts/consistent-indexed-object-style": ["error", "record"],
2704
- "ts/consistent-type-definitions": ["error", "interface"],
2705
- "ts/consistent-type-imports": [
2706
- "error",
2707
- { disallowTypeAnnotations: false, prefer: "type-imports" }
2708
- ],
2709
2633
  "ts/default-param-last": "error",
2710
2634
  "ts/explicit-function-return-type": [
2711
2635
  "error",
@@ -2724,7 +2648,7 @@ async function typescript(options = {}) {
2724
2648
  "ts/method-signature-style": "off",
2725
2649
  "ts/no-array-constructor": "off",
2726
2650
  "ts/no-confusing-non-null-assertion": "error",
2727
- "ts/no-dupe-class-members": "error",
2651
+ "ts/no-dupe-class-members": "off",
2728
2652
  "ts/no-dynamic-delete": "off",
2729
2653
  "ts/no-empty-function": "error",
2730
2654
  "ts/no-empty-object-type": ["error", { allowInterfaces: "always" }],
@@ -2757,28 +2681,56 @@ async function typescript(options = {}) {
2757
2681
  "ts/prefer-literal-enum-member": ["error", { allowBitwiseExpressions: true }],
2758
2682
  "ts/triple-slash-reference": "off",
2759
2683
  "ts/unified-signatures": "off",
2760
- yoda: ["error", "never"],
2684
+ ...stylistic2 ? {
2685
+ "camelcase": "error",
2686
+ "id-length": [
2687
+ "error",
2688
+ {
2689
+ exceptions: ["_", "x", "y", "z", "a", "b", "e"],
2690
+ max: 30,
2691
+ min: 2,
2692
+ properties: "never"
2693
+ }
2694
+ ],
2695
+ "max-lines": [
2696
+ "warn",
2697
+ { max: 300, skipBlankLines: true, skipComments: true }
2698
+ ],
2699
+ "max-lines-per-function": [
2700
+ "warn",
2701
+ { max: 30, skipBlankLines: true, skipComments: true }
2702
+ ],
2703
+ "no-lone-blocks": "error",
2704
+ "no-multi-str": "error",
2705
+ "object-shorthand": "error",
2706
+ "one-var": ["error", { initialized: "never" }],
2707
+ "ts/array-type": [
2708
+ "error",
2709
+ {
2710
+ default: "generic",
2711
+ readonly: "generic"
2712
+ }
2713
+ ],
2714
+ "ts/consistent-generic-constructors": ["error", "constructor"],
2715
+ "ts/consistent-indexed-object-style": ["error", "record"],
2716
+ "ts/consistent-type-definitions": ["error", "interface"],
2717
+ "ts/consistent-type-imports": [
2718
+ "error",
2719
+ { disallowTypeAnnotations: false, prefer: "type-imports" }
2720
+ ],
2721
+ "yoda": ["error", "never"]
2722
+ } : {},
2761
2723
  ...tsconfigPath ? typeAwareRules : {},
2762
2724
  ...overrides
2763
2725
  }
2764
- },
2765
- {
2766
- files: ["**/*.d.ts"],
2767
- name: "style/typescript:dts-overrides",
2768
- rules: {
2769
- "eslint-comments/no-unlimited-disable": "off",
2770
- "import/no-duplicates": "off",
2771
- "max-lines": "off",
2772
- "no-restricted-syntax": "off",
2773
- "unused-imports/no-unused-vars": "off"
2774
- }
2775
2726
  }
2776
2727
  ];
2777
2728
  }
2778
2729
 
2779
2730
  // src/configs/unicorn.ts
2780
2731
  init_esm_shims();
2781
- async function unicorn() {
2732
+ async function unicorn(options = {}) {
2733
+ const { stylistic: stylistic2 = true } = options;
2782
2734
  return [
2783
2735
  {
2784
2736
  name: "style/unicorn",
@@ -2848,6 +2800,7 @@ async function unicorn() {
2848
2800
  inst: {
2849
2801
  instance: true
2850
2802
  },
2803
+ jsdoc: false,
2851
2804
  nums: {
2852
2805
  numbers: true
2853
2806
  },
@@ -2864,7 +2817,9 @@ async function unicorn() {
2864
2817
  /* eslint-enable @cspell/spellchecker */
2865
2818
  }
2866
2819
  ],
2867
- "unicorn/switch-case-braces": "error"
2820
+ ...stylistic2 ? {
2821
+ "unicorn/switch-case-braces": "error"
2822
+ } : {}
2868
2823
  }
2869
2824
  }
2870
2825
  ];
@@ -2895,7 +2850,7 @@ async function yaml(options = {}) {
2895
2850
  languageOptions: {
2896
2851
  parser: parserYaml
2897
2852
  },
2898
- name: "style/yaml:rules",
2853
+ name: "style/yaml/rules",
2899
2854
  rules: {
2900
2855
  "style/spaced-comment": "off",
2901
2856
  "yaml/block-mapping": "error",
@@ -2936,6 +2891,24 @@ init_esm_shims();
2936
2891
  import { FlatConfigComposer } from "eslint-flat-config-utils";
2937
2892
  import fs from "node:fs";
2938
2893
 
2894
+ // src/configs/jsx.ts
2895
+ init_esm_shims();
2896
+ async function jsx() {
2897
+ return [
2898
+ {
2899
+ files: [GLOB_JSX, GLOB_TSX],
2900
+ languageOptions: {
2901
+ parserOptions: {
2902
+ ecmaFeatures: {
2903
+ jsx: true
2904
+ }
2905
+ }
2906
+ },
2907
+ name: "style/jsx/setup"
2908
+ }
2909
+ ];
2910
+ }
2911
+
2939
2912
  // src/configs/test.ts
2940
2913
  init_esm_shims();
2941
2914
  var pluginTest;
@@ -3031,14 +3004,14 @@ var defaultPluginRenaming = {
3031
3004
  "@eslint-react/naming-convention": "react-naming-convention",
3032
3005
  "@stylistic": "style",
3033
3006
  "@typescript-eslint": "ts",
3034
- yml: "yaml"
3007
+ "yml": "yaml"
3035
3008
  };
3036
3009
  function style(options = {}, ...userConfigs) {
3037
3010
  const {
3038
3011
  autoRenamePlugins = true,
3039
3012
  componentExts: componentExtensions = [],
3040
3013
  gitignore: enableGitignore = true,
3041
- jsx,
3014
+ jsx: enableJsx = true,
3042
3015
  perfectionist: perfectionistOptions,
3043
3016
  react: enableReact = false,
3044
3017
  roblox: enableRoblox = true,
@@ -3056,7 +3029,7 @@ function style(options = {}, ...userConfigs) {
3056
3029
  }
3057
3030
  const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
3058
3031
  if (stylisticOptions && !("jsx" in stylisticOptions)) {
3059
- stylisticOptions.jsx = jsx ?? true;
3032
+ stylisticOptions.jsx = enableJsx;
3060
3033
  }
3061
3034
  const configs = [];
3062
3035
  if (enableGitignore) {
@@ -3080,25 +3053,24 @@ function style(options = {}, ...userConfigs) {
3080
3053
  }
3081
3054
  configs.push(
3082
3055
  ignores(),
3083
- comments(),
3084
- jsdoc({
3085
- stylistic: stylisticOptions
3086
- }),
3087
- imports({
3088
- stylistic: stylisticOptions
3089
- }),
3056
+ comments({ stylistic: stylisticOptions }),
3057
+ jsdoc({ stylistic: stylisticOptions }),
3058
+ imports({ stylistic: stylisticOptions }),
3090
3059
  promise(),
3091
- shopify(),
3060
+ shopify({ stylistic: stylisticOptions }),
3092
3061
  sonarjs(),
3093
- unicorn(),
3094
- perfectionist(perfectionistOptions),
3062
+ unicorn({ stylistic: stylisticOptions }),
3095
3063
  typescript({
3096
3064
  ...resolveSubOptions(options, "typescript"),
3097
3065
  componentExts: componentExtensions,
3098
3066
  isInEditor,
3099
- overrides: getOverrides(options, "typescript")
3067
+ overrides: getOverrides(options, "typescript"),
3068
+ stylistic: stylisticOptions
3100
3069
  })
3101
3070
  );
3071
+ if (enableJsx) {
3072
+ configs.push(jsx());
3073
+ }
3102
3074
  if (enableRoblox) {
3103
3075
  configs.push(
3104
3076
  roblox(
@@ -3111,7 +3083,7 @@ function style(options = {}, ...userConfigs) {
3111
3083
  );
3112
3084
  }
3113
3085
  if (stylisticOptions) {
3114
- configs.push(stylistic(stylisticOptions));
3086
+ configs.push(perfectionist(perfectionistOptions), stylistic(stylisticOptions));
3115
3087
  }
3116
3088
  if (options.test ?? false) {
3117
3089
  configs.push(
@@ -3144,9 +3116,11 @@ function style(options = {}, ...userConfigs) {
3144
3116
  overrides: getOverrides(options, "jsonc"),
3145
3117
  stylistic: stylisticOptions
3146
3118
  }),
3147
- packageJson(),
3148
- sortTsconfig()
3119
+ packageJson()
3149
3120
  );
3121
+ if (stylisticOptions) {
3122
+ configs.push(sortTsconfig());
3123
+ }
3150
3124
  }
3151
3125
  if (options.yaml ?? true) {
3152
3126
  configs.push(
@@ -3172,7 +3146,7 @@ function style(options = {}, ...userConfigs) {
3172
3146
  })
3173
3147
  );
3174
3148
  }
3175
- if (options.formatters) {
3149
+ if (options.formatters !== false) {
3176
3150
  configs.push(
3177
3151
  formatters(
3178
3152
  options.formatters,
@@ -3181,16 +3155,17 @@ function style(options = {}, ...userConfigs) {
3181
3155
  )
3182
3156
  );
3183
3157
  }
3184
- configs.push(
3185
- disables(),
3186
- // We require prettier to be the last config
3187
- prettier({
3188
- ...typeof enableTypeScript !== "boolean" ? enableTypeScript : {},
3189
- componentExts: componentExtensions,
3190
- overrides: getOverrides(options, "typescript"),
3191
- prettierOptions: typeof options["formatters"] === "boolean" ? {} : options["formatters"]?.prettierOptions || {}
3192
- })
3193
- );
3158
+ configs.push(disables());
3159
+ if (stylisticOptions) {
3160
+ configs.push(
3161
+ prettier({
3162
+ ...typeof enableTypeScript !== "boolean" ? enableTypeScript : {},
3163
+ componentExts: componentExtensions,
3164
+ overrides: getOverrides(options, "typescript"),
3165
+ prettierOptions: typeof options["formatters"] === "boolean" ? {} : options["formatters"]?.prettierOptions || {}
3166
+ })
3167
+ );
3168
+ }
3194
3169
  if ("files" in options) {
3195
3170
  throw new Error(
3196
3171
  '[@isentinel/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.'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isentinel/eslint-config",
3
- "version": "0.10.0",
3
+ "version": "1.0.0-beta.1",
4
4
  "description": "iSentinel's ESLint config",
5
5
  "keywords": [
6
6
  "eslint-config",
@@ -37,6 +37,7 @@
37
37
  "@cspell/eslint-plugin": "8.17.5",
38
38
  "@eslint-community/eslint-plugin-eslint-comments": "4.4.1",
39
39
  "@eslint/compat": "1.2.7",
40
+ "@eslint/markdown": "6.2.2",
40
41
  "@isentinel/dict-rbxts": "1.0.1",
41
42
  "@isentinel/dict-roblox": "1.0.3",
42
43
  "@shopify/eslint-plugin": "47.0.1",
@@ -45,7 +46,7 @@
45
46
  "@typescript-eslint/parser": "8.25.0",
46
47
  "ansis": "3.16.0",
47
48
  "eslint-config-flat-gitignore": "2.1.0",
48
- "eslint-config-prettier": "10.0.1",
49
+ "eslint-config-prettier": "10.0.2",
49
50
  "eslint-flat-config-utils": "2.0.1",
50
51
  "eslint-merge-processors": "2.0.0",
51
52
  "eslint-plugin-antfu": "3.1.0",
@@ -58,7 +59,6 @@
58
59
  "eslint-plugin-import-x": "4.6.1",
59
60
  "eslint-plugin-jsdoc": "50.6.3",
60
61
  "eslint-plugin-jsonc": "2.19.1",
61
- "eslint-plugin-markdown": "5.1.0",
62
62
  "eslint-plugin-no-only-tests": "3.3.0",
63
63
  "eslint-plugin-package-json": "0.26.0",
64
64
  "eslint-plugin-perfectionist": "4.9.0",
@@ -101,9 +101,9 @@
101
101
  "lint-staged": "15.4.3",
102
102
  "rimraf": "6.0.1",
103
103
  "simple-git-hooks": "2.11.1",
104
- "tsup": "8.3.6",
104
+ "tsup": "8.4.0",
105
105
  "typescript": "5.7.3",
106
- "@isentinel/eslint-config": "0.10.0"
106
+ "@isentinel/eslint-config": "1.0.0-beta.1"
107
107
  },
108
108
  "peerDependencies": {
109
109
  "@eslint-react/eslint-plugin": "^1.14.0",
@@ -129,7 +129,7 @@
129
129
  "build": "nr typegen && tsup --clean --dts",
130
130
  "build:inspector": "pnpm build && npx @eslint/config-inspector build",
131
131
  "dev": "npx @eslint/config-inspector --config eslint.config.ts",
132
- "lint": "eslint .",
132
+ "lint": "eslint",
133
133
  "release": "bumpp && pnpm publish --p",
134
134
  "stub": "tsup",
135
135
  "typecheck": "tsc --noEmit",