@plugjs/eslint-plugin 0.4.0 → 0.5.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.
package/README.md CHANGED
@@ -1,8 +1,17 @@
1
1
  PlugJS ESLint (v9) Shared Configuration
2
2
  =======================================
3
3
 
4
- This package exports simple configurations for linting our projects. It's the
5
- easiest way to actually share some configs and plugins.
4
+ Provides shared ESLint v9 flat-config presets for PlugJS projects. Its the
5
+ easiest way to share consistent rules and plugins across repos.
6
+
7
+ * [Quick Setup](#quick-setup)
8
+ * [Configurations](#configurations)
9
+ * [CLI Utility](#cli-utility)
10
+ * [Legal Stuff](#legal-stuff)
11
+
12
+
13
+ Quick Setup
14
+ -----------
6
15
 
7
16
  Just create a new `eslint.config.mjs` file following this template, your mileage
8
17
  might vary, and according to your specific needs you might need to add/remove
@@ -33,9 +42,9 @@ export default [
33
42
  rules: {
34
43
  // Turn _ON_ dependencies checks only for sources
35
44
  'import-x/no-extraneous-dependencies': [ 'error', {
36
- 'devDependencies': true,
45
+ 'devDependencies': false,
46
+ 'optionalDependencies': false,
37
47
  'peerDependencies': true,
38
- 'optionalDependencies': true,
39
48
  'bundledDependencies': false,
40
49
  } ],
41
50
  },
@@ -51,8 +60,8 @@ export default [
51
60
 
52
61
  // ===== IGNORED FILES =======================================================
53
62
  // REMEMBER! Ignores *must* be in its own configuration, they can not coexist
54
- // with "rules", "languageOptions", "files", ... or anything else, otherwise
55
- // ESLint will blaantly ignore the ignore files!
63
+ // with "rules", "languageOptions", "files", ... or anything else (ESLint v9
64
+ // flat config). Otherwise ESLint will blatantly ignore the ignored files!
56
65
  {
57
66
  ignores: [
58
67
  'coverage/',
@@ -63,27 +72,39 @@ export default [
63
72
  ]
64
73
  ```
65
74
 
66
- This includes a number of configurations:
67
75
 
68
- * `eslint-recommended`: recommended JavaScript config from ESLint.
76
+ Configurations
77
+ --------------
78
+
79
+ This includes a number of individual configurations:
80
+
81
+ * `plugjs/basic/base`: basic configuration of ESLint rules.
82
+ * `plugjs/basic/stylistic`: style shared between JavaScript and TypeScript.
83
+ * `plugjs/basic/unicorn`: extra niceties from the ESLint Unicorn plugin.
84
+ * `plugjs/basic/importx`: defines the style of our imports.
85
+
86
+ * `plugjs/javascript/shared`: shared configuration for JavaScript files.
87
+ * `plugjs/javascript/commonjs`: marks `*.cjs` files as `commonjs`.
88
+
89
+ * `plugjs/javascript/modules`: marks `*.mjs` files as `module`.
90
+ * `plugjs/typescript/plugin`: defines the "@typescript-eslint" plugin.
91
+ * `plugjs/typescript/options`: configuration for "@typescript-eslint".
92
+ * `plugjs/typescript/overrides`: our rules overriding recommended.
93
+
94
+ A set of grouped configurations are also available:
69
95
 
70
- * `plugjs-base`: basic configuration of ESLint rules.
71
- * `plugjs-stylistic`: style shared between JavaScript and TypeScript.
72
- * `plugjs-unicorn`: extra niceties from the ESLint Unicorn plugin.
73
- * `plugjs-importx`: defines the style of our imports.
96
+ * `plugjs/basic`: basic rules shared between JavaScript and TypeScript.
97
+ * includes all `plugjs/basic/...` individual configurations
98
+ * `plugjs/javascript`: rules specific to JavaScript code bases.
99
+ * includes all `plugjs/javascript/...` individual configurations
100
+ * `plugjs/typescript`: rules specific to TypeScript code bases.
101
+ * includes all `plugjs/typescript/...` individual configurations _and_...
102
+ * ...other rules from `typescript-eslint/recommended`: all other recommended
103
+ Typescript rules, restricted to `.ts`, `.cts`, and `.mts` files.
74
104
 
75
- * `plugjs-javascript`: basic extra rules for JavaScript sources.
76
- * `plugjs-javascript-cjs`: marks `*.cjs` files as `commonjs`.
77
- * `plugjs-javascript-mjs`: marks `*.mjs` files as `module`.
105
+ The default configuration exported by the plugin includes all the configurations
106
+ listed above _and_ the base `eslint/js/recommended` configuration from ESLint.
78
107
 
79
- * `typescript-eslint/recommended`: imports all the configurations from
80
- TypeScript ESlint recommended, but restrict them to operate only on
81
- `.ts`, `.cts`, and `.mts` files. This *should* include:
82
- * `typescript-eslint/base`: basic parser configuration.
83
- * `typescript-eslint/eslint-recommended`: disable ESLint rules conflicting
84
- with TypeScript.
85
- * `typescript-eslint/recommended`: recommended config for TypeScript
86
- * `plugjs-typescript`: our rules overriding `typescript-eslint/recommended`.
87
108
 
88
109
  Legal Stuff
89
110
  -----------
@@ -0,0 +1,22 @@
1
+ import type { ESLintConfig } from '.';
2
+ /** Basic configuration of ESLint rules. */
3
+ export declare const base: ESLintConfig<'plugjs/basic/base'>;
4
+ /** Style shared between JavaScript and TypeScript. */
5
+ export declare const stylistic: ESLintConfig<'plugjs/basic/stylistic'>;
6
+ /** Extra niceties from the ESLint Unicorn plugin. */
7
+ export declare const unicorn: ESLintConfig<'plugjs/basic/unicorn'>;
8
+ /** Defines the style of our imports. */
9
+ export declare const importx: ESLintConfig<'plugjs/basic/importx'>;
10
+ /**
11
+ * Base module: declares all the common rules shared between JavaScript and
12
+ * TypeScript code bases.
13
+ *
14
+ * This module includes these configurations:
15
+ *
16
+ * * `plugjs/basic/base`: basic configuration of ESLint rules.
17
+ * * `plugjs/basic/stylistic`: style shared between JavaScript and TypeScript.
18
+ * * `plugjs/basic/unicorn`: extra niceties from the ESLint Unicorn plugin.
19
+ * * `plugjs/basic/importx`: defines the style of our imports.
20
+ */
21
+ declare const _default: readonly [ESLintConfig<"plugjs/basic/base">, ESLintConfig<"plugjs/basic/stylistic">, ESLintConfig<"plugjs/basic/unicorn">, ESLintConfig<"plugjs/basic/importx">];
22
+ export default _default;
package/dist/basic.js ADDED
@@ -0,0 +1,170 @@
1
+ import stylisticPlugin from '@stylistic/eslint-plugin';
2
+ import importxPlugin from 'eslint-plugin-import-x';
3
+ import unicornPlugin from 'eslint-plugin-unicorn';
4
+ import globals from 'globals';
5
+ /* ========================================================================== */
6
+ /** Basic configuration of ESLint rules. */
7
+ export const base = {
8
+ name: 'plugjs/basic/base',
9
+ languageOptions: {
10
+ globals: globals.es2024,
11
+ },
12
+ rules: {
13
+ 'camelcase': ['error', {
14
+ properties: 'never',
15
+ }],
16
+ 'curly': ['error', 'multi-line'],
17
+ 'new-cap': 'error',
18
+ 'no-caller': 'error',
19
+ 'no-cond-assign': 'off', // overrides eslint recommended
20
+ 'no-console': 'warn',
21
+ 'no-debugger': 'warn',
22
+ 'no-extend-native': 'error',
23
+ 'no-extra-bind': 'error',
24
+ 'no-multi-str': 'error',
25
+ 'no-new-native-nonconstructor': 'error',
26
+ 'no-new-wrappers': 'error',
27
+ 'no-object-constructor': 'error',
28
+ 'no-template-curly-in-string': 'error',
29
+ 'no-throw-literal': 'error',
30
+ 'no-useless-concat': 'error',
31
+ 'no-var': 'error',
32
+ 'no-warning-comments': 'warn',
33
+ 'one-var': ['error', 'never'],
34
+ 'prefer-const': ['error', {
35
+ destructuring: 'all',
36
+ }],
37
+ 'prefer-promise-reject-errors': 'error',
38
+ 'prefer-rest-params': 'error',
39
+ 'prefer-spread': 'error',
40
+ },
41
+ };
42
+ /* ========================================================================== */
43
+ /** Style shared between JavaScript and TypeScript. */
44
+ export const stylistic = {
45
+ name: 'plugjs/basic/stylistic',
46
+ plugins: {
47
+ '@stylistic': stylisticPlugin,
48
+ },
49
+ rules: {
50
+ '@stylistic/array-bracket-newline': 'off',
51
+ '@stylistic/array-bracket-spacing': ['error', 'always'],
52
+ '@stylistic/arrow-parens': ['error', 'always'],
53
+ '@stylistic/block-spacing': ['error', 'always'],
54
+ '@stylistic/brace-style': 'error',
55
+ '@stylistic/comma-dangle': ['error', 'always-multiline'],
56
+ '@stylistic/comma-spacing': 'error',
57
+ '@stylistic/comma-style': 'error',
58
+ '@stylistic/computed-property-spacing': 'error',
59
+ '@stylistic/eol-last': ['error', 'always'],
60
+ '@stylistic/function-call-spacing': 'error',
61
+ '@stylistic/generator-star-spacing': ['error', 'after'],
62
+ '@stylistic/indent': ['error', 2, {
63
+ CallExpression: {
64
+ 'arguments': 2,
65
+ },
66
+ FunctionDeclaration: {
67
+ 'body': 1,
68
+ 'parameters': 2,
69
+ },
70
+ FunctionExpression: {
71
+ 'body': 1,
72
+ 'parameters': 2,
73
+ },
74
+ MemberExpression: 2,
75
+ ObjectExpression: 1,
76
+ SwitchCase: 1,
77
+ flatTernaryExpressions: true,
78
+ offsetTernaryExpressions: false,
79
+ }],
80
+ '@stylistic/key-spacing': 'error',
81
+ '@stylistic/keyword-spacing': 'error',
82
+ '@stylistic/linebreak-style': 'error',
83
+ '@stylistic/no-mixed-spaces-and-tabs': 'error',
84
+ '@stylistic/no-multi-spaces': 'error',
85
+ '@stylistic/no-multiple-empty-lines': ['error', { 'max': 2, 'maxBOF': 0, 'maxEOF': 1 }],
86
+ '@stylistic/no-tabs': 'error',
87
+ '@stylistic/no-trailing-spaces': 'error',
88
+ '@stylistic/object-curly-spacing': ['error', 'always'],
89
+ '@stylistic/operator-linebreak': ['error', 'after', {
90
+ 'overrides': {
91
+ '?': 'ignore',
92
+ ':': 'ignore',
93
+ '|': 'before',
94
+ '&': 'before',
95
+ },
96
+ }],
97
+ '@stylistic/padded-blocks': ['error', 'never'],
98
+ '@stylistic/quote-props': ['error', 'consistent'],
99
+ '@stylistic/quotes': ['error', 'single', { 'allowTemplateLiterals': 'never' }],
100
+ '@stylistic/semi': ['error', 'never'],
101
+ '@stylistic/semi-spacing': 'error',
102
+ '@stylistic/space-before-blocks': 'error',
103
+ '@stylistic/space-before-function-paren': ['error', {
104
+ asyncArrow: 'always',
105
+ anonymous: 'never',
106
+ named: 'never',
107
+ }],
108
+ '@stylistic/spaced-comment': ['error', 'always', { 'markers': ['/ <reference'] }],
109
+ '@stylistic/switch-colon-spacing': 'error',
110
+ '@stylistic/rest-spread-spacing': 'error',
111
+ '@stylistic/yield-star-spacing': ['error', 'after'],
112
+ },
113
+ };
114
+ /* ========================================================================== */
115
+ /** Extra niceties from the ESLint Unicorn plugin. */
116
+ export const unicorn = {
117
+ name: 'plugjs/basic/unicorn',
118
+ plugins: {
119
+ 'unicorn': unicornPlugin,
120
+ },
121
+ rules: {
122
+ 'unicorn/empty-brace-spaces': 'error',
123
+ 'unicorn/no-instanceof-builtins': 'error',
124
+ 'unicorn/prefer-node-protocol': 'error',
125
+ },
126
+ };
127
+ /* ========================================================================== */
128
+ /** Defines the style of our imports. */
129
+ export const importx = {
130
+ name: 'plugjs/basic/importx',
131
+ plugins: {
132
+ 'import-x': importxPlugin,
133
+ },
134
+ settings: {
135
+ 'import-x/extensions': ['.ts', '.cts', '.mts', '.js', '.cjs', '.mjs'],
136
+ 'import-x/external-module-folders': ['node_modules', 'node_modules/@types'],
137
+ 'import-x/parsers': {
138
+ '@typescript-eslint/parser': ['.ts', '.cts', '.mts'],
139
+ 'espree': ['.js', '.mjs', '.cjs'],
140
+ },
141
+ 'import-x/resolver': {
142
+ 'eslint-import-resolver-typescript': true,
143
+ 'eslint-import-resolver-node': true,
144
+ },
145
+ },
146
+ rules: {
147
+ 'import-x/consistent-type-specifier-style': ['error', 'prefer-top-level'],
148
+ 'import-x/no-cycle': ['error'],
149
+ 'import-x/no-duplicates': ['error'],
150
+ 'import-x/no-extraneous-dependencies': ['off'],
151
+ 'import-x/order': ['error', {
152
+ 'groups': ['builtin', 'external', 'internal', ['parent', 'sibling'], 'index', 'object', 'type'],
153
+ 'newlines-between': 'always',
154
+ 'warnOnUnassignedImports': true,
155
+ }],
156
+ },
157
+ };
158
+ /* ========================================================================== */
159
+ /**
160
+ * Base module: declares all the common rules shared between JavaScript and
161
+ * TypeScript code bases.
162
+ *
163
+ * This module includes these configurations:
164
+ *
165
+ * * `plugjs/basic/base`: basic configuration of ESLint rules.
166
+ * * `plugjs/basic/stylistic`: style shared between JavaScript and TypeScript.
167
+ * * `plugjs/basic/unicorn`: extra niceties from the ESLint Unicorn plugin.
168
+ * * `plugjs/basic/importx`: defines the style of our imports.
169
+ */
170
+ export default [base, stylistic, unicorn, importx];
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/check.js ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ /* eslint-disable no-console */
3
+ import { ESLint } from 'eslint';
4
+ /** @type Record<string, string[]> */
5
+ const deprecated = {};
6
+ // Pretty colors
7
+ const ylw = '\u001b[38;5;220m'; // yellow
8
+ const grn = '\u001b[38;5;76m'; // greenish
9
+ const rst = '\u001b[0m'; // reset
10
+ // Running in GitHub Actions?
11
+ const gh = process.env.GITHUB_ACTIONS === 'true';
12
+ // Files to probe to surface deprecations across JS/TS variants
13
+ const FILES = ['x.js', 'x.mjs', 'x.cjs', 'x.ts', 'x.cts', 'x.mts'];
14
+ // Create a new ESLint
15
+ const eslint = new ESLint();
16
+ // Fake lint some sources (JS, TS, ...) to get the deprecated rules
17
+ for (const f of FILES) {
18
+ const results = await eslint.lintText('var foo="bar";', { filePath: f });
19
+ for (const result of results) {
20
+ for (const rule of result.usedDeprecatedRules) {
21
+ deprecated[rule.ruleId] = rule.replacedBy;
22
+ }
23
+ }
24
+ }
25
+ // Print the deprecated rules in order
26
+ const deprecations = Object.entries(deprecated);
27
+ if (deprecations.length !== 0) {
28
+ deprecations
29
+ .sort(([a], [b]) => a.localeCompare(b))
30
+ .forEach(([rule, replacement]) => {
31
+ if (replacement.length) {
32
+ console.log(`Rule "${ylw}${rule}${rst}" deprecated and replaced by "${grn}${replacement.join(`${rst}", "${grn}`)}${rst}"`);
33
+ if (gh)
34
+ console.log(`::warning::Rule "${rule}" deprecated and replaced by "${replacement.join(', ')}"`);
35
+ }
36
+ else {
37
+ console.log(`Rule "${ylw}${rule}${rst}" deprecated without replacement`);
38
+ if (gh)
39
+ console.log(`::warning::Rule "${rule}" deprecated without replacement`);
40
+ }
41
+ });
42
+ }
43
+ else {
44
+ console.log(`${grn}Success:${rst} no deprecated rules found!`);
45
+ }
@@ -0,0 +1,45 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ /** A _named_ ESLint configuration. */
3
+ export type ESLintConfig<N extends string = string> = {
4
+ readonly name: N;
5
+ } & TSESLint.FlatConfig.Config;
6
+ /** All ESLint configurations. */
7
+ export declare const configs: {
8
+ readonly basic: readonly [ESLintConfig<"plugjs/basic/base">, ESLintConfig<"plugjs/basic/stylistic">, ESLintConfig<"plugjs/basic/unicorn">, ESLintConfig<"plugjs/basic/importx">];
9
+ readonly 'basic/base': ESLintConfig<"plugjs/basic/base">;
10
+ readonly 'basic/stylistic': ESLintConfig<"plugjs/basic/stylistic">;
11
+ readonly 'basic/unicorn': ESLintConfig<"plugjs/basic/unicorn">;
12
+ readonly 'basic/importx': ESLintConfig<"plugjs/basic/importx">;
13
+ readonly javascript: readonly [ESLintConfig<"plugjs/javascript/shared">, ESLintConfig<"plugjs/javascript/commonjs">, ESLintConfig<"plugjs/javascript/modules">];
14
+ readonly 'javascript/shared': ESLintConfig<"plugjs/javascript/shared">;
15
+ readonly 'javascript/commonjs': ESLintConfig<"plugjs/javascript/commonjs">;
16
+ readonly 'javascript/modules': ESLintConfig<"plugjs/javascript/modules">;
17
+ readonly typescript: readonly [ESLintConfig<"plugjs/typescript/plugin">, ESLintConfig<"plugjs/typescript/options">, ...ESLintConfig[], ESLintConfig<"plugjs/typescript/overrides">];
18
+ readonly 'typescript/plugin': ESLintConfig<"plugjs/typescript/plugin">;
19
+ readonly 'typescript/options': ESLintConfig<"plugjs/typescript/options">;
20
+ readonly 'typescript/overrides': ESLintConfig<"plugjs/typescript/overrides">;
21
+ };
22
+ /**
23
+ * The default ESLint configuration for PlugJS.
24
+ *
25
+ * This includes all the configurations from:
26
+ *
27
+ * * `eslint/js/recommended`: the base ESLint recommended rules for JavaScript.
28
+ * * `plugjs/basic`: basic rules shared between JavaScript and TypeScript.
29
+ * * `plugjs/basic/base`: basic configuration of ESLint rules.
30
+ * * `plugjs/basic/stylistic`: style shared between JavaScript and TypeScript.
31
+ * * `plugjs/basic/unicorn`: extra niceties from the ESLint Unicorn plugin.
32
+ * * `plugjs/basic/importx`: defines the style of our imports.
33
+ * * `plugjs/javascript`: rules specific to JavaScript code bases.
34
+ * * `plugjs/javascript/shared`: shared configuration for JavaScript files.
35
+ * * `plugjs/javascript/commonjs`: marks `*.cjs` files as `commonjs`.
36
+ * * `plugjs/javascript/modules`: marks `*.mjs` files as `module`.
37
+ * * `plugjs/typescript`: rules specific to TypeScript code bases.
38
+ * * `plugjs/typescript/plugin`: defines the "@typescript-eslint" plugin.
39
+ * * `plugjs/typescript/options`: configuration for "@typescript-eslint".
40
+ * * other rules from `typescript-eslint/recommended`: all other recommended
41
+ * Typescript rules, restricted to `.ts`, `.cts`, and `.mts` files.
42
+ * * `plugjs/typescript/overrides`: our rules overriding recommended.
43
+ */
44
+ declare const _default: readonly [ESLintConfig<"eslint/js/recommended">, ESLintConfig<"plugjs/basic/base">, ESLintConfig<"plugjs/basic/stylistic">, ESLintConfig<"plugjs/basic/unicorn">, ESLintConfig<"plugjs/basic/importx">, ESLintConfig<"plugjs/javascript/shared">, ESLintConfig<"plugjs/javascript/commonjs">, ESLintConfig<"plugjs/javascript/modules">, ESLintConfig<"plugjs/typescript/plugin">, ESLintConfig<"plugjs/typescript/options">, ...ESLintConfig[], ESLintConfig<"plugjs/typescript/overrides">];
45
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ import js from '@eslint/js';
2
+ import basicConfigs, * as basic from './basic.js';
3
+ import javascriptConfigs, * as javascript from './javascript.js';
4
+ import typescriptConfigs, * as typescript from './typescript.js';
5
+ /* ========================================================================== *
6
+ * INTERNAL *
7
+ * ========================================================================== */
8
+ /* Give the "eslint/js/recommended" a name so that it shows up in the GUI */
9
+ const initial = {
10
+ name: 'eslint/js/recommended',
11
+ ...js.configs.recommended,
12
+ };
13
+ /* ========================================================================== *
14
+ * EXPORTS *
15
+ * ========================================================================== */
16
+ /** All ESLint configurations. */
17
+ export const configs = {
18
+ 'basic': basicConfigs,
19
+ 'basic/base': basic.base,
20
+ 'basic/stylistic': basic.stylistic,
21
+ 'basic/unicorn': basic.unicorn,
22
+ 'basic/importx': basic.importx,
23
+ 'javascript': javascriptConfigs,
24
+ 'javascript/shared': javascript.shared,
25
+ 'javascript/commonjs': javascript.commonjs,
26
+ 'javascript/modules': javascript.modules,
27
+ 'typescript': typescriptConfigs,
28
+ 'typescript/plugin': typescript.plugin,
29
+ 'typescript/options': typescript.options,
30
+ 'typescript/overrides': typescript.overrides,
31
+ };
32
+ /**
33
+ * The default ESLint configuration for PlugJS.
34
+ *
35
+ * This includes all the configurations from:
36
+ *
37
+ * * `eslint/js/recommended`: the base ESLint recommended rules for JavaScript.
38
+ * * `plugjs/basic`: basic rules shared between JavaScript and TypeScript.
39
+ * * `plugjs/basic/base`: basic configuration of ESLint rules.
40
+ * * `plugjs/basic/stylistic`: style shared between JavaScript and TypeScript.
41
+ * * `plugjs/basic/unicorn`: extra niceties from the ESLint Unicorn plugin.
42
+ * * `plugjs/basic/importx`: defines the style of our imports.
43
+ * * `plugjs/javascript`: rules specific to JavaScript code bases.
44
+ * * `plugjs/javascript/shared`: shared configuration for JavaScript files.
45
+ * * `plugjs/javascript/commonjs`: marks `*.cjs` files as `commonjs`.
46
+ * * `plugjs/javascript/modules`: marks `*.mjs` files as `module`.
47
+ * * `plugjs/typescript`: rules specific to TypeScript code bases.
48
+ * * `plugjs/typescript/plugin`: defines the "@typescript-eslint" plugin.
49
+ * * `plugjs/typescript/options`: configuration for "@typescript-eslint".
50
+ * * other rules from `typescript-eslint/recommended`: all other recommended
51
+ * Typescript rules, restricted to `.ts`, `.cts`, and `.mts` files.
52
+ * * `plugjs/typescript/overrides`: our rules overriding recommended.
53
+ */
54
+ export default [
55
+ initial,
56
+ ...basicConfigs,
57
+ ...javascriptConfigs,
58
+ ...typescriptConfigs,
59
+ ];
@@ -0,0 +1,18 @@
1
+ import type { ESLintConfig } from '.';
2
+ /** Shared configuration for JavaScript files (CommonJS or ES modules). */
3
+ export declare const shared: ESLintConfig<'plugjs/javascript/shared'>;
4
+ /** Marks `*.cjs` files as `commonjs`. */
5
+ export declare const commonjs: ESLintConfig<'plugjs/javascript/commonjs'>;
6
+ /** Marks `*.mjs` files as `module`. */
7
+ export declare const modules: ESLintConfig<'plugjs/javascript/modules'>;
8
+ /**
9
+ * JavaScript module: declares all the common rules for JavaScript code bases.
10
+ *
11
+ * This module includes these configurations:
12
+ *
13
+ * * `plugjs/javascript/shared`: shared configuration for JavaScript files.
14
+ * * `plugjs/javascript/commonjs`: marks `*.cjs` files as `commonjs`.
15
+ * * `plugjs/javascript/modules`: marks `*.mjs` files as `module`.
16
+ */
17
+ declare const _default: readonly [ESLintConfig<"plugjs/javascript/shared">, ESLintConfig<"plugjs/javascript/commonjs">, ESLintConfig<"plugjs/javascript/modules">];
18
+ export default _default;
@@ -0,0 +1,80 @@
1
+ /** Basic extra rules for JavaScript sources. */
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import process from 'node:process';
5
+ import globals from 'globals';
6
+ /* ========================================================================== *
7
+ * INTERNALS *
8
+ * ========================================================================== */
9
+ function findModuleType(directory) {
10
+ const file = path.join(directory, 'package.json');
11
+ try {
12
+ const data = JSON.parse(fs.readFileSync(file, 'utf-8'));
13
+ return data.type || 'commonjs';
14
+ }
15
+ catch (error) {
16
+ if (error.code !== 'ENOENT') {
17
+ throw new Error(`Error reading "${file}"`, { cause: error });
18
+ }
19
+ const parent = path.dirname(directory);
20
+ if (parent === directory)
21
+ return 'commonjs';
22
+ return findModuleType(parent);
23
+ }
24
+ }
25
+ const moduleType = findModuleType(process.cwd());
26
+ /* ========================================================================== *
27
+ * CONFIGS *
28
+ * ========================================================================== */
29
+ /** Shared configuration for JavaScript files (CommonJS or ES modules). */
30
+ export const shared = {
31
+ name: 'plugjs/javascript/shared',
32
+ files: ['**/*.js', '**/*.cjs', '**/*.mjs'],
33
+ rules: {
34
+ 'guard-for-in': 'error',
35
+ 'no-array-constructor': 'error',
36
+ 'no-invalid-this': 'error',
37
+ 'no-unused-expressions': 'error',
38
+ 'no-unused-vars': ['error', {
39
+ args: 'after-used',
40
+ argsIgnorePattern: '^_',
41
+ }],
42
+ },
43
+ };
44
+ /* ========================================================================== */
45
+ /** Marks `*.cjs` files as `commonjs`. */
46
+ export const commonjs = {
47
+ name: 'plugjs/javascript/commonjs',
48
+ files: moduleType === 'commonjs' ? ['**/*.cjs', '**/*.js'] : ['**/*.cjs'],
49
+ languageOptions: {
50
+ sourceType: 'commonjs',
51
+ globals: globals.node,
52
+ },
53
+ rules: {
54
+ 'strict': ['error', 'global'],
55
+ },
56
+ };
57
+ /* ========================================================================== */
58
+ /** Marks `*.mjs` files as `module`. */
59
+ export const modules = {
60
+ name: 'plugjs/javascript/modules',
61
+ files: moduleType === 'module' ? ['**/*.mjs', '**/*.js'] : ['**/*.mjs'],
62
+ languageOptions: {
63
+ sourceType: 'module',
64
+ globals: globals.nodeBuiltin,
65
+ },
66
+ rules: {
67
+ 'strict': ['error', 'never'],
68
+ },
69
+ };
70
+ /* ========================================================================== */
71
+ /**
72
+ * JavaScript module: declares all the common rules for JavaScript code bases.
73
+ *
74
+ * This module includes these configurations:
75
+ *
76
+ * * `plugjs/javascript/shared`: shared configuration for JavaScript files.
77
+ * * `plugjs/javascript/commonjs`: marks `*.cjs` files as `commonjs`.
78
+ * * `plugjs/javascript/modules`: marks `*.mjs` files as `module`.
79
+ */
80
+ export default [shared, commonjs, modules];
@@ -0,0 +1,20 @@
1
+ import type { ESLintConfig } from './index';
2
+ /** Define the "@typescript-eslint" plugin. */
3
+ export declare const plugin: ESLintConfig<'plugjs/typescript/plugin'>;
4
+ /** Configuration for "@typescript-eslint" scoped to TypeScript sources. */
5
+ export declare const options: ESLintConfig<'plugjs/typescript/options'>;
6
+ /** Our own rules overriding `typescript-eslint/recommended`. */
7
+ export declare const overrides: ESLintConfig<'plugjs/typescript/overrides'>;
8
+ /**
9
+ * TypeScript module: declares all the common rules for TypeScript code bases.
10
+ *
11
+ * This module includes these configurations:
12
+ *
13
+ * * `plugjs/typescript/plugin`: defines the "@typescript-eslint" plugin.
14
+ * * `plugjs/typescript/options`: configuration for "@typescript-eslint".
15
+ * * other rules from `typescript-eslint/recommended`: all other recommended
16
+ * Typescript rules, restricted to `.ts`, `.cts`, and `.mts` files.
17
+ * * `plugjs/typescript/overrides`: our rules overriding recommended.
18
+ */
19
+ declare const _default: readonly [ESLintConfig<"plugjs/typescript/plugin">, ESLintConfig<"plugjs/typescript/options">, ...ESLintConfig[], ESLintConfig<"plugjs/typescript/overrides">];
20
+ export default _default;
@@ -0,0 +1,71 @@
1
+ import tseslint from 'typescript-eslint';
2
+ /* ========================================================================== *
3
+ * INTERNALS *
4
+ * ========================================================================== */
5
+ /**
6
+ * Split the "base" config from "typescript-eslint" into its plugin definition
7
+ * and the rest of the config (namely, the language options). We'll want to
8
+ * apply the plugin **globally** so that all configs can use it, but the
9
+ * language options only to TypeScript files.
10
+ */
11
+ const { plugins, ...opts } = tseslint.configs.base;
12
+ /** Map the "typescript-eslint" recommended configs */
13
+ const configs = tseslint.configs.recommended.map((config) => {
14
+ // Allow the "@typescript-eslint" plugin to be visible everywhere...
15
+ if (config.name === tseslint.configs.base.name)
16
+ return null;
17
+ config.files = ['**/*.ts', '**/*.cts', '**/*.mts'];
18
+ return config;
19
+ }).filter((config) => !!config);
20
+ /* ========================================================================== *
21
+ * CONFIGS *
22
+ * ========================================================================== */
23
+ /** Define the "@typescript-eslint" plugin. */
24
+ export const plugin = {
25
+ name: 'plugjs/typescript/plugin',
26
+ plugins,
27
+ };
28
+ /* ========================================================================== */
29
+ /** Configuration for "@typescript-eslint" scoped to TypeScript sources. */
30
+ export const options = {
31
+ ...opts,
32
+ files: ['**/*.ts', '**/*.cts', '**/*.mts'],
33
+ name: 'plugjs/typescript/options',
34
+ };
35
+ /* ========================================================================== */
36
+ /** Our own rules overriding `typescript-eslint/recommended`. */
37
+ export const overrides = {
38
+ name: 'plugjs/typescript/overrides',
39
+ files: ['**/*.ts', '**/*.cts', '**/*.mts'],
40
+ rules: {
41
+ 'no-unused-vars': 'off', // overrides ESLint Recommended for TypeScript
42
+ 'no-dupe-class-members': 'off', // overrides ESLint Recommended for TypeScript
43
+ '@typescript-eslint/consistent-type-imports': 'error',
44
+ '@typescript-eslint/explicit-function-return-type': ['error', {
45
+ allowExpressions: true,
46
+ allowDirectConstAssertionInArrowFunctions: true,
47
+ allowConciseArrowFunctionExpressionsStartingWithVoid: true,
48
+ }],
49
+ '@typescript-eslint/no-dupe-class-members': 'error',
50
+ '@typescript-eslint/no-empty-object-type': 'off',
51
+ '@typescript-eslint/no-explicit-any': 'off',
52
+ '@typescript-eslint/no-floating-promises': 'error',
53
+ '@typescript-eslint/no-invalid-this': 'error',
54
+ '@typescript-eslint/no-unused-vars': ['error', {
55
+ args: 'after-used',
56
+ argsIgnorePattern: '^_',
57
+ }],
58
+ },
59
+ };
60
+ /**
61
+ * TypeScript module: declares all the common rules for TypeScript code bases.
62
+ *
63
+ * This module includes these configurations:
64
+ *
65
+ * * `plugjs/typescript/plugin`: defines the "@typescript-eslint" plugin.
66
+ * * `plugjs/typescript/options`: configuration for "@typescript-eslint".
67
+ * * other rules from `typescript-eslint/recommended`: all other recommended
68
+ * Typescript rules, restricted to `.ts`, `.cts`, and `.mts` files.
69
+ * * `plugjs/typescript/overrides`: our rules overriding recommended.
70
+ */
71
+ export default [plugin, options, ...configs, overrides];
package/package.json CHANGED
@@ -1,19 +1,29 @@
1
1
  {
2
2
  "name": "@plugjs/eslint-plugin",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Shared ESLint configurations and extras",
5
- "main": "./index.mjs",
6
5
  "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ }
15
+ }
16
+ },
7
17
  "author": "Team Juit <developers@juit.com>",
8
18
  "license": "Apache-2.0",
9
19
  "bin": {
10
- "eslint-check-deprecated-rules": "./check.mjs"
20
+ "eslint-check-deprecated-rules": "./dist/check.js"
11
21
  },
12
22
  "scripts": {
13
- "build": "node check.mjs && eslint"
23
+ "build": "./build.sh"
14
24
  },
15
25
  "dependencies": {
16
- "@eslint/js": "^9.34.0",
26
+ "@eslint/js": "^9.35.0",
17
27
  "@stylistic/eslint-plugin": "^5.3.1",
18
28
  "eslint-import-resolver-node": "^0.3.9",
19
29
  "eslint-import-resolver-typescript": "^4.4.4",
@@ -23,15 +33,18 @@
23
33
  "typescript-eslint": "^8.42.0"
24
34
  },
25
35
  "devDependencies": {
26
- "eslint": "^9.34.0"
36
+ "@types/node": "^24.3.1",
37
+ "eslint": "^9.35.0",
38
+ "type-fest": "^4.41.0",
39
+ "typescript": "^5.9.2"
27
40
  },
28
41
  "peerDependencies": {
29
- "eslint": "^9.34.0"
42
+ "eslint": "^9.35.0"
30
43
  },
31
44
  "files": [
32
45
  "*.md",
33
- "configs/",
34
- "index.mjs"
46
+ "dist/",
47
+ "src/"
35
48
  ],
36
49
  "repository": {
37
50
  "type": "git",
@@ -3,11 +3,13 @@ import importxPlugin from 'eslint-plugin-import-x'
3
3
  import unicornPlugin from 'eslint-plugin-unicorn'
4
4
  import globals from 'globals'
5
5
 
6
+ import type { ESLintConfig } from '.'
7
+
6
8
  /* ========================================================================== */
7
9
 
8
10
  /** Basic configuration of ESLint rules. */
9
- export const base = {
10
- name: 'plugjs-base',
11
+ export const base: ESLintConfig<'plugjs/basic/base'> = {
12
+ name: 'plugjs/basic/base',
11
13
 
12
14
  languageOptions: {
13
15
  globals: globals.es2024,
@@ -48,8 +50,8 @@ export const base = {
48
50
  /* ========================================================================== */
49
51
 
50
52
  /** Style shared between JavaScript and TypeScript. */
51
- export const stylistic = {
52
- name: 'plugjs-stylistic',
53
+ export const stylistic: ESLintConfig<'plugjs/basic/stylistic'> = {
54
+ name: 'plugjs/basic/stylistic',
53
55
 
54
56
  plugins: {
55
57
  '@stylistic': stylisticPlugin,
@@ -124,8 +126,8 @@ export const stylistic = {
124
126
  /* ========================================================================== */
125
127
 
126
128
  /** Extra niceties from the ESLint Unicorn plugin. */
127
- export const unicorn = {
128
- name: 'plugjs-unicorn',
129
+ export const unicorn: ESLintConfig<'plugjs/basic/unicorn'> = {
130
+ name: 'plugjs/basic/unicorn',
129
131
 
130
132
  plugins: {
131
133
  'unicorn': unicornPlugin,
@@ -141,8 +143,8 @@ export const unicorn = {
141
143
  /* ========================================================================== */
142
144
 
143
145
  /** Defines the style of our imports. */
144
- export const importx = {
145
- name: 'plugjs-importx',
146
+ export const importx: ESLintConfig<'plugjs/basic/importx'> = {
147
+ name: 'plugjs/basic/importx',
146
148
 
147
149
  plugins: {
148
150
  'import-x': importxPlugin,
@@ -182,9 +184,9 @@ export const importx = {
182
184
  *
183
185
  * This module includes these configurations:
184
186
  *
185
- * * `plugjs-base`: basic configuration of ESLint rules.
186
- * * `plugjs-stylistic`: style shared between JavaScript and TypeScript.
187
- * * `plugjs-unicorn`: extra niceties from the ESLint Unicorn plugin.
188
- * * `plugjs-importx`: defines the style of our imports.
187
+ * * `plugjs/basic/base`: basic configuration of ESLint rules.
188
+ * * `plugjs/basic/stylistic`: style shared between JavaScript and TypeScript.
189
+ * * `plugjs/basic/unicorn`: extra niceties from the ESLint Unicorn plugin.
190
+ * * `plugjs/basic/importx`: defines the style of our imports.
189
191
  */
190
- export default [ base, stylistic, unicorn, importx ]
192
+ export default [ base, stylistic, unicorn, importx ] as const
@@ -4,7 +4,7 @@
4
4
  import { ESLint } from 'eslint'
5
5
 
6
6
  /** @type Record<string, string[]> */
7
- const deprecated = {}
7
+ const deprecated: Record<string, string[]> = {}
8
8
 
9
9
  // Pretty colors
10
10
  const ylw = '\u001b[38;5;220m' // yellow
@@ -13,11 +13,14 @@ const rst = '\u001b[0m' // reset
13
13
  // Running in GitHub Actions?
14
14
  const gh = process.env.GITHUB_ACTIONS === 'true'
15
15
 
16
+ // Files to probe to surface deprecations across JS/TS variants
17
+ const FILES = [ 'x.js', 'x.mjs', 'x.cjs', 'x.ts', 'x.cts', 'x.mts' ]
18
+
16
19
  // Create a new ESLint
17
20
  const eslint = new ESLint()
18
21
 
19
22
  // Fake lint some sources (JS, TS, ...) to get the deprecated rules
20
- for (const f of [ 'x.js', 'x.mjs', 'x.cjs', 'x.ts', 'x.cts', 'x.mts' ]) {
23
+ for (const f of FILES) {
21
24
  const results = await eslint.lintText('var foo="bar";', { filePath: f })
22
25
  for (const result of results) {
23
26
  for (const rule of result.usedDeprecatedRules) {
package/src/index.ts ADDED
@@ -0,0 +1,78 @@
1
+ import js from '@eslint/js'
2
+
3
+ import basicConfigs, * as basic from './basic.js'
4
+ import javascriptConfigs, * as javascript from './javascript.js'
5
+ import typescriptConfigs, * as typescript from './typescript.js'
6
+
7
+ import type { TSESLint } from '@typescript-eslint/utils'
8
+
9
+ /* ========================================================================== *
10
+ * TYPES *
11
+ * ========================================================================== */
12
+
13
+ /** A _named_ ESLint configuration. */
14
+ export type ESLintConfig<N extends string = string> = {
15
+ readonly name: N
16
+ } & TSESLint.FlatConfig.Config
17
+
18
+ /* ========================================================================== *
19
+ * INTERNAL *
20
+ * ========================================================================== */
21
+
22
+ /* Give the "eslint/js/recommended" a name so that it shows up in the GUI */
23
+ const initial: ESLintConfig<'eslint/js/recommended'> = { // give a name to this config before we go completely nuts!
24
+ name: 'eslint/js/recommended',
25
+ ...js.configs.recommended,
26
+ }
27
+
28
+ /* ========================================================================== *
29
+ * EXPORTS *
30
+ * ========================================================================== */
31
+
32
+ /** All ESLint configurations. */
33
+ export const configs = {
34
+ 'basic': basicConfigs,
35
+ 'basic/base': basic.base,
36
+ 'basic/stylistic': basic.stylistic,
37
+ 'basic/unicorn': basic.unicorn,
38
+ 'basic/importx': basic.importx,
39
+
40
+ 'javascript': javascriptConfigs,
41
+ 'javascript/shared': javascript.shared,
42
+ 'javascript/commonjs': javascript.commonjs,
43
+ 'javascript/modules': javascript.modules,
44
+
45
+ 'typescript': typescriptConfigs,
46
+ 'typescript/plugin': typescript.plugin,
47
+ 'typescript/options': typescript.options,
48
+ 'typescript/overrides': typescript.overrides,
49
+ } as const
50
+
51
+ /**
52
+ * The default ESLint configuration for PlugJS.
53
+ *
54
+ * This includes all the configurations from:
55
+ *
56
+ * * `eslint/js/recommended`: the base ESLint recommended rules for JavaScript.
57
+ * * `plugjs/basic`: basic rules shared between JavaScript and TypeScript.
58
+ * * `plugjs/basic/base`: basic configuration of ESLint rules.
59
+ * * `plugjs/basic/stylistic`: style shared between JavaScript and TypeScript.
60
+ * * `plugjs/basic/unicorn`: extra niceties from the ESLint Unicorn plugin.
61
+ * * `plugjs/basic/importx`: defines the style of our imports.
62
+ * * `plugjs/javascript`: rules specific to JavaScript code bases.
63
+ * * `plugjs/javascript/shared`: shared configuration for JavaScript files.
64
+ * * `plugjs/javascript/commonjs`: marks `*.cjs` files as `commonjs`.
65
+ * * `plugjs/javascript/modules`: marks `*.mjs` files as `module`.
66
+ * * `plugjs/typescript`: rules specific to TypeScript code bases.
67
+ * * `plugjs/typescript/plugin`: defines the "@typescript-eslint" plugin.
68
+ * * `plugjs/typescript/options`: configuration for "@typescript-eslint".
69
+ * * other rules from `typescript-eslint/recommended`: all other recommended
70
+ * Typescript rules, restricted to `.ts`, `.cts`, and `.mts` files.
71
+ * * `plugjs/typescript/overrides`: our rules overriding recommended.
72
+ */
73
+ export default [
74
+ initial,
75
+ ...basicConfigs,
76
+ ...javascriptConfigs,
77
+ ...typescriptConfigs,
78
+ ] as const
@@ -0,0 +1,101 @@
1
+ /** Basic extra rules for JavaScript sources. */
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+ import process from 'node:process'
5
+
6
+ import globals from 'globals'
7
+
8
+ import type { ESLintConfig } from '.'
9
+
10
+ /* ========================================================================== *
11
+ * INTERNALS *
12
+ * ========================================================================== */
13
+
14
+ function findModuleType(directory: string): 'commonjs' | 'module' {
15
+ const file = path.join(directory, 'package.json')
16
+ try {
17
+ const data = JSON.parse(fs.readFileSync(file, 'utf-8'))
18
+ return data.type || 'commonjs'
19
+ } catch (error: any) {
20
+ if (error.code !== 'ENOENT') {
21
+ throw new Error(`Error reading "${file}"`, { cause: error })
22
+ }
23
+
24
+ const parent = path.dirname(directory)
25
+ if (parent === directory) return 'commonjs'
26
+ return findModuleType(parent)
27
+ }
28
+ }
29
+
30
+ const moduleType = findModuleType(process.cwd())
31
+
32
+ /* ========================================================================== *
33
+ * CONFIGS *
34
+ * ========================================================================== */
35
+
36
+ /** Shared configuration for JavaScript files (CommonJS or ES modules). */
37
+ export const shared: ESLintConfig<'plugjs/javascript/shared'> = {
38
+ name: 'plugjs/javascript/shared',
39
+
40
+ files: [ '**/*.js', '**/*.cjs', '**/*.mjs' ],
41
+
42
+ rules: {
43
+ 'guard-for-in': 'error',
44
+ 'no-array-constructor': 'error',
45
+ 'no-invalid-this': 'error',
46
+ 'no-unused-expressions': 'error',
47
+ 'no-unused-vars': [ 'error', {
48
+ args: 'after-used',
49
+ argsIgnorePattern: '^_',
50
+ } ],
51
+ },
52
+ }
53
+
54
+ /* ========================================================================== */
55
+
56
+ /** Marks `*.cjs` files as `commonjs`. */
57
+ export const commonjs: ESLintConfig<'plugjs/javascript/commonjs'> = {
58
+ name: 'plugjs/javascript/commonjs',
59
+
60
+ files: moduleType === 'commonjs' ? [ '**/*.cjs', '**/*.js' ] : [ '**/*.cjs' ],
61
+
62
+ languageOptions: {
63
+ sourceType: 'commonjs',
64
+ globals: globals.node,
65
+ },
66
+
67
+ rules: {
68
+ 'strict': [ 'error', 'global' ],
69
+ },
70
+ }
71
+
72
+ /* ========================================================================== */
73
+
74
+ /** Marks `*.mjs` files as `module`. */
75
+ export const modules: ESLintConfig<'plugjs/javascript/modules'> = {
76
+ name: 'plugjs/javascript/modules',
77
+
78
+ files: moduleType === 'module' ? [ '**/*.mjs', '**/*.js' ] : [ '**/*.mjs' ],
79
+
80
+ languageOptions: {
81
+ sourceType: 'module',
82
+ globals: globals.nodeBuiltin,
83
+ },
84
+
85
+ rules: {
86
+ 'strict': [ 'error', 'never' ],
87
+ },
88
+ }
89
+
90
+ /* ========================================================================== */
91
+
92
+ /**
93
+ * JavaScript module: declares all the common rules for JavaScript code bases.
94
+ *
95
+ * This module includes these configurations:
96
+ *
97
+ * * `plugjs/javascript/shared`: shared configuration for JavaScript files.
98
+ * * `plugjs/javascript/commonjs`: marks `*.cjs` files as `commonjs`.
99
+ * * `plugjs/javascript/modules`: marks `*.mjs` files as `module`.
100
+ */
101
+ export default [ shared, commonjs, modules ] as const
@@ -0,0 +1,86 @@
1
+ import tseslint from 'typescript-eslint'
2
+
3
+ import type { TSESLint } from '@typescript-eslint/utils'
4
+ import type { ESLintConfig } from './index'
5
+
6
+ /* ========================================================================== *
7
+ * INTERNALS *
8
+ * ========================================================================== */
9
+
10
+ /**
11
+ * Split the "base" config from "typescript-eslint" into its plugin definition
12
+ * and the rest of the config (namely, the language options). We'll want to
13
+ * apply the plugin **globally** so that all configs can use it, but the
14
+ * language options only to TypeScript files.
15
+ */
16
+ const { plugins, ...opts } = tseslint.configs.base as TSESLint.FlatConfig.Config
17
+
18
+ /** Map the "typescript-eslint" recommended configs */
19
+ const configs = tseslint.configs.recommended.map((config: TSESLint.FlatConfig.Config) => {
20
+ // Allow the "@typescript-eslint" plugin to be visible everywhere...
21
+ if (config.name === tseslint.configs.base.name) return null
22
+ config.files = [ '**/*.ts', '**/*.cts', '**/*.mts' ]
23
+ return config
24
+ }).filter((config): config is ESLintConfig => !! config)
25
+
26
+ /* ========================================================================== *
27
+ * CONFIGS *
28
+ * ========================================================================== */
29
+
30
+ /** Define the "@typescript-eslint" plugin. */
31
+ export const plugin: ESLintConfig<'plugjs/typescript/plugin'> = {
32
+ name: 'plugjs/typescript/plugin',
33
+ plugins,
34
+ }
35
+
36
+ /* ========================================================================== */
37
+
38
+ /** Configuration for "@typescript-eslint" scoped to TypeScript sources. */
39
+ export const options: ESLintConfig<'plugjs/typescript/options'> = {
40
+ ...opts,
41
+ files: [ '**/*.ts', '**/*.cts', '**/*.mts' ],
42
+ name: 'plugjs/typescript/options',
43
+ }
44
+
45
+ /* ========================================================================== */
46
+
47
+ /** Our own rules overriding `typescript-eslint/recommended`. */
48
+ export const overrides: ESLintConfig<'plugjs/typescript/overrides'> = {
49
+ name: 'plugjs/typescript/overrides',
50
+
51
+ files: [ '**/*.ts', '**/*.cts', '**/*.mts' ],
52
+
53
+ rules: {
54
+ 'no-unused-vars': 'off', // overrides ESLint Recommended for TypeScript
55
+ 'no-dupe-class-members': 'off', // overrides ESLint Recommended for TypeScript
56
+
57
+ '@typescript-eslint/consistent-type-imports': 'error',
58
+ '@typescript-eslint/explicit-function-return-type': [ 'error', {
59
+ allowExpressions: true,
60
+ allowDirectConstAssertionInArrowFunctions: true,
61
+ allowConciseArrowFunctionExpressionsStartingWithVoid: true,
62
+ } ],
63
+ '@typescript-eslint/no-dupe-class-members': 'error',
64
+ '@typescript-eslint/no-empty-object-type': 'off',
65
+ '@typescript-eslint/no-explicit-any': 'off',
66
+ '@typescript-eslint/no-floating-promises': 'error',
67
+ '@typescript-eslint/no-invalid-this': 'error',
68
+ '@typescript-eslint/no-unused-vars': [ 'error', {
69
+ args: 'after-used',
70
+ argsIgnorePattern: '^_',
71
+ } ],
72
+ },
73
+ }
74
+
75
+ /**
76
+ * TypeScript module: declares all the common rules for TypeScript code bases.
77
+ *
78
+ * This module includes these configurations:
79
+ *
80
+ * * `plugjs/typescript/plugin`: defines the "@typescript-eslint" plugin.
81
+ * * `plugjs/typescript/options`: configuration for "@typescript-eslint".
82
+ * * other rules from `typescript-eslint/recommended`: all other recommended
83
+ * Typescript rules, restricted to `.ts`, `.cts`, and `.mts` files.
84
+ * * `plugjs/typescript/overrides`: our rules overriding recommended.
85
+ */
86
+ export default [ plugin, options, ...configs, overrides ] as const
@@ -1,77 +0,0 @@
1
- /** Basic extra rules for JavaScript sources. */
2
- import process from 'node:process'
3
- import path from 'node:path'
4
- import fs from 'node:fs'
5
-
6
- import globals from 'globals'
7
-
8
- function findModuleType(directory) {
9
- const file = path.join(directory, 'package.json')
10
- try {
11
- const data = JSON.parse(fs.readFileSync(file, 'utf-8'))
12
- return data.type || 'commonjs'
13
- } catch (error) {
14
- if (error.code !== 'ENOENT') {
15
- throw new Error(`Error reading "${file}"`, { cause: error })
16
- }
17
-
18
- const parent = path.dirname(directory)
19
- if (parent === directory) return 'commonjs'
20
- return findModuleType(parent)
21
- }
22
- }
23
-
24
- const moduleType = findModuleType(process.cwd())
25
-
26
- export const javascript = {
27
- name: 'plugjs-javascript',
28
-
29
- files: [ '*.js', '*.cjs', '*.mjs' ],
30
-
31
- rules: {
32
- 'guard-for-in': 'error',
33
- 'no-array-constructor': 'error',
34
- 'no-invalid-this': 'error',
35
- 'no-unused-expressions': 'error',
36
- 'no-unused-vars': [ 'error', {
37
- args: 'after-used',
38
- argsIgnorePattern: '^_',
39
- } ],
40
- 'strict': [ 'error', 'global' ],
41
- },
42
- }
43
-
44
- /** Marks `*.cjs` files as `commonjs`. */
45
- export const javascriptCommonJs = {
46
- name: 'plugjs-javascript-cjs',
47
-
48
- files: moduleType === 'commonjs' ? [ '**/*.cjs', '**/*.js' ] : [ '**/*.cjs' ],
49
-
50
- languageOptions: {
51
- sourceType: 'commonjs',
52
- globals: globals.node,
53
- },
54
- }
55
-
56
- /** Marks `*.mjs` files as `module`. */
57
- export const javascriptModule = {
58
- name: 'plugjs-javascript-esm',
59
-
60
- files: moduleType === 'module' ? [ '**/*.mjs', '**/*.js' ] : [ '**/*.mjs' ],
61
-
62
- languageOptions: {
63
- sourceType: 'module',
64
- globals: globals.nodeBuiltin,
65
- },
66
- }
67
-
68
- /**
69
- * JavaScript module: declares all the common rules for JavaScript code bases.
70
- *
71
- * This module includes these configurations:
72
- *
73
- * * `plugjs-javascript`: basic extra rules for JavaScript sources.
74
- * * `plugjs-javascript-cjs`: marks `*.cjs` files as `commonjs`.
75
- * * `plugjs-javascript-mjs`: marks `*.mjs` files as `module`.
76
- */
77
- export default [ javascript, javascriptCommonJs, javascriptModule ]
@@ -1,51 +0,0 @@
1
- import tseslint from 'typescript-eslint'
2
-
3
- /** Our own rules overriding `typescript-eslint/recommended`. */
4
- export const typescript = {
5
- name: 'plugjs-typescript',
6
-
7
- files: [ '**/*.ts', '**/*.cts', '**/*.mts' ],
8
-
9
- rules: {
10
- 'no-unused-vars': 'off', // overrides ESLint Recommended for TypeScript
11
- 'no-dupe-class-members': 'off', // overrides ESLint Recommended for TypeScript
12
-
13
- '@typescript-eslint/consistent-type-imports': 'error',
14
- '@typescript-eslint/explicit-function-return-type': [ 'error', {
15
- allowExpressions: true,
16
- allowDirectConstAssertionInArrowFunctions: true,
17
- allowConciseArrowFunctionExpressionsStartingWithVoid: true,
18
- } ],
19
- '@typescript-eslint/no-dupe-class-members': 'error',
20
- '@typescript-eslint/no-empty-object-type': 'off',
21
- '@typescript-eslint/no-explicit-any': 'off',
22
- '@typescript-eslint/no-floating-promises': 'error',
23
- '@typescript-eslint/no-invalid-this': 'error',
24
- '@typescript-eslint/no-unused-vars': [ 'error', {
25
- args: 'after-used',
26
- argsIgnorePattern: '^_',
27
- } ],
28
- },
29
- }
30
-
31
- /**
32
- * TypeScript module: declares all the common rules for TypeScript code bases.
33
- *
34
- * This module includes these configurations:
35
- *
36
- * * `typescript-eslint/recommended`: imports all the configurations from
37
- * TypeScript ESlint recommended, but restrict them to operate only on
38
- * `.ts`, `.cts`, and `.mts` files. This *should* include:
39
- * * `typescript-eslint/base`: basic parser configuration.
40
- * * `typescript-eslint/eslint-recommended`: disable ESLint rules conflicting
41
- * with TypeScript.
42
- * * `typescript-eslint/recommended`: recommended config for TypeScript
43
- * * `plugjs-typescript`: our rules overriding `typescript-eslint/recommended`.
44
- */
45
- export default [
46
- ...tseslint.configs.recommended.map((config) => {
47
- config.files = [ '**/*.ts', '**/*.cts', '**/*.mts' ]
48
- return config
49
- }),
50
- typescript,
51
- ]
package/index.mjs DELETED
@@ -1,44 +0,0 @@
1
- import js from '@eslint/js'
2
-
3
- import basic from './configs/basic.mjs'
4
- import javascript from './configs/javascript.mjs'
5
- import typescript from './configs/typescript.mjs'
6
-
7
- export * from './configs/basic.mjs'
8
- export * from './configs/javascript.mjs'
9
- export * from './configs/typescript.mjs'
10
-
11
- /**
12
- * Base `ESLint` configuration for PlugJS.
13
- *
14
- * This includes a number of configurations:
15
- *
16
- * * `eslint-recommended`: recommended JavaScript config from ESLint.
17
- *
18
- * * `plugjs-base`: basic configuration of ESLint rules.
19
- * * `plugjs-stylistic`: style shared between JavaScript and TypeScript.
20
- * * `plugjs-unicorn`: extra niceties from the ESLint Unicorn plugin.
21
- * * `plugjs-importx`: defines the style of our imports.
22
- *
23
- * * `plugjs-javascript`: basic extra rules for JavaScript sources.
24
- * * `plugjs-javascript-cjs`: marks `*.cjs` files as `commonjs`.
25
- * * `plugjs-javascript-mjs`: marks `*.mjs` files as `module`.
26
- *
27
- * * `typescript-eslint/recommended`: imports all the configurations from
28
- * TypeScript ESlint recommended, but restrict them to operate only on
29
- * `.ts`, `.cts`, and `.mts` files. This *should* include:
30
- * * `typescript-eslint/base`: basic parser configuration.
31
- * * `typescript-eslint/eslint-recommended`: disable ESLint rules conflicting
32
- * with TypeScript.
33
- * * `typescript-eslint/recommended`: recommended config for TypeScript
34
- * * `plugjs-typescript`: our rules overriding `typescript-eslint/recommended`.
35
- */
36
- export default [
37
- { // give a name to this config before we go completely nuts!
38
- name: 'eslint/js/recommended',
39
- ...js.configs.recommended,
40
- },
41
- ...basic,
42
- ...javascript,
43
- ...typescript,
44
- ]