@cratis/eslint-config 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/base.js +49 -0
- package/consumer.js +12 -0
- package/index.js +16 -0
- package/internal.js +32 -0
- package/lib/coreRules.js +34 -0
- package/package.json +52 -0
- package/specs.js +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# @cratis/eslint-config
|
|
2
|
+
|
|
3
|
+
Shared [ESLint flat-config](https://eslint.org/docs/latest/use/configure/configuration-files) presets for Cratis projects.
|
|
4
|
+
|
|
5
|
+
Two audiences, deliberately separated:
|
|
6
|
+
|
|
7
|
+
| Preset | For | Adds |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `consumer` | Projects that **build on** Cratis (other products, apps) | House TypeScript/React hygiene + `for_*` BDD spec relaxations |
|
|
10
|
+
| `internal` | The Cratis **product repos** (Arc, Components, Fundamentals, …) | Everything in `consumer` **plus** the Cratis MIT license-header rule |
|
|
11
|
+
|
|
12
|
+
The license header is a Cratis *authoring* concern, so it lives only in `internal` — consumers never inherit it.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
yarn add -D @cratis/eslint-config eslint
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`eslint` is a peer dependency; everything else (typescript-eslint, eslint-plugin-react, …) ships transitively.
|
|
21
|
+
|
|
22
|
+
## Use — a project built on Cratis
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
// eslint.config.mjs
|
|
26
|
+
import cratis from '@cratis/eslint-config';
|
|
27
|
+
|
|
28
|
+
export default [
|
|
29
|
+
...cratis.configs.consumer,
|
|
30
|
+
// …your project-specific rules layered on top
|
|
31
|
+
];
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If you consume Cratis Arc proxies or Cratis Components, also compose the product rule packages:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
import cratis from '@cratis/eslint-config';
|
|
38
|
+
import arc from '@cratis/eslint-plugin-arc';
|
|
39
|
+
import components from '@cratis/eslint-plugin-components';
|
|
40
|
+
|
|
41
|
+
export default [
|
|
42
|
+
...cratis.configs.consumer,
|
|
43
|
+
...arc.configs.recommended, // skips generated proxies, MVVM view-model discipline
|
|
44
|
+
...components.configs.recommended, // no raw primereact dialogs, subpath-only imports
|
|
45
|
+
// …your project rules
|
|
46
|
+
];
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Use — inside a Cratis product repo
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
// eslint.config.mjs
|
|
53
|
+
import cratis from '@cratis/eslint-config';
|
|
54
|
+
|
|
55
|
+
export default cratis.configs.internal;
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Building blocks
|
|
59
|
+
|
|
60
|
+
`configs.base` (hygiene + ignores) and `configs.specs` (`for_*` relaxations) are exported too, so you can compose your own preset. Named exports `base`, `specs`, `consumer`, `internal`, and `ignores` are also available.
|
package/base.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import tseslintPlugin from '@typescript-eslint/eslint-plugin';
|
|
2
|
+
import tsParser from '@typescript-eslint/parser';
|
|
3
|
+
import noNull from 'eslint-plugin-no-null';
|
|
4
|
+
import react from 'eslint-plugin-react';
|
|
5
|
+
import globals from 'globals';
|
|
6
|
+
import { coreRules } from './lib/coreRules.js';
|
|
7
|
+
|
|
8
|
+
// Default ignore globs shared across Cratis projects: build output, generated proxy
|
|
9
|
+
// `Api/` folders, scaffolding templates, declaration files, and plain JS tooling.
|
|
10
|
+
// A consumer can append its own ignores in a later config object.
|
|
11
|
+
export const ignores = [
|
|
12
|
+
'**/*.d.ts',
|
|
13
|
+
'**/*.scss.d.ts',
|
|
14
|
+
'**/tsconfig.*',
|
|
15
|
+
'**/wallaby.js',
|
|
16
|
+
'**/*.js',
|
|
17
|
+
'**/dist/**',
|
|
18
|
+
'**/node_modules/**',
|
|
19
|
+
'**/wwwroot/**',
|
|
20
|
+
'**/templates/**',
|
|
21
|
+
'**/Api/**',
|
|
22
|
+
'**/rollup.config.mjs',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
// Product-agnostic Cratis hygiene for TypeScript/React. No license-header rule here —
|
|
26
|
+
// see `internal` for the Cratis-authoring layer.
|
|
27
|
+
const base = [
|
|
28
|
+
{ name: '@cratis/eslint-config/ignores', ignores },
|
|
29
|
+
{
|
|
30
|
+
name: '@cratis/eslint-config/base',
|
|
31
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
32
|
+
plugins: {
|
|
33
|
+
'@typescript-eslint': tseslintPlugin,
|
|
34
|
+
react,
|
|
35
|
+
'no-null': noNull,
|
|
36
|
+
},
|
|
37
|
+
languageOptions: {
|
|
38
|
+
globals: { ...globals.browser },
|
|
39
|
+
parser: tsParser,
|
|
40
|
+
sourceType: 'module',
|
|
41
|
+
},
|
|
42
|
+
settings: {
|
|
43
|
+
react: { version: 'detect' },
|
|
44
|
+
},
|
|
45
|
+
rules: coreRules,
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
export default base;
|
package/consumer.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import base from './base.js';
|
|
2
|
+
import specs from './specs.js';
|
|
3
|
+
|
|
4
|
+
// What a project consuming Cratis packages should lint with: the Cratis house
|
|
5
|
+
// TypeScript/React hygiene plus the BDD spec relaxations — WITHOUT the Cratis-internal
|
|
6
|
+
// MIT license header. Spread it first in your eslint.config, then layer project rules:
|
|
7
|
+
//
|
|
8
|
+
// import cratis from '@cratis/eslint-config';
|
|
9
|
+
// export default [...cratis.configs.consumer, ...yourProjectConfig];
|
|
10
|
+
const consumer = [...base, ...specs];
|
|
11
|
+
|
|
12
|
+
export default consumer;
|
package/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import base, { ignores } from './base.js';
|
|
2
|
+
import consumer from './consumer.js';
|
|
3
|
+
import internal from './internal.js';
|
|
4
|
+
import specs from './specs.js';
|
|
5
|
+
|
|
6
|
+
// Composable Cratis ESLint flat-config presets.
|
|
7
|
+
//
|
|
8
|
+
// base product-agnostic TypeScript/React hygiene + default ignores
|
|
9
|
+
// specs `for_*` BDD spec relaxations
|
|
10
|
+
// consumer base + specs — for projects built ON Cratis (no license header)
|
|
11
|
+
// internal consumer + the Cratis MIT license header — for Cratis product repos
|
|
12
|
+
export const configs = { base, specs, consumer, internal };
|
|
13
|
+
|
|
14
|
+
export { base, specs, consumer, internal, ignores };
|
|
15
|
+
|
|
16
|
+
export default { configs };
|
package/internal.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import header from '@tony.ganchev/eslint-plugin-header';
|
|
2
|
+
import base from './base.js';
|
|
3
|
+
import specs from './specs.js';
|
|
4
|
+
|
|
5
|
+
// The Cratis MIT license header, enforced on every Cratis-authored `.ts`/`.tsx`.
|
|
6
|
+
// This is an internal authoring rule: it belongs in the Cratis product repos
|
|
7
|
+
// (Arc, Components, Fundamentals, …), and consumers must NOT inherit it.
|
|
8
|
+
const licenseHeader = {
|
|
9
|
+
name: '@cratis/eslint-config/license-header',
|
|
10
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
11
|
+
plugins: { '@tony.ganchev': header },
|
|
12
|
+
rules: {
|
|
13
|
+
'@tony.ganchev/header': ['error', {
|
|
14
|
+
header: {
|
|
15
|
+
commentType: 'line',
|
|
16
|
+
lines: [
|
|
17
|
+
' Copyright (c) Cratis. All rights reserved.',
|
|
18
|
+
' Licensed under the MIT license. See LICENSE file in the project root for full license information.',
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
}],
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// What the Cratis product repos lint their own source with: the consumer preset plus
|
|
26
|
+
// the Cratis-authoring layer.
|
|
27
|
+
//
|
|
28
|
+
// import cratis from '@cratis/eslint-config';
|
|
29
|
+
// export default cratis.configs.internal;
|
|
30
|
+
const internal = [...base, ...specs, licenseHeader];
|
|
31
|
+
|
|
32
|
+
export default internal;
|
package/lib/coreRules.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import eslintJs from '@eslint/js';
|
|
2
|
+
import tseslint from 'typescript-eslint';
|
|
3
|
+
|
|
4
|
+
// Flatten the `rules` maps from one or more flat-config objects into a single map.
|
|
5
|
+
// typescript-eslint and @eslint/js ship their recommended sets as flat-config arrays;
|
|
6
|
+
// we merge them down so the whole house rule set can live on one config block.
|
|
7
|
+
export const collectRules = configOrArray => {
|
|
8
|
+
const items = Array.isArray(configOrArray) ? configOrArray : [configOrArray];
|
|
9
|
+
return items.reduce((accumulated, item) => (item && item.rules ? { ...accumulated, ...item.rules } : accumulated), {});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// The Cratis house TypeScript/React rule set, product-agnostic. This is the rule body
|
|
13
|
+
// the Cratis product repos historically copy-pasted into each repo's eslint.config.mjs.
|
|
14
|
+
// It deliberately does NOT include the MIT license-header rule — that is an internal
|
|
15
|
+
// authoring concern layered on by the `internal` preset, never inherited by consumers.
|
|
16
|
+
export const coreRules = {
|
|
17
|
+
...collectRules(eslintJs.configs.recommended),
|
|
18
|
+
...collectRules(tseslint.configs.recommended),
|
|
19
|
+
|
|
20
|
+
'no-irregular-whitespace': 0,
|
|
21
|
+
semi: [2, 'always'],
|
|
22
|
+
'react/display-name': 0,
|
|
23
|
+
'react/react-in-jsx-scope': 0,
|
|
24
|
+
'no-prototype-builtins': 0,
|
|
25
|
+
|
|
26
|
+
'@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true }],
|
|
27
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
|
28
|
+
'@typescript-eslint/explicit-module-boundary-types': 0,
|
|
29
|
+
'@typescript-eslint/no-non-null-assertion': 0,
|
|
30
|
+
'@typescript-eslint/no-empty-function': 'error',
|
|
31
|
+
'@typescript-eslint/no-var-requires': 'error',
|
|
32
|
+
'@typescript-eslint/ban-ts-comment': 0,
|
|
33
|
+
'@typescript-eslint/no-empty-interface': 0,
|
|
34
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cratis/eslint-config",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Shared Cratis ESLint flat-config presets. `consumer` is for projects that build on Cratis; `internal` adds the Cratis-authoring rules (MIT license header) used inside the Cratis product repos.",
|
|
5
|
+
"author": "Cratis",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/Cratis/Fundamentals.git"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"eslint",
|
|
17
|
+
"eslintconfig",
|
|
18
|
+
"eslint-config",
|
|
19
|
+
"cratis"
|
|
20
|
+
],
|
|
21
|
+
"files": [
|
|
22
|
+
"index.js",
|
|
23
|
+
"base.js",
|
|
24
|
+
"specs.js",
|
|
25
|
+
"consumer.js",
|
|
26
|
+
"internal.js",
|
|
27
|
+
"lib",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"exports": {
|
|
31
|
+
"./package.json": "./package.json",
|
|
32
|
+
".": "./index.js"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"test": "yarn g:test",
|
|
36
|
+
"ci": "yarn g:test"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@eslint/js": "^10.0.1",
|
|
40
|
+
"@tony.ganchev/eslint-plugin-header": "^3.4.4",
|
|
41
|
+
"@typescript-eslint/eslint-plugin": "^8.60.1",
|
|
42
|
+
"@typescript-eslint/parser": "^8.60.1",
|
|
43
|
+
"eslint-plugin-no-null": "^1.0.2",
|
|
44
|
+
"eslint-plugin-react": "^7.37.5",
|
|
45
|
+
"globals": "^17.6.0",
|
|
46
|
+
"typescript-eslint": "^8.60.1"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"eslint": ">=9",
|
|
50
|
+
"typescript": ">=4.8.4"
|
|
51
|
+
}
|
|
52
|
+
}
|
package/specs.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Cratis BDD specifications live in `for_*` folders and read as scenario sentences.
|
|
2
|
+
// They intentionally relax a handful of rules: expression-statement assertions, free
|
|
3
|
+
// naming for `when_…`/`and_…` describers, and empty setup bodies.
|
|
4
|
+
const specs = [
|
|
5
|
+
{
|
|
6
|
+
name: '@cratis/eslint-config/specs',
|
|
7
|
+
files: ['**/for_*/**/*.ts', '**/for_*/**/*.tsx'],
|
|
8
|
+
rules: {
|
|
9
|
+
'@typescript-eslint/naming-convention': 0,
|
|
10
|
+
'@typescript-eslint/no-unused-expressions': 0,
|
|
11
|
+
'@typescript-eslint/no-empty-function': 'off',
|
|
12
|
+
'no-restricted-globals': 0,
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
export default specs;
|