skinsuite 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -6
- package/dist/constants.d.ts +44 -7
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +44 -7
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +32 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -4
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +83 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +90 -0
- package/dist/manifest.js.map +1 -0
- package/dist/registry.d.ts +73 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +299 -0
- package/dist/registry.js.map +1 -0
- package/dist/remote-config.d.ts +25 -0
- package/dist/remote-config.d.ts.map +1 -0
- package/dist/remote-config.js +43 -0
- package/dist/remote-config.js.map +1 -0
- package/dist/scheme.d.ts +36 -0
- package/dist/scheme.d.ts.map +1 -0
- package/dist/scheme.js +47 -0
- package/dist/scheme.js.map +1 -0
- package/dist/types.d.ts +17 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/views/device-registry.d.ts +45 -0
- package/dist/views/device-registry.d.ts.map +1 -0
- package/dist/views/device-registry.js +55 -0
- package/dist/views/device-registry.js.map +1 -0
- package/dist/views/device.d.ts +63 -0
- package/dist/views/device.d.ts.map +1 -0
- package/dist/views/device.js +59 -0
- package/dist/views/device.js.map +1 -0
- package/dist/views/params.d.ts +24 -21
- package/dist/views/params.d.ts.map +1 -1
- package/dist/views/params.js +11 -11
- package/dist/views/params.js.map +1 -1
- package/docs/onboarding.md +479 -0
- package/package.json +23 -2
- package/src/constants.ts +141 -100
- package/src/index.ts +128 -65
- package/src/manifest.ts +131 -0
- package/src/registry.ts +400 -0
- package/src/scheme.ts +94 -0
- package/src/types.ts +19 -1
- package/src/views/device-registry.ts +96 -0
- package/src/views/device.ts +107 -0
- package/src/views/params.ts +26 -23
- package/src/vite/dir.ts +85 -0
- package/src/vite/index.ts +41 -0
- package/src/vite/plugin.ts +409 -0
- package/src/vite/theme.d.ts +49 -0
- package/src/vue/ThemeDebugPanel.vue +36 -0
- package/src/vue/ThemeDebugPanelBody.vue +505 -0
- package/src/vue/ThemeRoot.vue +59 -0
- package/src/vue/ThemeView.vue +92 -0
- package/src/vue/create-theme-state.ts +116 -0
- package/src/vue/define-theme-device.ts +157 -0
- package/src/vue/device-containers.ts +73 -0
- package/src/vue/device-domain.ts +149 -0
- package/src/vue/index.ts +98 -0
- package/src/vue/panel.ts +16 -0
- package/src/vue/plugin.ts +35 -0
- package/src/vue/remote-fetch.ts +74 -0
- package/src/vue/theme-intent.ts +157 -0
- package/src/vue/theme-persistence.ts +136 -0
- package/src/vue/theme-runtime.ts +163 -0
- package/src/vue/theme-scope.ts +148 -0
- package/src/vue/theme-store.ts +58 -0
- package/src/vue/theme-views.ts +39 -0
- package/src/vue/token-runtime.ts +81 -0
- package/src/vue/types.ts +67 -0
- package/src/vue/useParentThemeSync.ts +99 -0
- package/src/vue/useThemeDebugPanel.ts +192 -0
- package/src/vue/useThemeSources.ts +74 -0
- package/src/vue/view-page.ts +99 -0
- package/src/vue/view-registry.ts +215 -0
- package/src/vue/viewport.ts +54 -0
- package/src/mode.ts +0 -38
- package/src/tone.ts +0 -56
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 设备清单机制(**纯逻辑半边**)—— 「哪些设备、怎么判定」的唯一实现(内核版)
|
|
3
|
+
*
|
|
4
|
+
* === 设备 = 路由 + 容器 = 版式信息的一部分 ===
|
|
5
|
+
* 「有哪些设备」是宿主的部署事实(每个应用设备不同、容器位置不同),所以**设备清单
|
|
6
|
+
* (`DeviceDef[]`)由宿主声明**;但「怎么从清单判定出当前设备、怎么归一化外部输入、
|
|
7
|
+
* 怎么取容器」是**通用机制**,收在这里 —— 加一种设备时宿主只加一条声明,判定逻辑零改动。
|
|
8
|
+
*
|
|
9
|
+
* === 为什么这里只有「判定」、没有「组件」 ===
|
|
10
|
+
* 本文件是**纯逻辑**(不含 `Component` 类型),能被内核 tsc 独立检查、也能被任何前端复用。
|
|
11
|
+
* `containers` 用泛型 `T` 表达(宿主的「设备容器加载器」是 `T`),组件加载的**具体机制**
|
|
12
|
+
* (`pageContainers` / `resolveContainerOf`)在 `skinsuite/vue` 的 `device-containers`,
|
|
13
|
+
* 那里才 import Vue 的 `Component`。
|
|
14
|
+
*
|
|
15
|
+
* === 判定顺序就是清单顺序(先命中先用),最后一条必须无条件成立 ===
|
|
16
|
+
* 它是兜底设备。宿主关卡会核这一条。
|
|
17
|
+
*
|
|
18
|
+
* === 为什么判定必须收在一处 ===
|
|
19
|
+
* 三个分发器曾经各写一份「mini 来源」判定,口径不一致 → 同一个链接在不同页面落到
|
|
20
|
+
* 不同设备。现在判定只有一份,各页面自然同形。
|
|
21
|
+
*
|
|
22
|
+
* @author yijiu2025
|
|
23
|
+
* @since 2026-10-17(从 oauth21/src/theme/devices.ts 下沉)
|
|
24
|
+
*/
|
|
25
|
+
/** 判定上下文 —— 判定所需的**全部**外部信息(与页面无关的原始事实) */
|
|
26
|
+
export interface DeviceMatchContext {
|
|
27
|
+
/** `?isMobile=true` —— 显式意图,优先级最高 */
|
|
28
|
+
explicitMobile: boolean;
|
|
29
|
+
/** 路由 path(不含 query / hash) */
|
|
30
|
+
path: string;
|
|
31
|
+
/** `?from=` 的取值(iframe 来源标记,空串表示没给) */
|
|
32
|
+
from: string;
|
|
33
|
+
/** `?fromLogin=` 的取值(历史键:从 mini 登录页跳来) */
|
|
34
|
+
fromLogin: string;
|
|
35
|
+
/** 视口/UA 判定结果 */
|
|
36
|
+
viewportIsMobile: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** 一条设备声明(`containers` 是泛型:纯逻辑侧不关心它到底是什么,只透传) */
|
|
39
|
+
export interface DeviceDef<T = unknown> {
|
|
40
|
+
/** 设备 id = 主题包内的目录名,只允许 `[a-z0-9-]` */
|
|
41
|
+
id: string;
|
|
42
|
+
/** 中文名(调试面板 / 日志用) */
|
|
43
|
+
label: string;
|
|
44
|
+
/** 缩写名(URL 专属参数后缀用,如 `?th_<urlKey>` / `?th_color_<urlKey>`);缺省回落 `id` */
|
|
45
|
+
urlKey?: string;
|
|
46
|
+
/** 该设备在某页的容器(分发器渲染它);返回 undefined 表示「该设备没有这一页的容器」 */
|
|
47
|
+
containers: ReadonlyMap<string, T>;
|
|
48
|
+
/** 该设备在路由表里占的 path(相对根,`{page}` 由页面名替换) */
|
|
49
|
+
routePath(page: string): string;
|
|
50
|
+
/** 本次访问是否属于这台设备(清单顺序 = 优先级,先命中先用) */
|
|
51
|
+
match(ctx: DeviceMatchContext): boolean;
|
|
52
|
+
}
|
|
53
|
+
/** 归一化外部传入的设备名;不认识的取值返回 null(**不是**落默认设备) */
|
|
54
|
+
export declare function asDeviceId<T extends string>(known: readonly string[], raw: unknown): T | null;
|
|
55
|
+
/** 设备 id → 中文名(调试面板用;加设备不必再改面板) */
|
|
56
|
+
export declare function deviceLabel<T>(defs: readonly DeviceDef<T>[], id: string): string;
|
|
57
|
+
/** 从外部输入判定「本次访问属于哪台设备」;清单顺序 = 优先级,返回值永远非空 */
|
|
58
|
+
export declare function pickDeviceId<T>(defs: readonly DeviceDef<T>[], ctx: DeviceMatchContext, defaultDevice: string): string;
|
|
59
|
+
/** 取某设备的容器表;未知设备返回空表(调用方退到兜底设备) */
|
|
60
|
+
export declare function containersOf<T>(defs: readonly DeviceDef<T>[], id: string): ReadonlyMap<string, T>;
|
|
61
|
+
/** 从当前访问信息构造判定上下文 */
|
|
62
|
+
export declare function deviceContext(query: Record<string, unknown> | undefined, path: string, viewportIsMobile: boolean): DeviceMatchContext;
|
|
63
|
+
//# sourceMappingURL=device.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/views/device.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,2CAA2C;AAC3C,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,cAAc,EAAE,OAAO,CAAC;IACxB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB;IACjB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,OAAO;IACpC,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACnC,2CAA2C;IAC3C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,qCAAqC;IACrC,KAAK,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC;CACzC;AAED,6CAA6C;AAC7C,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,GAAG,EAAE,OAAO,GACX,CAAC,GAAG,IAAI,CAIV;AAED,mCAAmC;AACnC,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,6CAA6C;AAC7C,wBAAgB,YAAY,CAAC,CAAC,EAC5B,IAAI,EAAE,SAAS,SAAS,CAAC,CAAC,CAAC,EAAE,EAC7B,GAAG,EAAE,kBAAkB,EACvB,aAAa,EAAE,MAAM,GACpB,MAAM,CAMR;AAED,mCAAmC;AACnC,wBAAgB,YAAY,CAAC,CAAC,EAC5B,IAAI,EAAE,SAAS,SAAS,CAAC,CAAC,CAAC,EAAE,EAC7B,EAAE,EAAE,MAAM,GACT,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAExB;AAED,qBAAqB;AACrB,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC1C,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,OAAO,GACxB,kBAAkB,CAUpB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 设备清单机制(**纯逻辑半边**)—— 「哪些设备、怎么判定」的唯一实现(内核版)
|
|
3
|
+
*
|
|
4
|
+
* === 设备 = 路由 + 容器 = 版式信息的一部分 ===
|
|
5
|
+
* 「有哪些设备」是宿主的部署事实(每个应用设备不同、容器位置不同),所以**设备清单
|
|
6
|
+
* (`DeviceDef[]`)由宿主声明**;但「怎么从清单判定出当前设备、怎么归一化外部输入、
|
|
7
|
+
* 怎么取容器」是**通用机制**,收在这里 —— 加一种设备时宿主只加一条声明,判定逻辑零改动。
|
|
8
|
+
*
|
|
9
|
+
* === 为什么这里只有「判定」、没有「组件」 ===
|
|
10
|
+
* 本文件是**纯逻辑**(不含 `Component` 类型),能被内核 tsc 独立检查、也能被任何前端复用。
|
|
11
|
+
* `containers` 用泛型 `T` 表达(宿主的「设备容器加载器」是 `T`),组件加载的**具体机制**
|
|
12
|
+
* (`pageContainers` / `resolveContainerOf`)在 `skinsuite/vue` 的 `device-containers`,
|
|
13
|
+
* 那里才 import Vue 的 `Component`。
|
|
14
|
+
*
|
|
15
|
+
* === 判定顺序就是清单顺序(先命中先用),最后一条必须无条件成立 ===
|
|
16
|
+
* 它是兜底设备。宿主关卡会核这一条。
|
|
17
|
+
*
|
|
18
|
+
* === 为什么判定必须收在一处 ===
|
|
19
|
+
* 三个分发器曾经各写一份「mini 来源」判定,口径不一致 → 同一个链接在不同页面落到
|
|
20
|
+
* 不同设备。现在判定只有一份,各页面自然同形。
|
|
21
|
+
*
|
|
22
|
+
* @author yijiu2025
|
|
23
|
+
* @since 2026-10-17(从 oauth21/src/theme/devices.ts 下沉)
|
|
24
|
+
*/
|
|
25
|
+
/** 归一化外部传入的设备名;不认识的取值返回 null(**不是**落默认设备) */
|
|
26
|
+
export function asDeviceId(known, raw) {
|
|
27
|
+
return typeof raw === 'string' && known.includes(raw)
|
|
28
|
+
? raw
|
|
29
|
+
: null;
|
|
30
|
+
}
|
|
31
|
+
/** 设备 id → 中文名(调试面板用;加设备不必再改面板) */
|
|
32
|
+
export function deviceLabel(defs, id) {
|
|
33
|
+
return defs.find(def => def.id === id)?.label ?? id;
|
|
34
|
+
}
|
|
35
|
+
/** 从外部输入判定「本次访问属于哪台设备」;清单顺序 = 优先级,返回值永远非空 */
|
|
36
|
+
export function pickDeviceId(defs, ctx, defaultDevice) {
|
|
37
|
+
for (const def of defs) {
|
|
38
|
+
if (def.match(ctx))
|
|
39
|
+
return def.id;
|
|
40
|
+
}
|
|
41
|
+
// 清单被改坏(末条不再无条件成立)时的保底
|
|
42
|
+
return defaultDevice;
|
|
43
|
+
}
|
|
44
|
+
/** 取某设备的容器表;未知设备返回空表(调用方退到兜底设备) */
|
|
45
|
+
export function containersOf(defs, id) {
|
|
46
|
+
return defs.find(def => def.id === id)?.containers ?? new Map();
|
|
47
|
+
}
|
|
48
|
+
/** 从当前访问信息构造判定上下文 */
|
|
49
|
+
export function deviceContext(query, path, viewportIsMobile) {
|
|
50
|
+
const text = (key) => typeof query?.[key] === 'string' ? query[key] : '';
|
|
51
|
+
return {
|
|
52
|
+
explicitMobile: text('isMobile') === 'true',
|
|
53
|
+
path: path.split(/[?#]/)[0],
|
|
54
|
+
from: text('from'),
|
|
55
|
+
fromLogin: text('fromLogin'),
|
|
56
|
+
viewportIsMobile
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/views/device.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAgCH,6CAA6C;AAC7C,MAAM,UAAU,UAAU,CACxB,KAAwB,EACxB,GAAY;IAEZ,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAK,KAA2B,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC1E,CAAC,CAAE,GAAS;QACZ,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,WAAW,CAAI,IAA6B,EAAE,EAAU;IACtE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;AACtD,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,YAAY,CAC1B,IAA6B,EAC7B,GAAuB,EACvB,aAAqB;IAErB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC,EAAE,CAAC;IACpC,CAAC;IACD,uBAAuB;IACvB,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,YAAY,CAC1B,IAA6B,EAC7B,EAAU;IAEV,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,IAAI,IAAI,GAAG,EAAE,CAAC;AAClE,CAAC;AAED,qBAAqB;AACrB,MAAM,UAAU,aAAa,CAC3B,KAA0C,EAC1C,IAAY,EACZ,gBAAyB;IAEzB,MAAM,IAAI,GAAG,CAAC,GAAW,EAAU,EAAE,CACnC,OAAO,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,KAAK,CAAC,GAAG,CAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,OAAO;QACL,cAAc,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,MAAM;QAC3C,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;QAClB,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC;QAC5B,gBAAgB;KACjB,CAAC;AACJ,CAAC"}
|
package/dist/views/params.d.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 版式 / 配色参数的**设备维度**解析 —— `?th` / `?th_color`(下划线 + 设备缩写名)
|
|
3
|
+
*
|
|
4
|
+
* === 参数命名(2026-10-18 定稿,统一用下划线、禁用点号)===
|
|
5
|
+
* 版式:`?th`(三端通用) `?th_<设备缩写>`(某设备专属)
|
|
6
|
+
* 配色:`?th_color`(三端通用) `?th_color_<设备缩写>`(某设备专属)
|
|
7
|
+
* 设备专属键的后缀是**设备缩写名(urlKey)**,不是设备 id —— 由设备清单声明
|
|
8
|
+
* (`defineThemeDevice` 的 `urlKey`,缺省回落 `id`),内核不硬编码任何缩写。
|
|
3
9
|
*
|
|
4
10
|
* === 解决什么 ===
|
|
5
11
|
* 同一条链接要能给三台设备各指定一套版式:
|
|
6
12
|
* ```
|
|
7
|
-
* /login?
|
|
8
|
-
* /login?
|
|
9
|
-
* /login?
|
|
13
|
+
* /login?th=compact 三端共用(哪端没有就自动下沉到当前包)
|
|
14
|
+
* /login?th_mobile=default&th_std=compact 各端各指定(mini 走通用/包默认)
|
|
15
|
+
* /login?th_mobile=default&th=default 设备专属优先,通用键兜底
|
|
10
16
|
* ```
|
|
11
17
|
*
|
|
12
18
|
* === 取值链(每台设备各一条)===
|
|
13
|
-
* `
|
|
19
|
+
* `th_<urlKey>` → `th` → (返回 undefined:由调用方走包声明 → 当前包)
|
|
14
20
|
*
|
|
15
21
|
* === 为什么收在内核(而不是各页文件里)===
|
|
16
22
|
* 三个页面(login / register / forgot-password)各有**一份**注册表文件,但"哪个 query
|
|
@@ -21,36 +27,33 @@
|
|
|
21
27
|
*
|
|
22
28
|
* === 与配色侧同形(很重要)===
|
|
23
29
|
* 配色侧(`oauth21/src/stores/theme.ts` 的 `readUrlIntent`)用同样的键形
|
|
24
|
-
* (`
|
|
25
|
-
* 否则配置者要记两套规则,`?
|
|
30
|
+
* (`th_color_<urlKey>` / `th_color`)与同样的"设备专属优先"链。**两侧必须同形**,
|
|
31
|
+
* 否则配置者要记两套规则,`?th_color_mobile=blue&th_std=compact` 这种混搭就写不出来。
|
|
26
32
|
* 但两侧读的入口不同:配色侧读 `window.location.search`(store 是全局的,不依赖路由),
|
|
27
33
|
* 版式侧读**路由 query**(容器手上只有 `route.query`)—— 所以不是同一个函数,是同一套规则。
|
|
28
34
|
*
|
|
29
|
-
* ⚠️ query key 里带 `.` 是合法的(`URLSearchParams` 与 vue-router 都原样保留),
|
|
30
|
-
* 但访问时**必须用下标**(`query['view.standard']`)—— 点号在 JS 里不是合法标识符。
|
|
31
|
-
*
|
|
32
35
|
* @author yijiu2025
|
|
33
|
-
* @since 2026-09-26
|
|
36
|
+
* @since 2026-09-26(2026-10-18 改下划线 + urlKey:`?view.` → `?th_`、`?theme.` → `?th_color_`)
|
|
34
37
|
*/
|
|
35
38
|
/** 支持设备维度的参数名(与配色侧 `readUrlIntent` 的键保持一致) */
|
|
36
|
-
export type DeviceScopedParam = '
|
|
39
|
+
export type DeviceScopedParam = 'th' | 'th_color';
|
|
37
40
|
export declare const DEVICE_SCOPED_PARAMS: readonly DeviceScopedParam[];
|
|
38
41
|
/**
|
|
39
42
|
* 按**设备**读取版式 / 配色参数
|
|
40
43
|
*
|
|
41
|
-
* @param query
|
|
42
|
-
* @param name
|
|
43
|
-
* @param
|
|
44
|
-
* @returns `query['<name
|
|
44
|
+
* @param query 路由 query(`route.query`)
|
|
45
|
+
* @param name 参数名(`'th'` / `'th_color'`)
|
|
46
|
+
* @param deviceKey 设备**缩写名(urlKey)** —— 由调用方用 `urlKeyOf(deviceId)` 从设备清单查
|
|
47
|
+
* @returns `query['<name>_<deviceKey>']` 优先;缺席或空值时退 `query[name]`;
|
|
45
48
|
* 两者都没有则返回 undefined,表示"**这台设备**没有被显式指定"
|
|
46
49
|
*
|
|
47
50
|
* ⚠️ 只决定"取哪个键",**不做合法性校验** —— 校验属于各页 `pick*ViewId` 与配色注册表
|
|
48
|
-
* (本函数也拿不到"当前包里有没有这套版式")。返回值可能是数组(`?
|
|
51
|
+
* (本函数也拿不到"当前包里有没有这套版式")。返回值可能是数组(`?th=a&th=b`),
|
|
49
52
|
* 由下游按"非字符串即非法"处理,与改前的行为一致。
|
|
50
|
-
* ⚠️ 空串视为"未指定":`?
|
|
53
|
+
* ⚠️ 空串视为"未指定":`?th_std=` 不该把 `?th=compact` 顶掉 ——
|
|
51
54
|
* 部署方常把参数留空当作"这台设备不特殊指定"。
|
|
52
|
-
* ⚠️
|
|
53
|
-
*
|
|
55
|
+
* ⚠️ 缩写名是**宿主**的词汇表(本包不认识具体取值),所以这里只把它当字符串拼键;
|
|
56
|
+
* 「这个缩写名认不认得」由宿主的设备清单归一(`urlKeyOf`)。
|
|
54
57
|
*/
|
|
55
|
-
export declare function readDeviceParam(query: Record<string, unknown> | undefined, name: DeviceScopedParam,
|
|
58
|
+
export declare function readDeviceParam(query: Record<string, unknown> | undefined, name: DeviceScopedParam, deviceKey: string): unknown;
|
|
56
59
|
//# sourceMappingURL=params.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"params.d.ts","sourceRoot":"","sources":["../../src/views/params.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"params.d.ts","sourceRoot":"","sources":["../../src/views/params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,8CAA8C;AAC9C,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,UAAU,CAAC;AAElD,eAAO,MAAM,oBAAoB,EAAE,SAAS,iBAAiB,EAAuB,CAAC;AAYrF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC1C,IAAI,EAAE,iBAAiB,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAIT"}
|
package/dist/views/params.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const DEVICE_SCOPED_PARAMS = ['
|
|
1
|
+
export const DEVICE_SCOPED_PARAMS = ['th', 'th_color'];
|
|
2
2
|
/** 值"存在且非空" —— 空串 / 空数组视为**未指定**,不顶掉兜底键 */
|
|
3
3
|
function isPresent(value) {
|
|
4
4
|
if (value === undefined || value === null)
|
|
@@ -13,22 +13,22 @@ function isPresent(value) {
|
|
|
13
13
|
/**
|
|
14
14
|
* 按**设备**读取版式 / 配色参数
|
|
15
15
|
*
|
|
16
|
-
* @param query
|
|
17
|
-
* @param name
|
|
18
|
-
* @param
|
|
19
|
-
* @returns `query['<name
|
|
16
|
+
* @param query 路由 query(`route.query`)
|
|
17
|
+
* @param name 参数名(`'th'` / `'th_color'`)
|
|
18
|
+
* @param deviceKey 设备**缩写名(urlKey)** —— 由调用方用 `urlKeyOf(deviceId)` 从设备清单查
|
|
19
|
+
* @returns `query['<name>_<deviceKey>']` 优先;缺席或空值时退 `query[name]`;
|
|
20
20
|
* 两者都没有则返回 undefined,表示"**这台设备**没有被显式指定"
|
|
21
21
|
*
|
|
22
22
|
* ⚠️ 只决定"取哪个键",**不做合法性校验** —— 校验属于各页 `pick*ViewId` 与配色注册表
|
|
23
|
-
* (本函数也拿不到"当前包里有没有这套版式")。返回值可能是数组(`?
|
|
23
|
+
* (本函数也拿不到"当前包里有没有这套版式")。返回值可能是数组(`?th=a&th=b`),
|
|
24
24
|
* 由下游按"非字符串即非法"处理,与改前的行为一致。
|
|
25
|
-
* ⚠️ 空串视为"未指定":`?
|
|
25
|
+
* ⚠️ 空串视为"未指定":`?th_std=` 不该把 `?th=compact` 顶掉 ——
|
|
26
26
|
* 部署方常把参数留空当作"这台设备不特殊指定"。
|
|
27
|
-
* ⚠️
|
|
28
|
-
*
|
|
27
|
+
* ⚠️ 缩写名是**宿主**的词汇表(本包不认识具体取值),所以这里只把它当字符串拼键;
|
|
28
|
+
* 「这个缩写名认不认得」由宿主的设备清单归一(`urlKeyOf`)。
|
|
29
29
|
*/
|
|
30
|
-
export function readDeviceParam(query, name,
|
|
31
|
-
const scoped = query?.[`${name}
|
|
30
|
+
export function readDeviceParam(query, name, deviceKey) {
|
|
31
|
+
const scoped = query?.[`${name}_${deviceKey}`];
|
|
32
32
|
if (isPresent(scoped))
|
|
33
33
|
return scoped;
|
|
34
34
|
return query?.[name];
|
package/dist/views/params.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"params.js","sourceRoot":"","sources":["../../src/views/params.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"params.js","sourceRoot":"","sources":["../../src/views/params.ts"],"names":[],"mappings":"AAwCA,MAAM,CAAC,MAAM,oBAAoB,GAAiC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AAErF,2CAA2C;AAC3C,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IAC1D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAC7B,KAA0C,EAC1C,IAAuB,EACvB,SAAiB;IAEjB,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC,GAAG,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;IAC/C,IAAI,SAAS,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACrC,OAAO,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC"}
|