-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheslint.config.mts
More file actions
101 lines (94 loc) · 4.19 KB
/
Copy patheslint.config.mts
File metadata and controls
101 lines (94 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { next } from "@dylanmerigaud/config/eslint/next";
import { customLocalRules } from "./config/eslint-rules/index";
/**
* ESLint. The shared preset (@dylanmerigaud/config, `next`) owns the whole base:
* cast/null hygiene, typed env over process.env, the logger over console, no
* barrels, type over interface, React/hooks/a11y/Next, and the generic custom
* rules (no-emdash-in-text, no-console-use-logger, no-index-files,
* prefer-use-event-callback). This file adds only what is specific to ledgerloop,
* under the `custom-local` plugin namespace:
* • enforce-api-routes: hardcoded `/api/...` paths must come from API_ROUTES.
* • the Mastra require-await exemption (its step/tool `execute` and workflow
* callbacks are async by API contract even without an await).
* • the eval/sanity entrypoint relaxations the shared scripts block doesn't cover.
*
* ledgerloop adopts the full opinionated @dylanmerigaud/config layer (perfectionist
* import/member sorting, eslint-plugin-unicorn, the stricter @eslint-react rules):
* the code satisfies those rules rather than opting out. The only disabling below
* is the handful of framework truths (Mastra, rule-authoring code, eval/sanity
* entrypoints) plus any targeted per-line disable that carries its own reason.
*/
export default [
...next({ tsconfigRootDir: import.meta.dirname }),
// enforce-api-routes on repo-wide; route handlers and the API_ROUTES definition
// itself own the raw `/api/...` strings, so they are exempted just below.
{
files: ["**/*.{ts,tsx}"],
plugins: { "custom-local": customLocalRules },
rules: { "custom-local/enforce-api-routes": "error" },
},
{
files: ["app/api/**/*.ts", "lib/api-routes.ts"],
rules: { "custom-local/enforce-api-routes": "off" },
},
// Mastra workflows/agents/tools: `execute` and the workflow `.map()`/`.branch()`
// callbacks are async by Mastra's API contract even when a given body has no
// await, that is the framework shape, not a mistake. Scoped here, not global.
{
files: ["src/mastra/**/*.ts"],
rules: { "@typescript-eslint/require-await": "off" },
},
// Standalone tsx entrypoints beyond the shared scripts/db-seed block: the sanity
// check and the eval harness read process.env directly, print to the terminal,
// and don't touch API paths. (The shared preset already relaxes scripts/** and
// db/seed.ts; this extends the same treatment to eval/** and sanity.)
{
files: ["src/mastra/sanity.ts", "eval/**/*.ts"],
rules: {
"no-restricted-syntax": "off",
"no-console": "off",
"custom/no-console-use-logger": "off",
"custom-local/enforce-api-routes": "off",
},
},
// The shared scripts/** + db/seed.ts relaxation doesn't turn off the local
// enforce-api-routes rule (it lives in the shared preset which can't know about
// it), so do that here for those same paths.
{
files: ["scripts/**/*.ts", "db/seed.ts"],
rules: { "custom-local/enforce-api-routes": "off" },
},
// ESLint rule-authoring code: the barrel is the plugin entrypoint (loaded by
// jiti), and rule bodies compare against TSESTree's string AST types where the
// enum-comparison check doesn't apply.
{
files: ["config/eslint-rules/**/*.ts"],
rules: {
"@typescript-eslint/no-unsafe-enum-comparison": "off",
"custom/no-index-files": "off",
},
},
// src/mastra/index.ts is Mastra's required framework entry point (the shared
// preset bans barrels; the old local no-index-files rule whitelisted this exact
// path, so keep exempting it to preserve prior behavior).
{
files: ["src/mastra/index.ts"],
rules: { "custom/no-index-files": "off" },
},
// Playwright e2e: the bodies passed to `page.evaluate(...)` are serialized and
// run in the BROWSER, where `document`, `window`, and `CSS` exist. Declaring
// them as globals here lets unicorn/isolated-functions see they're defined in
// the evaluate context (it otherwise reports them as undefined captures).
{
files: ["e2e/**/*.ts"],
languageOptions: {
globals: {
document: "readonly",
window: "readonly",
CSS: "readonly",
navigator: "readonly",
getComputedStyle: "readonly",
},
},
},
];