@prairielearn/eslint-config 0.0.1 → 1.1.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/.turbo/turbo-build.log +0 -0
- package/CHANGELOG.md +13 -0
- package/README.md +111 -43
- package/dist/configs/base.d.ts +7 -0
- package/dist/configs/base.d.ts.map +1 -0
- package/dist/configs/base.js +121 -0
- package/dist/configs/base.js.map +1 -0
- package/dist/configs/imports.d.ts +6 -0
- package/dist/configs/imports.d.ts.map +1 -0
- package/dist/configs/imports.js +44 -0
- package/dist/configs/imports.js.map +1 -0
- package/dist/configs/jsdoc.d.ts +6 -0
- package/dist/configs/jsdoc.d.ts.map +1 -0
- package/dist/configs/jsdoc.js +70 -0
- package/dist/configs/jsdoc.js.map +1 -0
- package/dist/configs/lodash.d.ts +6 -0
- package/dist/configs/lodash.d.ts.map +1 -0
- package/dist/configs/lodash.js +24 -0
- package/dist/configs/lodash.js.map +1 -0
- package/dist/configs/perfectionist.d.ts +8 -0
- package/dist/configs/perfectionist.d.ts.map +1 -0
- package/dist/configs/perfectionist.js +43 -0
- package/dist/configs/perfectionist.js.map +1 -0
- package/dist/configs/prairielearn.d.ts +13 -0
- package/dist/configs/prairielearn.d.ts.map +1 -0
- package/dist/configs/prairielearn.js +29 -0
- package/dist/configs/prairielearn.js.map +1 -0
- package/dist/configs/react.d.ts +6 -0
- package/dist/configs/react.d.ts.map +1 -0
- package/dist/configs/react.js +63 -0
- package/dist/configs/react.js.map +1 -0
- package/dist/configs/stylistic.d.ts +6 -0
- package/dist/configs/stylistic.d.ts.map +1 -0
- package/dist/configs/stylistic.js +51 -0
- package/dist/configs/stylistic.js.map +1 -0
- package/dist/configs/tanstack.d.ts +6 -0
- package/dist/configs/tanstack.d.ts.map +1 -0
- package/dist/configs/tanstack.js +19 -0
- package/dist/configs/tanstack.js.map +1 -0
- package/dist/configs/typescript.d.ts +11 -0
- package/dist/configs/typescript.d.ts.map +1 -0
- package/dist/configs/typescript.js +106 -0
- package/dist/configs/typescript.js.map +1 -0
- package/dist/configs/unicorn.d.ts +6 -0
- package/dist/configs/unicorn.d.ts.map +1 -0
- package/dist/configs/unicorn.js +74 -0
- package/dist/configs/unicorn.js.map +1 -0
- package/dist/configs/vitest.d.ts +6 -0
- package/dist/configs/vitest.d.ts.map +1 -0
- package/dist/configs/vitest.js +26 -0
- package/dist/configs/vitest.js.map +1 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +112 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -7
- package/src/configs/base.ts +127 -0
- package/src/configs/imports.ts +50 -0
- package/src/configs/jsdoc.ts +72 -0
- package/src/configs/lodash.ts +26 -0
- package/src/configs/perfectionist.ts +48 -0
- package/src/configs/prairielearn.ts +42 -0
- package/src/configs/react.ts +82 -0
- package/src/configs/stylistic.ts +54 -0
- package/src/configs/tanstack.ts +21 -0
- package/src/configs/typescript.ts +108 -0
- package/src/configs/unicorn.ts +84 -0
- package/src/configs/vitest.ts +31 -0
- package/src/index.ts +190 -0
- package/src/types.d.ts +6 -0
- package/tsconfig.json +7 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
import { type PrairieLearnPluginOptions } from './configs/prairielearn.js';
|
|
3
|
+
export interface PrairieLearnEslintConfigOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Root directory for TypeScript project service.
|
|
6
|
+
* Required for type-aware linting.
|
|
7
|
+
*/
|
|
8
|
+
tsconfigRootDir: string;
|
|
9
|
+
/**
|
|
10
|
+
* Glob patterns for files to apply type-aware rules to.
|
|
11
|
+
* @default ['**\/*.{ts,tsx}']
|
|
12
|
+
*/
|
|
13
|
+
typeAwareFiles?: string[];
|
|
14
|
+
/**
|
|
15
|
+
* Files to allow in defaultProject for type-aware linting.
|
|
16
|
+
* Useful for config files outside the main tsconfig.
|
|
17
|
+
* @default ['*.config.ts', '*.config.mts', 'vitest.config.ts']
|
|
18
|
+
*/
|
|
19
|
+
allowDefaultProject?: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Enable `@prairielearn/eslint-plugin` rules.
|
|
22
|
+
* @default true
|
|
23
|
+
*/
|
|
24
|
+
prairielearn?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Options for the `@prairielearn/eslint-plugin` rules.
|
|
27
|
+
*/
|
|
28
|
+
prairieLearnOptions?: PrairieLearnPluginOptions;
|
|
29
|
+
/**
|
|
30
|
+
* Global ignores to apply.
|
|
31
|
+
* Will be merged with default ignores.
|
|
32
|
+
*/
|
|
33
|
+
ignores?: string[];
|
|
34
|
+
/**
|
|
35
|
+
* Disable specific config modules.
|
|
36
|
+
*/
|
|
37
|
+
disable?: {
|
|
38
|
+
react?: boolean;
|
|
39
|
+
vitest?: boolean;
|
|
40
|
+
perfectionist?: boolean;
|
|
41
|
+
unicorn?: boolean;
|
|
42
|
+
jsdoc?: boolean;
|
|
43
|
+
tanstack?: boolean;
|
|
44
|
+
lodash?: boolean;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Creates a PrairieLearn ESLint configuration array.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```js
|
|
52
|
+
* // eslint.config.mjs
|
|
53
|
+
* import { prairielearn } from '@prairielearn/eslint-config';
|
|
54
|
+
*
|
|
55
|
+
* export default [
|
|
56
|
+
* ...prairielearn({
|
|
57
|
+
* tsconfigRootDir: import.meta.dirname,
|
|
58
|
+
* }),
|
|
59
|
+
* // Add your project-specific rules here
|
|
60
|
+
* ];
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function prairielearn(options: PrairieLearnEslintConfigOptions): TSESLint.FlatConfig.ConfigArray;
|
|
64
|
+
export { baseConfig } from './configs/base.js';
|
|
65
|
+
export { importsConfig } from './configs/imports.js';
|
|
66
|
+
export { jsdocConfig } from './configs/jsdoc.js';
|
|
67
|
+
export { lodashConfig } from './configs/lodash.js';
|
|
68
|
+
export { perfectionistConfig } from './configs/perfectionist.js';
|
|
69
|
+
export { prairieLearnConfig, type PrairieLearnPluginOptions } from './configs/prairielearn.js';
|
|
70
|
+
export { reactConfig } from './configs/react.js';
|
|
71
|
+
export { stylisticConfig } from './configs/stylistic.js';
|
|
72
|
+
export { tanstackConfig } from './configs/tanstack.js';
|
|
73
|
+
export { typescriptConfig, typescriptTypeAwareRules } from './configs/typescript.js';
|
|
74
|
+
export { unicornConfig } from './configs/unicorn.js';
|
|
75
|
+
export { vitestConfig } from './configs/vitest.js';
|
|
76
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AASzD,OAAO,EAAE,KAAK,yBAAyB,EAAsB,MAAM,2BAA2B,CAAC;AAQ/F,MAAM,WAAW,+BAA+B;IAC9C;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,mBAAmB,CAAC,EAAE,yBAAyB,CAAC;IAEhD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,+BAA+B,GACvC,QAAQ,CAAC,UAAU,CAAC,WAAW,CAyFjC;AAGD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC/F,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["import type { TSESLint } from '@typescript-eslint/utils';\nimport { globalIgnores } from 'eslint/config';\nimport tseslint from 'typescript-eslint';\n\nimport { baseConfig } from './configs/base.js';\nimport { importsConfig } from './configs/imports.js';\nimport { jsdocConfig } from './configs/jsdoc.js';\nimport { lodashConfig } from './configs/lodash.js';\nimport { perfectionistConfig } from './configs/perfectionist.js';\nimport { type PrairieLearnPluginOptions, prairieLearnConfig } from './configs/prairielearn.js';\nimport { reactConfig } from './configs/react.js';\nimport { stylisticConfig } from './configs/stylistic.js';\nimport { tanstackConfig } from './configs/tanstack.js';\nimport { typescriptConfig, typescriptTypeAwareRules } from './configs/typescript.js';\nimport { unicornConfig } from './configs/unicorn.js';\nimport { vitestConfig } from './configs/vitest.js';\n\nexport interface PrairieLearnEslintConfigOptions {\n /**\n * Root directory for TypeScript project service.\n * Required for type-aware linting.\n */\n tsconfigRootDir: string;\n\n /**\n * Glob patterns for files to apply type-aware rules to.\n * @default ['**\\/*.{ts,tsx}']\n */\n typeAwareFiles?: string[];\n\n /**\n * Files to allow in defaultProject for type-aware linting.\n * Useful for config files outside the main tsconfig.\n * @default ['*.config.ts', '*.config.mts', 'vitest.config.ts']\n */\n allowDefaultProject?: string[];\n\n /**\n * Enable `@prairielearn/eslint-plugin` rules.\n * @default true\n */\n prairielearn?: boolean;\n\n /**\n * Options for the `@prairielearn/eslint-plugin` rules.\n */\n prairieLearnOptions?: PrairieLearnPluginOptions;\n\n /**\n * Global ignores to apply.\n * Will be merged with default ignores.\n */\n ignores?: string[];\n\n /**\n * Disable specific config modules.\n */\n disable?: {\n react?: boolean;\n vitest?: boolean;\n perfectionist?: boolean;\n unicorn?: boolean;\n jsdoc?: boolean;\n tanstack?: boolean;\n lodash?: boolean;\n };\n}\n\n/**\n * Creates a PrairieLearn ESLint configuration array.\n *\n * @example\n * ```js\n * // eslint.config.mjs\n * import { prairielearn } from '@prairielearn/eslint-config';\n *\n * export default [\n * ...prairielearn({\n * tsconfigRootDir: import.meta.dirname,\n * }),\n * // Add your project-specific rules here\n * ];\n * ```\n */\nexport function prairielearn(\n options: PrairieLearnEslintConfigOptions,\n): TSESLint.FlatConfig.ConfigArray {\n const {\n tsconfigRootDir,\n typeAwareFiles = ['**/*.{ts,tsx}'],\n allowDefaultProject = ['*.config.ts', '*.config.mts', 'vitest.config.ts'],\n prairielearn: enablePrairielearn = true,\n prairieLearnOptions,\n ignores = [],\n disable = {},\n } = options;\n\n const jsFiles = ['**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}'];\n\n const configs: TSESLint.FlatConfig.ConfigArray = [\n // Base typescript-eslint configs (scoped to JS/TS files)\n ...tseslint.config({\n extends: [...tseslint.configs.stylistic, ...tseslint.configs.strict],\n files: jsFiles,\n }),\n // Base configs (always included)\n ...baseConfig(),\n // TypeScript config (scoped to JS/TS files)\n {\n files: jsFiles,\n ...typescriptConfig()[0],\n },\n ...importsConfig(),\n ...stylisticConfig(),\n ];\n\n // Optional configs\n if (!disable.react) {\n configs.push(...reactConfig());\n }\n\n if (!disable.vitest) {\n configs.push(...vitestConfig());\n }\n\n if (!disable.perfectionist) {\n configs.push(...perfectionistConfig());\n }\n\n if (!disable.unicorn) {\n configs.push(...unicornConfig());\n }\n\n if (!disable.jsdoc) {\n configs.push(...jsdocConfig());\n }\n\n if (!disable.tanstack) {\n configs.push(...tanstackConfig());\n }\n\n if (!disable.lodash) {\n configs.push(...lodashConfig());\n }\n\n if (enablePrairielearn) {\n configs.push(...prairieLearnConfig(prairieLearnOptions));\n }\n\n // Type-aware rules (applied to specified files)\n // We use tseslint.config() to properly handle the extends syntax\n configs.push(\n ...tseslint.config({\n extends: [\n tseslint.configs.recommendedTypeCheckedOnly,\n tseslint.configs.stylisticTypeCheckedOnly,\n ],\n files: typeAwareFiles,\n languageOptions: {\n parserOptions: {\n projectService: {\n allowDefaultProject,\n },\n tsconfigRootDir,\n },\n },\n rules: typescriptTypeAwareRules(),\n }),\n );\n\n // Default ignores\n return [\n ...configs,\n globalIgnores(['.yarn/*', 'node_modules/*', 'dist/*', 'coverage/*', ...ignores]),\n ];\n}\n\n// Re-export individual configs for advanced use\nexport { baseConfig } from './configs/base.js';\nexport { importsConfig } from './configs/imports.js';\nexport { jsdocConfig } from './configs/jsdoc.js';\nexport { lodashConfig } from './configs/lodash.js';\nexport { perfectionistConfig } from './configs/perfectionist.js';\nexport { prairieLearnConfig, type PrairieLearnPluginOptions } from './configs/prairielearn.js';\nexport { reactConfig } from './configs/react.js';\nexport { stylisticConfig } from './configs/stylistic.js';\nexport { tanstackConfig } from './configs/tanstack.js';\nexport { typescriptConfig, typescriptTypeAwareRules } from './configs/typescript.js';\nexport { unicornConfig } from './configs/unicorn.js';\nexport { vitestConfig } from './configs/vitest.js';\n"]}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { globalIgnores } from 'eslint/config';
|
|
2
|
+
import tseslint from 'typescript-eslint';
|
|
3
|
+
import { baseConfig } from './configs/base.js';
|
|
4
|
+
import { importsConfig } from './configs/imports.js';
|
|
5
|
+
import { jsdocConfig } from './configs/jsdoc.js';
|
|
6
|
+
import { lodashConfig } from './configs/lodash.js';
|
|
7
|
+
import { perfectionistConfig } from './configs/perfectionist.js';
|
|
8
|
+
import { prairieLearnConfig } from './configs/prairielearn.js';
|
|
9
|
+
import { reactConfig } from './configs/react.js';
|
|
10
|
+
import { stylisticConfig } from './configs/stylistic.js';
|
|
11
|
+
import { tanstackConfig } from './configs/tanstack.js';
|
|
12
|
+
import { typescriptConfig, typescriptTypeAwareRules } from './configs/typescript.js';
|
|
13
|
+
import { unicornConfig } from './configs/unicorn.js';
|
|
14
|
+
import { vitestConfig } from './configs/vitest.js';
|
|
15
|
+
/**
|
|
16
|
+
* Creates a PrairieLearn ESLint configuration array.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```js
|
|
20
|
+
* // eslint.config.mjs
|
|
21
|
+
* import { prairielearn } from '@prairielearn/eslint-config';
|
|
22
|
+
*
|
|
23
|
+
* export default [
|
|
24
|
+
* ...prairielearn({
|
|
25
|
+
* tsconfigRootDir: import.meta.dirname,
|
|
26
|
+
* }),
|
|
27
|
+
* // Add your project-specific rules here
|
|
28
|
+
* ];
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function prairielearn(options) {
|
|
32
|
+
const { tsconfigRootDir, typeAwareFiles = ['**/*.{ts,tsx}'], allowDefaultProject = ['*.config.ts', '*.config.mts', 'vitest.config.ts'], prairielearn: enablePrairielearn = true, prairieLearnOptions, ignores = [], disable = {}, } = options;
|
|
33
|
+
const jsFiles = ['**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}'];
|
|
34
|
+
const configs = [
|
|
35
|
+
// Base typescript-eslint configs (scoped to JS/TS files)
|
|
36
|
+
...tseslint.config({
|
|
37
|
+
extends: [...tseslint.configs.stylistic, ...tseslint.configs.strict],
|
|
38
|
+
files: jsFiles,
|
|
39
|
+
}),
|
|
40
|
+
// Base configs (always included)
|
|
41
|
+
...baseConfig(),
|
|
42
|
+
// TypeScript config (scoped to JS/TS files)
|
|
43
|
+
{
|
|
44
|
+
files: jsFiles,
|
|
45
|
+
...typescriptConfig()[0],
|
|
46
|
+
},
|
|
47
|
+
...importsConfig(),
|
|
48
|
+
...stylisticConfig(),
|
|
49
|
+
];
|
|
50
|
+
// Optional configs
|
|
51
|
+
if (!disable.react) {
|
|
52
|
+
configs.push(...reactConfig());
|
|
53
|
+
}
|
|
54
|
+
if (!disable.vitest) {
|
|
55
|
+
configs.push(...vitestConfig());
|
|
56
|
+
}
|
|
57
|
+
if (!disable.perfectionist) {
|
|
58
|
+
configs.push(...perfectionistConfig());
|
|
59
|
+
}
|
|
60
|
+
if (!disable.unicorn) {
|
|
61
|
+
configs.push(...unicornConfig());
|
|
62
|
+
}
|
|
63
|
+
if (!disable.jsdoc) {
|
|
64
|
+
configs.push(...jsdocConfig());
|
|
65
|
+
}
|
|
66
|
+
if (!disable.tanstack) {
|
|
67
|
+
configs.push(...tanstackConfig());
|
|
68
|
+
}
|
|
69
|
+
if (!disable.lodash) {
|
|
70
|
+
configs.push(...lodashConfig());
|
|
71
|
+
}
|
|
72
|
+
if (enablePrairielearn) {
|
|
73
|
+
configs.push(...prairieLearnConfig(prairieLearnOptions));
|
|
74
|
+
}
|
|
75
|
+
// Type-aware rules (applied to specified files)
|
|
76
|
+
// We use tseslint.config() to properly handle the extends syntax
|
|
77
|
+
configs.push(...tseslint.config({
|
|
78
|
+
extends: [
|
|
79
|
+
tseslint.configs.recommendedTypeCheckedOnly,
|
|
80
|
+
tseslint.configs.stylisticTypeCheckedOnly,
|
|
81
|
+
],
|
|
82
|
+
files: typeAwareFiles,
|
|
83
|
+
languageOptions: {
|
|
84
|
+
parserOptions: {
|
|
85
|
+
projectService: {
|
|
86
|
+
allowDefaultProject,
|
|
87
|
+
},
|
|
88
|
+
tsconfigRootDir,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
rules: typescriptTypeAwareRules(),
|
|
92
|
+
}));
|
|
93
|
+
// Default ignores
|
|
94
|
+
return [
|
|
95
|
+
...configs,
|
|
96
|
+
globalIgnores(['.yarn/*', 'node_modules/*', 'dist/*', 'coverage/*', ...ignores]),
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
// Re-export individual configs for advanced use
|
|
100
|
+
export { baseConfig } from './configs/base.js';
|
|
101
|
+
export { importsConfig } from './configs/imports.js';
|
|
102
|
+
export { jsdocConfig } from './configs/jsdoc.js';
|
|
103
|
+
export { lodashConfig } from './configs/lodash.js';
|
|
104
|
+
export { perfectionistConfig } from './configs/perfectionist.js';
|
|
105
|
+
export { prairieLearnConfig } from './configs/prairielearn.js';
|
|
106
|
+
export { reactConfig } from './configs/react.js';
|
|
107
|
+
export { stylisticConfig } from './configs/stylistic.js';
|
|
108
|
+
export { tanstackConfig } from './configs/tanstack.js';
|
|
109
|
+
export { typescriptConfig, typescriptTypeAwareRules } from './configs/typescript.js';
|
|
110
|
+
export { unicornConfig } from './configs/unicorn.js';
|
|
111
|
+
export { vitestConfig } from './configs/vitest.js';
|
|
112
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TSESLint } from '@typescript-eslint/utils';\nimport { globalIgnores } from 'eslint/config';\nimport tseslint from 'typescript-eslint';\n\nimport { baseConfig } from './configs/base.js';\nimport { importsConfig } from './configs/imports.js';\nimport { jsdocConfig } from './configs/jsdoc.js';\nimport { lodashConfig } from './configs/lodash.js';\nimport { perfectionistConfig } from './configs/perfectionist.js';\nimport { type PrairieLearnPluginOptions, prairieLearnConfig } from './configs/prairielearn.js';\nimport { reactConfig } from './configs/react.js';\nimport { stylisticConfig } from './configs/stylistic.js';\nimport { tanstackConfig } from './configs/tanstack.js';\nimport { typescriptConfig, typescriptTypeAwareRules } from './configs/typescript.js';\nimport { unicornConfig } from './configs/unicorn.js';\nimport { vitestConfig } from './configs/vitest.js';\n\nexport interface PrairieLearnEslintConfigOptions {\n /**\n * Root directory for TypeScript project service.\n * Required for type-aware linting.\n */\n tsconfigRootDir: string;\n\n /**\n * Glob patterns for files to apply type-aware rules to.\n * @default ['**\\/*.{ts,tsx}']\n */\n typeAwareFiles?: string[];\n\n /**\n * Files to allow in defaultProject for type-aware linting.\n * Useful for config files outside the main tsconfig.\n * @default ['*.config.ts', '*.config.mts', 'vitest.config.ts']\n */\n allowDefaultProject?: string[];\n\n /**\n * Enable `@prairielearn/eslint-plugin` rules.\n * @default true\n */\n prairielearn?: boolean;\n\n /**\n * Options for the `@prairielearn/eslint-plugin` rules.\n */\n prairieLearnOptions?: PrairieLearnPluginOptions;\n\n /**\n * Global ignores to apply.\n * Will be merged with default ignores.\n */\n ignores?: string[];\n\n /**\n * Disable specific config modules.\n */\n disable?: {\n react?: boolean;\n vitest?: boolean;\n perfectionist?: boolean;\n unicorn?: boolean;\n jsdoc?: boolean;\n tanstack?: boolean;\n lodash?: boolean;\n };\n}\n\n/**\n * Creates a PrairieLearn ESLint configuration array.\n *\n * @example\n * ```js\n * // eslint.config.mjs\n * import { prairielearn } from '@prairielearn/eslint-config';\n *\n * export default [\n * ...prairielearn({\n * tsconfigRootDir: import.meta.dirname,\n * }),\n * // Add your project-specific rules here\n * ];\n * ```\n */\nexport function prairielearn(\n options: PrairieLearnEslintConfigOptions,\n): TSESLint.FlatConfig.ConfigArray {\n const {\n tsconfigRootDir,\n typeAwareFiles = ['**/*.{ts,tsx}'],\n allowDefaultProject = ['*.config.ts', '*.config.mts', 'vitest.config.ts'],\n prairielearn: enablePrairielearn = true,\n prairieLearnOptions,\n ignores = [],\n disable = {},\n } = options;\n\n const jsFiles = ['**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}'];\n\n const configs: TSESLint.FlatConfig.ConfigArray = [\n // Base typescript-eslint configs (scoped to JS/TS files)\n ...tseslint.config({\n extends: [...tseslint.configs.stylistic, ...tseslint.configs.strict],\n files: jsFiles,\n }),\n // Base configs (always included)\n ...baseConfig(),\n // TypeScript config (scoped to JS/TS files)\n {\n files: jsFiles,\n ...typescriptConfig()[0],\n },\n ...importsConfig(),\n ...stylisticConfig(),\n ];\n\n // Optional configs\n if (!disable.react) {\n configs.push(...reactConfig());\n }\n\n if (!disable.vitest) {\n configs.push(...vitestConfig());\n }\n\n if (!disable.perfectionist) {\n configs.push(...perfectionistConfig());\n }\n\n if (!disable.unicorn) {\n configs.push(...unicornConfig());\n }\n\n if (!disable.jsdoc) {\n configs.push(...jsdocConfig());\n }\n\n if (!disable.tanstack) {\n configs.push(...tanstackConfig());\n }\n\n if (!disable.lodash) {\n configs.push(...lodashConfig());\n }\n\n if (enablePrairielearn) {\n configs.push(...prairieLearnConfig(prairieLearnOptions));\n }\n\n // Type-aware rules (applied to specified files)\n // We use tseslint.config() to properly handle the extends syntax\n configs.push(\n ...tseslint.config({\n extends: [\n tseslint.configs.recommendedTypeCheckedOnly,\n tseslint.configs.stylisticTypeCheckedOnly,\n ],\n files: typeAwareFiles,\n languageOptions: {\n parserOptions: {\n projectService: {\n allowDefaultProject,\n },\n tsconfigRootDir,\n },\n },\n rules: typescriptTypeAwareRules(),\n }),\n );\n\n // Default ignores\n return [\n ...configs,\n globalIgnores(['.yarn/*', 'node_modules/*', 'dist/*', 'coverage/*', ...ignores]),\n ];\n}\n\n// Re-export individual configs for advanced use\nexport { baseConfig } from './configs/base.js';\nexport { importsConfig } from './configs/imports.js';\nexport { jsdocConfig } from './configs/jsdoc.js';\nexport { lodashConfig } from './configs/lodash.js';\nexport { perfectionistConfig } from './configs/perfectionist.js';\nexport { prairieLearnConfig, type PrairieLearnPluginOptions } from './configs/prairielearn.js';\nexport { reactConfig } from './configs/react.js';\nexport { stylisticConfig } from './configs/stylistic.js';\nexport { tanstackConfig } from './configs/tanstack.js';\nexport { typescriptConfig, typescriptTypeAwareRules } from './configs/typescript.js';\nexport { unicornConfig } from './configs/unicorn.js';\nexport { vitestConfig } from './configs/vitest.js';\n"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,52 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prairielearn/eslint-config",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/PrairieLearn/PrairieLearn.git",
|
|
8
|
+
"directory": "packages/eslint-config"
|
|
9
|
+
},
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=24.0.0"
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsgo",
|
|
19
|
+
"dev": "tsgo --watch --preserveWatchOutput"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"eslint": "^9.0.0",
|
|
23
|
+
"typescript": "^5.0.0"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@eslint-react/eslint-plugin": "^2.9.4",
|
|
27
|
+
"@eslint/eslintrc": "^3.0.0",
|
|
28
|
+
"@eslint/js": "^9.29.0",
|
|
29
|
+
"@prairielearn/eslint-plugin": "^3.1.1",
|
|
30
|
+
"@stylistic/eslint-plugin": "^5.7.0",
|
|
31
|
+
"@tanstack/eslint-plugin-query": "^5.91.2",
|
|
32
|
+
"@typescript-eslint/utils": "^8.53.0",
|
|
33
|
+
"@vitest/eslint-plugin": "^1.6.6",
|
|
34
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
35
|
+
"eslint-plugin-import-x": "^4.16.1",
|
|
36
|
+
"eslint-plugin-jsdoc": "^62.0.0",
|
|
37
|
+
"eslint-plugin-jsx-a11y-x": "^0.1.1",
|
|
38
|
+
"eslint-plugin-no-floating-promise": "^2.0.0",
|
|
39
|
+
"eslint-plugin-perfectionist": "^5.3.1",
|
|
40
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
41
|
+
"eslint-plugin-react-you-might-not-need-an-effect": "^0.8.5",
|
|
42
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
43
|
+
"eslint-plugin-you-dont-need-lodash-underscore": "^6.14.0",
|
|
44
|
+
"globals": "^16.5.0",
|
|
45
|
+
"typescript-eslint": "^8.53.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@prairielearn/tsconfig": "^2.0.0",
|
|
49
|
+
"@types/node": "^24.10.9",
|
|
50
|
+
"@typescript/native-preview": "^7.0.0-dev.20260106.1"
|
|
51
|
+
}
|
|
10
52
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import type { TSESLint } from '@typescript-eslint/utils';
|
|
3
|
+
import noFloatingPromise from 'eslint-plugin-no-floating-promise';
|
|
4
|
+
import globals from 'globals';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Base JavaScript/TypeScript configuration.
|
|
8
|
+
* Core rules that apply to all JS/TS files.
|
|
9
|
+
*/
|
|
10
|
+
export function baseConfig(): TSESLint.FlatConfig.ConfigArray {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
languageOptions: {
|
|
14
|
+
globals: { ...globals.node },
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
linterOptions: {
|
|
18
|
+
reportUnusedDisableDirectives: 'error',
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
plugins: {
|
|
22
|
+
'no-floating-promise': noFloatingPromise,
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
rules: {
|
|
26
|
+
...js.configs.all.rules,
|
|
27
|
+
'array-callback-return': 'off',
|
|
28
|
+
'arrow-body-style': 'off',
|
|
29
|
+
camelcase: 'off',
|
|
30
|
+
'capitalized-comments': 'off',
|
|
31
|
+
'class-methods-use-this': 'off',
|
|
32
|
+
complexity: 'off',
|
|
33
|
+
'consistent-return': 'off',
|
|
34
|
+
'consistent-this': 'off',
|
|
35
|
+
curly: ['error', 'multi-line', 'consistent'],
|
|
36
|
+
'default-case': 'off',
|
|
37
|
+
'dot-notation': 'off',
|
|
38
|
+
eqeqeq: ['error', 'smart'],
|
|
39
|
+
'func-names': 'off',
|
|
40
|
+
'func-style': 'off',
|
|
41
|
+
'guard-for-in': 'off',
|
|
42
|
+
'handle-callback-err': 'error',
|
|
43
|
+
'id-length': 'off',
|
|
44
|
+
'init-declarations': 'off',
|
|
45
|
+
'logical-assignment-operators': 'off',
|
|
46
|
+
'max-classes-per-file': 'off',
|
|
47
|
+
'max-depth': 'off',
|
|
48
|
+
'max-lines': 'off',
|
|
49
|
+
'max-lines-per-function': 'off',
|
|
50
|
+
'max-params': ['error', { max: 6 }],
|
|
51
|
+
'max-statements': 'off',
|
|
52
|
+
'new-cap': 'off',
|
|
53
|
+
'no-await-in-loop': 'off',
|
|
54
|
+
'no-bitwise': 'off',
|
|
55
|
+
'no-console': ['error', { allow: ['warn', 'error', 'table', 'trace'] }],
|
|
56
|
+
'no-continue': 'off',
|
|
57
|
+
'no-duplicate-imports': 'error',
|
|
58
|
+
'no-else-return': 'off',
|
|
59
|
+
'no-empty-function': 'off',
|
|
60
|
+
'no-eq-null': 'off',
|
|
61
|
+
'no-implicit-coercion': 'off',
|
|
62
|
+
'no-inline-comments': 'off',
|
|
63
|
+
'no-invalid-this': 'off',
|
|
64
|
+
'no-lonely-if': 'off',
|
|
65
|
+
'no-loop-func': 'off',
|
|
66
|
+
'no-magic-numbers': 'off',
|
|
67
|
+
'no-negated-condition': 'off',
|
|
68
|
+
'no-nested-ternary': 'off',
|
|
69
|
+
'no-new': 'off',
|
|
70
|
+
'no-param-reassign': 'off',
|
|
71
|
+
'no-plusplus': 'off',
|
|
72
|
+
'no-promise-executor-return': 'off',
|
|
73
|
+
'no-redeclare': 'off',
|
|
74
|
+
'no-restricted-globals': [
|
|
75
|
+
'error',
|
|
76
|
+
// These are not available in ES modules.
|
|
77
|
+
'__filename',
|
|
78
|
+
'__dirname',
|
|
79
|
+
],
|
|
80
|
+
'no-shadow': 'off',
|
|
81
|
+
'no-template-curly-in-string': 'error',
|
|
82
|
+
'no-ternary': 'off',
|
|
83
|
+
'no-undef': 'off',
|
|
84
|
+
'no-undef-init': 'off',
|
|
85
|
+
'no-undefined': 'off',
|
|
86
|
+
'no-underscore-dangle': 'off',
|
|
87
|
+
'no-unmodified-loop-condition': 'off',
|
|
88
|
+
'no-unneeded-ternary': 'off',
|
|
89
|
+
'no-unused-vars': 'off',
|
|
90
|
+
'no-use-before-define': 'off',
|
|
91
|
+
'no-useless-assignment': 'off',
|
|
92
|
+
'no-useless-concat': 'off',
|
|
93
|
+
'no-useless-constructor': 'off',
|
|
94
|
+
'no-useless-return': 'off',
|
|
95
|
+
'no-void': 'off', // https://typescript-eslint.io/rules/no-floating-promises/#ignorevoid
|
|
96
|
+
'no-warning-comments': 'off',
|
|
97
|
+
'object-shorthand': 'error',
|
|
98
|
+
'one-var': ['off', 'never'],
|
|
99
|
+
'prefer-arrow-callback': 'off',
|
|
100
|
+
'prefer-const': ['error', { destructuring: 'all' }],
|
|
101
|
+
'prefer-destructuring': 'off',
|
|
102
|
+
'prefer-named-capture-group': 'off',
|
|
103
|
+
'prefer-object-has-own': 'off',
|
|
104
|
+
'prefer-template': 'off',
|
|
105
|
+
radix: ['error', 'as-needed'],
|
|
106
|
+
'require-atomic-updates': 'off',
|
|
107
|
+
'require-await': 'off',
|
|
108
|
+
'require-unicode-regexp': 'off',
|
|
109
|
+
'sort-vars': 'off',
|
|
110
|
+
'sort-keys': 'off',
|
|
111
|
+
|
|
112
|
+
// Floating promise detection
|
|
113
|
+
'no-floating-promise/no-floating-promise': 'error',
|
|
114
|
+
|
|
115
|
+
// Sort imports within a single import statement
|
|
116
|
+
'sort-imports': [
|
|
117
|
+
'error',
|
|
118
|
+
{
|
|
119
|
+
ignoreDeclarationSort: true,
|
|
120
|
+
ignoreMemberSort: false,
|
|
121
|
+
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
import importX from 'eslint-plugin-import-x';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Import ordering and resolution rules.
|
|
6
|
+
*/
|
|
7
|
+
export function importsConfig(): TSESLint.FlatConfig.ConfigArray {
|
|
8
|
+
return [
|
|
9
|
+
{
|
|
10
|
+
plugins: {
|
|
11
|
+
'import-x': importX,
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
rules: {
|
|
15
|
+
// Enforce alphabetical order of import specifiers within each import group.
|
|
16
|
+
// The import-x/order rule handles the overall sorting of the import groups.
|
|
17
|
+
'import-x/order': [
|
|
18
|
+
'error',
|
|
19
|
+
{
|
|
20
|
+
alphabetize: {
|
|
21
|
+
order: 'asc',
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
'newlines-between': 'always',
|
|
25
|
+
|
|
26
|
+
pathGroups: [
|
|
27
|
+
{
|
|
28
|
+
group: 'external',
|
|
29
|
+
pattern: '@prairielearn/**',
|
|
30
|
+
position: 'after',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
|
|
34
|
+
pathGroupsExcludedImportTypes: ['builtin'],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
settings: {
|
|
40
|
+
'import-x/parsers': {
|
|
41
|
+
'@typescript-eslint/parser': ['.ts', '.js'],
|
|
42
|
+
},
|
|
43
|
+
'import-x/resolver': {
|
|
44
|
+
node: true,
|
|
45
|
+
typescript: true,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
import jsdoc from 'eslint-plugin-jsdoc';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* JSDoc documentation rules.
|
|
6
|
+
*/
|
|
7
|
+
export function jsdocConfig(): TSESLint.FlatConfig.ConfigArray {
|
|
8
|
+
return [
|
|
9
|
+
{
|
|
10
|
+
plugins: {
|
|
11
|
+
jsdoc,
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
settings: {
|
|
15
|
+
jsdoc: {
|
|
16
|
+
contexts: [
|
|
17
|
+
// We don't want to require documentation of a 'locals' (res.locals) variable
|
|
18
|
+
// AST Parser: https://github.com/es-joy/jsdoccomment
|
|
19
|
+
{
|
|
20
|
+
comment: 'JsdocBlock:not(:has(JsdocTag[tag="param"][name="locals"]))',
|
|
21
|
+
context: 'FunctionDeclaration',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
comment: 'JsdocBlock:not(:has(JsdocTag[tag="param"][name="locals"]))',
|
|
25
|
+
context: 'FunctionExpression',
|
|
26
|
+
},
|
|
27
|
+
'ArrowFunctionExpression',
|
|
28
|
+
'TSDeclareFunction',
|
|
29
|
+
],
|
|
30
|
+
exemptDestructuredRootsFromChecks: true,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
// TypeScript files
|
|
35
|
+
{
|
|
36
|
+
files: ['**/*.{ts,tsx}'],
|
|
37
|
+
rules: {
|
|
38
|
+
...jsdoc.configs['flat/recommended-typescript-error'].rules,
|
|
39
|
+
'jsdoc/check-line-alignment': 'error',
|
|
40
|
+
'jsdoc/check-tag-names': ['error', { definedTags: ['knipignore'] }],
|
|
41
|
+
'jsdoc/convert-to-jsdoc-comments': [
|
|
42
|
+
'error',
|
|
43
|
+
{
|
|
44
|
+
allowedPrefixes: ['@ts-', 'istanbul ', 'c8 ', 'v8 ', 'eslint', 'prettier-', 'global'],
|
|
45
|
+
contexts: ['FunctionDeclaration', 'TSDeclareFunction'],
|
|
46
|
+
contextsBeforeAndAfter: ['TSPropertySignature'],
|
|
47
|
+
enforceJsdocLineStyle: 'single',
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
'jsdoc/require-asterisk-prefix': 'error',
|
|
51
|
+
'jsdoc/require-jsdoc': 'off',
|
|
52
|
+
'jsdoc/require-param': 'off',
|
|
53
|
+
'jsdoc/require-returns': 'off',
|
|
54
|
+
'jsdoc/tag-lines': 'off',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
// JavaScript files
|
|
58
|
+
{
|
|
59
|
+
files: ['**/*.js'],
|
|
60
|
+
rules: {
|
|
61
|
+
...jsdoc.configs['flat/recommended-typescript-flavor-error'].rules,
|
|
62
|
+
'jsdoc/check-line-alignment': 'error',
|
|
63
|
+
'jsdoc/require-asterisk-prefix': 'error',
|
|
64
|
+
'jsdoc/require-jsdoc': 'off',
|
|
65
|
+
'jsdoc/require-param': 'off',
|
|
66
|
+
'jsdoc/require-param-description': 'off',
|
|
67
|
+
'jsdoc/require-returns': 'off',
|
|
68
|
+
'jsdoc/tag-lines': 'off',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FlatCompat } from '@eslint/eslintrc';
|
|
2
|
+
import type { TSESLint } from '@typescript-eslint/utils';
|
|
3
|
+
import youDontNeedLodashUnderscore from 'eslint-plugin-you-dont-need-lodash-underscore';
|
|
4
|
+
|
|
5
|
+
const compat = new FlatCompat();
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Lodash/underscore replacement rules.
|
|
9
|
+
*/
|
|
10
|
+
export function lodashConfig(): TSESLint.FlatConfig.ConfigArray {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
plugins: {
|
|
14
|
+
'you-dont-need-lodash-underscore': youDontNeedLodashUnderscore,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
// Use FlatCompat to extend the legacy config
|
|
18
|
+
...compat.extends('plugin:you-dont-need-lodash-underscore/all'),
|
|
19
|
+
{
|
|
20
|
+
rules: {
|
|
21
|
+
// The _.omit function is still useful in some contexts.
|
|
22
|
+
'you-dont-need-lodash-underscore/omit': 'off',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
import perfectionist from 'eslint-plugin-perfectionist';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Perfectionist sorting rules.
|
|
6
|
+
* Most rules are off by default but pre-configured for convenient inline enabling.
|
|
7
|
+
* `sort-jsx-props` is enabled by default with callback grouping.
|
|
8
|
+
*/
|
|
9
|
+
export function perfectionistConfig(): TSESLint.FlatConfig.ConfigArray {
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
plugins: {
|
|
13
|
+
perfectionist,
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
rules: {
|
|
17
|
+
// Configure all perfectionist rules to be off by default but with options preset
|
|
18
|
+
...Object.fromEntries(
|
|
19
|
+
Object.keys(perfectionist.rules ?? {}).map((ruleName) => [
|
|
20
|
+
'perfectionist/' + ruleName,
|
|
21
|
+
[
|
|
22
|
+
// Configure the options for every rule, to make inline usage more convenient.
|
|
23
|
+
'off',
|
|
24
|
+
// These rules don't have a comment partition
|
|
25
|
+
['sort-heritage-clauses', 'sort-jsx-props', 'sort-switch-case'].includes(ruleName)
|
|
26
|
+
? { type: 'natural' }
|
|
27
|
+
: { partitionByComment: true, type: 'natural' },
|
|
28
|
+
],
|
|
29
|
+
]),
|
|
30
|
+
),
|
|
31
|
+
|
|
32
|
+
// Enable sort-jsx-props with callback grouping
|
|
33
|
+
'perfectionist/sort-jsx-props': [
|
|
34
|
+
'error',
|
|
35
|
+
{
|
|
36
|
+
customGroups: [
|
|
37
|
+
{ elementNamePattern: '^on[A-Z]', groupName: 'callback' },
|
|
38
|
+
{ elementNamePattern: '^(key|ref)$', groupName: 'reserved' },
|
|
39
|
+
],
|
|
40
|
+
groups: ['reserved', 'unknown', 'shorthand-prop', 'callback'],
|
|
41
|
+
ignoreCase: true,
|
|
42
|
+
type: 'unsorted',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
|
|
3
|
+
import prairielearn from '@prairielearn/eslint-plugin';
|
|
4
|
+
|
|
5
|
+
export interface PrairieLearnPluginOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Types to allow when using the safe-db-types rule.
|
|
8
|
+
*/
|
|
9
|
+
allowDbTypes?: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* PrairieLearn-specific ESLint plugin rules.
|
|
14
|
+
* Includes AWS client configuration, JSX safety, SQL blocks, and database type safety.
|
|
15
|
+
*/
|
|
16
|
+
export function prairieLearnConfig(
|
|
17
|
+
options?: PrairieLearnPluginOptions,
|
|
18
|
+
): TSESLint.FlatConfig.ConfigArray {
|
|
19
|
+
const { allowDbTypes = [] } = options ?? {};
|
|
20
|
+
|
|
21
|
+
return [
|
|
22
|
+
{
|
|
23
|
+
plugins: {
|
|
24
|
+
'@prairielearn': prairielearn,
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
rules: {
|
|
28
|
+
'@prairielearn/aws-client-mandatory-config': 'error',
|
|
29
|
+
'@prairielearn/aws-client-shared-config': 'error',
|
|
30
|
+
'@prairielearn/jsx-no-dollar-interpolation': 'error',
|
|
31
|
+
'@prairielearn/no-current-target-in-callback': 'error',
|
|
32
|
+
'@prairielearn/no-unused-sql-blocks': 'error',
|
|
33
|
+
'@prairielearn/safe-db-types': [
|
|
34
|
+
'error',
|
|
35
|
+
{
|
|
36
|
+
allowDbTypes,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
}
|