koishi-plugin-echo-cave 1.7.3 → 1.7.5

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.
@@ -0,0 +1,4 @@
1
+ import { EchoCave } from './index';
2
+ import { Context, Session } from 'koishi';
3
+ export declare function sendCaveMsg(ctx: Context, session: Session, caveMsg: EchoCave): Promise<void>;
4
+ export declare function formatDate(date: Date): string;
package/lib/index.cjs CHANGED
@@ -36,74 +36,6 @@ __export(index_exports, {
36
36
  });
37
37
  module.exports = __toCommonJS(index_exports);
38
38
  var import_koishi_plugin_adapter_onebot = require("@pynickle/koishi-plugin-adapter-onebot");
39
- var import_fs = __toESM(require("fs"), 1);
40
- var import_koishi = require("koishi");
41
- var import_node_path2 = __toESM(require("node:path"), 1);
42
-
43
- // src/image-helper.ts
44
- var import_node_fs = require("node:fs");
45
- var import_node_path = __toESM(require("node:path"), 1);
46
- async function saveImages(ctx, imgElement) {
47
- const imgUrl = imgElement.url;
48
- const originalImgName = imgElement.file;
49
- const lastDotIndex = originalImgName.lastIndexOf(".");
50
- let imgExt = "";
51
- if (lastDotIndex === -1) {
52
- imgExt = "png";
53
- } else {
54
- imgExt = originalImgName.substring(lastDotIndex + 1);
55
- }
56
- const imgPath = import_node_path.default.join(ctx.baseDir, "data", "cave", "images");
57
- const imgName = (/* @__PURE__ */ new Date()).getTime().toString();
58
- let fullImgPath = import_node_path.default.join(imgPath, `${imgName}.${imgExt}`);
59
- ctx.logger.info(
60
- `Saving image from URL: ${imgUrl} to path: ${imgName}.${imgExt}`
61
- );
62
- const buffer = await ctx.http.get(imgUrl);
63
- if (buffer.byteLength === 0) throw new Error("Image download failed");
64
- await import_node_fs.promises.writeFile(fullImgPath, Buffer.from(buffer));
65
- return fullImgPath;
66
- }
67
-
68
- // src/forward-helper.ts
69
- async function reconstructForwardMsg(ctx, message) {
70
- return Promise.all(
71
- message.map(async (msg) => {
72
- const content = await processMessageContent(ctx, msg);
73
- return {
74
- type: "node",
75
- data: {
76
- user_id: msg.sender.user_id,
77
- nickname: msg.sender.nickname,
78
- content
79
- }
80
- };
81
- })
82
- );
83
- }
84
- async function processMessageContent(ctx, msg) {
85
- if (typeof msg.message === "string") {
86
- return msg.message;
87
- }
88
- const firstElement = msg.message[0];
89
- if (firstElement?.type === "forward") {
90
- return reconstructForwardMsg(ctx, firstElement.data.content);
91
- }
92
- return Promise.all(
93
- msg.message.map(async (element) => {
94
- if (element.type === "image") {
95
- return {
96
- ...element,
97
- data: {
98
- ...element.data,
99
- url: await saveImages(ctx, element.data)
100
- }
101
- };
102
- }
103
- return element;
104
- })
105
- );
106
- }
107
39
 
108
40
  // src/cqcode-helper.ts
