@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,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-config-ownership 腿·**配置键归属判据**(E6#111d · 1.34)单测。
|
|
3
|
+
*
|
|
4
|
+
* 为什么值得一条测试:这条腿**两侧都容易错,且错法不同**——
|
|
5
|
+
* · 太松(放过一个宿主保留键)⇒ 装上壳后那个键被**运行时拒绝注册**,作者却在 lint 里看到全绿
|
|
6
|
+
* ("本地绿、装上炸"是作者最恨的一类);太松(放过一个不带前缀的键)⇒ 键归别人名下,
|
|
7
|
+
* 两个插件撞键时一个静默失效。
|
|
8
|
+
* · 太紧(把弱默认值面的键当"新键"要求前缀)⇒ **把 `configurationDefaults` 这个能力判死**
|
|
9
|
+
* (它的语义就是给**别人的**键建议弱默认值),作者只能 disable 整条腿。
|
|
10
|
+
* 故:判据①(宿主保留面 ⇒ 红)/判据②(本仓前缀 ⇒ 黄)/**面差异**(`defaults` 面不判②)/
|
|
11
|
+
* fail-closed / 豁免 —— 正反两向都钉住,另加三条元判据:
|
|
12
|
+
* · **同一份源码 + 不同 pluginId ⇒ 不同裁决**(证明真在读 manifest,不是恒红/恒绿);
|
|
13
|
+
* · **红与黄在同一例里同时断言**(`violations` 长度与 `advisories` 长度各就各位)——
|
|
14
|
+
* 只测"报出来了"是不够的,**分级写错**(黄判成红)同样是这条腿的失效方向;
|
|
15
|
+
* · **账读不到 ⇒ 明示空转**(不是静默绿)——账是判据① 的**唯一**输入(不许内联一份清单)。
|
|
16
|
+
*/
|
|
17
|
+
import { describe, expect, it } from "vitest";
|
|
18
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
19
|
+
import { tmpdir } from "node:os";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import { judgeConfigKey, judgeRegisterIdentity, runConfigOwnershipCheck, } from "./config-ownership.js";
|
|
22
|
+
/** 宿主保留面夹具(不依赖真账内容——真账会被后续轮次加家族;这里只钉判据的形状) */
|
|
23
|
+
const RESERVED = {
|
|
24
|
+
commandPrefixes: ["workbench.", "view."],
|
|
25
|
+
protocolIds: ["bracket"],
|
|
26
|
+
configKeys: ["app.theme", "app.surfaceRadius", "app.schemaVersion"],
|
|
27
|
+
pseudoPluginIds: ["app", "appearance", "update"],
|
|
28
|
+
appearanceRecipeIds: [],
|
|
29
|
+
appearanceColorwayIds: [],
|
|
30
|
+
appearanceIconThemeIds: [],
|
|
31
|
+
appearanceSentinels: [],
|
|
32
|
+
appearanceIdGrants: {},
|
|
33
|
+
contextKeysHostOnly: [],
|
|
34
|
+
contextKeysPublic: [],
|
|
35
|
+
};
|
|
36
|
+
const NO_LEDGER = join(tmpdir(), "no-such-host-reserved.json");
|
|
37
|
+
/** 造一个临时插件工程(manifest 写成 JSONC——作者面允许注释,读 manifest 的代码必须容忍) */
|
|
38
|
+
function withPlugin(opts, fn) {
|
|
39
|
+
const base = mkdtempSync(join(tmpdir(), "cfg-owner-"));
|
|
40
|
+
const root = opts.dirName ? join(base, opts.dirName) : base;
|
|
41
|
+
mkdirSync(join(root, "src"), { recursive: true });
|
|
42
|
+
if (opts.manifest !== null) {
|
|
43
|
+
const raw = opts.manifest ?? {
|
|
44
|
+
pluginId: "file-tree",
|
|
45
|
+
name: "文件树",
|
|
46
|
+
version: "1.0.0",
|
|
47
|
+
contributes: { configuration: { title: "文件树", properties: { "file-tree.confirmDelete": { type: "boolean" } } } },
|
|
48
|
+
};
|
|
49
|
+
writeFileSync(join(root, "plugin.json"), `{\n // 作者允许的注释\n ${JSON.stringify(raw).slice(1, -1)},\n}\n`, "utf8");
|
|
50
|
+
}
|
|
51
|
+
for (const [rel, body] of Object.entries(opts.files ?? {})) {
|
|
52
|
+
const abs = join(root, rel);
|
|
53
|
+
mkdirSync(join(abs, ".."), { recursive: true });
|
|
54
|
+
writeFileSync(abs, body, "utf8");
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
fn(root);
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
rmSync(base, { recursive: true, force: true });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const manifest = (contributes, pluginId = "file-tree") => ({
|
|
64
|
+
pluginId,
|
|
65
|
+
name: "文件树",
|
|
66
|
+
version: "1.0.0",
|
|
67
|
+
contributes,
|
|
68
|
+
});
|
|
69
|
+
describe("judgeConfigKey —— 纯判据(只换第一段的建议名形状)", () => {
|
|
70
|
+
const judge = (key, face) => judgeConfigKey(key, "file-tree", RESERVED, face);
|
|
71
|
+
it("宿主保留键 ⇒ host-reserved(红)+ 建议名只换第一段(词干零变化)", () => {
|
|
72
|
+
expect(judge("app.theme", "declared")).toEqual({
|
|
73
|
+
code: "host-reserved",
|
|
74
|
+
suggested: "file-tree.theme",
|
|
75
|
+
reserved: "app.theme",
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
it("退役键 app.schemaVersion 也拦(宿主从不注册它 ⇒ 这里拦它才是判据① 的硬核)", () => {
|
|
79
|
+
expect(judge("app.schemaVersion", "declared")?.code).toBe("host-reserved");
|
|
80
|
+
});
|
|
81
|
+
it("不带本仓前缀(声明面)⇒ no-plugin-prefix(黄)+ 建议名", () => {
|
|
82
|
+
expect(judge("confirmDelete", "declared")).toEqual({ code: "no-plugin-prefix", suggested: "file-tree.confirmDelete" });
|
|
83
|
+
expect(judge("explorer.confirmDelete", "declared")).toEqual({
|
|
84
|
+
code: "no-plugin-prefix",
|
|
85
|
+
suggested: "file-tree.confirmDelete",
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
it("🔴 面差异:弱默认值面**不判**判据②(它的键天然是别人的键)——但判据① 照判", () => {
|
|
89
|
+
expect(judge("editor.fontSize", "defaults")).toBeNull(); // 建议别人的键 = 本能力的正常用法
|
|
90
|
+
expect(judge("app.theme", "defaults")?.code).toBe("host-reserved"); // 顶替宿主设置面 = 照拦
|
|
91
|
+
});
|
|
92
|
+
it("合规:本仓前缀 ⇒ 零命中(任何面)", () => {
|
|
93
|
+
expect(judge("file-tree.confirmDelete", "declared")).toBeNull();
|
|
94
|
+
expect(judge("file-tree.confirmDelete", "defaults")).toBeNull();
|
|
95
|
+
});
|
|
96
|
+
it("judgeRegisterIdentity:宿主伪身份 ⇒ 红;别人的 id ⇒ 黄;自己的 id ⇒ 零命中", () => {
|
|
97
|
+
expect(judgeRegisterIdentity("app", "file-tree", RESERVED)?.code).toBe("host-reserved");
|
|
98
|
+
expect(judgeRegisterIdentity("other-plugin", "file-tree", RESERVED)?.code).toBe("no-plugin-prefix");
|
|
99
|
+
expect(judgeRegisterIdentity("file-tree", "file-tree", RESERVED)).toBeNull();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe("三面(声明 / 弱默认值 / 运行时)+ 分级", () => {
|
|
103
|
+
it("正控:三面都合规 ⇒ 零红零黄,三面读数各就各位", () => {
|
|
104
|
+
withPlugin({
|
|
105
|
+
manifest: manifest({
|
|
106
|
+
configuration: { title: "文件树", properties: { "file-tree.confirmDelete": { type: "boolean" } } },
|
|
107
|
+
configurationDefaults: { "editor.fontSize": 13 }, // 建议别人的键 = 正常用法,不报
|
|
108
|
+
}),
|
|
109
|
+
files: { "src/config.ts": 'registerConfiguration("file-tree", { title: "x", properties: {} });\n' },
|
|
110
|
+
}, (root) => {
|
|
111
|
+
const r = runConfigOwnershipCheck(root, RESERVED, NO_LEDGER);
|
|
112
|
+
expect(r.violations).toHaveLength(0);
|
|
113
|
+
expect(r.advisories).toHaveLength(0);
|
|
114
|
+
expect(r.declaredKeys).toEqual(["file-tree.confirmDelete"]);
|
|
115
|
+
expect(r.defaultsKeys).toEqual(["editor.fontSize"]);
|
|
116
|
+
expect(r.runtimeIdentities).toEqual(["file-tree"]);
|
|
117
|
+
expect(r.pluginId).toBe("file-tree");
|
|
118
|
+
expect(r.pluginIdSource).toBe("plugin.json");
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
it("🔴 判据① 红 + 🟡 判据② 黄 **在同一例里同时断言**(分级写错也要被抓)", () => {
|
|
122
|
+
withPlugin({
|
|
123
|
+
manifest: manifest({
|
|
124
|
+
configuration: {
|
|
125
|
+
title: "文件树",
|
|
126
|
+
properties: {
|
|
127
|
+
"app.theme": { type: "string" }, // 判据① ⇒ 红
|
|
128
|
+
"explorer.confirmDelete": { type: "boolean" }, // 判据② ⇒ 黄
|
|
129
|
+
"file-tree.expandDepth": { type: "number" }, // 合规 ⇒ 不报
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
}),
|
|
133
|
+
}, (root) => {
|
|
134
|
+
const r = runConfigOwnershipCheck(root, RESERVED, NO_LEDGER);
|
|
135
|
+
expect(r.violations).toHaveLength(1); // 红:只在 violations 里
|
|
136
|
+
expect(r.advisories).toHaveLength(1); // 黄:只在 advisories 里(没进 violations)
|
|
137
|
+
expect(r.red.map((s) => s.key)).toEqual(["app.theme"]);
|
|
138
|
+
expect(r.yellow.map((s) => s.key)).toEqual(["explorer.confirmDelete"]);
|
|
139
|
+
expect(r.red[0].face).toBe("declared");
|
|
140
|
+
// 红的那条:报点带宿主保留键名 + 建议名;行号是真行号(不是恒 1)
|
|
141
|
+
expect(r.violations[0].file).toBe("plugin.json");
|
|
142
|
+
expect(r.violations[0].line).toBeGreaterThan(1);
|
|
143
|
+
expect(r.violations[0].message).toContain("宿主");
|
|
144
|
+
expect(r.violations[0].message).toContain('改成 "file-tree.theme"');
|
|
145
|
+
expect(r.advisories[0].message).toContain('改成 "file-tree.confirmDelete"');
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
it("弱默认值面:宿主键 ⇒ 红;别人的键 ⇒ 不报(同一次声明里两种结果并存)", () => {
|
|
149
|
+
withPlugin({
|
|
150
|
+
manifest: manifest({
|
|
151
|
+
configurationDefaults: { "app.surfaceRadius": 8, "editor.wordWrap": true },
|
|
152
|
+
}),
|
|
153
|
+
}, (root) => {
|
|
154
|
+
const r = runConfigOwnershipCheck(root, RESERVED, NO_LEDGER);
|
|
155
|
+
expect(r.violations).toHaveLength(1);
|
|
156
|
+
expect(r.red[0].face).toBe("defaults");
|
|
157
|
+
expect(r.red[0].key).toBe("app.surfaceRadius");
|
|
158
|
+
expect(r.advisories).toHaveLength(0); // editor.wordWrap 不报(面差异)
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
it("运行时面:冒充宿主身份 ⇒ 红;用别人的 id ⇒ 黄;用自己的 id ⇒ 零命中", () => {
|
|
162
|
+
withPlugin({
|
|
163
|
+
files: {
|
|
164
|
+
"src/impersonate.ts": 'registerConfiguration("app", { title: "冒充", properties: {} });\n',
|
|
165
|
+
"src/borrow.ts": 'registerConfigurationDefaults("other-plugin", { "editor.fontSize": 12 });\n',
|
|
166
|
+
"src/own.ts": 'registerConfiguration("file-tree", { title: "自己", properties: {} });\n',
|
|
167
|
+
},
|
|
168
|
+
}, (root) => {
|
|
169
|
+
const r = runConfigOwnershipCheck(root, RESERVED, NO_LEDGER);
|
|
170
|
+
expect(r.violations).toHaveLength(1); // 冒充宿主 = 红
|
|
171
|
+
expect(r.advisories).toHaveLength(1); // 借别人的 id = 黄
|
|
172
|
+
expect(r.red[0].face).toBe("runtime");
|
|
173
|
+
expect(r.red[0].key).toBe("app");
|
|
174
|
+
expect(r.red[0].file).toBe("src/impersonate.ts");
|
|
175
|
+
expect(r.red[0].line).toBe(1);
|
|
176
|
+
expect(r.violations[0].message).toContain("宿主自己的身份");
|
|
177
|
+
expect(r.yellow[0].file).toBe("src/borrow.ts");
|
|
178
|
+
// 三面读数含全部身份名(合规的也在——口径:名数,非站点数);目录遍历顺序不参与断言(比集合)
|
|
179
|
+
expect([...r.runtimeIdentities].sort()).toEqual(["app", "file-tree", "other-plugin"]);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
it("测试/mock 文件跳过(与另几条腿同口径)——夹具里的 app.* 不报", () => {
|
|
183
|
+
withPlugin({ files: { "src/config.test.ts": 'registerConfiguration("app", { title: "夹具", properties: {} });\n' } }, (root) => {
|
|
184
|
+
const r = runConfigOwnershipCheck(root, RESERVED, NO_LEDGER);
|
|
185
|
+
expect(r.violations).toHaveLength(0);
|
|
186
|
+
expect(r.runtimeIdentities).toEqual([]);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
it("fail-closed:没有 plugin.json ⇒ 红一条(不受豁免注释管辖)", () => {
|
|
190
|
+
withPlugin({ manifest: null, dirName: "no-manifest" }, (root) => {
|
|
191
|
+
const r = runConfigOwnershipCheck(root, RESERVED, NO_LEDGER);
|
|
192
|
+
expect(r.violations).toHaveLength(1);
|
|
193
|
+
expect(r.violations[0].file).toBe("plugin.json");
|
|
194
|
+
expect(r.violations[0].message).toContain("拿不到本仓 pluginId");
|
|
195
|
+
expect(r.red).toHaveLength(0); // 红的是 fail-closed 那条,不是判据命中
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
it("账读不到 ⇒ hostLedger.found = false + 两栏计数为 0(判据① 明示空转,不许静默绿)", () => {
|
|
199
|
+
withPlugin({}, (root) => {
|
|
200
|
+
const r = runConfigOwnershipCheck(root, { ...RESERVED, configKeys: [], pseudoPluginIds: [] }, NO_LEDGER);
|
|
201
|
+
expect(r.hostLedger.found).toBe(false);
|
|
202
|
+
expect(r.hostLedger.configKeys).toBe(0);
|
|
203
|
+
expect(r.hostLedger.pseudoPluginIds).toBe(0);
|
|
204
|
+
expect(r.violations).toHaveLength(0); // 账空 ⇒ 判据① 无从命中(这正是"空转"的样子)
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
it("元判据:同一份源码 + 不同 pluginId ⇒ 不同裁决(真在读 manifest,不是恒红)", () => {
|
|
208
|
+
const body = manifest({
|
|
209
|
+
configuration: { title: "x", properties: { "file-tree.confirmDelete": { type: "boolean" } } },
|
|
210
|
+
});
|
|
211
|
+
withPlugin({ manifest: body }, (root) => {
|
|
212
|
+
expect(runConfigOwnershipCheck(root, RESERVED, NO_LEDGER).violations).toHaveLength(0);
|
|
213
|
+
});
|
|
214
|
+
withPlugin({
|
|
215
|
+
manifest: manifest({
|
|
216
|
+
configuration: { title: "x", properties: { "file-tree.confirmDelete": { type: "boolean" } } },
|
|
217
|
+
}, "marketplace"),
|
|
218
|
+
}, (root) => {
|
|
219
|
+
const r = runConfigOwnershipCheck(root, RESERVED, NO_LEDGER);
|
|
220
|
+
expect(r.advisories).toHaveLength(1); // 换身份后同一个键成了"不带本仓前缀"
|
|
221
|
+
expect(r.advisories[0].message).toContain('应以 "marketplace." 开头');
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
it("知情绕行:行级 disable 注释 ⇒ 该行整体静默(红也不亮)", () => {
|
|
225
|
+
withPlugin({
|
|
226
|
+
manifest: manifest({
|
|
227
|
+
configuration: {
|
|
228
|
+
title: "x",
|
|
229
|
+
properties: {
|
|
230
|
+
// disable 注释必须紧邻违规行的上一行
|
|
231
|
+
"app.theme": { type: "string" },
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
}),
|
|
235
|
+
}, (root) => {
|
|
236
|
+
// 先在**没有**豁免时确认它真的会红(否则本控什么都没证明)
|
|
237
|
+
expect(runConfigOwnershipCheck(root, RESERVED, NO_LEDGER).violations).toHaveLength(1);
|
|
238
|
+
});
|
|
239
|
+
const raw = JSON.stringify(manifest({ configuration: { title: "x", properties: { "app.theme": { type: "string" } } } }));
|
|
240
|
+
const base = mkdtempSync(join(tmpdir(), "cfg-owner-"));
|
|
241
|
+
try {
|
|
242
|
+
writeFileSync(join(base, "plugin.json"), `{\n // eslint-disable-next-line ${"linkdesk/no-unowned-config-key"} -- 本仓键名迁移留待下个版本\n ${raw.slice(1)}\n`, "utf8");
|
|
243
|
+
const r = runConfigOwnershipCheck(base, RESERVED, NO_LEDGER);
|
|
244
|
+
expect(r.violations).toHaveLength(0); // 豁免生效
|
|
245
|
+
expect(r.red).toHaveLength(0);
|
|
246
|
+
}
|
|
247
|
+
finally {
|
|
248
|
+
rmSync(base, { recursive: true, force: true });
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
//# sourceMappingURL=config-ownership.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-ownership.test.js","sourceRoot":"","sources":["../../../src/eslint/checks/config-ownership.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type PluginIdSource } from "./plugin-prefix.js";
|
|
2
|
+
import { type HostReservedNames } from "./command-ownership.js";
|
|
3
|
+
import { type CheckViolation } from "./scan.js";
|
|
4
|
+
/** 判据命中的两种形态(与 `CommandIdCode` / `ConfigKeyCode` 同词表:红 = 占别人的面;黄 = 不带本仓归属) */
|
|
5
|
+
export type ContextKeyCode = "host-reserved" | "no-plugin-prefix";
|
|
6
|
+
/** 一处不合规站点(探针与腿共用同一份数据) */
|
|
7
|
+
export interface ContextKeySite {
|
|
8
|
+
/** 工程相对路径(正斜杠) */
|
|
9
|
+
file: string;
|
|
10
|
+
line: number;
|
|
11
|
+
/** 旗子名 */
|
|
12
|
+
key: string;
|
|
13
|
+
code: ContextKeyCode;
|
|
14
|
+
/** 应改成什么:**只换第一段**(`<pluginId>.` + 原名第一段之后的全部)——词干零变化 */
|
|
15
|
+
suggested: string;
|
|
16
|
+
/** code = host-reserved 时:撞上的那条宿主专用旗子名 */
|
|
17
|
+
reserved?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ContextOwnershipReport {
|
|
20
|
+
root: string;
|
|
21
|
+
pluginId: string | null;
|
|
22
|
+
pluginIdSource: PluginIdSource | null;
|
|
23
|
+
pluginIdNote: string | null;
|
|
24
|
+
/** fail-closed:非 null ⇒ 本腿报红(拿不到身份就无从判归属) */
|
|
25
|
+
error: string | null;
|
|
26
|
+
/** 🔴 必须改的(进腿报点)——1.49 收紧后 = 占用宿主专用旗子 + 不带本仓归属 */
|
|
27
|
+
red: ContextKeySite[];
|
|
28
|
+
/** 🟡 建议改的——🔴 **1.49 起恒空**(归属判据已升红);字段保留只为探针输出形状不塌 */
|
|
29
|
+
yellow: ContextKeySite[];
|
|
30
|
+
/** 🟠 **宿主公开约定面**的写点——**不报点、不拦、不进任何退出码**(登记用:让"谁在设约定面"可见) */
|
|
31
|
+
publicFace: ContextKeySite[];
|
|
32
|
+
/** 扫到的**全部**旗子名(合规 + 不合规,按出现顺序去重)——探针的读数面(口径:名数,非站点数) */
|
|
33
|
+
keys: string[];
|
|
34
|
+
/** 账的加载实况(账没读到 ⇒ 判据① 空转,报告里必须能看出来) */
|
|
35
|
+
hostLedger: {
|
|
36
|
+
file: string;
|
|
37
|
+
found: boolean;
|
|
38
|
+
contextKeysHostOnly: number;
|
|
39
|
+
contextKeysPublic: number;
|
|
40
|
+
};
|
|
41
|
+
/** 腿报点 = fail-closed + 全部红 */
|
|
42
|
+
violations: CheckViolation[];
|
|
43
|
+
/** 黄灯建议——🔴 **1.49 起恒空**(归属判据已升红);保留字段=探针/渲染器的输出形状不变 */
|
|
44
|
+
advisories: CheckViolation[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 一个 context key 的裁决(纯函数——单测与探针共用,别在别处再写一份判据)。
|
|
48
|
+
*
|
|
49
|
+
* 🔴 建议名的形状 = **只替换第一段**(`explorerFocus` → `file-tree.explorerFocus`,词干零变化),
|
|
50
|
+
* 与 `judgeCommandId` / `judgeConfigKey` 同形。
|
|
51
|
+
* ⚠️ **约定面(`contextKeysPublic`)在这里返回 null**——它既不是红的,也**不判黄**:
|
|
52
|
+
* 约定面是**名册里已登记的名字**,谁设都合法(1.37 §13.5);它的写点由 `publicFace` 单独登记。
|
|
53
|
+
*/
|
|
54
|
+
export declare function judgeContextKey(key: string, pluginId: string, reserved: HostReservedNames): {
|
|
55
|
+
code: ContextKeyCode;
|
|
56
|
+
suggested: string;
|
|
57
|
+
reserved?: string;
|
|
58
|
+
} | null;
|
|
59
|
+
/**
|
|
60
|
+
* 扫描面:源码里 `contextKey.set("<字面量>", …)` 与 `ContextKeyService.setValue("<字面量>", …)`。
|
|
61
|
+
* 🔴 两支**都要扫**:前者是插件侧惯用写法(`contextKey` 是注入的 API 对象),后者是壳侧写法——
|
|
62
|
+
* 同一件事的两张脸,只扫一支 = 漏一半(1.37 §十七 的复现命令就是按这两支取读数的)。
|
|
63
|
+
* ⚠️ `` ` `` 定界符保留,但**分两种**:
|
|
64
|
+
* · **无插值**的模板(`` set(`myFlag`, 1) ``)= 字面量 ⇒ **扫得到**(能扫到就是收益)。
|
|
65
|
+
* · **带插值**的(`` set(`exp${x}`, 1) ``)⇒ 名字在运行时才拼出来,**扫不到**——§15.1 登记的残余边界。
|
|
66
|
+
* 实现上由 `(?![\s\S]*?\$\{)` 挡:模板体里出现 `${` 一律不匹配(**不是**匹配出一个
|
|
67
|
+
* `exp${x}` 这种不存在的名字——那会变成假红,比漏报更坏)。
|
|
68
|
+
*/
|
|
69
|
+
export declare const RE_CONTEXT_KEY_SET: RegExp;
|
|
70
|
+
/**
|
|
71
|
+
* 跑本仓 context key 归属判据。返回结构化报告(探针用)+ 腿报点(`lint.ts` 用)——**同一份实现**。
|
|
72
|
+
*/
|
|
73
|
+
export declare function runContextOwnershipCheck(root: string, reserved?: HostReservedNames, reservedFile?: string): ContextOwnershipReport;
|
|
74
|
+
//# sourceMappingURL=context-ownership.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-ownership.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/context-ownership.ts"],"names":[],"mappings":"AAiDA,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAwC,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtG,OAAO,EAAsD,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAGpG,8EAA8E;AAC9E,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAElE,2BAA2B;AAC3B,MAAM,WAAW,cAAc;IAC7B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU;IACV,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,cAAc,CAAC;IACrB,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6CAA6C;IAC7C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kDAAkD;IAClD,GAAG,EAAE,cAAc,EAAE,CAAC;IACtB,uDAAuD;IACvD,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,6DAA6D;IAC7D,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,yDAAyD;IACzD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,sCAAsC;IACtC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,CAAC;IACrG,8BAA8B;IAC9B,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,wDAAwD;IACxD,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,iBAAiB,GAC1B;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAUvE;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,QAC0G,CAAC;AAE1I;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,iBAAsC,EAChD,YAAY,GAAE,MAA2B,GACxC,sBAAsB,CAuFxB"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-context-ownership 腿·**上下文旗子归属判据**(E6#111h · 轮次 1.38)。
|
|
3
|
+
*
|
|
4
|
+
* ── 为什么(本件立项的那条轴)──
|
|
5
|
+
* context key 是**宿主的运行时状态面**:`contextKey.set(name, value)` 把名字**当 map 键**写进
|
|
6
|
+
* `ContextKeyService` 的 `_state`,宿主(和任何人)的命令/菜单 `when` 再按名字去读——
|
|
7
|
+
* **写入时零归属校验、读取时零编译期校验**(`matches()` 就是一次 map 查表)。
|
|
8
|
+
* 插件用宿主的旗子名 ⇒ 宿主菜单/命令面板的显隐条件被外部改写(**两边都不报错**,用户只看到
|
|
9
|
+
* 「菜单项莫名其妙不见了」);插件用别人的旗子名 ⇒ 后写者静默胜出。
|
|
10
|
+
* 1.37 实测:官方 18 仓 **23 个**插件旗子不带本仓归属,另有一处 `inputFocus` 是**借共享组件**来的。
|
|
11
|
+
*
|
|
12
|
+
* ── 账分两段(🔴 本腿读的就是这两段,与壳仓 `scripts/gen-host-reserved.mjs` 的账同源)──
|
|
13
|
+
* · **`contextKeysHostOnly`**(宿主专用 ⇒ 判据① 🔴 红):宿主内核/壳自己写的状态旗子
|
|
14
|
+
* (`activeEditor` / `editorCount` / `inputFocus` / `sidebarPosition` / `updateActionable` …)。
|
|
15
|
+
* · **`contextKeysPublic`**(宿主公开约定面 ⇒ **不判**):宿主 `when` 读、**写的人是插件**
|
|
16
|
+
* (今天 = 官方 `settings` 的齿轮菜单 4 个 `setting*`)。它们**事实上已是谁都能设、谁都能读**的
|
|
17
|
+
* 公开约定面(`MenuId` 是开放字符串 ⇒ 第三方可加入 `settingItemGear` 槽)⇒
|
|
18
|
+
* **第三方设它不判**(1.37 §13.5 裁决:登记 + 出声,不拦)。
|
|
19
|
+
* 🔴 **两段不许合并**:合成一栏 ⇒ 官方 `settings` 拿这 4 个约定面名字当"占用宿主旗子"⇒ **当场假红**
|
|
20
|
+
* (它恰恰是约定面的正当使用方)——与 1.36「外观账一栏混两空间 ⇒ 官方 theme-defaults 假红」同一种病。
|
|
21
|
+
*
|
|
22
|
+
* ── 两条判据 ──
|
|
23
|
+
* ① **宿主专用旗子**(🔴 红):源码字符串字面量 `contextKey.set("<contextKeysHostOnly 中的名字>")`
|
|
24
|
+
* ⇒ 占用宿主状态面。判据出处 = 1.37 §10.2 + §12.2。
|
|
25
|
+
* ③ **本仓归属**(🔴 红 · **1.49 收紧**):`contextKey.set("<name>")` 的 name **不以本仓 `pluginId` + `.` 开头**
|
|
26
|
+
* ⇒ 改成 `<pluginId>.<你的名字>`(只换第一段、词干零变化)。
|
|
27
|
+
* ⚠️ 归属段用 **`.`** 而非 `-`:旗子是 **map 键**(`when` 里的标识符),
|
|
28
|
+
* 命令 id / 配置键 / 外观 id 用的都是 `.`——`-` 在 `when` 表达式里会被当成减号。
|
|
29
|
+
* 🕐 **收紧史**:1.38 落地时按轴上排序纪律只判黄(官方仓当时还没改名);1.49 清账完成后兑现为红。
|
|
30
|
+
* 🔴 **`contextKeysPublic`(约定面)仍然不判**——它**不是**「还没收紧的黄」,是**已裁决的豁免**
|
|
31
|
+
* (1.46 丙路线:登记 + 出声,不拦;第三方设约定面合法)。收紧只动「不带本仓归属的裸名」,
|
|
32
|
+
* ⛔ 别把约定面一起收成红(那会让官方 `settings` 当场假红)。
|
|
33
|
+
*
|
|
34
|
+
* ── 🔴 射程(1.37 §15.1 登记的边界,别当成 bug)──
|
|
35
|
+
* 只扫**源码字符串字面量**。三种看不见(**登记为残余边界**,负控 ⑦ 断言它们**不被抓**):
|
|
36
|
+
* ① `` contextKey.set(`exp${x}`, 1) `` 模板字符串拼名(名字运行时才成形);
|
|
37
|
+
* ② 常量写入(`const K = "..."` 再 `set(K)`);③ `_state.set` 直写。
|
|
38
|
+
* ②③ 两项宿主侧已由生成器手工补齐,插件侧两方都扫不到。
|
|
39
|
+
*
|
|
40
|
+
* ── 🔴 分工:判据① 运行时也报(但语义完全不同)──
|
|
41
|
+
* 壳运行时在 `contextKey:set` 的过桥处对宿主专用名**出声 + 放行**(`IpcBridgeHandler/ui.ts`)——
|
|
42
|
+
* 那是**第二道网**,且它**拿不到写入者身份**(IPC 通道不带 pluginId ⇒ 「先者保留」结构上做不到)。
|
|
43
|
+
* ⇒ **保护主力在本腿**:这里能在作者仓里、**带身份**地提前把同一件事报出来。
|
|
44
|
+
*
|
|
45
|
+
* 知情绕行 = 标准 disable 注释(`CHECK_IDS.contextOwnership`)。⚠️ **fail-closed 不参与豁免**:
|
|
46
|
+
* 拿不到 `pluginId` 说的不是「你的旗子怎么写」,而是「你的身份读不到」——那是工程根的问题。
|
|
47
|
+
*/
|
|
48
|
+
import { existsSync } from "node:fs";
|
|
49
|
+
import { resolve } from "node:path";
|
|
50
|
+
import { resolvePluginIdForCss } from "./plugin-prefix.js";
|
|
51
|
+
import { HOST_RESERVED_FILE, loadHostReserved } from "./command-ownership.js";
|
|
52
|
+
import { collectFiles, isTestOrMockRel, readSource, relPath } from "./scan.js";
|
|
53
|
+
import { buildDisableIndex, isDisabled, CHECK_IDS } from "./disable.js";
|
|
54
|
+
/**
|
|
55
|
+
* 一个 context key 的裁决(纯函数——单测与探针共用,别在别处再写一份判据)。
|
|
56
|
+
*
|
|
57
|
+
* 🔴 建议名的形状 = **只替换第一段**(`explorerFocus` → `file-tree.explorerFocus`,词干零变化),
|
|
58
|
+
* 与 `judgeCommandId` / `judgeConfigKey` 同形。
|
|
59
|
+
* ⚠️ **约定面(`contextKeysPublic`)在这里返回 null**——它既不是红的,也**不判黄**:
|
|
60
|
+
* 约定面是**名册里已登记的名字**,谁设都合法(1.37 §13.5);它的写点由 `publicFace` 单独登记。
|
|
61
|
+
*/
|
|
62
|
+
export function judgeContextKey(key, pluginId, reserved) {
|
|
63
|
+
const dot = key.indexOf(".");
|
|
64
|
+
const suggested = `${pluginId}.${dot > 0 ? key.slice(dot + 1) : key}`;
|
|
65
|
+
// ① 宿主专用(比**全等**——保留面是一张逐个列出的名字清单,不是前缀面)
|
|
66
|
+
if (reserved.contextKeysHostOnly.includes(key))
|
|
67
|
+
return { code: "host-reserved", suggested, reserved: key };
|
|
68
|
+
// ② 宿主公开约定面 ⇒ **不判**(登记在 publicFace 里,见 run 函数)
|
|
69
|
+
if (reserved.contextKeysPublic.includes(key))
|
|
70
|
+
return null;
|
|
71
|
+
// ③ 本仓前缀
|
|
72
|
+
if (!key.startsWith(`${pluginId}.`))
|
|
73
|
+
return { code: "no-plugin-prefix", suggested };
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 扫描面:源码里 `contextKey.set("<字面量>", …)` 与 `ContextKeyService.setValue("<字面量>", …)`。
|
|
78
|
+
* 🔴 两支**都要扫**:前者是插件侧惯用写法(`contextKey` 是注入的 API 对象),后者是壳侧写法——
|
|
79
|
+
* 同一件事的两张脸,只扫一支 = 漏一半(1.37 §十七 的复现命令就是按这两支取读数的)。
|
|
80
|
+
* ⚠️ `` ` `` 定界符保留,但**分两种**:
|
|
81
|
+
* · **无插值**的模板(`` set(`myFlag`, 1) ``)= 字面量 ⇒ **扫得到**(能扫到就是收益)。
|
|
82
|
+
* · **带插值**的(`` set(`exp${x}`, 1) ``)⇒ 名字在运行时才拼出来,**扫不到**——§15.1 登记的残余边界。
|
|
83
|
+
* 实现上由 `(?![\s\S]*?\$\{)` 挡:模板体里出现 `${` 一律不匹配(**不是**匹配出一个
|
|
84
|
+
* `exp${x}` 这种不存在的名字——那会变成假红,比漏报更坏)。
|
|
85
|
+
*/
|
|
86
|
+
export const RE_CONTEXT_KEY_SET = /(?:contextKey[?.]*\s*\.\s*set[?.]*|ContextKeyService\s*\.\s*setValue)\s*\(\s*(?:"([^"\n]*)"|'([^'\n]*)'|`((?![\s\S]*?\$\{)[^`\n]*)`)/g;
|
|
87
|
+
/**
|
|
88
|
+
* 跑本仓 context key 归属判据。返回结构化报告(探针用)+ 腿报点(`lint.ts` 用)——**同一份实现**。
|
|
89
|
+
*/
|
|
90
|
+
export function runContextOwnershipCheck(root, reserved = loadHostReserved(), reservedFile = HOST_RESERVED_FILE) {
|
|
91
|
+
const absRoot = resolve(root);
|
|
92
|
+
const resolution = resolvePluginIdForCss(absRoot);
|
|
93
|
+
const violations = [];
|
|
94
|
+
const report = {
|
|
95
|
+
root: absRoot,
|
|
96
|
+
pluginId: resolution.pluginId,
|
|
97
|
+
pluginIdSource: resolution.source,
|
|
98
|
+
pluginIdNote: resolution.note,
|
|
99
|
+
error: resolution.error,
|
|
100
|
+
red: [],
|
|
101
|
+
yellow: [],
|
|
102
|
+
publicFace: [],
|
|
103
|
+
keys: [],
|
|
104
|
+
hostLedger: {
|
|
105
|
+
file: reservedFile,
|
|
106
|
+
found: existsSync(reservedFile),
|
|
107
|
+
contextKeysHostOnly: reserved.contextKeysHostOnly.length,
|
|
108
|
+
contextKeysPublic: reserved.contextKeysPublic.length,
|
|
109
|
+
},
|
|
110
|
+
violations,
|
|
111
|
+
advisories: [],
|
|
112
|
+
};
|
|
113
|
+
// ── fail-closed(不可豁免:拿不到身份 = 判据①③ 全部无从谈起)──
|
|
114
|
+
if (resolution.error || !resolution.pluginId) {
|
|
115
|
+
violations.push({
|
|
116
|
+
file: "plugin.json",
|
|
117
|
+
line: 1,
|
|
118
|
+
message: `拿不到本仓 pluginId:${resolution.error}。旗子的归属判据以「本仓身份」为唯一前缀来源——读不到它就无从判` +
|
|
119
|
+
`「这个旗子是不是你的」。在插件工程根修好 plugin.json(或显式声明 pluginId),` +
|
|
120
|
+
`别用 disable 注释绕:这是身份问题,不受豁免注释管辖。`,
|
|
121
|
+
});
|
|
122
|
+
return report;
|
|
123
|
+
}
|
|
124
|
+
const pluginId = resolution.pluginId;
|
|
125
|
+
const prefix = `${pluginId}.`;
|
|
126
|
+
for (const abs of collectFiles(absRoot, [".ts", ".tsx", ".js", ".jsx"])) {
|
|
127
|
+
const rel = relPath(absRoot, abs);
|
|
128
|
+
if (isTestOrMockRel(rel))
|
|
129
|
+
continue;
|
|
130
|
+
const src = readSource(abs);
|
|
131
|
+
const idx = buildDisableIndex(src, [CHECK_IDS.contextOwnership]);
|
|
132
|
+
for (const m of src.matchAll(RE_CONTEXT_KEY_SET)) {
|
|
133
|
+
const key = m[1] ?? m[2] ?? m[3];
|
|
134
|
+
const line = src.slice(0, m.index ?? 0).split("\n").length;
|
|
135
|
+
if (!report.keys.includes(key))
|
|
136
|
+
report.keys.push(key);
|
|
137
|
+
const verdict = judgeContextKey(key, pluginId, reserved);
|
|
138
|
+
// 约定面:**不报点**,只在报告里登记一行("谁在设约定面"要可见,但谁设都合法)
|
|
139
|
+
if (!verdict && reserved.contextKeysPublic.includes(key)) {
|
|
140
|
+
report.publicFace.push({ file: rel, line, key, code: "no-plugin-prefix", suggested: key });
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (!verdict)
|
|
144
|
+
continue;
|
|
145
|
+
const message = verdict.code === "host-reserved"
|
|
146
|
+
? `运行时面(源码里 contextKey.set / ContextKeyService.setValue 的字面量):旗子 "${key}" 是**宿主专用的状态面**` +
|
|
147
|
+
`(保留清单见包内 schemas/host-reserved.json 的 contextKeysHostOnly)。` +
|
|
148
|
+
`占用它 = 改写宿主菜单/命令面板的显隐条件——宿主那条 when 读到的是**你的值**,` +
|
|
149
|
+
`而**两边都不报错**(用户只看到"菜单项莫名其妙不见了")。` +
|
|
150
|
+
`改法:改成 "${verdict.suggested}"(只换第一段、词干零变化)。`
|
|
151
|
+
: `运行时面(源码里 contextKey.set / ContextKeyService.setValue 的字面量):旗子 "${key}" 不带本仓归属` +
|
|
152
|
+
`(本插件 pluginId = "${pluginId}",新旗子应以 "${prefix}" 开头)——旗子是**全局名册的键**:` +
|
|
153
|
+
`同名旗子被两个插件设时后写者静默胜出(壳运行时只出声、不拦——因为旗子是**状态写**,` +
|
|
154
|
+
`后写者覆盖前写者是正常行为)。改成 "${verdict.suggested}"(只换第一段、词干零变化)。`;
|
|
155
|
+
const site = {
|
|
156
|
+
file: rel,
|
|
157
|
+
line,
|
|
158
|
+
key,
|
|
159
|
+
code: verdict.code,
|
|
160
|
+
suggested: verdict.suggested,
|
|
161
|
+
...(verdict.reserved !== undefined ? { reserved: verdict.reserved } : {}),
|
|
162
|
+
};
|
|
163
|
+
if (verdict.code === "host-reserved" || verdict.code === "no-plugin-prefix") {
|
|
164
|
+
if (isDisabled(idx, line, CHECK_IDS.contextOwnership))
|
|
165
|
+
continue;
|
|
166
|
+
report.red.push(site);
|
|
167
|
+
violations.push({ file: rel, line, message });
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
report.yellow.push(site);
|
|
171
|
+
report.advisories.push({ file: rel, line, message });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return report;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=context-ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-ownership.js","sourceRoot":"","sources":["../../../src/eslint/checks/context-ownership.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-ownership.test.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/context-ownership.test.ts"],"names":[],"mappings":""}
|