config.js
4.98 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/**
* 架构红线的**单源装配**:composition-root 白名单、规则名单、规则集拼装、语言层全局。
*
* 根 `eslint.config.js` 与 `packages/config/eslint/rules.js` 都从这里 import,不各自再抄一份
* ——历史上两处漂移过(白名单、globals、规则集不一致)。改红线装配只改这一个文件。
*
* 白名单是绝对路径,规则 C 按 `绝对路径 === r || 绝对路径.endsWith(r)` 匹配。新增豁免点
* 先改任务文档(arch-root-solution.md 决定 1)再改这里。
*/
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const here = path.dirname(fileURLToPath(import.meta.url))
// tools/eslint-rules/ 上两级即仓库根。
const repoRoot = path.resolve(here, '..', '..')
/**
* 规则 C 豁免点(composition root):这些文件允许顶层建连接。
* 绝对路径,精确匹配,不放宽到整个 app 目录。
*/
export const COMPOSITION_ROOTS = [
// voko-server 的 runtime 工厂负责读取 env、创建连接并统一管理资源生命周期。
path.join(repoRoot, 'apps/voko-server/src/assembly/runtime.js'),
// worker 进程入口与数据库 init / migrate / status / baseline 命令各自是独立 composition root。
path.join(repoRoot, 'apps/voko-server/src/voko-worker-main.js'),
path.join(repoRoot, 'apps/voko-server/src/db/init-current-schema.js'),
path.join(repoRoot, 'apps/voko-server/src/db/baseline-existing-database.js'),
path.join(repoRoot, 'apps/voko-server/src/db/migrate-database.js'),
path.join(repoRoot, 'apps/voko-server/src/db/migration-status.js'),
]
/**
* Vite 配置文件白名单:构建期读 `process.env`(NODE_ENV / 代理目标等)是 Vite 配置的合理需求,
* 不是散读 env。用路径后缀匹配覆盖 `packages/config/vite/base.js` 与各 app 的 `vite.config.js`。
* 它们不会建 DB 连接,整文件豁免连接检查也无副作用。
*/
export const VITE_CONFIG_WHITELIST = [
'packages/config/vite/base.js',
'vite.config.js',
]
/**
* tools/scripts/ 下的脚本都是独立可执行入口(自带 shebang、直接 `node tools/scripts/x.js` 跑),
* 每个进程各自是自己的 composition root:读 env、顶层建连接都是合理的。整目录一条豁免,
* 不逐个文件散白。以 `/` 结尾表示目录前缀匹配(见 no-conn-outside-root.js 的匹配逻辑)。
*/
export const TOOLS_SCRIPTS_ROOTS = ['tools/scripts/', '/tools/']
/** 规则 C 的完整连接创建豁免集。 */
export const CONN_WHITELIST = [
...COMPOSITION_ROOTS,
...VITE_CONFIG_WHITELIST,
...TOOLS_SCRIPTS_ROOTS,
]
/** 架构红线规则名(供测试/下游静态断言「红线确实进了装配」)。 */
export const ENFORCED_RULE_NAMES = Object.freeze([
'drama/no-deep-import',
'drama/no-subdomain-deep-import',
'drama/no-conn-outside-root',
'drama/no-app-import',
'drama/no-drama-rule-disable',
])
/**
* 四条架构红线 + 禁 disable 绕行 + 通用 JS 规则,一份定义供全部消费方复用。
* @param {string[]} [connWhitelist] 允许顶层建连接的 composition root 文件集。
* @returns {import('eslint').Linter.RulesRecord}
*/
export function buildArchRules(connWhitelist = CONN_WHITELIST) {
return {
'drama/no-deep-import': 'error',
'drama/no-subdomain-deep-import': 'error',
'drama/no-conn-outside-root': ['error', { connExemptFiles: connWhitelist }],
'drama/no-app-import': 'error',
'drama/no-drama-rule-disable': 'error',
'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
'no-undef': 'error',
}
}
/** Node 24 运行时全局(ESM/CJS 通用),单源,避免根配置与 config 预设各写一份漂移。 */
export const BASE_GLOBALS = {
process: 'readonly',
console: 'readonly',
URL: 'readonly',
URLSearchParams: 'readonly',
Buffer: 'readonly',
fetch: 'readonly',
setTimeout: 'readonly',
clearTimeout: 'readonly',
setInterval: 'readonly',
clearInterval: 'readonly',
structuredClone: 'readonly',
// Web 平台 API(Node 24 与浏览器均为全局;api-sdk 走 fetch/流式解析需要)。
Response: 'readonly',
Headers: 'readonly',
ReadableStream: 'readonly',
TextDecoder: 'readonly',
TextEncoder: 'readonly',
AbortController: 'readonly',
AbortSignal: 'readonly',
DOMException: 'readonly',
}
/** 浏览器运行时全局(Vue 组件与前端 app 的 .js 用),单源。 */
export const BROWSER_GLOBALS = {
window: 'readonly',
document: 'readonly',
navigator: 'readonly',
localStorage: 'readonly',
sessionStorage: 'readonly',
HTMLElement: 'readonly',
Image: 'readonly',
Audio: 'readonly',
MouseEvent: 'readonly',
KeyboardEvent: 'readonly',
CustomEvent: 'readonly',
performance: 'readonly',
requestAnimationFrame: 'readonly',
cancelAnimationFrame: 'readonly',
}
/** CommonJS 脚本全局(`.cjs`:迁移、table 定义等)。 */
export const COMMONJS_GLOBALS = {
...BASE_GLOBALS,
require: 'readonly',
module: 'readonly',
exports: 'readonly',
__dirname: 'readonly',
__filename: 'readonly',
}