karin-plugin-mys-core 1.0.0
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 +123 -0
- package/config/config.json +3 -0
- package/lib/app.d.ts +2 -0
- package/lib/apps/MiHoYoLogin.d.ts +5 -0
- package/lib/apps/MiHoYoLogin.js +241 -0
- package/lib/base-B1BvQ4ol.d.ts +99 -0
- package/lib/chunk-4JTLXC2G.js +519 -0
- package/lib/chunk-7QISGXVH.js +347 -0
- package/lib/chunk-JIO4GOQA.js +31 -0
- package/lib/chunk-JML6VYXN.js +47 -0
- package/lib/chunk-MLKGABMK.js +9 -0
- package/lib/database-BDHrI6Vm.d.ts +5 -0
- package/lib/define-CrfHwHnK.d.ts +163 -0
- package/lib/dir.d.ts +27 -0
- package/lib/dir.js +7 -0
- package/lib/exports/core.d.ts +228 -0
- package/lib/exports/core.js +39 -0
- package/lib/exports/database.d.ts +47 -0
- package/lib/exports/database.js +17 -0
- package/lib/exports/types.d.ts +10 -0
- package/lib/exports/types.js +11 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +8 -0
- package/lib/web.config.d.ts +5 -0
- package/lib/web.config.js +30 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Karin TypeScript 插件开发模板
|
|
2
|
+
|
|
3
|
+
## 📖 目录
|
|
4
|
+
|
|
5
|
+
- [前言](#前言)
|
|
6
|
+
- [快速开始](#快速开始)
|
|
7
|
+
- [详细开发流程](#详细开发流程)
|
|
8
|
+
- [常见问题与建议](#常见问题与建议)
|
|
9
|
+
- [贡献与反馈](#贡献与反馈)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 前言
|
|
14
|
+
|
|
15
|
+
TypeScript 插件开发流程现在更加简单,无需手动克隆模板仓库,只需一条命令即可快速开始!
|
|
16
|
+
|
|
17
|
+
> TypeScript 编写 → 编译为 JS → 发布 NPM 包 → 用户安装
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🚀 快速开始
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm create karin
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- 按提示选择“ts插件开发模板”即可自动初始化项目。
|
|
28
|
+
- 进入新建的项目目录,继续开发。
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 详细开发流程
|
|
33
|
+
|
|
34
|
+
1. **一键创建项目**
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm create karin
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- 选择“ts插件开发模板”
|
|
41
|
+
- 填写你的插件名称(会自动作为 package.json 的 name)
|
|
42
|
+
- 其余信息按提示填写
|
|
43
|
+
|
|
44
|
+
2. **安装依赖**
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pnpm install
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
3. **开发与调试**
|
|
51
|
+
|
|
52
|
+
- 启动开发命令:
|
|
53
|
+
```bash
|
|
54
|
+
pnpm dev
|
|
55
|
+
```
|
|
56
|
+
- 编写你的插件代码于 `src/` 目录。
|
|
57
|
+
- 编译输出:
|
|
58
|
+
```bash
|
|
59
|
+
pnpm build
|
|
60
|
+
```
|
|
61
|
+
- 调试编译之后的代码:
|
|
62
|
+
```bash
|
|
63
|
+
pnpm app
|
|
64
|
+
```
|
|
65
|
+
- 本地调试建议:
|
|
66
|
+
- 可用 `pnpm link --global` 进行全局软链测试。
|
|
67
|
+
- 或在 karin 根目录用 `pnpm add ../your-plugin-repo -w` 进行本地依赖测试。
|
|
68
|
+
|
|
69
|
+
4. **配置 NPM 秘钥**
|
|
70
|
+
|
|
71
|
+
> 用于自动化发布,建议开启 2FA。
|
|
72
|
+
|
|
73
|
+
1. 注册 [npmjs](https://www.npmjs.com/) 账号。
|
|
74
|
+
2. 进入 `Access Tokens`,新建 `Classic Token`,类型选 `Automation`。
|
|
75
|
+
3. 复制生成的 Token。
|
|
76
|
+
4. 打开你的 GitHub 仓库 → Settings → Secrets and variables → Actions。
|
|
77
|
+
5. 新建 `NPM_TOKEN`,粘贴 Token。
|
|
78
|
+
6. 允许 GitHub Actions 创建和批准 PR(Settings → Actions)。
|
|
79
|
+
|
|
80
|
+
5. **设置包信息**
|
|
81
|
+
|
|
82
|
+
> 包名必须唯一,建议先在 [npm](https://www.npmjs.com/) 搜索确认。
|
|
83
|
+
|
|
84
|
+
- 初始化时填写的插件名会自动作为 package.json 的 name,无需手动修改。
|
|
85
|
+
- 其他如 `author`、`description`、`homepage`、`bugs.url`、`repository` 可在 package.json 中补充完善。
|
|
86
|
+
- **CI 配置无需再手动修改 package-name,已自动同步。**
|
|
87
|
+
|
|
88
|
+
6. **自动化发布**
|
|
89
|
+
|
|
90
|
+
> 推送代码后,GitHub Actions 会自动编译并发布到 npm。
|
|
91
|
+
|
|
92
|
+
- 常规开发流程:
|
|
93
|
+
1. `git add . && git commit -m "feat: ..." && git push`
|
|
94
|
+
2. 等待 CI 自动发布
|
|
95
|
+
3. 发布成功后可在 npm 页面看到新版本
|
|
96
|
+
|
|
97
|
+
7. **安装与验证**
|
|
98
|
+
|
|
99
|
+
- 在 karin 根目录下安装你的插件:
|
|
100
|
+
```bash
|
|
101
|
+
pnpm add your-package-name -w
|
|
102
|
+
```
|
|
103
|
+
- 验证插件是否生效,可查看 karin 启动日志或相关功能。
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 💡 常见问题与建议
|
|
108
|
+
|
|
109
|
+
- **Q: 发布失败怎么办?**
|
|
110
|
+
- 检查 NPM_TOKEN 是否配置正确,权限是否足够。
|
|
111
|
+
- 包名是否唯一,未被占用。
|
|
112
|
+
- Actions 日志可定位具体报错。
|
|
113
|
+
- **Q: 如何本地调试插件?**
|
|
114
|
+
- 推荐用 `pnpm link` 或本地依赖安装。
|
|
115
|
+
- **Q: 如何贡献代码?**
|
|
116
|
+
- 欢迎 PR,建议先提 issue 讨论。
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 贡献与反馈
|
|
121
|
+
|
|
122
|
+
- 有任何建议或问题,欢迎在 [Issues](https://github.com/KarinJS/karin-plugin-template-ts/issues) 提出。
|
|
123
|
+
- 也可加入官方交流群交流经验。
|
package/lib/app.d.ts
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UserInfo,
|
|
3
|
+
common_exports,
|
|
4
|
+
fetchQRcode,
|
|
5
|
+
getCookieAccountInfoByGameToken,
|
|
6
|
+
getTokenByGameToken,
|
|
7
|
+
getUserFullInfo,
|
|
8
|
+
queryQRcode
|
|
9
|
+
} from "../chunk-4JTLXC2G.js";
|
|
10
|
+
import "../chunk-7QISGXVH.js";
|
|
11
|
+
import "../chunk-JML6VYXN.js";
|
|
12
|
+
import "../chunk-JIO4GOQA.js";
|
|
13
|
+
import "../chunk-MLKGABMK.js";
|
|
14
|
+
|
|
15
|
+
// src/apps/MiHoYoLogin.ts
|
|
16
|
+
import karin, { common as karinCommon, logger, segment } from "node-karin";
|
|
17
|
+
import lodash from "node-karin/lodash";
|
|
18
|
+
import QR from "qrcode";
|
|
19
|
+
var QRCodes = /* @__PURE__ */ new Map();
|
|
20
|
+
var MiHoYoLoginQRCode = karin.command(
|
|
21
|
+
/^#?(扫码|二维码|辅助)(登录|绑定|登陆)$/i,
|
|
22
|
+
async (e) => {
|
|
23
|
+
const qrcode = QRCodes.get(e.userId);
|
|
24
|
+
if (qrcode) {
|
|
25
|
+
if (qrcode === true) return true;
|
|
26
|
+
e.reply(["\u8BF7\u4F7F\u7528\u7C73\u6E38\u793E\u626B\u7801\u767B\u5F55", qrcode], {
|
|
27
|
+
at: true,
|
|
28
|
+
recallMsg: 60
|
|
29
|
+
});
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
QRCodes.set(e.userId, true);
|
|
33
|
+
const device = common_exports.randomString(64, "All");
|
|
34
|
+
const QRcode = await fetchQRcode().request({ device });
|
|
35
|
+
if (!QRcode?.data?.url) {
|
|
36
|
+
QRCodes.delete(e.userId);
|
|
37
|
+
e.reply("\u83B7\u53D6\u4E8C\u7EF4\u7801\u5931\u8D25\u3001\u8BF7\u7A0D\u540E\u518D\u8BD5", { at: true });
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
const image = (await QR.toDataURL(QRcode.data.url)).replace("data:image/png;base64,", "base64://");
|
|
41
|
+
if (!image) {
|
|
42
|
+
QRCodes.delete(e.userId);
|
|
43
|
+
e.reply("\u751F\u6210\u4E8C\u7EF4\u7801\u5931\u8D25\u3001\u8BF7\u7A0D\u540E\u518D\u8BD5", { at: true });
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
QRCodes.set(e.userId, image);
|
|
47
|
+
e.reply(["\u8BF7\u4F7F\u7528\u7C73\u6E38\u793E\u626B\u7801\u767B\u5F55", segment.image(image)], { at: true, recallMsg: 60 });
|
|
48
|
+
let data, Scanned;
|
|
49
|
+
const ticket = QRcode.data.url.split("ticket=")[1];
|
|
50
|
+
for (let n = 1; n < 60; n++) {
|
|
51
|
+
await karinCommon.sleep(5e3);
|
|
52
|
+
try {
|
|
53
|
+
const res3 = await queryQRcode().request({ device, ticket });
|
|
54
|
+
if (!res3) continue;
|
|
55
|
+
if (res3.retcode === 3503) {
|
|
56
|
+
e.reply(res3.message, { at: true, recallMsg: 60 });
|
|
57
|
+
QRCodes.delete(e.userId);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
if (res3.retcode !== 0) {
|
|
61
|
+
e.reply("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55", { at: true, recallMsg: 60 });
|
|
62
|
+
QRCodes.delete(e.userId);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (res3.data.stat === "Scanned") {
|
|
66
|
+
if (Scanned) {
|
|
67
|
+
e.reply("\u4E8C\u7EF4\u7801\u5DF2\u626B\u63CF\uFF0C\u8BF7\u786E\u8BA4\u767B\u5F55", { at: true, recallMsg: 60 });
|
|
68
|
+
} else {
|
|
69
|
+
Scanned = true;
|
|
70
|
+
QRCodes.set(e.userId, true);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (res3.data.stat === "Confirmed") {
|
|
74
|
+
data = JSON.parse(res3.data.payload.raw);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {
|
|
78
|
+
logger.error(err);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (!data?.uid && !data?.token) {
|
|
83
|
+
e.reply("\u7C73\u6E38\u793E\u767B\u5F55\u5931\u8D25", { at: true });
|
|
84
|
+
QRCodes.delete(e.userId);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
const res = await getTokenByGameToken().request({
|
|
88
|
+
account_id: parseInt(data.uid),
|
|
89
|
+
game_token: data.token
|
|
90
|
+
});
|
|
91
|
+
if (!res) {
|
|
92
|
+
e.reply("\u83B7\u53D6Token\u5931\u8D25", { at: true });
|
|
93
|
+
QRCodes.delete(e.userId);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
const stoken = `stoken=${res.data.token.token};stuid=${res.data.user_info.aid};mid=${res.data.user_info.mid};`;
|
|
97
|
+
const res2 = await getCookieAccountInfoByGameToken().request({
|
|
98
|
+
account_id: data.uid,
|
|
99
|
+
game_token: data.token
|
|
100
|
+
});
|
|
101
|
+
const cookie = `ltuid=${res.data.user_info.aid};ltoken=${res.data.token.token};cookie_token=${res2.data.cookie_token};account_id=${res.data.user_info.aid}`;
|
|
102
|
+
const message = await bingStoken(e.userId, stoken, { cookie, Serv: "mihoyo" /* cn */ });
|
|
103
|
+
e.reply(message, { at: true });
|
|
104
|
+
QRCodes.delete(e.userId);
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
var bingCookie = async (userId, cookie, Serv = "mihoyo" /* cn */) => {
|
|
109
|
+
const cookieObj = common_exports.StrToObj(cookie.replace(/[#'" ]/g, ""), ";");
|
|
110
|
+
if (!cookieObj.cookie_token && !cookieObj.cookie_token_v2) {
|
|
111
|
+
return "\u53D1\u9001Cookie\u4E0D\u5B8C\u6574\uFF0C\u5EFA\u8BAE\u4F7F\u7528#\u626B\u7801\u767B\u5F55";
|
|
112
|
+
}
|
|
113
|
+
const ltuid = cookieObj.ltuid || cookieObj.login_uid || cookieObj.ltuid_v2 || cookieObj.account_id_v2 || cookieObj.ltmid_v2;
|
|
114
|
+
if (!ltuid) {
|
|
115
|
+
return "\u53D1\u9001Cookie\u4E0D\u5B8C\u6574\uFF0C\u5EFA\u8BAE\u4F7F\u7528#\u626B\u7801\u767B\u5F55";
|
|
116
|
+
}
|
|
117
|
+
let cookieParams = {};
|
|
118
|
+
let flagV2 = false;
|
|
119
|
+
if (cookieObj.cookie_token_v2 && (cookieObj.account_mid_v2 || cookieObj.ltmid_v2)) {
|
|
120
|
+
flagV2 = true;
|
|
121
|
+
cookieParams = {
|
|
122
|
+
ltuid,
|
|
123
|
+
account_mid_v2: cookieObj.account_mid_v2,
|
|
124
|
+
cookie_token_v2: cookieObj.cookie_token_v2,
|
|
125
|
+
ltoken_v2: cookieObj.ltoken_v2,
|
|
126
|
+
ltmid_v2: cookieObj.ltmid_v2
|
|
127
|
+
};
|
|
128
|
+
} else {
|
|
129
|
+
cookieParams = {
|
|
130
|
+
ltuid,
|
|
131
|
+
account_id: ltuid,
|
|
132
|
+
ltoken: cookieObj.ltoken,
|
|
133
|
+
cookie_token: cookieObj.cookie_token || cookieObj.cookie_token_v2
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (cookieObj.mi18nLang) {
|
|
137
|
+
cookieParams.mi18nLang = cookieObj.mi18nLang;
|
|
138
|
+
}
|
|
139
|
+
const cookieStr = common_exports.ObjToStr(cookieParams, ";");
|
|
140
|
+
let uidList = {
|
|
141
|
+
Serv,
|
|
142
|
+
uids: { data: {}, names: {} },
|
|
143
|
+
message: "\u5237\u65B0UID\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\uFF01"
|
|
144
|
+
};
|
|
145
|
+
for (const serv of Serv ? [Serv] : ["mihoyo" /* cn */, "hoyolab" /* os */]) {
|
|
146
|
+
uidList = await UserInfo.refreshUid({
|
|
147
|
+
type: serv,
|
|
148
|
+
ltuid,
|
|
149
|
+
cookie: cookieStr
|
|
150
|
+
});
|
|
151
|
+
if (!uidList.message) break;
|
|
152
|
+
}
|
|
153
|
+
if (uidList.message) {
|
|
154
|
+
return uidList.message;
|
|
155
|
+
}
|
|
156
|
+
if (flagV2 && isNaN(Number(cookieParams.ltuid))) {
|
|
157
|
+
const userFullInfo = await getUserFullInfo({
|
|
158
|
+
type: uidList.Serv,
|
|
159
|
+
ltuid,
|
|
160
|
+
cookie: cookieStr
|
|
161
|
+
}).request({});
|
|
162
|
+
if (userFullInfo?.data?.user_info) {
|
|
163
|
+
if (userFullInfo.data.user_info.uid) {
|
|
164
|
+
cookieParams.ltuid = cookieParams.account_id = userFullInfo.data.user_info.uid;
|
|
165
|
+
}
|
|
166
|
+
} else {
|
|
167
|
+
logger.mark(`\u7ED1\u5B9ACookie\u9519\u8BEF2\uFF1A${userFullInfo?.message || "Cookie\u9519\u8BEF"}`);
|
|
168
|
+
return `\u7ED1\u5B9ACookie\u5931\u8D25\uFF1A${userFullInfo?.message || "Cookie\u9519\u8BEF"}`;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const userInfo = await UserInfo.create(userId);
|
|
172
|
+
await userInfo.saveUserInfo({
|
|
173
|
+
userId,
|
|
174
|
+
...uidList.uids.data,
|
|
175
|
+
ltuids: lodash.uniq([...userInfo.ltuids, cookieParams.ltuid]),
|
|
176
|
+
stuids: userInfo.stuids,
|
|
177
|
+
deviceList: userInfo.deviceList
|
|
178
|
+
});
|
|
179
|
+
const ltuidInfo = userInfo.getLtuidInfo(cookieParams.ltuid);
|
|
180
|
+
await userInfo.saveMysAccountInfo({
|
|
181
|
+
ltuid: cookieParams.ltuid,
|
|
182
|
+
type: uidList.Serv,
|
|
183
|
+
cookie: common_exports.ObjToStr(cookieParams, ";"),
|
|
184
|
+
stoken: ltuidInfo?.stoken || "",
|
|
185
|
+
deviceId: ltuidInfo?.deviceId || ""
|
|
186
|
+
});
|
|
187
|
+
logger.mark(`[${userId}] \u4FDD\u5B58Cookie\u6210\u529F [ltuid:${cookieParams.ltuid}]`);
|
|
188
|
+
const sendMsg = [];
|
|
189
|
+
lodash.forEach(uidList.uids.data, (uids, game) => {
|
|
190
|
+
sendMsg.push(`\u3010${uidList.uids.names[game]}\u3011\uFF1A${uids.join("\u3001")}`);
|
|
191
|
+
});
|
|
192
|
+
return `Cookie\u7ED1\u5B9A\u6210\u529F\uFF01
|
|
193
|
+
${sendMsg.join("\n")}`;
|
|
194
|
+
};
|
|
195
|
+
var bingStoken = async (userId, stoken, option) => {
|
|
196
|
+
const { cookie = "", Serv = "mihoyo" /* cn */ } = option || {};
|
|
197
|
+
const stokenObj = common_exports.StrToObj(stoken.replace(/[#'" ]/g, ""), ";");
|
|
198
|
+
if (!stokenObj.stoken || !(stokenObj.stuid || stokenObj.ltuid) || !stokenObj.mid) {
|
|
199
|
+
return "\u53D1\u9001Stoken\u4E0D\u5B8C\u6574\uFF0C\u5EFA\u8BAE\u4F7F\u7528#\u626B\u7801\u767B\u5F55";
|
|
200
|
+
}
|
|
201
|
+
const stokenParams = {
|
|
202
|
+
stuid: stokenObj.stuid || stokenObj.ltuid,
|
|
203
|
+
stoken: stokenObj.stoken,
|
|
204
|
+
mid: stokenObj.mid
|
|
205
|
+
};
|
|
206
|
+
let updata = { Serv, cookie, message: "" };
|
|
207
|
+
if (!updata.cookie) {
|
|
208
|
+
for (const serv of Serv ? [Serv] : ["mihoyo" /* cn */, "hoyolab" /* os */]) {
|
|
209
|
+
updata = await UserInfo.refreshCookie(stokenParams, serv);
|
|
210
|
+
if (updata.cookie) break;
|
|
211
|
+
}
|
|
212
|
+
if (updata.message) {
|
|
213
|
+
return updata.message;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const Stoken = common_exports.ObjToStr(stokenParams, ";");
|
|
217
|
+
const userInfo = await UserInfo.create(userId);
|
|
218
|
+
await userInfo.saveUserInfo({
|
|
219
|
+
userId,
|
|
220
|
+
ltuids: userInfo.ltuids,
|
|
221
|
+
stuids: lodash.uniq([...userInfo.stuids, stokenParams.stuid]),
|
|
222
|
+
deviceList: userInfo.deviceList
|
|
223
|
+
});
|
|
224
|
+
const ltuidInfo = userInfo.getLtuidInfo(stokenParams.stuid);
|
|
225
|
+
await userInfo.saveMysAccountInfo({
|
|
226
|
+
ltuid: stokenParams.stuid,
|
|
227
|
+
type: updata.Serv,
|
|
228
|
+
cookie: ltuidInfo?.cookie || "",
|
|
229
|
+
stoken: Stoken,
|
|
230
|
+
deviceId: ltuidInfo?.deviceId || ""
|
|
231
|
+
});
|
|
232
|
+
logger.mark(`[${userId}] \u4FDD\u5B58Stoken\u6210\u529F [stuid: ${stokenParams.stuid}]`);
|
|
233
|
+
const sendMsg = [];
|
|
234
|
+
sendMsg.push(`\u7C73\u6E38\u793EID\uFF1A${stokenParams.stuid}
|
|
235
|
+
Stoken\u7ED1\u5B9A\u6210\u529F\uFF01`);
|
|
236
|
+
sendMsg.push(await bingCookie(userId, updata.cookie, updata.Serv));
|
|
237
|
+
return sendMsg.join("\n");
|
|
238
|
+
};
|
|
239
|
+
export {
|
|
240
|
+
MiHoYoLoginQRCode
|
|
241
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ModelStatic, Model, ModelAttributeColumnOptions, DataTypes } from 'sequelize';
|
|
2
|
+
|
|
3
|
+
interface MysAccountInfoType {
|
|
4
|
+
ltuid: string;
|
|
5
|
+
type: MysAccountType;
|
|
6
|
+
cookie: string;
|
|
7
|
+
stoken: string;
|
|
8
|
+
/** 绑定的设备ID */
|
|
9
|
+
deviceId: string;
|
|
10
|
+
}
|
|
11
|
+
declare const enum MysAccountType {
|
|
12
|
+
cn = "mihoyo",
|
|
13
|
+
os = "hoyolab"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface BaseUserInfoType {
|
|
17
|
+
userId: string;
|
|
18
|
+
ltuids: string[];
|
|
19
|
+
stuids: string[];
|
|
20
|
+
deviceList: string[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare const enum Dialect {
|
|
24
|
+
Sqlite = "sqlite",
|
|
25
|
+
MySQL = "mysql",
|
|
26
|
+
MariaDB = "mariadb",
|
|
27
|
+
PostgreSQL = "postgres",
|
|
28
|
+
MSSQL = "mssql",
|
|
29
|
+
Oracle = "oracle",
|
|
30
|
+
DB2 = "db2",
|
|
31
|
+
Snowflake = "snowflake"
|
|
32
|
+
}
|
|
33
|
+
declare enum DatabaseType {
|
|
34
|
+
File = "file",
|
|
35
|
+
Dir = "dir",
|
|
36
|
+
Db = "db"
|
|
37
|
+
}
|
|
38
|
+
type ModelAttributes<M extends Model = Model, TAttributes = any> = {
|
|
39
|
+
[name in keyof TAttributes]: ModelAttributeColumnOptions<M>;
|
|
40
|
+
};
|
|
41
|
+
type DatabaseReturn<T> = T & {
|
|
42
|
+
_save: (data: T) => Promise<void>;
|
|
43
|
+
};
|
|
44
|
+
type DatabaseClassInstance<T extends Record<string, any>> = {
|
|
45
|
+
/** 数据库标识 */
|
|
46
|
+
dialect: Dialect;
|
|
47
|
+
model: ModelStatic<Model>;
|
|
48
|
+
databasePath: string;
|
|
49
|
+
databaseType: DatabaseType;
|
|
50
|
+
/** 表名 */
|
|
51
|
+
modelName: string;
|
|
52
|
+
/** 表定义 */
|
|
53
|
+
modelSchema: ModelAttributes<Model>;
|
|
54
|
+
/** 检查数据库是否可用 */
|
|
55
|
+
check(): Promise<boolean>;
|
|
56
|
+
/**
|
|
57
|
+
* 初始化表
|
|
58
|
+
* @param DataDir 插件数据目录
|
|
59
|
+
* @param modelName 表名
|
|
60
|
+
* @param modelSchema 表定义
|
|
61
|
+
* @param type 数据库类型
|
|
62
|
+
*/
|
|
63
|
+
init(DataDir: string, modelName: string, modelSchema: ModelAttributes<Model>, type: DatabaseType): Promise<DatabaseClassInstance<T>>;
|
|
64
|
+
/** 将表定义转换为 JSON 对象 */
|
|
65
|
+
schemaToJSON(pk: string): T;
|
|
66
|
+
/** 获取用户数据文件路径 */
|
|
67
|
+
userPath(pk: string): string;
|
|
68
|
+
/** 根据主键读取用户数据文件 */
|
|
69
|
+
readSync(path: string, pk: string): DatabaseReturn<T>;
|
|
70
|
+
/** 根据主键读取用户数据目录 */
|
|
71
|
+
readDirSync(pk: string): DatabaseReturn<T>;
|
|
72
|
+
/** 写入用户数据文件 */
|
|
73
|
+
writeFileSync(pk: string, data: Record<string, any>): boolean;
|
|
74
|
+
/** 写入用户数据目录 */
|
|
75
|
+
writeDirSync(pk: string, data: Record<string, any>): boolean;
|
|
76
|
+
/** 保存用户数据到文件 */
|
|
77
|
+
saveFile(pk: string): (data: T) => Promise<void>;
|
|
78
|
+
/** 保存用户数据到目录 */
|
|
79
|
+
saveDir(pk: string): (data: T) => Promise<void>;
|
|
80
|
+
/** 保存用户数据到 SQL 数据库 */
|
|
81
|
+
saveSql(model: Model<any, any>, pk: string): (data: T) => Promise<void>;
|
|
82
|
+
/** 根据主键查找或创建用户数据 */
|
|
83
|
+
findByPk(pk: string, create: true): Promise<DatabaseReturn<T>>;
|
|
84
|
+
/** 根据主键查找用户数据 */
|
|
85
|
+
findByPk(pk: string, create: boolean): Promise<DatabaseReturn<T> | undefined>;
|
|
86
|
+
/** 根据主键数组查找用户数据 */
|
|
87
|
+
findAllByPks(pks: string[]): Promise<DatabaseReturn<T>[]>;
|
|
88
|
+
/** 删除用户数据 */
|
|
89
|
+
destroy(pk: string): Promise<boolean>;
|
|
90
|
+
};
|
|
91
|
+
interface DatabaseClassStatic {
|
|
92
|
+
Column(type: keyof typeof DataTypes, def: any, option?: Partial<ModelAttributeColumnOptions<Model>>): ModelAttributeColumnOptions<Model>;
|
|
93
|
+
ArrayColumn(key: string, fn?: (data: string[]) => string[]): ModelAttributeColumnOptions<Model>;
|
|
94
|
+
JsonColumn(key: string, def: {
|
|
95
|
+
[key in string]: any;
|
|
96
|
+
}): ModelAttributeColumnOptions<Model>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { type BaseUserInfoType as B, Dialect as D, type ModelAttributes as M, DatabaseType as a, type DatabaseReturn as b, type DatabaseClassInstance as c, type DatabaseClassStatic as d, type MysAccountInfoType as e, MysAccountType as f };
|