@linkdesk/plugin-sdk 0.1.32 → 0.1.34
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/dist/eslint/checks/appearance-ownership.d.ts +4 -3
- package/dist/eslint/checks/appearance-ownership.d.ts.map +1 -1
- package/dist/eslint/checks/appearance-ownership.js +22 -14
- package/dist/eslint/checks/appearance-ownership.js.map +1 -1
- package/dist/eslint/checks/appearance-ownership.test.d.ts +2 -0
- package/dist/eslint/checks/appearance-ownership.test.d.ts.map +1 -0
- package/dist/eslint/checks/appearance-ownership.test.js +348 -0
- package/dist/eslint/checks/appearance-ownership.test.js.map +1 -0
- package/dist/eslint/checks/command-ownership.d.ts +11 -1
- package/dist/eslint/checks/command-ownership.d.ts.map +1 -1
- package/dist/eslint/checks/command-ownership.js +10 -4
- package/dist/eslint/checks/command-ownership.js.map +1 -1
- package/dist/eslint/checks/command-ownership.test.d.ts +2 -0
- package/dist/eslint/checks/command-ownership.test.d.ts.map +1 -0
- package/dist/eslint/checks/command-ownership.test.js +207 -0
- package/dist/eslint/checks/command-ownership.test.js.map +1 -0
- package/dist/eslint/checks/config-ownership.d.ts +3 -3
- package/dist/eslint/checks/config-ownership.d.ts.map +1 -1
- package/dist/eslint/checks/config-ownership.js +15 -11
- package/dist/eslint/checks/config-ownership.js.map +1 -1
- package/dist/eslint/checks/config-ownership.test.d.ts +2 -0
- package/dist/eslint/checks/config-ownership.test.d.ts.map +1 -0
- package/dist/eslint/checks/config-ownership.test.js +252 -0
- package/dist/eslint/checks/config-ownership.test.js.map +1 -0
- package/dist/eslint/checks/context-ownership.d.ts +74 -0
- package/dist/eslint/checks/context-ownership.d.ts.map +1 -0
- package/dist/eslint/checks/context-ownership.js +177 -0
- package/dist/eslint/checks/context-ownership.js.map +1 -0
- package/dist/eslint/checks/context-ownership.test.d.ts +2 -0
- package/dist/eslint/checks/context-ownership.test.d.ts.map +1 -0
- package/dist/eslint/checks/context-ownership.test.js +205 -0
- package/dist/eslint/checks/context-ownership.test.js.map +1 -0
- package/dist/eslint/checks/disable.d.ts +5 -0
- package/dist/eslint/checks/disable.d.ts.map +1 -1
- package/dist/eslint/checks/disable.js +5 -0
- package/dist/eslint/checks/disable.js.map +1 -1
- package/dist/eslint/checks/plugin-prefix.test.d.ts +2 -0
- package/dist/eslint/checks/plugin-prefix.test.d.ts.map +1 -0
- package/dist/eslint/checks/plugin-prefix.test.js +229 -0
- package/dist/eslint/checks/plugin-prefix.test.js.map +1 -0
- package/dist/eslint/checks/reserved-classes.test.d.ts +2 -0
- package/dist/eslint/checks/reserved-classes.test.d.ts.map +1 -0
- package/dist/eslint/checks/reserved-classes.test.js +122 -0
- package/dist/eslint/checks/reserved-classes.test.js.map +1 -0
- package/dist/eslint/checks/selector-form.test.d.ts +2 -0
- package/dist/eslint/checks/selector-form.test.d.ts.map +1 -0
- package/dist/eslint/checks/selector-form.test.js +211 -0
- package/dist/eslint/checks/selector-form.test.js.map +1 -0
- package/dist/eslint/checks/token-scope.test.d.ts +2 -0
- package/dist/eslint/checks/token-scope.test.d.ts.map +1 -0
- package/dist/eslint/checks/token-scope.test.js +185 -0
- package/dist/eslint/checks/token-scope.test.js.map +1 -0
- package/dist/eslint/index.d.ts +12 -0
- package/dist/eslint/index.d.ts.map +1 -1
- package/dist/eslint/index.js +11 -0
- package/dist/eslint/index.js.map +1 -1
- package/dist/eslint/lint.d.ts +17 -0
- package/dist/eslint/lint.d.ts.map +1 -1
- package/dist/eslint/lint.js +64 -13
- package/dist/eslint/lint.js.map +1 -1
- package/dist/pack.test.d.ts +2 -0
- package/dist/pack.test.d.ts.map +1 -0
- package/dist/pack.test.js +58 -0
- package/dist/pack.test.js.map +1 -0
- package/dist/publish.test.d.ts +2 -0
- package/dist/publish.test.d.ts.map +1 -0
- package/dist/publish.test.js +340 -0
- package/dist/publish.test.js.map +1 -0
- package/dist/validate.test.d.ts +2 -0
- package/dist/validate.test.d.ts.map +1 -0
- package/dist/validate.test.js +107 -0
- package/dist/validate.test.js.map +1 -0
- package/package.json +68 -68
- package/schemas/host-reserved.json +9 -6
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-css-namespace 腿 单测——**@keyframes 名不得撞宿主保留关键帧名**。
|
|
3
|
+
*
|
|
4
|
+
* 为什么值得一条测试:这条腿的错法同样是**静默**的——关键帧撞名在界面上只表现成「动画不对」,
|
|
5
|
+
* 不报错;而不查/误报又会让插件仓 CI 白红。故正反两向都钉住。
|
|
6
|
+
*
|
|
7
|
+
* ── 🔴 判据①「裸定义宿主保留类名」已退役(E6#109p-b · 轮次 1.28 · 2026-09-16)──
|
|
8
|
+
* 退役记录写在这里(连同一条**退役钉子**测试:留 `classes` 字段也不再生效):
|
|
9
|
+
* 1.27 全量门禁体检实测(`docs/02-Electron架构/E6_插件生态与发布/01-插件独立构建/样式命名空间归一化/27-任务-门禁健康度体检.md` §十二.2(a)):
|
|
10
|
+
* · 清单的 `classes` 段**已随 E6#109l-b(1.21b)整块删除** ⇒ `classMap` 恒空 ⇒ 判据想报也报不出来;
|
|
11
|
+
* · 同一轴上 `plugin-prefix.ts` 的「裸定义必须带 `<pluginId>-`」**完全覆盖**它;
|
|
12
|
+
* · `classes` 段是**终态删除**(类名规则已结构性化,登记表只剩 `keyframes`)⇒ 输入不会回来。
|
|
13
|
+
* ⇒ 代码路径 + `ReservedNames.classes` 字段一并删除。**判据② 保留**:拿不到 pluginId 时前缀腿
|
|
14
|
+
* fail-closed,此时本腿是唯一能逐点报出「你占了宿主关键帧名」的腿(1.27 实验 (d) 实证)。
|
|
15
|
+
*/
|
|
16
|
+
import { describe, expect, it } from "vitest";
|
|
17
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
18
|
+
import { tmpdir } from "node:os";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import { runReservedClassCheck, loadReservedNames } from "./reserved-classes.js";
|
|
21
|
+
const RESERVED = {
|
|
22
|
+
keyframes: [{ name: "ldk-selectbox-in", why: "共享组件下拉入场" }],
|
|
23
|
+
};
|
|
24
|
+
function withFixture(css, fn) {
|
|
25
|
+
const root = mkdtempSync(join(tmpdir(), "ldk-reserved-"));
|
|
26
|
+
mkdirSync(join(root, "src"), { recursive: true });
|
|
27
|
+
writeFileSync(join(root, "src", "style.css"), css, "utf8");
|
|
28
|
+
try {
|
|
29
|
+
fn(root);
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
rmSync(root, { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
describe("runReservedClassCheck —— 正控(不许误伤)", () => {
|
|
36
|
+
it("带插件前缀的类名 ⇒ 零违规", () => {
|
|
37
|
+
withFixture(".my-plugin-card { color: red; }\n.my-plugin-title { color: blue; }\n", (root) => {
|
|
38
|
+
expect(runReservedClassCheck(root, RESERVED)).toHaveLength(0);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
it("scoped 调优(.my-bar .badge)⇒ 零违规", () => {
|
|
42
|
+
withFixture(".my-bar .badge { margin-left: 4px; }\n", (root) => {
|
|
43
|
+
expect(runReservedClassCheck(root, RESERVED)).toHaveLength(0);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it("复合状态类不占名(.my-card.active)⇒ 零违规", () => {
|
|
47
|
+
withFixture(".my-card.active { border-color: var(--accent); }\n", (root) => {
|
|
48
|
+
expect(runReservedClassCheck(root, RESERVED)).toHaveLength(0);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
it("带前缀的关键帧(本仓自己的)⇒ 零违规", () => {
|
|
52
|
+
withFixture("@keyframes probe-demo-fadeIn { from { opacity: 0 } }\n", (root) => {
|
|
53
|
+
expect(runReservedClassCheck(root, RESERVED)).toHaveLength(0);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
it("保留名清单为空 ⇒ 不产生任何违规(文件缺失时不假装有判据)", () => {
|
|
57
|
+
withFixture("@keyframes ldk-selectbox-in { from { opacity: 0 } }\n", (root) => {
|
|
58
|
+
expect(runReservedClassCheck(root, { keyframes: [] })).toHaveLength(0);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe("runReservedClassCheck —— 负控(必红)", () => {
|
|
63
|
+
it("@keyframes 撞宿主关键帧名 ⇒ 红,且报出文件名与名字", () => {
|
|
64
|
+
withFixture("@keyframes ldk-selectbox-in { from { opacity: 0 } }\n", (root) => {
|
|
65
|
+
const v = runReservedClassCheck(root, RESERVED);
|
|
66
|
+
expect(v).toHaveLength(1);
|
|
67
|
+
expect(v[0].file).toBe("src/style.css");
|
|
68
|
+
expect(v[0].message).toContain("ldk-selectbox-in");
|
|
69
|
+
expect(v[0].message).toContain("与宿主关键帧同名");
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
it("注释里的关键帧名不算违规(判据只看真实规则)", () => {
|
|
73
|
+
withFixture("/* 注意:别用 @keyframes ldk-selectbox-in */\n.my-card { color: red; }\n", (root) => {
|
|
74
|
+
expect(runReservedClassCheck(root, RESERVED)).toHaveLength(0);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe("🔴 判据① 退役钉子(E6#109p-b · 1.28)", () => {
|
|
79
|
+
it("裸定义 `.badge` **不再**由本腿报(退役后它只由前缀腿那条结构性判据管)", () => {
|
|
80
|
+
withFixture(".badge { color: red; }\n.input { padding: 2px; }\n", (root) => {
|
|
81
|
+
// 退役前这两行各报 1 条(夹具清单里给过 badge/input);退役后本腿一条都不报。
|
|
82
|
+
expect(runReservedClassCheck(root, RESERVED)).toHaveLength(0);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
it("清单里就算还留着历史的 `classes` 键 ⇒ 也一律忽略(输入不会回来)", () => {
|
|
86
|
+
const root = mkdtempSync(join(tmpdir(), "ldk-reserved-"));
|
|
87
|
+
const file = join(root, "reserved-class-names.json");
|
|
88
|
+
writeFileSync(file, JSON.stringify({
|
|
89
|
+
classes: { shared: [{ name: "demo-shared", why: "夹具——历史遗留" }], host: [{ name: "demo-host", why: "夹具" }] },
|
|
90
|
+
keyframes: [{ name: "demo-keyframe", why: "夹具" }],
|
|
91
|
+
}), "utf8");
|
|
92
|
+
try {
|
|
93
|
+
const names = loadReservedNames(file);
|
|
94
|
+
expect("classes" in names).toBe(false); // 字段已删(不再读、不再暴露)
|
|
95
|
+
expect(names.keyframes.map((k) => k.name)).toEqual(["demo-keyframe"]);
|
|
96
|
+
mkdirSync(join(root, "src"), { recursive: true });
|
|
97
|
+
writeFileSync(join(root, "src", "style.css"), ".demo-shared { color: red; }\n", "utf8");
|
|
98
|
+
expect(runReservedClassCheck(root, names)).toHaveLength(0);
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
rmSync(root, { recursive: true, force: true });
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe("runReservedClassCheck —— 知情绕行", () => {
|
|
106
|
+
it("标准 disable 注释 ⇒ 该行豁免", () => {
|
|
107
|
+
withFixture("/* eslint-disable-next-line linkdesk/no-reserved-class-name -- 内容画布:随宿主动画走 */\n" +
|
|
108
|
+
"@keyframes ldk-selectbox-in { from { opacity: 0 } }\n", (root) => {
|
|
109
|
+
expect(runReservedClassCheck(root, RESERVED)).toHaveLength(0);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
describe("loadReservedNames —— 随包清单可读", () => {
|
|
114
|
+
it("包内 schemas/reserved-class-names.json 能被读到(只剩 keyframes;classes 段是终态删除)", () => {
|
|
115
|
+
const names = loadReservedNames();
|
|
116
|
+
// 🔴 E6#109p-b(1.28):`classes` 整块早在 E6#109l-b 就从清单删了 ⇒ 本轮连**读它的代码**一起退役。
|
|
117
|
+
// 反向断言仍有意为之:谁把 `classes` 加回清单(或加回字段)⇒ 这条当场红,逼一次知情决策。
|
|
118
|
+
expect(names.keyframes.map((k) => k.name)).toContain("ldk-selectbox-in");
|
|
119
|
+
expect("classes" in names).toBe(false);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=reserved-classes.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reserved-classes.test.js","sourceRoot":"","sources":["../../../src/eslint/checks/reserved-classes.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector-form.test.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/selector-form.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-css-namespace 腿·**选择器形态判据**(E6#109o-b · 1.26)单测。
|
|
3
|
+
*
|
|
4
|
+
* 覆盖 32 号档 §三.3 的插件侧那一表:负控①–⑦ + 正控①–⑤(**正控条数 ≥ 负控条数**的纪律下面
|
|
5
|
+
* 又补了三条,见文件末的「补充正控」)。
|
|
6
|
+
*
|
|
7
|
+
* 为什么值得一条测试(沿用 `token-scope.test.ts` 的理由):这条腿**两条失效方向都是静默的**——
|
|
8
|
+
* · 太松(放过一条 `button { }`)⇒ 它改掉宿主与其他插件**所有**按钮,表现是「某个页面某个控件
|
|
9
|
+
* 看着不对」,而**任何日志都不会响**(这就是本系列一句话根因:不是问题在长大,是尺子一直在漏);
|
|
10
|
+
* · 太紧(把 `.my-root :focus-visible { }` 判成无锚)⇒ **假红**,而假红会让真红失效
|
|
11
|
+
* (22 号档 §10.3):作者学会「看到红就 disable」,门禁失效。
|
|
12
|
+
* 🔴 这条正是 1.25 实测的 **F3**:`hasAncestor()` / `subjectOf()` 会把 `.x :pseudo` 误判成
|
|
13
|
+
* `.x` 的一次**顶层定义** ⇒ 本轴自带 `formOf()`,下面「正控②」就是它的反面钉子。
|
|
14
|
+
*/
|
|
15
|
+
import { describe, expect, it } from "vitest";
|
|
16
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
17
|
+
import { tmpdir } from "node:os";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { runSelectorFormCheck, judgeSelectorForm } from "./selector-form.js";
|
|
20
|
+
import { formOf } from "./css-selectors.js";
|
|
21
|
+
/** 造一个临时插件工程(`manifest` 传 null ⇒ 不写 plugin.json,用来钉 fail-closed) */
|
|
22
|
+
function withPlugin(opts, fn) {
|
|
23
|
+
const base = mkdtempSync(join(tmpdir(), "css-selector-form-"));
|
|
24
|
+
const root = opts.dirName ? join(base, opts.dirName) : base;
|
|
25
|
+
mkdirSync(join(root, "src", "styles"), { recursive: true });
|
|
26
|
+
if (opts.manifest !== null) {
|
|
27
|
+
const raw = opts.manifest ?? { pluginId: "demo-plugin", name: "夹具", version: "1.0.0" };
|
|
28
|
+
writeFileSync(join(root, "plugin.json"), `{\n // 注释\n ${JSON.stringify(raw).slice(1, -1)},\n}\n`, "utf8");
|
|
29
|
+
}
|
|
30
|
+
if (opts.css !== undefined) {
|
|
31
|
+
writeFileSync(join(root, opts.cssRel ?? join("src", "styles", "App.css")), opts.css, "utf8");
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
fn(root);
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
rmSync(base, { recursive: true, force: true });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
describe("判据 S2:插件禁无锚选择器(元素/通配/属性/伪类/伪元素/id 一视同仁)", () => {
|
|
41
|
+
it("负控①:`* { margin: 0 }` ⇒ S2 红", () => {
|
|
42
|
+
withPlugin({ css: "* { margin: 0; }\n" }, (root) => {
|
|
43
|
+
const r = runSelectorFormCheck(root);
|
|
44
|
+
expect(r.error).toBeNull();
|
|
45
|
+
expect(r.violations).toHaveLength(1);
|
|
46
|
+
expect(r.anchorless[0].code).toBe("S2");
|
|
47
|
+
expect(r.violations[0].file).toBe("src/styles/App.css");
|
|
48
|
+
expect(r.violations[0].line).toBe(1);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
it("负控②:`@media print { button { border: none } }` ⇒ S2 红(**@media 内同样是顶层**)", () => {
|
|
52
|
+
withPlugin({ css: "@media print {\n button { border: none; }\n}\n" }, (root) => {
|
|
53
|
+
const r = runSelectorFormCheck(root);
|
|
54
|
+
expect(r.anchorless).toHaveLength(1);
|
|
55
|
+
expect(r.anchorless[0].selector).toBe("button");
|
|
56
|
+
expect(r.violations[0].line).toBe(2);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
it("负控③:`#some-id { display: none }` ⇒ S2 红(**id 与元素同罪**)", () => {
|
|
60
|
+
withPlugin({ css: "#some-id { display: none; }\n" }, (root) => {
|
|
61
|
+
const r = runSelectorFormCheck(root);
|
|
62
|
+
expect(r.anchorless).toHaveLength(1);
|
|
63
|
+
expect(r.anchorless[0].code).toBe("S2");
|
|
64
|
+
expect(r.anchorless[0].form.kind).toBe("anchored"); // id 是**名字锚** ⇒ 形态上是 anchored
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
it("负控③b:限定形态 `html #some-id { }` 同样红(id 在复合里也算)", () => {
|
|
68
|
+
withPlugin({ css: "html #some-id { display: none; }\n" }, (root) => {
|
|
69
|
+
expect(runSelectorFormCheck(root).anchorless).toHaveLength(1);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
it("负控④:`:root { --x: 1 }` ⇒ S2 红(无锚;也命中 token 腿,允许双报)", () => {
|
|
73
|
+
withPlugin({ css: ":root { --x: 1; }\n" }, (root) => {
|
|
74
|
+
const r = runSelectorFormCheck(root);
|
|
75
|
+
expect(r.anchorless).toHaveLength(1);
|
|
76
|
+
expect(r.anchorless[0].selector).toBe(":root");
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
it("负控④b:纯伪元素形态 `::-webkit-scrollbar { }` 也是站点(1.25 的 F1 钉子)", () => {
|
|
80
|
+
withPlugin({ css: "::-webkit-scrollbar { width: 4px; }\n" }, (root) => {
|
|
81
|
+
const r = runSelectorFormCheck(root);
|
|
82
|
+
expect(r.anchorless).toHaveLength(1);
|
|
83
|
+
expect(r.anchorless[0].form.purePseudo).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
it("负控⑦:拿不到 `pluginId`(无 plugin.json)⇒ fail-closed 红(与 `plugin-prefix.ts` 同款)", () => {
|
|
87
|
+
withPlugin({ manifest: null, css: "* { margin: 0; }\n" }, (root) => {
|
|
88
|
+
const r = runSelectorFormCheck(root);
|
|
89
|
+
expect(r.error).not.toBeNull();
|
|
90
|
+
expect(r.violations).toHaveLength(1);
|
|
91
|
+
expect(r.violations[0].file).toBe("plugin.json");
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
describe("判据 S3:跨方命中必须自带自有命名空间", () => {
|
|
96
|
+
it("负控⑤:`body .ldk-input { }` ⇒ S3 红(跨方命中 + 无自有锚)", () => {
|
|
97
|
+
withPlugin({ css: "body .ldk-input { height: 20px; }\n" }, (root) => {
|
|
98
|
+
const r = runSelectorFormCheck(root);
|
|
99
|
+
expect(r.anchorless).toHaveLength(0);
|
|
100
|
+
expect(r.crossParty).toHaveLength(1);
|
|
101
|
+
expect(r.crossParty[0].code).toBe("S3");
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
it("负控⑥:`.ldk-side-panel :focus-visible { outline: none }` ⇒ S3 红(🔴 F3 的钉子)", () => {
|
|
105
|
+
// 用 hasAncestor()/subjectOf() 判形态的实现会把这一条**漏掉**(它们剥掉伪类后只剩 `.ldk-side-panel`
|
|
106
|
+
// ⇒ 看起来「有主体、无祖先」⇒ 被当成一次顶层定义)——`formOf()` 认它有两个 compound ⇒ 形态是
|
|
107
|
+
// anchored ⇒ 交给 S3(跨方命中不带自有锚)来判。**这条就是本轴自带形态口径的理由。**
|
|
108
|
+
withPlugin({ css: ".ldk-side-panel :focus-visible { outline: none; }\n" }, (root) => {
|
|
109
|
+
const r = runSelectorFormCheck(root);
|
|
110
|
+
expect(r.anchorless).toHaveLength(0);
|
|
111
|
+
expect(r.crossParty).toHaveLength(1);
|
|
112
|
+
expect(r.crossParty[0].code).toBe("S3");
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
it("负控⑥b:`:has(.ldk-x)` 内的**提及**算提及;而**主体无锚**时归 S2(`(...)` 内不算锚)", () => {
|
|
116
|
+
// ① `body:has(.ldk-badge)`:`.ldk-badge` 在**过滤器**里 ⇒ 主体是 `body` ⇒ **顶层无锚** ⇒ S2
|
|
117
|
+
// (这正是 R0 的口径:「`(...)` 内的内容不算锚——那是过滤器不是主体」。)
|
|
118
|
+
withPlugin({ css: "body:has(.ldk-badge) { padding: 0; }\n" }, (root) => {
|
|
119
|
+
const r = runSelectorFormCheck(root);
|
|
120
|
+
expect(r.anchorless).toHaveLength(1);
|
|
121
|
+
expect(r.anchorless[0].code).toBe("S2");
|
|
122
|
+
expect(r.crossParty).toHaveLength(0);
|
|
123
|
+
});
|
|
124
|
+
// ② `main .other-root:has(.ldk-badge)`:有名字锚(`.other-root`)但**不是本仓前缀** ⇒ S3
|
|
125
|
+
withPlugin({ css: "main .other-root:has(.ldk-badge) { padding: 0; }\n" }, (root) => {
|
|
126
|
+
const r = runSelectorFormCheck(root);
|
|
127
|
+
expect(r.anchorless).toHaveLength(0);
|
|
128
|
+
expect(r.crossParty).toHaveLength(1);
|
|
129
|
+
expect(r.crossParty[0].selector).toBe("main .other-root:has(.ldk-badge)");
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
describe("正控:合规形态必须绿(正控条数 ≥ 负控条数)", () => {
|
|
134
|
+
it("正控①:`.serial-monitor-root input { }` ⇒ 绿(**限定有锚**——R2 的正确解法)", () => {
|
|
135
|
+
withPlugin({ manifest: { pluginId: "serial-monitor", name: "夹具", version: "1.0.0" }, css: ".serial-monitor-root input { height: 20px; }\n" }, (root) => {
|
|
136
|
+
expect(runSelectorFormCheck(root).violations).toHaveLength(0);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
it("正控②:`.my-root :focus-visible { }` ⇒ 绿(🔴 **F3 反面钉子**:形态谓词必须认它有祖先)", () => {
|
|
140
|
+
withPlugin({ css: ".my-root :focus-visible { outline: 1px solid red; }\n" }, (root) => {
|
|
141
|
+
const r = runSelectorFormCheck(root);
|
|
142
|
+
expect(formOf(".my-root :focus-visible").kind).toBe("anchored");
|
|
143
|
+
expect(r.violations).toHaveLength(0);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
it("正控③:`.settings-slider-control .ldk-slider { }` ⇒ 绿(R3 合规形态:跨方命中 + 自有前缀)", () => {
|
|
147
|
+
withPlugin({ manifest: { pluginId: "settings", name: "夹具", version: "1.0.0" }, css: ".settings-slider-control .ldk-slider { width: 100%; }\n" }, (root) => {
|
|
148
|
+
expect(runSelectorFormCheck(root).violations).toHaveLength(0);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
it("正控④:`.marketplace-mpd-title-row .ldk-badge .codicon { }` ⇒ 绿(主体是三方类,仍带自有锚)", () => {
|
|
152
|
+
withPlugin({ manifest: { pluginId: "marketplace", name: "夹具", version: "1.0.0" }, css: ".marketplace-mpd-title-row .ldk-badge .codicon { font-size: 12px; }\n" }, (root) => {
|
|
153
|
+
expect(runSelectorFormCheck(root).violations).toHaveLength(0);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
it("正控⑤:`.settings-row:has(.ldk-theme-picker) { }` ⇒ 绿(`:has()` 内的提及算提及、自有锚在主体上)", () => {
|
|
157
|
+
withPlugin({ manifest: { pluginId: "settings", name: "夹具", version: "1.0.0" }, css: ".settings-row:has(.ldk-theme-picker) { flex-direction: column; }\n" }, (root) => {
|
|
158
|
+
expect(runSelectorFormCheck(root).violations).toHaveLength(0);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
it("正控⑥:`@keyframes` 体内的 `from` / `to` **不是选择器** ⇒ 绿", () => {
|
|
162
|
+
withPlugin({ css: ".demo-plugin-root { animation: demo-plugin-in 1s; }\n@keyframes demo-plugin-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n" }, (root) => {
|
|
163
|
+
expect(runSelectorFormCheck(root).violations).toHaveLength(0);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
it("正控⑦:多选择器列表里**只报坏的那一份**(`button, .demo-plugin-root { }` ⇒ 1 处)", () => {
|
|
167
|
+
withPlugin({ css: "button,\n.demo-plugin-root { margin: 0; }\n" }, (root) => {
|
|
168
|
+
const r = runSelectorFormCheck(root);
|
|
169
|
+
expect(r.violations).toHaveLength(1);
|
|
170
|
+
expect(r.anchorless[0].selector).toBe("button");
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
it("正控⑧:同一份 CSS + 不同 `pluginId` ⇒ 不同裁决(证明这条腿在读 manifest,不是恒红/恒绿)", () => {
|
|
174
|
+
const css = ".other-ns-root .ldk-badge { color: red; }\n";
|
|
175
|
+
withPlugin({ manifest: { pluginId: "demo-plugin", name: "夹具", version: "1.0.0" }, css }, (root) => {
|
|
176
|
+
expect(runSelectorFormCheck(root).crossParty).toHaveLength(1); // `.other-ns-root` 不是我的前缀 ⇒ 红
|
|
177
|
+
});
|
|
178
|
+
withPlugin({ manifest: { pluginId: "other", name: "夹具", version: "1.0.0" }, css }, (root) => {
|
|
179
|
+
expect(runSelectorFormCheck(root).violations).toHaveLength(0); // `.other-` 就是本仓前缀 ⇒ 绿
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
it("正控⑨:`animation` 声明不是选择器(`animation: button 1s` 不该被当成元素选择器)", () => {
|
|
183
|
+
withPlugin({ css: ".demo-plugin-root { animation: demo-plugin-in 1s; }\n@keyframes demo-plugin-in { to { opacity: 1; } }\n" }, (root) => {
|
|
184
|
+
expect(runSelectorFormCheck(root).violations).toHaveLength(0);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
describe("判定体 `judgeSelectorForm()` 与形态谓词 `formOf()`", () => {
|
|
189
|
+
it("判定体逐条符合预期(六形态 × 两判据)", () => {
|
|
190
|
+
const id = "demo-plugin";
|
|
191
|
+
// 绿:有锚、无 ldk 提及
|
|
192
|
+
expect(judgeSelectorForm({ selector: ".demo-plugin-root .a", pluginId: id })).toBeNull();
|
|
193
|
+
// S2:顶层无锚
|
|
194
|
+
expect(judgeSelectorForm({ selector: "select", pluginId: id })?.code).toBe("S2");
|
|
195
|
+
expect(judgeSelectorForm({ selector: ":focus-visible", pluginId: id })?.code).toBe("S2");
|
|
196
|
+
expect(judgeSelectorForm({ selector: "::-webkit-scrollbar", pluginId: id })?.code).toBe("S2");
|
|
197
|
+
// S2:限定无锚(B 段)
|
|
198
|
+
expect(judgeSelectorForm({ selector: "html body", pluginId: id })?.code).toBe("S2");
|
|
199
|
+
// S3:有锚但跨方命中不带自有锚
|
|
200
|
+
expect(judgeSelectorForm({ selector: ".a .ldk-badge", pluginId: id })?.code).toBe("S3");
|
|
201
|
+
});
|
|
202
|
+
it("`formOf()`:纯伪类/纯伪元素主体 ⇒ 无锚(不是无主体);`.a :focus-visible` 不是顶层无锚(F3 反面)", () => {
|
|
203
|
+
expect(formOf("::-webkit-scrollbar")).toEqual({ kind: "anchorless", top: true, purePseudo: true });
|
|
204
|
+
expect(formOf(":root")).toEqual({ kind: "anchorless", top: true, purePseudo: false });
|
|
205
|
+
expect(formOf("html body")).toEqual({ kind: "anchorless", top: false, purePseudo: false });
|
|
206
|
+
expect(formOf(".a :focus-visible").kind).toBe("anchored");
|
|
207
|
+
expect(formOf("#a").kind).toBe("anchored");
|
|
208
|
+
expect(formOf("div:has(.a)").kind).toBe("anchorless"); // `(...)` 内不算锚(过滤器不是主体)
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
//# sourceMappingURL=selector-form.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector-form.test.js","sourceRoot":"","sources":["../../../src/eslint/checks/selector-form.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-scope.test.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/token-scope.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-css-namespace 腿·**token(自定义属性)作用域判据**(E6#109n-b · 1.24)单测。
|
|
3
|
+
*
|
|
4
|
+
* 覆盖 31 号档 §3.3 负控表的插件侧六条(④–⑨)+ 两条元判据:
|
|
5
|
+
* · **同一份 CSS + 不同 pluginId ⇒ 不同裁决**(证明这条腿在读 manifest,不是恒红/恒绿);
|
|
6
|
+
* · **黄灯不进腿报点**(V6 的「只报不拦」是结构性的,不靠措辞)。
|
|
7
|
+
*
|
|
8
|
+
* 为什么值得一条测试(沿用 `plugin-prefix.test.ts` 的理由):这条腿**两条失效方向都是静默的**——
|
|
9
|
+
* · 太松(放过一处 `:root` 覆写)⇒ 宿主 / 他方的颜色、圆角、z-index 被全局改写,
|
|
10
|
+
* 表现是「切了主题才好、换个主题又坏」(1.23 实测:83/94 个契约名没有 inline 屏蔽);
|
|
11
|
+
* · 太紧(把「自有类之下的裸名」判红)⇒ 插件仓 CI 白红,作者学会「看到红就 disable」,门禁失效。
|
|
12
|
+
*/
|
|
13
|
+
import { describe, expect, it } from "vitest";
|
|
14
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
15
|
+
import { tmpdir } from "node:os";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
import { runTokenScopeCheck } from "./token-scope.js";
|
|
18
|
+
/** 造一个临时插件工程(`manifest` 传 null ⇒ 不写 plugin.json,用来钉 fail-closed) */
|
|
19
|
+
function withPlugin(opts, fn) {
|
|
20
|
+
const base = mkdtempSync(join(tmpdir(), "css-token-scope-"));
|
|
21
|
+
const root = opts.dirName ? join(base, opts.dirName) : base;
|
|
22
|
+
mkdirSync(join(root, "src", "styles"), { recursive: true });
|
|
23
|
+
if (opts.manifest !== null) {
|
|
24
|
+
// JSONC(带注释与尾逗号)——作者面允许这么写,读 manifest 的代码必须容忍
|
|
25
|
+
const raw = opts.manifest ?? { pluginId: "demo-plugin", name: "夹具", version: "1.0.0" };
|
|
26
|
+
writeFileSync(join(root, "plugin.json"), `{\n // 注释\n ${JSON.stringify(raw).slice(1, -1)},\n}\n`, "utf8");
|
|
27
|
+
}
|
|
28
|
+
if (opts.css !== undefined) {
|
|
29
|
+
writeFileSync(join(root, opts.cssRel ?? join("src", "styles", "App.css")), opts.css, "utf8");
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
fn(root);
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
rmSync(base, { recursive: true, force: true });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
describe("判据 V1:插件在文档级定义「无主」名字 ⇒ 红", () => {
|
|
39
|
+
it("负控④:`:root { --bg-card: red }`(`marketplace` 案复刻)⇒ V1 红 + 进腿报点", () => {
|
|
40
|
+
withPlugin({ css: ":root { --bg-card: red; }\n" }, (root) => {
|
|
41
|
+
const r = runTokenScopeCheck(root);
|
|
42
|
+
expect(r.error).toBeNull();
|
|
43
|
+
expect(r.red).toHaveLength(1);
|
|
44
|
+
expect(r.red[0].code).toBe("V1");
|
|
45
|
+
expect(r.red[0].scope).toBe("doc");
|
|
46
|
+
expect(r.violations).toHaveLength(1);
|
|
47
|
+
expect(r.violations[0].file).toBe("src/styles/App.css");
|
|
48
|
+
expect(r.violations[0].line).toBe(1);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
it("负控⑤:`:root { --other-plugin-ok: red }`(带前缀但**不是我的**前缀)⇒ V1 红", () => {
|
|
52
|
+
withPlugin({ css: ":root { --other-plugin-ok: red; }\n" }, (root) => {
|
|
53
|
+
const r = runTokenScopeCheck(root);
|
|
54
|
+
expect(r.red).toHaveLength(1);
|
|
55
|
+
expect(r.red[0].code).toBe("V1");
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
it("文档级各形态都算文档级(`html` / `body` / `*` / `[data-theme=…]`)", () => {
|
|
59
|
+
withPlugin({ css: "html { --a: 1; }\nbody { --b: 1; }\n* { --c: 1; }\n[data-theme=\"dark\"] { --d: 1; }\n" }, (root) => {
|
|
60
|
+
expect(runTokenScopeCheck(root).red).toHaveLength(4);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
it("正控:按 `@media` 包裹不改变裁决(同一个文档级定义照样红)", () => {
|
|
64
|
+
withPlugin({ css: "@media (min-width: 100px) {\n :root { --a: 1; }\n}\n" }, (root) => {
|
|
65
|
+
expect(runTokenScopeCheck(root).red).toHaveLength(1);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe("判据 V6:插件在文档级定义「有主」名字 ⇒ 🟡 黄(只报不拦)", () => {
|
|
70
|
+
it("负控⑥:`:root { --demo-plugin-ok: red }` ⇒ **不红**(黄,且**不进腿报点**)", () => {
|
|
71
|
+
withPlugin({ css: ":root { --demo-plugin-ok: red; }\n" }, (root) => {
|
|
72
|
+
const r = runTokenScopeCheck(root);
|
|
73
|
+
expect(r.red).toHaveLength(0);
|
|
74
|
+
expect(r.violations).toHaveLength(0); // 🔴 「只报不拦」是结构性的:黄不进 legs.violations
|
|
75
|
+
expect(r.yellow).toHaveLength(1);
|
|
76
|
+
expect(r.yellow[0].code).toBe("V6");
|
|
77
|
+
expect(r.advisories).toHaveLength(1);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
it("正控:把同一个名字搬进自有根类 ⇒ 黄也没有(完全合规)", () => {
|
|
81
|
+
withPlugin({ css: ".demo-plugin-root { --demo-plugin-ok: red; }\n" }, (root) => {
|
|
82
|
+
const r = runTokenScopeCheck(root);
|
|
83
|
+
expect(r.red).toHaveLength(0);
|
|
84
|
+
expect(r.yellow).toHaveLength(0);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
describe("判据 V2:定义 `ldk-*` 自定义属性 ⇒ 红(任何作用域)", () => {
|
|
89
|
+
it("顶层 `.ldk-badge { --ldk-x: 1 }` ⇒ V2 红(名字层先出口)", () => {
|
|
90
|
+
withPlugin({ css: ".ldk-badge { --ldk-x: 1; }\n" }, (root) => {
|
|
91
|
+
const r = runTokenScopeCheck(root);
|
|
92
|
+
expect(r.red).toHaveLength(1);
|
|
93
|
+
expect(r.red[0].code).toBe("V2");
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
it("`:root { --ldk-x: 1 }` ⇒ V2 红(同一站点同时命中 V2/V1 ⇒ 只报最具体的一条)", () => {
|
|
97
|
+
withPlugin({ css: ":root { --ldk-x: 1; }\n" }, (root) => {
|
|
98
|
+
const r = runTokenScopeCheck(root);
|
|
99
|
+
expect(r.red).toHaveLength(1);
|
|
100
|
+
expect(r.red[0].code).toBe("V2");
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
it("自有类之下写 `--ldk-x` **照样红**(V2 与作用域无关)", () => {
|
|
104
|
+
withPlugin({ css: ".demo-plugin-root { --ldk-x: 1; }\n" }, (root) => {
|
|
105
|
+
expect(runTokenScopeCheck(root).red.some((s) => s.code === "V2")).toBe(true);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe("判据 V5:类限定定义不含自有类 ⇒ 红", () => {
|
|
110
|
+
it("负控⑦:顶层 `.ldk-badge { --my-x: 1 }`(借宿主类当自己的地盘)⇒ V5 红", () => {
|
|
111
|
+
withPlugin({ css: ".ldk-badge { --my-x: 1; }\n" }, (root) => {
|
|
112
|
+
const r = runTokenScopeCheck(root);
|
|
113
|
+
expect(r.red).toHaveLength(1);
|
|
114
|
+
expect(r.red[0].code).toBe("V5");
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
it("正控:`.demo-plugin-root .ldk-badge { --my-x: 1 }` ⇒ 绿(scoped 调优合法)", () => {
|
|
118
|
+
withPlugin({ css: ".demo-plugin-root .ldk-badge { --my-x: 1; }\n" }, (root) => {
|
|
119
|
+
const r = runTokenScopeCheck(root);
|
|
120
|
+
expect(r.red).toHaveLength(0);
|
|
121
|
+
expect(r.yellow).toHaveLength(0);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
it("正控⑨:自有根类下的**裸名** ⇒ 绿(名字无前缀不构成违规——只有「文档级 + 无主」才红)", () => {
|
|
125
|
+
withPlugin({ css: ".demo-plugin-root { --ok-color: 1; }\n" }, (root) => {
|
|
126
|
+
expect(runTokenScopeCheck(root).red).toHaveLength(0);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
it("正控:自有类**在祖先位**也满足(`.demo-plugin-a .demo-plugin-b { --x: 1 }`)⇒ 绿", () => {
|
|
130
|
+
withPlugin({ css: ".demo-plugin-a .demo-plugin-b { --x: 1; }\n" }, (root) => {
|
|
131
|
+
expect(runTokenScopeCheck(root).red).toHaveLength(0);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
it("正控:`id` 与元素/属性形态不在本轴射程(`#demo-plugin-root` / `div` / `[data-x]`)", () => {
|
|
135
|
+
withPlugin({ css: "#demo-plugin-root { --a: 1; }\ndiv { --b: 1; }\n[data-x] { --c: 1; }\n" }, (root) => {
|
|
136
|
+
const r = runTokenScopeCheck(root);
|
|
137
|
+
expect(r.red).toHaveLength(0);
|
|
138
|
+
expect(r.yellow).toHaveLength(0);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
describe("元判据:读 manifest(不是恒红/恒绿)+ fail-closed + 口径", () => {
|
|
143
|
+
it("同一份 CSS + 不同 pluginId ⇒ 不同裁决(证明这条腿真在读本仓 manifest)", () => {
|
|
144
|
+
const css = ":root { --alpha-ok: 1; }\n";
|
|
145
|
+
withPlugin({ manifest: { pluginId: "alpha", name: "a", version: "1.0.0" }, css }, (root) => {
|
|
146
|
+
expect(runTokenScopeCheck(root).yellow.map((s) => s.code)).toEqual(["V6"]);
|
|
147
|
+
});
|
|
148
|
+
withPlugin({ manifest: { pluginId: "beta", name: "b", version: "1.0.0" }, css }, (root) => {
|
|
149
|
+
expect(runTokenScopeCheck(root).red.map((s) => s.code)).toEqual(["V1"]);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
it("fail-closed:没有 plugin.json ⇒ 红(拿不到前缀就判不了「有主 / 无主」)", () => {
|
|
153
|
+
withPlugin({ manifest: null, css: ".demo-plugin-root { --a: 1; }\n" }, (root) => {
|
|
154
|
+
const r = runTokenScopeCheck(root);
|
|
155
|
+
expect(r.error).not.toBeNull();
|
|
156
|
+
expect(r.violations).toHaveLength(1);
|
|
157
|
+
expect(r.violations[0].file).toBe("plugin.json");
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
it("知情绕行:disable 注释盖得住红与黄(同一个 `check-css-namespace` id)", () => {
|
|
161
|
+
withPlugin({
|
|
162
|
+
css: "/* eslint-disable linkdesk/no-reserved-class-name -- 内容画布 */\n:root { --bg-card: red; }\n" +
|
|
163
|
+
":root { --demo-plugin-x: 1; }\n",
|
|
164
|
+
}, (root) => {
|
|
165
|
+
const r = runTokenScopeCheck(root);
|
|
166
|
+
expect(r.red).toHaveLength(0);
|
|
167
|
+
expect(r.yellow).toHaveLength(0);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
it("口径:`var(--x)` 用法不算定义(没有冒号);多选择器规则逐 compound 判", () => {
|
|
171
|
+
withPlugin({ css: ".demo-plugin-root { color: var(--text-primary); }\n:root, .demo-plugin-root { --a: 1; }\n" }, (root) => {
|
|
172
|
+
const r = runTokenScopeCheck(root);
|
|
173
|
+
// 第一行没有定义;第二行 = 两个 compound,`:root` 那半红(V1)、自有类那半绿
|
|
174
|
+
expect(r.red).toHaveLength(1);
|
|
175
|
+
expect(r.red[0].selector).toBe(":root");
|
|
176
|
+
expect(r.red[0].line).toBe(2);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
it("口径:注释里的 `--x:` 不算定义(`stripComments` 等长替换)", () => {
|
|
180
|
+
withPlugin({ css: "/* :root { --bg-card: red; } 这是注释里的示例 */\n.demo-plugin-root { --a: 1; }\n" }, (root) => {
|
|
181
|
+
expect(runTokenScopeCheck(root).red).toHaveLength(0);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
//# sourceMappingURL=token-scope.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-scope.test.js","sourceRoot":"","sources":["../../../src/eslint/checks/token-scope.test.ts"],"names":[],"mappings":"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"}
|
package/dist/eslint/index.d.ts
CHANGED
|
@@ -57,4 +57,16 @@ export type { ConfigOwnershipReport, ConfigKeySite, ConfigKeyCode, ConfigKeyFace
|
|
|
57
57
|
*/
|
|
58
58
|
export { runAppearanceOwnershipCheck, judgeAppearanceId, reservedIdsForSpace, grantHoldersFor, readThemeJson, themeIdLine, } from "./checks/appearance-ownership.js";
|
|
59
59
|
export type { AppearanceOwnershipReport, AppearanceIdSite, AppearanceIdCode, AppearanceIdSpace, AppearanceIdFace, } from "./checks/appearance-ownership.js";
|
|
60
|
+
/**
|
|
61
|
+
* 🔴 E6#111h(1.38):同一纪律再加一个 —— `runContextOwnershipCheck`(上下文旗子归属判据)。
|
|
62
|
+
* 壳仓只读探针 `scripts/audit-nonnaming.mjs` 用它出旗子面读数;**同样不是第二条判据路径**
|
|
63
|
+
* (`lint.ts` 的第八条腿用的就是它——同一份实现,改一处两边一起变)。
|
|
64
|
+
* 分级与配置腿/外观腿同形:判据① 占**宿主专用**旗子 = 红(进腿报点);判据③ 新旗子不带本仓前缀 = 黄
|
|
65
|
+
* (`contextAdvisories`,只打印,1.49 才收紧为红)。
|
|
66
|
+
* 🟠 **宿主公开约定面**(`contextKeysPublic`)**不判**——第三方设它合法(`MenuId` 是开放字符串),
|
|
67
|
+
* 只登记在报告的 `publicFace` 里让"谁在设约定面"可见。
|
|
68
|
+
* 🔴 **两段不许合并**(合成一栏 ⇒ 官方 `settings` 的 4 个约定面旗子被当成"占用宿主旗子"= 假红)。
|
|
69
|
+
*/
|
|
70
|
+
export { runContextOwnershipCheck, judgeContextKey, RE_CONTEXT_KEY_SET } from "./checks/context-ownership.js";
|
|
71
|
+
export type { ContextOwnershipReport, ContextKeySite, ContextKeyCode } from "./checks/context-ownership.js";
|
|
60
72
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAClE,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACxF,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpH,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACpF,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACvG,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAExG;;;;;GAKG;AACH,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAC3G,YAAY,EACV,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,GAClB,MAAM,+BAA+B,CAAC;AAEvC;;;;;;GAMG;AACH,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/H,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAEvH;;;;;;;;GAQG;AACH,OAAO,EACL,2BAA2B,EAC3B,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,WAAW,GACZ,MAAM,kCAAkC,CAAC;AAC1C,YAAY,EACV,yBAAyB,EACzB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAClE,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACxF,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpH,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACpF,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACvG,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAExG;;;;;GAKG;AACH,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAC3G,YAAY,EACV,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,GAClB,MAAM,+BAA+B,CAAC;AAEvC;;;;;;GAMG;AACH,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/H,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAEvH;;;;;;;;GAQG;AACH,OAAO,EACL,2BAA2B,EAC3B,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,WAAW,GACZ,MAAM,kCAAkC,CAAC;AAC1C,YAAY,EACV,yBAAyB,EACzB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAE1C;;;;;;;;;GASG;AACH,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC9G,YAAY,EAAE,sBAAsB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC"}
|