@dsh-plus/notify-email 0.1.25 → 0.1.27
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 +46 -11
- package/package.json +2 -2
- package/src/client/card.tsx +11 -4
- package/src/client/client.ts +12 -15
- package/src/client/i18n.ts +2 -0
- package/src/ns.ts +4 -4
package/lib/client.js
CHANGED
|
@@ -72,6 +72,35 @@ window.__ModuleLoader__.load({
|
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
//#endregion
|
|
75
|
+
//#region ../shared/src/client/config-slots.ts
|
|
76
|
+
/** dsh-plus 聚合 bundle 的包名(各插件 row 均经其补丁层插入 profile)。 */
|
|
77
|
+
const DSH_PLUS_BUNDLE = "@dsh-plus/bundle-main";
|
|
78
|
+
/**
|
|
79
|
+
* 把一张配置卡片同时注册进 legacy 与新版三个槽位。
|
|
80
|
+
* 任一槽位在当前 dsh 版本未声明时对应 inject 挂起等待,版本不命中即 no-op。
|
|
81
|
+
*/
|
|
82
|
+
function injectPluginConfigCard(slots, reg) {
|
|
83
|
+
const base = {
|
|
84
|
+
locale: reg.ns,
|
|
85
|
+
inject: reg.inject
|
|
86
|
+
};
|
|
87
|
+
slots.inject("settings.plugin.item", () => slots.register({
|
|
88
|
+
name: "settings.plugin.item",
|
|
89
|
+
key: reg.ns,
|
|
90
|
+
...base
|
|
91
|
+
}, reg.component));
|
|
92
|
+
slots.inject("plugins.row.config", () => slots.register({
|
|
93
|
+
name: "plugins.row.config",
|
|
94
|
+
key: `${DSH_PLUS_BUNDLE}#${reg.rowId}`,
|
|
95
|
+
...base
|
|
96
|
+
}, reg.component));
|
|
97
|
+
slots.inject("plugins.bundle.config", () => slots.register({
|
|
98
|
+
name: "plugins.bundle.config",
|
|
99
|
+
key: reg.pkg,
|
|
100
|
+
...base
|
|
101
|
+
}, reg.component));
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
75
104
|
//#region ../shared/src/client/fields.tsx
|
|
76
105
|
function TextField(props) {
|
|
77
106
|
const p = props.prefix ?? "dshp";
|
|
@@ -370,11 +399,11 @@ ${extra}
|
|
|
370
399
|
//#region src/ns.ts
|
|
371
400
|
/**
|
|
372
401
|
* settings 命名空间字面量(纯常量,零依赖,浏览器半可安全引入)。
|
|
373
|
-
* 服务端直接以字面量注册(0.1.2-alpha.2
|
|
374
|
-
* config.ts
|
|
402
|
+
* 服务端直接以字面量注册(0.1.2-alpha.2 起 dsh-settings 对命名空间做编译期
|
|
403
|
+
* 语法校验,见 config.ts);浏览器半把它作为配置卡片的注册键
|
|
404
|
+
* (legacy settings.plugin.item keyed 槽位按「卡片编辑的 settings 命名空间」
|
|
405
|
+
* 分发;0.1.6-alpha.2 起改挂插件页 row/bundle config,见 shared/config-slots),
|
|
375
406
|
* 同一字面量两处共用,防止漂移。
|
|
376
|
-
* 契约:该槽位按「卡片编辑的 settings 命名空间」作 key 分发,
|
|
377
|
-
* 官方配置页只渲染 key 命中 Host 已注册命名空间的卡片。
|
|
378
407
|
* @module notify-email/ns
|
|
379
408
|
*/
|
|
380
409
|
const SETTINGS_NS = "dsh-plus-notify-email";
|
|
@@ -395,7 +424,9 @@ ${extra}
|
|
|
395
424
|
//#endregion
|
|
396
425
|
//#region src/client/card.tsx
|
|
397
426
|
/**
|
|
398
|
-
*
|
|
427
|
+
* 「邮件通知」配置卡片:经 injectPluginConfigCard 注册(legacy settings.plugin.item
|
|
428
|
+
* 与 0.1.6-alpha.2 插件页 plugins.row.config / plugins.bundle.config,view 分发
|
|
429
|
+
* summary/page)。
|
|
399
430
|
* 外壳与基础控件走 @dsh-plus/shared/client 套件(CardChrome/TextField/CheckRow),
|
|
400
431
|
* 本文件只保留业务字段与保存/测试逻辑。交互对齐官方卡片:折叠/展开、
|
|
401
432
|
* staged draft、未保存标记、保存/放弃;另加「发送测试邮件」。
|
|
@@ -453,7 +484,7 @@ ${extra}
|
|
|
453
484
|
const { t, scope, api } = props;
|
|
454
485
|
const snapshot = (0, react.useSyncExternalStore)((listener) => scope.subscribe(listener), () => scope.getSnapshot());
|
|
455
486
|
const value = snapshot.value;
|
|
456
|
-
const [open, setOpen] = (0, react.useState)(
|
|
487
|
+
const [open, setOpen] = (0, react.useState)(props.view === "page");
|
|
457
488
|
const [draft, setDraft] = (0, react.useState)(null);
|
|
458
489
|
const [passConfigured, setPassConfigured] = (0, react.useState)(false);
|
|
459
490
|
const [saving, setSaving] = (0, react.useState)(false);
|
|
@@ -476,6 +507,7 @@ ${extra}
|
|
|
476
507
|
}, [api, snapshot]);
|
|
477
508
|
const dirty = (0, react.useMemo)(() => value !== void 0 && draft !== null && JSON.stringify(toPatch(draft)) !== JSON.stringify(toPatch(draftFromValue(value))), [value, draft]);
|
|
478
509
|
const invalid = (0, react.useMemo)(() => draft !== null && (!isPositiveInt(draft.port) || !isPositiveInt(draft.idleDebounceMs) || !isPositiveInt(draft.maxBodyChars) || Number(draft.maxBodyChars) < 200), [draft]);
|
|
510
|
+
if (props.view === "summary") return t("summaryLine");
|
|
479
511
|
if (value === void 0 || draft === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
480
512
|
className: "dne-card",
|
|
481
513
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -711,6 +743,7 @@ ${extra}
|
|
|
711
743
|
const ownZh = {
|
|
712
744
|
title: "邮件通知",
|
|
713
745
|
description: "任务结束、等待决策或出错时向指定邮箱发送邮件。",
|
|
746
|
+
summaryLine: "任务结束、等待决策或出错时向指定邮箱发送邮件。",
|
|
714
747
|
enabled: "启用通知",
|
|
715
748
|
host: "SMTP 服务器",
|
|
716
749
|
hostHint: "如 smtp.qq.com、smtp.163.com。",
|
|
@@ -748,6 +781,7 @@ ${extra}
|
|
|
748
781
|
const ownEn = {
|
|
749
782
|
title: "Email notifications",
|
|
750
783
|
description: "Email a mailbox when a task finishes, awaits a decision, or fails.",
|
|
784
|
+
summaryLine: "Email a mailbox when a task finishes, awaits a decision, or fails.",
|
|
751
785
|
enabled: "Enable notifications",
|
|
752
786
|
host: "SMTP host",
|
|
753
787
|
hostHint: "e.g. smtp.qq.com, smtp.gmail.com.",
|
|
@@ -806,16 +840,17 @@ ${extra}
|
|
|
806
840
|
}), "notify-email: locale");
|
|
807
841
|
const scope = createSettingsScope(c, SETTINGS_NS, "notify-email: settings scope");
|
|
808
842
|
const api = createNamespaceApi(c.get("remote").settings, SETTINGS_NS);
|
|
809
|
-
c.slots
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
843
|
+
injectPluginConfigCard(c.slots, {
|
|
844
|
+
ns: SETTINGS_NS,
|
|
845
|
+
rowId: "dsh-plus-notify-email",
|
|
846
|
+
pkg: "@dsh-plus/notify-email",
|
|
847
|
+
component: NotifyEmailCard,
|
|
813
848
|
inject: () => ({
|
|
814
849
|
t: c.locale.bind(NS),
|
|
815
850
|
scope,
|
|
816
851
|
api
|
|
817
852
|
})
|
|
818
|
-
}
|
|
853
|
+
});
|
|
819
854
|
}
|
|
820
855
|
//#endregion
|
|
821
856
|
exports.apply = apply;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-plus/notify-email",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "dsh-plus service+ui plugin: 任务结束/等待决策/出错时向指定邮箱发送邮件通知",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"nodemailer": "9.0.6",
|
|
35
|
-
"@dsh-plus/shared": "0.1.
|
|
35
|
+
"@dsh-plus/shared": "0.1.20"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@deepseek-ai/cordis": "^4.0.2",
|
package/src/client/card.tsx
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 「邮件通知」配置卡片:经 injectPluginConfigCard 注册(legacy settings.plugin.item
|
|
3
|
+
* 与 0.1.6-alpha.2 插件页 plugins.row.config / plugins.bundle.config,view 分发
|
|
4
|
+
* summary/page)。
|
|
3
5
|
* 外壳与基础控件走 @dsh-plus/shared/client 套件(CardChrome/TextField/CheckRow),
|
|
4
6
|
* 本文件只保留业务字段与保存/测试逻辑。交互对齐官方卡片:折叠/展开、
|
|
5
7
|
* staged draft、未保存标记、保存/放弃;另加「发送测试邮件」。
|
|
@@ -16,6 +18,7 @@ import {
|
|
|
16
18
|
CheckRow,
|
|
17
19
|
IDLE_STATUS,
|
|
18
20
|
type NamespaceSettingsApi,
|
|
21
|
+
type PluginConfigViewProps,
|
|
19
22
|
type Scope,
|
|
20
23
|
TextField,
|
|
21
24
|
} from '@dsh-plus/shared/client'
|
|
@@ -24,7 +27,7 @@ import { SETTINGS_NS } from '../ns.ts'
|
|
|
24
27
|
import { sendTest } from './api.ts'
|
|
25
28
|
import type { Translate } from './i18n.ts'
|
|
26
29
|
|
|
27
|
-
export interface CardProps {
|
|
30
|
+
export interface CardProps extends PluginConfigViewProps {
|
|
28
31
|
t: Translate
|
|
29
32
|
scope: Scope
|
|
30
33
|
api: NamespaceSettingsApi
|
|
@@ -113,14 +116,15 @@ function toPatch(draft: Draft): Record<string, unknown> {
|
|
|
113
116
|
|
|
114
117
|
const TRIGGER_KEYS = ['onComplete', 'onError', 'onAborted', 'onQuestion', 'onPlanReview'] as const
|
|
115
118
|
|
|
116
|
-
export function NotifyEmailCard(props: CardProps): ReactElement | null {
|
|
119
|
+
export function NotifyEmailCard(props: CardProps): ReactElement | string | null {
|
|
117
120
|
const { t, scope, api } = props
|
|
118
121
|
const snapshot = useSyncExternalStore(
|
|
119
122
|
(listener: () => void) => scope.subscribe(listener),
|
|
120
123
|
() => scope.getSnapshot(),
|
|
121
124
|
)
|
|
122
125
|
const value = snapshot.value as ConfigValue | undefined
|
|
123
|
-
|
|
126
|
+
// 0.1.6-alpha.2 插件页 page 视图为表单落地页,默认展开;旧槽位无 view,保持折叠。
|
|
127
|
+
const [open, setOpen] = useState(props.view === 'page')
|
|
124
128
|
const [draft, setDraft] = useState<Draft | null>(null)
|
|
125
129
|
const [passConfigured, setPassConfigured] = useState(false)
|
|
126
130
|
const [saving, setSaving] = useState(false)
|
|
@@ -170,6 +174,9 @@ export function NotifyEmailCard(props: CardProps): ReactElement | null {
|
|
|
170
174
|
[draft],
|
|
171
175
|
)
|
|
172
176
|
|
|
177
|
+
// 插件页 summary 视图只出一行简介(hooks 已全部落定,可安全提前返回)。
|
|
178
|
+
if (props.view === 'summary') return t('summaryLine')
|
|
179
|
+
|
|
173
180
|
if (value === undefined || draft === null) {
|
|
174
181
|
return (
|
|
175
182
|
<li className="dne-card">
|
package/src/client/client.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 浏览器半入口:注册 locale 字典 +
|
|
2
|
+
* 浏览器半入口:注册 locale 字典 + 注册「邮件通知」卡片
|
|
3
|
+
* (injectPluginConfigCard 三槽位:legacy settings.plugin.item 与 0.1.6-alpha.2
|
|
4
|
+
* 独立插件页的 plugins.row.config / plugins.bundle.config)。
|
|
3
5
|
* 构建产物为 window.__ModuleLoader__.load({id, factory}) 形式的 CJS factory
|
|
4
6
|
* (包装见 tsdown.config.ts);样式沿用官方 data-plugin-css 约定,HMR 据此卸载。
|
|
5
7
|
*
|
|
6
8
|
* 类型说明:浏览器半只用到 slots/locale/remote 的很窄一面,
|
|
7
9
|
* scope 与基础控件走 @dsh-plus/shared/client 套件(收编自本插件原实现)。
|
|
8
|
-
* 该插槽为 keyed 槽位(0.1.2-alpha.2 复核不变):key 必须是卡片编辑的 settings
|
|
9
|
-
* 命名空间(即服务端注册的同一字面量,见 ../ns.ts),
|
|
10
|
-
* 官方配置页按此 key 与 Host 已注册命名空间配对分发。
|
|
11
10
|
* 配置读写经 ctx.remote.settings 直连(0.1.2-alpha.1 起 connection.api.settings
|
|
12
11
|
* 已移除;不复用 settingsScope 服务——非 loopback 页面下它固定 memory 模式无数据);
|
|
13
12
|
* 自定义端点仅剩「发送测试邮件」(api.ts)。
|
|
13
|
+
* 卡片 key/rowId 约定见 @dsh-plus/shared/client/config-slots。
|
|
14
14
|
* @module @dsh-plus/notify-email/client
|
|
15
15
|
*/
|
|
16
16
|
import type { Context } from '@deepseek-ai/cordis'
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
createNamespaceApi,
|
|
20
20
|
createSettingsScope,
|
|
21
21
|
injectCardStyle,
|
|
22
|
+
injectPluginConfigCard,
|
|
22
23
|
type PluginClientContext,
|
|
23
24
|
} from '@dsh-plus/shared/client'
|
|
24
25
|
import { SETTINGS_NS } from '../ns.ts'
|
|
@@ -45,15 +46,11 @@ export function apply(ctx: Context): void {
|
|
|
45
46
|
c.effect(() => c.locale.register(NS, { zh, en }), 'notify-email: locale')
|
|
46
47
|
const scope = createSettingsScope(c, SETTINGS_NS, 'notify-email: settings scope')
|
|
47
48
|
const api = createNamespaceApi(c.get('remote').settings, SETTINGS_NS)
|
|
48
|
-
c.slots
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
},
|
|
56
|
-
NotifyEmailCard,
|
|
57
|
-
),
|
|
58
|
-
)
|
|
49
|
+
injectPluginConfigCard(c.slots, {
|
|
50
|
+
ns: SETTINGS_NS,
|
|
51
|
+
rowId: 'dsh-plus-notify-email',
|
|
52
|
+
pkg: '@dsh-plus/notify-email',
|
|
53
|
+
component: NotifyEmailCard,
|
|
54
|
+
inject: () => ({ t: c.locale.bind(NS), scope, api }),
|
|
55
|
+
})
|
|
59
56
|
}
|
package/src/client/i18n.ts
CHANGED
|
@@ -10,6 +10,7 @@ export const NS = 'dsh-plus-notify-email'
|
|
|
10
10
|
const ownZh = {
|
|
11
11
|
title: '邮件通知',
|
|
12
12
|
description: '任务结束、等待决策或出错时向指定邮箱发送邮件。',
|
|
13
|
+
summaryLine: '任务结束、等待决策或出错时向指定邮箱发送邮件。',
|
|
13
14
|
enabled: '启用通知',
|
|
14
15
|
host: 'SMTP 服务器',
|
|
15
16
|
hostHint: '如 smtp.qq.com、smtp.163.com。',
|
|
@@ -48,6 +49,7 @@ const ownZh = {
|
|
|
48
49
|
const ownEn = {
|
|
49
50
|
title: 'Email notifications',
|
|
50
51
|
description: 'Email a mailbox when a task finishes, awaits a decision, or fails.',
|
|
52
|
+
summaryLine: 'Email a mailbox when a task finishes, awaits a decision, or fails.',
|
|
51
53
|
enabled: 'Enable notifications',
|
|
52
54
|
host: 'SMTP host',
|
|
53
55
|
hostHint: 'e.g. smtp.qq.com, smtp.gmail.com.',
|
package/src/ns.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* settings 命名空间字面量(纯常量,零依赖,浏览器半可安全引入)。
|
|
3
|
-
* 服务端直接以字面量注册(0.1.2-alpha.2
|
|
4
|
-
* config.ts
|
|
3
|
+
* 服务端直接以字面量注册(0.1.2-alpha.2 起 dsh-settings 对命名空间做编译期
|
|
4
|
+
* 语法校验,见 config.ts);浏览器半把它作为配置卡片的注册键
|
|
5
|
+
* (legacy settings.plugin.item keyed 槽位按「卡片编辑的 settings 命名空间」
|
|
6
|
+
* 分发;0.1.6-alpha.2 起改挂插件页 row/bundle config,见 shared/config-slots),
|
|
5
7
|
* 同一字面量两处共用,防止漂移。
|
|
6
|
-
* 契约:该槽位按「卡片编辑的 settings 命名空间」作 key 分发,
|
|
7
|
-
* 官方配置页只渲染 key 命中 Host 已注册命名空间的卡片。
|
|
8
8
|
* @module notify-email/ns
|
|
9
9
|
*/
|
|
10
10
|
export const SETTINGS_NS = 'dsh-plus-notify-email'
|