@linkdesk/plugin-sdk 0.1.31 → 0.1.33
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 +91 -0
- package/dist/eslint/checks/appearance-ownership.d.ts.map +1 -0
- package/dist/eslint/checks/appearance-ownership.js +314 -0
- package/dist/eslint/checks/appearance-ownership.js.map +1 -0
- 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 +33 -4
- package/dist/eslint/checks/command-ownership.d.ts.map +1 -1
- package/dist/eslint/checks/command-ownership.js +22 -2
- 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.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 +173 -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 +10 -0
- package/dist/eslint/checks/disable.d.ts.map +1 -1
- package/dist/eslint/checks/disable.js +10 -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 +26 -3
- package/dist/eslint/index.d.ts.map +1 -1
- package/dist/eslint/index.js +24 -3
- package/dist/eslint/index.js.map +1 -1
- package/dist/eslint/lint.d.ts +39 -0
- package/dist/eslint/lint.d.ts.map +1 -1
- package/dist/eslint/lint.js +113 -3
- 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 +22 -6
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type PluginIdSource } from "./plugin-prefix.js";
|
|
2
|
+
import { manifestIdLine, type HostReservedNames } from "./command-ownership.js";
|
|
3
|
+
import { type CheckViolation } from "./scan.js";
|
|
4
|
+
/** 判据命中的三种形态(红 = 占宿主兜底面;黄 = 不带本仓归属 / 同插件跨配方重复配色) */
|
|
5
|
+
export type AppearanceIdCode = "host-reserved" | "no-plugin-prefix" | "same-plugin-colorway";
|
|
6
|
+
/**
|
|
7
|
+
* 外观 id 的**空间**——判据按空间比,**永不跨空间**(两个名字空间不可合栏,见文件头判据②)。
|
|
8
|
+
* · `recipe` 配方 id(`app.theme` 取值空间)
|
|
9
|
+
* · `colorway` 配色变体 id(`app.themeColor` / colors 域来源取值空间)
|
|
10
|
+
* · `iconTheme` 图标主题 id(`app.iconTheme` 取值空间)
|
|
11
|
+
* · `sharedIcon` 共享图标 id(`contributes.icons` 的键)
|
|
12
|
+
* · `sentinel` 外观哨兵值(壳的取值约定;插件无声明通道 ⇒ 恒空转)
|
|
13
|
+
*/
|
|
14
|
+
export type AppearanceIdSpace = "recipe" | "colorway" | "iconTheme" | "sharedIcon" | "sentinel";
|
|
15
|
+
/** 扫描面:声明面(plugin.json)/主题文件面(themes/*.json) */
|
|
16
|
+
export type AppearanceIdFace = "declared" | "themeFile";
|
|
17
|
+
/** 一处不合规站点(探针与腿共用同一份数据) */
|
|
18
|
+
export interface AppearanceIdSite {
|
|
19
|
+
face: AppearanceIdFace;
|
|
20
|
+
/** 工程相对路径(正斜杠) */
|
|
21
|
+
file: string;
|
|
22
|
+
line: number;
|
|
23
|
+
id: string;
|
|
24
|
+
space: AppearanceIdSpace;
|
|
25
|
+
code: AppearanceIdCode;
|
|
26
|
+
/** 应改成什么:**只换第一段**(`<pluginId>.` + 原 id 第一段之后的全部)——词干零变化 */
|
|
27
|
+
suggested: string;
|
|
28
|
+
/** code = host-reserved 时:撞上的那条宿主兜底 id */
|
|
29
|
+
reserved?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface AppearanceOwnershipReport {
|
|
32
|
+
root: string;
|
|
33
|
+
pluginId: string | null;
|
|
34
|
+
pluginIdSource: PluginIdSource | null;
|
|
35
|
+
pluginIdNote: string | null;
|
|
36
|
+
/** fail-closed:非 null ⇒ 本腿报红(拿不到身份就无从判归属) */
|
|
37
|
+
error: string | null;
|
|
38
|
+
/** 🔴 必须改的(进腿报点):占用宿主保留面 */
|
|
39
|
+
red: AppearanceIdSite[];
|
|
40
|
+
/** 🟡 建议改的(只打印,不拦):不带本仓归属 / 同插件跨配方重复配色 */
|
|
41
|
+
yellow: AppearanceIdSite[];
|
|
42
|
+
/** 各面的**全部** id(合规 + 不合规,按出现顺序去重)——探针的读数面(口径:名数,非站点数) */
|
|
43
|
+
declaredRecipeIds: string[];
|
|
44
|
+
declaredIconThemeIds: string[];
|
|
45
|
+
declaredSharedIconIds: string[];
|
|
46
|
+
themeFileRecipeIds: string[];
|
|
47
|
+
themeFileColorwayIds: string[];
|
|
48
|
+
/** 主题文件读不出来的个数(不是判据——是"这一面扫了个空"的报警器,必须让作者看见) */
|
|
49
|
+
themeFilesUnparsed: number;
|
|
50
|
+
/** 账的加载实况(账没读到 ⇒ 判据② 空转,报告里必须能看出来) */
|
|
51
|
+
hostLedger: {
|
|
52
|
+
file: string;
|
|
53
|
+
found: boolean;
|
|
54
|
+
appearanceRecipeIds: number;
|
|
55
|
+
appearanceColorwayIds: number;
|
|
56
|
+
appearanceIconThemeIds: number;
|
|
57
|
+
appearanceSentinels: number;
|
|
58
|
+
appearanceIdGrants: number;
|
|
59
|
+
};
|
|
60
|
+
/** 腿报点 = fail-closed + 全部红 */
|
|
61
|
+
violations: CheckViolation[];
|
|
62
|
+
/** 黄灯建议(`lint.ts` 打印用;**不进** `LintLeg.violations` ⇒ 不拦 CI) */
|
|
63
|
+
advisories: CheckViolation[];
|
|
64
|
+
}
|
|
65
|
+
/** 账里该空间的兜底 id 栏——**按空间取**(⛔ 永不跨空间:两个名字空间合栏 = 假红,见文件头判据②) */
|
|
66
|
+
export declare function reservedIdsForSpace(space: AppearanceIdSpace, reserved: HostReservedNames): string[];
|
|
67
|
+
/** 该 id 的**证照**持有者(账 `appearanceIdGrants`)——🔴 **按 id 记**,不是白名单(新插件永远不在表里) */
|
|
68
|
+
export declare function grantHoldersFor(id: string, reserved: HostReservedNames): string[];
|
|
69
|
+
/**
|
|
70
|
+
* 一个外观 id 的裁决(纯函数——单测与探针共用,别在别处再写一份判据)。
|
|
71
|
+
*
|
|
72
|
+
* 🔴 判据顺序 = **先②后①**:占宿主兜底面是红,能同时命中「不带前缀」的那一半不该把红降级成黄。
|
|
73
|
+
* 🔴 判据① 对 `iconTheme` 空间**不判**(任务书 §二.2 ⑦:本轮不改名——改名 = 设置页可见文字变化)。
|
|
74
|
+
*/
|
|
75
|
+
export declare function judgeAppearanceId(id: string, space: AppearanceIdSpace, pluginId: string, reserved: HostReservedNames): {
|
|
76
|
+
code: AppearanceIdCode;
|
|
77
|
+
suggested: string;
|
|
78
|
+
reserved?: string;
|
|
79
|
+
} | null;
|
|
80
|
+
/** theme JSON / 清单里 `"id": "<value>"` 的行号(1-based;找不到 ⇒ 1,不许当成「不存在」)——**复用命令腿那一份**(同一种 JSON 读取,⛔ 两条腿各写一份 = 迟早漂) */
|
|
81
|
+
export declare const themeIdLine: typeof manifestIdLine;
|
|
82
|
+
/** 读 theme JSON(含容错的 JSONC 剥注释 + 去尾逗号;读不出 ⇒ null,由调用方计入 `themeFilesUnparsed`) */
|
|
83
|
+
export declare function readThemeJson(abs: string): {
|
|
84
|
+
id?: string;
|
|
85
|
+
colorwayIds: string[];
|
|
86
|
+
} | null;
|
|
87
|
+
/**
|
|
88
|
+
* 跑本仓外观 id 归属判据。返回结构化报告(探针用)+ 腿报点(`lint.ts` 用)——**同一份实现**。
|
|
89
|
+
*/
|
|
90
|
+
export declare function runAppearanceOwnershipCheck(root: string, reserved?: HostReservedNames, reservedFile?: string): AppearanceOwnershipReport;
|
|
91
|
+
//# sourceMappingURL=appearance-ownership.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-ownership.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/appearance-ownership.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-appearance-ownership 腿·**外观族 id 归属判据**(E6#111f · 轮次 1.36)。
|
|
3
|
+
*
|
|
4
|
+
* ── 为什么(本件立项的那条轴)──
|
|
5
|
+
* 外观 id(配方 / 配色 / 图标主题 / 共享图标)是**全局名册的键**:配方 id 进 `app.theme` 取值空间、
|
|
6
|
+
* 配色 id 进 `app.themeColor` 取值空间,两者都由**壳的能力面**消费(主题卡片、配色下拉、图标主题选择器)。
|
|
7
|
+
* 不带本仓归属的 id ⇒ 两个插件可以声明**同一个名字**(今天后注册者**静默**覆盖 ⇒ 有一个永远不生效),
|
|
8
|
+
* 或者插件占**宿主兜底**的名字(`dark` / `light` / `dark-fallback` / `default`)⇒ 顶替宿主的保底面。
|
|
9
|
+
*
|
|
10
|
+
* ── 判据(与壳仓 `scripts/gen-host-reserved.mjs` 的账同源)──
|
|
11
|
+
* ① **本仓前缀**(🟡 黄):**新**声明的外观 id 第一段应是本仓 `pluginId`(`<pluginId>.<名字>`,只换第一段、词干零变化)。
|
|
12
|
+
* ⚠️ ★**回退条件**:1.36 任务书 §二.2 把它定为红**但附回退条件**——「若本格落地时判定存量改名不执行
|
|
13
|
+
* (例如 1.42 改名轮被砍),本判据**必须**回退到黄」。本格落地时:存量 25 条改名**判给 1.47**(不是本格执行)
|
|
14
|
+
* ⇒ 照轴上的**排序纪律**(1.32/1.34/1.36/1.38 的判据先以「黄灯 + 账」落地,**1.49 才收紧为红**)
|
|
15
|
+
* ——本判据在本格是**黄**,进 `advisories` 只打印不拦。
|
|
16
|
+
* 🔴 例外:**图标主题 id 不判①**(任务书 §二.2 ⑦:本轮不改名——改名会让设置页可见文字变化,
|
|
17
|
+
* 违「操作体验零变化」上位约束)⇒ 只判②。这一格不是漏了,是**判据表里"⚪不判"那一行的落地**。
|
|
18
|
+
* 🔴 **第二条同类例外(跑官方 18 仓实测抓到的缺陷)**:**宿主兜底 id 本身不判①**——它在账的**本空间**栏内,
|
|
19
|
+
* 要么已判红,要么你就是**持证照的实现者**。对后者建议 `<pluginId>.light` = 让官方实现者去改宿主的兜底名
|
|
20
|
+
* ⇒ **断掉「保底 → 官方实现」接替链**(本轴硬禁区),而且那条建议**永远修不得**。
|
|
21
|
+
* 实测读数(修前 / 修后):`theme-defaults` 报 **4 条黄 → 1 条黄**——被除掉的三条是 `light` 配方×2
|
|
22
|
+
* + `light` 配色(**修不得的建议**);留下的一条是配色 `dark`,它**是** `theme-defaults` 自己的配色变体
|
|
23
|
+
* (不在任何兜底栏内)⇒ 该改名,与 1.35 §13 的 16 条配色改名表一致。
|
|
24
|
+
* ② **宿主保留面**(🔴 红):声明 id ∈ 账(包内 `schemas/host-reserved.json`)**对应空间**那一栏,
|
|
25
|
+
* 且声明者**不在** `appearanceIdGrants[id]`(证照)里 ⇒ 占用宿主兜底面。**按空间比、绝不跨空间**:
|
|
26
|
+
* 配方 id 与配色 id 是**两个名字空间**(`mint-soda` 同时是两者)——合栏比会把官方 `theme-defaults`
|
|
27
|
+
* 的配色 `dark` 判成顶替配方 `dark`(**假红**;而它恰恰是宿主亮兜底的**官方实现者**,有 `light` 证照)。
|
|
28
|
+
* ③ **同插件跨配方同配色 id**(🟡 黄 + 登记):同一插件的两个配方声明同一个配色 id
|
|
29
|
+
* (壳侧 `theme.ts:92` 的契约是「配色变体 id 全局唯一」;跨配方重复今天表现为壳 UI 的 React key 碰撞)。
|
|
30
|
+
*
|
|
31
|
+
* ── 扫描面(两面)──
|
|
32
|
+
* · **声明面** `declared` = `plugin.json`:`contributes.themes[].id`(配方)/`contributes.iconThemes[].id`
|
|
33
|
+
* (图标主题)/`contributes.icons` 的键(共享图标);
|
|
34
|
+
* · **主题文件面** `themeFile` = 仓内 `themes/*.json`:顶层 `id`(配方)+ `colorways[].id`(配色)。
|
|
35
|
+
* 🔴 配色 id **只在这里出现**(plugin.json 不声明配色)——少了这一面,判据②对配色空间就是瞎子。
|
|
36
|
+
* · 哨兵空间(`followTheme`)**恒空转**:插件没有声明哨兵的通道(它是壳的取值约定,不是 id)。
|
|
37
|
+
*
|
|
38
|
+
* ── 🔴 与运行时同源 ──
|
|
39
|
+
* 壳运行时(`src/core/registry/appearance/appearanceOwnership.ts`)对**同样的三条分支**做仲裁:
|
|
40
|
+
* 判据② 命中在壳里是**当场拒注册 + console.error**;本腿是**提前在作者仓里把同一件事报出来**
|
|
41
|
+
* (作者不必等装上壳才发现自己的 id 被拒)。判据①③ 运行时不管(存量 25 条还在,运行时拒前缀不合规的 id
|
|
42
|
+
* 会把存量插件当场弄坏)⇒ 只在这里、且只是黄。
|
|
43
|
+
*
|
|
44
|
+
* 知情绕行 = 标准 disable 注释(`CHECK_IDS.appearanceOwnership`)。⚠️ **fail-closed 不参与豁免**:
|
|
45
|
+
* 拿不到 `pluginId` 说的不是「你的 id 怎么写」,而是「你的身份读不到」——那是工程根的问题。
|
|
46
|
+
*/
|
|
47
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
48
|
+
import { join, resolve } from "node:path";
|
|
49
|
+
import { resolvePluginIdForCss } from "./plugin-prefix.js";
|
|
50
|
+
import { HOST_RESERVED_FILE, loadHostReserved, manifestIdLine } from "./command-ownership.js";
|
|
51
|
+
import { isTestOrMockRel, relPath } from "./scan.js";
|
|
52
|
+
import { buildDisableIndex, isDisabled, CHECK_IDS } from "./disable.js";
|
|
53
|
+
/** 账里该空间的兜底 id 栏——**按空间取**(⛔ 永不跨空间:两个名字空间合栏 = 假红,见文件头判据②) */
|
|
54
|
+
export function reservedIdsForSpace(space, reserved) {
|
|
55
|
+
switch (space) {
|
|
56
|
+
case "recipe": return reserved.appearanceRecipeIds;
|
|
57
|
+
case "colorway": return reserved.appearanceColorwayIds;
|
|
58
|
+
case "iconTheme": return reserved.appearanceIconThemeIds;
|
|
59
|
+
case "sharedIcon": return []; // 宿主没有兜底共享图标(账里没有这一栏)——本空间只剩"跨插件同 id"那条判据
|
|
60
|
+
case "sentinel": return reserved.appearanceSentinels;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** 该 id 的**证照**持有者(账 `appearanceIdGrants`)——🔴 **按 id 记**,不是白名单(新插件永远不在表里) */
|
|
64
|
+
export function grantHoldersFor(id, reserved) {
|
|
65
|
+
return reserved.appearanceIdGrants[id] ?? [];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 一个外观 id 的裁决(纯函数——单测与探针共用,别在别处再写一份判据)。
|
|
69
|
+
*
|
|
70
|
+
* 🔴 判据顺序 = **先②后①**:占宿主兜底面是红,能同时命中「不带前缀」的那一半不该把红降级成黄。
|
|
71
|
+
* 🔴 判据① 对 `iconTheme` 空间**不判**(任务书 §二.2 ⑦:本轮不改名——改名 = 设置页可见文字变化)。
|
|
72
|
+
*/
|
|
73
|
+
export function judgeAppearanceId(id, space, pluginId, reserved) {
|
|
74
|
+
const dot = id.indexOf(".");
|
|
75
|
+
const suggested = `${pluginId}.${dot > 0 ? id.slice(dot + 1) : id}`;
|
|
76
|
+
// ② 宿主保留面(**按空间比全等**——保留面是一张逐个列出的 id 清单,不是前缀面)
|
|
77
|
+
if (reservedIdsForSpace(space, reserved).includes(id) && !grantHoldersFor(id, reserved).includes(pluginId)) {
|
|
78
|
+
return { code: "host-reserved", suggested, reserved: id };
|
|
79
|
+
}
|
|
80
|
+
// ① 本仓前缀(🔴 iconTheme 不判——见文件头;sentinel 无声明通道,也不判)
|
|
81
|
+
if (space === "recipe" || space === "colorway" || space === "sharedIcon") {
|
|
82
|
+
// 🔴 **宿主兜底 id 本身不判①**(跑官方 18 仓实测抓到的缺陷,见文件头):它在**本空间**账内 ⇒
|
|
83
|
+
// 要么上面已判红(无证照),要么你是**持证照的实现者**(`light` ⇐ theme-defaults)。给后者建议
|
|
84
|
+
// `<pluginId>.light` = 让官方实现者去改宿主兜底的名字 ⇒ **断掉「保底 → 官方实现」接替链**
|
|
85
|
+
// (本轴硬禁区),且那条建议**永远修不得** ⇒ 报它 = 报一个不允许修的洞(与 iconTheme 不判①同理)。
|
|
86
|
+
if (!reservedIdsForSpace(space, reserved).includes(id) && !id.startsWith(`${pluginId}.`)) {
|
|
87
|
+
return { code: "no-plugin-prefix", suggested };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
/** theme JSON / 清单里 `"id": "<value>"` 的行号(1-based;找不到 ⇒ 1,不许当成「不存在」)——**复用命令腿那一份**(同一种 JSON 读取,⛔ 两条腿各写一份 = 迟早漂) */
|
|
93
|
+
export const themeIdLine = manifestIdLine;
|
|
94
|
+
/** 读 theme JSON(含容错的 JSONC 剥注释 + 去尾逗号;读不出 ⇒ null,由调用方计入 `themeFilesUnparsed`) */
|
|
95
|
+
export function readThemeJson(abs) {
|
|
96
|
+
let raw;
|
|
97
|
+
try {
|
|
98
|
+
raw = readFileSync(abs, "utf8");
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const cleaned = raw
|
|
105
|
+
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
106
|
+
.replace(/(^|[^:"'\\])\/\/.*$/gm, "$1")
|
|
107
|
+
.replace(/,(\s*[}\]])/g, "$1");
|
|
108
|
+
const data = JSON.parse(cleaned);
|
|
109
|
+
const colorwayIds = Array.isArray(data.colorways)
|
|
110
|
+
? data.colorways
|
|
111
|
+
.map((c) => c?.id)
|
|
112
|
+
.filter((v) => typeof v === "string" && v.length > 0)
|
|
113
|
+
: [];
|
|
114
|
+
return { ...(typeof data.id === "string" && data.id ? { id: data.id } : {}), colorwayIds };
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** 主题实体文件(仓内 `themes/*.json`,含子目录)
|
|
121
|
+
* ⚠️ `isTestOrMockRel` 只认 `.ts/.tsx/.js/.jsx` **文件名**(`*.test.ts` / `*.fixture.ts`)⇒ 对 `.json` **恒 false**;
|
|
122
|
+
* 这里仍然带着它,只为与另几条腿**同形状**(哪天那个共享谓词学会目录级口径,几条腿一起变)。
|
|
123
|
+
* 🔴 也就是说:**主题文件面目前不跳任何文件**——那不是漏了:主题 JSON 是**发布产物**,出现在 `themes/` 下
|
|
124
|
+
* 就是真声明。在这里另写一个「目录级跳过」= 凭空造第二条口径,只会与另几条腿漂。 */
|
|
125
|
+
function themeFilesOf(root) {
|
|
126
|
+
const dir = join(root, "themes");
|
|
127
|
+
if (!existsSync(dir))
|
|
128
|
+
return [];
|
|
129
|
+
const out = [];
|
|
130
|
+
const walk = (cur) => {
|
|
131
|
+
let entries;
|
|
132
|
+
try {
|
|
133
|
+
entries = readdirSync(cur, { withFileTypes: true });
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
for (const e of entries) {
|
|
139
|
+
if (e.name === "node_modules" || e.name === ".git")
|
|
140
|
+
continue;
|
|
141
|
+
const p = join(cur, e.name);
|
|
142
|
+
if (e.isDirectory())
|
|
143
|
+
walk(p);
|
|
144
|
+
else if (e.isFile() && e.name.endsWith(".json") && !isTestOrMockRel(relPath(root, p)))
|
|
145
|
+
out.push(p);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
walk(dir);
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
/** `contributes` 里的主题声明/图标主题声明/共享图标键(读不出 ⇒ 都空) */
|
|
152
|
+
function contributeIdsOf(contributes) {
|
|
153
|
+
const idsOf = (node) => Array.isArray(node)
|
|
154
|
+
? node.map((x) => x?.id).filter((v) => typeof v === "string" && v.length > 0)
|
|
155
|
+
: [];
|
|
156
|
+
const icons = contributes?.icons;
|
|
157
|
+
return {
|
|
158
|
+
themeIds: idsOf(contributes?.themes),
|
|
159
|
+
iconThemeIds: idsOf(contributes?.iconThemes),
|
|
160
|
+
sharedIconIds: icons && typeof icons === "object" && !Array.isArray(icons) ? Object.keys(icons) : [],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* 跑本仓外观 id 归属判据。返回结构化报告(探针用)+ 腿报点(`lint.ts` 用)——**同一份实现**。
|
|
165
|
+
*/
|
|
166
|
+
export function runAppearanceOwnershipCheck(root, reserved = loadHostReserved(), reservedFile = HOST_RESERVED_FILE) {
|
|
167
|
+
const absRoot = resolve(root);
|
|
168
|
+
const manifestPath = join(absRoot, "plugin.json");
|
|
169
|
+
const resolution = resolvePluginIdForCss(absRoot);
|
|
170
|
+
const violations = [];
|
|
171
|
+
const report = {
|
|
172
|
+
root: absRoot,
|
|
173
|
+
pluginId: resolution.pluginId,
|
|
174
|
+
pluginIdSource: resolution.source,
|
|
175
|
+
pluginIdNote: resolution.note,
|
|
176
|
+
error: resolution.error,
|
|
177
|
+
red: [],
|
|
178
|
+
yellow: [],
|
|
179
|
+
declaredRecipeIds: [],
|
|
180
|
+
declaredIconThemeIds: [],
|
|
181
|
+
declaredSharedIconIds: [],
|
|
182
|
+
themeFileRecipeIds: [],
|
|
183
|
+
themeFileColorwayIds: [],
|
|
184
|
+
themeFilesUnparsed: 0,
|
|
185
|
+
hostLedger: {
|
|
186
|
+
file: reservedFile,
|
|
187
|
+
found: existsSync(reservedFile),
|
|
188
|
+
appearanceRecipeIds: reserved.appearanceRecipeIds.length,
|
|
189
|
+
appearanceColorwayIds: reserved.appearanceColorwayIds.length,
|
|
190
|
+
appearanceIconThemeIds: reserved.appearanceIconThemeIds.length,
|
|
191
|
+
appearanceSentinels: reserved.appearanceSentinels.length,
|
|
192
|
+
appearanceIdGrants: Object.keys(reserved.appearanceIdGrants).length,
|
|
193
|
+
},
|
|
194
|
+
violations,
|
|
195
|
+
advisories: [],
|
|
196
|
+
};
|
|
197
|
+
// ── fail-closed(不可豁免:拿不到身份 = 判据①② 全部无从谈起)──
|
|
198
|
+
if (resolution.error || !resolution.pluginId) {
|
|
199
|
+
violations.push({
|
|
200
|
+
file: "plugin.json",
|
|
201
|
+
line: 1,
|
|
202
|
+
message: `拿不到本仓 pluginId:${resolution.error}。外观 id 的归属判据以「本仓身份」为唯一前缀来源——读不到它就无从判` +
|
|
203
|
+
`「这个 id 是不是你的」。在插件工程根修好 plugin.json(或显式声明 pluginId),` +
|
|
204
|
+
`别用 disable 注释绕:这是身份问题,不受豁免注释管辖。`,
|
|
205
|
+
});
|
|
206
|
+
return report;
|
|
207
|
+
}
|
|
208
|
+
const pluginId = resolution.pluginId;
|
|
209
|
+
const prefix = `${pluginId}.`;
|
|
210
|
+
const manifestRaw = existsSync(manifestPath) ? readFileSync(manifestPath, "utf8") : "";
|
|
211
|
+
const manifestDisabled = buildDisableIndex(manifestRaw, [CHECK_IDS.appearanceOwnership]);
|
|
212
|
+
const push = (site, message, disabled) => {
|
|
213
|
+
if (disabled && isDisabled(disabled.idx, disabled.line, CHECK_IDS.appearanceOwnership))
|
|
214
|
+
return;
|
|
215
|
+
if (site.code === "host-reserved") {
|
|
216
|
+
report.red.push(site);
|
|
217
|
+
violations.push({ file: site.file, line: site.line, message });
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
report.yellow.push(site);
|
|
221
|
+
report.advisories.push({ file: site.file, line: site.line, message });
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
/** 判据②① 合一的报点(两个面共用) */
|
|
225
|
+
const judgeAndPush = (face, space, id, file, line) => {
|
|
226
|
+
const verdict = judgeAppearanceId(id, space, pluginId, reserved);
|
|
227
|
+
if (!verdict)
|
|
228
|
+
return;
|
|
229
|
+
const where = face === "declared"
|
|
230
|
+
? "声明面(plugin.json contributes)"
|
|
231
|
+
: "主题文件面(themes/*.json)";
|
|
232
|
+
const spaceLabel = space === "recipe" ? "配方 id" : space === "colorway" ? "配色变体 id" : space === "iconTheme" ? "图标主题 id" : "共享图标 id";
|
|
233
|
+
const message = verdict.code === "host-reserved"
|
|
234
|
+
? `${where}:${spaceLabel} "${id}" 属于**宿主的兜底面**(保留清单见包内 schemas/host-reserved.json 的 ` +
|
|
235
|
+
`appearance${space === "recipe" ? "RecipeIds" : space === "colorway" ? "ColorwayIds" : space === "iconTheme" ? "IconThemeIds" : "Sentinels"})。` +
|
|
236
|
+
`占用它 = 顶替宿主保底(壳运行时会**当场拒绝注册**这条 id 并报错)——宿主兜底是"全部主题插件卸载后仍能渲染"的那一层。` +
|
|
237
|
+
`改法:改成 "${verdict.suggested}"(只换第一段、词干零变化);若你确实是宿主兜底的官方实现者,` +
|
|
238
|
+
`需在账的 appearanceIdGrants 里为该 id 记一条证照(一次公共面决策,不是作者自己能加的)。`
|
|
239
|
+
: `${where}:${spaceLabel} "${id}" 不带本仓归属(本插件 pluginId = "${pluginId}",新 ${spaceLabel}应以 "${prefix}" 开头)` +
|
|
240
|
+
`——外观 id 是**全局名册的键**:同名 id 被两个插件声明时只有一个能生效(壳 1.36 起"先者保留",后到者被拒),` +
|
|
241
|
+
`跨插件撞名还会在校验层被记一笔。改成 "${verdict.suggested}"(只换第一段、词干零变化)。`;
|
|
242
|
+
push({ face, file, line, id, space, code: verdict.code, suggested: verdict.suggested, ...(verdict.reserved !== undefined ? { reserved: verdict.reserved } : {}) }, message, { idx: face === "declared" ? manifestDisabled : buildDisableIndex(readFileSync(join(absRoot, file), "utf8"), [CHECK_IDS.appearanceOwnership]), line });
|
|
243
|
+
};
|
|
244
|
+
// ── ①② 声明面:plugin.json(读不出 ⇒ 跳过——plugin-prefix 腿已对同一件事 fail-closed 报红,不重复报)
|
|
245
|
+
if (manifestRaw) {
|
|
246
|
+
let contributes;
|
|
247
|
+
try {
|
|
248
|
+
const manifest = JSON.parse(manifestRaw.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'\\])\/\/.*$/gm, "$1").replace(/,(\s*[}\]])/g, "$1"));
|
|
249
|
+
contributes = manifest.contributes;
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
contributes = undefined; // manifest 坏 → 由 plugin-prefix 腿报;这里不重复
|
|
253
|
+
}
|
|
254
|
+
const { themeIds, iconThemeIds, sharedIconIds } = contributeIdsOf(contributes);
|
|
255
|
+
for (const id of themeIds) {
|
|
256
|
+
if (!report.declaredRecipeIds.includes(id))
|
|
257
|
+
report.declaredRecipeIds.push(id);
|
|
258
|
+
judgeAndPush("declared", "recipe", id, "plugin.json", themeIdLine(manifestRaw, id));
|
|
259
|
+
}
|
|
260
|
+
for (const id of iconThemeIds) {
|
|
261
|
+
if (!report.declaredIconThemeIds.includes(id))
|
|
262
|
+
report.declaredIconThemeIds.push(id);
|
|
263
|
+
judgeAndPush("declared", "iconTheme", id, "plugin.json", themeIdLine(manifestRaw, id));
|
|
264
|
+
}
|
|
265
|
+
for (const id of sharedIconIds) {
|
|
266
|
+
if (!report.declaredSharedIconIds.includes(id))
|
|
267
|
+
report.declaredSharedIconIds.push(id);
|
|
268
|
+
judgeAndPush("declared", "sharedIcon", id, "plugin.json", themeIdLine(manifestRaw, id));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// ── ①② 主题文件面:themes/*.json(顶层 id = 配方;colorways[].id = 配色)
|
|
272
|
+
// 🔴 配色 id **只在这一面出现**——少了它,判据②对配色空间就是瞎子。
|
|
273
|
+
const colorwayFiles = new Map(); // colorwayId → 声明它的主题文件(判据③用)
|
|
274
|
+
for (const abs of themeFilesOf(absRoot)) {
|
|
275
|
+
const rel = relPath(absRoot, abs);
|
|
276
|
+
const raw = readFileSync(abs, "utf8");
|
|
277
|
+
const data = readThemeJson(abs);
|
|
278
|
+
if (!data) {
|
|
279
|
+
report.themeFilesUnparsed++;
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (data.id) {
|
|
283
|
+
if (!report.themeFileRecipeIds.includes(data.id))
|
|
284
|
+
report.themeFileRecipeIds.push(data.id);
|
|
285
|
+
judgeAndPush("themeFile", "recipe", data.id, rel, themeIdLine(raw, data.id));
|
|
286
|
+
}
|
|
287
|
+
for (const cw of data.colorwayIds) {
|
|
288
|
+
if (!report.themeFileColorwayIds.includes(cw))
|
|
289
|
+
report.themeFileColorwayIds.push(cw);
|
|
290
|
+
judgeAndPush("themeFile", "colorway", cw, rel, themeIdLine(raw, cw));
|
|
291
|
+
const files = colorwayFiles.get(cw) ?? [];
|
|
292
|
+
if (!files.includes(rel))
|
|
293
|
+
files.push(rel);
|
|
294
|
+
colorwayFiles.set(cw, files);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// ── ③ 同插件跨配方同配色 id(🟡 黄 + 登记):同一配色 id 出现在**两个不同主题文件**里
|
|
298
|
+
// 契约出处 = 壳 `theme.ts` 的「配色变体 id 须全局唯一」(跨配方重复今天表现为壳 UI 的 React key 碰撞)。
|
|
299
|
+
for (const [cw, files] of colorwayFiles) {
|
|
300
|
+
if (files.length < 2)
|
|
301
|
+
continue;
|
|
302
|
+
const verdict = judgeAppearanceId(cw, "colorway", pluginId, reserved);
|
|
303
|
+
// 已被判红/黄的 id 不重复报(红的意思已经说过了——同一处报两次只会稀释信号)
|
|
304
|
+
if (verdict)
|
|
305
|
+
continue;
|
|
306
|
+
for (const file of files.slice(1)) {
|
|
307
|
+
push({ face: "themeFile", file, line: themeIdLine(readFileSync(join(absRoot, file), "utf8"), cw), id: cw, space: "colorway", code: "same-plugin-colorway", suggested: `${prefix}${cw.includes(".") ? cw.slice(cw.indexOf(".") + 1) : cw}` }, `主题文件面:配色变体 id "${cw}" 在本插件被声明了 ${files.length} 次(${files.join(" / ")})` +
|
|
308
|
+
`——壳的契约是「配色变体 id **全局唯一**」(跨配方重复会让壳 UI 的配色下拉出现重复项/React key 碰撞)。` +
|
|
309
|
+
`改法:每个配方用自己的配色 id(形如 "${prefix}<配方名>.<配色名>")。`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return report;
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=appearance-ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-ownership.js","sourceRoot":"","sources":["../../../src/eslint/checks/appearance-ownership.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-ownership.test.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/appearance-ownership.test.ts"],"names":[],"mappings":""}
|