koishi-plugin-forward-hime 1.4.2-alpha.0 → 1.4.2-alpha.1

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,45 @@
1
+ // client/index.ts
2
+ import { send } from "@koishijs/client";
3
+ import { defineComponent, h, inject } from "vue";
4
+ var index_default = (ctx) => {
5
+ ctx.slot({
6
+ type: "plugin-details",
7
+ order: -800,
8
+ component: defineComponent({
9
+ setup() {
10
+ const current = inject(
11
+ "manager.settings.current"
12
+ );
13
+ return () => {
14
+ const plugin = current?.value;
15
+ if (!plugin || plugin.name !== "forward-hime" && !plugin.path?.includes("forward-hime")) {
16
+ return null;
17
+ }
18
+ return h(
19
+ "button",
20
+ {
21
+ class: "k-button",
22
+ onClick: async () => {
23
+ const contents = await send(
24
+ "forward-hime:get-diagnostics"
25
+ );
26
+ const url = URL.createObjectURL(
27
+ new Blob([contents], { type: "application/x-ndjson" })
28
+ );
29
+ const anchor = document.createElement("a");
30
+ anchor.href = url;
31
+ anchor.download = "forward-hime-diagnostics.jsonl";
32
+ anchor.click();
33
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
34
+ }
35
+ },
36
+ "\u4E0B\u8F7D\u8BCA\u65AD\u65E5\u5FD7"
37
+ );
38
+ };
39
+ }
40
+ })
41
+ });
42
+ };
43
+ export {
44
+ index_default as default
45
+ };
@@ -0,0 +1,2 @@
1
+ import { Context } from "koishi";
2
+ export declare function consoleInit(ctx: Context): void;
@@ -8,7 +8,7 @@ export declare function decoratorInit(cfg: ConfigSet): void;
8
8
  export declare function defaultDecorator({ head, content }: ForwardMsg): Element[];
9
9
  export declare function defaultMiddleware(session: Session): ForwardMsg;
10
10
  export declare function MsgMiddlewareCache(session: Session): Promise<void>;
11
- export declare function MsgDecorator(session: Session, node: ForwardNode): Promise<any>;
11
+ export declare function MsgDecorator(session: Session, node: ForwardNode, traceId?: string): Promise<any>;
12
12
  export declare function MsgDecoratorNoRelay(session: Session, node: ForwardNode): Promise<any>;
13
13
  export declare function MsgDecoratorFallback(session: Session, node: ForwardNode): Promise<Element[]>;
14
14
  export declare function MsgDecoratorFallbackReason(session: Session, node: ForwardNode, reason: string): Promise<Element[]>;