109
41
  function createTextMsg(content) {
@@ -118,10 +50,7 @@ function createTextMsg(content) {
118
50
  // src/onebot-helper.ts
119
51
  async function getUserName(ctx, session, userId) {
120
52
  try {
121
- const memberInfo = await session.onebot.getGroupMemberInfo(
122
- session.channelId,
123
- userId
124
- );
53
+ const memberInfo = await session.onebot.getGroupMemberInfo(session.channelId, userId);
125
54
  return memberInfo.card || memberInfo.nickname || userId;
126
55
  } catch (error) {
127
56
  ctx.logger.warn(`\u83B7\u53D6\u7FA4\u6210\u5458\u4FE1\u606F\u5931\u8D25\uFF08userId: ${userId}\uFF09\uFF1A`, error);
@@ -129,7 +58,7 @@ async function getUserName(ctx, session, userId) {
129
58
  }
130
59
  }
131
60
 
132
- // src/msg-helper.ts
61
+ // src/cave-helper.ts
133
62
  async function sendCaveMsg(ctx, session, caveMsg) {
134
63
  const { channelId } = session;
135
64
  const content = JSON.parse(caveMsg.content);
@@ -226,9 +155,7 @@ async function sendCaveMsg(ctx, session, caveMsg) {
226
155
  const last = content.at(-1);
227
156
  const needsNewline = last?.type === "text";
228
157
  content.unshift(createTextMsg(chosen.prefix));
229
- content.push(
230
- createTextMsg(`${needsNewline ? "\n\n" : ""}${chosen.suffix}`)
231
- );
158
+ content.push(createTextMsg(`${needsNewline ? "\n\n" : ""}${chosen.suffix}`));
232
159
  await session.onebot.sendGroupMsg(channelId, content);
233
160
  }
234
161
  function formatDate(date) {
@@ -239,13 +166,117 @@ function formatDate(date) {
239
166
  });
240
167
  }
241
168
 
169
+ // src/image-helper.ts
170
+ var import_axios = __toESM(require("axios"), 1);
171
+ var import_node_fs = require("node:fs");
172
+ var import_node_path = __toESM(require("node:path"), 1);
173
+ async function saveImages(ctx, imgElement) {
174
+ const imgUrl = imgElement.url;
175
+ const originalImgName = imgElement.file;
176
+ const ext = (() => {
177
+ const i = originalImgName.lastIndexOf(".");
178
+ return i === -1 ? "png" : originalImgName.slice(i + 1).toLowerCase();
179
+ })();
180
+ const imgDir = import_node_path.default.join(ctx.baseDir, "data", "cave", "images");
181
+ const imgName = Date.now().toString();
182
+ const fullImgPath = import_node_path.default.join(imgDir, `${imgName}.${ext}`);
183
+ ctx.logger.info(`Saving image from ${imgUrl} -> ${fullImgPath}`);
184
+ try {
185
+ await import_node_fs.promises.mkdir(imgDir, { recursive: true });
186
+ const res = await import_axios.default.get(imgUrl, {
187
+ responseType: "arraybuffer",
188
+ validateStatus: () => true
189
+ });
190
+ if (res.status < 200 || res.status >= 300) {
191
+ ctx.logger.warn(`Image download failed: HTTP ${res.status}`);
192
+ return imgUrl;
193
+ }
194
+ const type = res.headers["content-type"];
195
+ if (!type || !type.startsWith("image/")) {
196
+ ctx.logger.warn(`Invalid image content-type: ${type}`);
197
+ return imgUrl;
198
+ }
199
+ const buffer = Buffer.from(res.data);
200
+ if (!buffer || buffer.length === 0) {
201
+ ctx.logger.warn("Downloaded image buffer is empty");
202
+ return imgUrl;
203
+ }
204
+ await import_node_fs.promises.writeFile(fullImgPath, buffer);
205
+ ctx.logger.info(`Image saved successfully: ${fullImgPath}`);
206
+ return fullImgPath;
207
+ } catch (err) {
208
+ ctx.logger.error(`Failed to save image: ${err}`);
209
+ return imgUrl;
210
+ }
211
+ }
212
+
213
+ // src/forward-helper.ts
214
+ async function reconstructForwardMsg(ctx, message) {
215
+ return Promise.all(
216
+ message.map(async (msg) => {
217
+ const content = await processForwardMessageContent(ctx, msg);
218
+ return {
219
+ type: "node",
220
+ data: {
221
+ user_id: msg.sender.user_id,
222
+ nickname: msg.sender.nickname,
223
+ content
224
+ }
225
+ };
226
+ })
227
+ );
228
+ }
229
+ async function processForwardMessageContent(ctx, msg) {
230
+ if (typeof msg.message === "string") {
231
+ return msg.message;
232
+ }
233
+ const firstElement = msg.message[0];
234
+ if (firstElement?.type === "forward") {
235
+ return reconstructForwardMsg(ctx, firstElement.data.content);
236
+ }
237
+ return Promise.all(
238
+ msg.message.map(async (element) => {
239
+ if (element.type === "image") {
240
+ return {
241
+ ...element,
242
+ data: {
243
+ ...element.data,
244
+ url: await saveImages(ctx, element.data)
245
+ }
246
+ };
247
+ }
248
+ return element;
249
+ })
250
+ );
251
+ }
252
+
253
+ // src/msg-helper.ts
254
+ async function processMessageContent(ctx, msg) {
255
+ return Promise.all(
256
+ msg.map(async (element) => {
257
+ if (element.type === "image") {
258
+ return {
259
+ ...element,
260
+ data: {
261
+ ...element.data,
262
+ url: await saveImages(ctx, element.data)
263
+ }
264
+ };
265
+ }
266
+ return element;
267
+ })
268
+ );
269
+ }
270
+
242
271
  // src/index.ts
272
+ var import_koishi_plugin_adapter_onebot2 = require("@pynickle/koishi-plugin-adapter-onebot");
273
+ var import_fs = __toESM(require("fs"), 1);
274
+ var import_koishi = require("koishi");
275
+ var import_node_path2 = __toESM(require("node:path"), 1);
243
276
  var name = "echo-cave";
244
277
  var inject = ["database"];
245
278
  var Config = import_koishi.Schema.object({
246
- adminMessageProtection: import_koishi.Schema.boolean().description(
247
- "\u5F00\u542F\u7BA1\u7406\u5458\u6D88\u606F\u4FDD\u62A4\uFF0C\u5F00\u542F\u540E\u7BA1\u7406\u5458\u53D1\u5E03\u7684\u6D88\u606F\u53EA\u80FD\u7531\u7BA1\u7406\u5458\u5220\u9664"
248
- ).default(false)
279
+ adminMessageProtection: import_koishi.Schema.boolean().description("\u5F00\u542F\u7BA1\u7406\u5458\u6D88\u606F\u4FDD\u62A4\uFF0C\u5F00\u542F\u540E\u7BA1\u7406\u5458\u53D1\u5E03\u7684\u6D88\u606F\u53EA\u80FD\u7531\u7BA1\u7406\u5458\u5220\u9664").default(false)
249
280
  });
250
281
  function apply(ctx, cfg) {
251
282
  const imgPath = import_node_path2.default.join(ctx.baseDir, "data", "cave", "images");
@@ -269,10 +300,9 @@ function apply(ctx, cfg) {
269
300
  unique: ["content"]
270
301
  }
271
302
  );
272
- ctx.command(
273
- "cave [id:number]",
274
- "\u968F\u673A\u83B7\u53D6 / \u83B7\u53D6\u7279\u5B9A id \u7684\u56DE\u58F0\u6D1E\u4FE1\u606F"
275
- ).action(async ({ session }, id) => await getCave(ctx, session, id));
303
+ ctx.command("cave [id:number]", "\u968F\u673A\u83B7\u53D6 / \u83B7\u53D6\u7279\u5B9A id \u7684\u56DE\u58F0\u6D1E\u4FE1\u606F").action(
304
+ async ({ session }, id) => await getCave(ctx, session, id)
305
+ );
276
306
  ctx.command("cave.echo", "\u5C06\u6D88\u606F\u5B58\u5165\u56DE\u58F0\u6D1E").action(
277
307
  async ({ session }) => await addCave(ctx, session)
278
308
  );
@@ -369,10 +399,7 @@ async function deleteCave(ctx, session, cfg, id) {
369
399
  const userAuthority = user.authority;
370
400
  const isCurrentUserAdmin = userAuthority >= 4;
371
401
  if (cfg.adminMessageProtection) {
372
- const caveUser = await ctx.database.getUser(
373
- session.platform,
374
- caveMsg.userId
375
- );
402
+ const caveUser = await ctx.database.getUser(session.platform, caveMsg.userId);
376
403
  const isCaveUserAdmin = caveUser.authority >= 4;
377
404
  if (isCaveUserAdmin && !isCurrentUserAdmin) {
378
405
  return "\u26D4 \u8BE5\u6D88\u606F\u7531\u7BA1\u7406\u5458\u53D1\u5E03\uFF0C\u5DF2\u5F00\u542F\u7BA1\u7406\u5458\u6D88\u606F\u4FDD\u62A4\uFF0C\u53EA\u6709\u7BA1\u7406\u5458\u53EF\u4EE5\u5220\u9664\u3002";
@@ -404,9 +431,14 @@ async function addCave(ctx, session) {
404
431
  content = JSON.stringify(message);
405
432
  } else {
406
433
  type = "msg";
407
- content = JSON.stringify(
408
- (await session.onebot.getMsg(messageId)).message
409
- );
434
+ const message = (await session.onebot.getMsg(messageId)).message;
435
+ let msgJson;
436
+ if (typeof message === "string") {
437
+ msgJson = import_koishi_plugin_adapter_onebot2.CQCode.parse(message);
438
+ } else {
439
+ msgJson = message;
440
+ }
441
+ content = JSON.stringify(await processMessageContent(ctx, msgJson));
410
442
  }
411
443
  await ctx.database.get("echo_cave", { content }).then((existing) => {
412
444
  if (existing) {
@@ -1,4 +1,3 @@
1
- import { Context, Session } from 'koishi';
2
- import { EchoCave } from './index';
3
- export declare function sendCaveMsg(ctx: Context, session: Session, caveMsg: EchoCave): Promise<void>;
4
- export declare function formatDate(date: Date): string;
1
+ import { CQCode } from '@pynickle/koishi-plugin-adapter-onebot';
2
+ import { Context } from 'koishi';
3
+ export declare function processMessageContent(ctx: Context, msg: CQCode[]): Promise<CQCode[]>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-echo-cave",
3
3
  "description": "Group echo cave",
4
- "version": "1.7.3",
4
+ "version": "1.7.5",
5
5
  "main": "lib/index.cjs",
6
6
  "typings": "lib/index.d.ts",
7
7
  "type": "module",
@@ -11,8 +11,9 @@
11
11
  ],
12
12
  "license": "MIT",
13
13
  "scripts": {
14
- "lint": "eslint ./src --ext .ts",
15
- "lint:fix": "eslint ./src --ext .ts --fix",
14
+ "lint": "npx oxlint ./src",
15
+ "lint:fix": "npx oxlint ./src --fix",
16
+ "fmt": "npx oxfmt ./src",
16
17
  "build": "node esbuild.config.js && tsc --emitDeclarationOnly",
17
18
  "release": "semantic-release"
18
19
  },
@@ -26,7 +27,8 @@
26
27
  "koishi": "^4.18.9"
27
28
  },
28
29
  "dependencies": {
29
- "@pynickle/koishi-plugin-adapter-onebot": "^1.0.0"
30
+ "@pynickle/koishi-plugin-adapter-onebot": "^1.0.0",
31
+ "axios": "^1.13.2"
30
32
  },
31
33
  "devDependencies": {
32
34
  "@semantic-release/changelog": "^6.0.3",
@@ -34,17 +36,13 @@
34
36
  "@semantic-release/git": "^10.0.1",
35
37
  "@semantic-release/npm": "^13.1.2",
36
38
  "@semantic-release/release-notes-generator": "^14.1.0",
37
- "@trivago/prettier-plugin-sort-imports": "^6.0.0",
38
39
  "@types/node": "^24.10.1",
39
40
  "conventional-changelog-conventionalcommits": "^9.1.0",
40
41
  "esbuild": "^0.27.0",
41
42
  "esbuild-plugin-yaml": "^0.0.1",
42
- "eslint": "^9.39.1",
43
- "eslint-config-prettier": "^10.1.8",
44
- "eslint-plugin-prettier": "^5.5.4",
45
- "prettier": "^3.7.2",
43
+ "oxfmt": "^0.16.0",
44
+ "oxlint": "^1.31.0",
46
45
  "semantic-release": "^25.0.2",
47
- "typescript": "^5.9.3",
48
- "typescript-eslint": "^8.48.0"
46
+ "typescript": "^5.9.3"
49
47
  }
50
48
  }