@karinjs/plugin-basic 1.0.2 → 1.0.4
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/config/config.json +6 -0
- package/dist/apps/exit.d.ts +5 -0
- package/dist/apps/exit.js +10 -0
- package/dist/apps/restart.d.ts +5 -0
- package/dist/apps/restart.js +22 -0
- package/dist/apps/status.d.ts +5 -0
- package/dist/apps/status.js +78 -0
- package/dist/apps/update.d.ts +14 -0
- package/dist/apps/update.js +217 -0
- package/dist/chunk-7VNKIAO2.js +86 -0
- package/dist/chunk-XKQYARLA.js +46 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -0
- package/dist/web.config.d.ts +34 -0
- package/dist/web.config.js +65 -0
- package/package.json +12 -20
- package/config/comment/config.json +0 -6
- package/config/config/config.yaml +0 -11
- package/lib/apps/exit.d.ts +0 -1
- package/lib/apps/exit.js +0 -6
- package/lib/apps/restart.d.ts +0 -1
- package/lib/apps/restart.js +0 -16
- package/lib/apps/status.d.ts +0 -1
- package/lib/apps/status.js +0 -70
- package/lib/apps/update.d.ts +0 -10
- package/lib/apps/update.js +0 -214
- package/lib/cli/pr.d.ts +0 -2
- package/lib/cli/pr.js +0 -73
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -4
- package/lib/types/config.d.ts +0 -11
- package/lib/types/config.js +0 -1
- package/lib/utils/config.d.ts +0 -9
- package/lib/utils/config.js +0 -38
- package/lib/utils/dir.d.ts +0 -5
- package/lib/utils/dir.js +0 -9
- package/lib/utils/index.d.ts +0 -3
- package/lib/utils/index.js +0 -3
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// src/apps/exit.ts
|
|
2
|
+
import { common, karin } from "node-karin";
|
|
3
|
+
var exit = karin.command(/^#关机$/, async (e) => {
|
|
4
|
+
await e.reply(`\u5F00\u59CB\u5173\u673A \u672C\u6B21\u8FD0\u884C\u65F6\u95F4: ${common.uptime()}`, { at: true });
|
|
5
|
+
process.emit("SIGINT");
|
|
6
|
+
return true;
|
|
7
|
+
}, { name: "\u5173\u673A", perm: "admin" });
|
|
8
|
+
export {
|
|
9
|
+
exit
|
|
10
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
config
|
|
3
|
+
} from "../chunk-XKQYARLA.js";
|
|
4
|
+
import "../chunk-7VNKIAO2.js";
|
|
5
|
+
|
|
6
|
+
// src/apps/restart.ts
|
|
7
|
+
import { common, karin, logger, restart } from "node-karin";
|
|
8
|
+
var restarts = karin.command(/^#重启$/, async (e) => {
|
|
9
|
+
try {
|
|
10
|
+
await e.reply(`\u5F00\u59CB\u91CD\u542F \u672C\u6B21\u8FD0\u884C\u65F6\u95F4: ${common.uptime()}`, { at: true });
|
|
11
|
+
const { status, data } = await restart(e.selfId, e.contact, e.messageId, config().restartMode);
|
|
12
|
+
if (status === "failed") throw data;
|
|
13
|
+
return true;
|
|
14
|
+
} catch (error) {
|
|
15
|
+
logger.error(error);
|
|
16
|
+
await e.reply(`\u91CD\u542F\u5931\u8D25: ${error.message || "\u672A\u77E5\u539F\u56E0"}`, { at: true });
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}, { name: "\u91CD\u542F", perm: "admin" });
|
|
20
|
+
export {
|
|
21
|
+
restarts
|
|
22
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
config
|
|
3
|
+
} from "../chunk-XKQYARLA.js";
|
|
4
|
+
import "../chunk-7VNKIAO2.js";
|
|
5
|
+
|
|
6
|
+
// src/apps/status.ts
|
|
7
|
+
import moment from "node-karin/moment";
|
|
8
|
+
import { EVENT_COUNT, hooks, karin, RECV_MSG, redis, SEND_MSG } from "node-karin";
|
|
9
|
+
var status = karin.command(/^#状态$/, async (e) => {
|
|
10
|
+
const today = moment().format("YYYY-MM-DD");
|
|
11
|
+
const month = moment().format("YYYY-MM");
|
|
12
|
+
const [
|
|
13
|
+
send,
|
|
14
|
+
recv,
|
|
15
|
+
event,
|
|
16
|
+
sendMonth,
|
|
17
|
+
recvMonth,
|
|
18
|
+
eventMonth
|
|
19
|
+
] = await Promise.all([
|
|
20
|
+
getStat(`${SEND_MSG}:${today}*`),
|
|
21
|
+
getStat(`${RECV_MSG}:${today}*`),
|
|
22
|
+
getStat(`${EVENT_COUNT}:${today}*`),
|
|
23
|
+
getStat(`${SEND_MSG}:${month}*`),
|
|
24
|
+
getStat(`${RECV_MSG}:${month}*`),
|
|
25
|
+
getStat(`${EVENT_COUNT}:${month}*`)
|
|
26
|
+
]);
|
|
27
|
+
await e.reply([
|
|
28
|
+
"------\u673A\u5668\u4EBA\u72B6\u6001------",
|
|
29
|
+
`\u5F53\u524D\u7248\u672C\uFF1Av${process.env.KARIN_VERSION}`,
|
|
30
|
+
`\u5185\u5B58\u5360\u7528\uFF1A${MB()}MB`,
|
|
31
|
+
`\u8FD0\u884C\u65F6\u95F4\uFF1A${uptime()}`,
|
|
32
|
+
"------\u4ECA\u65E5\u7EDF\u8BA1------",
|
|
33
|
+
`\u53D1\u9001\u6D88\u606F\uFF1A${send}\u6B21`,
|
|
34
|
+
`\u63D2\u4EF6\u89E6\u53D1\uFF1A${event}\u6B21`,
|
|
35
|
+
`\u6536\u5230\u6D88\u606F\uFF1A${recv}\u6B21`,
|
|
36
|
+
"------\u672C\u6708\u7EDF\u8BA1------",
|
|
37
|
+
`\u53D1\u9001\u6D88\u606F\uFF1A${sendMonth}\u6B21`,
|
|
38
|
+
`\u63D2\u4EF6\u89E6\u53D1\uFF1A${eventMonth}\u6B21`,
|
|
39
|
+
`\u6536\u5230\u6D88\u606F\uFF1A${recvMonth}\u6B21`
|
|
40
|
+
].join("\n"));
|
|
41
|
+
return true;
|
|
42
|
+
}, { name: "\u72B6\u6001\u7EDF\u8BA1" });
|
|
43
|
+
var createKey = (contact) => {
|
|
44
|
+
const { scene, peer, subPeer } = contact;
|
|
45
|
+
return `${moment().format("YYYY-MM-DD")}:${scene}:${peer}${subPeer ? `:${subPeer}` : ""}`;
|
|
46
|
+
};
|
|
47
|
+
var getStat = async (pattern) => {
|
|
48
|
+
const keys = await redis.keys(pattern);
|
|
49
|
+
const values = await Promise.all(keys.map((key) => redis.get(key).then(Number)));
|
|
50
|
+
return values.reduce((total, value) => total + (value || 0), 0);
|
|
51
|
+
};
|
|
52
|
+
var MB = () => (process.memoryUsage().rss / 1024 / 1024).toFixed(2);
|
|
53
|
+
var uptime = () => {
|
|
54
|
+
const uptime2 = process.uptime();
|
|
55
|
+
const hour = Math.floor(uptime2 / 3600);
|
|
56
|
+
const minute = Math.floor(uptime2 % 3600 / 60);
|
|
57
|
+
return `${hour}\u5C0F\u65F6${minute}\u5206\u949F`;
|
|
58
|
+
};
|
|
59
|
+
(() => {
|
|
60
|
+
if (!config().status) return;
|
|
61
|
+
hooks.message((event, next) => {
|
|
62
|
+
try {
|
|
63
|
+
redis.incr(`${RECV_MSG}:${createKey(event.contact)}`);
|
|
64
|
+
} finally {
|
|
65
|
+
next();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
hooks.sendMsg.message((contact, _, __, next) => {
|
|
69
|
+
try {
|
|
70
|
+
redis.incr(`${SEND_MSG}:${createKey(contact)}`);
|
|
71
|
+
} finally {
|
|
72
|
+
next();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
})();
|
|
76
|
+
export {
|
|
77
|
+
status
|
|
78
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as node_karin from 'node-karin';
|
|
2
|
+
|
|
3
|
+
/** 插件列表 */
|
|
4
|
+
declare const plugins: node_karin.Command<keyof node_karin.MessageEventMap>;
|
|
5
|
+
/** 检查更新 */
|
|
6
|
+
declare const check: node_karin.Command<keyof node_karin.MessageEventMap>;
|
|
7
|
+
/** 更新插件 */
|
|
8
|
+
declare const update: node_karin.Command<keyof node_karin.MessageEventMap>;
|
|
9
|
+
/** 更新日志 */
|
|
10
|
+
declare const log: node_karin.Command<keyof node_karin.MessageEventMap>;
|
|
11
|
+
/** 全部更新 */
|
|
12
|
+
declare const updateAll: node_karin.Command<keyof node_karin.MessageEventMap>;
|
|
13
|
+
|
|
14
|
+
export { check, log, plugins, update, updateAll };
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
// src/apps/update.ts
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { changelog, checkGitPluginUpdate, checkPkgUpdate, getCommit, getPlugins, getPkgVersion, karin, updateAllGitPlugin, updateAllPkg, updateGitPlugin, updatePkg } from "node-karin";
|
|
5
|
+
var cache = [];
|
|
6
|
+
var getAll = async () => {
|
|
7
|
+
if (cache.length) return cache;
|
|
8
|
+
const git = await getPlugins("git", false);
|
|
9
|
+
const npm = await getPlugins("npm", false);
|
|
10
|
+
const list = [
|
|
11
|
+
"npm:node-karin",
|
|
12
|
+
...git.map((name) => `git:${name}`),
|
|
13
|
+
...npm.map((name) => `npm:${name}`)
|
|
14
|
+
];
|
|
15
|
+
cache.push(...list);
|
|
16
|
+
setTimeout(() => {
|
|
17
|
+
cache.length = 0;
|
|
18
|
+
}, 6e4);
|
|
19
|
+
return list;
|
|
20
|
+
};
|
|
21
|
+
var plugins = karin.command(/^#插件列表$/, async (e) => {
|
|
22
|
+
const list = await getAll();
|
|
23
|
+
list.forEach((item, index) => {
|
|
24
|
+
item += `${index + 1}. ${item}`;
|
|
25
|
+
});
|
|
26
|
+
await e.reply([
|
|
27
|
+
"\n\u63D2\u4EF6\u5217\u8868\uFF1A",
|
|
28
|
+
"\u66F4\u65B0\uFF1A#\u66F4\u65B0\u63D2\u4EF6 \u5E8F\u53F7\u6216\u540D\u79F0",
|
|
29
|
+
"\u68C0\u67E5\u66F4\u65B0\uFF1A#\u68C0\u67E5\u66F4\u65B0 \u5E8F\u53F7\u6216\u540D\u79F0",
|
|
30
|
+
"\u65E5\u5FD7\uFF1A#\u66F4\u65B0\u65E5\u5FD7 \u6761\u6570 \u5E8F\u53F7\u6216\u540D\u79F0",
|
|
31
|
+
...list
|
|
32
|
+
].join("\n"), { at: true });
|
|
33
|
+
return true;
|
|
34
|
+
}, { name: "\u63D2\u4EF6\u5217\u8868", perm: "admin" });
|
|
35
|
+
var check = karin.command(/^#检查更新/, async (e) => {
|
|
36
|
+
let name = e.msg.replace(/^#检查更新/, "").trim();
|
|
37
|
+
const index = Number(name);
|
|
38
|
+
if (index && typeof index === "number") {
|
|
39
|
+
const list = await getAll();
|
|
40
|
+
name = list[index - 1];
|
|
41
|
+
}
|
|
42
|
+
if (!name) {
|
|
43
|
+
await e.reply("\n\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u63D2\u4EF6\u540D\u79F0\u6216\u5E8F\u53F7~", { at: true });
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
const tips = "\u5F53\u524D\u7248\u672C\u5DF2\u662F\u6700\u65B0\u7248\u672C";
|
|
47
|
+
if (name.includes("git:")) {
|
|
48
|
+
name = name.replace("git:", "");
|
|
49
|
+
const file = path.join(process.cwd(), "plugins", name.replace("git:", ""));
|
|
50
|
+
const result = await checkGitPluginUpdate(file);
|
|
51
|
+
if (result.status === "error") {
|
|
52
|
+
const { data } = result;
|
|
53
|
+
const msg = typeof data === "string" ? data : `\u83B7\u53D6\u66F4\u65B0\u4FE1\u606F\u5931\u8D25: ${data.message || "\u672A\u77E5\u9519\u8BEF"}`;
|
|
54
|
+
await e.reply(msg, { at: true });
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
if (result.status === "no") {
|
|
58
|
+
await e.reply(`
|
|
59
|
+
${tips}${result.data.replace(tips + "\n", "")}`, { at: true });
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
await e.reply([
|
|
63
|
+
"\n\u5B58\u5728\u65B0\u7248\u672C:",
|
|
64
|
+
`\u540D\u79F0\uFF1A${name}`,
|
|
65
|
+
`\u843D\u540E: ${result.count}\u6B21\u63D0\u4EA4`,
|
|
66
|
+
`\u66F4\u65B0\u65E5\u5FD7\uFF1A
|
|
67
|
+
${result.data}`
|
|
68
|
+
].join("\n"), { at: true });
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
if (name.includes("npm:")) {
|
|
72
|
+
name = name.replace("npm:", "");
|
|
73
|
+
const result = await checkPkgUpdate(name);
|
|
74
|
+
if (result.status === "no") {
|
|
75
|
+
await e.reply(`
|
|
76
|
+
\u5F53\u524D\u7248\u672C: ${result.local}
|
|
77
|
+
${tips}`, { at: true });
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
if (result.status === "error") {
|
|
81
|
+
const { error } = result;
|
|
82
|
+
const msg = `\u83B7\u53D6\u66F4\u65B0\u4FE1\u606F\u5931\u8D25: ${error.message || "\u672A\u77E5\u9519\u8BEF"}`;
|
|
83
|
+
await e.reply(msg, { at: true });
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
await e.reply([
|
|
87
|
+
"\n\u5B58\u5728\u65B0\u7248\u672C:",
|
|
88
|
+
`\u540D\u79F0\uFF1A${name}`,
|
|
89
|
+
`\u5F53\u524D\u7248\u672C: ${result.local}`,
|
|
90
|
+
`\u6700\u65B0\u7248\u672C: ${result.remote}`
|
|
91
|
+
].join("\n"), { at: true });
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
await e.reply("\n\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u63D2\u4EF6\u540D\u79F0\u6216\u5E8F\u53F7~", { at: true });
|
|
95
|
+
return true;
|
|
96
|
+
}, { name: "\u68C0\u67E5\u66F4\u65B0", perm: "admin" });
|
|
97
|
+
var update = karin.command(/^#(强制)?更新(插件)?(?!列表|日志)/, async (e) => {
|
|
98
|
+
let name = e.msg.replace(/^#(强制)?更新(插件)?(?!列表|日志)/, "").trim();
|
|
99
|
+
const index = Number(name);
|
|
100
|
+
if (index && typeof index === "number") {
|
|
101
|
+
const list = await getAll();
|
|
102
|
+
name = list[index - 1];
|
|
103
|
+
}
|
|
104
|
+
if (!name) {
|
|
105
|
+
await e.reply("\n\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u63D2\u4EF6\u540D\u79F0\u6216\u5E8F\u53F7~", { at: true });
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
if (name.includes("git:")) {
|
|
109
|
+
name = name.replace("git:", "");
|
|
110
|
+
const file = path.join(process.cwd(), "plugins", name.replace("git:", ""));
|
|
111
|
+
let cmd = "git pull";
|
|
112
|
+
if (e.msg.includes("\u5F3A\u5236")) cmd = "git reset --hard && git pull --allow-unrelated-histories";
|
|
113
|
+
const result = await updateGitPlugin(file, cmd, 120);
|
|
114
|
+
if (result.status === "failed") {
|
|
115
|
+
const { data } = result;
|
|
116
|
+
const msg = typeof data === "string" ? data : `\u83B7\u53D6\u66F4\u65B0\u4FE1\u606F\u5931\u8D25: ${data.message || "\u672A\u77E5\u9519\u8BEF"}`;
|
|
117
|
+
await e.reply(msg, { at: true });
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
await e.reply(`
|
|
121
|
+
${result.data}`, { at: true });
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
if (name.includes("npm:")) {
|
|
125
|
+
name = name.replace("npm:", "");
|
|
126
|
+
const result = await updatePkg(name);
|
|
127
|
+
if (result.status === "failed") {
|
|
128
|
+
const { data } = result;
|
|
129
|
+
const msg = typeof data === "string" ? data : `\u83B7\u53D6\u66F4\u65B0\u4FE1\u606F\u5931\u8D25: ${data.message || "\u672A\u77E5\u9519\u8BEF"}`;
|
|
130
|
+
await e.reply(`
|
|
131
|
+
${msg}`, { at: true });
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
const log2 = parseLog(name, result.local, result.remote);
|
|
135
|
+
await e.reply(`
|
|
136
|
+
\u66F4\u65B0\u6210\u529F
|
|
137
|
+
\u5F53\u524D\u7248\u672C: ${result.remote}
|
|
138
|
+
\u66F4\u65B0\u65E5\u5FD7:
|
|
139
|
+
${log2}`, { at: true });
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
await e.reply("\n\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u63D2\u4EF6\u540D\u79F0\u6216\u5E8F\u53F7~", { at: true });
|
|
143
|
+
return true;
|
|
144
|
+
}, { name: "\u66F4\u65B0\u63D2\u4EF6", perm: "admin" });
|
|
145
|
+
var log = karin.command(/^#更新日志/, async (e) => {
|
|
146
|
+
const [index, num] = e.msg.replace(/^#更新日志/, "").trim().split(" ");
|
|
147
|
+
if (!index || !num) {
|
|
148
|
+
await e.reply("\n\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u547D\u4EE4 #\u66F4\u65B0\u65E5\u5FD7 <\u5E8F\u53F7\u6216\u63D2\u4EF6\u540D\u79F0> [\u65E5\u5FD7\u6570\u91CF]", { at: true });
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
const count = Number(num) || 10;
|
|
152
|
+
let name = index;
|
|
153
|
+
if (Number(index)) {
|
|
154
|
+
const list = await getAll();
|
|
155
|
+
name = list[Number(index) - 1];
|
|
156
|
+
}
|
|
157
|
+
if (!name) {
|
|
158
|
+
await e.reply("\n\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u63D2\u4EF6\u540D\u79F0\u6216\u5E8F\u53F7~", { at: true });
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
if (name.includes("npm:")) {
|
|
162
|
+
name = name.replace("npm:", "");
|
|
163
|
+
const local = await getPkgVersion(name);
|
|
164
|
+
if (!local) {
|
|
165
|
+
await e.reply("\u83B7\u53D6\u63D2\u4EF6\u7248\u672C\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u662F\u5426\u5B58\u5728\u6B64\u63D2\u4EF6", { at: true });
|
|
166
|
+
} else {
|
|
167
|
+
const result = parseLog(name, local, count);
|
|
168
|
+
await e.reply(`
|
|
169
|
+
${result}`, { at: true });
|
|
170
|
+
}
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
if (name.includes("git:")) {
|
|
174
|
+
name = name.replace("git:", "");
|
|
175
|
+
const file = path.join(process.cwd(), "plugins", name);
|
|
176
|
+
const result = await getCommit({ path: file, count });
|
|
177
|
+
await e.reply(`
|
|
178
|
+
${result}`, { at: true });
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
await e.reply("\n\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u63D2\u4EF6\u540D\u79F0\u6216\u5E8F\u53F7~", { at: true });
|
|
182
|
+
return true;
|
|
183
|
+
}, { name: "\u66F4\u65B0\u65E5\u5FD7", perm: "admin" });
|
|
184
|
+
var updateAll = karin.command(/^#全部(强制)?更新$/, async (e) => {
|
|
185
|
+
const cmd = e.msg.includes("\u5F3A\u5236") ? "git reset --hard && git pull --allow-unrelated-histories" : "git pull";
|
|
186
|
+
try {
|
|
187
|
+
const git = await updateAllGitPlugin(cmd);
|
|
188
|
+
const npm = await updateAllPkg();
|
|
189
|
+
await e.reply([
|
|
190
|
+
"\n\u5168\u90E8\u66F4\u65B0\u5B8C\u6210",
|
|
191
|
+
"-----",
|
|
192
|
+
git,
|
|
193
|
+
"-----",
|
|
194
|
+
npm
|
|
195
|
+
].join("\n"), { at: true });
|
|
196
|
+
} catch (error) {
|
|
197
|
+
await e.reply(`
|
|
198
|
+
\u5168\u90E8\u66F4\u65B0\u5931\u8D25: ${error.message || "\u672A\u77E5\u9519\u8BEF"}`, { at: true });
|
|
199
|
+
}
|
|
200
|
+
return true;
|
|
201
|
+
}, { name: "\u5168\u90E8\u66F4\u65B0", perm: "admin" });
|
|
202
|
+
var parseLog = (pkg, local, count) => {
|
|
203
|
+
const file = path.join(process.cwd(), "node_modules", pkg, "CHANGELOG.md");
|
|
204
|
+
if (!fs.existsSync(file)) return "\u63D2\u4EF6\u672A\u63D0\u4F9B`CHANGELOG.md`\u6587\u4EF6";
|
|
205
|
+
const data = fs.readFileSync(file, "utf-8");
|
|
206
|
+
if (typeof count === "number") {
|
|
207
|
+
return changelog.logs(data, local, count) || "\u672A\u627E\u5230\u5BF9\u5E94\u7684\u66F4\u65B0\u65E5\u5FD7";
|
|
208
|
+
}
|
|
209
|
+
return changelog.range(data, local, count) || "\u672A\u627E\u5230\u5BF9\u5E94\u7684\u66F4\u65B0\u65E5\u5FD7";
|
|
210
|
+
};
|
|
211
|
+
export {
|
|
212
|
+
check,
|
|
213
|
+
log,
|
|
214
|
+
plugins,
|
|
215
|
+
update,
|
|
216
|
+
updateAll
|
|
217
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// src/root.ts
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
// package.json
|
|
5
|
+
var package_default = {
|
|
6
|
+
name: "@karinjs/plugin-basic",
|
|
7
|
+
version: "1.0.4",
|
|
8
|
+
description: "karin plugin for basic functions",
|
|
9
|
+
homepage: "https://github.com/KarinJS/karin-plugin-basic",
|
|
10
|
+
bugs: {
|
|
11
|
+
url: "https://github.com/KarinJS/karin-plugin-basic/issues"
|
|
12
|
+
},
|
|
13
|
+
repository: {
|
|
14
|
+
type: "git",
|
|
15
|
+
url: "git+https://github.com/KarinJS/karin-plugin-basic.git"
|
|
16
|
+
},
|
|
17
|
+
author: "shijin",
|
|
18
|
+
type: "module",
|
|
19
|
+
main: "dist/index.js",
|
|
20
|
+
files: [
|
|
21
|
+
"dist",
|
|
22
|
+
"config",
|
|
23
|
+
"resources",
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"package.json",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
scripts: {
|
|
29
|
+
build: "tsc && tsup",
|
|
30
|
+
pub: "npm publish --access public",
|
|
31
|
+
sort: "npx sort-package-json",
|
|
32
|
+
dev: "tsx src/index.ts",
|
|
33
|
+
watch: "tsx watch src/index.ts",
|
|
34
|
+
karin: "karin"
|
|
35
|
+
},
|
|
36
|
+
devDependencies: {
|
|
37
|
+
"@types/node": "^20.17.17",
|
|
38
|
+
eslint: "^9.20.0",
|
|
39
|
+
neostandard: "^0.12.1",
|
|
40
|
+
"node-karin": "^1.4.3",
|
|
41
|
+
tsup: "^8.3.6",
|
|
42
|
+
tsx: "^4.19.2",
|
|
43
|
+
typescript: "^5.7.3"
|
|
44
|
+
},
|
|
45
|
+
publishConfig: {
|
|
46
|
+
access: "public",
|
|
47
|
+
registry: "https://registry.npmjs.org"
|
|
48
|
+
},
|
|
49
|
+
karin: {
|
|
50
|
+
main: "src/index.ts",
|
|
51
|
+
apps: [
|
|
52
|
+
"dist/apps"
|
|
53
|
+
],
|
|
54
|
+
"ts-apps": [
|
|
55
|
+
"dist/apps"
|
|
56
|
+
],
|
|
57
|
+
static: [
|
|
58
|
+
"resources"
|
|
59
|
+
],
|
|
60
|
+
files: [
|
|
61
|
+
"config"
|
|
62
|
+
],
|
|
63
|
+
"ts-web": "src/web.config.ts",
|
|
64
|
+
web: "dist/web.config.js"
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// src/root.ts
|
|
69
|
+
import { fileURLToPath } from "node:url";
|
|
70
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
71
|
+
var __dirname = path.dirname(__filename);
|
|
72
|
+
var __pluginDir = path.resolve(__dirname, "../");
|
|
73
|
+
var info = {
|
|
74
|
+
/** 插件目录 */
|
|
75
|
+
dir: __pluginDir,
|
|
76
|
+
/** 插件名称 */
|
|
77
|
+
name: package_default.name.replace(/\//g, "-"),
|
|
78
|
+
/** 插件版本 */
|
|
79
|
+
version: package_default.version,
|
|
80
|
+
/** package.json */
|
|
81
|
+
pkg: package_default
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export {
|
|
85
|
+
info
|
|
86
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
info
|
|
3
|
+
} from "./chunk-7VNKIAO2.js";
|
|
4
|
+
|
|
5
|
+
// src/utils/config.ts
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import {
|
|
9
|
+
watch,
|
|
10
|
+
basePath,
|
|
11
|
+
filesByExt,
|
|
12
|
+
copyConfigSync,
|
|
13
|
+
requireFileSync
|
|
14
|
+
} from "node-karin";
|
|
15
|
+
var cache;
|
|
16
|
+
var dir = path.join(basePath, info.name, "config");
|
|
17
|
+
var defConfig = path.join(info.dir, "config");
|
|
18
|
+
var main = () => {
|
|
19
|
+
copyConfigSync(defConfig, dir, [".json"]);
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
const list = filesByExt(dir, ".json", "abs");
|
|
22
|
+
list.forEach((file) => watch(file, (old, now) => {
|
|
23
|
+
cache = void 0;
|
|
24
|
+
}));
|
|
25
|
+
}, 2e3);
|
|
26
|
+
};
|
|
27
|
+
var config = () => {
|
|
28
|
+
if (cache) return cache;
|
|
29
|
+
const user = requireFileSync(`${dir}/config.json`);
|
|
30
|
+
const def = requireFileSync(`${defConfig}/config.json`);
|
|
31
|
+
const result = { ...def, ...user };
|
|
32
|
+
cache = result;
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
var writeConfig = (config2) => {
|
|
36
|
+
const def = requireFileSync(`${defConfig}/config.json`);
|
|
37
|
+
const result = { ...def, ...config2 };
|
|
38
|
+
cache = result;
|
|
39
|
+
fs.writeFileSync(`${dir}/config.json`, JSON.stringify(result, null, 2));
|
|
40
|
+
};
|
|
41
|
+
main();
|
|
42
|
+
|
|
43
|
+
export {
|
|
44
|
+
config,
|
|
45
|
+
writeConfig
|
|
46
|
+
};
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as node_karin from 'node-karin';
|
|
2
|
+
|
|
3
|
+
/** `config.json` 文件的类型定义 */
|
|
4
|
+
interface Config {
|
|
5
|
+
/** 是否统计状态 关闭后可降低redis压力 */
|
|
6
|
+
status: boolean;
|
|
7
|
+
/** 全部更新是否使用转发 */
|
|
8
|
+
forward: boolean;
|
|
9
|
+
/** 默认重启是否为前台重启 true为前台重启 false为后台重启 */
|
|
10
|
+
restartMode: boolean;
|
|
11
|
+
/** 更新完成是否自动重启 */
|
|
12
|
+
restart: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare const _default: {
|
|
16
|
+
info: {
|
|
17
|
+
name: string;
|
|
18
|
+
version: string;
|
|
19
|
+
description: string;
|
|
20
|
+
author: {
|
|
21
|
+
name: string;
|
|
22
|
+
avatar: string;
|
|
23
|
+
}[];
|
|
24
|
+
};
|
|
25
|
+
/** 动态渲染的组件 */
|
|
26
|
+
components: () => node_karin.SwitchProps[];
|
|
27
|
+
/** 前端点击保存之后调用的方法 */
|
|
28
|
+
save: (config: Config) => {
|
|
29
|
+
success: boolean;
|
|
30
|
+
message: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { _default as default };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
config,
|
|
3
|
+
writeConfig
|
|
4
|
+
} from "./chunk-XKQYARLA.js";
|
|
5
|
+
import {
|
|
6
|
+
info
|
|
7
|
+
} from "./chunk-7VNKIAO2.js";
|
|
8
|
+
|
|
9
|
+
// src/web.config.ts
|
|
10
|
+
import { components } from "node-karin";
|
|
11
|
+
var web_config_default = {
|
|
12
|
+
info: {
|
|
13
|
+
name: "\u57FA\u7840\u63D2\u4EF6",
|
|
14
|
+
version: info.version,
|
|
15
|
+
description: info.pkg.description,
|
|
16
|
+
author: [
|
|
17
|
+
{
|
|
18
|
+
name: info.pkg.author,
|
|
19
|
+
avatar: "https://github.com/sj817.png"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
/** 动态渲染的组件 */
|
|
24
|
+
components: () => {
|
|
25
|
+
const cfg = config();
|
|
26
|
+
const list = [
|
|
27
|
+
components.switch.create("status", {
|
|
28
|
+
color: "success",
|
|
29
|
+
label: "\u7EDF\u8BA1\u72B6\u6001",
|
|
30
|
+
description: "\u5173\u95ED\u540E\u53EF\u964D\u4F4Eredis\u538B\u529B...",
|
|
31
|
+
defaultSelected: cfg.status
|
|
32
|
+
}),
|
|
33
|
+
components.switch.create("forward", {
|
|
34
|
+
color: "success",
|
|
35
|
+
label: "\u66F4\u65B0\u8F6C\u53D1",
|
|
36
|
+
description: "\u5168\u90E8\u66F4\u65B0\u662F\u5426\u4F7F\u7528\u8F6C\u53D1",
|
|
37
|
+
defaultSelected: cfg.forward
|
|
38
|
+
}),
|
|
39
|
+
components.switch.create("restartMode", {
|
|
40
|
+
color: "success",
|
|
41
|
+
label: "\u91CD\u542F\u65B9\u5F0F",
|
|
42
|
+
description: "\u6253\u5F00\u4E3A\u524D\u53F0\u91CD\u542F \u5173\u95ED\u4E3A\u540E\u53F0\u91CD\u542F",
|
|
43
|
+
defaultSelected: cfg.restartMode
|
|
44
|
+
}),
|
|
45
|
+
components.switch.create("restart", {
|
|
46
|
+
color: "success",
|
|
47
|
+
label: "\u81EA\u52A8\u91CD\u542F",
|
|
48
|
+
description: "\u66F4\u65B0\u5B8C\u6210\u662F\u5426\u81EA\u52A8\u91CD\u542F",
|
|
49
|
+
defaultSelected: cfg.restart
|
|
50
|
+
})
|
|
51
|
+
];
|
|
52
|
+
return list;
|
|
53
|
+
},
|
|
54
|
+
/** 前端点击保存之后调用的方法 */
|
|
55
|
+
save: (config2) => {
|
|
56
|
+
writeConfig(config2);
|
|
57
|
+
return {
|
|
58
|
+
success: true,
|
|
59
|
+
message: "\u4FDD\u5B58\u6210\u529F"
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
export {
|
|
64
|
+
web_config_default as default
|
|
65
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@karinjs/plugin-basic",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "karin plugin for basic functions",
|
|
5
5
|
"homepage": "https://github.com/KarinJS/karin-plugin-basic",
|
|
6
6
|
"bugs": {
|
|
@@ -12,10 +12,9 @@
|
|
|
12
12
|
},
|
|
13
13
|
"author": "shijin",
|
|
14
14
|
"type": "module",
|
|
15
|
-
"main": "
|
|
15
|
+
"main": "dist/index.js",
|
|
16
16
|
"files": [
|
|
17
|
-
"
|
|
18
|
-
"/lib/**/*.d.ts",
|
|
17
|
+
"dist",
|
|
19
18
|
"config",
|
|
20
19
|
"resources",
|
|
21
20
|
"LICENSE",
|
|
@@ -23,11 +22,11 @@
|
|
|
23
22
|
"README.md"
|
|
24
23
|
],
|
|
25
24
|
"scripts": {
|
|
26
|
-
"build": "tsc
|
|
27
|
-
"pr": "node lib/cli/pr.js",
|
|
25
|
+
"build": "tsc && tsup",
|
|
28
26
|
"pub": "npm publish --access public",
|
|
29
27
|
"sort": "npx sort-package-json",
|
|
30
|
-
"dev": "tsx
|
|
28
|
+
"dev": "tsx src/index.ts",
|
|
29
|
+
"watch": "tsx watch src/index.ts",
|
|
31
30
|
"karin": "karin"
|
|
32
31
|
},
|
|
33
32
|
"publishConfig": {
|
|
@@ -37,25 +36,18 @@
|
|
|
37
36
|
"karin": {
|
|
38
37
|
"main": "src/index.ts",
|
|
39
38
|
"apps": [
|
|
40
|
-
"
|
|
39
|
+
"dist/apps"
|
|
41
40
|
],
|
|
42
41
|
"ts-apps": [
|
|
43
|
-
"
|
|
42
|
+
"dist/apps"
|
|
44
43
|
],
|
|
45
44
|
"static": [
|
|
46
45
|
"resources"
|
|
47
46
|
],
|
|
48
47
|
"files": [
|
|
49
|
-
"config"
|
|
50
|
-
"data",
|
|
51
|
-
"resources"
|
|
52
|
-
],
|
|
53
|
-
"include": [
|
|
54
|
-
"src/**/*"
|
|
48
|
+
"config"
|
|
55
49
|
],
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
"@karinjs/**/*"
|
|
59
|
-
]
|
|
50
|
+
"ts-web": "src/web.config.ts",
|
|
51
|
+
"web": "dist/web.config.js"
|
|
60
52
|
}
|
|
61
|
-
}
|
|
53
|
+
}
|
package/lib/apps/exit.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const exit: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
package/lib/apps/exit.js
DELETED
package/lib/apps/restart.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const restarts: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
package/lib/apps/restart.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { config } from '../utils/config.js';
|
|
2
|
-
import { common, karin, logger, restart } from 'node-karin';
|
|
3
|
-
export const restarts = karin.command(/^#重启$/, async (e) => {
|
|
4
|
-
try {
|
|
5
|
-
await e.reply(`开始重启 本次运行时间: ${common.uptime()}`, { at: true });
|
|
6
|
-
const { status, data } = await restart(e.selfId, e.contact, e.messageId, config().restartMode);
|
|
7
|
-
if (status === 'failed')
|
|
8
|
-
throw data;
|
|
9
|
-
return true;
|
|
10
|
-
}
|
|
11
|
-
catch (error) {
|
|
12
|
-
logger.error(error);
|
|
13
|
-
await e.reply(`重启失败: ${error.message || '未知原因'}`, { at: true });
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
}, { name: '重启', perm: 'admin' });
|
package/lib/apps/status.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const status: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
package/lib/apps/status.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import moment from 'node-karin/moment';
|
|
2
|
-
import { config } from '../utils/config.js';
|
|
3
|
-
import { EVENT_COUNT, karin, RECV_MSG, redis, SEND_MSG } from 'node-karin';
|
|
4
|
-
export const status = karin.command(/^#状态$/, async (e) => {
|
|
5
|
-
const today = moment().format('YYYY-MM-DD');
|
|
6
|
-
const month = moment().format('YYYY-MM');
|
|
7
|
-
const [send, recv, event, sendMonth, recvMonth, eventMonth] = await Promise.all([
|
|
8
|
-
getStat(`${SEND_MSG}:${today}*`),
|
|
9
|
-
getStat(`${RECV_MSG}:${today}*`),
|
|
10
|
-
getStat(`${EVENT_COUNT}:${today}*`),
|
|
11
|
-
getStat(`${SEND_MSG}:${month}*`),
|
|
12
|
-
getStat(`${RECV_MSG}:${month}*`),
|
|
13
|
-
getStat(`${EVENT_COUNT}:${month}*`)
|
|
14
|
-
]);
|
|
15
|
-
await e.reply([
|
|
16
|
-
'------机器人状态------',
|
|
17
|
-
`当前版本:v${process.env.KARIN_VERSION}`,
|
|
18
|
-
`内存占用:${MB()}MB`,
|
|
19
|
-
`运行时间:${uptime()}`,
|
|
20
|
-
'------今日统计------',
|
|
21
|
-
`发送消息:${send}次`,
|
|
22
|
-
`插件触发:${event}次`,
|
|
23
|
-
`收到消息:${recv}次`,
|
|
24
|
-
'------本月统计------',
|
|
25
|
-
`发送消息:${sendMonth}次`,
|
|
26
|
-
`插件触发:${eventMonth}次`,
|
|
27
|
-
`收到消息:${recvMonth}次`
|
|
28
|
-
].join('\n'));
|
|
29
|
-
return true;
|
|
30
|
-
}, { name: '状态统计' });
|
|
31
|
-
/**
|
|
32
|
-
* 生成存储键
|
|
33
|
-
* @param contact 联系人
|
|
34
|
-
* @example
|
|
35
|
-
* ```ts
|
|
36
|
-
* friend:<peer>
|
|
37
|
-
* group:<peer>
|
|
38
|
-
* guild:<peer>:<subPeer>
|
|
39
|
-
* direct:<peer>:<subPeer>
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
|
-
const createKey = (contact) => {
|
|
43
|
-
const { scene, peer, subPeer } = contact;
|
|
44
|
-
return `${moment().format('YYYY-MM-DD')}:${scene}:${peer}${subPeer ? `:${subPeer}` : ''}`;
|
|
45
|
-
};
|
|
46
|
-
/**
|
|
47
|
-
* 获取 Redis 键值统计
|
|
48
|
-
*/
|
|
49
|
-
const getStat = async (pattern) => {
|
|
50
|
-
const keys = await redis.keys(pattern);
|
|
51
|
-
const values = await Promise.all(keys.map((key) => redis.get(key).then(Number)));
|
|
52
|
-
return values.reduce((total, value) => total + (value || 0), 0);
|
|
53
|
-
};
|
|
54
|
-
const MB = () => (process.memoryUsage().rss / 1024 / 1024).toFixed(2);
|
|
55
|
-
const uptime = () => {
|
|
56
|
-
const uptime = process.uptime();
|
|
57
|
-
const hour = Math.floor(uptime / 3600);
|
|
58
|
-
const minute = Math.floor((uptime % 3600) / 60);
|
|
59
|
-
return `${hour}小时${minute}分钟`;
|
|
60
|
-
};
|
|
61
|
-
(() => {
|
|
62
|
-
if (!config().status)
|
|
63
|
-
return;
|
|
64
|
-
karin.on(RECV_MSG, (contact) => redis.incr(`${RECV_MSG}:${createKey(contact)}`));
|
|
65
|
-
karin.on(SEND_MSG, (contact) => redis.incr(`${SEND_MSG}:${createKey(contact)}`));
|
|
66
|
-
karin.on(EVENT_COUNT, ({ plugin, event }) => {
|
|
67
|
-
const key = `${EVENT_COUNT}:${moment().format('YYYY-MM-DD')}:${plugin.file.basename}:${plugin.file.method}`;
|
|
68
|
-
redis.incr(key);
|
|
69
|
-
});
|
|
70
|
-
})();
|
package/lib/apps/update.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/** 插件列表 */
|
|
2
|
-
export declare const plugins: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
|
3
|
-
/** 检查更新 */
|
|
4
|
-
export declare const check: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
|
5
|
-
/** 更新插件 */
|
|
6
|
-
export declare const update: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
|
7
|
-
/** 更新日志 */
|
|
8
|
-
export declare const log: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
|
9
|
-
/** 全部更新 */
|
|
10
|
-
export declare const updateAll: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
package/lib/apps/update.js
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { changelog, checkGitPluginUpdate, checkPkgUpdate, getCommit, getPlugins, getPkgVersion, karin, updateAllGitPlugin, updateAllPkg, updateGitPlugin, updatePkg } from 'node-karin';
|
|
4
|
-
const cache = [];
|
|
5
|
-
const getAll = async () => {
|
|
6
|
-
if (cache.length)
|
|
7
|
-
return cache;
|
|
8
|
-
const git = await getPlugins('git', false);
|
|
9
|
-
const npm = await getPlugins('npm', false);
|
|
10
|
-
const list = [
|
|
11
|
-
'npm:node-karin',
|
|
12
|
-
...git.map(name => `git:${name}`),
|
|
13
|
-
...npm.map(name => `npm:${name}`)
|
|
14
|
-
];
|
|
15
|
-
cache.push(...list);
|
|
16
|
-
setTimeout(() => {
|
|
17
|
-
cache.length = 0;
|
|
18
|
-
}, 60000);
|
|
19
|
-
return list;
|
|
20
|
-
};
|
|
21
|
-
/** 插件列表 */
|
|
22
|
-
export const plugins = karin.command(/^#插件列表$/, async (e) => {
|
|
23
|
-
const list = await getAll();
|
|
24
|
-
list.forEach((item, index) => {
|
|
25
|
-
item += `${index + 1}. ${item}`;
|
|
26
|
-
});
|
|
27
|
-
await e.reply([
|
|
28
|
-
'\n插件列表:',
|
|
29
|
-
'更新:#更新插件 序号或名称',
|
|
30
|
-
'检查更新:#检查更新 序号或名称',
|
|
31
|
-
'日志:#更新日志 条数 序号或名称',
|
|
32
|
-
...list,
|
|
33
|
-
].join('\n'), { at: true });
|
|
34
|
-
return true;
|
|
35
|
-
}, { name: '插件列表', perm: 'admin' });
|
|
36
|
-
/** 检查更新 */
|
|
37
|
-
export const check = karin.command(/^#检查更新/, async (e) => {
|
|
38
|
-
let name = e.msg.replace(/^#检查更新/, '').trim();
|
|
39
|
-
/** 传入的是序号 */
|
|
40
|
-
const index = Number(name);
|
|
41
|
-
if (index && typeof index === 'number') {
|
|
42
|
-
const list = await getAll();
|
|
43
|
-
name = list[index - 1];
|
|
44
|
-
}
|
|
45
|
-
if (!name) {
|
|
46
|
-
await e.reply('\n请输入正确的插件名称或序号~', { at: true });
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
const tips = '当前版本已是最新版本';
|
|
50
|
-
if (name.includes('git:')) {
|
|
51
|
-
name = name.replace('git:', '');
|
|
52
|
-
const file = path.join(process.cwd(), 'plugins', name.replace('git:', ''));
|
|
53
|
-
const result = await checkGitPluginUpdate(file);
|
|
54
|
-
if (result.status === 'error') {
|
|
55
|
-
const { data } = result;
|
|
56
|
-
const msg = typeof data === 'string' ? data : `获取更新信息失败: ${data.message || '未知错误'}`;
|
|
57
|
-
await e.reply(msg, { at: true });
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
if (result.status === 'no') {
|
|
61
|
-
await e.reply(`\n${tips}${result.data.replace(tips + '\n', '')}`, { at: true });
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
await e.reply([
|
|
65
|
-
'\n存在新版本:',
|
|
66
|
-
`名称:${name}`,
|
|
67
|
-
`落后: ${result.count}次提交`,
|
|
68
|
-
`更新日志:\n${result.data}`,
|
|
69
|
-
].join('\n'), { at: true });
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
if (name.includes('npm:')) {
|
|
73
|
-
name = name.replace('npm:', '');
|
|
74
|
-
const result = await checkPkgUpdate(name);
|
|
75
|
-
if (result.status === 'no') {
|
|
76
|
-
await e.reply(`\n当前版本: ${result.local}\n${tips}`, { at: true });
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
if (result.status === 'error') {
|
|
80
|
-
const { error } = result;
|
|
81
|
-
const msg = `获取更新信息失败: ${error.message || '未知错误'}`;
|
|
82
|
-
await e.reply(msg, { at: true });
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
await e.reply([
|
|
86
|
-
'\n存在新版本:',
|
|
87
|
-
`名称:${name}`,
|
|
88
|
-
`当前版本: ${result.local}`,
|
|
89
|
-
`最新版本: ${result.remote}`,
|
|
90
|
-
].join('\n'), { at: true });
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
await e.reply('\n请输入正确的插件名称或序号~', { at: true });
|
|
94
|
-
return true;
|
|
95
|
-
}, { name: '检查更新', perm: 'admin' });
|
|
96
|
-
/** 更新插件 */
|
|
97
|
-
export const update = karin.command(/^#(强制)?更新(插件)?(?!列表|日志)/, async (e) => {
|
|
98
|
-
let name = e.msg.replace(/^#(强制)?更新(插件)?(?!列表|日志)/, '').trim();
|
|
99
|
-
/** 传入的是序号 */
|
|
100
|
-
const index = Number(name);
|
|
101
|
-
if (index && typeof index === 'number') {
|
|
102
|
-
const list = await getAll();
|
|
103
|
-
name = list[index - 1];
|
|
104
|
-
}
|
|
105
|
-
if (!name) {
|
|
106
|
-
await e.reply('\n请输入正确的插件名称或序号~', { at: true });
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
109
|
-
if (name.includes('git:')) {
|
|
110
|
-
name = name.replace('git:', '');
|
|
111
|
-
const file = path.join(process.cwd(), 'plugins', name.replace('git:', ''));
|
|
112
|
-
let cmd = 'git pull';
|
|
113
|
-
if (e.msg.includes('强制'))
|
|
114
|
-
cmd = 'git reset --hard && git pull --allow-unrelated-histories';
|
|
115
|
-
const result = await updateGitPlugin(file, cmd, 120);
|
|
116
|
-
if (result.status === 'failed') {
|
|
117
|
-
const { data } = result;
|
|
118
|
-
const msg = typeof data === 'string' ? data : `获取更新信息失败: ${data.message || '未知错误'}`;
|
|
119
|
-
await e.reply(msg, { at: true });
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
await e.reply(`\n${result.data}`, { at: true });
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
if (name.includes('npm:')) {
|
|
126
|
-
name = name.replace('npm:', '');
|
|
127
|
-
const result = await updatePkg(name);
|
|
128
|
-
if (result.status === 'failed') {
|
|
129
|
-
const { data } = result;
|
|
130
|
-
const msg = typeof data === 'string' ? data : `获取更新信息失败: ${data.message || '未知错误'}`;
|
|
131
|
-
await e.reply(`\n${msg}`, { at: true });
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
const log = parseLog(name, result.local, result.remote);
|
|
135
|
-
await e.reply(`\n更新成功\n当前版本: ${result.remote}\n更新日志: \n${log}`, { at: true });
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
await e.reply('\n请输入正确的插件名称或序号~', { at: true });
|
|
139
|
-
return true;
|
|
140
|
-
}, { name: '更新插件', perm: 'admin' });
|
|
141
|
-
/** 更新日志 */
|
|
142
|
-
export const log = karin.command(/^#更新日志/, async (e) => {
|
|
143
|
-
// 更新日志 npm:node-karin 10
|
|
144
|
-
const [index, num] = e.msg.replace(/^#更新日志/, '').trim().split(' ');
|
|
145
|
-
if (!index || !num) {
|
|
146
|
-
await e.reply('\n请输入正确的命令 #更新日志 <序号或插件名称> [日志数量]', { at: true });
|
|
147
|
-
return true;
|
|
148
|
-
}
|
|
149
|
-
const count = Number(num) || 10;
|
|
150
|
-
let name = index;
|
|
151
|
-
if (Number(index)) {
|
|
152
|
-
const list = await getAll();
|
|
153
|
-
name = list[Number(index) - 1];
|
|
154
|
-
}
|
|
155
|
-
if (!name) {
|
|
156
|
-
await e.reply('\n请输入正确的插件名称或序号~', { at: true });
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
if (name.includes('npm:')) {
|
|
160
|
-
name = name.replace('npm:', '');
|
|
161
|
-
const local = await getPkgVersion(name);
|
|
162
|
-
if (!local) {
|
|
163
|
-
await e.reply('获取插件版本失败,请检查是否存在此插件', { at: true });
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
const result = parseLog(name, local, count);
|
|
167
|
-
await e.reply(`\n${result}`, { at: true });
|
|
168
|
-
}
|
|
169
|
-
return true;
|
|
170
|
-
}
|
|
171
|
-
if (name.includes('git:')) {
|
|
172
|
-
name = name.replace('git:', '');
|
|
173
|
-
const file = path.join(process.cwd(), 'plugins', name);
|
|
174
|
-
const result = await getCommit({ path: file, count });
|
|
175
|
-
await e.reply(`\n${result}`, { at: true });
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
await e.reply('\n请输入正确的插件名称或序号~', { at: true });
|
|
179
|
-
return true;
|
|
180
|
-
}, { name: '更新日志', perm: 'admin' });
|
|
181
|
-
/** 全部更新 */
|
|
182
|
-
export const updateAll = karin.command(/^#全部(强制)?更新$/, async (e) => {
|
|
183
|
-
const cmd = e.msg.includes('强制') ? 'git reset --hard && git pull --allow-unrelated-histories' : 'git pull';
|
|
184
|
-
try {
|
|
185
|
-
const git = await updateAllGitPlugin(cmd);
|
|
186
|
-
const npm = await updateAllPkg();
|
|
187
|
-
await e.reply([
|
|
188
|
-
'\n全部更新完成',
|
|
189
|
-
'-----',
|
|
190
|
-
git,
|
|
191
|
-
'-----',
|
|
192
|
-
npm,
|
|
193
|
-
].join('\n'), { at: true });
|
|
194
|
-
}
|
|
195
|
-
catch (error) {
|
|
196
|
-
await e.reply(`\n全部更新失败: ${error.message || '未知错误'}`, { at: true });
|
|
197
|
-
}
|
|
198
|
-
return true;
|
|
199
|
-
}, { name: '全部更新', perm: 'admin' });
|
|
200
|
-
/**
|
|
201
|
-
* @param pkg npm包名
|
|
202
|
-
* @param local 本地版本
|
|
203
|
-
* @param count 提取的日志数量 或 版本号
|
|
204
|
-
*/
|
|
205
|
-
const parseLog = (pkg, local, count) => {
|
|
206
|
-
const file = path.join(process.cwd(), 'node_modules', pkg, 'CHANGELOG.md');
|
|
207
|
-
if (!fs.existsSync(file))
|
|
208
|
-
return '插件未提供`CHANGELOG.md`文件';
|
|
209
|
-
const data = fs.readFileSync(file, 'utf-8');
|
|
210
|
-
if (typeof count === 'number') {
|
|
211
|
-
return changelog.logs(data, local, count) || '未找到对应的更新日志';
|
|
212
|
-
}
|
|
213
|
-
return changelog.range(data, local, count) || '未找到对应的更新日志';
|
|
214
|
-
};
|
package/lib/cli/pr.d.ts
DELETED
package/lib/cli/pr.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
/**
|
|
4
|
-
* @description 获取package.json路径
|
|
5
|
-
*/
|
|
6
|
-
const getPkgPath = () => process.cwd() + '/package.json';
|
|
7
|
-
/**
|
|
8
|
-
* @description 读取package.json
|
|
9
|
-
*/
|
|
10
|
-
const readPkg = () => JSON.parse(fs.readFileSync(getPkgPath(), 'utf-8'));
|
|
11
|
-
/**
|
|
12
|
-
* @description 写入package.json
|
|
13
|
-
* @param pkg package.json
|
|
14
|
-
*/
|
|
15
|
-
const writePkg = (pkg) => fs.writeFileSync(getPkgPath(), JSON.stringify(pkg, null, 2));
|
|
16
|
-
/**
|
|
17
|
-
* @description 构建pr版本号 <主版本号>.<次版本号>.<修订号>-<预发布标识>.<PR标识>.<PR编号>.<工作流唯一编号>-<时间戳>
|
|
18
|
-
|
|
19
|
-
* @param pkg package.json
|
|
20
|
-
*/
|
|
21
|
-
const updateVersion = (pkg) => {
|
|
22
|
-
const list = pkg.version.split('.');
|
|
23
|
-
// 1.0.0 => 1.0.1-beta.pr.pr编号.工作流唯一编号-时间戳 => 1.0.1-beta.pr.184-1631537630
|
|
24
|
-
const timestamp = Math.floor(Date.now() / 1000);
|
|
25
|
-
list[2] = `${Number(list[2]) + 1}-beta.pr.${process.env.PR_NUMBER}.${process.env.GITHUB_RUN_ATTEMPT || 1}-${timestamp}`;
|
|
26
|
-
pkg.version = list.join('.');
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* @description 设置环境变量
|
|
30
|
-
* @param pkg package.json
|
|
31
|
-
*/
|
|
32
|
-
const setEnvVariables = (pkg) => {
|
|
33
|
-
fs.appendFileSync(process.env.GITHUB_ENV, `PKG_NAME=${pkg.name}\nPKG_VERSION=${pkg.version}\n`);
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* @description 更新版本号并设置环境变量
|
|
37
|
-
*/
|
|
38
|
-
const version = () => {
|
|
39
|
-
const pkg = readPkg();
|
|
40
|
-
updateVersion(pkg);
|
|
41
|
-
writePkg(pkg);
|
|
42
|
-
setEnvVariables(pkg);
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* @description 删除devDependencies和peerDependencies
|
|
46
|
-
*/
|
|
47
|
-
const clean = () => {
|
|
48
|
-
const pkg = readPkg();
|
|
49
|
-
delete pkg.devDependencies;
|
|
50
|
-
delete pkg.peerDependencies;
|
|
51
|
-
writePkg(pkg);
|
|
52
|
-
};
|
|
53
|
-
/**
|
|
54
|
-
* @description 执行所有操作
|
|
55
|
-
*/
|
|
56
|
-
const all = () => {
|
|
57
|
-
const pkg = readPkg();
|
|
58
|
-
updateVersion(pkg);
|
|
59
|
-
delete pkg.devDependencies;
|
|
60
|
-
delete pkg.peerDependencies;
|
|
61
|
-
writePkg(pkg);
|
|
62
|
-
setEnvVariables(pkg);
|
|
63
|
-
};
|
|
64
|
-
const cmd = process.argv[2];
|
|
65
|
-
if (cmd === 'version') {
|
|
66
|
-
version();
|
|
67
|
-
}
|
|
68
|
-
else if (cmd === 'clean') {
|
|
69
|
-
clean();
|
|
70
|
-
}
|
|
71
|
-
else if (cmd === 'all') {
|
|
72
|
-
all();
|
|
73
|
-
}
|
package/lib/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/index.js
DELETED
package/lib/types/config.d.ts
DELETED
package/lib/types/config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/utils/config.d.ts
DELETED
package/lib/utils/config.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { dirPath } from '../utils/index.js';
|
|
2
|
-
import { watch, basePath, filesByExt, copyConfigSync, requireFileSync, } from 'node-karin';
|
|
3
|
-
let cache;
|
|
4
|
-
/**
|
|
5
|
-
* @description package.json
|
|
6
|
-
*/
|
|
7
|
-
export const pkg = () => requireFileSync(`${dirPath}/package.json`);
|
|
8
|
-
/** 用户配置的插件名称 */
|
|
9
|
-
const pluginName = pkg().name.replace(/\//g, '-');
|
|
10
|
-
/** 用户配置 */
|
|
11
|
-
const dirConfig = `${basePath}/${pluginName}/config`;
|
|
12
|
-
/** 默认配置 */
|
|
13
|
-
const defConfig = `${dirPath}/config/config`;
|
|
14
|
-
/**
|
|
15
|
-
* @description 初始化配置文件
|
|
16
|
-
*/
|
|
17
|
-
copyConfigSync(defConfig, dirConfig, ['.yaml']);
|
|
18
|
-
/**
|
|
19
|
-
* @description 配置文件
|
|
20
|
-
*/
|
|
21
|
-
export const config = () => {
|
|
22
|
-
if (cache)
|
|
23
|
-
return cache;
|
|
24
|
-
const user = requireFileSync(`${dirConfig}/config.yaml`);
|
|
25
|
-
const def = requireFileSync(`${defConfig}/config.yaml`);
|
|
26
|
-
const result = { ...def, ...user };
|
|
27
|
-
cache = result;
|
|
28
|
-
return result;
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* @description 监听配置文件
|
|
32
|
-
*/
|
|
33
|
-
setTimeout(() => {
|
|
34
|
-
const list = filesByExt(dirConfig, '.yaml', 'abs');
|
|
35
|
-
list.forEach(file => watch(file, (old, now) => {
|
|
36
|
-
cache = undefined;
|
|
37
|
-
}));
|
|
38
|
-
}, 2000);
|
package/lib/utils/dir.d.ts
DELETED
package/lib/utils/dir.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
|
-
/** 当前文件的绝对路径 */
|
|
4
|
-
const filePath = fileURLToPath(import.meta.url).replace(/\\/g, '/');
|
|
5
|
-
/** 插件包绝对路径 */
|
|
6
|
-
const dirPath = path.resolve(filePath, '../../../');
|
|
7
|
-
/** 插件包的名称 */
|
|
8
|
-
const basename = path.basename(dirPath);
|
|
9
|
-
export { dirPath, basename };
|
package/lib/utils/index.d.ts
DELETED
package/lib/utils/index.js
DELETED