@travetto/eslint 3.0.0-rc.11

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 ADDED
@@ -0,0 +1,9 @@
1
+ <!-- This file was generated by @travetto/doc and should not be modified directly -->
2
+ <!-- Please modify https://github.com/travetto/travetto/tree/main/module/eslint-plugin/DOC.ts and execute "npx trv doc" to rebuild -->
3
+ # ES Linting Rules
4
+ ## ES Linting Rules
5
+
6
+ **Install: @travetto/eslint-plugin**
7
+ ```bash
8
+ npm install @travetto/eslint-plugin
9
+ ```
package/__index__.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './support/bin/types';
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@travetto/eslint",
3
+ "version": "3.0.0-rc.11",
4
+ "description": "ES Linting Rules",
5
+ "keywords": [
6
+ "eslint",
7
+ "travetto",
8
+ "typescript"
9
+ ],
10
+ "homepage": "https://travetto.io",
11
+ "license": "MIT",
12
+ "author": {
13
+ "email": "travetto.framework@gmail.com",
14
+ "name": "Travetto Framework"
15
+ },
16
+ "main": "__index__.ts",
17
+ "files": [
18
+ "support",
19
+ "__index__.ts"
20
+ ],
21
+ "repository": {
22
+ "url": "https://github.com/travetto/travetto.git",
23
+ "directory": "module/eslint"
24
+ },
25
+ "dependencies": {
26
+ "@travetto/manifest": "^3.0.0-rc.12",
27
+ "@types/eslint": "^8.21.1",
28
+ "@typescript-eslint/eslint-plugin": "^5.52.0",
29
+ "@typescript-eslint/parser": "^5.52.0",
30
+ "eslint": "^8.34.0",
31
+ "eslint-plugin-unused-imports": "^2.0.0"
32
+ },
33
+ "peerDependencies": {
34
+ "@travetto/cli": "^3.0.0-rc.14"
35
+ },
36
+ "peerDependenciesMeta": {
37
+ "@travetto/cli": {
38
+ "optional": true
39
+ }
40
+ },
41
+ "travetto": {
42
+ "displayName": "ES Linting Rules"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ }
47
+ }
@@ -0,0 +1,113 @@
1
+ import * as parser from '@typescript-eslint/parser';
2
+
3
+ import { RootIndex } from '@travetto/manifest';
4
+
5
+ export const RULE_COMMON = {
6
+ languageOptions: {
7
+ ecmaVersion: 'latest',
8
+ sourceType: RootIndex.manifest.moduleType,
9
+ globals: {
10
+ AbortController: false,
11
+ AbortSignal: false,
12
+ AggregateError: false,
13
+ Array: false,
14
+ ArrayBuffer: false,
15
+ Atomics: false,
16
+ BigInt: false,
17
+ BigInt64Array: false,
18
+ BigUint64Array: false,
19
+ Boolean: false,
20
+ Buffer: false,
21
+ clearImmediate: false,
22
+ clearInterval: false,
23
+ clearTimeout: false,
24
+ console: false,
25
+ DataView: false,
26
+ Date: false,
27
+ decodeURI: false,
28
+ decodeURIComponent: false,
29
+ DOMException: false,
30
+ encodeURI: false,
31
+ encodeURIComponent: false,
32
+ Error: false,
33
+ EvalError: false,
34
+ Event: false,
35
+ EventTarget: false,
36
+ fetch: false,
37
+ FinalizationRegistry: false,
38
+ Float32Array: false,
39
+ Float64Array: false,
40
+ FormData: false,
41
+ Function: false,
42
+ global: false,
43
+ globalThis: false,
44
+ Headers: false,
45
+ Infinity: false,
46
+ Int16Array: false,
47
+ Int32Array: false,
48
+ Int8Array: false,
49
+ Intl: false,
50
+ isFinite: false,
51
+ isNaN: false,
52
+ JSON: false,
53
+ Map: false,
54
+ Math: false,
55
+ MessageChannel: false,
56
+ MessageEvent: false,
57
+ MessagePort: false,
58
+ NaN: false,
59
+ Number: false,
60
+ Object: false,
61
+ parseFloat: false,
62
+ parseInt: false,
63
+ performance: false,
64
+ process: false,
65
+ Promise: false,
66
+ propertyIsEnumerable: false,
67
+ Proxy: false,
68
+ queueMicrotask: false,
69
+ RangeError: false,
70
+ ReferenceError: false,
71
+ Reflect: false,
72
+ RegExp: false,
73
+ Request: false,
74
+ require: false,
75
+ Response: false,
76
+ Set: false,
77
+ setImmediate: false,
78
+ setInterval: false,
79
+ setTimeout: false,
80
+ SharedArrayBuffer: false,
81
+ String: false,
82
+ structuredClone: false,
83
+ Symbol: false,
84
+ SyntaxError: false,
85
+ TextDecoder: false,
86
+ TextEncoder: false,
87
+ TypeError: false,
88
+ Uint16Array: false,
89
+ Uint32Array: false,
90
+ Uint8Array: false,
91
+ Uint8ClampedArray: false,
92
+ undefined: false,
93
+ unescape: false,
94
+ URIError: false,
95
+ WeakMap: false,
96
+ WeakRef: false,
97
+ WeakSet: false,
98
+ },
99
+ parser,
100
+ parserOptions: {
101
+ project: 'tsconfig.json'
102
+ },
103
+ },
104
+ };
105
+
106
+ export const IGNORES = [
107
+ 'node_modules/**/*',
108
+ 'dist/**/*',
109
+ 'out/**/*',
110
+ '**/*.d.ts',
111
+ '**/fixtures/**/*',
112
+ '**/resources/**/*'
113
+ ];
@@ -0,0 +1,39 @@
1
+ import path from 'path';
2
+
3
+ import { RootIndex } from '@travetto/manifest';
4
+
5
+ export function buildEslintConfig(): string {
6
+ const rulesImp = RootIndex.resolveFileImport('@travetto/eslint/support/bin/eslint-config.ts');
7
+ const manifestImp = RootIndex.resolveFileImport('@travetto/manifest/__index__.ts');
8
+ const manifestFile = RootIndex.mainModule.outputPath;
9
+
10
+ const common = {
11
+ manifest: `process.env.TRV_MANIFEST = '${path.resolve(manifestFile)}'`,
12
+ pluginFiles: 'const pluginFiles = RootIndex.findSupport({ filter: f => /support\\/eslint[.]/.test(f) })',
13
+ build: 'const config = buildConfig(plugins)',
14
+ };
15
+
16
+ const lines = RootIndex.manifest.moduleType === 'commonjs' ?
17
+ [
18
+ common.manifest,
19
+ `const { buildConfig } = require('${rulesImp}')`,
20
+ `const { RootIndex } = require('${manifestImp}')`,
21
+ common.pluginFiles,
22
+ 'const plugins = pluginFiles.map(x => require(x.outputFile))',
23
+ common.build,
24
+ 'module.exports = config',
25
+ ''
26
+ ] :
27
+ [
28
+ common.manifest,
29
+ `const { buildConfig } = await import('${rulesImp}')`,
30
+ `const { RootIndex } = await import('${manifestImp}')`,
31
+ common.pluginFiles,
32
+ 'const plugins = await Promise.all(pluginFiles.map(x => import(x.outputFile)))',
33
+ common.build,
34
+ 'export default config',
35
+ ''
36
+ ];
37
+
38
+ return lines.join(';\n');
39
+ }
@@ -0,0 +1,86 @@
1
+ // @ts-expect-error
2
+ import * as unused from 'eslint-plugin-unused-imports';
3
+ import * as tsEslintPlugin from '@typescript-eslint/eslint-plugin';
4
+ import { existsSync, readFileSync } from 'fs';
5
+
6
+ import { path, RootIndex } from '@travetto/manifest';
7
+
8
+ import { IGNORES, RULE_COMMON } from './eslint-common';
9
+ import { STD_RULES } from './eslint-std-rules';
10
+ import { TrvEslintPlugin } from './types';
11
+
12
+ export function buildConfig(pluginMaps: Record<string, TrvEslintPlugin>[]): readonly unknown[] {
13
+ const plugins: TrvEslintPlugin[] = pluginMaps.map(Object.values).flat();
14
+ const pluginRules: Record<string, TrvEslintPlugin['rules'][string]['defaultLevel']> = {};
15
+ for (const { name, rules } of plugins) {
16
+ for (const ruleName of Object.keys(rules)) {
17
+ pluginRules[`${name}/${ruleName}`] = rules[ruleName].defaultLevel ?? 'error';
18
+ }
19
+ }
20
+
21
+ const overrides = path.resolve(RootIndex.manifest.workspacePath, 'eslint-overrides.json');
22
+
23
+ const extra: (typeof STD_RULES)[] = existsSync(overrides) ? JSON.parse(readFileSync(overrides, 'utf8')) : [];
24
+
25
+ const result = [
26
+ 'eslint:recommended',
27
+ { ignores: IGNORES, },
28
+ {
29
+ ...RULE_COMMON,
30
+ files: ['**/*.ts', '**/*.js'],
31
+ plugins: {
32
+ '@typescript-eslint': {
33
+ rules: tsEslintPlugin.rules,
34
+ },
35
+ 'unused-imports': {
36
+ rules: unused.rules,
37
+ },
38
+ ...(Object.fromEntries(plugins.map(x => [x.name, x])))
39
+ },
40
+ rules: {
41
+ ...STD_RULES,
42
+ ...pluginRules
43
+ }
44
+ },
45
+ {
46
+ ...RULE_COMMON,
47
+ files: ['**/*.ts'],
48
+ rules: {
49
+ '@typescript-eslint/explicit-function-return-type': 'warn',
50
+ 'no-undef': 0,
51
+ }
52
+ },
53
+ {
54
+ ...RULE_COMMON,
55
+ files: ['**/DOC.ts', '**/doc/**/*.ts'],
56
+ rules: {
57
+ 'max-len': 0,
58
+ '@typescript-eslint/quotes': 'warn',
59
+ '@typescript-eslint/indent': 0,
60
+ '@typescript-eslint/consistent-type-assertions': 0,
61
+ '@typescript-eslint/explicit-function-return-type': 0
62
+ }
63
+ },
64
+ {
65
+ ...RULE_COMMON,
66
+ files: ['module/compiler/**/*.ts', 'module/transformer/**/*.ts', '**/support/transform*.ts', '**/support/transformer.*.ts'],
67
+ rules: {
68
+ 'no-restricted-imports': 0
69
+ }
70
+ },
71
+ {
72
+ ...RULE_COMMON,
73
+ files: ['**/test/**/*.ts', '**/support/test/**/*.ts'],
74
+ rules: {
75
+ '@typescript-eslint/consistent-type-assertions': 0,
76
+ '@typescript-eslint/explicit-function-return-type': 0
77
+ }
78
+ },
79
+ ...extra.map(ex => ({
80
+ ...RULE_COMMON,
81
+ ...ex
82
+ }))
83
+ ] as const;
84
+
85
+ return result;
86
+ }
@@ -0,0 +1,219 @@
1
+ export const STD_RULES = {
2
+ 'no-loss-of-precision': 0,
3
+ 'unused-imports/no-unused-imports': 'error',
4
+ 'no-unused-vars': 0,
5
+ 'no-dupe-class-members': 0,
6
+ '@typescript-eslint/array-type': 'error',
7
+ '@typescript-eslint/explicit-function-return-type': 0,
8
+ '@typescript-eslint/no-non-null-assertion': 0,
9
+ '@typescript-eslint/no-explicit-any': 'warn',
10
+ '@typescript-eslint/explicit-member-accessibility': [0, { accessibility: 'explicit' }],
11
+ indent: 0,
12
+ '@typescript-eslint/indent': [
13
+ 'error',
14
+ 2,
15
+ {
16
+ ignoredNodes: [
17
+ 'PropertyDefinition[decorators]',
18
+ 'TSUnionType',
19
+ 'TSTypeParameterInstantiation',
20
+ 'FunctionExpression > .params[decorators.length > 0]',
21
+ 'FunctionExpression > .params > :matches(Decorator, :not(:first-child))',
22
+ 'ClassBody.body > PropertyDefinition[decorators.length > 0] > .key'
23
+ ],
24
+ SwitchCase: 1
25
+ }
26
+ ],
27
+ '@typescript-eslint/member-delimiter-style': [
28
+ 'error',
29
+ {
30
+ multiline: { delimiter: 'semi', requireLast: true },
31
+ singleline: { delimiter: 'comma', requireLast: false }
32
+ }
33
+ ],
34
+ 'no-restricted-imports': ['error', { paths: ['typescript'] }],
35
+ '@typescript-eslint/no-use-before-define': ['error', { classes: false }],
36
+ '@typescript-eslint/member-ordering': [
37
+ 'error',
38
+ {
39
+ default: [
40
+ 'private-static-field',
41
+ 'protected-static-field',
42
+ 'public-static-field',
43
+ 'private-static-method',
44
+ 'protected-static-method',
45
+ 'public-static-method',
46
+ 'private-instance-field',
47
+ 'protected-instance-field',
48
+ 'public-instance-field',
49
+ 'private-constructor',
50
+ 'protected-constructor',
51
+ 'public-constructor',
52
+ 'private-instance-method',
53
+ 'protected-instance-method',
54
+ 'public-instance-method'
55
+ ]
56
+ }
57
+ ],
58
+ '@typescript-eslint/no-var-requires': 0,
59
+ '@typescript-eslint/no-empty-function': 0,
60
+ '@typescript-eslint/no-for-in-array': 'error',
61
+ '@typescript-eslint/no-inferrable-types': 0,
62
+ '@typescript-eslint/no-this-alias': 'error',
63
+ 'require-atomic-updates': 0,
64
+ '@typescript-eslint/no-unused-vars': [
65
+ 'error',
66
+ { varsIgnorePattern: '^(_|[A-Z])[A-Za-z0-9]*', args: 'none' }
67
+ ],
68
+ '@typescript-eslint/quotes': [
69
+ 'error',
70
+ 'single',
71
+ { avoidEscape: true, allowTemplateLiterals: false }
72
+ ],
73
+ '@typescript-eslint/semi': [
74
+ 'error',
75
+ 'always'
76
+ ],
77
+ '@typescript-eslint/no-empty-interface': 0,
78
+ '@typescript-eslint/triple-slash-reference': 0,
79
+ '@typescript-eslint/interface-name-prefix': 0,
80
+ 'no-case-declarations': [
81
+ 'error'
82
+ ],
83
+ 'no-ex-assign': 0,
84
+ '@typescript-eslint/ban-types': 0,
85
+ '@typescript-eslint/ban-ts-comment': 0,
86
+ '@typescript-eslint/type-annotation-spacing': 'error',
87
+ '@typescript-eslint/explicit-module-boundary-types': 0,
88
+ 'arrow-body-style': ['error', 'as-needed'],
89
+ '@typescript-eslint/naming-convention': [
90
+ 'error',
91
+ {
92
+ selector: 'default',
93
+ format: ['camelCase']
94
+ },
95
+ {
96
+ selector: 'parameter',
97
+ format: [],
98
+ filter: { regex: '^__', match: true }
99
+ },
100
+ {
101
+ selector: 'variable',
102
+ format: [],
103
+ filter: { regex: '^__', match: true }
104
+ },
105
+ {
106
+ selector: 'property',
107
+ format: [
108
+ 'camelCase',
109
+ 'UPPER_CASE',
110
+ 'PascalCase',
111
+ 'snake_case'
112
+ ],
113
+ leadingUnderscore: 'allow'
114
+ },
115
+ {
116
+ selector: 'variable',
117
+ format: [
118
+ 'camelCase',
119
+ 'UPPER_CASE',
120
+ 'PascalCase'
121
+ ],
122
+ leadingUnderscore: 'allow'
123
+ },
124
+ {
125
+ selector: 'method',
126
+ format: [
127
+ 'camelCase',
128
+ 'UPPER_CASE',
129
+ 'PascalCase'
130
+ ],
131
+ leadingUnderscore: 'allow'
132
+ },
133
+ {
134
+ selector: 'parameter',
135
+ format: ['camelCase'],
136
+ leadingUnderscore: 'allow'
137
+ },
138
+ {
139
+ selector: 'typeLike',
140
+ format: ['PascalCase']
141
+ },
142
+ {
143
+ selector: 'function',
144
+ format: ['PascalCase', 'camelCase']
145
+ },
146
+ {
147
+ selector: 'objectLiteralProperty',
148
+ modifiers: ['requiresQuotes'],
149
+ format: null,
150
+ custom: { regex: '.*', match: true }
151
+ },
152
+ {
153
+ selector: 'objectLiteralMethod',
154
+ modifiers: ['requiresQuotes'],
155
+ format: null,
156
+ custom: { regex: '.*', match: true }
157
+ }
158
+ ],
159
+ curly: 'error',
160
+ 'dot-notation': 0,
161
+ eqeqeq: ['error', 'smart'],
162
+ 'guard-for-in': 'error',
163
+ 'id-match': 'error',
164
+ 'max-len': ['error', { code: 180 }],
165
+ 'new-parens': 'error',
166
+ 'no-bitwise': 'error',
167
+ 'no-caller': 'error',
168
+ 'no-console': [
169
+ 'error',
170
+ {
171
+ allow: [
172
+ 'log',
173
+ 'warn',
174
+ 'trace',
175
+ 'debug',
176
+ 'info',
177
+ 'error',
178
+ 'Console',
179
+ 'profile',
180
+ 'profileEnd'
181
+ ]
182
+ }
183
+ ],
184
+ 'no-extra-boolean-cast': 0,
185
+ 'no-prototype-builtins': 0,
186
+ 'no-debugger': 'error',
187
+ 'no-duplicate-imports': 'error',
188
+ 'no-empty': 0,
189
+ 'no-eval': 'error',
190
+ 'no-fallthrough': 'error',
191
+ 'no-invalid-this': 0,
192
+ 'no-irregular-whitespace': 'error',
193
+ 'no-multiple-empty-lines': 'error',
194
+ 'no-new-wrappers': 'error',
195
+ 'no-redeclare': 0,
196
+ '@typescript-eslint/no-redeclare': ['error', { builtinGlobals: false, }],
197
+ 'no-shadow': ['error', { hoist: 'all' }],
198
+ 'no-sparse-arrays': 'error',
199
+ 'no-template-curly-in-string': 'error',
200
+ 'no-throw-literal': 'error',
201
+ 'no-trailing-spaces': 'error',
202
+ 'no-underscore-dangle': 0,
203
+ 'no-useless-escape': 0,
204
+ 'no-unused-expressions': 0,
205
+ 'no-unused-labels': 'error',
206
+ 'no-var': 'error',
207
+ 'object-shorthand': 'error',
208
+ 'prefer-const': 'error',
209
+ 'prefer-object-spread': 'error',
210
+ 'prefer-template': 'error',
211
+ 'quote-props': ['error', 'as-needed'],
212
+ radix: 'error',
213
+ 'spaced-comment': [
214
+ 'error',
215
+ 'always',
216
+ { line: { markers: ['/'] } }
217
+ ],
218
+ '@typescript-eslint/consistent-type-assertions': ['warn', { assertionStyle: 'never' }]
219
+ };
@@ -0,0 +1,7 @@
1
+ export type TrvEslintPlugin = {
2
+ name: string;
3
+ rules: Record<string, {
4
+ defaultLevel?: string | boolean | number;
5
+ create: Function;
6
+ }>;
7
+ };
@@ -0,0 +1,36 @@
1
+ import { RootIndex } from '@travetto/manifest';
2
+ import { ExecUtil, GlobalEnvConfig } from '@travetto/base';
3
+ import { CliCommand, CliModuleUtil, OptionConfig } from '@travetto/cli';
4
+
5
+ type Options = {
6
+ changed: OptionConfig<boolean>;
7
+ };
8
+
9
+ /**
10
+ * Command line support for linting
11
+ */
12
+ export class LintCommand extends CliCommand<Options> {
13
+ name = 'lint';
14
+
15
+ getOptions(): Options {
16
+ return {
17
+ changed: this.boolOption({ desc: 'Only check changed modules', def: false }),
18
+ };
19
+ }
20
+
21
+ envInit(): GlobalEnvConfig {
22
+ return { debug: false };
23
+ }
24
+
25
+ async action(): Promise<void> {
26
+ const mods = await CliModuleUtil.findModules(this.cmd.changed ? 'changed' : 'all');
27
+
28
+ const res = await ExecUtil.spawn('npx', ['eslint', ...mods.filter(x => x.local).map(x => x.sourcePath)], {
29
+ cwd: RootIndex.manifest.workspacePath,
30
+ stdio: 'inherit',
31
+ catchAsResult: true
32
+ }).result;
33
+
34
+ return this.exit(res.code);
35
+ }
36
+ }
@@ -0,0 +1,18 @@
1
+ import fs from 'fs/promises';
2
+
3
+ import { CliCommand } from '@travetto/cli';
4
+ import { path, RootIndex } from '@travetto/manifest';
5
+
6
+ import { buildEslintConfig } from './bin/eslint-config-file';
7
+
8
+ export class LintConfigureCommand extends CliCommand {
9
+ name = 'lint:register';
10
+
11
+ async action(): Promise<void> {
12
+ const content = buildEslintConfig();
13
+ const output = path.resolve(RootIndex.manifest.workspacePath, 'eslint.config.js');
14
+ await fs.writeFile(output, content.replaceAll(RootIndex.manifest.workspacePath, '.').trim());
15
+
16
+ console.log(`Wrote eslint config to ${output}`);
17
+ }
18
+ }