@@ -0,0 +1,18 @@
1
+ import { Context } from "koishi";
2
+ export interface DiagnosticEvent {
3
+ traceId: string;
4
+ phase: string;
5
+ [key: string]: unknown;
6
+ }
7
+ export declare function createTraceId(): `${string}-${string}-${string}-${string}-${string}`;
8
+ export declare function diagnosticFilename(value: unknown): string;
9
+ export declare function diagnosticMime(value: unknown): string;
10
+ export declare function diagnosticsInit(ctx: Context): void;
11
+ export declare function writeDiagnostic(event: DiagnosticEvent): void;
12
+ export declare function readDiagnosticLogs(): Promise<string>;
13
+ export declare function sanitizeError(error: unknown): {
14
+ name: string;
15
+ code: string | number;
16
+ httpStatus: number;
17
+ summary: string;
18
+ };
package/lib/index.js CHANGED
@@ -250,6 +250,99 @@ var onebot_default = {
250
250
 
251
251
  // src/relay.ts
252
252
  var import_koishi5 = require("koishi");
253
+
254
+ // src/diagnostics.ts
255
+ var import_crypto = require("crypto");
256
+ var import_promises = require("fs/promises");
257
+ var import_path = require("path");
258
+ var RETENTION_DAYS = 7;
259
+ var FILE_PATTERN = /^\d{4}-\d{2}-\d{2}\.jsonl$/;
260
+ var root = "";
261
+ var writeQueue = Promise.resolve();
262
+ var lastCleanupDate = "";
263
+ function createTraceId() {
264
+ return (0, import_crypto.randomUUID)();
265
+ }
266
+ function diagnosticFilename(value) {
267
+ if (typeof value !== "string" || /^https?:\/\//i.test(value)) return void 0;
268
+ return value.replace(/[?#].*$/, "").split(/[\\/]/).pop()?.slice(0, 120);
269
+ }
270
+ function diagnosticMime(value) {
271
+ return typeof value === "string" && /^[\w.+-]+\/[\w.+-]+$/.test(value) ? value : void 0;
272
+ }
273
+ function utcDate(timestamp = Date.now()) {
274
+ return new Date(timestamp).toISOString().slice(0, 10);
275
+ }
276
+ async function cleanup(date) {
277
+ if (date === lastCleanupDate) return;
278
+ const cutoff = Date.parse(`${date}T00:00:00.000Z`) - (RETENTION_DAYS - 1) * 864e5;
279
+ for (const filename of await (0, import_promises.readdir)(root)) {
280
+ if (!FILE_PATTERN.test(filename)) continue;
281
+ if (Date.parse(`${filename.slice(0, 10)}T00:00:00.000Z`) < cutoff) {
282
+ await (0, import_promises.rm)((0, import_path.join)(root, filename), { force: true });
283
+ }
284
+ }
285
+ lastCleanupDate = date;
286
+ }
287
+ function diagnosticsInit(ctx2) {
288
+ root = (0, import_path.join)(ctx2.baseDir, "data", "forward-hime");
289
+ writeQueue = Promise.resolve();
290
+ lastCleanupDate = "";
291
+ writeQueue = writeQueue.then(async () => {
292
+ await (0, import_promises.mkdir)(root, { recursive: true });
293
+ await cleanup(utcDate());
294
+ }).catch((error) => logger.warn("failed to initialize diagnostic log", error));
295
+ }
296
+ function writeDiagnostic(event) {
297
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
298
+ const date = timestamp.slice(0, 10);
299
+ const line = JSON.stringify({ timestamp, ...event }) + "\n";
300
+ writeQueue = writeQueue.then(async () => {
301
+ await (0, import_promises.mkdir)(root, { recursive: true });
302
+ await cleanup(date);
303
+ await (0, import_promises.appendFile)((0, import_path.join)(root, `${date}.jsonl`), line, "utf8");
304
+ }).catch((error) => logger.warn("failed to write diagnostic log", error));
305
+ }
306
+ async function readDiagnosticLogs() {
307
+ await writeQueue;
308
+ const cutoff = new Date(
309
+ Date.parse(`${utcDate()}T00:00:00.000Z`) - (RETENTION_DAYS - 1) * 864e5
310
+ ).toISOString().slice(0, 10);
311
+ const files = (await (0, import_promises.readdir)(root).catch(() => [])).filter(
312
+ (filename) => FILE_PATTERN.test(filename) && filename.slice(0, 10) >= cutoff
313
+ ).sort();
314
+ const contents = await Promise.all(
315
+ files.map((filename) => (0, import_promises.readFile)((0, import_path.join)(root, filename), "utf8"))
316
+ );
317
+ return contents.join("");
318
+ }
319
+ function sanitizeError(error) {
320
+ const value = error;
321
+ const message = typeof value?.message === "string" ? value.message : String(error);
322
+ const lowerMessage = message.toLowerCase();
323
+ let summary = "request failed";
324
+ if (lowerMessage.includes("timeout") || lowerMessage.includes("timed out")) {
325
+ summary = "request timed out";
326
+ } else if (lowerMessage.includes("denied") || lowerMessage.includes("401") || lowerMessage.includes("403")) {
327
+ summary = "request denied";
328
+ } else if (lowerMessage.includes("not found") || lowerMessage.includes("404")) {
329
+ summary = "resource not found";
330
+ } else if (lowerMessage.includes("too large")) {
331
+ summary = "media exceeds size limit";
332
+ } else if (lowerMessage.includes("network") || lowerMessage.includes("econn") || lowerMessage.includes("enotfound")) {
333
+ summary = "network error";
334
+ } else if (lowerMessage.includes("empty media")) {
335
+ summary = "empty media payload";
336
+ }
337
+ return {
338
+ name: typeof value?.name === "string" && /^[a-z][\w.-]{0,63}$/i.test(value.name) ? value.name : "Error",
339
+ code: typeof value?.code === "string" && /^[\w.-]{1,64}$/.test(value.code) || typeof value?.code === "number" ? value.code : void 0,
340
+ httpStatus: typeof value?.status === "number" ? value.status : Number(/\bstatus\s+(\d{3})\b/i.exec(message)?.[1]) || void 0,
341
+ summary
342
+ };
343
+ }
344
+
345
+ // src/relay.ts
253
346
  var DEFAULT_IMAGE_MIME = "image/jpeg";
254
347
  var DEFAULT_AUDIO_MIME = "audio/mpeg";
255
348
  var DEFAULT_VIDEO_MIME = "video/mp4";
@@ -364,9 +457,23 @@ function networkMessageFromError(error) {
364
457
  }
365
458
  return "\u7F51\u7EDC\u95EE\u9898\uFF1A\u5A92\u4F53\u6587\u4EF6\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u3002";
366
459
  }
367
- async function downloadAndRelay(element) {
460
+ async function downloadAndRelay(element, traceId, session, node) {
461
+ const startedAt = Date.now();
368
462
  const kind = normalizeMediaType(element.type);
369
463
  const src = mediaUrlFromElement(element);
464
+ const media = {
465
+ type: kind,
466
+ filename: diagnosticFilename(element.attrs?.filename),
467
+ mime: diagnosticMime(element.attrs?.mime),
468
+ size: typeof element.attrs?.size === "number" ? element.attrs.size : void 0
469
+ };
470
+ const context = {
471
+ source: session && { platform: session.platform, node: session.channelId },
472
+ target: node && { platform: node.Platform, node: node.Guild }
473
+ };
474
+ if (traceId) {
475
+ writeDiagnostic({ traceId, phase: "media-relay-start", media, ...context });
476
+ }
370
477
  if (!src) {
371
478
  throw new MediaRelayError(
372
479
  `missing media src for ${element.type}`,
@@ -377,6 +484,17 @@ async function downloadAndRelay(element) {
377
484
  const cacheKey = getCacheKey(element);
378
485
  const cacheItem = relayCache.get(cacheKey);
379
486
  if (cacheItem) {
487
+ if (traceId) {
488
+ writeDiagnostic({
489
+ traceId,
490
+ phase: "media-relay-result",
491
+ status: "cache-hit",
492
+ bytes: cacheItem.buffer.length,
493
+ mime: diagnosticMime(cacheItem.mime),
494
+ durationMs: Date.now() - startedAt,
495
+ ...context
496
+ });
497
+ }
380
498
  return relayElementFromCache(cacheItem);
381
499
  }
382
500
  const timeoutSignal = typeof AbortSignal.timeout === "function" ? AbortSignal.timeout(relayConfig.RequestTimeoutSec * 1e3) : void 0;
@@ -438,9 +556,21 @@ async function downloadAndRelay(element) {
438
556
  buffer,
439
557
  filename
440
558
  });
559
+ if (traceId) {
560
+ writeDiagnostic({
561
+ traceId,
562
+ phase: "media-relay-result",
563
+ status: "success",
564
+ media,
565
+ bytes: buffer.length,
566
+ mime: diagnosticMime(mime),
567
+ ...context,
568
+ durationMs: Date.now() - startedAt
569
+ });
570
+ }
441
571
  return relayed;
442
572
  }
443
- async function relayForwardContent(content) {
573
+ async function relayForwardContent(content, traceId, session, node) {
444
574
  if (!relayConfig.Enabled) {
445
575
  return content;
446
576
  }
@@ -450,9 +580,24 @@ async function relayForwardContent(content) {
450
580
  newContent.push(element);
451
581
  continue;
452
582
  }
583
+ const startedAt = Date.now();
453
584
  try {
454
- newContent.push(await downloadAndRelay(element));
585
+ newContent.push(await downloadAndRelay(element, traceId, session, node));
455
586
  } catch (error) {
587
+ if (traceId) {
588
+ writeDiagnostic({
589
+ traceId,
590
+ phase: "media-relay-result",
591
+ status: "error",
592
+ error: sanitizeError(error),
593
+ durationMs: Date.now() - startedAt,
594
+ source: session && {
595
+ platform: session.platform,
596
+ node: session.channelId
597
+ },
598
+ target: node && { platform: node.Platform, node: node.Guild }
599
+ });
600
+ }
456
601
  throw new MediaRelayError(
457
602
  error instanceof Error ? error.message : "relay failed",
458
603
  networkMessageFromError(error)
@@ -463,29 +608,63 @@ async function relayForwardContent(content) {
463
608
  }
464
609
 
465
610
  // src/message.ts
466
- async function MessageSendWithDecorator(ctx2, node, session, Deco) {
611
+ async function MessageSendWithDecorator(ctx2, node, session, Deco, traceId, attempt) {
612
+ const startedAt = Date.now();
467
613
  const uuid = session.channelId + ":" + session.messageId;
468
- const content = await Deco(session, node);
469
- await ctx2.bots[`${node.Platform}:${node.BotID}`].sendMessage(node.Guild, content).then((res) => {
470
- const mc = {
471
- platform: node.Platform,
472
- bot: node.BotID,
473
- guild: node.Guild,
474
- msgid: res[0],
475
- uuid
476
- };
477
- if (!mc.msgid) {
478
- throw new Error(`Empty Message ID`);
479
- } else {
480
- msgCache(mc);
481
- logger.debug(`[MessageForward] to ${mc.platform} ${mc.uuid}`);
614
+ writeDiagnostic({
615
+ traceId,
616
+ phase: "send-attempt",
617
+ attempt,
618
+ source: { platform: session.platform, node: session.channelId },
619
+ target: { platform: node.Platform, node: node.Guild },
620
+ elementTypes: session.elements.map((element) => element.type)
621
+ });
622
+ try {
623
+ const content = await Deco(session, node, traceId);
624
+ const res = await ctx2.bots[`${node.Platform}:${node.BotID}`].sendMessage(
625
+ node.Guild,
626
+ content
627
+ );
628
+ {
629
+ const mc = {
630
+ platform: node.Platform,
631
+ bot: node.BotID,
632
+ guild: node.Guild,
633
+ msgid: res[0],
634
+ uuid
635
+ };
636
+ if (!mc.msgid) {
637
+ throw new Error(`Empty Message ID`);
638
+ } else {
639
+ msgCache(mc);
640
+ logger.debug(`[MessageForward] to ${mc.platform} ${mc.uuid}`);
641
+ }
482
642
  }
483
- }).catch((error) => {
643
+ writeDiagnostic({
644
+ traceId,
645
+ phase: "send-result",
646
+ attempt,
647
+ status: "success",
648
+ durationMs: Date.now() - startedAt,
649
+ source: { platform: session.platform, node: session.channelId },
650
+ target: { platform: node.Platform, node: node.Guild }
651
+ });
652
+ } catch (error) {
653
+ writeDiagnostic({
654
+ traceId,
655
+ phase: "send-result",
656
+ attempt,
657
+ status: "error",
658
+ durationMs: Date.now() - startedAt,
659
+ source: { platform: session.platform, node: session.channelId },
660
+ target: { platform: node.Platform, node: node.Guild },
661
+ error: sanitizeError(error)
662
+ });
484
663
  logger.error(
485
664
  `ERROR:<MessageSendWithDecorator ${node.Platform}> ctx=${ctx2} ${error}`
486
665
  );
487
666
  throw error;
488
- });
667
+ }
489
668
  }
490
669
  function sessionTypeArray(session) {
491
670
  let contentTypes = "|";
@@ -495,9 +674,34 @@ function sessionTypeArray(session) {
495
674
  return contentTypes;
496
675
  }
497
676
  async function MessageForward(ctx2, node, session, timeoutSec, relayEnabled) {
677
+ const traceId = createTraceId();
678
+ const source = { platform: session.platform, node: session.channelId };
679
+ const target = { platform: node.Platform, node: node.Guild };
498
680
  if (!botExistsCheck(ctx2, node)) {
681
+ writeDiagnostic({
682
+ traceId,
683
+ phase: "forward-result",
684
+ status: "bot-missing",
685
+ source,
686
+ target
687
+ });
499
688
  return;
500
689
  }
690
+ writeDiagnostic({
691
+ traceId,
692
+ phase: "forward-start",
693
+ source,
694
+ target,
695
+ elementTypes: session.elements.map((element) => element.type),
696
+ media: session.elements.filter(
697
+ (element) => ["img", "image", "audio", "video", "file"].includes(element.type)
698
+ ).map((element) => ({
699
+ type: element.type,
700
+ filename: diagnosticFilename(element.attrs?.filename),
701
+ mime: diagnosticMime(element.attrs?.mime),
702
+ size: typeof element.attrs?.size === "number" ? element.attrs.size : void 0
703
+ }))
704
+ });
501
705
  const timeoutMs = (timeoutSec ?? 30) * 1e3;
502
706
  const deco = relayEnabled !== false ? MsgDecorator : MsgDecoratorNoRelay;
503
707
  function warnIfSlow(promise) {
@@ -509,8 +713,16 @@ async function MessageForward(ctx2, node, session, timeoutSec, relayEnabled) {
509
713
  return promise.finally(() => clearTimeout(timer));
510
714
  }
511
715
  function sendDegraded(reason) {
716
+ writeDiagnostic({ traceId, phase: "forward-degraded", source, target });
512
717
  const fallbackDeco = reason ? (fallbackSession, fallbackNode) => MsgDecoratorFallbackReason(fallbackSession, fallbackNode, reason) : MsgDecoratorFallback;
513
- MessageSendWithDecorator(ctx2, node, session, fallbackDeco).catch((error) => {
718
+ MessageSendWithDecorator(
719
+ ctx2,
720
+ node,
721
+ session,
722
+ fallbackDeco,
723
+ traceId,
724
+ "fallback"
725
+ ).catch((error) => {
514
726
  logger.error(
515
727
  `ERROR:<MessageSendFallback ${node.Platform}> ctx=${ctx2} ${sessionTypeArray(session)} ${error}`
516
728
  );
@@ -522,28 +734,43 @@ async function MessageForward(ctx2, node, session, timeoutSec, relayEnabled) {
522
734
  }
523
735
  return void 0;
524
736
  }
525
- warnIfSlow(MessageSendWithDecorator(ctx2, node, session, deco)).catch(
526
- (firstError) => {
527
- logger.error(
528
- `ERROR:<MessageSend ${node.Platform}> ctx=${ctx2} ${sessionTypeArray(session)} ${firstError}`
737
+ const traceableDeco = (sourceSession, targetNode, id) => deco(sourceSession, targetNode, id);
738
+ warnIfSlow(
739
+ MessageSendWithDecorator(
740
+ ctx2,
741
+ node,
742
+ session,
743
+ traceableDeco,
744
+ traceId,
745
+ relayEnabled === false ? "direct" : "relay"
746
+ )
747
+ ).catch((firstError) => {
748
+ logger.error(
749
+ `ERROR:<MessageSend ${node.Platform}> ctx=${ctx2} ${sessionTypeArray(session)} ${firstError}`
750
+ );
751
+ if (relayEnabled !== false && firstError instanceof MediaRelayError) {
752
+ logger.info(
753
+ `[MessageForward] relay failed, retrying without relay: ${node.Platform}`
529
754
  );
530
- if (relayEnabled !== false && firstError instanceof MediaRelayError) {
531
- logger.info(
532
- `[MessageForward] relay failed, retrying without relay: ${node.Platform}`
755
+ warnIfSlow(
756
+ MessageSendWithDecorator(
757
+ ctx2,
758
+ node,
759
+ session,
760
+ MsgDecoratorNoRelay,
761
+ traceId,
762
+ "direct-retry"
763
+ )
764
+ ).catch((secondError) => {
765
+ logger.error(
766
+ `ERROR:<MessageSendDirect ${node.Platform}> ctx=${ctx2} ${sessionTypeArray(session)} ${secondError}`
533
767
  );
534
- warnIfSlow(
535
- MessageSendWithDecorator(ctx2, node, session, MsgDecoratorNoRelay)
536
- ).catch((secondError) => {
537
- logger.error(
538
- `ERROR:<MessageSendDirect ${node.Platform}> ctx=${ctx2} ${sessionTypeArray(session)} ${secondError}`
539
- );
540
- sendDegraded(reasonFromError(secondError));
541
- });
542
- } else {
543
- sendDegraded(reasonFromError(firstError));
544
- }
768
+ sendDegraded(reasonFromError(secondError));
769
+ });
770
+ } else {
771
+ sendDegraded(reasonFromError(firstError));
545
772
  }
546
- );
773
+ });
547
774
  }
548
775
  async function MessageDelete(ctx2, msg) {
549
776
  if (!botExistsCheck(ctx2, { Platform: msg.platform, BotID: msg.bot, Guild: msg.guild })) {
@@ -620,7 +847,7 @@ async function MsgMiddlewareCache(session) {
620
847
  msgMiddleCacheAppend({ UUID: MsgUUIDFromSession(session), msg: elems });
621
848
  logger.debug(`[msgMiddleCache] CACHED`);
622
849
  }
623
- async function MsgDecorator(session, node) {
850
+ async function MsgDecorator(session, node, traceId) {
624
851
  let elems;
625
852
  const _platform_out = decorators_exports[node.Platform];
626
853
  const elemCache = msgMiddleCacheFind(MsgUUIDFromSession(session));
@@ -636,7 +863,7 @@ async function MsgDecorator(session, node) {
636
863
  }
637
864
  elems = {
638
865
  head: elems.head,
639
- content: await relayForwardContent(elems.content)
866
+ content: await relayForwardContent(elems.content, traceId, session, node)
640
867
  };
641
868
  if (_platform_out && typeof _platform_out.Decorator === "function") {
642
869
  return _platform_out.Decorator(elems);
@@ -692,7 +919,7 @@ async function MsgDecoratorFallbackReason(session, node, reason) {
692
919
  return defaultDecoratorFallback(elems, reason);
693
920
  }
694
921
  async function atTranslator(session, _, { head, content }) {
695
- const newMsg = await new Promise((resolve) => {
922
+ const newMsg = await new Promise((resolve2) => {
696
923
  const newContent = [];
697
924
  for (const key in content) {
698
925
  const element = content[key];
@@ -706,7 +933,7 @@ async function atTranslator(session, _, { head, content }) {
706
933
  newContent.push(element);
707
934
  }
708
935
  }
709
- resolve({ head, content: newContent });
936
+ resolve2({ head, content: newContent });
710
937
  });
711
938
  return newMsg;
712
939
  }
@@ -728,6 +955,21 @@ async function quoteTranslator(session, node, { head, content }) {
728
955
  return { head, content };
729
956
  }
730
957
 
958
+ // src/console.ts
959
+ var import_path2 = require("path");
960
+ function consoleInit(ctx2) {
961
+ ctx2.inject(["console"], (ctx3) => {
962
+ const console = ctx3.console;
963
+ console.addListener("forward-hime:get-diagnostics", readDiagnosticLogs, {
964
+ authority: 4
965
+ });
966
+ console.addEntry({
967
+ dev: (0, import_path2.resolve)(__dirname, "../client/index.ts"),
968
+ prod: (0, import_path2.resolve)(__dirname, "client")
969
+ });
970
+ });
971
+ }
972
+
731
973
  // src/index.ts
732
974
  var name = `forward hime - \u8F6C\u53D1\u59EC`;
733
975
  var usage = `
@@ -743,11 +985,13 @@ var usage = `
743
985
  ---`;
744
986
  var reusable = true;
745
987
  var inject = {
746
- optional: ["cache"]
988
+ optional: ["cache", "console"]
747
989
  };
748
990
  var Config = createConfig();
749
991
  function apply(ctx2, cfg) {
750
992
  loggerInit(ctx2);
993
+ diagnosticsInit(ctx2);
994
+ consoleInit(ctx2);
751
995
  msgCacheInit(ctx2, cfg);
752
996
  decoratorInit(cfg);
753
997
  ctx2.on("message-created", async (session) => {
package/lib/relay.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { Element } from "koishi";
2
2
  import { ConfigSet } from "./config";
3
+ import { Session } from "koishi";
4
+ import { ForwardNode } from "./config";
3
5
  export declare class MediaRelayError extends Error {
4
6
  userMessage: string;
5
7
  constructor(message: string, userMessage: string);
6
8
  }
7
9
  export declare function relayInit(cfg: ConfigSet): void;
8
- export declare function relayForwardContent(content: Element[]): Promise<Element[]>;
10
+ export declare function relayForwardContent(content: Element[], traceId?: string, session?: Session, node?: ForwardNode): Promise<Element[]>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-forward-hime",
3
3
  "description": "多群组消息互通",
4
- "version": "1.4.2-alpha.0",
4
+ "version": "1.4.2-alpha.1",
5
5
  "author": {
6
6
  "name": "xianii",
7
7
  "email": "jiyucheng007@gmail.com"
@@ -57,7 +57,8 @@
57
57
  },
58
58
  "scripts": {
59
59
  "prepare": "husky",
60
- "build": "rm -f tsconfig.tsbuildinfo && rm -rf lib && tsc -b && esbuild src/index.ts --bundle --platform=node --packages=external --outfile=lib/index.js",
60
+ "build": "rm -f tsconfig.tsbuildinfo && rm -rf lib && tsc -b && esbuild src/index.ts --bundle --platform=node --packages=external --outfile=lib/index.js && esbuild client/index.ts --bundle --platform=browser --format=esm --packages=external --outfile=lib/client/index.js",
61
+ "test": "node --test",
61
62
  "eslint": "eslint \"src/**/*.{ts,tsx}\"",
62
63
  "format": "prettier --write .",
63
64
  "pub": "npm publish --access public"