e10-data 0.1.9 → 0.1.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/README.md +2 -2
- package/bin/e10-data.mjs +178 -62
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ npm i -g e10-data # 全局安装
|
|
|
9
9
|
e10-data --version # 验证
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
> 依赖:认证复用 `weaver-e10-login`
|
|
12
|
+
> 依赖:认证复用 `weaver-e10-login` 的登录态。**加解密全部由 `e10-login` 负责,本 CLI 不实现任何加解密**(auth 文件由 e10-login 自己的密钥体系加密:1.5.0 起为「每机随机密钥 + OS keychain」,早期版本为固定 seed,只有 e10-login 解得开)。CLI 通过 e10-login 的命令出口取明文凭据,优先级:**① `e10-login auth --json`**(推荐的正式契约)→ **② `e10-login whoami --json`**(其 JSON 带 `cookies` 时)→ **③ `e10-login whoami`**(文本解析,当前实际路径)→ **④ 明文镜像 `~/.workbuddy/e10-login-cache.md`**(兜底,命中时打印告警)。请先安装并登录 weaver-e10-login(`e10-login oidc`)。
|
|
13
13
|
|
|
14
14
|
## 命令总览
|
|
15
15
|
|
|
@@ -29,7 +29,7 @@ e10-data attend statis 考勤假期余额统计 getAttendInfoStatis(hr-atte
|
|
|
29
29
|
- `--json`:原样输出接口 JSON(供脚本/Agent 消费);默认人读输出。
|
|
30
30
|
- 复杂 JSON/中文参数:推荐 `@文件` 承载(如 `--dsl @q.json`、`--where @cond.json`)。
|
|
31
31
|
- ⚠️ 大整数精度(自动处理):E10 的 ID 多为 19 位,超过 JS 安全整数(2^53-1≈9e15)。CLI 解析 JSON 时**自动把超范围裸整数转成字符串**再发请求/输出(实测后端接受字符串做 =/IN/BETWEEN 数值比较),无需手动加引号,也不误伤字符串正文。
|
|
32
|
-
-
|
|
32
|
+
- 认证:**加解密由 `e10-login` 负责(本 CLI 不参与)**。凭据出口优先级:`e10-login auth --json` → `e10-login whoami --json` → `e10-login whoami`(文本)→ 明文镜像 `~/.workbuddy/e10-login-cache.md`(兜底,命中时告警)。命中的出口会记入 `~/.e10-cli/.e10-data-auth-mode`(只存模式名、不存凭据),下次优先复用。环境变量:`E10_DATA_AUTH_PROBE=1` 强制重新探测、`E10_DATA_AUTH_MODE=<模式名>` 手动指定、`E10_DATA_QUIET=1` 抑制告警(告警只走 stderr)。
|
|
33
33
|
- 版本更新:`npm i -g e10-data@latest`;查看源上最新 `npm view e10-data version`。
|
|
34
34
|
|
|
35
35
|
## 用法示例
|
package/bin/e10-data.mjs
CHANGED
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
* e10-data attend statis 考勤假期余额统计 getAttendInfoStatis(hr-attendance 病假/事假,2026-09-07)
|
|
16
16
|
*
|
|
17
17
|
* 通用:--json 原样输出;复杂 JSON 参数支持 @文件 或 内联(中文走 @文件 更稳)
|
|
18
|
-
*
|
|
18
|
+
* 认证:加解密全部由 e10-login 负责(本 CLI 不实现任何加解密)。凭据出口优先级:
|
|
19
|
+
* ① e10-login auth --json → ② e10-login whoami --json → ③ e10-login whoami(文本解析)
|
|
20
|
+
* → ④ 明文镜像 ~/.workbuddy/e10-login-cache.md(兜底,命中时告警);均不可用时提示先 e10-login oidc 登录
|
|
19
21
|
*
|
|
20
22
|
* 用法示例:
|
|
21
23
|
* node e10-data.mjs query --conn 1144919996804022272 --model dw --schema dw --dsl @q.json
|
|
@@ -29,6 +31,7 @@ import fs from "node:fs";
|
|
|
29
31
|
import os from "node:os";
|
|
30
32
|
import path from "node:path";
|
|
31
33
|
import crypto from "node:crypto";
|
|
34
|
+
import { spawnSync } from "node:child_process";
|
|
32
35
|
import { fileURLToPath } from "node:url";
|
|
33
36
|
|
|
34
37
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -40,70 +43,148 @@ function cliVersion() {
|
|
|
40
43
|
const UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36";
|
|
41
44
|
const EB_BIZ_ID = "10000000000000000";
|
|
42
45
|
|
|
43
|
-
// ----------------
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
// ---------------- 认证(加解密全部交由 e10-login,本 CLI 不再实现任何加解密)----------------
|
|
47
|
+
// 背景:auth 文件由 e10-login 自己的密钥体系加密 —— e10-login 1.5.0 起为「每机随机密钥 + OS keychain
|
|
48
|
+
// (@napi-rs/keyring,service=e10-cli / account=auth-key;keychain 不可用才落 ~/.e10-cli/.key)」,
|
|
49
|
+
// 早期版本为固定 seed。**只有 e10-login 解得开**,所以本 CLI 只负责「向 e10-login 要明文凭据」,
|
|
50
|
+
// 不再自行解密 —— e10-login 以后更换密钥体系 / 算法 / profile 机制,本 CLI 都无需改动。
|
|
51
|
+
// 凭据出口优先级(命中即返回;命中的"模式名"会记入 ~/.e10-cli/.e10-data-auth-mode,只存模式、不存凭据):
|
|
52
|
+
// ① e10-login auth --json 正式契约(推荐 e10-login 侧新增;一旦可用自动优先)
|
|
53
|
+
// ② e10-login whoami --json 其 JSON 输出带 cookies 字段时可用
|
|
54
|
+
// ③ e10-login whoami 文本输出解析(当前 e10-login 1.5.0 的实际可用路径)
|
|
55
|
+
// ④ ~/.workbuddy/e10-login-cache.md 明文镜像 —— 最后兜底,命中时打印告警(该文件可能已过期)
|
|
56
|
+
// 环境变量:E10_DATA_AUTH_PROBE=1 强制重新探测优先级;E10_DATA_AUTH_MODE=<模式名> 手动指定;
|
|
57
|
+
// E10_DATA_QUIET=1 抑制告警输出(告警一律走 stderr,不污染 --json 的 stdout)。
|
|
58
|
+
const AUTH_MODE_FILE = path.join(os.homedir(), ".e10-cli", ".e10-data-auth-mode");
|
|
59
|
+
|
|
60
|
+
/** 定位当前 profile 的 auth 文件(仅用于"是否已登录"的判断与报错提示,本 CLI 不读其内容做解密) */
|
|
61
|
+
function authFilePath() {
|
|
62
|
+
const home = os.homedir();
|
|
63
|
+
let profile = "default";
|
|
49
64
|
try {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
if (combined.length < IV + TAG + 1) return null;
|
|
53
|
-
const key = crypto.createHash("sha256").update(E10_AUTH_SEED).digest();
|
|
54
|
-
const decipher = crypto.createDecipheriv("aes-256-gcm", key, combined.subarray(0, IV), { authTagLength: TAG });
|
|
55
|
-
decipher.setAuthTag(combined.subarray(combined.length - TAG));
|
|
56
|
-
return JSON.parse(Buffer.concat([decipher.update(combined.subarray(IV, combined.length - TAG)), decipher.final()]).toString("utf-8"));
|
|
57
|
-
} catch { return null; }
|
|
58
|
-
}
|
|
59
|
-
function parseAuthPayload(raw) {
|
|
60
|
-
try { // 兼容两种形态:加密 wrapper({enc:true,data:base64})与明文 JSON({cookies,userId,...})
|
|
61
|
-
const obj = JSON.parse(raw);
|
|
62
|
-
if (obj && obj.enc === true && typeof obj.data === "string") return decryptAuthWrapper(obj);
|
|
63
|
-
if (obj && obj.cookies && (obj.userId || obj.cookies.ETEAMSID)) return obj;
|
|
65
|
+
const activeFile = path.join(home, ".e10-cli", "profile");
|
|
66
|
+
if (fs.existsSync(activeFile)) { const n = fs.readFileSync(activeFile, "utf-8").trim(); if (n) profile = n; }
|
|
64
67
|
} catch {}
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (c && !/langType=/.test(c)) c = "langType=zh_CN; " + c;
|
|
72
|
-
if (c && agent && !/agentType=/.test(c)) c += "; agentType=" + agent;
|
|
73
|
-
if (c && !/isAgent=/.test(c)) c += "; isAgent=true";
|
|
74
|
-
if (!c && eteamsid) c = "langType=zh_CN; ETEAMSID=" + eteamsid + "; agentType=" + agent + "; isAgent=true";
|
|
75
|
-
return { eteamsid, cookie: c };
|
|
76
|
-
}
|
|
77
|
-
function authFromE10Cli() { // ① 权威源:~/.e10-cli/profiles/<active>/auth
|
|
68
|
+
return { profile, file: path.join(home, ".e10-cli", "profiles", profile, "auth") };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let lastLoginDiag = "";
|
|
72
|
+
/** 调用 e10-login(凭据的唯一来源);失败返回 null,并把诊断信息留在 lastLoginDiag */
|
|
73
|
+
function runLoginCli(args) {
|
|
78
74
|
try {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
75
|
+
const r = spawnSync("e10-login", args, { shell: true, encoding: "utf-8", timeout: 20000, windowsHide: true });
|
|
76
|
+
const out = (r.stdout || "").trim();
|
|
77
|
+
if (r.error || r.status !== 0) {
|
|
78
|
+
lastLoginDiag = ((r.stderr || "") + out).trim().split(/\r?\n/).slice(0, 2).join(" / ") || (r.error ? String(r.error.message) : "exit=" + r.status);
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return out || null;
|
|
82
|
+
} catch (e) { lastLoginDiag = String((e && e.message) || e); return null; }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** 归一化 + 校验(缺 baseUrl / eteamsid / cookie 一律视为该出口不可用,继续下一个出口) */
|
|
86
|
+
function normalizeAuth(o) {
|
|
87
|
+
if (!o) return null;
|
|
88
|
+
const baseUrl = String(o.baseUrl || "").trim().replace(/\/+$/, "");
|
|
89
|
+
const eteamsid = String(o.eteamsid || "").trim();
|
|
90
|
+
const cookie = String(o.cookie || "").trim();
|
|
91
|
+
if (!baseUrl || !eteamsid || !cookie) return null;
|
|
92
|
+
if (/^\((未知|空)\)$/.test(eteamsid) || /^\((未知|空)\)$/.test(cookie)) return null;
|
|
93
|
+
return { baseUrl, eteamsid, cookie, userId: String(o.userId || "").trim(), tenantKey: String(o.tenantKey || "").trim(), source: o.source };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** ① e10-login auth --json(正式契约:{v,baseUrl,eteamsId,cookie,userAgent,userId,tenantKey,agentType,profile}) */
|
|
97
|
+
function providerAuthJson() {
|
|
98
|
+
const out = runLoginCli(["auth", "--json"]);
|
|
99
|
+
if (!out) return null;
|
|
100
|
+
let j; try { j = JSON.parse(out); } catch { return null; }
|
|
101
|
+
if (!j || typeof j !== "object" || Array.isArray(j)) return null;
|
|
102
|
+
return normalizeAuth({
|
|
103
|
+
baseUrl: j.baseUrl || j.base_url,
|
|
104
|
+
eteamsid: j.eteamsId || j.eteamsid,
|
|
105
|
+
cookie: typeof j.cookie === "string" ? j.cookie : "",
|
|
106
|
+
userId: j.userId || j.employeeId,
|
|
107
|
+
tenantKey: j.tenantKey,
|
|
108
|
+
source: "e10-login auth --json",
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** ② e10-login whoami --json(需其 JSON 带 cookies 字符串;当前 1.5.0 未带 → 自动落到 ③) */
|
|
113
|
+
function providerWhoamiJson() {
|
|
114
|
+
const out = runLoginCli(["whoami", "--json"]);
|
|
115
|
+
if (!out) return null;
|
|
116
|
+
let j; try { j = JSON.parse(out); } catch { return null; }
|
|
117
|
+
if (!j || typeof j !== "object" || Array.isArray(j)) return null;
|
|
118
|
+
const cookie = typeof j.cookies === "string" ? j.cookies : (typeof j.cookie === "string" ? j.cookie : "");
|
|
119
|
+
return normalizeAuth({
|
|
120
|
+
baseUrl: j.baseUrl,
|
|
121
|
+
eteamsid: j.eteamsId || j.eteamsid,
|
|
122
|
+
cookie,
|
|
123
|
+
userId: j.employeeId || j.userId,
|
|
124
|
+
tenantKey: j.tenantKey,
|
|
125
|
+
source: "e10-login whoami --json",
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** ③ e10-login whoami(文本输出解析:employeeId / tenantKey / baseUrl / ETEAMSID / cookies / User-Agent) */
|
|
130
|
+
function providerWhoamiText() {
|
|
131
|
+
const out = runLoginCli(["whoami"]);
|
|
132
|
+
if (!out) return null;
|
|
133
|
+
const m = {};
|
|
134
|
+
for (const line of out.split(/\r?\n/)) {
|
|
135
|
+
const x = line.match(/^\s*([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.+?)\s*$/);
|
|
136
|
+
if (x) m[x[1].toLowerCase()] = x[2];
|
|
137
|
+
}
|
|
138
|
+
return normalizeAuth({
|
|
139
|
+
baseUrl: m["baseurl"],
|
|
140
|
+
eteamsid: m["eteamsid"],
|
|
141
|
+
cookie: m["cookies"],
|
|
142
|
+
userId: m["employeeid"] || m["userid"],
|
|
143
|
+
tenantKey: m["tenantkey"],
|
|
144
|
+
source: "e10-login whoami(文本)",
|
|
145
|
+
});
|
|
92
146
|
}
|
|
93
|
-
|
|
147
|
+
|
|
148
|
+
/** ④ 明文镜像(最后兜底:不涉及任何解密,但可能已过期 → 命中时告警) */
|
|
149
|
+
function providerCacheMd() {
|
|
94
150
|
const p = path.join(os.homedir(), ".workbuddy", "e10-login-cache.md");
|
|
95
151
|
if (!fs.existsSync(p)) return null;
|
|
96
152
|
const txt = fs.readFileSync(p, "utf-8");
|
|
97
153
|
const get = (key) => {
|
|
98
|
-
const
|
|
99
|
-
return
|
|
154
|
+
const mm = txt.match(new RegExp("\\*\\*" + key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "\\*\\*\\s*[::]\\s*`?([^`\\n]+)`?"));
|
|
155
|
+
return mm ? mm[1].trim() : "";
|
|
100
156
|
};
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
if (!
|
|
104
|
-
return
|
|
157
|
+
const eteamsid = get("ETEAMSID");
|
|
158
|
+
let cookie = get("完整 Cookie 串");
|
|
159
|
+
if (!cookie && eteamsid) cookie = "langType=zh_CN; ETEAMSID=" + eteamsid + "; agentType=workbuddy; isAgent=true";
|
|
160
|
+
return normalizeAuth({
|
|
161
|
+
baseUrl: get("baseUrl"), eteamsid, cookie,
|
|
162
|
+
userId: get("userId") || get("employeeId"), tenantKey: get("tenantKey"),
|
|
163
|
+
source: "明文镜像 ~/.workbuddy/e10-login-cache.md(可能已过期)",
|
|
164
|
+
});
|
|
105
165
|
}
|
|
106
|
-
|
|
166
|
+
|
|
167
|
+
const AUTH_PROVIDERS = [
|
|
168
|
+
["auth-json", providerAuthJson],
|
|
169
|
+
["whoami-json", providerWhoamiJson],
|
|
170
|
+
["whoami-text", providerWhoamiText],
|
|
171
|
+
["cache-md", providerCacheMd],
|
|
172
|
+
];
|
|
173
|
+
/** 兜底出口不进记忆:否则 e10-login 偶发不可用一次,就会把"用镜像"永久设为首选、次次告警 */
|
|
174
|
+
const AUTH_FALLBACK_PROVIDERS = new Set(["cache-md"]);
|
|
175
|
+
|
|
176
|
+
function readAuthModeMemo() {
|
|
177
|
+
try {
|
|
178
|
+
const s = fs.readFileSync(AUTH_MODE_FILE, "utf-8").trim();
|
|
179
|
+
return AUTH_PROVIDERS.some(([n]) => n === s) ? s : null;
|
|
180
|
+
} catch { return null; }
|
|
181
|
+
}
|
|
182
|
+
function writeAuthModeMemo(name) {
|
|
183
|
+
try { fs.mkdirSync(path.dirname(AUTH_MODE_FILE), { recursive: true }); fs.writeFileSync(AUTH_MODE_FILE, name, "utf-8"); } catch {}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** 凭据取自 e10-login 时,顺手把明文镜像刷新到最新(保持镜像可用;镜像不参与正常取数) */
|
|
187
|
+
function syncCacheMd(auth) {
|
|
107
188
|
try {
|
|
108
189
|
const p = path.join(os.homedir(), ".workbuddy", "e10-login-cache.md");
|
|
109
190
|
if (!fs.existsSync(p) || !/🔐 登录信息缓存/.test(fs.readFileSync(p, "utf-8"))) return; // 非标准缓存文件不动它
|
|
@@ -117,16 +198,47 @@ function syncCacheMd(auth) { // 读到权威源后自动回写明文镜像(内
|
|
|
117
198
|
txt = n;
|
|
118
199
|
};
|
|
119
200
|
rep("baseUrl", auth.baseUrl); rep("ETEAMSID", auth.eteamsid); rep("完整 Cookie 串", auth.cookie); rep("userId", auth.userId || ""); rep("tenantKey", auth.tenantKey || "");
|
|
120
|
-
rep("缓存记录时间", ts + "(e10-data
|
|
201
|
+
rep("缓存记录时间", ts + "(e10-data 自动同步,凭据来源:" + (auth.source || "") + ")");
|
|
121
202
|
if (changed) fs.writeFileSync(p, txt, "utf-8");
|
|
122
203
|
} catch {}
|
|
123
204
|
}
|
|
205
|
+
|
|
206
|
+
/** 取凭据:按优先级依次尝试各出口;命中的模式会被记住(下次优先尝试它,省一次进程调用) */
|
|
124
207
|
function loadAuth() {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
208
|
+
const { profile, file } = authFilePath();
|
|
209
|
+
const override = (process.env.E10_DATA_AUTH_MODE || "").trim();
|
|
210
|
+
const memo = override || (process.env.E10_DATA_AUTH_PROBE ? null : readAuthModeMemo());
|
|
211
|
+
const order = memo
|
|
212
|
+
? AUTH_PROVIDERS.filter(([n]) => n === memo).concat(AUTH_PROVIDERS.filter(([n]) => n !== memo))
|
|
213
|
+
: AUTH_PROVIDERS;
|
|
214
|
+
|
|
215
|
+
const diag = [];
|
|
216
|
+
for (const [name, fn] of order) {
|
|
217
|
+
let got = null;
|
|
218
|
+
lastLoginDiag = "";
|
|
219
|
+
try { got = fn(); } catch (e) { diag.push(name + ": " + ((e && e.message) || e)); }
|
|
220
|
+
if (got) {
|
|
221
|
+
if (name !== memo && !AUTH_FALLBACK_PROVIDERS.has(name)) writeAuthModeMemo(name);
|
|
222
|
+
got.profile = profile;
|
|
223
|
+
if (name === "cache-md") {
|
|
224
|
+
if (!process.env.E10_DATA_QUIET) {
|
|
225
|
+
console.error("[e10-data][warn] 凭据来源=" + got.source + ";正常应由 e10-login 提供凭据,请检查 `e10-login whoami` 是否能输出 cookies。");
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
syncCacheMd(got); // 凭据来自 e10-login → 顺便把镜像刷新到最新
|
|
229
|
+
}
|
|
230
|
+
return got;
|
|
231
|
+
}
|
|
232
|
+
if (lastLoginDiag) diag.push(name + ": " + lastLoginDiag);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
throw new Error(
|
|
236
|
+
"未取得登录凭据(解密由 e10-login 负责,本 CLI 不参与)。请依次检查:\n" +
|
|
237
|
+
" ① e10-login 是否可用:`e10-login --version`(缺失 → `npm i -g e10-login`);`e10-login whoami` 应能输出 cookies\n" +
|
|
238
|
+
" ② 是否已登录 / 登录态是否失效:`e10-login oidc` 重新登录(当前 profile: " + profile + ")\n" +
|
|
239
|
+
" ③ auth 文件:" + (fs.existsSync(file) ? "存在" : "不存在") + "(" + file + ")—— 其加解密由 e10-login 负责\n" +
|
|
240
|
+
(diag.length ? " 探测诊断:" + diag.join(" | ") + "\n" : "")
|
|
241
|
+
);
|
|
130
242
|
}
|
|
131
243
|
const auth = loadAuth();
|
|
132
244
|
const BASE = auth.baseUrl.replace(/\/+$/, "");
|
|
@@ -135,7 +247,11 @@ const USER = { id: auth.userId || "", tenantKey: auth.tenantKey || "" };
|
|
|
135
247
|
// ---------------- HTTP ----------------
|
|
136
248
|
function checkAuthFail(resp, text, j) {
|
|
137
249
|
if (resp.status === 401 || (j && String(j.code) === "-1" && /token|登录|失效/i.test(String(j.msg || "")))) {
|
|
138
|
-
|
|
250
|
+
const from = (auth && auth.source) || "未知";
|
|
251
|
+
const hint = /镜像/.test(from)
|
|
252
|
+
? "当前用的是明文镜像兜底凭据(可能已过期),请先确认 `e10-login whoami` 能正常导出 cookies,或执行 `e10-login oidc` 重新登录"
|
|
253
|
+
: "凭据由 e10-login 提供,请执行 `e10-login oidc` 重新登录";
|
|
254
|
+
throw new Error("登录态失效(" + (j.msg || resp.status) + "):凭据来源=" + from + ";" + hint);
|
|
139
255
|
}
|
|
140
256
|
}
|
|
141
257
|
async function postJson(endpoint, bodyObj, extraHeaders = {}) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "e10-data",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "泛微 E10 数据接口统一 CLI(data-assistant 专家配套):DSL 查询/数据源/文档/词库/关联字段翻译/环境参数配置中心(conf,支持 confGroup 分组)
|
|
3
|
+
"version": "0.1.10",
|
|
4
|
+
"description": "泛微 E10 数据接口统一 CLI(data-assistant 专家配套):DSL 查询/数据源/文档/词库/关联字段翻译/环境参数配置中心(conf,支持 confGroup 分组)/专家包版本管理;认证加解密全部交由 weaver-e10-login(本 CLI 不再自行解密,通过 e10-login 命令出口获取凭据)",
|
|
5
5
|
"author": "e10-dw",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|