@jayyuen66/dsh-plugin-shared 0.2.1 → 0.2.2
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/config/oxlint.base.js +1 -1
- package/dist/types/config/oxlint.base.d.ts +22 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,7 +92,7 @@ End users do not install or enable it separately: any consumer package pulls it
|
|
|
92
92
|
- **A host package under `dependencies` disables the consumer's host.** Profiles install with `nodeLinker: hoisted` and `autoInstallPeers: false`, so a listed host package is materialized as a real directory next to the copy the host process already loaded. `@deepseek-ai/dsh-tools` keys its tool-runtime scheduler with a plain `Symbol` (not `Symbol.for`), so symbol identity is per module instance: the host reads the scheduler from the duplicate and gets `undefined`, and every native tool call throws. Build, typecheck and tests pass up to that point; the invariant has to be stated in the manifest.
|
|
93
93
|
- **`@deepseek-ai/dsh-output-retention` is the one required peer.** It is a value import (`truncateEnd`), provided by the host at runtime, and marked `"optional": false` in `peerDependenciesMeta` rather than left implicit — a peer left out of that table is a hard requirement for npm 7+.
|
|
94
94
|
- **The remaining peers are optional.** Except for the bare `@deepseek-ai/dsh` peer, which only declares the host line, they carry type declarations only. `devDependencies` holds the exact development line, including `@deepseek-ai/dsh-llm` and `@deepseek-ai/dsh-util-values`, whose types the local PTC declarations name, and `@deepseek-ai/dsh-tool-executor-ptc`, whose types only the parity check reads. Profiles never install peers, so no duplicate appears.
|
|
95
|
-
- **Version requirements separate the install gate from the build baseline.** Every `@deepseek-ai/dsh-*` peer uses the same `^0.2.1-rc.3` range as `engines.dsh`, so a
|
|
95
|
+
- **Version requirements separate the install gate from the build baseline.** Every `@deepseek-ai/dsh-*` peer uses the same `^0.2.1-rc.3` range as `engines.dsh`, and that range deliberately names one host line. npm resolves each peer on its own, so a peer listing both lines (`^0.2.1-rc.3||^0.2.2-alpha.2`) lets the required `@deepseek-ai/dsh-output-retention` come from the alpha line while cordis comes from the rc line, and a clean install stops at `ERESOLVE`. The supported window is not narrowed by this: the host compares `engines.dsh` with `includePrerelease: true`, under which `^0.2.1-rc.3` is true for `0.2.1-rc.3`, `0.2.1-rc.4`, `0.2.1-rc.5` and `0.2.2-alpha.2`. `devDependencies` pin the exact line this repository compiles and tests against (`0.2.2-alpha.2`) and must stay uniform: one `dsh-session` version per tree keeps the nominal types recognizable. `@deepseek-ai/cordis` stays exact in `devDependencies` (`4.0.6-alpha.1`) and its peer range `^4.0.5||^4.0.6-alpha.1` covers both host lines, because one package cannot mix lines the way the host family does; union ranges carry no spaces around `||`, so one spec stays one argument wherever a spec list is split on blanks. `test/publish-manifest.test.ts` checks each of these separately.
|
|
96
96
|
- Known upstream limitation: `@deepseek-ai/dsh-llm`'s declarations import `@deepseek-ai/dsh-attachment`, which that package does not declare. It is reached through `dsh-session`, so a consumer running with `skipLibCheck: false` sees `TS2307` from that package, not from this one. The published `./lib/tool-events` declaration also names `@deepseek-ai/dsh-util-values`, which is reached through `dsh-session` / `dsh-tools`; a consumer running with `skipLibCheck: false` must have that package resolvable as well.
|
|
97
97
|
|
|
98
98
|
### Shared version floor
|
package/README.zh-CN.md
CHANGED
|
@@ -92,7 +92,7 @@ import { isRecord, fieldOf } from "@jayyuen66/dsh-plugin-shared/lib/record";
|
|
|
92
92
|
- **宿主包写进 `dependencies` 会让消费方的宿主无法工作。** profile 用 `nodeLinker: hoisted` 与 `autoInstallPeers: false` 安装,于是列在 `dependencies` 里的宿主包会被安装成真实目录,与宿主进程已加载的那份并存。`@deepseek-ai/dsh-tools` 的工具运行期调度键是普通 `Symbol`(不是 `Symbol.for`),符号身份按模块实例计算:宿主从副本上读那个键得到 `undefined`,于是每一次原生工具调用都抛错。构建、类型检查与测试在此之前全部通过;这条不变式只能写在 manifest 上。
|
|
93
93
|
- **`@deepseek-ai/dsh-output-retention` 是唯一必需 peer。** 它是值导入(`truncateEnd`),运行期由宿主提供;在 `peerDependenciesMeta` 里明写成 `"optional": false`,不靠"没写就等于必需",因为没写进那张表对 npm 7+ 就是硬要求。
|
|
94
94
|
- **其余 peer 都是 optional。** 除裸 `@deepseek-ai/dsh`(只声明宿主版本线)外,它们只承载类型声明。`devDependencies` 保存精确的开发线,其中包括本包 PTC 声明所引用的 `@deepseek-ai/dsh-llm` 与 `@deepseek-ai/dsh-util-values`,以及只有对照断言会读其类型的 `@deepseek-ai/dsh-tool-executor-ptc`。profile 不装 peer,所以不会产生副本。
|
|
95
|
-
- **版本要求把装载门与构建基线分开。** 每条 `@deepseek-ai/dsh-*` peer 与 `engines.dsh` 使用同一条 `^0.2.1-rc.3`
|
|
95
|
+
- **版本要求把装载门与构建基线分开。** 每条 `@deepseek-ai/dsh-*` peer 与 `engines.dsh` 使用同一条 `^0.2.1-rc.3` 范围,而这条范围刻意只写一条宿主线:npm 对每条 peer 独立解析,把两条线并列(`^0.2.1-rc.3||^0.2.2-alpha.2`)会让必需 peer `@deepseek-ai/dsh-output-retention` 取到 alpha 线、cordis 取到 rc 线,干净目录安装止步于 `ERESOLVE`。支持窗口并没有因此变窄——宿主比较 `engines.dsh` 时带 `includePrerelease: true`,在该语义下 `^0.2.1-rc.3` 对 `0.2.1-rc.3`、`0.2.1-rc.4`、`0.2.1-rc.5`、`0.2.2-alpha.2` 全为真。`devDependencies` 精确锁定本仓编译与测试用的那一线(`0.2.2-alpha.2`),且必须统一:一棵树里只有一份 `dsh-session`,nominal 类型才互相认得。`@deepseek-ai/cordis` 在 `devDependencies` 里精确锁定 `4.0.6-alpha.1`,peer 范围 `^4.0.5||^4.0.6-alpha.1` 同时覆盖 rc 线与 alpha 线——单独一枚包不存在宿主家族那种混线问题。含多条比较符的范围在 `||` 两侧不带空格:一枚说明符因此是一个不含空白的 token,在任何按空白切分参数表的安装命令里都不会被拆开(CI 的类型面 peer 安装按行读取)。`test/publish-manifest.test.ts` 分别检查这三件事。
|
|
96
96
|
- 已知上游限制:`@deepseek-ai/dsh-llm` 的声明文件引用了它自己没声明的 `@deepseek-ai/dsh-attachment`。它经 `dsh-session` 传递进来,所以开 `skipLibCheck: false` 的消费方会看到来自那个包的 `TS2307`,不是来自本包。发布出去的 `./lib/tool-events` 声明还引用了 `@deepseek-ai/dsh-util-values`,它经 `dsh-session` / `dsh-tools` 传递进来;开 `skipLibCheck: false` 的消费方同样必须能解析到这个包。
|
|
97
97
|
|
|
98
98
|
### shared 的版本下限
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire as e}from"node:module";import{defineConfig as t}from"oxlint";const n=`同 no-unsafe-member-access`,r={"vitest/*":{kind:`仅限特定文件`,measured:7,note:`用例结构类判断在非用例文件上无从计算`},"vitest/no-hooks":{kind:`上游不推荐`,measured:181,note:`禁用 hook 本身;本仓按官方 vitest 用法大量使用 before*/after*`},"vitest/no-conditional-in-test":{kind:`仅限特定文件`,measured:523,note:`平台/宿主版本分支是刻意的(macOS 与 Linux 的家目录形态、0.1.7 与 0.1.6 的 API 差异)`},"vitest/max-expects":{kind:`上游不推荐`,measured:163,note:`给单条用例的断言条数设上限属风格偏好,不指向缺陷`},"vitest/prefer-expect-assertions":{kind:`上游不推荐`,measured:2902,note:`要求每个 async 用例手写 expect.assertions(n),是与断言强度无关的计数要求`},"vitest/require-test-timeout":{kind:`上游不推荐`,measured:2892,note:`要求每条用例显式 timeout;本仓用泵式假时钟,超时由 13 份 vitest 配置统一给出`},"vitest/prefer-importing-vitest-globals":{kind:`实测有害`,measured:0,note:`autofix 方向是删掉显式 import 改回裸全局;13 份 vitest 配置都没开 globals:true,应用后立即出现 3605 处 TS2593、测试全部失效`},"vitest/no-importing-vitest-globals":{kind:`实测有害`,measured:133,note:`与上一条同族、方向相反,两条同时开启就是把两种写法都判违规`},"vitest/prefer-import-in-mock":{kind:`实测有害`,measured:6,note:"动态形态按完整模块导出校验工厂返回值,而 @types/node 的 os、@types/react 都是 `export =` 形状、类型上没有 default;实测三处 TS2769+TS2740/2741,react 那处无论怎么展开都补不出 default"},"vitest/prefer-lowercase-title":{kind:`仅限特定文件`,measured:171,note:`只在用例文件里生效:它带 autofix,实测一轮 oxlint --fix 静默把 260 条标题改成了小写(含 nO_VERIFY 这种坏名字)。包级 titlePrefixes 只留真正的技术名(GET/CSRF/组件名…):非技术名(工单号一类)不该借这条豁免留在标题里,而中文开头的标题天然满足要求(无大小写),免检范围能收多小就收多小。实测 oxlint 前缀一命中就把整条标题免检,所以陈旧条目由配置基线自检按『免检范围未被使用』指出,不靠人工巡检`},"vitest/prefer-called-times":{kind:`与已启用规则互斥`,measured:0,note:`实测核对(同文件四种写法各跑一次):toHaveBeenCalledTimes(1) 被 prefer-called-once 判违规、toHaveBeenCalledOnce() 被本条判违规、expect(spy.mock.calls).toHaveLength(1) 被 prefer-to-have-been-called-times 判违规,只有 n>=2 能同时满足三条 ⇒ 三条同开等于「单次调用」这条断言无法书写(实测逼得消费方改用 assert.equal(spy.mock.calls.length, 1) 绕行)。保留 prefer-called-once 与 prefer-to-have-been-called-times 两条方向一致的组合,关闭本条`},"vitest/prefer-describe-function-title":{kind:`与已启用规则互斥`,measured:48,note:"要求 `describe(fn)`,而 valid-title 要求字符串字面量(oxlint 1.85 的 valid-title 是 DummyRule、无任何选项);上游 recommended 收的是 valid-title,取它,26 处 `describe(fn)` 按代码改成同名字符串"},"vitest/prefer-to-be-truthy":{kind:`实测有害`,measured:117,note:`把 toStrictEqual(true) 放宽成 toTruthy(),接受任意真值是削弱断言`},"vitest/prefer-to-be-falsy":{kind:`实测有害`,measured:89,note:`同族,放宽成 toFalsy() 同样是削弱断言`},"regexp/no-super-linear-backtracking":{kind:`仅限特定文件`,measured:23,note:`测试夹具里的宽正则只跑短输入,ReDoS 不构成运行风险;生产侧 2 处与脚本侧 1 处保持开启并按代码修`},"e18e/prefer-static-regex":{kind:`仅限特定文件`,measured:1778,note:`只对生产代码开(PROD_OVERRIDES):生产 78 处按代码提到模块作用域;测试 1672 处与脚本 28 处里的内联正则不构成性能问题`},"e18e/ban-dependencies":{kind:`仅限特定文件`,measured:1,note:`唯一命中是消费方脚本对 js-yaml 的 mark.snippet 的依赖,换 yaml 不是等价替换;脚本面关闭,生产代码仍生效`},"import/no-default-export":{kind:`与官方形态冲突`,measured:38,note:`官方 cordis 入口就是 default export(vendor/loader/src/index.ts 的 unwrapExports 先 unwrap default),12 条正是 12 个 bundle 入口`},"import/no-named-export":{kind:`与官方形态冲突`,measured:895,note:`13 个包与上游 deepseek-harness 一样以具名导出 + 子路径说明符对外提供接口`},"import/prefer-default-export":{kind:`与官方形态冲突`,measured:58,note:`与 no-default-export 同族、方向与 cordis 入口相反`},"import/no-nodejs-modules":{kind:`与官方形态冲突`,measured:448,note:"宿主侧就运行在 node 上,`node:` 内置模块是运行环境本身而不是越界"},"import/no-named-as-default-member":{kind:`与官方形态冲突`,measured:47,note:`对具名导出的默认对象做成员访问是本仓消费官方声明的常态`},"import/no-anonymous-default-export":{kind:`与官方形态冲突`,measured:12,note:`官方 cordis 入口是匿名对象 default export(registry.ts 的 RegistryService.plugin() 读 name/Config,isApplicable() 判 apply),改成具名等于改官方形态`},"eslint/no-duplicate-imports":{kind:`实测有害`,measured:166,note:`ESLint 官方已废弃(不区分 import type),由 import/no-duplicates 取代`},"import/group-exports":{kind:`上游不推荐`,measured:766,note:`要求单点导出,与具名导出的接口形态冲突`},"import/exports-last":{kind:`上游不推荐`,measured:528,note:`要求导出语句在文件末尾`},"import/no-relative-parent-imports":{kind:`上游不推荐`,measured:277,note:`包内 lib/ 与 test/ 的相对父级引用是既有结构`},"import/max-dependencies":{kind:`上游不推荐`,measured:25,note:`给 import 条数设上限;宿主侧消费官方服务天然依赖多`},"node/no-process-env":{kind:`上游不推荐`,measured:51,note:`环境变量是本仓的输入来源(DSH_HOME、profile 目录、构建期开关);eslint-plugin-n 的 recommended 也不含本条`},"eslint/no-magic-numbers":{kind:`上游不推荐`,measured:5774,note:`把 HTTP 状态码/毫秒阈值抽成常量的计数规则`},"eslint/sort-keys":{kind:`上游不推荐`,measured:4101,note:`对象键排序;成对字面量与 locale 字典的可读性会一起受损`},"eslint/sort-imports":{kind:`上游不推荐`,measured:675,note:`字母序 import,与 oxfmt 的分组形态冲突`},"eslint/capitalized-comments":{kind:`上游不推荐`,measured:2388,note:`本仓注释以中文为主,「首字母大写」对中文注释无从判定`},"eslint/no-ternary":{kind:`上游不推荐`,measured:1024,note:`禁三元;改写成 if/else 并不会更正确`},"eslint/no-undefined":{kind:`上游不推荐`,measured:2009,note:"禁 `undefined` 字面量,与本仓大量显式可选返回形态冲突"},"eslint/no-void":{kind:`上游不推荐`,measured:172,note:"禁 `void` 前缀,而 `void promise` 正是满足 no-floating-promises 的官方写法"},"unicorn/no-null":{kind:`上游不推荐`,measured:788,note:`禁 null;官方声明与 JSON 边界大量用 null,改成 undefined 会改变序列化形态`},"typescript/prefer-readonly-parameter-types":{kind:`上游不推荐`,measured:2433,note:`要求每个入参类型全 readonly;官方声明(SessionEvent/ConfigForm 等)是可变的,改不动也不该改`},"oxc/no-async-await":{kind:`与已启用规则互斥`,measured:2160,note:`禁 async/await,而同表里 promise-function-async、require-await、no-floating-promises 都在要求用 async`},"oxc/no-optional-chaining":{kind:`与已启用规则互斥`,measured:1354,note:"禁 `?.`,而 typescript/prefer-optional-chain 正在要求把 && 链改成 `?.`"},"oxc/no-rest-spread-properties":{kind:`与已启用规则互斥`,measured:550,note:`禁对象 spread,而 ES2024 目标与官方声明的投影写法都靠它`},"typescript/no-explicit-any":{kind:`仅限特定文件`,measured:1,note:`用例里的桩件面(mini-react 之类)需要 any 才塞得进官方签名`},"typescript/no-non-null-assertion":{kind:`仅限特定文件`,measured:536,note:"用例里 `!` 是「前驱条件已成立」的最短写法"},"typescript/no-unsafe-type-assertion":{kind:`仅限特定文件`,measured:844,note:"桩件需要 `as never` / `as unknown as` 跨官方名义类型"},"typescript/require-await":{kind:`仅限特定文件`,measured:467,note:`官方 async 契约的同步实现与测试替身撑不住这条;prod 侧的条数按代码修,不进豁免`},"eslint/require-await":{kind:`与官方形态冲突`,measured:481,note:`它与 typescript/require-await 是同一条判断的两份实现,不是两条:实测核对(一段无 await 的 async 函数、--type-aware)单开各自都报、同开报两次,即 2 errors / 1 defect。按 typescript-eslint 官方对 extension rule 的处理方式裁决:留带类型信息的扩展那条、关基线那条。覆盖范围没有因此变小:全仓逐行去重实测 514 行两点同报、typescript 独有 0 行、eslint 独有只落在用例范围与配置自身的中间态;而 --type-aware 实测对 .mjs 也会由扩展那条报出,所以 scripts/*.mjs 面不需要基线那条补位。用例文件由 TEST_OVERRIDES 整族豁免`},"eslint/max-statements":{kind:`仅限特定文件`,measured:549,note:`用例体天然长(given/when/then 展开)`},"eslint/max-lines-per-function":{kind:`仅限特定文件`,measured:365,note:`同上`},"eslint/max-lines":{kind:`仅限特定文件`,measured:54,note:`单个用例文件的长度不作为缺陷信号`},"node/no-sync":{kind:`仅限特定文件`,measured:299,note:`构建脚本与门禁脚本按设计同步读;生产代码的写侧由每包 syncWrites 逐项登记,不在豁免里`},"node/no-top-level-await":{kind:`仅限特定文件`,measured:53,note:`脚本以 node 直接执行,顶层 await 是 ESM 常态;prod 侧 0 条`},"typescript/strict-boolean-expressions":{kind:`仅限特定文件`,measured:0,note:`scripts/*.mjs 无类型面,隐式 any 上无从判定`},"typescript/no-implied-eval":{kind:`仅限特定文件`,measured:0,note:`同上:这条要类型信息才能判`},"typescript/no-unsafe-member-access":{kind:`仅限特定文件`,measured:0,note:`无类型标注的脚本里每个值都落进隐式 any`},"typescript/no-unsafe-call":{kind:`仅限特定文件`,measured:0,note:n},"typescript/no-unsafe-assignment":{kind:`仅限特定文件`,measured:0,note:n},"typescript/no-unsafe-return":{kind:`仅限特定文件`,measured:0,note:n},"typescript/no-unsafe-argument":{kind:`仅限特定文件`,measured:0,note:n},"typescript/require-array-sort-compare":{kind:`仅限特定文件`,measured:0,note:`无类型脚本里「比较器缺失」判不出来`},"unicorn/no-process-exit":{kind:`仅限特定文件`,measured:2,note:`CLI 脚本的 process.exit 就是它的返回方式`},"eslint/no-continue":{kind:`仅限特定文件`,measured:53,note:`只对 scripts/ 豁免:TS 侧实测 0 条(包代码本来就不用 continue),908 行的门禁脚本改成嵌套 if 只会更难读`},"unicorn/max-nested-calls":{kind:`仅限特定文件`,measured:59,note:`只对 scripts/ 豁免:TS 侧实测 0 条;CLI 脚本里链式 map/filter/join 的深度由数据形状决定,不指向缺陷`},"unicorn/no-useless-undefined":{kind:`仅限特定文件`,measured:0,note:`脚本侧同上调;prod 仍按配置项 checkArguments:false 生效`},"react/set-state-in-effect":{kind:`与官方形态冲突`,measured:16,note:`卡片用 effect 同步宿主态到 store 是挂载适配器形态;Compiler 建议的 render 期推导要改写 12 份适配器的状态流`},"react/no-deriving-state-in-effects":{kind:`与官方形态冲突`,measured:7,note:`适配器形态里「props/state 派生值在 effect 对齐宿主」是挂载动作,不是可下沉到 render 的纯派生`},"react/exhaustive-effect-dependencies":{kind:`与官方形态冲突`,measured:8,note:`Compiler 版依赖审计对适配器的内联闭包全量追问;与 react-hooks/exhaustive-deps(保留并已修)形成双门,留后者`},"react/hooks":{kind:`与官方形态冲突`,measured:13,note:`「同一 hook 函数跨渲染同引用」在适配器的内联闭包形态下整体不成立;收敛批次把闭包提升后再回来开`},"react/refs":{kind:`与官方形态冲突`,measured:1,note:`挂载适配器在 render 期读 ref 对齐宿主布局;收敛批次改成挂载后读`},"react/todo":{kind:`上游不推荐`,measured:6,note:`报的是 React 编译器 BuildHIR 自己不支持 try/catch(-finally) 的上游 TODO,不是代码缺陷`},"react/rules-of-hooks":{kind:`仅限特定文件`,measured:3,note:`只对用例文件豁免(TEST_FILE_OVERRIDES):测试架在组件树外直接驱动卡片适配 hook(useCardOf / useSyncExternalStore 桩),调用次数顺序由桩件固定。键用表载前缀 react/(诊断文案显示 react-hooks(...) 是显示名,配置键以 --rules 的 Source 列为准)`}},i=[`typescript/no-empty-object-type`],a=[`existsSync`,`readFileSync`,`readdirSync`,`readSync`,`realpathSync`,`statSync`],o=[`eslint`,`typescript`,`unicorn`,`oxc`,`node`,`promise`,`vitest`,`import`,`react`,`jsx-a11y`],s={label:`sonarjs`,packageName:`eslint-plugin-sonarjs`,extraCandidates:[`eslint-plugin-sonarjs/cjs/plugin.js`]},c=[s,{label:`regexp`,packageName:`eslint-plugin-regexp`},{label:`zod`,packageName:`eslint-plugin-zod`},{label:`e18e`,packageName:`@e18e/eslint-plugin`}];function l(e,t){return(typeof e==`string`?e:`${e.name} ${e.specifier}`).includes(t.packageName)}function u(t){let n=e(import.meta.url),r=[];for(let e of[t.packageName,...t.extraCandidates??[]])try{return n.resolve(e)}catch{r.push(e)}throw Error(`oxlint 基线要挂 ${t.packageName},但从本包解析不到它(试过 ${r.join(`、`)})。要么在本包 devDependencies 里装 ${t.packageName},要么把你自己解析到的 ${t.label} 入口经 definePluginConfig({ jsPlugins: [...] }) 传进来(入口路径须指向 ${t.packageName},换成别家的插件无法满足这条规则表)。`)}function d(e,t=()=>u(s)){let n=e??[],r=null;try{r=t()}catch(e){if(!n.some(e=>l(e,s)))throw e}return r===null?[...n]:[r,...n.filter(e=>e!==r)]}function f(e,t={}){let n=d(e);for(let r of c.filter(e=>e!==s))if(!(e??[]).some(e=>l(e,r))){let e=(t[r.label]??(()=>u(r)))();n=[e,...n.filter(t=>t!==e)]}return n}const p={"sonarjs/no-identical-functions":`error`,"sonarjs/no-duplicated-branches":`error`,"sonarjs/no-all-duplicated-branches":`error`,"sonarjs/no-collapsible-if":`error`,"sonarjs/no-identical-conditions":`error`,"sonarjs/no-identical-expressions":`error`,"sonarjs/no-duplicate-string":`error`,"sonarjs/cognitive-complexity":`error`,"sonarjs/max-switch-cases":`error`,"sonarjs/no-inverted-boolean-check":`error`,"sonarjs/no-duplicate-in-composite":`error`,"sonarjs/duplicates-in-character-class":`error`,"sonarjs/no-useless-catch":`error`,"sonarjs/no-extra-arguments":`error`,"sonarjs/no-redundant-assignments":`error`,"sonarjs/prefer-single-boolean-return":`error`,"sonarjs/label-position":`error`},m={"regexp/confusing-quantifier":`error`,"regexp/control-character-escape":`error`,"regexp/match-any":`error`,"regexp/negation":`error`,"regexp/no-contradiction-with-assertion":`error`,"regexp/no-dupe-characters-character-class":`error`,"regexp/no-dupe-disjunctions":`error`,"regexp/no-empty-alternative":`error`,"regexp/no-empty-capturing-group":`error`,"regexp/no-empty-character-class":`error`,"regexp/no-empty-group":`error`,"regexp/no-empty-lookarounds-assertion":`error`,"regexp/no-empty-string-literal":`error`,"regexp/no-escape-backspace":`error`,"regexp/no-extra-lookaround-assertions":`error`,"regexp/no-invalid-regexp":`error`,"regexp/no-invisible-character":`error`,"regexp/no-lazy-ends":`error`,"regexp/no-legacy-features":`error`,"regexp/no-misleading-capturing-group":`error`,"regexp/no-misleading-unicode-character":`error`,"regexp/no-missing-g-flag":`error`,"regexp/no-non-standard-flag":`error`,"regexp/no-obscure-range":[`error`,{allowed:[`alphanumeric`,`一-鿿`,`一-龥`]}],"regexp/no-optional-assertion":`error`,"regexp/no-potentially-useless-backreference":`error`,"regexp/no-super-linear-backtracking":`error`,"regexp/no-trivially-nested-assertion":`error`,"regexp/no-trivially-nested-quantifier":`error`,"regexp/no-unused-capturing-group":`error`,"regexp/no-useless-assertions":`error`,"regexp/no-useless-backreference":`error`,"regexp/no-useless-character-class":`error`,"regexp/no-useless-dollar-replacements":`error`,"regexp/no-useless-escape":`error`,"regexp/no-useless-flag":`error`,"regexp/no-useless-lazy":`error`,"regexp/no-useless-non-capturing-group":`error`,"regexp/no-useless-quantifier":`error`,"regexp/no-useless-range":`error`,"regexp/no-useless-set-operand":`error`,"regexp/no-useless-string-literal":`error`,"regexp/no-useless-two-nums-quantifier":`error`,"regexp/no-zero-quantifier":`error`,"regexp/optimal-lookaround-quantifier":`error`,"regexp/optimal-quantifier-concatenation":`error`,"regexp/prefer-character-class":`error`,"regexp/prefer-d":`error`,"regexp/prefer-plus-quantifier":`error`,"regexp/prefer-predefined-assertion":`error`,"regexp/prefer-question-quantifier":`error`,"regexp/prefer-range":`error`,"regexp/prefer-set-operation":`error`,"regexp/prefer-star-quantifier":`error`,"regexp/prefer-unicode-codepoint-escapes":`error`,"regexp/prefer-w":`error`,"regexp/simplify-set-operations":`error`,"regexp/sort-flags":`error`,"regexp/strict":`error`,"regexp/use-ignore-case":`error`},h={"zod/consistent-import":[`error`,{syntax:`named`}],"zod/no-any-schema":`error`,"zod/no-coerce-boolean":`error`,"zod/no-conflicting-checks":`error`,"zod/no-duplicate-schema-methods":`error`,"zod/no-empty-custom-schema":`error`,"zod/no-native-enum":`error`,"zod/no-number-schema-with-finite":`error`,"zod/no-number-schema-with-int":`error`,"zod/no-number-schema-with-is-finite":`error`,"zod/no-number-schema-with-is-int":`error`,"zod/no-number-schema-with-safe":`error`,"zod/no-number-schema-with-step":`error`,"zod/no-optional-and-default-together":`error`,"zod/no-promise-schema":`error`,"zod/no-schema-with-is-nullable":`error`,"zod/no-schema-with-is-optional":`error`,"zod/no-throw-in-refine":`error`,"zod/no-transform-in-record-key":`error`,"zod/prefer-top-level-string-formats":`error`,"zod/require-brand-type-parameter":`error`,"zod/require-error-message":`error`},g={"e18e/ban-dependencies":`error`,"e18e/prefer-array-fill":`error`,"e18e/prefer-array-from-map":`error`,"e18e/prefer-array-to-reversed":`error`,"e18e/prefer-array-to-sorted":`error`,"e18e/prefer-array-to-spliced":`error`,"e18e/prefer-static-regex":`off`,"e18e/prefer-timer-args":`error`,"e18e/prefer-url-canparse":`error`},_={correctness:`error`,suspicious:`error`,style:`error`,perf:`error`,restriction:`error`,pedantic:`error`,nursery:`error`},v={typeAware:!0,typeCheck:!0,denyWarnings:!0,maxWarnings:0,reportUnusedDisableDirectives:`error`,respectEslintDisableDirectives:!1},y=[`**/node_modules/**`,`.toolchain/**`,`coverage/**`,`dist/**`,`client.js`,`host.js`],b=/* @__PURE__ */ `vitest/consistent-each-for.vitest/consistent-test-filename.vitest/consistent-test-it.vitest/consistent-vitest-vi.vitest/expect-expect.vitest/hoisted-apis-on-top.vitest/max-expects.vitest/max-nested-describe.vitest/no-alias-methods.vitest/no-commented-out-tests.vitest/no-conditional-expect.vitest/no-conditional-in-test.vitest/no-conditional-tests.vitest/no-disabled-tests.vitest/no-duplicate-hooks.vitest/no-focused-tests.vitest/no-hooks.vitest/no-identical-title.vitest/no-import-node-test.vitest/no-importing-vitest-globals.vitest/no-interpolation-in-snapshots.vitest/no-large-snapshots.vitest/no-mocks-import.vitest/no-restricted-matchers.vitest/no-restricted-vi-methods.vitest/no-standalone-expect.vitest/no-test-prefixes.vitest/no-test-return-statement.vitest/no-unneeded-async-expect-function.vitest/padding-around-after-all-blocks.vitest/padding-around-test-blocks.vitest/prefer-called-exactly-once-with.vitest/prefer-called-once.vitest/prefer-called-times.vitest/prefer-called-with.vitest/prefer-comparison-matcher.vitest/prefer-describe-function-title.vitest/prefer-each.vitest/prefer-equality-matcher.vitest/prefer-expect-assertions.vitest/prefer-expect-resolves.vitest/prefer-expect-type-of.vitest/prefer-hooks-in-order.vitest/prefer-hooks-on-top.vitest/prefer-import-in-mock.vitest/prefer-importing-vitest-globals.vitest/prefer-lowercase-title.vitest/prefer-mock-promise-shorthand.vitest/prefer-mock-return-shorthand.vitest/prefer-snapshot-hint.vitest/prefer-spy-on.vitest/prefer-strict-boolean-matchers.vitest/prefer-strict-equal.vitest/prefer-to-be.vitest/prefer-to-be-falsy.vitest/prefer-to-be-object.vitest/prefer-to-be-truthy.vitest/prefer-to-contain.vitest/prefer-to-have-been-called-times.vitest/prefer-to-have-length.vitest/prefer-todo.vitest/require-awaited-expect-poll.vitest/require-hook.vitest/require-local-test-context-for-concurrent-snapshots.vitest/require-mock-type-parameters.vitest/require-test-timeout.vitest/require-to-throw-message.vitest/require-top-level-describe.vitest/valid-describe-callback.vitest/valid-expect.vitest/valid-expect-in-promise.vitest/valid-title.vitest/warn-todo`.split(`.`),x=/* @__PURE__ */ new Set([`vitest/max-expects`,`vitest/no-conditional-in-test`,`vitest/no-hooks`,`vitest/no-importing-vitest-globals`,`vitest/prefer-called-times`,`vitest/prefer-describe-function-title`,`vitest/prefer-expect-assertions`,`vitest/prefer-import-in-mock`,`vitest/prefer-importing-vitest-globals`,`vitest/prefer-to-be-falsy`,`vitest/prefer-to-be-truthy`,`vitest/require-test-timeout`]),S={"eslint/one-var":[`error`,`never`],"eslint/func-style":[`error`,`declaration`,{allowArrowFunctions:!0,overrides:{namedExports:`ignore`}}],"eslint/id-length":[`error`,{exceptions:[`a`,`i`,`t`,`x`,`y`,`z`]}],"eslint/init-declarations":[`error`,`never`,{ignoreForLoopInit:!0}],"eslint/max-lines":[`error`,{max:2e3,skipBlankLines:!0,skipComments:!0}],"eslint/max-lines-per-function":[`error`,{max:120,skipBlankLines:!0,skipComments:!0}],"eslint/complexity":`error`,"eslint/max-params":[`error`,{max:5}],"eslint/max-statements":[`error`,50],"eslint/no-console":[`error`,{allow:[`warn`,`error`,`info`]}],"eslint/no-warning-comments":[`error`,{terms:[`todo`,`fixme`,`xxx`,`hack`],location:`start`}],"eslint/no-param-reassign":`error`,"eslint/no-underscore-dangle":[`error`,{allow:[`__memoryInsightCardApplied`,`__memoryTdaiCardApplied`,`__sessionRescueApplied`,`__wukilDevToolsCardApplied`]}],"eslint/no-magic-numbers":`off`,"eslint/sort-keys":`off`,"eslint/sort-imports":`off`,"eslint/capitalized-comments":`off`,"eslint/no-ternary":`off`,"eslint/no-undefined":`off`,"eslint/no-void":`off`,"eslint/no-duplicate-imports":`off`,"eslint/require-await":`off`,"import/no-named-export":`off`,"import/group-exports":`off`,"import/exports-last":`off`,"import/prefer-default-export":`off`,"import/no-nodejs-modules":`off`,"import/no-relative-parent-imports":`off`,"import/max-dependencies":`off`,"import/no-default-export":`off`,"import/no-anonymous-default-export":`off`,"import/no-named-as-default-member":`off`,"import/consistent-type-specifier-style":[`error`,`prefer-top-level`],"import/no-duplicates":`error`,"import/no-cycle":`error`,"import/named":`error`,"import/first":`error`,"import/newline-after-import":`error`,"node/no-process-env":`off`,"node/no-sync":[`error`,{ignores:a}],"node/no-top-level-await":`error`,"oxc/no-async-await":`off`,"oxc/no-optional-chaining":`off`,"oxc/no-rest-spread-properties":`off`,"promise/always-return":`error`,"promise/no-promise-in-callback":[`error`,{exemptDeclarations:!0}],"promise/no-return-wrap":`error`,"promise/param-names":`error`,"promise/prefer-await-to-then":`error`,"typescript/consistent-type-imports":[`error`,{disallowTypeAnnotations:!1}],"typescript/explicit-function-return-type":[`error`,{allowDirectConstAssertionInArrowFunctions:!0,allowExpressions:!0,allowHigherOrderFunctions:!0,allowIIFEs:!0,allowTypedFunctionExpressions:!0,allowedNames:[`handler`,`callback`]}],"typescript/no-explicit-any":`error`,"typescript/no-floating-promises":`error`,"typescript/no-unsafe-assignment":`error`,"typescript/no-unsafe-type-assertion":`error`,"typescript/no-non-null-assertion":`error`,"typescript/require-await":`error`,"typescript/prefer-readonly-parameter-types":`off`,"typescript/promise-function-async":[`error`,{checkArrowFunctions:!1}],"typescript/consistent-return":[`error`,{treatUndefinedAsUnspecified:!0}],"typescript/only-throw-error":`error`,"unicorn/no-array-reduce":[`error`,{allowSimpleOperations:!0}],"unicorn/no-null":`off`,"unicorn/no-useless-undefined":[`error`,{checkArguments:!1}],"react/set-state-in-effect":`off`,"react/no-deriving-state-in-effects":`off`,"react/exhaustive-effect-dependencies":`off`,"react/hooks":`off`,"react/refs":`off`,"react/todo":`off`,...m,...h,...g,...Object.fromEntries(b.map(e=>[e,`off`]))},C=[`**/*.test.ts`,`**/*.test.tsx`],w=[`**/__tests__/**/*.spec.ts`,`**/test/**/*.spec.ts`],T={files:[...C,`**/test/**`,`**/__tests__/**`],rules:{"typescript/no-non-null-assertion":`off`,"typescript/no-unsafe-type-assertion":`off`,"typescript/no-explicit-any":`off`,"typescript/require-await":`off`,"eslint/max-statements":`off`,"eslint/max-lines":`off`,"eslint/max-lines-per-function":`off`,"node/no-top-level-await":`off`,"regexp/no-super-linear-backtracking":`off`}},E={files:[`lib/**`,`src/**`,`host.ts`,`cli-main.ts`],rules:{"e18e/prefer-static-regex":`error`}},D=[`expect`,`expectTypeOf`,`assert`,`assertType`],O=/^[A-Za-z_$][\w$]*$/u,k={files:[...C,...w],rules:{...Object.fromEntries(b.filter(e=>!x.has(e)).map(e=>[e,`error`])),"vitest/expect-expect":[`error`,{assertFunctionNames:D}],"react/rules-of-hooks":`off`}};function A(e={}){let t=e.assertionHelpers??[],n=e.titlePrefixes??[],r=[...t,...n].filter(e=>!O.test(e));if(r.length>0)throw Error(`assertionHelpers / titlePrefixes 只收裸标识符,不接受通配或带点形式(前者等于让 vitest/expect-expect 失去作用):${r.join(`, `)}`);let i=[.../* @__PURE__ */ new Set([...D,...t])];return{...k,rules:{...k.rules,"vitest/expect-expect":[`error`,{assertFunctionNames:i}],...n.length===0?{}:{"vitest/prefer-lowercase-title":[`error`,{allowedPrefixes:[...new Set(n)]}]}}}}const j={files:[`scripts/**`,`*.mjs`,`*.mts`],rules:{"eslint/no-continue":`off`,"unicorn/max-nested-calls":`off`,"eslint/id-length":[`error`,{exceptions:[`a`,`i`,`t`,`x`,`y`,`z`,`n`,`p`,`s`,`v`,`e`,`f`,`ok`,`fs`,`id`]}],"unicorn/no-process-exit":`off`,"unicorn/no-useless-undefined":`off`,"typescript/no-non-null-assertion":`off`,"node/no-sync":`off`,"node/no-top-level-await":`off`,"e18e/ban-dependencies":`off`,"typescript/no-unsafe-member-access":`off`,"typescript/no-unsafe-call":`off`,"typescript/no-unsafe-assignment":`off`,"typescript/no-unsafe-return":`off`,"typescript/no-unsafe-argument":`off`,"typescript/strict-boolean-expressions":`off`,"typescript/no-implied-eval":`off`,"typescript/require-array-sort-compare":`off`}};function M(e){let t={...r,...e};return e=>{let n=t[e];if(n!==void 0)return n;let r=e.indexOf(`/`);return r===-1?void 0:t[`${e.slice(0,r)}/*`]}}function N(e,t,n){if(t===void 0)return;let r=[];for(let[e,i]of Object.entries(t))if((Array.isArray(i)?i[0]:i)===`off`){let t=n(e);(t===void 0||t.note.trim().length===0)&&r.push(e)}if(r.length>0)throw Error(`${e} 里这些规则被关成 off 但没有依据(OFF_JUSTIFICATIONS 查不到,或 note 为空):${r.join(`, `)}。要么在代码里修,要么给它补一条 kind + measured + note。`)}function P(e={}){let{syncWrites:n=[],extraRules:r={},extraOverrides:i=[],extraIgnorePatterns:s=[],jsPlugins:c,offReasons:l={},assertionHelpers:u=[],titlePrefixes:d=[]}=e,m=M(l),h={...S,...p,...n.length>0?{"node/no-sync":[`error`,{ignores:[.../* @__PURE__ */ new Set([...a,...n])]}]}:{},...r},g=[T,A({assertionHelpers:u,titlePrefixes:d}),j,E,...i];N(`rules`,h,m);for(let[e,t]of g.entries())N(`overrides[${e}]`,t.rules,m);return t({plugins:o,env:{node:!0,es2024:!0,browser:!0},options:v,categories:_,ignorePatterns:[...y,...s],jsPlugins:f(c),rules:h,overrides:g})}export{S as BASE_RULES,g as E18E_RULES,r as OFF_JUSTIFICATIONS,E as PROD_OVERRIDES,a as READONLY_SYNC_ALLOWLIST,m as REGEXP_RULES,i as RETIRED_OFFS,j as SCRIPTS_OVERRIDES,k as TEST_FILE_OVERRIDES,T as TEST_OVERRIDES,b as VITEST_ALL_RULES,D as VITEST_ASSERTION_DEFAULTS,h as ZOD_RULES,P as definePluginConfig,A as makeTestFileOverrides,f as resolveBundledJsPlugins,d as resolveJsPlugins};
|
|
1
|
+
import{createRequire as e}from"node:module";import{defineConfig as t}from"oxlint";const n=`同 no-unsafe-member-access`,r={"vitest/*":{kind:`仅限特定文件`,measured:7,note:`用例结构类判断在非用例文件上无从计算`},"vitest/no-hooks":{kind:`上游不推荐`,measured:181,note:`禁用 hook 本身;本仓按官方 vitest 用法大量使用 before*/after*`},"vitest/no-conditional-in-test":{kind:`仅限特定文件`,measured:523,note:`平台/宿主版本分支是刻意的(macOS 与 Linux 的家目录形态、0.1.7 与 0.1.6 的 API 差异)`},"vitest/max-expects":{kind:`上游不推荐`,measured:163,note:`给单条用例的断言条数设上限属风格偏好,不指向缺陷`},"vitest/prefer-expect-assertions":{kind:`上游不推荐`,measured:2902,note:`要求每个 async 用例手写 expect.assertions(n),是与断言强度无关的计数要求`},"vitest/require-test-timeout":{kind:`上游不推荐`,measured:2892,note:`要求每条用例显式 timeout;本仓用泵式假时钟,超时由 13 份 vitest 配置统一给出`},"vitest/prefer-importing-vitest-globals":{kind:`实测有害`,measured:0,note:`autofix 方向是删掉显式 import 改回裸全局;13 份 vitest 配置都没开 globals:true,应用后立即出现 3605 处 TS2593、测试全部失效`},"vitest/no-importing-vitest-globals":{kind:`实测有害`,measured:133,note:`与上一条同族、方向相反,两条同时开启就是把两种写法都判违规`},"vitest/prefer-import-in-mock":{kind:`实测有害`,measured:6,note:"动态形态按完整模块导出校验工厂返回值,而 @types/node 的 os、@types/react 都是 `export =` 形状、类型上没有 default;实测三处 TS2769+TS2740/2741,react 那处无论怎么展开都补不出 default"},"vitest/prefer-lowercase-title":{kind:`仅限特定文件`,measured:171,note:`只在用例文件里生效:它带 autofix,实测一轮 oxlint --fix 静默把 260 条标题改成了小写(含 nO_VERIFY 这种坏名字)。包级 titlePrefixes 只留真正的技术名(GET/CSRF/组件名…):非技术名(工单号一类)不该借这条豁免留在标题里,而中文开头的标题天然满足要求(无大小写),免检范围能收多小就收多小。实测 oxlint 前缀一命中就把整条标题免检,所以陈旧条目由配置基线自检按『免检范围未被使用』指出,不靠人工巡检`},"vitest/prefer-called-times":{kind:`与已启用规则互斥`,measured:0,note:`实测核对(同文件四种写法各跑一次):toHaveBeenCalledTimes(1) 被 prefer-called-once 判违规、toHaveBeenCalledOnce() 被本条判违规、expect(spy.mock.calls).toHaveLength(1) 被 prefer-to-have-been-called-times 判违规,只有 n>=2 能同时满足三条 ⇒ 三条同开等于「单次调用」这条断言无法书写(实测逼得消费方改用 assert.equal(spy.mock.calls.length, 1) 绕行)。保留 prefer-called-once 与 prefer-to-have-been-called-times 两条方向一致的组合,关闭本条`},"vitest/prefer-describe-function-title":{kind:`与已启用规则互斥`,measured:48,note:"要求 `describe(fn)`,而 valid-title 要求字符串字面量(oxlint 1.85 的 valid-title 是 DummyRule、无任何选项);上游 recommended 收的是 valid-title,取它,26 处 `describe(fn)` 按代码改成同名字符串"},"vitest/prefer-to-be-truthy":{kind:`实测有害`,measured:117,note:`把 toStrictEqual(true) 放宽成 toTruthy(),接受任意真值是削弱断言`},"vitest/prefer-to-be-falsy":{kind:`实测有害`,measured:89,note:`同族,放宽成 toFalsy() 同样是削弱断言`},"regexp/no-super-linear-backtracking":{kind:`仅限特定文件`,measured:23,note:`测试夹具里的宽正则只跑短输入,ReDoS 不构成运行风险;生产侧 2 处与脚本侧 1 处保持开启并按代码修`},"e18e/prefer-static-regex":{kind:`仅限特定文件`,measured:1778,note:`只对生产代码开(PROD_OVERRIDES):生产 78 处按代码提到模块作用域;测试 1672 处与脚本 28 处里的内联正则不构成性能问题`},"e18e/ban-dependencies":{kind:`仅限特定文件`,measured:1,note:`唯一命中是消费方脚本对 js-yaml 的 mark.snippet 的依赖,换 yaml 不是等价替换;脚本面关闭,生产代码仍生效`},"import/no-default-export":{kind:`与官方形态冲突`,measured:38,note:`官方 cordis 入口就是 default export(vendor/loader/src/index.ts 的 unwrapExports 先 unwrap default),12 条正是 12 个 bundle 入口`},"import/no-named-export":{kind:`与官方形态冲突`,measured:895,note:`13 个包与上游 deepseek-harness 一样以具名导出 + 子路径说明符对外提供接口`},"import/prefer-default-export":{kind:`与官方形态冲突`,measured:58,note:`与 no-default-export 同族、方向与 cordis 入口相反`},"import/no-nodejs-modules":{kind:`与官方形态冲突`,measured:448,note:"宿主侧就运行在 node 上,`node:` 内置模块是运行环境本身而不是越界"},"import/no-named-as-default-member":{kind:`与官方形态冲突`,measured:47,note:`对具名导出的默认对象做成员访问是本仓消费官方声明的常态`},"import/no-anonymous-default-export":{kind:`与官方形态冲突`,measured:12,note:`官方 cordis 入口是匿名对象 default export(registry.ts 的 RegistryService.plugin() 读 name/Config,isApplicable() 判 apply),改成具名等于改官方形态`},"eslint/no-duplicate-imports":{kind:`实测有害`,measured:166,note:`ESLint 官方已废弃(不区分 import type),由 import/no-duplicates 取代`},"import/group-exports":{kind:`上游不推荐`,measured:766,note:`要求单点导出,与具名导出的接口形态冲突`},"import/exports-last":{kind:`上游不推荐`,measured:528,note:`要求导出语句在文件末尾`},"import/no-relative-parent-imports":{kind:`上游不推荐`,measured:277,note:`包内 lib/ 与 test/ 的相对父级引用是既有结构`},"import/max-dependencies":{kind:`上游不推荐`,measured:25,note:`给 import 条数设上限;宿主侧消费官方服务天然依赖多`},"node/no-process-env":{kind:`上游不推荐`,measured:51,note:`环境变量是本仓的输入来源(DSH_HOME、profile 目录、构建期开关);eslint-plugin-n 的 recommended 也不含本条`},"eslint/no-magic-numbers":{kind:`上游不推荐`,measured:5774,note:`把 HTTP 状态码/毫秒阈值抽成常量的计数规则`},"eslint/sort-keys":{kind:`上游不推荐`,measured:4101,note:`对象键排序;成对字面量与 locale 字典的可读性会一起受损`},"eslint/sort-imports":{kind:`上游不推荐`,measured:675,note:`字母序 import,与 oxfmt 的分组形态冲突`},"eslint/capitalized-comments":{kind:`上游不推荐`,measured:2388,note:`本仓注释以中文为主,「首字母大写」对中文注释无从判定`},"eslint/no-ternary":{kind:`上游不推荐`,measured:1024,note:`禁三元;改写成 if/else 并不会更正确`},"eslint/no-undefined":{kind:`上游不推荐`,measured:2009,note:"禁 `undefined` 字面量,与本仓大量显式可选返回形态冲突"},"eslint/no-void":{kind:`上游不推荐`,measured:172,note:"禁 `void` 前缀,而 `void promise` 正是满足 no-floating-promises 的官方写法"},"unicorn/no-null":{kind:`上游不推荐`,measured:788,note:`禁 null;官方声明与 JSON 边界大量用 null,改成 undefined 会改变序列化形态`},"typescript/prefer-readonly-parameter-types":{kind:`上游不推荐`,measured:2433,note:`要求每个入参类型全 readonly;官方声明(SessionEvent/ConfigForm 等)是可变的,改不动也不该改`},"oxc/no-async-await":{kind:`与已启用规则互斥`,measured:2160,note:`禁 async/await,而同表里 promise-function-async、require-await、no-floating-promises 都在要求用 async`},"oxc/no-optional-chaining":{kind:`与已启用规则互斥`,measured:1354,note:"禁 `?.`,而 typescript/prefer-optional-chain 正在要求把 && 链改成 `?.`"},"oxc/no-rest-spread-properties":{kind:`与已启用规则互斥`,measured:550,note:`禁对象 spread,而 ES2024 目标与官方声明的投影写法都靠它`},"typescript/no-explicit-any":{kind:`仅限特定文件`,measured:1,note:`用例里的桩件面(mini-react 之类)需要 any 才塞得进官方签名`},"typescript/no-non-null-assertion":{kind:`仅限特定文件`,measured:536,note:"用例里 `!` 是「前驱条件已成立」的最短写法"},"typescript/no-unsafe-type-assertion":{kind:`仅限特定文件`,measured:844,note:"桩件需要 `as never` / `as unknown as` 跨官方名义类型"},"typescript/require-await":{kind:`仅限特定文件`,measured:467,note:`官方 async 契约的同步实现与测试替身撑不住这条;prod 侧的条数按代码修,不进豁免`},"eslint/require-await":{kind:`与官方形态冲突`,measured:481,note:`它与 typescript/require-await 是同一条判断的两份实现,不是两条:实测核对(一段无 await 的 async 函数、--type-aware)单开各自都报、同开报两次,即 2 errors / 1 defect。按 typescript-eslint 官方对 extension rule 的处理方式裁决:留带类型信息的扩展那条、关基线那条。覆盖范围没有因此变小:全仓逐行去重实测 514 行两点同报、typescript 独有 0 行、eslint 独有只落在用例范围与配置自身的中间态;而 --type-aware 实测对 .mjs 也会由扩展那条报出,所以 scripts/*.mjs 面不需要基线那条补位。用例文件由 TEST_OVERRIDES 整族豁免`},"eslint/max-statements":{kind:`仅限特定文件`,measured:549,note:`用例体天然长(given/when/then 展开)`},"eslint/max-lines-per-function":{kind:`仅限特定文件`,measured:365,note:`同上`},"eslint/max-lines":{kind:`仅限特定文件`,measured:54,note:`单个用例文件的长度不作为缺陷信号`},"node/no-sync":{kind:`仅限特定文件`,measured:299,note:`构建脚本与门禁脚本按设计同步读;写侧豁免按文件生效(syncIoScopes),不在这一层的豁免里`},"node/no-top-level-await":{kind:`仅限特定文件`,measured:53,note:`脚本以 node 直接执行,顶层 await 是 ESM 常态;prod 侧 0 条`},"typescript/strict-boolean-expressions":{kind:`仅限特定文件`,measured:0,note:`scripts/*.mjs 无类型面,隐式 any 上无从判定`},"typescript/no-implied-eval":{kind:`仅限特定文件`,measured:0,note:`同上:这条要类型信息才能判`},"typescript/no-unsafe-member-access":{kind:`仅限特定文件`,measured:0,note:`无类型标注的脚本里每个值都落进隐式 any`},"typescript/no-unsafe-call":{kind:`仅限特定文件`,measured:0,note:n},"typescript/no-unsafe-assignment":{kind:`仅限特定文件`,measured:0,note:n},"typescript/no-unsafe-return":{kind:`仅限特定文件`,measured:0,note:n},"typescript/no-unsafe-argument":{kind:`仅限特定文件`,measured:0,note:n},"typescript/require-array-sort-compare":{kind:`仅限特定文件`,measured:0,note:`无类型脚本里「比较器缺失」判不出来`},"unicorn/no-process-exit":{kind:`仅限特定文件`,measured:2,note:`CLI 脚本的 process.exit 就是它的返回方式`},"eslint/no-continue":{kind:`仅限特定文件`,measured:53,note:`只对 scripts/ 豁免:TS 侧实测 0 条(包代码本来就不用 continue),908 行的门禁脚本改成嵌套 if 只会更难读`},"unicorn/max-nested-calls":{kind:`仅限特定文件`,measured:59,note:`只对 scripts/ 豁免:TS 侧实测 0 条;CLI 脚本里链式 map/filter/join 的深度由数据形状决定,不指向缺陷`},"unicorn/no-useless-undefined":{kind:`仅限特定文件`,measured:0,note:`脚本侧同上调;prod 仍按配置项 checkArguments:false 生效`},"react/set-state-in-effect":{kind:`与官方形态冲突`,measured:16,note:`卡片用 effect 同步宿主态到 store 是挂载适配器形态;Compiler 建议的 render 期推导要改写 12 份适配器的状态流`},"react/no-deriving-state-in-effects":{kind:`与官方形态冲突`,measured:7,note:`适配器形态里「props/state 派生值在 effect 对齐宿主」是挂载动作,不是可下沉到 render 的纯派生`},"react/exhaustive-effect-dependencies":{kind:`与官方形态冲突`,measured:8,note:`Compiler 版依赖审计对适配器的内联闭包全量追问;与 react-hooks/exhaustive-deps(保留并已修)形成双门,留后者`},"react/hooks":{kind:`与官方形态冲突`,measured:13,note:`「同一 hook 函数跨渲染同引用」在适配器的内联闭包形态下整体不成立;收敛批次把闭包提升后再回来开`},"react/refs":{kind:`与官方形态冲突`,measured:1,note:`挂载适配器在 render 期读 ref 对齐宿主布局;收敛批次改成挂载后读`},"react/todo":{kind:`上游不推荐`,measured:6,note:`报的是 React 编译器 BuildHIR 自己不支持 try/catch(-finally) 的上游 TODO,不是代码缺陷`},"react/rules-of-hooks":{kind:`仅限特定文件`,measured:3,note:`只对用例文件豁免(TEST_FILE_OVERRIDES):测试架在组件树外直接驱动卡片适配 hook(useCardOf / useSyncExternalStore 桩),调用次数顺序由桩件固定。键用表载前缀 react/(诊断文案显示 react-hooks(...) 是显示名,配置键以 --rules 的 Source 列为准)`}},i=[`typescript/no-empty-object-type`],a=[`existsSync`,`readFileSync`,`readdirSync`,`readSync`,`realpathSync`,`statSync`],o=[`eslint`,`typescript`,`unicorn`,`oxc`,`node`,`promise`,`vitest`,`import`,`react`,`jsx-a11y`],s={label:`sonarjs`,packageName:`eslint-plugin-sonarjs`,extraCandidates:[`eslint-plugin-sonarjs/cjs/plugin.js`]},c=[s,{label:`regexp`,packageName:`eslint-plugin-regexp`},{label:`zod`,packageName:`eslint-plugin-zod`},{label:`e18e`,packageName:`@e18e/eslint-plugin`}];function l(e,t){return(typeof e==`string`?e:`${e.name} ${e.specifier}`).includes(t.packageName)}function u(t){let n=e(import.meta.url),r=[];for(let e of[t.packageName,...t.extraCandidates??[]])try{return n.resolve(e)}catch{r.push(e)}throw Error(`oxlint 基线要挂 ${t.packageName},但从本包解析不到它(试过 ${r.join(`、`)})。要么在本包 devDependencies 里装 ${t.packageName},要么把你自己解析到的 ${t.label} 入口经 definePluginConfig({ jsPlugins: [...] }) 传进来(入口路径须指向 ${t.packageName},换成别家的插件无法满足这条规则表)。`)}function d(e,t=()=>u(s)){let n=e??[],r=null;try{r=t()}catch(e){if(!n.some(e=>l(e,s)))throw e}return r===null?[...n]:[r,...n.filter(e=>e!==r)]}function f(e,t={}){let n=d(e);for(let r of c.filter(e=>e!==s))if(!(e??[]).some(e=>l(e,r))){let e=(t[r.label]??(()=>u(r)))();n=[e,...n.filter(t=>t!==e)]}return n}const p={"sonarjs/no-identical-functions":`error`,"sonarjs/no-duplicated-branches":`error`,"sonarjs/no-all-duplicated-branches":`error`,"sonarjs/no-collapsible-if":`error`,"sonarjs/no-identical-conditions":`error`,"sonarjs/no-identical-expressions":`error`,"sonarjs/no-duplicate-string":`error`,"sonarjs/cognitive-complexity":`error`,"sonarjs/max-switch-cases":`error`,"sonarjs/no-inverted-boolean-check":`error`,"sonarjs/no-duplicate-in-composite":`error`,"sonarjs/duplicates-in-character-class":`error`,"sonarjs/no-useless-catch":`error`,"sonarjs/no-extra-arguments":`error`,"sonarjs/no-redundant-assignments":`error`,"sonarjs/prefer-single-boolean-return":`error`,"sonarjs/label-position":`error`},m={"regexp/confusing-quantifier":`error`,"regexp/control-character-escape":`error`,"regexp/match-any":`error`,"regexp/negation":`error`,"regexp/no-contradiction-with-assertion":`error`,"regexp/no-dupe-characters-character-class":`error`,"regexp/no-dupe-disjunctions":`error`,"regexp/no-empty-alternative":`error`,"regexp/no-empty-capturing-group":`error`,"regexp/no-empty-character-class":`error`,"regexp/no-empty-group":`error`,"regexp/no-empty-lookarounds-assertion":`error`,"regexp/no-empty-string-literal":`error`,"regexp/no-escape-backspace":`error`,"regexp/no-extra-lookaround-assertions":`error`,"regexp/no-invalid-regexp":`error`,"regexp/no-invisible-character":`error`,"regexp/no-lazy-ends":`error`,"regexp/no-legacy-features":`error`,"regexp/no-misleading-capturing-group":`error`,"regexp/no-misleading-unicode-character":`error`,"regexp/no-missing-g-flag":`error`,"regexp/no-non-standard-flag":`error`,"regexp/no-obscure-range":[`error`,{allowed:[`alphanumeric`,`一-鿿`,`一-龥`]}],"regexp/no-optional-assertion":`error`,"regexp/no-potentially-useless-backreference":`error`,"regexp/no-super-linear-backtracking":`error`,"regexp/no-trivially-nested-assertion":`error`,"regexp/no-trivially-nested-quantifier":`error`,"regexp/no-unused-capturing-group":`error`,"regexp/no-useless-assertions":`error`,"regexp/no-useless-backreference":`error`,"regexp/no-useless-character-class":`error`,"regexp/no-useless-dollar-replacements":`error`,"regexp/no-useless-escape":`error`,"regexp/no-useless-flag":`error`,"regexp/no-useless-lazy":`error`,"regexp/no-useless-non-capturing-group":`error`,"regexp/no-useless-quantifier":`error`,"regexp/no-useless-range":`error`,"regexp/no-useless-set-operand":`error`,"regexp/no-useless-string-literal":`error`,"regexp/no-useless-two-nums-quantifier":`error`,"regexp/no-zero-quantifier":`error`,"regexp/optimal-lookaround-quantifier":`error`,"regexp/optimal-quantifier-concatenation":`error`,"regexp/prefer-character-class":`error`,"regexp/prefer-d":`error`,"regexp/prefer-plus-quantifier":`error`,"regexp/prefer-predefined-assertion":`error`,"regexp/prefer-question-quantifier":`error`,"regexp/prefer-range":`error`,"regexp/prefer-set-operation":`error`,"regexp/prefer-star-quantifier":`error`,"regexp/prefer-unicode-codepoint-escapes":`error`,"regexp/prefer-w":`error`,"regexp/simplify-set-operations":`error`,"regexp/sort-flags":`error`,"regexp/strict":`error`,"regexp/use-ignore-case":`error`},h={"zod/consistent-import":[`error`,{syntax:`named`}],"zod/no-any-schema":`error`,"zod/no-coerce-boolean":`error`,"zod/no-conflicting-checks":`error`,"zod/no-duplicate-schema-methods":`error`,"zod/no-empty-custom-schema":`error`,"zod/no-native-enum":`error`,"zod/no-number-schema-with-finite":`error`,"zod/no-number-schema-with-int":`error`,"zod/no-number-schema-with-is-finite":`error`,"zod/no-number-schema-with-is-int":`error`,"zod/no-number-schema-with-safe":`error`,"zod/no-number-schema-with-step":`error`,"zod/no-optional-and-default-together":`error`,"zod/no-promise-schema":`error`,"zod/no-schema-with-is-nullable":`error`,"zod/no-schema-with-is-optional":`error`,"zod/no-throw-in-refine":`error`,"zod/no-transform-in-record-key":`error`,"zod/prefer-top-level-string-formats":`error`,"zod/require-brand-type-parameter":`error`,"zod/require-error-message":`error`},g={"e18e/ban-dependencies":`error`,"e18e/prefer-array-fill":`error`,"e18e/prefer-array-from-map":`error`,"e18e/prefer-array-to-reversed":`error`,"e18e/prefer-array-to-sorted":`error`,"e18e/prefer-array-to-spliced":`error`,"e18e/prefer-static-regex":`off`,"e18e/prefer-timer-args":`error`,"e18e/prefer-url-canparse":`error`},_={correctness:`error`,suspicious:`error`,style:`error`,perf:`error`,restriction:`error`,pedantic:`error`,nursery:`error`},v={typeAware:!0,typeCheck:!0,denyWarnings:!0,maxWarnings:0,reportUnusedDisableDirectives:`error`,respectEslintDisableDirectives:!1},y=[`**/node_modules/**`,`.toolchain/**`,`coverage/**`,`dist/**`,`client.js`,`host.js`],b=/* @__PURE__ */ `vitest/consistent-each-for.vitest/consistent-test-filename.vitest/consistent-test-it.vitest/consistent-vitest-vi.vitest/expect-expect.vitest/hoisted-apis-on-top.vitest/max-expects.vitest/max-nested-describe.vitest/no-alias-methods.vitest/no-commented-out-tests.vitest/no-conditional-expect.vitest/no-conditional-in-test.vitest/no-conditional-tests.vitest/no-disabled-tests.vitest/no-duplicate-hooks.vitest/no-focused-tests.vitest/no-hooks.vitest/no-identical-title.vitest/no-import-node-test.vitest/no-importing-vitest-globals.vitest/no-interpolation-in-snapshots.vitest/no-large-snapshots.vitest/no-mocks-import.vitest/no-restricted-matchers.vitest/no-restricted-vi-methods.vitest/no-standalone-expect.vitest/no-test-prefixes.vitest/no-test-return-statement.vitest/no-unneeded-async-expect-function.vitest/padding-around-after-all-blocks.vitest/padding-around-test-blocks.vitest/prefer-called-exactly-once-with.vitest/prefer-called-once.vitest/prefer-called-times.vitest/prefer-called-with.vitest/prefer-comparison-matcher.vitest/prefer-describe-function-title.vitest/prefer-each.vitest/prefer-equality-matcher.vitest/prefer-expect-assertions.vitest/prefer-expect-resolves.vitest/prefer-expect-type-of.vitest/prefer-hooks-in-order.vitest/prefer-hooks-on-top.vitest/prefer-import-in-mock.vitest/prefer-importing-vitest-globals.vitest/prefer-lowercase-title.vitest/prefer-mock-promise-shorthand.vitest/prefer-mock-return-shorthand.vitest/prefer-snapshot-hint.vitest/prefer-spy-on.vitest/prefer-strict-boolean-matchers.vitest/prefer-strict-equal.vitest/prefer-to-be.vitest/prefer-to-be-falsy.vitest/prefer-to-be-object.vitest/prefer-to-be-truthy.vitest/prefer-to-contain.vitest/prefer-to-have-been-called-times.vitest/prefer-to-have-length.vitest/prefer-todo.vitest/require-awaited-expect-poll.vitest/require-hook.vitest/require-local-test-context-for-concurrent-snapshots.vitest/require-mock-type-parameters.vitest/require-test-timeout.vitest/require-to-throw-message.vitest/require-top-level-describe.vitest/valid-describe-callback.vitest/valid-expect.vitest/valid-expect-in-promise.vitest/valid-title.vitest/warn-todo`.split(`.`),x=/* @__PURE__ */ new Set([`vitest/max-expects`,`vitest/no-conditional-in-test`,`vitest/no-hooks`,`vitest/no-importing-vitest-globals`,`vitest/prefer-called-times`,`vitest/prefer-describe-function-title`,`vitest/prefer-expect-assertions`,`vitest/prefer-import-in-mock`,`vitest/prefer-importing-vitest-globals`,`vitest/prefer-to-be-falsy`,`vitest/prefer-to-be-truthy`,`vitest/require-test-timeout`]),S={"eslint/one-var":[`error`,`never`],"eslint/func-style":[`error`,`declaration`,{allowArrowFunctions:!0,overrides:{namedExports:`ignore`}}],"eslint/id-length":[`error`,{exceptions:[`a`,`i`,`t`,`x`,`y`,`z`]}],"eslint/init-declarations":[`error`,`never`,{ignoreForLoopInit:!0}],"eslint/max-lines":[`error`,{max:2e3,skipBlankLines:!0,skipComments:!0}],"eslint/max-lines-per-function":[`error`,{max:120,skipBlankLines:!0,skipComments:!0}],"eslint/complexity":`error`,"eslint/max-params":[`error`,{max:5}],"eslint/max-statements":[`error`,50],"eslint/no-console":[`error`,{allow:[`warn`,`error`,`info`]}],"eslint/no-warning-comments":[`error`,{terms:[`todo`,`fixme`,`xxx`,`hack`],location:`start`}],"eslint/no-param-reassign":`error`,"eslint/no-underscore-dangle":[`error`,{allow:[`__memoryInsightCardApplied`,`__memoryTdaiCardApplied`,`__sessionRescueApplied`,`__wukilDevToolsCardApplied`]}],"eslint/no-magic-numbers":`off`,"eslint/sort-keys":`off`,"eslint/sort-imports":`off`,"eslint/capitalized-comments":`off`,"eslint/no-ternary":`off`,"eslint/no-undefined":`off`,"eslint/no-void":`off`,"eslint/no-duplicate-imports":`off`,"eslint/require-await":`off`,"import/no-named-export":`off`,"import/group-exports":`off`,"import/exports-last":`off`,"import/prefer-default-export":`off`,"import/no-nodejs-modules":`off`,"import/no-relative-parent-imports":`off`,"import/max-dependencies":`off`,"import/no-default-export":`off`,"import/no-anonymous-default-export":`off`,"import/no-named-as-default-member":`off`,"import/consistent-type-specifier-style":[`error`,`prefer-top-level`],"import/no-duplicates":`error`,"import/no-cycle":`error`,"import/named":`error`,"import/first":`error`,"import/newline-after-import":`error`,"node/no-process-env":`off`,"node/no-sync":[`error`,{ignores:a}],"node/no-top-level-await":`error`,"oxc/no-async-await":`off`,"oxc/no-optional-chaining":`off`,"oxc/no-rest-spread-properties":`off`,"promise/always-return":`error`,"promise/no-promise-in-callback":[`error`,{exemptDeclarations:!0}],"promise/no-return-wrap":`error`,"promise/param-names":`error`,"promise/prefer-await-to-then":`error`,"typescript/consistent-type-imports":[`error`,{disallowTypeAnnotations:!1}],"typescript/explicit-function-return-type":[`error`,{allowDirectConstAssertionInArrowFunctions:!0,allowExpressions:!0,allowHigherOrderFunctions:!0,allowIIFEs:!0,allowTypedFunctionExpressions:!0,allowedNames:[`handler`,`callback`]}],"typescript/no-explicit-any":`error`,"typescript/no-floating-promises":`error`,"typescript/no-unsafe-assignment":`error`,"typescript/no-unsafe-type-assertion":`error`,"typescript/no-non-null-assertion":`error`,"typescript/require-await":`error`,"typescript/prefer-readonly-parameter-types":`off`,"typescript/promise-function-async":[`error`,{checkArrowFunctions:!1}],"typescript/consistent-return":[`error`,{treatUndefinedAsUnspecified:!0}],"typescript/only-throw-error":`error`,"unicorn/no-array-reduce":[`error`,{allowSimpleOperations:!0}],"unicorn/no-null":`off`,"unicorn/no-useless-undefined":[`error`,{checkArguments:!1}],"react/set-state-in-effect":`off`,"react/no-deriving-state-in-effects":`off`,"react/exhaustive-effect-dependencies":`off`,"react/hooks":`off`,"react/refs":`off`,"react/todo":`off`,...m,...h,...g,...Object.fromEntries(b.map(e=>[e,`off`]))},C=[`**/*.test.ts`,`**/*.test.tsx`],w=[`**/__tests__/**/*.spec.ts`,`**/test/**/*.spec.ts`],T={files:[...C,`**/test/**`,`**/__tests__/**`],rules:{"typescript/no-non-null-assertion":`off`,"typescript/no-unsafe-type-assertion":`off`,"typescript/no-explicit-any":`off`,"typescript/require-await":`off`,"eslint/max-statements":`off`,"eslint/max-lines":`off`,"eslint/max-lines-per-function":`off`,"node/no-top-level-await":`off`,"regexp/no-super-linear-backtracking":`off`}},E={files:[`lib/**`,`src/**`,`host.ts`,`cli-main.ts`],rules:{"e18e/prefer-static-regex":`error`}},D=[`expect`,`expectTypeOf`,`assert`,`assertType`],O=/^[A-Za-z_$][\w$]*$/u,k={files:[...C,...w],rules:{...Object.fromEntries(b.filter(e=>!x.has(e)).map(e=>[e,`error`])),"vitest/expect-expect":[`error`,{assertFunctionNames:D}],"react/rules-of-hooks":`off`}};function A(e={}){let t=e.assertionHelpers??[],n=e.titlePrefixes??[],r=[...t,...n].filter(e=>!O.test(e));if(r.length>0)throw Error(`assertionHelpers / titlePrefixes 只收裸标识符,不接受通配或带点形式(前者等于让 vitest/expect-expect 失去作用):${r.join(`, `)}`);let i=[.../* @__PURE__ */ new Set([...D,...t])];return{...k,rules:{...k.rules,"vitest/expect-expect":[`error`,{assertFunctionNames:i}],...n.length===0?{}:{"vitest/prefer-lowercase-title":[`error`,{allowedPrefixes:[...new Set(n)]}]}}}}const j={files:[`scripts/**`,`*.mjs`,`*.mts`],rules:{"eslint/no-continue":`off`,"unicorn/max-nested-calls":`off`,"eslint/id-length":[`error`,{exceptions:[`a`,`i`,`t`,`x`,`y`,`z`,`n`,`p`,`s`,`v`,`e`,`f`,`ok`,`fs`,`id`]}],"unicorn/no-process-exit":`off`,"unicorn/no-useless-undefined":`off`,"typescript/no-non-null-assertion":`off`,"node/no-sync":`off`,"node/no-top-level-await":`off`,"e18e/ban-dependencies":`off`,"typescript/no-unsafe-member-access":`off`,"typescript/no-unsafe-call":`off`,"typescript/no-unsafe-assignment":`off`,"typescript/no-unsafe-return":`off`,"typescript/no-unsafe-argument":`off`,"typescript/strict-boolean-expressions":`off`,"typescript/no-implied-eval":`off`,"typescript/require-array-sort-compare":`off`}};function M(e){let t={...r,...e};return e=>{let n=t[e];if(n!==void 0)return n;let r=e.indexOf(`/`);return r===-1?void 0:t[`${e.slice(0,r)}/*`]}}function N(e,t,n){if(t===void 0)return;let r=[];for(let[e,i]of Object.entries(t))if((Array.isArray(i)?i[0]:i)===`off`){let t=n(e);(t===void 0||t.note.trim().length===0)&&r.push(e)}if(r.length>0)throw Error(`${e} 里这些规则被关成 off 但没有依据(OFF_JUSTIFICATIONS 查不到,或 note 为空):${r.join(`, `)}。要么在代码里修,要么给它补一条 kind + measured + note。`)}function P(e={}){let{syncIoScopes:n=[],extraRules:r={},extraOverrides:i=[],extraIgnorePatterns:s=[],jsPlugins:c,offReasons:l={},assertionHelpers:u=[],titlePrefixes:d=[]}=e,m=M(l),h={...S,...p,...r},g=n.map((e,t)=>{if(e.files.length===0||e.apis.length===0)throw Error(`syncIoScopes[${String(t)}] 要 files 与 apis 同时非空,否则这条 override 是死配置。`);return{files:[...e.files],rules:{"node/no-sync":[`error`,{ignores:[.../* @__PURE__ */ new Set([...a,...e.apis])]}]}}}),b=[T,A({assertionHelpers:u,titlePrefixes:d}),j,E,...g,...i];N(`rules`,h,m);for(let[e,t]of b.entries())N(`overrides[${e}]`,t.rules,m);return t({plugins:o,env:{node:!0,es2024:!0,browser:!0},options:v,categories:_,ignorePatterns:[...y,...s],jsPlugins:f(c),rules:h,overrides:b})}export{S as BASE_RULES,g as E18E_RULES,r as OFF_JUSTIFICATIONS,E as PROD_OVERRIDES,a as READONLY_SYNC_ALLOWLIST,m as REGEXP_RULES,i as RETIRED_OFFS,j as SCRIPTS_OVERRIDES,k as TEST_FILE_OVERRIDES,T as TEST_OVERRIDES,b as VITEST_ALL_RULES,D as VITEST_ASSERTION_DEFAULTS,h as ZOD_RULES,P as definePluginConfig,A as makeTestFileOverrides,f as resolveBundledJsPlugins,d as resolveJsPlugins};
|
|
@@ -202,8 +202,29 @@ export interface TestFileOverridesOptions {
|
|
|
202
202
|
*/
|
|
203
203
|
export declare function makeTestFileOverrides(opts?: TestFileOverridesOptions): OxlintOverride;
|
|
204
204
|
export declare const SCRIPTS_OVERRIDES: OxlintOverride;
|
|
205
|
+
/**
|
|
206
|
+
* 一条按文件生效的同步 API 豁免。
|
|
207
|
+
*
|
|
208
|
+
* `files` 是 oxlint 的 override 匹配式(包内相对路径),`apis` 是这些文件里除基线只读名单之外
|
|
209
|
+
* 还允许出现的同步方法名 —— 名单不外溢:同包里另一个文件用同一个 API 照样报。
|
|
210
|
+
*/
|
|
211
|
+
export interface SyncIoScope {
|
|
212
|
+
readonly files: readonly string[];
|
|
213
|
+
readonly apis: readonly string[];
|
|
214
|
+
}
|
|
205
215
|
export interface PluginLintOptions {
|
|
206
|
-
|
|
216
|
+
/**
|
|
217
|
+
* 同步 API 的**文件级**豁免,一枚 scope 对应一条 override。
|
|
218
|
+
*
|
|
219
|
+
* 换掉的是早前的包级扁平名单 `syncWrites`:那张表把 `writeFileSync` / `rmSync` 登记进去之后,
|
|
220
|
+
* 整个包任何位置的同步写都不再报,而配套注释写的是「谁用谁声明」—— 结构与说法不是一回事。
|
|
221
|
+
* 这里让豁免跟着 `files` 生效。
|
|
222
|
+
*
|
|
223
|
+
* 生成的 override 必须自带基线只读名单:oxlint 对同一条规则在 override 里是**整条设置替换**,
|
|
224
|
+
* 实测(oxlint 1.90)override 只写 `ignores: ["readFileSync"]` 时,基线豁免过的 `existsSync`
|
|
225
|
+
* 在那个文件里就变成了报的。
|
|
226
|
+
*/
|
|
227
|
+
syncIoScopes?: SyncIoScope[];
|
|
207
228
|
extraRules?: RuleTable;
|
|
208
229
|
extraOverrides?: OxlintOverride[];
|
|
209
230
|
extraIgnorePatterns?: string[];
|
package/package.json
CHANGED