@dsh-plus/access-gate 0.3.21 → 0.3.23
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/lib/client.js +51 -142
- package/package.json +12 -12
- package/src/client/card.tsx +3 -12
- package/src/client/client.ts +2 -2
- package/src/ns.ts +2 -2
package/lib/client.js
CHANGED
|
@@ -4,50 +4,18 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
-
let react = require("react");
|
|
8
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
-
let
|
|
8
|
+
let react = require("react");
|
|
9
|
+
require("@deepseek-ai/dsh-client-ui-primitives");
|
|
10
10
|
//#region ../shared/src/client/card.tsx
|
|
11
11
|
const IDLE_STATUS = {
|
|
12
12
|
kind: "idle",
|
|
13
13
|
text: ""
|
|
14
14
|
};
|
|
15
|
-
/** 状态行 + 动作按钮(两种形态共用,类名随形态切换度量)。 */
|
|
16
|
-
function CardFoot(props) {
|
|
17
|
-
const p = props.prefix;
|
|
18
|
-
const section = props.variant === "section";
|
|
19
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
20
|
-
className: section ? `${p}-sectionFooter` : `${p}-footer`,
|
|
21
|
-
children: [props.status !== void 0 && props.status.kind !== "idle" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
22
|
-
className: `${p}-status${props.status.kind === "error" ? ` ${p}-statusError` : ""}`,
|
|
23
|
-
role: "status",
|
|
24
|
-
children: props.status.text
|
|
25
|
-
}) : null, props.actions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
26
|
-
type: "button",
|
|
27
|
-
className: `${p}-btn ${action.variant === "primary" ? `${p}-btnPrimary` : `${p}-btnGhost`}`,
|
|
28
|
-
disabled: action.disabled === true,
|
|
29
|
-
onClick: action.onClick,
|
|
30
|
-
children: action.label
|
|
31
|
-
}, action.key))]
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
/** 只读提示 + 字段区 + 页脚(两种形态共用)。 */
|
|
35
|
-
function CardBody(props) {
|
|
36
|
-
const p = props.prefix;
|
|
37
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
38
|
-
props.readOnlyNotice !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
39
|
-
className: `${p}-readOnly`,
|
|
40
|
-
role: "status",
|
|
41
|
-
children: props.readOnlyNotice
|
|
42
|
-
}) : null,
|
|
43
|
-
props.children,
|
|
44
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardFoot, { ...props })
|
|
45
|
-
] });
|
|
46
|
-
}
|
|
47
15
|
function CardChrome(props) {
|
|
48
16
|
const p = props.prefix;
|
|
49
17
|
const badge = props.statusBadge;
|
|
50
|
-
|
|
18
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
51
19
|
className: `${p}-section`,
|
|
52
20
|
"aria-label": props.title,
|
|
53
21
|
children: [
|
|
@@ -72,50 +40,37 @@ window.__ModuleLoader__.load({
|
|
|
72
40
|
className: `${p}-sectionDesc`,
|
|
73
41
|
children: props.description
|
|
74
42
|
}),
|
|
75
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
43
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
76
44
|
className: `${p}-sectionBody`,
|
|
77
|
-
children:
|
|
45
|
+
children: [
|
|
46
|
+
props.readOnlyNotice !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
47
|
+
className: `${p}-readOnly`,
|
|
48
|
+
role: "status",
|
|
49
|
+
children: props.readOnlyNotice
|
|
50
|
+
}) : null,
|
|
51
|
+
props.children,
|
|
52
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
53
|
+
className: `${p}-sectionFooter`,
|
|
54
|
+
children: [props.status !== void 0 && props.status.kind !== "idle" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
55
|
+
className: `${p}-status${props.status.kind === "error" ? ` ${p}-statusError` : ""}`,
|
|
56
|
+
role: "status",
|
|
57
|
+
children: props.status.text
|
|
58
|
+
}) : null, props.actions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
59
|
+
type: "button",
|
|
60
|
+
className: `${p}-btn ${action.variant === "primary" ? `${p}-btnPrimary` : `${p}-btnGhost`}`,
|
|
61
|
+
disabled: action.disabled === true,
|
|
62
|
+
onClick: action.onClick,
|
|
63
|
+
children: action.label
|
|
64
|
+
}, action.key))]
|
|
65
|
+
})
|
|
66
|
+
]
|
|
78
67
|
})
|
|
79
68
|
]
|
|
80
69
|
});
|
|
81
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
82
|
-
className: `${p}-card${props.open ? ` ${p}-cardOpen` : ""}`,
|
|
83
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
84
|
-
type: "button",
|
|
85
|
-
className: `${p}-header`,
|
|
86
|
-
"aria-expanded": props.open,
|
|
87
|
-
"aria-label": props.title,
|
|
88
|
-
onClick: () => props.onToggle(!props.open),
|
|
89
|
-
children: [
|
|
90
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
91
|
-
className: `${p}-headText`,
|
|
92
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
93
|
-
className: `${p}-name`,
|
|
94
|
-
children: props.title
|
|
95
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
96
|
-
className: `${p}-description`,
|
|
97
|
-
children: props.description
|
|
98
|
-
})]
|
|
99
|
-
}),
|
|
100
|
-
badge !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
101
|
-
className: `${p}-statusBadge ${badge.on ? `${p}-statusOn` : `${p}-statusOff`}`,
|
|
102
|
-
children: badge.text
|
|
103
|
-
}) : null,
|
|
104
|
-
props.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
105
|
-
className: `${p}-pending`,
|
|
106
|
-
children: props.dirtyLabel
|
|
107
|
-
}) : null,
|
|
108
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: `${p}-chevron${props.open ? ` ${p}-chevronOpen` : ""}` })
|
|
109
|
-
]
|
|
110
|
-
}), props.open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
111
|
-
className: `${p}-body`,
|
|
112
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardBody, { ...props })
|
|
113
|
-
}) : null]
|
|
114
|
-
});
|
|
115
70
|
}
|
|
116
71
|
/** 取值未到达时的占位:与 CardChrome 同形态,避免宿主页里闪一次卡片外壳。 */
|
|
117
72
|
function CardLoading(props) {
|
|
118
|
-
|
|
73
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
119
74
|
className: `${props.prefix}-section`,
|
|
120
75
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
121
76
|
className: `${props.prefix}-readOnly`,
|
|
@@ -123,41 +78,20 @@ window.__ModuleLoader__.load({
|
|
|
123
78
|
children: props.text
|
|
124
79
|
})
|
|
125
80
|
});
|
|
126
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
127
|
-
className: `${props.prefix}-card`,
|
|
128
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
129
|
-
className: `${props.prefix}-readOnly`,
|
|
130
|
-
role: "status",
|
|
131
|
-
children: props.text
|
|
132
|
-
})
|
|
133
|
-
});
|
|
134
81
|
}
|
|
135
82
|
//#endregion
|
|
136
83
|
//#region ../shared/src/client/config-slots.ts
|
|
137
84
|
/** dsh-plus 聚合 bundle 的包名(各插件 row 均经其补丁层插入 profile)。 */
|
|
138
85
|
const DSH_PLUS_BUNDLE = "@dsh-plus/bundle-main";
|
|
139
86
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* 故用无边框分节;summary 与 legacy 槽位保持卡片形态。
|
|
143
|
-
*/
|
|
144
|
-
function cardVariantFor(view) {
|
|
145
|
-
return view === "page" ? "section" : "card";
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* 把一张配置卡片同时注册进 legacy 与新版三个槽位。
|
|
149
|
-
* 任一槽位在当前 dsh 版本未声明时对应 inject 挂起等待,版本不命中即 no-op。
|
|
87
|
+
* 把一张配置卡片注册进插件页的两个配置槽位。
|
|
88
|
+
* 两个槽位都由 0.2.1-alpha.1 的插件页声明,任一缺席即报错——不做版本探测。
|
|
150
89
|
*/
|
|
151
90
|
function injectPluginConfigCard(slots, reg) {
|
|
152
91
|
const base = {
|
|
153
92
|
locale: reg.ns,
|
|
154
93
|
inject: reg.inject
|
|
155
94
|
};
|
|
156
|
-
slots.inject("settings.plugin.item", () => slots.register({
|
|
157
|
-
name: "settings.plugin.item",
|
|
158
|
-
key: reg.ns,
|
|
159
|
-
...base
|
|
160
|
-
}, reg.component));
|
|
161
95
|
slots.inject("plugins.row.config", () => slots.register({
|
|
162
96
|
name: "plugins.row.config",
|
|
163
97
|
key: `${DSH_PLUS_BUNDLE}#${reg.rowId}`,
|
|
@@ -343,36 +277,33 @@ window.__ModuleLoader__.load({
|
|
|
343
277
|
//#endregion
|
|
344
278
|
//#region ../shared/src/client/styles.ts
|
|
345
279
|
/**
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
280
|
+
* 配置分节样式工厂(各插件 client 的公共收编版)。
|
|
281
|
+
*
|
|
282
|
+
* 目标宿主 dsh 0.2.1-alpha.1:插件页把配置视图放进已有页面级内边距的容器里
|
|
283
|
+
* (`div.detailSections[data-plugin-config]` 或 `section.detailSection[data-plugin-config]`),
|
|
284
|
+
* 外层无边框——故这里输出的是**无边框分节**(小节标题 13px/600、字段 12px 0、
|
|
285
|
+
* 横向零内边距、页脚非 sticky),度量对齐官方设置页
|
|
286
|
+
* (`@deepseek-ai/dsh-client-ui-primitives` 的 settings-form)。
|
|
287
|
+
*
|
|
288
|
+
* 移动端与可达性(767px 断点 + pointer:coarse,对齐 ui-mobile-fit 约定):
|
|
349
289
|
* - 窄屏 input/textarea 16px(防 iOS 聚焦缩放)、可点目标 ≥44px;
|
|
350
|
-
* -
|
|
351
|
-
* - 展开态 body 底部 sticky 保存栏(长表单滚动中始终可达)。
|
|
352
|
-
* - 分节形态(-section,插件页 page 视图内嵌宿主页面):无边框/背景、横向零
|
|
353
|
-
* 内边距,页脚不 sticky——官方插件页已提供页面级内边距,再叠一层卡片会
|
|
354
|
-
* 缩窄移动端可用宽度(卡片套卡片)。
|
|
290
|
+
* - 页脚按钮等宽换行、状态文字独占一行。
|
|
355
291
|
* 沿用官方 data-plugin / data-plugin-css 约定(HMR 据此卸载),不覆盖上游选择器。
|
|
356
292
|
* @module @dsh-plus/shared/client/styles
|
|
357
293
|
*/
|
|
358
|
-
/**
|
|
294
|
+
/** 生成全套分节 CSS;prefix 为插件类名前缀(如 'dne'),extra 为插件特有规则。 */
|
|
359
295
|
function cardCss(prefix, extra = "") {
|
|
360
296
|
return `
|
|
361
|
-
.${prefix}-
|
|
362
|
-
.${prefix}-
|
|
363
|
-
.${prefix}-
|
|
364
|
-
.${prefix}-
|
|
365
|
-
.${prefix}-
|
|
366
|
-
.${prefix}-
|
|
367
|
-
.${prefix}-
|
|
368
|
-
.${prefix}-description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}
|
|
369
|
-
.${prefix}-chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s;display:inline-flex}
|
|
370
|
-
.${prefix}-chevronOpen{transform:rotate(180deg)}
|
|
297
|
+
.${prefix}-section{box-sizing:border-box;flex-direction:column;width:100%;min-width:0;padding:16px 0;display:flex}
|
|
298
|
+
.${prefix}-sectionHead{align-items:center;gap:8px;min-width:0;display:flex}
|
|
299
|
+
.${prefix}-sectionTitle{min-width:0;color:var(--dsw-alias-label-primary);flex:1;margin:0;font-size:13px;font-weight:600;line-height:1.5}
|
|
300
|
+
.${prefix}-sectionBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
301
|
+
.${prefix}-sectionDesc{color:var(--dsw-alias-label-tertiary);margin:4px 0 0;font-size:12px;line-height:1.5}
|
|
302
|
+
.${prefix}-sectionBody{flex-direction:column;min-width:0;display:flex}
|
|
303
|
+
.${prefix}-sectionFooter{align-items:center;gap:8px;padding-top:16px;display:flex;flex-wrap:wrap}
|
|
371
304
|
.${prefix}-pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
372
|
-
.${prefix}-statusBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
373
305
|
.${prefix}-statusOn{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary)}
|
|
374
306
|
.${prefix}-statusOff{color:var(--dsw-alias-label-tertiary)}
|
|
375
|
-
.${prefix}-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}
|
|
376
307
|
.${prefix}-field{flex-direction:column;gap:6px;padding:12px 0;display:flex}
|
|
377
308
|
.${prefix}-field+.${prefix}-field{border-top:1px solid var(--dsw-alias-border-l2)}
|
|
378
309
|
.${prefix}-head{align-items:center;gap:8px;display:flex}
|
|
@@ -398,19 +329,9 @@ window.__ModuleLoader__.load({
|
|
|
398
329
|
.${prefix}-checkRow input:checked::after{left:16px;background:var(--dsw-alias-bg-base)}
|
|
399
330
|
.${prefix}-checkRow input:disabled{opacity:.4;cursor:default}
|
|
400
331
|
.${prefix}-checkRow input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
|
|
401
|
-
/* 宿主内嵌分节形态(插件页 page 视图):官方设置页同构——无边框/背景,
|
|
402
|
-
横向零内边距(宽度交给宿主页面容器),小节标题 13px/600,页脚非 sticky。 */
|
|
403
|
-
.${prefix}-section{box-sizing:border-box;flex-direction:column;width:100%;min-width:0;padding:16px 0;display:flex}
|
|
404
|
-
.${prefix}-sectionHead{align-items:center;gap:8px;min-width:0;display:flex}
|
|
405
|
-
.${prefix}-sectionTitle{min-width:0;color:var(--dsw-alias-label-primary);flex:1;margin:0;font-size:13px;font-weight:600;line-height:1.5}
|
|
406
|
-
.${prefix}-sectionBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
407
|
-
.${prefix}-sectionDesc{color:var(--dsw-alias-label-tertiary);margin:4px 0 0;font-size:12px;line-height:1.5}
|
|
408
|
-
.${prefix}-sectionBody{flex-direction:column;min-width:0;display:flex}
|
|
409
|
-
.${prefix}-sectionFooter{align-items:center;gap:8px;padding-top:16px;display:flex;flex-wrap:wrap}
|
|
410
332
|
.${prefix}-groupLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600;padding:12px 0 2px;margin:0}
|
|
411
333
|
.${prefix}-readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}
|
|
412
334
|
.${prefix}-warn{color:var(--dsw-alias-label-error);margin:12px 0 0;font-size:12px;line-height:1.5}
|
|
413
|
-
.${prefix}-footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex;flex-wrap:wrap}
|
|
414
335
|
.${prefix}-status{min-width:0;color:var(--dsw-alias-label-secondary);flex:1;margin:0;font-size:12px;line-height:1.5}
|
|
415
336
|
.${prefix}-statusError{color:var(--dsw-alias-label-error)}
|
|
416
337
|
.${prefix}-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}
|
|
@@ -420,16 +341,10 @@ window.__ModuleLoader__.load({
|
|
|
420
341
|
.${prefix}-btn:disabled{opacity:.4;cursor:default}
|
|
421
342
|
.${prefix}-btn:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}
|
|
422
343
|
@media (max-width:767px){
|
|
423
|
-
.${prefix}-body{margin:0 10px}
|
|
424
|
-
.${prefix}-header{padding:12px 12px}
|
|
425
344
|
.${prefix}-input,.${prefix}-select{font-size:16px;height:40px}
|
|
426
345
|
.${prefix}-checkRow{min-height:44px;padding:8px 0}
|
|
427
|
-
.${prefix}-footer{position:sticky;bottom:0;background:var(--dsw-alias-bg-layer-2);margin:0 -10px;padding:10px 10px 6px;border-top:1px solid var(--dsw-alias-border-l2);border-bottom-left-radius:12px;border-bottom-right-radius:12px}
|
|
428
346
|
.${prefix}-status{flex-basis:100%;flex:none}
|
|
429
347
|
.${prefix}-btn{min-height:44px;flex:1;min-width:96px}
|
|
430
|
-
.${prefix}-statusBadge{display:none}
|
|
431
|
-
.${prefix}-sectionBadge{display:inline-block}
|
|
432
|
-
.${prefix}-sectionFooter{position:static}
|
|
433
348
|
}
|
|
434
349
|
@media (pointer:coarse){
|
|
435
350
|
.${prefix}-btn{min-height:44px}
|
|
@@ -460,8 +375,8 @@ ${extra}
|
|
|
460
375
|
* settings 命名空间字面量(纯常量,零依赖,浏览器半可安全引入)。
|
|
461
376
|
* 服务端直接以字面量注册(0.1.2-alpha.2 起 dsh-settings 对命名空间做编译期
|
|
462
377
|
* 语法校验,见 config.ts);浏览器半把它作为配置卡片的注册键
|
|
463
|
-
*
|
|
464
|
-
*
|
|
378
|
+
* (插件页配置卡片挂在 row/bundle config 槽位上,与命名空间解耦,
|
|
379
|
+
* 见 shared/config-slots),
|
|
465
380
|
* 同一字面量两处共用,防止漂移。
|
|
466
381
|
* @module access-gate/ns
|
|
467
382
|
*/
|
|
@@ -469,8 +384,8 @@ ${extra}
|
|
|
469
384
|
//#endregion
|
|
470
385
|
//#region src/client/card.tsx
|
|
471
386
|
/**
|
|
472
|
-
* 「访问控制」配置卡片:经 injectPluginConfigCard
|
|
473
|
-
*
|
|
387
|
+
* 「访问控制」配置卡片:经 injectPluginConfigCard 注册(插件页 plugins.row.config /
|
|
388
|
+
* plugins.bundle.config,view 分发 summary/page)。
|
|
474
389
|
* 外壳与基础控件走 @dsh-plus/shared/client 套件(CardChrome/TextField/CheckRow),
|
|
475
390
|
* 本文件保留业务字段(白名单 textarea/诊断面板)与保存逻辑。
|
|
476
391
|
* 配置读写经共享层 ctx.remote.settings 直连(0.1.7 起 settingsScope 已由
|
|
@@ -607,7 +522,6 @@ ${extra}
|
|
|
607
522
|
const { t, scope, api } = props;
|
|
608
523
|
const snapshot = (0, react.useSyncExternalStore)((listener) => scope.subscribe(listener), () => scope.getSnapshot());
|
|
609
524
|
const value = snapshot.value;
|
|
610
|
-
const [open, setOpen] = (0, react.useState)(props.view === "page");
|
|
611
525
|
const [draft, setDraft] = (0, react.useState)(null);
|
|
612
526
|
const [saving, setSaving] = (0, react.useState)(false);
|
|
613
527
|
const [status, setStatus] = (0, react.useState)(IDLE_STATUS);
|
|
@@ -618,10 +532,8 @@ ${extra}
|
|
|
618
532
|
}, [value, draft]);
|
|
619
533
|
const dirty = (0, react.useMemo)(() => value !== void 0 && draft !== null && JSON.stringify(toPatch(draft)) !== JSON.stringify(toPatch(draftFromValue(value))), [value, draft]);
|
|
620
534
|
if (props.view === "summary") return t("summaryLine");
|
|
621
|
-
const variant = cardVariantFor(props.view);
|
|
622
535
|
if (value === void 0 || draft === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardLoading, {
|
|
623
536
|
prefix: "dag",
|
|
624
|
-
variant,
|
|
625
537
|
text: t("loading")
|
|
626
538
|
});
|
|
627
539
|
const edit = (key, editValue) => {
|
|
@@ -653,9 +565,6 @@ ${extra}
|
|
|
653
565
|
prefix: "dag",
|
|
654
566
|
title: t("title"),
|
|
655
567
|
description: t("description"),
|
|
656
|
-
open,
|
|
657
|
-
onToggle: setOpen,
|
|
658
|
-
variant,
|
|
659
568
|
statusBadge: {
|
|
660
569
|
text: t(draft.enabled ? "enabledOn" : "enabledOff"),
|
|
661
570
|
on: draft.enabled
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-plus/access-gate",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.23",
|
|
4
4
|
"description": "dsh-plus service+ui plugin: dsh web 全量访问围栏——与官方 browser-auth 合并:官方 cookie 为唯一凭据,可选 IP 附加围栏,未认证导航渲染 token 输入页(PWA 可恢复),loopback 管理通道",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -31,21 +31,21 @@
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@dsh-plus/shared": "0.1.
|
|
34
|
+
"@dsh-plus/shared": "0.1.33"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
38
|
-
"@deepseek-ai/dsh-home-paths": "^0.2.
|
|
39
|
-
"@deepseek-ai/dsh-settings": "^0.2.
|
|
40
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
37
|
+
"@deepseek-ai/cordis": "^4.0.5-alpha.1",
|
|
38
|
+
"@deepseek-ai/dsh-home-paths": "^0.2.1-alpha.1",
|
|
39
|
+
"@deepseek-ai/dsh-settings": "^0.2.1-alpha.1",
|
|
40
|
+
"@deepseek-ai/schemastery": "^3.18.5-alpha.1"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@deepseek-ai/cordis": "4.0.
|
|
44
|
-
"@deepseek-ai/dsh-client-connection": "0.2.
|
|
45
|
-
"@deepseek-ai/dsh-home-paths": "0.2.
|
|
46
|
-
"@deepseek-ai/dsh-host-webserver": "0.2.
|
|
47
|
-
"@deepseek-ai/dsh-settings": "0.2.
|
|
48
|
-
"@deepseek-ai/schemastery": "3.18.
|
|
43
|
+
"@deepseek-ai/cordis": "4.0.5-alpha.1",
|
|
44
|
+
"@deepseek-ai/dsh-client-connection": "0.2.1-alpha.1",
|
|
45
|
+
"@deepseek-ai/dsh-home-paths": "0.2.1-alpha.1",
|
|
46
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.1",
|
|
47
|
+
"@deepseek-ai/dsh-settings": "0.2.1-alpha.1",
|
|
48
|
+
"@deepseek-ai/schemastery": "3.18.5-alpha.1",
|
|
49
49
|
"@types/react": "~18.3.31",
|
|
50
50
|
"react": "^18.2.0"
|
|
51
51
|
},
|
package/src/client/card.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 「访问控制」配置卡片:经 injectPluginConfigCard
|
|
3
|
-
*
|
|
2
|
+
* 「访问控制」配置卡片:经 injectPluginConfigCard 注册(插件页 plugins.row.config /
|
|
3
|
+
* plugins.bundle.config,view 分发 summary/page)。
|
|
4
4
|
* 外壳与基础控件走 @dsh-plus/shared/client 套件(CardChrome/TextField/CheckRow),
|
|
5
5
|
* 本文件保留业务字段(白名单 textarea/诊断面板)与保存逻辑。
|
|
6
6
|
* 配置读写经共享层 ctx.remote.settings 直连(0.1.7 起 settingsScope 已由
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
CardLoading,
|
|
19
19
|
type CardStatusState,
|
|
20
20
|
CheckRow,
|
|
21
|
-
cardVariantFor,
|
|
22
21
|
IDLE_STATUS,
|
|
23
22
|
type NamespaceSettingsApi,
|
|
24
23
|
type PluginConfigViewProps,
|
|
@@ -177,8 +176,6 @@ export function AccessGateCard(props: CardProps): ReactElement | string | null {
|
|
|
177
176
|
() => scope.getSnapshot(),
|
|
178
177
|
)
|
|
179
178
|
const value = snapshot.value as ConfigValue | undefined
|
|
180
|
-
// 0.1.6-alpha.2 插件页 page 视图为表单落地页,默认展开;旧槽位无 view,保持折叠。
|
|
181
|
-
const [open, setOpen] = useState(props.view === 'page')
|
|
182
179
|
const [draft, setDraft] = useState<Draft | null>(null)
|
|
183
180
|
const [saving, setSaving] = useState(false)
|
|
184
181
|
const [status, setStatus] = useState<CardStatusState>(IDLE_STATUS)
|
|
@@ -201,11 +198,8 @@ export function AccessGateCard(props: CardProps): ReactElement | string | null {
|
|
|
201
198
|
// 插件页 summary 视图只出一行简介(hooks 已全部落定,可安全提前返回)。
|
|
202
199
|
if (props.view === 'summary') return t('summaryLine')
|
|
203
200
|
|
|
204
|
-
// 插件页 page 视图内嵌宿主页面容器(已带页面级内边距与标题),用无边框分节。
|
|
205
|
-
const variant = cardVariantFor(props.view)
|
|
206
|
-
|
|
207
201
|
if (value === undefined || draft === null) {
|
|
208
|
-
return <CardLoading prefix="dag"
|
|
202
|
+
return <CardLoading prefix="dag" text={t('loading')} />
|
|
209
203
|
}
|
|
210
204
|
const edit = <K extends keyof Draft>(key: K, editValue: Draft[K]): void => {
|
|
211
205
|
setDraft({ ...draft, [key]: editValue })
|
|
@@ -236,9 +230,6 @@ export function AccessGateCard(props: CardProps): ReactElement | string | null {
|
|
|
236
230
|
prefix="dag"
|
|
237
231
|
title={t('title')}
|
|
238
232
|
description={t('description')}
|
|
239
|
-
open={open}
|
|
240
|
-
onToggle={setOpen}
|
|
241
|
-
variant={variant}
|
|
242
233
|
statusBadge={{ text: t(draft.enabled ? 'enabledOn' : 'enabledOff'), on: draft.enabled }}
|
|
243
234
|
dirty={dirty}
|
|
244
235
|
dirtyLabel={t('unsaved')}
|
package/src/client/client.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 浏览器半入口:注册 locale 字典 + 注册「访问控制」卡片
|
|
3
|
-
* (injectPluginConfigCard
|
|
4
|
-
*
|
|
3
|
+
* (injectPluginConfigCard 两槽位:插件页 plugins.row.config /
|
|
4
|
+
* plugins.bundle.config)。
|
|
5
5
|
* 构建产物为 window.__ModuleLoader__.load({id, factory}) 形式的 CJS factory
|
|
6
6
|
* (包装见 tsdown.config.ts);样式沿用官方 data-plugin-css 约定,HMR 据此卸载。
|
|
7
7
|
*
|
package/src/ns.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* settings 命名空间字面量(纯常量,零依赖,浏览器半可安全引入)。
|
|
3
3
|
* 服务端直接以字面量注册(0.1.2-alpha.2 起 dsh-settings 对命名空间做编译期
|
|
4
4
|
* 语法校验,见 config.ts);浏览器半把它作为配置卡片的注册键
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* (插件页配置卡片挂在 row/bundle config 槽位上,与命名空间解耦,
|
|
6
|
+
* 见 shared/config-slots),
|
|
7
7
|
* 同一字面量两处共用,防止漂移。
|
|
8
8
|
* @module access-gate/ns
|
|
9
9
|
*/
|