@isentinel/eslint-config 3.0.0-beta.4 → 3.0.0-beta.5

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
@@ -117,6 +117,20 @@ set:
117
117
  }
118
118
  ```
119
119
 
120
+ Alternatively, you can install `@isentinel/tsconfig` from pnpm:
121
+
122
+ ```bash
123
+ pnpm install --save-dev @isentinel/tsconfig
124
+ ```
125
+
126
+ And use it in your `tsconfig.json`:
127
+
128
+ ```json
129
+ {
130
+ "extends": "@isentinel/tsconfig/roblox"
131
+ }
132
+ ```
133
+
120
134
  ### ESLint
121
135
 
122
136
  The `ts/no-non-null-assertion` rule is enabled by default, which will warn you
package/dist/cli.js CHANGED
@@ -11,7 +11,7 @@ import { execSync } from "node:child_process";
11
11
 
12
12
  //#region package.json
13
13
  var name = "@isentinel/eslint-config";
14
- var version = "3.0.0-beta.4";
14
+ var version = "3.0.0-beta.5";
15
15
  var description = "iSentinel's ESLint config";
16
16
  var keywords = [
17
17
  "eslint-config",
@@ -59,6 +59,7 @@ var dependencies = {
59
59
  "@eslint/markdown": "catalog:prod",
60
60
  "@isentinel/dict-rbxts": "catalog:prod",
61
61
  "@isentinel/dict-roblox": "catalog:prod",
62
+ "@isentinel/eslint-plugin-comment-length": "catalog:prod",
62
63
  "@prettier/plugin-oxc": "catalog:prod",
63
64
  "@shopify/eslint-plugin": "catalog:prod",
64
65
  "@stylistic/eslint-plugin": "catalog:prod",
@@ -73,7 +74,6 @@ var dependencies = {
73
74
  "eslint-plugin-antfu": "catalog:prod",
74
75
  "eslint-plugin-arrow-return-style-x": "catalog:prod",
75
76
  "eslint-plugin-better-max-params": "catalog:prod",
76
- "eslint-plugin-comment-length": "catalog:prod",
77
77
  "eslint-plugin-de-morgan": "catalog:prod",
78
78
  "eslint-plugin-format-lua": "catalog:prod",
79
79
  "eslint-plugin-import-lite": "catalog:prod",
@@ -105,6 +105,7 @@ var devDependencies = {
105
105
  "@eslint-react/eslint-plugin": "catalog:peer",
106
106
  "@eslint/config-inspector": "catalog:dev",
107
107
  "@isentinel/eslint-config": "workspace:*",
108
+ "@isentinel/tsconfig": "catalog:dev",
108
109
  "@stylistic/eslint-plugin-migrate": "catalog:dev",
109
110
  "@types/fs-extra": "catalog:dev",
110
111
  "@types/node": "catalog:dev",
@@ -117,6 +118,7 @@ var devDependencies = {
117
118
  "eslint-plugin-jest": "catalog:peer",
118
119
  "eslint-plugin-n": "catalog:peer",
119
120
  "eslint-plugin-react-roblox-hooks": "catalog:peer",
121
+ "eslint-plugin-unused-imports": "catalog:dev",
120
122
  "eslint-typegen": "catalog:dev",
121
123
  "esno": "catalog:dev",
122
124
  "execa": "catalog:dev",
@@ -471,7 +473,7 @@ async function updateEslintFiles(result) {
471
473
  const pathESLintIgnore = path.join(cwd, ".eslintignore");
472
474
  const pathPackageJSON = path.join(cwd, "package.json");
473
475
  const packageContent = await fsp.readFile(pathPackageJSON, "utf-8");
474
- const configFileName = JSON.parse(packageContent).type === "module" ? "eslint.config.js" : "eslint.config.mjs";
476
+ const configFileName = JSON.parse(packageContent)["type"] === "module" ? "eslint.config.js" : "eslint.config.mjs";
475
477
  const pathFlatConfig = path.join(cwd, configFileName);
476
478
  const eslintIgnores = [];
477
479
  if (fs.existsSync(pathESLintIgnore)) {
@@ -513,7 +515,7 @@ async function updatePackageJson(result) {
513
515
  const parsedPackage = JSON.parse(packageContent);
514
516
  parsedPackage.devDependencies ??= {};
515
517
  parsedPackage.devDependencies["@isentinel/eslint-config"] = `^${version}`;
516
- parsedPackage.devDependencies.eslint ??= versionsMap.eslint;
518
+ parsedPackage.devDependencies["eslint"] ??= versionsMap.eslint;
517
519
  const addedPackages = [];
518
520
  for (const framework of result.frameworks) if (framework in dependenciesMap) for (const dep of dependenciesMap[framework]) {
519
521
  parsedPackage.devDependencies[dep] = versionsMap[dep];
@@ -548,7 +550,7 @@ async function updateVscodeSettings(result) {
548
550
  //#endregion
549
551
  //#region src/cli/run.ts
550
552
  async function run(options = {}) {
551
- const argumentSkipPrompt = !!(process.env.SKIP_PROMPT ?? "") || options.yes;
553
+ const argumentSkipPrompt = !!(process.env["SKIP_PROMPT"] ?? "") || options.yes;
552
554
  const argumentTemplate = options.frameworks?.map((framework) => framework.trim()).filter((framework) => {
553
555
  return frameworks.includes(framework);
554
556
  });
@@ -0,0 +1,96 @@
1
+ import { createRequire } from "module";
2
+
3
+ //#region node_modules/.pnpm/eslint-plugin-unused-imports@4.2.0_@typescript-eslint+eslint-plugin@8.39.1_@typescript-_d725b5966c09a4e636f423644baea633/node_modules/eslint-plugin-unused-imports/dist/index.mjs
4
+ var commaFilter = { filter: (token) => token.value === "," };
5
+ var includeCommentsFilter = { includeComments: true };
6
+ function makePredicate(isImport, addFixer) {
7
+ return (problem, context) => {
8
+ const sourceCode = context.sourceCode || context.getSourceCode();
9
+ const { parent } = problem.node ?? sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(problem.loc.start));
10
+ return parent ? /^Import(|Default|Namespace)Specifier$/.test(parent.type) == isImport ? Object.assign(problem, addFixer?.(parent, sourceCode)) : false : isImport ? false : problem;
11
+ };
12
+ }
13
+ var unusedVarsPredicate = makePredicate(false);
14
+ var unusedImportsPredicate = makePredicate(true, (parent, sourceCode) => ({ fix(fixer) {
15
+ const grandParent = parent.parent;
16
+ if (!grandParent) return null;
17
+ if (grandParent.specifiers.length === 1) {
18
+ const nextToken = sourceCode.getTokenAfter(grandParent, includeCommentsFilter);
19
+ const newLinesBetween = nextToken ? nextToken.loc.start.line - grandParent.loc.start.line : 0;
20
+ const endOfReplaceRange = nextToken ? nextToken.range[0] : grandParent.range[1];
21
+ const count = Math.max(0, newLinesBetween - 1);
22
+ return [fixer.remove(grandParent), fixer.replaceTextRange([grandParent.range[1], endOfReplaceRange], "\n".repeat(count))];
23
+ }
24
+ if (parent !== grandParent.specifiers[grandParent.specifiers.length - 1]) {
25
+ const comma = sourceCode.getTokenAfter(parent, commaFilter);
26
+ const prevNode = sourceCode.getTokenBefore(parent);
27
+ return [
28
+ fixer.removeRange([prevNode.range[1], parent.range[0]]),
29
+ fixer.remove(parent),
30
+ fixer.remove(comma)
31
+ ];
32
+ }
33
+ if (grandParent.specifiers.filter((specifier) => specifier.type === "ImportSpecifier").length === 1) {
34
+ const start = sourceCode.getTokenBefore(parent, commaFilter);
35
+ const end = sourceCode.getTokenAfter(parent, { filter: (token) => token.value === "}" });
36
+ return fixer.removeRange([start.range[0], end.range[1]]);
37
+ }
38
+ return fixer.removeRange([sourceCode.getTokenBefore(parent, commaFilter).range[0], parent.range[1]]);
39
+ } }));
40
+ function createRuleWithPredicate(name, baseRule, predicate) {
41
+ return {
42
+ ...baseRule,
43
+ meta: {
44
+ ...baseRule.meta,
45
+ fixable: "code",
46
+ docs: {
47
+ ...baseRule.meta?.docs,
48
+ url: `https://github.com/sweepline/eslint-plugin-unused-imports/blob/master/docs/rules/${name}.md`
49
+ }
50
+ },
51
+ create(context) {
52
+ return baseRule.create(Object.create(context, { report: {
53
+ enumerable: true,
54
+ value(problem) {
55
+ const result = predicate(problem, context);
56
+ if (result) context.report(result);
57
+ }
58
+ } }));
59
+ }
60
+ };
61
+ }
62
+ var rule;
63
+ var require2 = createRequire(import.meta.url);
64
+ function getBaseRule() {
65
+ if (!rule) rule = getRuleFromTSLintPlugin() ?? getRuleFromTSLint() ?? getESLintBaseRule();
66
+ return rule;
67
+ }
68
+ function getRuleFromTSLintPlugin() {
69
+ try {
70
+ return require2("@typescript-eslint/eslint-plugin").rules["no-unused-vars"];
71
+ } catch (_) {
72
+ return null;
73
+ }
74
+ }
75
+ function getRuleFromTSLint() {
76
+ try {
77
+ return require2("typescript-eslint").plugin.rules["no-unused-vars"];
78
+ } catch (_) {
79
+ return null;
80
+ }
81
+ }
82
+ function getESLintBaseRule() {
83
+ return new (require2("eslint")).Linter({ configType: "eslintrc" }).getRules().get("no-unused-vars");
84
+ }
85
+ var no_unused_vars_default = createRuleWithPredicate("no-unused-vars", getBaseRule(), unusedVarsPredicate);
86
+ var no_unused_imports_default = createRuleWithPredicate("no-unused-imports", getBaseRule(), unusedImportsPredicate);
87
+ var index_default = {
88
+ meta: { name: "unused-imports" },
89
+ rules: {
90
+ "no-unused-vars": no_unused_vars_default,
91
+ "no-unused-imports": no_unused_imports_default
92
+ }
93
+ };
94
+
95
+ //#endregion
96
+ export { index_default as default };
package/dist/index.d.ts CHANGED
@@ -7353,6 +7353,16 @@ interface RuleOptions {
7353
7353
  * @see https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v60.0.0/docs/rules/throw-new-error.md
7354
7354
  */
7355
7355
  'unicorn/throw-new-error'?: Linter.RuleEntry<[]>;
7356
+ /**
7357
+ * Disallow unused variables
7358
+ * @see https://github.com/sweepline/eslint-plugin-unused-imports/blob/master/docs/rules/no-unused-imports.md
7359
+ */
7360
+ 'unused-imports/no-unused-imports'?: Linter.RuleEntry<UnusedImportsNoUnusedImports>;
7361
+ /**
7362
+ * Disallow unused variables
7363
+ * @see https://github.com/sweepline/eslint-plugin-unused-imports/blob/master/docs/rules/no-unused-vars.md
7364
+ */
7365
+ 'unused-imports/no-unused-vars'?: Linter.RuleEntry<UnusedImportsNoUnusedVars>;
7356
7366
  /**
7357
7367
  * Require calls to `isNaN()` when checking for `NaN`
7358
7368
  * @see https://eslint.org/docs/latest/rules/use-isnan
@@ -14846,6 +14856,32 @@ type UnicornTemplateIndent = [] | [{
14846
14856
  selectors?: string[];
14847
14857
  comments?: string[];
14848
14858
  }];
14859
+ // ----- unused-imports/no-unused-imports -----
14860
+ type UnusedImportsNoUnusedImports = [] | [(("all" | "local") | {
14861
+ args?: ("all" | "after-used" | "none");
14862
+ argsIgnorePattern?: string;
14863
+ caughtErrors?: ("all" | "none");
14864
+ caughtErrorsIgnorePattern?: string;
14865
+ destructuredArrayIgnorePattern?: string;
14866
+ ignoreClassWithStaticInitBlock?: boolean;
14867
+ ignoreRestSiblings?: boolean;
14868
+ reportUsedIgnorePattern?: boolean;
14869
+ vars?: ("all" | "local");
14870
+ varsIgnorePattern?: string;
14871
+ })];
14872
+ // ----- unused-imports/no-unused-vars -----
14873
+ type UnusedImportsNoUnusedVars = [] | [(("all" | "local") | {
14874
+ args?: ("all" | "after-used" | "none");
14875
+ argsIgnorePattern?: string;
14876
+ caughtErrors?: ("all" | "none");
14877
+ caughtErrorsIgnorePattern?: string;
14878
+ destructuredArrayIgnorePattern?: string;
14879
+ ignoreClassWithStaticInitBlock?: boolean;
14880
+ ignoreRestSiblings?: boolean;
14881
+ reportUsedIgnorePattern?: boolean;
14882
+ vars?: ("all" | "local");
14883
+ varsIgnorePattern?: string;
14884
+ })];
14849
14885
  // ----- use-isnan -----
14850
14886
  type UseIsnan = [] | [{
14851
14887
  enforceForSwitchCase?: boolean;
@@ -15428,7 +15464,7 @@ declare function ignores(userIgnores?: Array<string>): Promise<Array<TypedFlatCo
15428
15464
  declare function imports(options?: OptionsProjectType & OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
15429
15465
  //#endregion
15430
15466
  //#region src/configs/javascript.d.ts
15431
- declare function javascript(options?: OptionsIsInEditor & OptionsOverrides & OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
15467
+ declare function javascript(options?: OptionsIsInEditor & OptionsOverrides & OptionsRoblox & OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
15432
15468
  //#endregion
15433
15469
  //#region src/configs/jsdoc.d.ts
15434
15470
  declare function jsdoc(options?: JsDocOptions & OptionsProjectType & OptionsStylistic): Promise<Array<TypedFlatConfigItem>>;
@@ -15525,6 +15561,7 @@ declare const defaultPluginRenaming: {
15525
15561
  "@eslint-react": string;
15526
15562
  "@eslint-react/hooks-extra": string;
15527
15563
  "@eslint-react/naming-convention": string;
15564
+ "@isentinel/eslint-plugin-comment-length": string;
15528
15565
  "@stylistic": string;
15529
15566
  "@typescript-eslint": string;
15530
15567
  "arrow-return-style-x": string;
@@ -15569,6 +15606,7 @@ declare const GLOB_HTML = "**/*.htm?(l)";
15569
15606
  declare const GLOB_XML = "**/*.xml";
15570
15607
  declare const GLOB_GRAPHQL = "**/*.{g,graph}ql";
15571
15608
  declare const GLOB_TESTS: string[];
15609
+ declare const GLOB_BUILD_TOOLS: string[];
15572
15610
  declare const GLOB_ALL_SRC: string[];
15573
15611
  declare const GLOB_EXCLUDE: string[];
15574
15612
  //#endregion
@@ -15704,4 +15742,4 @@ declare function resolveWithDefaults<T>(value: boolean | T | undefined, defaults
15704
15742
  */
15705
15743
  declare function shouldEnableFeature<T extends Record<string, any>>(options: boolean | T | undefined, key: keyof T, defaultValue?: boolean): boolean;
15706
15744
  //#endregion
15707
- export { Awaitable, type ConfigNames, GLOB_ALL_JSON, GLOB_ALL_SRC, GLOB_CSS, GLOB_DTS, GLOB_EXCLUDE, GLOB_GRAPHQL, 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_ROOT, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_XML, GLOB_YAML, GitignoreOptions, JsDocOptions, OptionsComponentExtensions, OptionsConfig, OptionsFiles, OptionsFormatters, OptionsHasTypeScript, OptionsIsInEditor, OptionsOverrides, OptionsProjectType, OptionsRoblox, OptionsStylistic, OptionsTestFramework, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, OptionsTypescript, PerfectionistConfig, type PrettierOptions, PrettierRuleOptions, ReactConfig, ResolvedOptions, Rules, SpellCheckConfig, StylisticConfig, StylisticConfigDefaults, TypedFlatConfigItem, combine, comments, createTsParser, isentinel as default, defaultPluginRenaming, disables, ensurePackages, eslintPlugin, getOverrides, getTsConfig, gitignore, ignores, imports, interopDefault, isInEditorEnvironment, isInGitHooksOrLintStaged, isentinel, javascript, jsdoc, jsonc, markdown, mergePrettierOptions, node, packageJson, parserPlain, perfectionist, pnpm, prettier, promise, react, renamePluginInConfigs, renameRules, require, resolvePrettierConfigOptions, resolveSubOptions, resolveWithDefaults, roblox, shopify, shouldEnableFeature, sonarjs, sortGithubAction, sortTsconfig, spelling, stylistic, toml, typescript, unicorn, yaml };
15745
+ export { Awaitable, type ConfigNames, GLOB_ALL_JSON, GLOB_ALL_SRC, GLOB_BUILD_TOOLS, GLOB_CSS, GLOB_DTS, GLOB_EXCLUDE, GLOB_GRAPHQL, 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_ROOT, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_XML, GLOB_YAML, GitignoreOptions, JsDocOptions, OptionsComponentExtensions, OptionsConfig, OptionsFiles, OptionsFormatters, OptionsHasTypeScript, OptionsIsInEditor, OptionsOverrides, OptionsProjectType, OptionsRoblox, OptionsStylistic, OptionsTestFramework, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, OptionsTypescript, PerfectionistConfig, type PrettierOptions, PrettierRuleOptions, ReactConfig, ResolvedOptions, Rules, SpellCheckConfig, StylisticConfig, StylisticConfigDefaults, TypedFlatConfigItem, combine, comments, createTsParser, isentinel as default, defaultPluginRenaming, disables, ensurePackages, eslintPlugin, getOverrides, getTsConfig, gitignore, ignores, imports, interopDefault, isInEditorEnvironment, isInGitHooksOrLintStaged, isentinel, javascript, jsdoc, jsonc, markdown, mergePrettierOptions, node, packageJson, parserPlain, perfectionist, pnpm, prettier, promise, react, renamePluginInConfigs, renameRules, require, resolvePrettierConfigOptions, resolveSubOptions, resolveWithDefaults, roblox, shopify, shouldEnableFeature, sonarjs, sortGithubAction, sortTsconfig, spelling, stylistic, toml, typescript, unicorn, yaml };
package/dist/index.js CHANGED
@@ -69,6 +69,18 @@ const GLOB_TESTS = [
69
69
  `**/*.bench.${GLOB_SRC_EXT}`,
70
70
  `**/*.benchmark.${GLOB_SRC_EXT}`
71
71
  ];
72
+ const GLOB_BUILD_TOOLS = [
73
+ "**/.husky/**/*",
74
+ `**/config/${GLOB_SRC}`,
75
+ `**/*config.${GLOB_SRC_EXT}`,
76
+ `**/*config.*.${GLOB_SRC_EXT}`,
77
+ `**/build/${GLOB_SRC}`,
78
+ `**/tools/${GLOB_SRC}`,
79
+ `**/setup/${GLOB_SRC}`,
80
+ `**/dev/${GLOB_SRC}`,
81
+ `**/tasks/${GLOB_SRC}`,
82
+ "**/.github/scripts/**/*"
83
+ ];
72
84
  const GLOB_ALL_SRC = [
73
85
  GLOB_SRC,
74
86
  GLOB_STYLE,
@@ -179,7 +191,7 @@ function createTsParser(options) {
179
191
  };
180
192
  }
181
193
  async function ensurePackages(packages) {
182
- if ((process.env.CI ?? "") || !process.stdout.isTTY) return;
194
+ if ((process.env["CI"] ?? "") || !process.stdout.isTTY) return;
183
195
  const nonExistingPackages = packages.filter((index) => index !== void 0 && !isPackageExists(index));
184
196
  if (nonExistingPackages.length === 0) return;
185
197
  if (await (await import("@clack/prompts")).confirm({ message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?` }) === true) await import("@antfu/install-pkg").then(async (index) => {
@@ -201,18 +213,18 @@ async function interopDefault(dynamicImport) {
201
213
  return resolved;
202
214
  }
203
215
  function isInEditorEnvironment() {
204
- if (process.env.CI ?? "") return false;
216
+ if (process.env["CI"] ?? "") return false;
205
217
  if (isInGitHooksOrLintStaged()) return false;
206
218
  return [
207
- process.env.VSCODE_PID,
208
- process.env.VSCODE_CWD,
209
- process.env.JETBRAINS_IDE,
210
- process.env.VIM,
211
- process.env.NVIM
219
+ process.env["VSCODE_PID"],
220
+ process.env["VSCODE_CWD"],
221
+ process.env["JETBRAINS_IDE"],
222
+ process.env["VIM"],
223
+ process.env["NVIM"]
212
224
  ].some(Boolean);
213
225
  }
214
226
  function isInGitHooksOrLintStaged() {
215
- return [process.env.GIT_PARAMS ?? process.env.VSCODE_GIT_COMMAND ?? process.env.npm_lifecycle_script?.startsWith("lint-staged")].some(Boolean);
227
+ return [process.env["GIT_PARAMS"] ?? process.env["VSCODE_GIT_COMMAND"] ?? process.env["npm_lifecycle_script"]?.startsWith("lint-staged")].some(Boolean);
216
228
  }
217
229
  function mergePrettierOptions(options, overrides = {}) {
218
230
  return {
@@ -335,7 +347,7 @@ function shouldEnableFeature(options, key, defaultValue = true) {
335
347
  async function comments(options = {}) {
336
348
  const { prettierOptions = {}, stylistic: stylistic$1 = true } = options;
337
349
  const [pluginCommentLength, pluginComments, pluginStylistic] = await Promise.all([
338
- interopDefault(import("eslint-plugin-comment-length")),
350
+ interopDefault(import("@isentinel/eslint-plugin-comment-length")),
339
351
  interopDefault(import("@eslint-community/eslint-plugin-eslint-comments")),
340
352
  interopDefault(import("@stylistic/eslint-plugin"))
341
353
  ]);
@@ -368,7 +380,7 @@ async function comments(options = {}) {
368
380
  files: [GLOB_SRC],
369
381
  name: "isentinel/eslint/comments/src",
370
382
  rules: { "comment-length/limit-single-line-comments": ["error", {
371
- maxLength: Number(prettierOptions.jsdocPrintWidth) + 2,
383
+ maxLength: Number(prettierOptions["jsdocPrintWidth"]) + 2,
372
384
  tabSize: prettierOptions.tabWidth
373
385
  }] }
374
386
  }] : []
@@ -396,6 +408,15 @@ async function disables() {
396
408
  "no-console": "off"
397
409
  }
398
410
  },
411
+ {
412
+ files: GLOB_BUILD_TOOLS,
413
+ name: "isentinel/disables/build-tools",
414
+ rules: {
415
+ "antfu/no-top-level-await": "off",
416
+ "no-console": "off",
417
+ "ts/explicit-function-return-type": "off"
418
+ }
419
+ },
399
420
  {
400
421
  files: ["**/bin/**/*", `**/bin.${GLOB_SRC_EXT}`],
401
422
  name: "isentinel/disables/bin",
@@ -3566,11 +3587,12 @@ var require_globals = /* @__PURE__ */ __commonJS({ "node_modules/.pnpm/globals@1
3566
3587
  //#region src/configs/javascript.ts
3567
3588
  var import_globals = /* @__PURE__ */ __toESM(require_globals(), 1);
3568
3589
  async function javascript(options = {}) {
3569
- const { isInEditor = false, overrides = {}, stylistic: stylistic$1 = true } = options;
3570
- const [pluginAntfu, pluginDeMorgan, pluginMaxParameters] = await Promise.all([
3590
+ const { isInEditor = false, overrides = {}, roblox: roblox$1 = true, stylistic: stylistic$1 = true } = options;
3591
+ const [pluginAntfu, pluginDeMorgan, pluginMaxParameters, pluginUnusedImports] = await Promise.all([
3571
3592
  interopDefault(import("eslint-plugin-antfu")),
3572
3593
  interopDefault(import("eslint-plugin-de-morgan")),
3573
- interopDefault(import("eslint-plugin-better-max-params"))
3594
+ interopDefault(import("eslint-plugin-better-max-params")),
3595
+ interopDefault(import("./dist-CRJXXCjc.js"))
3574
3596
  ]);
3575
3597
  return [{
3576
3598
  languageOptions: {
@@ -3598,7 +3620,8 @@ async function javascript(options = {}) {
3598
3620
  plugins: {
3599
3621
  "antfu": pluginAntfu,
3600
3622
  "better-max-params": pluginMaxParameters,
3601
- "de-morgan": pluginDeMorgan
3623
+ "de-morgan": pluginDeMorgan,
3624
+ "unused-imports": pluginUnusedImports
3602
3625
  },
3603
3626
  rules: {
3604
3627
  "accessor-pairs": ["error", {
@@ -3741,12 +3764,7 @@ async function javascript(options = {}) {
3741
3764
  allowTaggedTemplates: true,
3742
3765
  allowTernary: true
3743
3766
  }],
3744
- "no-unused-vars": ["error", {
3745
- args: "none",
3746
- caughtErrors: "none",
3747
- ignoreRestSiblings: true,
3748
- vars: "all"
3749
- }],
3767
+ "no-unused-vars": "off",
3750
3768
  "no-use-before-define": ["error", {
3751
3769
  classes: false,
3752
3770
  functions: false,
@@ -3777,6 +3795,18 @@ async function javascript(options = {}) {
3777
3795
  "prefer-template": "error",
3778
3796
  "symbol-description": "error",
3779
3797
  "unicode-bom": ["error", "never"],
3798
+ "unused-imports/no-unused-imports": isInEditor ? "warn" : "error",
3799
+ "unused-imports/no-unused-vars": ["error", {
3800
+ args: "all",
3801
+ argsIgnorePattern: "^_+",
3802
+ caughtErrors: "all",
3803
+ caughtErrorsIgnorePattern: "^_+",
3804
+ destructuredArrayIgnorePattern: "^_+",
3805
+ ignoreRestSiblings: true,
3806
+ reportUsedIgnorePattern: true,
3807
+ vars: "all",
3808
+ varsIgnorePattern: "^_+"
3809
+ }],
3780
3810
  "use-isnan": ["error", {
3781
3811
  enforceForIndexOf: true,
3782
3812
  enforceForSwitchCase: true
@@ -3820,7 +3850,8 @@ async function javascript(options = {}) {
3820
3850
  }
3821
3851
  ],
3822
3852
  "one-var": ["error", { initialized: "never" }],
3823
- "yoda": ["error", "never"]
3853
+ "yoda": ["error", "never"],
3854
+ ...!roblox$1 ? { "func-style": ["error", "declaration"] } : {}
3824
3855
  } : {},
3825
3856
  ...overrides
3826
3857
  }
@@ -3849,11 +3880,13 @@ async function jsdoc(options = {}) {
3849
3880
  "jsdoc/no-defaults": "warn",
3850
3881
  "jsdoc/no-types": "warn",
3851
3882
  "jsdoc/require-description": ["warn", { exemptedBy: [
3852
- "hidden, ignore",
3883
+ "hidden",
3884
+ "ignore",
3853
3885
  "inheritdoc",
3854
3886
  "client",
3855
3887
  "server",
3856
- "see"
3888
+ "see",
3889
+ "metadata"
3857
3890
  ] }],
3858
3891
  "jsdoc/require-description-complete-sentence": "warn",
3859
3892
  "jsdoc/require-param-description": "warn",
@@ -4453,6 +4486,7 @@ const defaultPluginRenaming = {
4453
4486
  "@eslint-react": "react",
4454
4487
  "@eslint-react/hooks-extra": "react-hooks-extra",
4455
4488
  "@eslint-react/naming-convention": "react-naming-convention",
4489
+ "@isentinel/eslint-plugin-comment-length": "comment-length",
4456
4490
  "@stylistic": "style",
4457
4491
  "@typescript-eslint": "ts",
4458
4492
  "arrow-return-style-x": "arrow-style",
@@ -4468,7 +4502,7 @@ const defaultPluginRenaming = {
4468
4502
  * @returns A promise that resolves to an array of user configuration items.
4469
4503
  */
4470
4504
  async function isentinel(options = {}, ...userConfigs) {
4471
- const { autoRenamePlugins = true, componentExts: componentExtensions = [], eslintPlugin: enableEslintPlugin = false, formatters, gitignore: enableGitignore = true, jsx: enableJsx = true, pnpm: enableCatalogs = false, react: enableReact = false, roblox: enableRoblox = true, spellCheck: enableSpellCheck, typescript: enableTypeScript } = options;
4505
+ const { autoRenamePlugins = true, componentExts: componentExtensions = [], eslintPlugin: enableEslintPlugin = false, formatters, gitignore: enableGitignore = true, jsdoc: enableJsdoc = true, jsx: enableJsx = true, pnpm: enableCatalogs = false, react: enableReact = false, roblox: enableRoblox = true, spellCheck: enableSpellCheck, typescript: enableTypeScript } = options;
4472
4506
  let { isInEditor } = options;
4473
4507
  if (isInEditor === void 0) {
4474
4508
  isInEditor = isInEditorEnvironment();
@@ -4507,21 +4541,24 @@ async function isentinel(options = {}, ...userConfigs) {
4507
4541
  }), ignores(options.ignores), imports({
4508
4542
  stylistic: stylisticOptions,
4509
4543
  type: options.type
4510
- }), jsdoc({
4511
- stylistic: stylisticOptions,
4512
- type: options.type
4513
4544
  }), packageJson({
4514
4545
  roblox: options.roblox,
4515
4546
  type: options.type
4516
4547
  }), javascript({
4517
4548
  isInEditor,
4518
- overrides: getOverrides(options, "javascript")
4549
+ overrides: getOverrides(options, "javascript"),
4550
+ roblox: options.roblox,
4551
+ stylistic: stylisticOptions
4519
4552
  }), promise(), shopify({ stylistic: stylisticOptions }), sonarjs({ isInEditor }), typescript({
4520
4553
  ...resolveSubOptions(options, "typescript"),
4521
4554
  componentExts: componentExtensions,
4522
4555
  overrides: getOverrides(options, "typescript"),
4523
4556
  stylistic: stylisticOptions
4524
4557
  }), unicorn({ stylistic: stylisticOptions }));
4558
+ if (enableJsdoc !== false) configs.push(jsdoc({
4559
+ stylistic: stylisticOptions,
4560
+ type: options.type
4561
+ }));
4525
4562
  if (options.type === "package" && options.roblox === false) configs.push(node());
4526
4563
  if (enableJsx) configs.push(jsx());
4527
4564
  if (enableEslintPlugin !== false) configs.push(eslintPlugin({ overrides: getOverrides(options, "eslintPlugin") }));
@@ -4599,7 +4636,11 @@ async function isentinel(options = {}, ...userConfigs) {
4599
4636
  composer = composer.append(...configs, ...userConfigs);
4600
4637
  if (autoRenamePlugins) composer = composer.renamePlugins(defaultPluginRenaming);
4601
4638
  if (isInEditor) {
4602
- const disableAutofixRules = ["no-useless-return", "prefer-const"];
4639
+ const disableAutofixRules = [
4640
+ "no-useless-return",
4641
+ "prefer-const",
4642
+ "unused-imports/no-unused-imports"
4643
+ ];
4603
4644
  if (enableRoblox) disableAutofixRules.push("unicorn/no-array-for-each");
4604
4645
  composer = composer.disableRulesFix(disableAutofixRules, { builtinRules: async () => {
4605
4646
  return (await import("eslint/use-at-your-own-risk")).builtinRules;
@@ -4695,7 +4736,7 @@ async function prettier(options) {
4695
4736
  rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, {
4696
4737
  embeddedLanguageFormatting: "auto",
4697
4738
  parser: "markdown",
4698
- printWidth: Number(prettierOptions.jsdocPrintWidth) || 80,
4739
+ printWidth: Number(prettierOptions["jsdocPrintWidth"]) || 80,
4699
4740
  proseWrap: "always"
4700
4741
  })] }
4701
4742
  });
@@ -4755,12 +4796,13 @@ async function promise() {
4755
4796
  async function react(options = {}) {
4756
4797
  const { additionalComponents, additionalHooks, filenameCase = "kebabCase", files = [GLOB_SRC], filesTypeAware = [GLOB_TS, GLOB_TSX], ignoresTypeAware = [`${GLOB_MARKDOWN}/**`], importSource, jsxPragma, overrides = {}, skipImportCheck, stylistic: stylistic$1 = true, typeAware = true } = options;
4757
4798
  await ensurePackages(["@eslint-react/eslint-plugin", "eslint-plugin-react-roblox-hooks"]);
4758
- const [pluginReact, pluginReactHooks, pluginStylistic, pluginTs, pluginUnicorn] = await Promise.all([
4799
+ const [pluginReact, pluginReactHooks, pluginStylistic, pluginTs, pluginUnicorn, pluginUnusedImports] = await Promise.all([
4759
4800
  interopDefault(import("@eslint-react/eslint-plugin")),
4760
4801
  interopDefault(import("eslint-plugin-react-roblox-hooks")),
4761
4802
  interopDefault(import("@stylistic/eslint-plugin")),
4762
4803
  interopDefault(import("@typescript-eslint/eslint-plugin")),
4763
- interopDefault(import("eslint-plugin-unicorn"))
4804
+ interopDefault(import("eslint-plugin-unicorn")),
4805
+ interopDefault(import("./dist-CRJXXCjc.js"))
4764
4806
  ]);
4765
4807
  const { plugins } = pluginReact.configs.all;
4766
4808
  const isTypeAware = (typeAware ? getTsConfig(options.tsconfigPath) : void 0) !== void 0;
@@ -4786,7 +4828,8 @@ async function react(options = {}) {
4786
4828
  "react-naming-convention": plugins["@eslint-react/naming-convention"],
4787
4829
  "style": pluginStylistic,
4788
4830
  "ts": pluginTs,
4789
- "unicorn": pluginUnicorn
4831
+ "unicorn": pluginUnicorn,
4832
+ "unused-imports": pluginUnusedImports
4790
4833
  }
4791
4834
  },
4792
4835
  {
@@ -4811,8 +4854,8 @@ async function react(options = {}) {
4811
4854
  "react/ensure-forward-ref-using-ref": "warn",
4812
4855
  "react/jsx-no-duplicate-props": "off",
4813
4856
  "react/jsx-no-undef": "off",
4814
- "react/jsx-uses-react": "off",
4815
- "react/jsx-uses-vars": "off",
4857
+ "react/jsx-uses-react": "error",
4858
+ "react/jsx-uses-vars": "error",
4816
4859
  "react/no-access-state-in-setstate": "error",
4817
4860
  "react/no-array-index-key": "warn",
4818
4861
  "react/no-children-count": "warn",
@@ -5396,7 +5439,7 @@ async function stylistic(options = {}, prettierOptions = {}) {
5396
5439
  quotes,
5397
5440
  semi
5398
5441
  });
5399
- const createArrowStyleRule = (parser, maxLength) => {
5442
+ function createArrowStyleRule(parser, maxLength) {
5400
5443
  return { "arrow-style/arrow-return-style": ["error", {
5401
5444
  jsxAlwaysUseExplicitReturn: true,
5402
5445
  maxLen: maxLength ?? arrowLength ?? prettierOptions.printWidth ?? 100,
@@ -5408,7 +5451,7 @@ async function stylistic(options = {}, prettierOptions = {}) {
5408
5451
  plugins: [require$1.resolve("@prettier/plugin-oxc")]
5409
5452
  })
5410
5453
  }] };
5411
- };
5454
+ }
5412
5455
  return [
5413
5456
  {
5414
5457
  name: "isentinel/stylistic/setup",
@@ -5488,7 +5531,7 @@ async function stylistic(options = {}, prettierOptions = {}) {
5488
5531
  },
5489
5532
  {
5490
5533
  files: [GLOB_MARKDOWN_CODE],
5491
- rules: { ...createArrowStyleRule("oxc", Number(prettierOptions.jsdocPrintWidth) || 80) }
5534
+ rules: { ...createArrowStyleRule("oxc", Number(prettierOptions["jsdocPrintWidth"]) || 80) }
5492
5535
  }
5493
5536
  ];
5494
5537
  }
@@ -5551,6 +5594,7 @@ async function typescript(options = {}) {
5551
5594
  "dot-notation": "off",
5552
5595
  "no-implied-eval": "off",
5553
5596
  "no-unsafe-optional-chaining": "error",
5597
+ "prefer-promise-reject-errors": "off",
5554
5598
  "ts/await-thenable": "error",
5555
5599
  "ts/consistent-type-assertions": ["error", {
5556
5600
  assertionStyle: "as",
@@ -5648,8 +5692,8 @@ async function typescript(options = {}) {
5648
5692
  files,
5649
5693
  name: "isentinel/typescript/rules",
5650
5694
  rules: {
5651
- ...renameRules(pluginTs.configs["eslint-recommended"].overrides?.[0].rules ?? {}, { "@typescript-eslint": "ts" }),
5652
- ...renameRules(pluginTs.configs.strict.rules ?? {}, { "@typescript-eslint": "ts" }),
5695
+ ...renameRules(pluginTs.configs["eslint-recommended"]?.overrides?.[0]?.rules ?? {}, { "@typescript-eslint": "ts" }),
5696
+ ...renameRules(pluginTs.configs["strict"]?.rules ?? {}, { "@typescript-eslint": "ts" }),
5653
5697
  "no-dupe-class-members": "off",
5654
5698
  "no-empty-function": "off",
5655
5699
  "no-loss-of-precision": "off",
@@ -5658,7 +5702,6 @@ async function typescript(options = {}) {
5658
5702
  "no-shadow": "off",
5659
5703
  "no-unused-expressions": "off",
5660
5704
  "no-unused-private-class-members": "off",
5661
- "no-unused-vars": "off",
5662
5705
  "no-use-before-define": "off",
5663
5706
  "no-useless-constructor": "off",
5664
5707
  "prefer-destructuring": "off",
@@ -5686,12 +5729,7 @@ async function typescript(options = {}) {
5686
5729
  "ts/no-require-imports": "error",
5687
5730
  "ts/no-shadow": "error",
5688
5731
  "ts/no-unused-expressions": "error",
5689
- "ts/no-unused-vars": ["error", {
5690
- argsIgnorePattern: "^_+",
5691
- caughtErrorsIgnorePattern: "^_+",
5692
- reportUsedIgnorePattern: true,
5693
- varsIgnorePattern: "^_+"
5694
- }],
5732
+ "ts/no-unused-vars": "off",
5695
5733
  "ts/no-use-before-define": "off",
5696
5734
  "ts/no-useless-constructor": "error",
5697
5735
  "ts/no-wrapper-object-types": "error",
@@ -5857,4 +5895,4 @@ async function yaml(options = {}) {
5857
5895
  }
5858
5896
 
5859
5897
  //#endregion
5860
- export { GLOB_ALL_JSON, GLOB_ALL_SRC, GLOB_CSS, GLOB_DTS, GLOB_EXCLUDE, GLOB_GRAPHQL, 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_ROOT, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_XML, GLOB_YAML, StylisticConfigDefaults, combine, comments, createTsParser, isentinel as default, defaultPluginRenaming, disables, ensurePackages, eslintPlugin, getOverrides, getTsConfig, gitignore, ignores, imports, interopDefault, isInEditorEnvironment, isInGitHooksOrLintStaged, isentinel, javascript, jsdoc, jsonc, markdown, mergePrettierOptions, node, packageJson, parserPlain, perfectionist, pnpm, prettier, promise, react, renamePluginInConfigs, renameRules, require$1 as require, resolvePrettierConfigOptions, resolveSubOptions, resolveWithDefaults, roblox, shopify, shouldEnableFeature, sonarjs, sortGithubAction, sortTsconfig, spelling, stylistic, toml, typescript, unicorn, yaml };
5898
+ export { GLOB_ALL_JSON, GLOB_ALL_SRC, GLOB_BUILD_TOOLS, GLOB_CSS, GLOB_DTS, GLOB_EXCLUDE, GLOB_GRAPHQL, 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_ROOT, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_XML, GLOB_YAML, StylisticConfigDefaults, combine, comments, createTsParser, isentinel as default, defaultPluginRenaming, disables, ensurePackages, eslintPlugin, getOverrides, getTsConfig, gitignore, ignores, imports, interopDefault, isInEditorEnvironment, isInGitHooksOrLintStaged, isentinel, javascript, jsdoc, jsonc, markdown, mergePrettierOptions, node, packageJson, parserPlain, perfectionist, pnpm, prettier, promise, react, renamePluginInConfigs, renameRules, require$1 as require, resolvePrettierConfigOptions, resolveSubOptions, resolveWithDefaults, roblox, shopify, shouldEnableFeature, sonarjs, sortGithubAction, sortTsconfig, spelling, stylistic, toml, typescript, unicorn, yaml };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isentinel/eslint-config",
3
- "version": "3.0.0-beta.4",
3
+ "version": "3.0.0-beta.5",
4
4
  "description": "iSentinel's ESLint config",
5
5
  "keywords": [
6
6
  "eslint-config",
@@ -44,6 +44,7 @@
44
44
  "@eslint/markdown": "7.2.0",
45
45
  "@isentinel/dict-rbxts": "1.0.1",
46
46
  "@isentinel/dict-roblox": "1.0.3",
47
+ "@isentinel/eslint-plugin-comment-length": "2.2.0",
47
48
  "@prettier/plugin-oxc": "0.0.4",
48
49
  "@shopify/eslint-plugin": "50.0.0",
49
50
  "@stylistic/eslint-plugin": "6.0.0-beta.1",
@@ -58,7 +59,6 @@
58
59
  "eslint-plugin-antfu": "3.1.1",
59
60
  "eslint-plugin-arrow-return-style-x": "1.2.6",
60
61
  "eslint-plugin-better-max-params": "1.0.0",
61
- "eslint-plugin-comment-length": "2.2.2",
62
62
  "eslint-plugin-de-morgan": "1.3.1",
63
63
  "eslint-plugin-format-lua": "1.0.1-beta.2",
64
64
  "eslint-plugin-import-lite": "0.3.0",
@@ -89,6 +89,7 @@
89
89
  "@antfu/ni": "25.0.0",
90
90
  "@eslint-react/eslint-plugin": "1.52.5",
91
91
  "@eslint/config-inspector": "1.2.0",
92
+ "@isentinel/tsconfig": "1.0.0",
92
93
  "@stylistic/eslint-plugin-migrate": "4.4.1",
93
94
  "@types/fs-extra": "11.0.4",
94
95
  "@types/node": "24.3.1",
@@ -101,6 +102,7 @@
101
102
  "eslint-plugin-jest": "29.0.1",
102
103
  "eslint-plugin-n": "17.21.3",
103
104
  "eslint-plugin-react-roblox-hooks": "5.1.0-rbx.1",
105
+ "eslint-plugin-unused-imports": "4.2.0",
104
106
  "eslint-typegen": "2.3.0",
105
107
  "esno": "4.8.0",
106
108
  "execa": "9.6.0",
@@ -115,7 +117,7 @@
115
117
  "tsdown": "0.14.2",
116
118
  "type-fest": "4.41.0",
117
119
  "typescript": "5.8.3",
118
- "@isentinel/eslint-config": "3.0.0-beta.4"
120
+ "@isentinel/eslint-config": "3.0.0-beta.5"
119
121
  },
120
122
  "peerDependencies": {
121
123
  "@eslint-react/eslint-plugin": "^1.45.0",