@sparkelf/dsh-plugin-dataops 0.1.0-rc.10
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/LICENSE +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +63 -0
- package/README.zh.md +63 -0
- package/lib/client.js +540 -0
- package/lib/index.js +499 -0
- package/lib/invariant.js +16 -0
- package/lib/types/client/DataOpsExpiryModal.d.ts +12 -0
- package/lib/types/client/DataOpsSection.d.ts +12 -0
- package/lib/types/client/contract.d.ts +18 -0
- package/lib/types/client/controller.d.ts +33 -0
- package/lib/types/client/index.d.ts +12 -0
- package/lib/types/client/locales.d.ts +39 -0
- package/lib/types/client/store.d.ts +54 -0
- package/lib/types/index.d.ts +33 -0
- package/lib/types/invariant.d.ts +13 -0
- package/package.json +92 -0
package/lib/client.js
ADDED
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@sparkelf/dsh-plugin-dataops",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
let react = require("react");
|
|
9
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
10
|
+
let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
11
|
+
//#region lib/types/client/controller.js
|
|
12
|
+
const STATUS_PATH = "/integrations/dataops/status";
|
|
13
|
+
const CONNECT_PATH = "/integrations/dataops/connect";
|
|
14
|
+
const DISCONNECT_PATH = "/integrations/dataops/disconnect";
|
|
15
|
+
const OAUTH_EVENT_TYPE = "dsh:dataops-oauth";
|
|
16
|
+
function browserHostUrl(path) {
|
|
17
|
+
return new URL(path.replace(/^[/]/u, ""), document.baseURI).toString();
|
|
18
|
+
}
|
|
19
|
+
async function readStatus() {
|
|
20
|
+
const response = await fetch(browserHostUrl(STATUS_PATH), { cache: "no-store" });
|
|
21
|
+
if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
|
|
22
|
+
return response.json();
|
|
23
|
+
}
|
|
24
|
+
function oauthFailureKey(reason) {
|
|
25
|
+
switch (reason) {
|
|
26
|
+
case "pending-state": return "authorizationExpired";
|
|
27
|
+
case "missing-code": return "authorizationResponseInvalid";
|
|
28
|
+
case "token-request-rejected": return "tokenRequestRejected";
|
|
29
|
+
case "token-account-rejected": return "tokenAccountRejected";
|
|
30
|
+
case "token-service-failed": return "tokenServiceFailed";
|
|
31
|
+
case "token-response-invalid": return "tokenResponseInvalid";
|
|
32
|
+
case "account-verification": return "accountVerificationFailed";
|
|
33
|
+
case "authorization-activation": return "authorizationActivationFailed";
|
|
34
|
+
default: return "connectFailed";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Own browser status refresh, OAuth popup handoff, and expiry notification timing. */
|
|
38
|
+
var DataOpsController = class {
|
|
39
|
+
actions;
|
|
40
|
+
authorizationPopup = null;
|
|
41
|
+
expiryTimer;
|
|
42
|
+
/**
|
|
43
|
+
* Attach the root-scoped store actions supplied by a slot registration.
|
|
44
|
+
* @param actions - Bound writes for the shared DataOps Client store.
|
|
45
|
+
*/
|
|
46
|
+
attach(actions) {
|
|
47
|
+
this.actions = actions;
|
|
48
|
+
}
|
|
49
|
+
writes() {
|
|
50
|
+
return this.actions;
|
|
51
|
+
}
|
|
52
|
+
clearExpiryTimer() {
|
|
53
|
+
if (this.expiryTimer === void 0) return;
|
|
54
|
+
clearTimeout(this.expiryTimer);
|
|
55
|
+
this.expiryTimer = void 0;
|
|
56
|
+
}
|
|
57
|
+
scheduleExpiry(status) {
|
|
58
|
+
this.clearExpiryTimer();
|
|
59
|
+
if (!status.authorizationAccepted || status.expiresAt === null) return;
|
|
60
|
+
const delay = status.expiresAt - Date.now();
|
|
61
|
+
if (delay <= 0) return;
|
|
62
|
+
this.expiryTimer = setTimeout(() => {
|
|
63
|
+
this.expiryTimer = void 0;
|
|
64
|
+
this.load();
|
|
65
|
+
}, delay);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Refresh the authoritative Host projection and schedule its known expiry.
|
|
69
|
+
* @returns A promise settled after the shared status reflects the response.
|
|
70
|
+
*/
|
|
71
|
+
async load() {
|
|
72
|
+
const actions = this.writes();
|
|
73
|
+
actions.beginLoad();
|
|
74
|
+
try {
|
|
75
|
+
const status = await readStatus();
|
|
76
|
+
actions.setStatus(status);
|
|
77
|
+
this.scheduleExpiry(status);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error("mcp-dataops: status request failed", error);
|
|
80
|
+
actions.setFailure("connectionFailed");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Start the always-mounted browser lifecycle.
|
|
85
|
+
* @returns A disposer for browser listeners, popup ownership, and expiry timing.
|
|
86
|
+
*/
|
|
87
|
+
start() {
|
|
88
|
+
const onMessage = (event) => {
|
|
89
|
+
if (event.origin !== window.location.origin || event.source !== this.authorizationPopup) return;
|
|
90
|
+
const data = event.data;
|
|
91
|
+
if (data?.type !== OAUTH_EVENT_TYPE) return;
|
|
92
|
+
this.authorizationPopup = null;
|
|
93
|
+
if (data.result === "connected") this.load();
|
|
94
|
+
else if (data.result !== "cancelled") this.writes().setFailure(oauthFailureKey(data.reason));
|
|
95
|
+
};
|
|
96
|
+
const onFocus = () => {
|
|
97
|
+
this.load();
|
|
98
|
+
};
|
|
99
|
+
const onVisibility = () => {
|
|
100
|
+
if (document.visibilityState === "visible") this.load();
|
|
101
|
+
};
|
|
102
|
+
window.addEventListener("message", onMessage);
|
|
103
|
+
window.addEventListener("focus", onFocus);
|
|
104
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
105
|
+
this.load();
|
|
106
|
+
return () => {
|
|
107
|
+
this.clearExpiryTimer();
|
|
108
|
+
window.removeEventListener("message", onMessage);
|
|
109
|
+
window.removeEventListener("focus", onFocus);
|
|
110
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
111
|
+
this.authorizationPopup?.close();
|
|
112
|
+
this.authorizationPopup = null;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** Open the real DataOps authorization handoff from a user gesture. */
|
|
116
|
+
openAuthorization() {
|
|
117
|
+
const actions = this.writes();
|
|
118
|
+
actions.clearFailure();
|
|
119
|
+
const connectUrl = new URL(browserHostUrl(CONNECT_PATH));
|
|
120
|
+
connectUrl.searchParams.set("origin", window.location.origin);
|
|
121
|
+
this.authorizationPopup = window.open(connectUrl.toString(), "dsh-dataops-authorization", "popup,width=720,height=760");
|
|
122
|
+
if (this.authorizationPopup === null) actions.setFailure("popupBlocked");
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Revoke the current grant and refresh shared state.
|
|
126
|
+
* @returns Whether the disconnect completed and Settings may collapse confirmation.
|
|
127
|
+
*/
|
|
128
|
+
async disconnect() {
|
|
129
|
+
const actions = this.writes();
|
|
130
|
+
actions.setDisconnecting(true);
|
|
131
|
+
actions.clearFailure();
|
|
132
|
+
try {
|
|
133
|
+
const response = await fetch(browserHostUrl(DISCONNECT_PATH), { method: "POST" });
|
|
134
|
+
if (!response.ok) throw new Error(`DataOps disconnect failed with HTTP ${String(response.status)}`);
|
|
135
|
+
await this.load();
|
|
136
|
+
return true;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error("mcp-dataops: disconnect request failed", error);
|
|
139
|
+
actions.setFailure("disconnectFailed");
|
|
140
|
+
return false;
|
|
141
|
+
} finally {
|
|
142
|
+
actions.setDisconnecting(false);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region lib/types/client/store.js
|
|
148
|
+
/**
|
|
149
|
+
* Return whether the stored grant exists but is no longer accepted.
|
|
150
|
+
* @param status - Current Host-projected DataOps status.
|
|
151
|
+
* @returns Whether a writable stored grant needs interactive sign-in.
|
|
152
|
+
*/
|
|
153
|
+
function isLoginExpired(status) {
|
|
154
|
+
return status?.credentialConfigured === true && !status.authorizationAccepted && status.credentialWritable;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Create the root-scoped state shared by DataOps Settings and expiry modal.
|
|
158
|
+
* @returns A store handle shared by both root-scope registrations.
|
|
159
|
+
*/
|
|
160
|
+
function createDataOpsStore() {
|
|
161
|
+
return (0, _deepseek_ai_dsh_client_store.defineStore)({
|
|
162
|
+
init: () => ({
|
|
163
|
+
loading: true,
|
|
164
|
+
failure: void 0,
|
|
165
|
+
disconnecting: false,
|
|
166
|
+
expiryPromptDismissed: false
|
|
167
|
+
}),
|
|
168
|
+
actions: {
|
|
169
|
+
beginLoad: (draft) => {
|
|
170
|
+
draft.loading = true;
|
|
171
|
+
draft.failure = void 0;
|
|
172
|
+
},
|
|
173
|
+
setStatus: (draft, status) => {
|
|
174
|
+
const wasExpired = isLoginExpired(draft.status);
|
|
175
|
+
const expired = isLoginExpired(status);
|
|
176
|
+
draft.status = status;
|
|
177
|
+
draft.loading = false;
|
|
178
|
+
draft.failure = void 0;
|
|
179
|
+
if (!expired || !wasExpired) draft.expiryPromptDismissed = false;
|
|
180
|
+
},
|
|
181
|
+
setFailure: (draft, failure) => {
|
|
182
|
+
draft.loading = false;
|
|
183
|
+
draft.failure = failure;
|
|
184
|
+
},
|
|
185
|
+
clearFailure: (draft) => {
|
|
186
|
+
draft.failure = void 0;
|
|
187
|
+
},
|
|
188
|
+
setDisconnecting: (draft, disconnecting) => {
|
|
189
|
+
draft.disconnecting = disconnecting;
|
|
190
|
+
},
|
|
191
|
+
dismissExpiryPrompt: (draft) => {
|
|
192
|
+
draft.expiryPromptDismissed = true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness-plus/deepseek-harness-plus/packages/plus/dataops/src/client/DataOpsSection.module.css.mjs
|
|
199
|
+
const css = ".-x0sCW_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.-x0sCW_title{margin:0;font-size:16px;font-weight:500;line-height:24px}.-x0sCW_body{flex-direction:column;gap:14px;display:flex}.-x0sCW_confirmCopy{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}.-x0sCW_statusRow,.-x0sCW_accountRow,.-x0sCW_actions,.-x0sCW_confirmActions{align-items:center;display:flex}.-x0sCW_statusRow{gap:8px;min-height:24px}.-x0sCW_statusLabel{min-width:0;font-size:14px;font-weight:500;line-height:22px}.-x0sCW_accountRow{background:var(--dsw-alias-interactive-bg-hover);border-radius:8px;gap:12px;padding:12px}.-x0sCW_avatar{background:var(--dsw-alias-interactive-bg-hover-solid);width:40px;height:40px;color:var(--dsw-alias-label-primary);border-radius:50%;flex:0 0 40px;place-items:center;font-size:14px;font-weight:600;display:grid}.-x0sCW_accountCopy{flex-direction:column;gap:1px;min-width:0;display:flex}.-x0sCW_accountCopy strong{text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:500;line-height:22px;overflow:hidden}.-x0sCW_accountCopy span{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}.-x0sCW_actions,.-x0sCW_confirmActions{flex-wrap:wrap;gap:8px}.-x0sCW_confirmBox{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);border-radius:8px;flex-direction:column;gap:10px;padding:12px;display:flex}.-x0sCW_confirmTitle{margin:0;font-size:14px;font-weight:500;line-height:22px}.-x0sCW_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.-x0sCW_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}@media (width<=560px){.-x0sCW_actions>button,.-x0sCW_confirmActions>button{flex:auto}}";
|
|
200
|
+
const tagId = "@sparkelf/dsh-plugin-dataops/DataOpsSection.module.css";
|
|
201
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
202
|
+
const tag = document.createElement("style");
|
|
203
|
+
tag.dataset.plugin = "@sparkelf/dsh-plugin-dataops";
|
|
204
|
+
tag.dataset.pluginCss = tagId;
|
|
205
|
+
tag.textContent = css;
|
|
206
|
+
document.head.appendChild(tag);
|
|
207
|
+
}
|
|
208
|
+
var DataOpsSection_module_css_default = {
|
|
209
|
+
"accountCopy": "-x0sCW_accountCopy",
|
|
210
|
+
"accountRow": "-x0sCW_accountRow",
|
|
211
|
+
"actions": "-x0sCW_actions",
|
|
212
|
+
"avatar": "-x0sCW_avatar",
|
|
213
|
+
"body": "-x0sCW_body",
|
|
214
|
+
"confirmActions": "-x0sCW_confirmActions",
|
|
215
|
+
"confirmBox": "-x0sCW_confirmBox",
|
|
216
|
+
"confirmCopy": "-x0sCW_confirmCopy",
|
|
217
|
+
"confirmTitle": "-x0sCW_confirmTitle",
|
|
218
|
+
"error": "-x0sCW_error",
|
|
219
|
+
"hint": "-x0sCW_hint",
|
|
220
|
+
"section": "-x0sCW_section",
|
|
221
|
+
"statusLabel": "-x0sCW_statusLabel",
|
|
222
|
+
"statusRow": "-x0sCW_statusRow",
|
|
223
|
+
"title": "-x0sCW_title"
|
|
224
|
+
};
|
|
225
|
+
//#endregion
|
|
226
|
+
//#region lib/types/client/DataOpsExpiryModal.js
|
|
227
|
+
/**
|
|
228
|
+
* Render the frame-wide expired-sign-in prompt and own its browser lifecycle.
|
|
229
|
+
* @param props - Root-scoped overlay owner, shared store, and injected callbacks.
|
|
230
|
+
* @returns The modal contribution, or nothing before injection or expiry.
|
|
231
|
+
*/
|
|
232
|
+
function DataOpsExpiryModal(props) {
|
|
233
|
+
const { t, start, openAuthorization } = props;
|
|
234
|
+
if (t === void 0 || start === void 0 || openAuthorization === void 0) return null;
|
|
235
|
+
return (0, react_jsx_runtime.jsx)(Loaded$1, {
|
|
236
|
+
...props,
|
|
237
|
+
t,
|
|
238
|
+
start,
|
|
239
|
+
openAuthorization
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
function Loaded$1(props) {
|
|
243
|
+
const state = props.useStore((value) => value);
|
|
244
|
+
(0, react.useEffect)(() => props.start(), [props.start]);
|
|
245
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
246
|
+
open: isLoginExpired(state.status) && !state.expiryPromptDismissed,
|
|
247
|
+
onClose: props.actions.dismissExpiryPrompt,
|
|
248
|
+
title: props.t("loginExpired"),
|
|
249
|
+
closeLabel: props.t("close"),
|
|
250
|
+
description: props.t("loginExpiredHint"),
|
|
251
|
+
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
252
|
+
variant: "ghost",
|
|
253
|
+
onClick: props.actions.dismissExpiryPrompt,
|
|
254
|
+
children: props.t("later")
|
|
255
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
256
|
+
variant: "primary",
|
|
257
|
+
onClick: props.openAuthorization,
|
|
258
|
+
children: props.t("signInAgain")
|
|
259
|
+
})] }),
|
|
260
|
+
children: state.failure !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
261
|
+
className: DataOpsSection_module_css_default.error,
|
|
262
|
+
role: "alert",
|
|
263
|
+
children: props.t(state.failure)
|
|
264
|
+
})
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
//#endregion
|
|
268
|
+
//#region lib/types/client/DataOpsSection.js
|
|
269
|
+
/**
|
|
270
|
+
* Render the DataOps connection state and authorization controls.
|
|
271
|
+
* @param props - Root-scoped Settings owner, store, and injected callbacks.
|
|
272
|
+
* @returns The localized Settings section, or nothing before injection.
|
|
273
|
+
*/
|
|
274
|
+
function DataOpsSection(props) {
|
|
275
|
+
const { t, reload, openAuthorization, disconnect } = props;
|
|
276
|
+
if (t === void 0 || reload === void 0 || openAuthorization === void 0 || disconnect === void 0) return null;
|
|
277
|
+
return (0, react_jsx_runtime.jsx)(Loaded, {
|
|
278
|
+
...props,
|
|
279
|
+
t,
|
|
280
|
+
reload,
|
|
281
|
+
openAuthorization,
|
|
282
|
+
disconnect
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
function Loaded(props) {
|
|
286
|
+
const { t, reload, openAuthorization, disconnect } = props;
|
|
287
|
+
const { status, loading, failure, disconnecting } = props.useStore((value) => value);
|
|
288
|
+
const [confirmingDisconnect, setConfirmingDisconnect] = (0, react.useState)(false);
|
|
289
|
+
const state = (0, react.useMemo)(() => {
|
|
290
|
+
if (loading) return {
|
|
291
|
+
dot: "ongoing",
|
|
292
|
+
label: t("loading")
|
|
293
|
+
};
|
|
294
|
+
if (failure !== void 0 && status === void 0) return {
|
|
295
|
+
dot: "warning",
|
|
296
|
+
label: t("connectionFailed")
|
|
297
|
+
};
|
|
298
|
+
if (status?.authorizationAccepted === true) return {
|
|
299
|
+
dot: "done",
|
|
300
|
+
label: t("connected")
|
|
301
|
+
};
|
|
302
|
+
if (isLoginExpired(status)) return {
|
|
303
|
+
dot: "warning",
|
|
304
|
+
label: t("loginExpired")
|
|
305
|
+
};
|
|
306
|
+
if (status?.credentialWritable === false) return {
|
|
307
|
+
dot: "warning",
|
|
308
|
+
label: t("managedByAdministrator")
|
|
309
|
+
};
|
|
310
|
+
return {
|
|
311
|
+
dot: "warning",
|
|
312
|
+
label: t("notConnected")
|
|
313
|
+
};
|
|
314
|
+
}, [
|
|
315
|
+
failure,
|
|
316
|
+
loading,
|
|
317
|
+
status,
|
|
318
|
+
t
|
|
319
|
+
]);
|
|
320
|
+
const connectedAccount = status?.authorizationAccepted === true ? status.account : null;
|
|
321
|
+
const accountIdentity = connectedAccount?.email || connectedAccount?.username;
|
|
322
|
+
const showActions = !confirmingDisconnect && (status !== void 0 || failure !== void 0);
|
|
323
|
+
const confirmDisconnect = () => {
|
|
324
|
+
disconnect().then((completed) => {
|
|
325
|
+
if (completed) setConfirmingDisconnect(false);
|
|
326
|
+
});
|
|
327
|
+
};
|
|
328
|
+
return (0, react_jsx_runtime.jsxs)("section", {
|
|
329
|
+
className: DataOpsSection_module_css_default.section,
|
|
330
|
+
children: [(0, react_jsx_runtime.jsx)("h2", {
|
|
331
|
+
className: DataOpsSection_module_css_default.title,
|
|
332
|
+
children: t("title")
|
|
333
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
334
|
+
className: DataOpsSection_module_css_default.body,
|
|
335
|
+
children: [
|
|
336
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
337
|
+
className: DataOpsSection_module_css_default.statusRow,
|
|
338
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: state.dot }), (0, react_jsx_runtime.jsx)("span", {
|
|
339
|
+
className: DataOpsSection_module_css_default.statusLabel,
|
|
340
|
+
role: failure !== void 0 && status === void 0 ? "alert" : void 0,
|
|
341
|
+
children: state.label
|
|
342
|
+
})]
|
|
343
|
+
}),
|
|
344
|
+
connectedAccount !== null && (0, react_jsx_runtime.jsxs)("div", {
|
|
345
|
+
className: DataOpsSection_module_css_default.accountRow,
|
|
346
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
347
|
+
className: DataOpsSection_module_css_default.avatar,
|
|
348
|
+
"aria-hidden": "true",
|
|
349
|
+
children: (connectedAccount.displayName || connectedAccount.username).slice(0, 1).toUpperCase()
|
|
350
|
+
}), (0, react_jsx_runtime.jsxs)("span", {
|
|
351
|
+
className: DataOpsSection_module_css_default.accountCopy,
|
|
352
|
+
children: [(0, react_jsx_runtime.jsx)("strong", { children: connectedAccount.displayName || connectedAccount.username }), (0, react_jsx_runtime.jsx)("span", { children: accountIdentity })]
|
|
353
|
+
})]
|
|
354
|
+
}),
|
|
355
|
+
isLoginExpired(status) && (0, react_jsx_runtime.jsx)("p", {
|
|
356
|
+
className: DataOpsSection_module_css_default.hint,
|
|
357
|
+
children: t("loginExpiredHint")
|
|
358
|
+
}),
|
|
359
|
+
failure !== void 0 && status !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
360
|
+
className: DataOpsSection_module_css_default.error,
|
|
361
|
+
role: "alert",
|
|
362
|
+
children: t(failure)
|
|
363
|
+
}),
|
|
364
|
+
showActions && (0, react_jsx_runtime.jsxs)("div", {
|
|
365
|
+
className: DataOpsSection_module_css_default.actions,
|
|
366
|
+
children: [
|
|
367
|
+
status !== void 0 && status.credentialWritable && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
368
|
+
variant: "primary",
|
|
369
|
+
onClick: openAuthorization,
|
|
370
|
+
children: status.authorizationAccepted ? t("reauthorize") : status.credentialConfigured ? t("signInAgain") : t("connect")
|
|
371
|
+
}),
|
|
372
|
+
status?.credentialConfigured === true && status.credentialWritable && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
373
|
+
variant: "outline",
|
|
374
|
+
onClick: () => {
|
|
375
|
+
setConfirmingDisconnect(true);
|
|
376
|
+
},
|
|
377
|
+
children: t("disconnect")
|
|
378
|
+
}),
|
|
379
|
+
status === void 0 && failure !== void 0 && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
380
|
+
variant: "ghost",
|
|
381
|
+
onClick: reload,
|
|
382
|
+
children: t("retry")
|
|
383
|
+
})
|
|
384
|
+
]
|
|
385
|
+
}),
|
|
386
|
+
confirmingDisconnect && (0, react_jsx_runtime.jsxs)("div", {
|
|
387
|
+
className: DataOpsSection_module_css_default.confirmBox,
|
|
388
|
+
children: [
|
|
389
|
+
(0, react_jsx_runtime.jsx)("h3", {
|
|
390
|
+
className: DataOpsSection_module_css_default.confirmTitle,
|
|
391
|
+
children: t("confirmDisconnect")
|
|
392
|
+
}),
|
|
393
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
394
|
+
className: DataOpsSection_module_css_default.confirmCopy,
|
|
395
|
+
children: t("confirmDisconnectDetail")
|
|
396
|
+
}),
|
|
397
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
398
|
+
className: DataOpsSection_module_css_default.confirmActions,
|
|
399
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
400
|
+
variant: "ghost",
|
|
401
|
+
disabled: disconnecting,
|
|
402
|
+
onClick: () => {
|
|
403
|
+
setConfirmingDisconnect(false);
|
|
404
|
+
},
|
|
405
|
+
children: t("keepConnected")
|
|
406
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
407
|
+
variant: "outline",
|
|
408
|
+
disabled: disconnecting,
|
|
409
|
+
onClick: confirmDisconnect,
|
|
410
|
+
children: t("confirm")
|
|
411
|
+
})]
|
|
412
|
+
})
|
|
413
|
+
]
|
|
414
|
+
})
|
|
415
|
+
]
|
|
416
|
+
})]
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
//#endregion
|
|
420
|
+
//#region lib/types/client/locales.js
|
|
421
|
+
/** English DataOps Settings copy. */
|
|
422
|
+
const en = {
|
|
423
|
+
nav: "DataOps",
|
|
424
|
+
title: "DataOps",
|
|
425
|
+
close: "Close",
|
|
426
|
+
later: "Later",
|
|
427
|
+
connected: "Connected",
|
|
428
|
+
loginExpired: "Sign-in expired",
|
|
429
|
+
loginExpiredHint: "Sign in again to continue using DataOps tools.",
|
|
430
|
+
notConnected: "Not connected",
|
|
431
|
+
connectionFailed: "Connection failed",
|
|
432
|
+
managedByAdministrator: "Managed by administrator",
|
|
433
|
+
connect: "Connect DataOps",
|
|
434
|
+
reauthorize: "Authorize again",
|
|
435
|
+
signInAgain: "Sign in again",
|
|
436
|
+
disconnect: "Disconnect",
|
|
437
|
+
confirmDisconnect: "Disconnect this DataOps account?",
|
|
438
|
+
confirmDisconnectDetail: "You’ll need to connect DataOps again before using this account.",
|
|
439
|
+
keepConnected: "Keep connected",
|
|
440
|
+
confirm: "Disconnect",
|
|
441
|
+
retry: "Retry",
|
|
442
|
+
loading: "Checking connection…",
|
|
443
|
+
popupBlocked: "The authorization window could not be opened. Allow pop-ups for this page and try again.",
|
|
444
|
+
connectFailed: "DataOps connection failed. Try again.",
|
|
445
|
+
authorizationExpired: "The DataOps authorization request expired. Connect again.",
|
|
446
|
+
authorizationResponseInvalid: "DataOps returned an incomplete authorization response. Connect again.",
|
|
447
|
+
tokenRequestRejected: "DataOps rejected the authorization request. Connect again.",
|
|
448
|
+
tokenAccountRejected: "DataOps rejected the selected account authorization. Sign in again.",
|
|
449
|
+
tokenServiceFailed: "The DataOps authorization service failed. Try again.",
|
|
450
|
+
tokenResponseInvalid: "DataOps returned an invalid token response. Connect again.",
|
|
451
|
+
accountVerificationFailed: "The authorized DataOps account could not be verified. Try again.",
|
|
452
|
+
authorizationActivationFailed: "The DataOps authorization could not be activated. Try again.",
|
|
453
|
+
disconnectFailed: "Unable to disconnect DataOps. Try again."
|
|
454
|
+
};
|
|
455
|
+
/** Chinese DataOps Settings copy. */
|
|
456
|
+
const zh = {
|
|
457
|
+
nav: "DataOps",
|
|
458
|
+
title: "DataOps",
|
|
459
|
+
close: "关闭",
|
|
460
|
+
later: "稍后",
|
|
461
|
+
connected: "已连接",
|
|
462
|
+
loginExpired: "登录已过期",
|
|
463
|
+
loginExpiredHint: "重新登录后即可继续使用 DataOps 工具。",
|
|
464
|
+
notConnected: "未连接",
|
|
465
|
+
connectionFailed: "连接失败",
|
|
466
|
+
managedByAdministrator: "由管理员管理",
|
|
467
|
+
connect: "连接 DataOps",
|
|
468
|
+
reauthorize: "重新授权",
|
|
469
|
+
signInAgain: "重新登录",
|
|
470
|
+
disconnect: "断开连接",
|
|
471
|
+
confirmDisconnect: "要断开这个 DataOps 账号吗?",
|
|
472
|
+
confirmDisconnectDetail: "断开后,需要重新连接 DataOps 才能继续使用此账号。",
|
|
473
|
+
keepConnected: "保持连接",
|
|
474
|
+
confirm: "确认断开",
|
|
475
|
+
retry: "重试",
|
|
476
|
+
loading: "正在检查连接…",
|
|
477
|
+
popupBlocked: "无法打开授权窗口。请允许当前页面打开弹窗后重试。",
|
|
478
|
+
connectFailed: "DataOps 连接失败,请重试。",
|
|
479
|
+
authorizationExpired: "DataOps 授权请求已失效,请重新连接。",
|
|
480
|
+
authorizationResponseInvalid: "DataOps 返回的授权结果不完整,请重新连接。",
|
|
481
|
+
tokenRequestRejected: "DataOps 拒绝了授权请求,请重新连接。",
|
|
482
|
+
tokenAccountRejected: "DataOps 拒绝了所选账号的授权,请重新登录。",
|
|
483
|
+
tokenServiceFailed: "DataOps 授权服务失败,请重试。",
|
|
484
|
+
tokenResponseInvalid: "DataOps 返回的token response无效,请重新连接。",
|
|
485
|
+
accountVerificationFailed: "无法确认已授权的 DataOps 账号,请重试。",
|
|
486
|
+
authorizationActivationFailed: "无法启用 DataOps 授权,请重试。",
|
|
487
|
+
disconnectFailed: "无法断开 DataOps,请重试。"
|
|
488
|
+
};
|
|
489
|
+
//#endregion
|
|
490
|
+
//#region lib/types/client/index.js
|
|
491
|
+
const NS = "settings.dataops";
|
|
492
|
+
/** Client services required for the Settings and frame-overlay contributions. */
|
|
493
|
+
const inject = ["slots", "locale"];
|
|
494
|
+
/** Register the shared DataOps lifecycle, Settings section, and expiry modal. */
|
|
495
|
+
function apply(ctx) {
|
|
496
|
+
ctx.effect(() => ctx.locale.register(NS, {
|
|
497
|
+
zh,
|
|
498
|
+
en
|
|
499
|
+
}), "mcp-dataops: Client copy");
|
|
500
|
+
const t = ctx.locale.bind(NS);
|
|
501
|
+
const store = createDataOpsStore();
|
|
502
|
+
const controller = new DataOpsController();
|
|
503
|
+
const injectFace = (actions) => {
|
|
504
|
+
controller.attach(actions);
|
|
505
|
+
return {
|
|
506
|
+
t,
|
|
507
|
+
start: () => controller.start(),
|
|
508
|
+
reload: () => {
|
|
509
|
+
controller.load();
|
|
510
|
+
},
|
|
511
|
+
openAuthorization: () => {
|
|
512
|
+
controller.openAuthorization();
|
|
513
|
+
},
|
|
514
|
+
disconnect: () => controller.disconnect()
|
|
515
|
+
};
|
|
516
|
+
};
|
|
517
|
+
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
518
|
+
name: "settings.section",
|
|
519
|
+
id: "dataops",
|
|
520
|
+
order: 25,
|
|
521
|
+
label: () => t("nav"),
|
|
522
|
+
store,
|
|
523
|
+
inject: injectFace
|
|
524
|
+
}, DataOpsSection));
|
|
525
|
+
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
526
|
+
name: "shell.overlay",
|
|
527
|
+
id: "dataops-authorization",
|
|
528
|
+
order: 25,
|
|
529
|
+
store,
|
|
530
|
+
inject: injectFace
|
|
531
|
+
}, DataOpsExpiryModal));
|
|
532
|
+
}
|
|
533
|
+
//#endregion
|
|
534
|
+
exports.apply = apply;
|
|
535
|
+
exports.inject = inject;
|
|
536
|
+
return module.exports;
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
//# sourceMappingURL=client.js.map
|