@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 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;
@@ -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;