@venizia/dev-configs 0.2.0-9 → 0.2.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/LICENSE.md +0 -1
- package/README.md +91 -103
- package/dist/eslint.d.ts.map +1 -1
- package/dist/eslint.js +2 -1
- package/dist/eslint.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +32 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +111 -0
- package/dist/react.js.map +1 -0
- package/package.json +2 -2
package/LICENSE.md
CHANGED
|
@@ -72,7 +72,6 @@ Ignis uses the following open-source libraries. We are grateful to the authors a
|
|
|
72
72
|
|
|
73
73
|
| Library | License | Description |
|
|
74
74
|
|---------|---------|-------------|
|
|
75
|
-
| [Lodash](https://github.com/lodash/lodash) | MIT | Utility library |
|
|
76
75
|
| [reflect-metadata](https://github.com/rbuckton/reflect-metadata) | Apache-2.0 | Metadata reflection API |
|
|
77
76
|
|
|
78
77
|
### Documentation Dependencies
|
package/README.md
CHANGED
|
@@ -1,29 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
# @venizia/dev-configs
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
**Shared ESLint, Prettier, and TypeScript configs for the IGNIS ecosystem**
|
|
6
|
-
|
|
7
|
-
[](https://www.npmjs.com/package/@venizia/dev-configs)
|
|
8
|
-
[](./LICENSE.md)
|
|
9
|
-
[](https://www.typescriptlang.org/)
|
|
10
|
-
[](https://eslint.org/)
|
|
11
|
-
[](https://prettier.io/)
|
|
12
|
-
|
|
13
|
-
[Documentation](https://ignis.venizia.ai) •
|
|
14
|
-
[Best practices](https://ignis.venizia.ai/best-practices/) •
|
|
15
|
-
[Repository](https://github.com/VENIZIA-AI/ignis)
|
|
16
|
-
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
One source of truth for lint, format, and compile settings across every IGNIS package, example, and
|
|
22
|
-
downstream app. It ships three things: an ESLint flat config array, a Prettier config object, and two
|
|
23
|
-
`tsconfig` files - one base, one for NodeNext modules.
|
|
24
|
-
|
|
25
|
-
Reach for it when you are building on IGNIS and want the same rules the framework itself is written
|
|
26
|
-
under. Consumption is three lines per tool.
|
|
3
|
+
The ESLint, Prettier and TypeScript settings every IGNIS package is built with. Install it as a dev
|
|
4
|
+
dependency in an application that wants the same rules.
|
|
27
5
|
|
|
28
6
|
## Install
|
|
29
7
|
|
|
@@ -31,94 +9,114 @@ under. Consumption is three lines per tool.
|
|
|
31
9
|
bun add -d @venizia/dev-configs eslint prettier typescript
|
|
32
10
|
```
|
|
33
11
|
|
|
34
|
-
`eslint
|
|
35
|
-
|
|
12
|
+
`eslint` (9 or 10), `prettier` (3) and `typescript` (5 or 6) are optional peers. Install only the
|
|
13
|
+
tools you use.
|
|
36
14
|
|
|
37
15
|
## Use it
|
|
38
16
|
|
|
39
|
-
|
|
17
|
+
Each tool takes one file.
|
|
40
18
|
|
|
41
19
|
```javascript
|
|
20
|
+
// eslint.config.mjs
|
|
42
21
|
import { eslintConfigs } from '@venizia/dev-configs';
|
|
43
22
|
|
|
44
|
-
export default eslintConfigs;
|
|
23
|
+
export default [{ ignores: ['dist/'] }, ...eslintConfigs];
|
|
45
24
|
```
|
|
46
25
|
|
|
47
|
-
**`.prettierrc.mjs`**
|
|
48
|
-
|
|
49
26
|
```javascript
|
|
27
|
+
// .prettierrc.mjs
|
|
50
28
|
import { prettierConfigs } from '@venizia/dev-configs';
|
|
51
29
|
|
|
52
30
|
export default prettierConfigs;
|
|
53
31
|
```
|
|
54
32
|
|
|
55
|
-
**`tsconfig.json`**
|
|
56
|
-
|
|
57
33
|
```json
|
|
34
|
+
// tsconfig.json
|
|
58
35
|
{
|
|
59
36
|
"extends": "@venizia/dev-configs/tsconfig.common.json",
|
|
60
|
-
"compilerOptions": {
|
|
37
|
+
"compilerOptions": {
|
|
38
|
+
"outDir": "dist",
|
|
39
|
+
"rootDir": "src",
|
|
40
|
+
"experimentalDecorators": true,
|
|
41
|
+
"emitDecoratorMetadata": true
|
|
42
|
+
},
|
|
61
43
|
"include": ["src"]
|
|
62
44
|
}
|
|
63
45
|
```
|
|
64
46
|
|
|
65
|
-
|
|
47
|
+
## Declare the decorator flag in your own tsconfig
|
|
66
48
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
49
|
+
The base config sets `experimentalDecorators`. But Bun can miss a flag inherited through `extends`
|
|
50
|
+
when it runs your source. Parameter decorators are then dropped with no error, and an `@inject`
|
|
51
|
+
value is `undefined` at run time.
|
|
70
52
|
|
|
71
|
-
|
|
53
|
+
Declare `experimentalDecorators: true` in your application's own `tsconfig.json`, as in the example
|
|
54
|
+
earlier. Every IGNIS example does.
|
|
72
55
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
> **Bun does not resolve these flags through `extends`.** An application `tsconfig.json` must declare
|
|
79
|
-
> them inline, even when it already extends `tsconfig.common.json`.
|
|
56
|
+
| Flag | Base value | Why |
|
|
57
|
+
| :--- | :--- | :--- |
|
|
58
|
+
| `experimentalDecorators` | `true` | `@inject`, `@controller`, `@repository` and the other decorators need it |
|
|
59
|
+
| `emitDecoratorMetadata` | `true` | Optional. IGNIS reads `design:paramtypes` once, to validate a `@repository` constructor, and skips the check when the metadata is absent |
|
|
60
|
+
| `useDefineForClassFields` | `false` | Class fields are assigned, not defined, so a subclass field initializer does not shadow a value the base constructor set |
|
|
80
61
|
|
|
81
|
-
|
|
82
|
-
{
|
|
83
|
-
"extends": "@venizia/dev-configs/tsconfig.common.json",
|
|
84
|
-
"compilerOptions": {
|
|
85
|
-
"experimentalDecorators": true,
|
|
86
|
-
"emitDecoratorMetadata": true,
|
|
87
|
-
"useDefineForClassFields": false
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
```
|
|
62
|
+
## Entry points
|
|
91
63
|
|
|
92
|
-
|
|
93
|
-
|
|
64
|
+
| Entry point | What it gives |
|
|
65
|
+
| :--- | :--- |
|
|
66
|
+
| `@venizia/dev-configs` | `eslintConfigs` (flat config array), `ReactEslintConfigs`, `prettierConfigs`, `BunCompiler` |
|
|
67
|
+
| `@venizia/dev-configs/tsconfig.base.json` | Target and lib ES2024, `module` Node16, strict mode with `noImplicitAny`, `strictPropertyInitialization` and `useUnknownInCatchVariables` off, `noEmitOnError`, tests excluded |
|
|
68
|
+
| `@venizia/dev-configs/tsconfig.common.json` | Extends the base and switches `module` and `moduleResolution` to `nodenext` |
|
|
94
69
|
|
|
95
70
|
## What each config sets
|
|
96
71
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
A flat config array (ESLint 9+; the legacy `.eslintrc` format is not supported). Three layers, later
|
|
100
|
-
ones winning:
|
|
101
|
-
|
|
102
|
-
| Layer | Source | Brings |
|
|
103
|
-
| :--- | :--- | :--- |
|
|
104
|
-
| 1 | `@minimaltech/eslint-common` | `eslint:recommended`, `typescript-eslint` recommended, `eslint-plugin-prettier` (format violations are lint errors), naming-convention rules |
|
|
105
|
-
| 2 | `@minimaltech/eslint-node` | `eslint-plugin-n`, LoopBack-style strict rules |
|
|
106
|
-
| 3 | this package | the IGNIS overrides below |
|
|
107
|
-
|
|
108
|
-
| Rule | Setting | Why |
|
|
109
|
-
| :--- | :--- | :--- |
|
|
110
|
-
| `@typescript-eslint/no-explicit-any` | `off` | framework generics need escape hatches; prefer a simple cast over a baroque one |
|
|
111
|
-
| `curly` | `['error', 'all']` | always braces, no single-line ifs |
|
|
112
|
-
| `unicorn/switch-case-braces` | `['error', 'always']` | braced `case` blocks so a `const` cannot leak between cases |
|
|
72
|
+
`eslintConfigs` is `@minimaltech/eslint-node` (ESLint recommended, typescript-eslint, Prettier as a
|
|
73
|
+
lint rule, naming conventions, `curly`, `eslint-plugin-n`) plus these IGNIS rules:
|
|
113
74
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
75
|
+
| Rule | Setting |
|
|
76
|
+
| :--- | :--- |
|
|
77
|
+
| `@typescript-eslint/no-explicit-any` | `off` |
|
|
78
|
+
| `@typescript-eslint/ban-ts-comment` | `error` - `@ts-expect-error` with a description is still allowed |
|
|
79
|
+
| `@typescript-eslint/no-namespace` | `error` |
|
|
80
|
+
| `unicorn/switch-case-braces` | `['error', 'always']` |
|
|
81
|
+
|
|
82
|
+
`ReactEslintConfigs.create({ plugins })` is `eslintConfigs` plus what a React frontend needs. The
|
|
83
|
+
plugins come in as options, so a backend installs none of them:
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
// eslint.config.mjs
|
|
87
|
+
import { ReactEslintConfigs } from '@venizia/dev-configs';
|
|
88
|
+
import react from 'eslint-plugin-react';
|
|
89
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
90
|
+
import jsxA11y from 'eslint-plugin-jsx-a11y';
|
|
91
|
+
|
|
92
|
+
export default [
|
|
93
|
+
{ ignores: ['dist/'] },
|
|
94
|
+
...ReactEslintConfigs.create({ plugins: { react, reactHooks, jsxA11y } }),
|
|
95
|
+
];
|
|
119
96
|
```
|
|
120
97
|
|
|
121
|
-
|
|
98
|
+
| Adds | Setting |
|
|
99
|
+
| :--- | :--- |
|
|
100
|
+
| React correctness (`jsx-key`, `no-children-prop`, `no-deprecated`, ... - 14 rules) | `error`, `.jsx`/`.tsx` |
|
|
101
|
+
| `jsx-a11y` basics (`alt-text`, `aria-props`, `aria-role`, ... - 9 rules) | `error`, `.jsx`/`.tsx` |
|
|
102
|
+
| `react-hooks/rules-of-hooks` / `exhaustive-deps` | `error` / `warn`, every source file |
|
|
103
|
+
| `@typescript-eslint/consistent-type-imports` | `['error', { prefer: 'type-imports' }]` |
|
|
104
|
+
| `naming-convention` | the base rule, plus PascalCase functions (`function App()`), `.jsx`/`.tsx` |
|
|
105
|
+
| `no-floating-promises`, `no-void`, `no-invalid-this`, `no-use-before-define` | `off` - a UI fires promises from handlers and uses components above their declaration |
|
|
106
|
+
| `no-explicit-any` | `warn` (the base has it `off`) |
|
|
107
|
+
| `no-shadow` | `warn` |
|
|
108
|
+
| `no-unused-vars` | `warn`, `_`-prefixed names ignored |
|
|
109
|
+
|
|
110
|
+
Rules the automatic JSX runtime or `tsc` already enforce (`react-in-jsx-scope`, `prop-types`,
|
|
111
|
+
`jsx-no-undef`, ...) are left out.
|
|
112
|
+
|
|
113
|
+
- `reactVersion` defaults to `'detect'`. Under ESLint 10, eslint-plugin-react 7 cannot detect it and
|
|
114
|
+
aborts - pass the version: `create({ plugins, reactVersion: '19.2' })`.
|
|
115
|
+
- In an `eslint.config.ts`, `eslint-plugin-jsx-a11y` needs `@types/eslint-plugin-jsx-a11y`.
|
|
116
|
+
- `consistent-type-imports` keeps the default `fixStyle`; a codebase that prefers
|
|
117
|
+
`inline-type-imports` sets it on top.
|
|
118
|
+
|
|
119
|
+
`prettierConfigs`:
|
|
122
120
|
|
|
123
121
|
| Setting | Value |
|
|
124
122
|
| :--- | :--- |
|
|
@@ -130,35 +128,25 @@ root and **must `include` the config files themselves** or ESLint fails on them:
|
|
|
130
128
|
| `bracketSpacing` | `true` |
|
|
131
129
|
| `arrowParens` | `'avoid'` |
|
|
132
130
|
|
|
133
|
-
|
|
131
|
+
`BunCompiler.compile()` builds one Bun executable: minified, with a linked source map. The
|
|
132
|
+
compile target comes from `BUN_TARGET` and defaults to `bun-linux-x64`.
|
|
134
133
|
|
|
135
|
-
|
|
134
|
+
```typescript
|
|
135
|
+
import { BunCompiler } from '@venizia/dev-configs';
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
| `tsconfig.base.json` | the foundation: `target`/`lib` ES2024, `module` Node16, the decorator flags, strict mode, `declaration` + source maps, `noEmitOnError` |
|
|
140
|
-
| `tsconfig.common.json` | applications: extends the base, switches `module` and `moduleResolution` to `nodenext` |
|
|
141
|
-
|
|
142
|
-
Strictness is deliberately balanced rather than maximal - `strict: true`, but `noImplicitAny`,
|
|
143
|
-
`strictPropertyInitialization`, and `useUnknownInCatchVariables` are `false` because DI-injected
|
|
144
|
-
properties and framework generics cannot satisfy them. `noUnusedLocals`, `noUnusedParameters`,
|
|
145
|
-
`noImplicitOverride`, and `noFallthroughCasesInSwitch` are on.
|
|
146
|
-
|
|
147
|
-
The base config `exclude`s tests (`**/*.test.ts`, `**/*.spec.ts`, `**/__tests__/**`). If your build
|
|
148
|
-
config re-includes them, remember `noEmitOnError: true` means one broken test aborts the whole emit.
|
|
137
|
+
await BunCompiler.compile({ entrypoint: './src/index.ts', outfile: './dist/app' });
|
|
138
|
+
```
|
|
149
139
|
|
|
150
|
-
##
|
|
140
|
+
## Where it sits
|
|
151
141
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
- It is the root of the build chain: `dev-configs -> inversion -> helpers -> boot -> core`.
|
|
155
|
-
- Use `tsc` directly. Never `npx`, `bunx`, or `bun x` for TypeScript compilation.
|
|
142
|
+
The root of the chain, with no IGNIS dependency: **dev-configs** -> inversion -> {filter, helpers}
|
|
143
|
+
-> {boot, kernel} -> connectors -> {core-worker, core-server} -> atlas.
|
|
156
144
|
|
|
157
145
|
## Links
|
|
158
146
|
|
|
159
|
-
[
|
|
160
|
-
[
|
|
161
|
-
[Changelog](https://ignis.venizia.ai/changelogs/)
|
|
162
|
-
[
|
|
147
|
+
- [Tooling configuration](https://ignis.venizia.ai/best-practices/code-style-standards/tooling)
|
|
148
|
+
- [TypeScript 6 and toolchain changelog](https://ignis.venizia.ai/changelogs/2026-03-31-typescript-6-and-toolchain)
|
|
149
|
+
- [Changelog](https://ignis.venizia.ai/changelogs/)
|
|
150
|
+
- [Source](https://github.com/VENIZIA-AI/ignis/blob/main/packages/dev-configs)
|
|
163
151
|
|
|
164
152
|
MIT licensed - see [LICENSE.md](./LICENSE.md).
|
package/dist/eslint.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGrC,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGrC,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAexC,CAAC"}
|
package/dist/eslint.js
CHANGED
|
@@ -11,12 +11,13 @@ exports.eslintConfigs = [
|
|
|
11
11
|
{
|
|
12
12
|
rules: {
|
|
13
13
|
"@typescript-eslint/no-explicit-any": "off",
|
|
14
|
+
"@typescript-eslint/ban-ts-comment": "error",
|
|
15
|
+
"@typescript-eslint/no-namespace": "error",
|
|
14
16
|
},
|
|
15
17
|
},
|
|
16
18
|
{
|
|
17
19
|
plugins: { unicorn: eslint_plugin_unicorn_1.default },
|
|
18
20
|
rules: {
|
|
19
|
-
curly: ["error", "all"],
|
|
20
21
|
"unicorn/switch-case-braces": ["error", "always"],
|
|
21
22
|
},
|
|
22
23
|
},
|
package/dist/eslint.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":";;;;;;AAAA,2EAAqD;AAErD,kFAA4C;AAE/B,QAAA,aAAa,GAAoB;IAC5C,GAAG,qBAAa;IAChB;QACE,KAAK,EAAE;YACL,oCAAoC,EAAE,KAAK;
|
|
1
|
+
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":";;;;;;AAAA,2EAAqD;AAErD,kFAA4C;AAE/B,QAAA,aAAa,GAAoB;IAC5C,GAAG,qBAAa;IAChB;QACE,KAAK,EAAE;YACL,oCAAoC,EAAE,KAAK;YAC3C,mCAAmC,EAAE,OAAO;YAC5C,iCAAiC,EAAE,OAAO;SAC3C;KACF;IACD;QACE,OAAO,EAAE,EAAE,OAAO,EAAP,+BAAO,EAAE;QACpB,KAAK,EAAE;YACL,4BAA4B,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;SAClD;KACF;CACF,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -17,4 +17,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./compile"), exports);
|
|
18
18
|
__exportStar(require("./eslint"), exports);
|
|
19
19
|
__exportStar(require("./prettier"), exports);
|
|
20
|
+
__exportStar(require("./react"), exports);
|
|
20
21
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,2CAAyB;AACzB,6CAA2B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,2CAAyB;AACzB,6CAA2B;AAC3B,0CAAwB"}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ESLint, Linter } from "eslint";
|
|
2
|
+
/** Without `configs`: each plugin types its presets its own way, and only the rules are used here. */
|
|
3
|
+
type TRulesPlugin = Omit<ESLint.Plugin, "configs">;
|
|
4
|
+
export interface IReactEslintPlugins {
|
|
5
|
+
react: TRulesPlugin;
|
|
6
|
+
reactHooks: TRulesPlugin;
|
|
7
|
+
jsxA11y: TRulesPlugin;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The base preset plus what a React frontend needs on top: the React, hooks and accessibility rules,
|
|
11
|
+
* and the base rules a UI relaxes on purpose. The plugins come in as options, so a backend that
|
|
12
|
+
* never calls this installs none of them.
|
|
13
|
+
*
|
|
14
|
+
* ```js
|
|
15
|
+
* import react from 'eslint-plugin-react';
|
|
16
|
+
* import reactHooks from 'eslint-plugin-react-hooks';
|
|
17
|
+
* import jsxA11y from 'eslint-plugin-jsx-a11y';
|
|
18
|
+
*
|
|
19
|
+
* export default ReactEslintConfigs.create({ plugins: { react, reactHooks, jsxA11y } });
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* `reactVersion` defaults to `detect`. Under ESLint 10, eslint-plugin-react 7 cannot detect it and
|
|
23
|
+
* aborts, so pass the version there (`reactVersion: '19.2'`).
|
|
24
|
+
*/
|
|
25
|
+
export declare class ReactEslintConfigs {
|
|
26
|
+
static create(opts: {
|
|
27
|
+
plugins: IReactEslintPlugins;
|
|
28
|
+
reactVersion?: string;
|
|
29
|
+
}): Linter.Config[];
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAG7C,sGAAsG;AACtG,KAAK,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,EAAE,YAAY,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;CACvB;AAID;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,kBAAkB;IAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;QAClB,OAAO,EAAE,mBAAmB,CAAC;QAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,MAAM,CAAC,MAAM,EAAE;CA+FpB"}
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReactEslintConfigs = void 0;
|
|
4
|
+
const eslint_1 = require("./eslint");
|
|
5
|
+
const NAMING_CONVENTION = "@typescript-eslint/naming-convention";
|
|
6
|
+
/**
|
|
7
|
+
* The base preset plus what a React frontend needs on top: the React, hooks and accessibility rules,
|
|
8
|
+
* and the base rules a UI relaxes on purpose. The plugins come in as options, so a backend that
|
|
9
|
+
* never calls this installs none of them.
|
|
10
|
+
*
|
|
11
|
+
* ```js
|
|
12
|
+
* import react from 'eslint-plugin-react';
|
|
13
|
+
* import reactHooks from 'eslint-plugin-react-hooks';
|
|
14
|
+
* import jsxA11y from 'eslint-plugin-jsx-a11y';
|
|
15
|
+
*
|
|
16
|
+
* export default ReactEslintConfigs.create({ plugins: { react, reactHooks, jsxA11y } });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* `reactVersion` defaults to `detect`. Under ESLint 10, eslint-plugin-react 7 cannot detect it and
|
|
20
|
+
* aborts, so pass the version there (`reactVersion: '19.2'`).
|
|
21
|
+
*/
|
|
22
|
+
class ReactEslintConfigs {
|
|
23
|
+
static create(opts) {
|
|
24
|
+
const { react, reactHooks, jsxA11y } = opts.plugins;
|
|
25
|
+
const { reactVersion = "detect" } = opts;
|
|
26
|
+
// The last config that sets it wins, as in ESLint itself.
|
|
27
|
+
const baseNaming = [...eslint_1.eslintConfigs]
|
|
28
|
+
.reverse()
|
|
29
|
+
.find((config) => config.rules?.[NAMING_CONVENTION])?.rules?.[NAMING_CONVENTION];
|
|
30
|
+
// A bare severity carries no selectors; nothing to extend then but the severity.
|
|
31
|
+
const [severity, ...selectors] = Array.isArray(baseNaming) ? baseNaming : [baseNaming ?? "error"];
|
|
32
|
+
return [
|
|
33
|
+
...eslint_1.eslintConfigs,
|
|
34
|
+
{
|
|
35
|
+
files: ["**/*.{jsx,tsx}"],
|
|
36
|
+
plugins: { react, "jsx-a11y": jsxA11y },
|
|
37
|
+
settings: { react: { version: reactVersion } },
|
|
38
|
+
rules: {
|
|
39
|
+
// The base naming rule, plus PascalCase functions: a component declared as `function App()`.
|
|
40
|
+
[NAMING_CONVENTION]: [
|
|
41
|
+
severity,
|
|
42
|
+
...selectors,
|
|
43
|
+
{ selector: "function", format: ["camelCase", "PascalCase"] },
|
|
44
|
+
],
|
|
45
|
+
// Correctness rules from react's recommended set. Left out: what the automatic JSX runtime or
|
|
46
|
+
// tsc already covers (react-in-jsx-scope, jsx-uses-react, prop-types, jsx-no-undef,
|
|
47
|
+
// jsx-no-duplicate-props, no-unknown-property).
|
|
48
|
+
"react/display-name": "error",
|
|
49
|
+
"react/jsx-boolean-value": "error",
|
|
50
|
+
"react/jsx-key": "error",
|
|
51
|
+
"react/jsx-no-comment-textnodes": "error",
|
|
52
|
+
"react/jsx-no-target-blank": "error",
|
|
53
|
+
"react/no-children-prop": "error",
|
|
54
|
+
"react/no-danger-with-children": "error",
|
|
55
|
+
"react/no-deprecated": "error",
|
|
56
|
+
"react/no-direct-mutation-state": "error",
|
|
57
|
+
"react/no-find-dom-node": "error",
|
|
58
|
+
"react/no-is-mounted": "error",
|
|
59
|
+
"react/no-render-return-value": "error",
|
|
60
|
+
"react/no-string-refs": "error",
|
|
61
|
+
"react/require-render-return": "error",
|
|
62
|
+
"jsx-a11y/alt-text": "error",
|
|
63
|
+
"jsx-a11y/anchor-has-content": "error",
|
|
64
|
+
"jsx-a11y/aria-props": "error",
|
|
65
|
+
"jsx-a11y/aria-proptypes": "error",
|
|
66
|
+
"jsx-a11y/aria-role": "error",
|
|
67
|
+
"jsx-a11y/aria-unsupported-elements": "error",
|
|
68
|
+
"jsx-a11y/role-has-required-aria-props": "error",
|
|
69
|
+
"jsx-a11y/role-supports-aria-props": "error",
|
|
70
|
+
"jsx-a11y/tabindex-no-positive": "error",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
// Custom hooks live in .ts files too.
|
|
75
|
+
files: ["**/*.{js,jsx,ts,tsx}"],
|
|
76
|
+
plugins: { "react-hooks": reactHooks },
|
|
77
|
+
rules: {
|
|
78
|
+
"react-hooks/rules-of-hooks": "error",
|
|
79
|
+
"react-hooks/exhaustive-deps": "warn",
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
rules: {
|
|
84
|
+
"@typescript-eslint/consistent-type-imports": [
|
|
85
|
+
"error",
|
|
86
|
+
{ prefer: "type-imports" },
|
|
87
|
+
],
|
|
88
|
+
// A UI hands promises to event handlers and effects that do not await them.
|
|
89
|
+
"@typescript-eslint/no-floating-promises": "off",
|
|
90
|
+
"no-void": "off",
|
|
91
|
+
// Function components, not classes; a component may be used above its declaration.
|
|
92
|
+
"@typescript-eslint/no-invalid-this": "off",
|
|
93
|
+
"@typescript-eslint/no-use-before-define": "off",
|
|
94
|
+
"@typescript-eslint/no-explicit-any": "warn",
|
|
95
|
+
"@typescript-eslint/no-shadow": "warn",
|
|
96
|
+
"@typescript-eslint/no-unused-vars": [
|
|
97
|
+
"warn",
|
|
98
|
+
{
|
|
99
|
+
argsIgnorePattern: "^_",
|
|
100
|
+
varsIgnorePattern: "^_",
|
|
101
|
+
caughtErrorsIgnorePattern: "^_",
|
|
102
|
+
ignoreRestSiblings: true,
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.ReactEslintConfigs = ReactEslintConfigs;
|
|
111
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/dev-configs",
|
|
3
|
-
"version": "0.2.0
|
|
3
|
+
"version": "0.2.1-0",
|
|
4
4
|
"description": "Shareable development configurations for TypeScript projects: ESLint v9 flat config (with unicorn plugin), Prettier formatting, and TypeScript compiler options with critical decorator support (experimentalDecorators, emitDecoratorMetadata, useDefineForClassFields). Single source of truth for consistent code style, type checking, and build settings across monorepo packages. 3-line consumption pattern per config.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build-tools",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
},
|
|
58
58
|
"license": "MIT",
|
|
59
59
|
"engines": {
|
|
60
|
-
"bun": ">=1.
|
|
60
|
+
"bun": ">=1.4"
|
|
61
61
|
},
|
|
62
62
|
"exports": {
|
|
63
63
|
".": {
|