@tsfpp/eslint-config 1.0.3 → 2.0.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/README.md +2 -0
- package/dist/base.d.ts +1 -1
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +21 -1
- package/dist/base.js.map +1 -1
- package/dist/layered.d.ts +35 -0
- package/dist/layered.d.ts.map +1 -0
- package/dist/layered.js +115 -0
- package/dist/layered.js.map +1 -0
- package/dist/plugin-compat.d.ts.map +1 -1
- package/dist/plugin-compat.js +3 -2
- package/dist/plugin-compat.js.map +1 -1
- package/package.json +30 -21
package/README.md
CHANGED
|
@@ -130,6 +130,8 @@ export default [
|
|
|
130
130
|
| `no-restricted-syntax` → `TSModuleDeclaration[kind='namespace']` | 1.9 | MUST |
|
|
131
131
|
| `no-restricted-syntax` → `BinaryExpression[operator="instanceof"]` | 1.9 | MUST |
|
|
132
132
|
| `no-restricted-syntax` → `NewExpression` | 1.9 | MUST |
|
|
133
|
+
| `no-restricted-globals` → `isNaN`, `isFinite`, `parseInt`, `parseFloat` | 1.13 | MUST |
|
|
134
|
+
| `no-restricted-syntax` → `Date.now()`, `Math.random()`, `process.env` | 4.6 | MUST |
|
|
133
135
|
| `functional/no-classes` | 1.9 | MUST |
|
|
134
136
|
| `functional/no-this-expressions` | 1.9 | MUST |
|
|
135
137
|
| `functional/no-let` | 2.1 | MUST |
|
package/dist/base.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @tsfpp/eslint-config — base
|
|
3
3
|
*
|
|
4
4
|
* Shared ESLint flat configuration for TSF++ projects (pure TypeScript targets).
|
|
5
|
-
* Enforces Rules 1.2–1.9, 2.1–2.3, 3.1–3.2, 3.4, 4.1, 4.2, 4.5, 6.2, 6.4, 11.2
|
|
5
|
+
* Enforces Rules 1.2–1.9, 1.13, 2.1–2.3, 3.1–3.2, 3.4, 4.1, 4.2, 4.5, 4.6, 6.2, 6.4, 11.2
|
|
6
6
|
* from CODING_STANDARD.md via @typescript-eslint and eslint-plugin-functional.
|
|
7
7
|
*
|
|
8
8
|
* Usage (base only):
|
package/dist/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAO,QAAQ,CAAA;AAMrC,QAAA,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAO,QAAQ,CAAA;AAMrC,QAAA,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EA+M1B,CAAA;AAED,eAAe,MAAM,CAAA"}
|
package/dist/base.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @tsfpp/eslint-config — base
|
|
3
3
|
*
|
|
4
4
|
* Shared ESLint flat configuration for TSF++ projects (pure TypeScript targets).
|
|
5
|
-
* Enforces Rules 1.2–1.9, 2.1–2.3, 3.1–3.2, 3.4, 4.1, 4.2, 4.5, 6.2, 6.4, 11.2
|
|
5
|
+
* Enforces Rules 1.2–1.9, 1.13, 2.1–2.3, 3.1–3.2, 3.4, 4.1, 4.2, 4.5, 4.6, 6.2, 6.4, 11.2
|
|
6
6
|
* from CODING_STANDARD.md via @typescript-eslint and eslint-plugin-functional.
|
|
7
7
|
*
|
|
8
8
|
* Usage (base only):
|
|
@@ -81,6 +81,26 @@ const config = [
|
|
|
81
81
|
selector: 'NewExpression',
|
|
82
82
|
message: 'TSF++ Rule 1.9: new is forbidden outside adapter boundaries. Add DEVIATION(1.9) and an eslint-disable comment.',
|
|
83
83
|
},
|
|
84
|
+
// Rule 4.6 — ambient nondeterminism is an effect (Appendix B); `new Date()` is already caught by Rule 1.9 above
|
|
85
|
+
{
|
|
86
|
+
selector: "CallExpression[callee.object.name='Date'][callee.property.name='now']",
|
|
87
|
+
message: 'TSF++ Rule 4.6: Date.now() is an effect; inject `now: () => Date` via Deps.',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
selector: "CallExpression[callee.object.name='Math'][callee.property.name='random']",
|
|
91
|
+
message: 'TSF++ Rule 4.6: Math.random() is an effect; inject a seeded generator via Deps.',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
selector: "MemberExpression[object.object.name='process'][object.property.name='env']",
|
|
95
|
+
message: 'TSF++ Rule 4.6: process.env is ambient input; load config at the boundary and inject it.',
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
// Rule 1.13 — numeric hazards: coercing globals (Appendix B)
|
|
99
|
+
'no-restricted-globals': ['error',
|
|
100
|
+
{ name: 'isNaN', message: 'TSF++ Rule 1.13: use Number.isNaN — the global coerces its argument.' },
|
|
101
|
+
{ name: 'isFinite', message: 'TSF++ Rule 1.13: use Number.isFinite — the global coerces its argument.' },
|
|
102
|
+
{ name: 'parseInt', message: 'TSF++ Rule 1.13: coercion parsing is forbidden in the core; parse at the boundary via a smart constructor.' },
|
|
103
|
+
{ name: 'parseFloat', message: 'TSF++ Rule 1.13: coercion parsing is forbidden in the core; parse at the boundary via a smart constructor.' },
|
|
84
104
|
],
|
|
85
105
|
// ── Immutability & functional style ──────────────────────────────────────
|
|
86
106
|
// Rule 2.1 — no `let`
|
package/dist/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../base.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @tsfpp/eslint-config/layered
|
|
3
|
+
*
|
|
4
|
+
* TSF++ ESLint profile enforcing Rule 11.5 (layer boundaries — functional core,
|
|
5
|
+
* imperative shell) and Rule 11.6 (import purity).
|
|
6
|
+
*
|
|
7
|
+
* Rule references in this file are to CODING_STANDARD.md.
|
|
8
|
+
*
|
|
9
|
+
* Why a separate profile: the base config constrains how a *file* is written.
|
|
10
|
+
* These rules constrain how files may *depend on each other*, which is what
|
|
11
|
+
* actually keeps the axioms true at program scale — a single outward import
|
|
12
|
+
* makes every function in a module effectful no matter how each was written.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* // eslint.config.js
|
|
16
|
+
* import tsfppLayered from '@tsfpp/eslint-config/layered'
|
|
17
|
+
* export default tsfppLayered
|
|
18
|
+
*
|
|
19
|
+
* The path globs below assume the conventional layout:
|
|
20
|
+
*
|
|
21
|
+
* src/core/ pure domain — types, ADTs, decisions
|
|
22
|
+
* src/use-case/ orchestration + ports
|
|
23
|
+
* src/boundary/ parsing and error mapping
|
|
24
|
+
* src/adapters/ effects: db, http clients, clock, entropy
|
|
25
|
+
* src/handlers/ transport entry points
|
|
26
|
+
* src/main.ts composition root
|
|
27
|
+
*
|
|
28
|
+
* Layer *names* are conventional; the inward-only *direction* is normative
|
|
29
|
+
* (Rule 11.5). Projects using a different layout should copy this file and
|
|
30
|
+
* adjust the globs — the shape of the restriction is the part worth keeping.
|
|
31
|
+
*/
|
|
32
|
+
import type { Linter } from 'eslint';
|
|
33
|
+
declare const config: Linter.Config[];
|
|
34
|
+
export default config;
|
|
35
|
+
//# sourceMappingURL=layered.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layered.d.ts","sourceRoot":"","sources":["../layered.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AA6BpC,QAAA,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EA4D1B,CAAA;AAED,eAAe,MAAM,CAAA"}
|
package/dist/layered.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @tsfpp/eslint-config/layered
|
|
3
|
+
*
|
|
4
|
+
* TSF++ ESLint profile enforcing Rule 11.5 (layer boundaries — functional core,
|
|
5
|
+
* imperative shell) and Rule 11.6 (import purity).
|
|
6
|
+
*
|
|
7
|
+
* Rule references in this file are to CODING_STANDARD.md.
|
|
8
|
+
*
|
|
9
|
+
* Why a separate profile: the base config constrains how a *file* is written.
|
|
10
|
+
* These rules constrain how files may *depend on each other*, which is what
|
|
11
|
+
* actually keeps the axioms true at program scale — a single outward import
|
|
12
|
+
* makes every function in a module effectful no matter how each was written.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* // eslint.config.js
|
|
16
|
+
* import tsfppLayered from '@tsfpp/eslint-config/layered'
|
|
17
|
+
* export default tsfppLayered
|
|
18
|
+
*
|
|
19
|
+
* The path globs below assume the conventional layout:
|
|
20
|
+
*
|
|
21
|
+
* src/core/ pure domain — types, ADTs, decisions
|
|
22
|
+
* src/use-case/ orchestration + ports
|
|
23
|
+
* src/boundary/ parsing and error mapping
|
|
24
|
+
* src/adapters/ effects: db, http clients, clock, entropy
|
|
25
|
+
* src/handlers/ transport entry points
|
|
26
|
+
* src/main.ts composition root
|
|
27
|
+
*
|
|
28
|
+
* Layer *names* are conventional; the inward-only *direction* is normative
|
|
29
|
+
* (Rule 11.5). Projects using a different layout should copy this file and
|
|
30
|
+
* adjust the globs — the shape of the restriction is the part worth keeping.
|
|
31
|
+
*/
|
|
32
|
+
/** Modules a pure core may never reach for. */
|
|
33
|
+
const OUTWARD_FROM_CORE = [
|
|
34
|
+
'**/adapters/**',
|
|
35
|
+
'**/infra/**',
|
|
36
|
+
'**/handlers/**',
|
|
37
|
+
'**/boundary/**',
|
|
38
|
+
'**/use-case/**',
|
|
39
|
+
'node:*',
|
|
40
|
+
'express',
|
|
41
|
+
'fastify',
|
|
42
|
+
'koa',
|
|
43
|
+
'next/*',
|
|
44
|
+
'react',
|
|
45
|
+
'react-dom',
|
|
46
|
+
];
|
|
47
|
+
/** Modules a use case may never reach for (it may use the core). */
|
|
48
|
+
const OUTWARD_FROM_USE_CASE = [
|
|
49
|
+
'**/adapters/**',
|
|
50
|
+
'**/infra/**',
|
|
51
|
+
'**/handlers/**',
|
|
52
|
+
'node:*',
|
|
53
|
+
'express',
|
|
54
|
+
'fastify',
|
|
55
|
+
'koa',
|
|
56
|
+
];
|
|
57
|
+
const config = [
|
|
58
|
+
// ── Rule 11.5 — the core is pure: nothing peripheral, nothing transport-shaped
|
|
59
|
+
{
|
|
60
|
+
files: ['**/core/**/*.ts', '**/domain/**/*.ts'],
|
|
61
|
+
rules: {
|
|
62
|
+
'no-restricted-imports': ['error', {
|
|
63
|
+
patterns: [{
|
|
64
|
+
group: OUTWARD_FROM_CORE,
|
|
65
|
+
message: 'TSF++ Rule 11.5: the core must not import adapters, transports, or node builtins. ' +
|
|
66
|
+
'Define a port (a function type) in the core and inject an implementation at the composition root (Rule 6.5).',
|
|
67
|
+
}],
|
|
68
|
+
}],
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
// ── Rule 11.5 — use cases orchestrate the core; they do not perform effects
|
|
72
|
+
{
|
|
73
|
+
files: ['**/use-case/**/*.ts', '**/use-cases/**/*.ts', '**/application/**/*.ts'],
|
|
74
|
+
rules: {
|
|
75
|
+
'no-restricted-imports': ['error', {
|
|
76
|
+
patterns: [{
|
|
77
|
+
group: OUTWARD_FROM_USE_CASE,
|
|
78
|
+
message: 'TSF++ Rule 11.5: a use case may depend on the core and on ports, never on a concrete adapter. ' +
|
|
79
|
+
'Accept the port through Deps (Rule 6.5).',
|
|
80
|
+
}],
|
|
81
|
+
}],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
// ── Rule 11.6 — import purity: a module may only define bindings
|
|
85
|
+
//
|
|
86
|
+
// Top-level ambient reads are worse than the in-function reads Rule 4.6
|
|
87
|
+
// forbids: they run before any caller exists, in module-graph order, and can
|
|
88
|
+
// be neither injected nor stubbed nor deferred.
|
|
89
|
+
{
|
|
90
|
+
files: ['**/*.ts'],
|
|
91
|
+
ignores: ['**/main.ts', '**/index.ts', '**/*.config.ts', '**/*.test.ts'],
|
|
92
|
+
rules: {
|
|
93
|
+
'no-restricted-syntax': ['error',
|
|
94
|
+
{
|
|
95
|
+
selector: ":matches(Program > VariableDeclaration, Program > ExportNamedDeclaration > VariableDeclaration) > VariableDeclarator > NewExpression[callee.name='Date']",
|
|
96
|
+
message: 'TSF++ Rule 11.6: reading the clock at import time. Expose a function and inject the clock (Rule 4.6).',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
selector: ":matches(Program > VariableDeclaration, Program > ExportNamedDeclaration > VariableDeclaration) > VariableDeclarator > MemberExpression[object.object.name='process'][object.property.name='env']",
|
|
100
|
+
message: 'TSF++ Rule 11.6: reading process.env at import time. Load config at the boundary and inject it.',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
selector: ":matches(Program > VariableDeclaration, Program > ExportNamedDeclaration > VariableDeclaration) > VariableDeclarator > AwaitExpression",
|
|
104
|
+
message: 'TSF++ Rule 11.6: top-level await performs I/O at import time and blocks the module graph.',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
selector: 'Program > ExpressionStatement > CallExpression',
|
|
108
|
+
message: 'TSF++ Rule 11.6: a bare call at module scope is a side effect at import time. Importing a module must only define bindings.',
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
export default config;
|
|
115
|
+
//# sourceMappingURL=layered.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layered.js","sourceRoot":"","sources":["../layered.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,+CAA+C;AAC/C,MAAM,iBAAiB,GAAG;IACxB,gBAAgB;IAChB,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,QAAQ;IACR,SAAS;IACT,SAAS;IACT,KAAK;IACL,QAAQ;IACR,OAAO;IACP,WAAW;CACZ,CAAA;AAED,oEAAoE;AACpE,MAAM,qBAAqB,GAAG;IAC5B,gBAAgB;IAChB,aAAa;IACb,gBAAgB;IAChB,QAAQ;IACR,SAAS;IACT,SAAS;IACT,KAAK;CACN,CAAA;AAED,MAAM,MAAM,GAAoB;IAC9B,gFAAgF;IAChF;QACE,KAAK,EAAE,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;QAC/C,KAAK,EAAE;YACL,uBAAuB,EAAE,CAAC,OAAO,EAAE;oBACjC,QAAQ,EAAE,CAAC;4BACT,KAAK,EAAE,iBAAiB;4BACxB,OAAO,EACL,oFAAoF;gCACpF,8GAA8G;yBACjH,CAAC;iBACH,CAAC;SACH;KACF;IAED,6EAA6E;IAC7E;QACE,KAAK,EAAE,CAAC,qBAAqB,EAAE,sBAAsB,EAAE,wBAAwB,CAAC;QAChF,KAAK,EAAE;YACL,uBAAuB,EAAE,CAAC,OAAO,EAAE;oBACjC,QAAQ,EAAE,CAAC;4BACT,KAAK,EAAE,qBAAqB;4BAC5B,OAAO,EACL,gGAAgG;gCAChG,0CAA0C;yBAC7C,CAAC;iBACH,CAAC;SACH;KACF;IAED,kEAAkE;IAClE,EAAE;IACF,wEAAwE;IACxE,6EAA6E;IAC7E,gDAAgD;IAChD;QACE,KAAK,EAAE,CAAC,SAAS,CAAC;QAClB,OAAO,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,CAAC;QACxE,KAAK,EAAE;YACL,sBAAsB,EAAE,CAAC,OAAO;gBAC9B;oBACE,QAAQ,EAAE,0JAA0J;oBACpK,OAAO,EAAE,uGAAuG;iBACjH;gBACD;oBACE,QAAQ,EAAE,mMAAmM;oBAC7M,OAAO,EAAE,iGAAiG;iBAC3G;gBACD;oBACE,QAAQ,EAAE,wIAAwI;oBAClJ,OAAO,EAAE,2FAA2F;iBACrG;gBACD;oBACE,QAAQ,EAAE,gDAAgD;oBAC1D,OAAO,EAAE,6HAA6H;iBACvI;aACF;SACF;KACF;CACF,CAAA;AAED,eAAe,MAAM,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-compat.d.ts","sourceRoot":"","sources":["../plugin-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"plugin-compat.d.ts","sourceRoot":"","sources":["../plugin-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,QAAQ,OAAO,KAAG,MAAM,CAAC,MAE7B,CAAA"}
|
package/dist/plugin-compat.js
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* Use exclusively at plugin registration sites. Never use to silence unrelated
|
|
26
26
|
* type errors.
|
|
27
27
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
export const coercePlugin = (plugin) =>
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- DEVIATION(1.6): see module JSDoc above
|
|
30
|
+
plugin;
|
|
30
31
|
//# sourceMappingURL=plugin-compat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-compat.js","sourceRoot":"","sources":["../plugin-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;;;;GAMG;AACH,
|
|
1
|
+
{"version":3,"file":"plugin-compat.js","sourceRoot":"","sources":["../plugin-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAe,EAAiB,EAAE;AAC7D,mHAAmH;AACnH,MAAuB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsfpp/eslint-config",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Shared ESLint flat configuration for TSF++ projects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -19,20 +19,21 @@
|
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"type": "module",
|
|
21
21
|
"exports": {
|
|
22
|
-
".":
|
|
23
|
-
"./react":
|
|
24
|
-
"./api":
|
|
25
|
-
"./package.json": "./package.json"
|
|
22
|
+
".": "./dist/base.js",
|
|
23
|
+
"./react": "./dist/react.js",
|
|
24
|
+
"./api": "./dist/api.js",
|
|
25
|
+
"./package.json": "./package.json",
|
|
26
|
+
"./layered": "./dist/layered.js"
|
|
26
27
|
},
|
|
27
28
|
"files": [
|
|
28
29
|
"dist/",
|
|
29
30
|
"README.md"
|
|
30
31
|
],
|
|
31
32
|
"scripts": {
|
|
32
|
-
"build":
|
|
33
|
+
"build": "tsc --project tsconfig.build.json",
|
|
33
34
|
"prepublishOnly": "pnpm run build",
|
|
34
|
-
"lint":
|
|
35
|
-
"test":
|
|
35
|
+
"lint": "eslint .",
|
|
36
|
+
"test": "node --input-type=module --eval \"import './dist/base.js'\""
|
|
36
37
|
},
|
|
37
38
|
"engines": {
|
|
38
39
|
"node": ">=18.18.0"
|
|
@@ -49,20 +50,28 @@
|
|
|
49
50
|
"typescript": ">=5.3.0"
|
|
50
51
|
},
|
|
51
52
|
"peerDependenciesMeta": {
|
|
52
|
-
"@tanstack/eslint-plugin-query": {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"eslint-plugin-
|
|
53
|
+
"@tanstack/eslint-plugin-query": {
|
|
54
|
+
"optional": true
|
|
55
|
+
},
|
|
56
|
+
"eslint-plugin-jsx-a11y": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"eslint-plugin-react": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"eslint-plugin-react-hooks": {
|
|
63
|
+
"optional": true
|
|
64
|
+
}
|
|
56
65
|
},
|
|
57
66
|
"devDependencies": {
|
|
58
|
-
"@tanstack/eslint-plugin-query":
|
|
67
|
+
"@tanstack/eslint-plugin-query": "^5.100.10",
|
|
59
68
|
"@typescript-eslint/eslint-plugin": "^8.59.3",
|
|
60
|
-
"@typescript-eslint/parser":
|
|
61
|
-
"eslint":
|
|
62
|
-
"eslint-plugin-functional":
|
|
63
|
-
"eslint-plugin-jsx-a11y":
|
|
64
|
-
"eslint-plugin-react":
|
|
65
|
-
"eslint-plugin-react-hooks":
|
|
66
|
-
"typescript":
|
|
69
|
+
"@typescript-eslint/parser": "^8.59.3",
|
|
70
|
+
"eslint": "^9.39.4",
|
|
71
|
+
"eslint-plugin-functional": "^9.0.0",
|
|
72
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
73
|
+
"eslint-plugin-react": "^7.37.5",
|
|
74
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
75
|
+
"typescript": "^5.9.3"
|
|
67
76
|
}
|
|
68
|
-
}
|
|
77
|
+
}
|