dsh-limix-data 0.0.0-stage → 0.3.11

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 ADDED
@@ -0,0 +1,73 @@
1
+ # PolyForm Noncommercial License 1.0.0
2
+
3
+ <https://polyformproject.org/licenses/noncommercial/1.0.0>
4
+
5
+ ## Acceptance
6
+
7
+ In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
8
+
9
+ ## Copyright License
10
+
11
+ The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
12
+
13
+ ## Distribution License
14
+
15
+ The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
16
+
17
+ ## Notices
18
+
19
+ You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
20
+
21
+ > Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
22
+
23
+ ## Changes and New Works License
24
+
25
+ The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
26
+
27
+ ## Patent License
28
+
29
+ The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
30
+
31
+ ## Noncommercial Purposes
32
+
33
+ Any noncommercial purpose is a permitted purpose.
34
+
35
+ ## Personal Uses
36
+
37
+ Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
38
+
39
+ ## Noncommercial Organizations
40
+
41
+ Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
42
+
43
+ ## Fair Use
44
+
45
+ You may have "fair use" rights for the software under the law. These terms do not limit them.
46
+
47
+ ## No Other Rights
48
+
49
+ These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
50
+
51
+ ## Patent Defense
52
+
53
+ If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
54
+
55
+ ## Violations
56
+
57
+ The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
58
+
59
+ ## No Liability
60
+
61
+ ***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
62
+
63
+ ## Definitions
64
+
65
+ The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
66
+
67
+ **You** refers to the individual or entity agreeing to these terms.
68
+
69
+ **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
70
+
71
+ **Your licenses** are all the licenses granted to you for the software under these terms.
72
+
73
+ **Use** means anything you do with the software requiring one of your licenses.
package/LICENSING.md ADDED
@@ -0,0 +1,19 @@
1
+ # 使用许可与商业授权
2
+
3
+ 从 0.3.10 起,本项目提供的自有代码采用 **PolyForm Noncommercial License 1.0.0**。非商业用途可按 LICENSE 使用、修改和分发;商业用途需要事先取得权利人的单独书面授权。
4
+
5
+ “没有直接收费”不自动等于非商业用途。为商业业务提供内部生产工具、集成进商业产品、为客户提供收费服务等用途,请先联系授权。许可证对非商业组织等情形有明确条款,具体以 LICENSE 原文为准。
6
+
7
+ 商业授权联系人:**Limitless**,GitHub [@Limitless2023](https://github.com/Limitless2023)。请在[仓库 Issues](https://github.com/Limitless2023/limix-dsh/issues/new?title=Commercial%20license%20inquiry) 发起商业授权咨询,说明使用主体、用途和部署规模;不要在公开 Issue 中附密钥、客户数据或合同资料。发起咨询不代表已经获得授权。
8
+
9
+ ## 授权范围
10
+
11
+ - 非商业条款适用于本项目有权许可的自有代码;不会替换第三方代码的许可证。
12
+ - tool 中打包的 React/React DOM 保留 MIT,全文见 THIRD-PARTY-NOTICES.md。npm 安装的独立依赖保留各自许可证。
13
+ - LimiX 的名称、Logo、图片与商标归原权利人;本许可证不另行授予商标权,也不授权将品牌用于其他产品。来源见 cover 包 assets/SOURCES.md。
14
+ - cover 的历史版本曾声明 MIT;已经授予的旧版权利不被新版条款撤回。仍以 MIT 获得的历史代码及其未变更部分保留该权利。旧版见 https://github.com/Limitless2023/limix-dsh/releases/tag/v0.3.9 。
15
+ - 插件授权不包含 LimiX API、DeepSeek 或其他第三方服务的账户、额度与服务使用权。
16
+
17
+ 这是**源码可见、非商业许可**,不称为“开源许可证”。本文是阅读指引,不修改 PolyForm 原文,也不限制第三方或旧版已经授予的权利。
18
+
19
+ 许可证原文来源:https://polyformproject.org/licenses/noncommercial/1.0.0
@@ -0,0 +1,46 @@
1
+ # Third-party and pre-existing rights
2
+
3
+ The PolyForm Noncommercial license applies to licensable original project code. It does not replace the independent licenses or previously granted rights described below.
4
+
5
+ ## React and React DOM 18.3.1
6
+
7
+ Bundled in dsh-limix-tool/lib/index.js to render reports. React used by the browser plugins is supplied by the Harness runtime.
8
+
9
+ Source: https://github.com/facebook/react/tree/v18.3.1
10
+ The following MIT license is reproduced from the installed React and React DOM packages:
11
+
12
+ MIT License
13
+
14
+ Copyright (c) Facebook, Inc. and its affiliates.
15
+
16
+ Permission is hereby granted, free of charge, to any person obtaining a copy
17
+ of this software and associated documentation files (the "Software"), to deal
18
+ in the Software without restriction, including without limitation the rights
19
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20
+ copies of the Software, and to permit persons to whom the Software is
21
+ furnished to do so, subject to the following conditions:
22
+
23
+ The above copyright notice and this permission notice shall be included in all
24
+ copies or substantial portions of the Software.
25
+
26
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
+ SOFTWARE.
33
+
34
+ ## Separately installed dependencies
35
+
36
+ mysql2 and pg, along with their transitive dependencies, are installed as separate npm packages. Their own license files and notices apply; this project does not relicense them. Python packages prepared at runtime also retain their own licenses.
37
+
38
+ ## LimiX brand assets
39
+
40
+ LimiX names, logos and images belong to their respective rights holders. No additional trademark rights are granted by this project's source-code license. Official source URLs and checksums are recorded in dsh-limix-cover/assets/SOURCES.md.
41
+
42
+ ## Earlier dsh-limix-cover releases
43
+
44
+ Earlier dsh-limix-cover releases, including 0.3.9, declared MIT in their package metadata. The new distribution policy does not withdraw prior grants or impose additional restrictions on code already received under those grants. Existing third-party and historical rights remain unaffected.
45
+
46
+ Reference: https://github.com/Limitless2023/limix-dsh/tree/v0.3.9/packages/brand
Binary file
@@ -0,0 +1,4 @@
1
+ # 全局设置页与路由;不在全局注册 datasource 工具。
2
+ - insert:
3
+ - id: limix-data-settings
4
+ name: dsh-limix-data
package/lib/client.js ADDED
@@ -0,0 +1,368 @@
1
+ window.__ModuleLoader__.load({ id: "dsh-limix-data", factory: (require) => {
2
+ var module = { exports: {} }; var exports = module.exports;
3
+ //#region rolldown:runtime
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
+ key = keys[i];
13
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
21
+ value: mod,
22
+ enumerable: true
23
+ }) : target, mod));
24
+
25
+ //#endregion
26
+ let react = require("react");
27
+ react = __toESM(react);
28
+ let react_jsx_runtime = require("react/jsx-runtime");
29
+ react_jsx_runtime = __toESM(react_jsx_runtime);
30
+
31
+ //#region src/client/DatasourceSettings.tsx
32
+ const ACCENT = "rgb(65, 118, 230)";
33
+ const EMPTY = {
34
+ name: "",
35
+ kind: "postgres",
36
+ host: "localhost",
37
+ port: 5432,
38
+ database: "",
39
+ schema: "",
40
+ username: "",
41
+ password: ""
42
+ };
43
+ const ui = {
44
+ wrap: {
45
+ padding: "8px 4px",
46
+ fontSize: 13,
47
+ maxWidth: 760
48
+ },
49
+ h: {
50
+ fontSize: 15,
51
+ fontWeight: 700,
52
+ margin: "0 0 4px"
53
+ },
54
+ sub: {
55
+ opacity: .55,
56
+ marginBottom: 14,
57
+ lineHeight: 1.6
58
+ },
59
+ card: {
60
+ border: "1px solid rgba(0,0,0,.09)",
61
+ borderRadius: 12,
62
+ padding: 14,
63
+ marginBottom: 12
64
+ },
65
+ row: {
66
+ display: "flex",
67
+ gap: 8,
68
+ flexWrap: "wrap",
69
+ marginBottom: 8
70
+ },
71
+ field: {
72
+ display: "flex",
73
+ flexDirection: "column",
74
+ gap: 3
75
+ },
76
+ label: {
77
+ fontSize: 11,
78
+ opacity: .55
79
+ },
80
+ input: {
81
+ padding: "5px 9px",
82
+ borderRadius: 8,
83
+ border: "1px solid rgba(0,0,0,.15)",
84
+ fontSize: 13,
85
+ background: "Canvas",
86
+ color: "CanvasText",
87
+ minWidth: 0
88
+ },
89
+ btn: (primary) => ({
90
+ fontSize: 12.5,
91
+ cursor: "pointer",
92
+ padding: "5px 14px",
93
+ borderRadius: 999,
94
+ border: primary ? "none" : "1px solid rgba(0,0,0,.15)",
95
+ background: primary ? ACCENT : "transparent",
96
+ color: primary ? "#fff" : "inherit"
97
+ }),
98
+ tag: (ok) => ({
99
+ fontSize: 12,
100
+ marginLeft: 8,
101
+ color: ok ? "#16a34a" : "#dc2626"
102
+ })
103
+ };
104
+ function DatasourceSettings() {
105
+ const [sources, setSources] = (0, react.useState)([]);
106
+ const [loaded, setLoaded] = (0, react.useState)(false);
107
+ const [dirty, setDirty] = (0, react.useState)(false);
108
+ const [msg, setMsg] = (0, react.useState)(null);
109
+ const [testing, setTesting] = (0, react.useState)(null);
110
+ const [testResult, setTestResult] = (0, react.useState)({});
111
+ (0, react.useEffect)(() => {
112
+ fetch("/limix-datasource/config").then((r) => r.json()).then((d) => {
113
+ setSources(d.sources ?? []);
114
+ setLoaded(true);
115
+ }).catch(() => {
116
+ setMsg({
117
+ ok: false,
118
+ text: "读取配置失败(Node 半路由不可达)"
119
+ });
120
+ setLoaded(true);
121
+ });
122
+ }, []);
123
+ function patch(i, k, v) {
124
+ setSources((ss) => ss.map((s, j) => j === i ? {
125
+ ...s,
126
+ [k]: v
127
+ } : s));
128
+ setDirty(true);
129
+ setMsg(null);
130
+ }
131
+ async function test(i) {
132
+ setTesting(i);
133
+ try {
134
+ const r = await fetch("/limix-datasource/test", {
135
+ method: "POST",
136
+ headers: { "content-type": "application/json" },
137
+ body: JSON.stringify({ source: sources[i] })
138
+ }).then((x) => x.json());
139
+ setTestResult((m) => ({
140
+ ...m,
141
+ [i]: r.ok ? {
142
+ ok: true,
143
+ text: `连接成功 ${r.version ?? ""}`
144
+ } : {
145
+ ok: false,
146
+ text: r.error ?? "失败"
147
+ }
148
+ }));
149
+ } catch (e) {
150
+ setTestResult((m) => ({
151
+ ...m,
152
+ [i]: {
153
+ ok: false,
154
+ text: String(e)
155
+ }
156
+ }));
157
+ } finally {
158
+ setTesting(null);
159
+ }
160
+ }
161
+ async function save() {
162
+ try {
163
+ const r = await fetch("/limix-datasource/config", {
164
+ method: "POST",
165
+ headers: { "content-type": "application/json" },
166
+ body: JSON.stringify({ sources })
167
+ }).then((x) => x.json());
168
+ if (r.ok) {
169
+ setSources(r.sources);
170
+ setDirty(false);
171
+ setMsg({
172
+ ok: true,
173
+ text: "已保存,agent 侧即时生效"
174
+ });
175
+ } else setMsg({
176
+ ok: false,
177
+ text: r.error ?? "保存失败"
178
+ });
179
+ } catch (e) {
180
+ setMsg({
181
+ ok: false,
182
+ text: String(e)
183
+ });
184
+ }
185
+ }
186
+ const F = (i, k, label, width, type = "text") => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
187
+ style: ui.field,
188
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
189
+ style: ui.label,
190
+ children: label
191
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
192
+ style: {
193
+ ...ui.input,
194
+ width
195
+ },
196
+ type,
197
+ value: String(sources[i][k] ?? ""),
198
+ onChange: (e) => patch(i, k, k === "port" ? Number(e.target.value) : e.target.value)
199
+ })]
200
+ });
201
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
202
+ style: ui.wrap,
203
+ children: [
204
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
205
+ style: ui.h,
206
+ children: "数据源"
207
+ }),
208
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
209
+ style: ui.sub,
210
+ children: [
211
+ "配置客户数据库连接(postgres / mysql),LimiX 分析师即可对话取数:看表结构 → 生成 SQL(先展示确认)→ 预览 → 物化成 CSV 进文件区 → 预测。全链路只读三闸防护;",
212
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "建议使用只读账号" }),
213
+ "。 凭据以 0600 权限明文存于 DSH_HOME/limix-datasource.json(本地单用户环境取舍)。"
214
+ ]
215
+ }),
216
+ !loaded && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
217
+ style: { opacity: .5 },
218
+ children: "加载中…"
219
+ }),
220
+ loaded && sources.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
221
+ style: {
222
+ opacity: .6,
223
+ marginBottom: 12
224
+ },
225
+ children: "还没有数据源,点下方\"新增\"。"
226
+ }),
227
+ sources.map((s, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
228
+ style: ui.card,
229
+ children: [
230
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
231
+ style: ui.row,
232
+ children: [
233
+ F(i, "name", "名称", 170),
234
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
235
+ style: ui.field,
236
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
237
+ style: ui.label,
238
+ children: "类型"
239
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
240
+ style: {
241
+ ...ui.input,
242
+ width: 110
243
+ },
244
+ value: s.kind,
245
+ onChange: (e) => patch(i, "kind", e.target.value),
246
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
247
+ value: "postgres",
248
+ children: "postgres"
249
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
250
+ value: "mysql",
251
+ children: "mysql"
252
+ })]
253
+ })]
254
+ }),
255
+ F(i, "host", "主机", 150),
256
+ F(i, "port", "端口", 70)
257
+ ]
258
+ }),
259
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
260
+ style: ui.row,
261
+ children: [
262
+ F(i, "database", "数据库", 130),
263
+ F(i, "schema", "schema(PG 可选)", 130),
264
+ F(i, "username", "用户名", 120),
265
+ F(i, "password", "密码", 140, "password")
266
+ ]
267
+ }),
268
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
269
+ style: {
270
+ display: "flex",
271
+ alignItems: "center",
272
+ gap: 8
273
+ },
274
+ children: [
275
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
276
+ style: {
277
+ display: "flex",
278
+ alignItems: "center",
279
+ gap: 5,
280
+ marginRight: "auto",
281
+ fontSize: 12
282
+ },
283
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
284
+ type: "checkbox",
285
+ checked: !!s.isDemo,
286
+ onChange: (e) => patch(i, "isDemo", e.target.checked)
287
+ }), "演示数据(模拟数据源)"]
288
+ }),
289
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
290
+ role: "button",
291
+ style: ui.btn(false),
292
+ onClick: () => void test(i),
293
+ children: testing === i ? "测试中…" : "测试连接"
294
+ }),
295
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
296
+ role: "button",
297
+ style: {
298
+ ...ui.btn(false),
299
+ color: "#dc2626"
300
+ },
301
+ onClick: () => {
302
+ setSources((ss) => ss.filter((_, j) => j !== i));
303
+ setDirty(true);
304
+ },
305
+ children: "删除"
306
+ }),
307
+ testResult[i] && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
308
+ style: ui.tag(testResult[i].ok),
309
+ children: testResult[i].text
310
+ })
311
+ ]
312
+ })
313
+ ]
314
+ }, s.id ?? `new-${i}`)),
315
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
316
+ style: {
317
+ display: "flex",
318
+ gap: 10,
319
+ alignItems: "center",
320
+ marginTop: 4
321
+ },
322
+ children: [
323
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
324
+ role: "button",
325
+ style: ui.btn(false),
326
+ onClick: () => {
327
+ setSources((ss) => [...ss, { ...EMPTY }]);
328
+ setDirty(true);
329
+ },
330
+ children: "+ 新增数据源"
331
+ }),
332
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
333
+ role: "button",
334
+ style: {
335
+ ...ui.btn(true),
336
+ opacity: dirty ? 1 : .5
337
+ },
338
+ onClick: () => {
339
+ if (dirty) save();
340
+ },
341
+ children: "保存"
342
+ }),
343
+ msg && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
344
+ style: ui.tag(msg.ok),
345
+ children: msg.text
346
+ })
347
+ ]
348
+ })
349
+ ]
350
+ });
351
+ }
352
+
353
+ //#endregion
354
+ //#region src/client/index.tsx
355
+ const inject = ["slots"];
356
+ function apply(ctx) {
357
+ ctx.slots.inject("settings.section", () => ctx.slots.register({
358
+ name: "settings.section",
359
+ id: "limix-datasource",
360
+ order: 30,
361
+ label: () => "数据源"
362
+ }, DatasourceSettings));
363
+ }
364
+
365
+ //#endregion
366
+ exports.apply = apply;
367
+ exports.inject = inject;
368
+ return module.exports; } });