@napuketto/loader 0.0.14 → 0.0.15
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/dist/host/self-host.cjs +157 -24
- package/dist/index.cjs +177 -0
- package/dist/index.d.cts +342 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +342 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +167 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/dist/host/self-host.cjs
CHANGED
|
@@ -25,6 +25,7 @@ let node_path = require("node:path");
|
|
|
25
25
|
let node_process = require("node:process");
|
|
26
26
|
node_process = __toESM(node_process, 1);
|
|
27
27
|
let node_os = require("node:os");
|
|
28
|
+
let zod = require("zod");
|
|
28
29
|
let node_readline = require("node:readline");
|
|
29
30
|
//#region src/instance-lock.ts
|
|
30
31
|
/**
|
|
@@ -459,20 +460,156 @@ function errorCodeOf(err) {
|
|
|
459
460
|
}
|
|
460
461
|
return "UNKNOWN";
|
|
461
462
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
"
|
|
467
|
-
"
|
|
468
|
-
"
|
|
469
|
-
"
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
"
|
|
474
|
-
"
|
|
475
|
-
"
|
|
463
|
+
/** 引导阶段(status 消息)。 */
|
|
464
|
+
const IpcBootPhaseSchema = zod.z.enum([
|
|
465
|
+
"booting",
|
|
466
|
+
"dlopening",
|
|
467
|
+
"logging",
|
|
468
|
+
"sessioning",
|
|
469
|
+
"ready",
|
|
470
|
+
"failed"
|
|
471
|
+
]);
|
|
472
|
+
/** 结构化日志级别(pino level)。 */
|
|
473
|
+
const IpcLogLevelSchema = zod.z.enum([
|
|
474
|
+
"trace",
|
|
475
|
+
"debug",
|
|
476
|
+
"info",
|
|
477
|
+
"warn",
|
|
478
|
+
"error",
|
|
479
|
+
"fatal"
|
|
480
|
+
]);
|
|
481
|
+
/** 登录状态(与 kernel LoginState 结构等价)。 */
|
|
482
|
+
const LoginStateSchema = zod.z.enum([
|
|
483
|
+
"idle",
|
|
484
|
+
"waiting_scan",
|
|
485
|
+
"scanned",
|
|
486
|
+
"logged_in",
|
|
487
|
+
"failed"
|
|
488
|
+
]);
|
|
489
|
+
/** selfInfo(与 kernel SelfInfo 结构等价)。 */
|
|
490
|
+
const SelfInfoSchema = zod.z.object({
|
|
491
|
+
uin: zod.z.string(),
|
|
492
|
+
uid: zod.z.string(),
|
|
493
|
+
nick: zod.z.string()
|
|
494
|
+
});
|
|
495
|
+
/** status 消息 payload。 */
|
|
496
|
+
const IpcStatusPayloadSchema = zod.z.object({
|
|
497
|
+
phase: IpcBootPhaseSchema,
|
|
498
|
+
message: zod.z.string().optional(),
|
|
499
|
+
error: zod.z.object({
|
|
500
|
+
code: zod.z.string(),
|
|
501
|
+
message: zod.z.string()
|
|
502
|
+
}).optional()
|
|
503
|
+
});
|
|
504
|
+
/** login 消息 payload。 */
|
|
505
|
+
const IpcLoginPayloadSchema = zod.z.object({
|
|
506
|
+
state: LoginStateSchema,
|
|
507
|
+
selfInfo: SelfInfoSchema.optional(),
|
|
508
|
+
/** 失败原因(state=failed 时;如「登录超时,请刷新页面重试」)。 */
|
|
509
|
+
message: zod.z.string().optional()
|
|
510
|
+
});
|
|
511
|
+
/** event 消息 payload(kernel 事件通道形状,翻译层按 service/name 断言具体类型)。 */
|
|
512
|
+
const IpcEventPayloadSchema = zod.z.object({
|
|
513
|
+
service: zod.z.string(),
|
|
514
|
+
name: zod.z.string(),
|
|
515
|
+
args: zod.z.array(zod.z.unknown())
|
|
516
|
+
});
|
|
517
|
+
/** log 消息 payload。 */
|
|
518
|
+
const IpcLogPayloadSchema = zod.z.object({
|
|
519
|
+
level: IpcLogLevelSchema,
|
|
520
|
+
message: zod.z.string()
|
|
521
|
+
});
|
|
522
|
+
/** 动作响应 payload(result 消息)。 */
|
|
523
|
+
const IpcResultPayloadSchema = zod.z.union([zod.z.object({
|
|
524
|
+
ok: zod.z.literal(true),
|
|
525
|
+
value: zod.z.unknown().optional()
|
|
526
|
+
}), zod.z.object({
|
|
527
|
+
ok: zod.z.literal(false),
|
|
528
|
+
error: zod.z.object({
|
|
529
|
+
code: zod.z.string(),
|
|
530
|
+
message: zod.z.string()
|
|
531
|
+
})
|
|
532
|
+
})]);
|
|
533
|
+
/** 动作请求 payload(action 消息)。 */
|
|
534
|
+
const IpcActionPayloadSchema = zod.z.object({
|
|
535
|
+
action: zod.z.string(),
|
|
536
|
+
params: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
537
|
+
});
|
|
538
|
+
/** 控制指令 payload(control 消息,父→子)。 */
|
|
539
|
+
const IpcControlPayloadSchema = zod.z.union([
|
|
540
|
+
zod.z.object({ command: zod.z.literal("stop") }),
|
|
541
|
+
zod.z.object({ command: zod.z.literal("restart") }),
|
|
542
|
+
zod.z.object({
|
|
543
|
+
command: zod.z.literal("login"),
|
|
544
|
+
uin: zod.z.string().optional(),
|
|
545
|
+
qr: zod.z.boolean().optional()
|
|
546
|
+
})
|
|
547
|
+
]);
|
|
548
|
+
const IpcStatusMessageSchema = zod.z.object({
|
|
549
|
+
v: zod.z.literal(1),
|
|
550
|
+
type: zod.z.literal("status"),
|
|
551
|
+
payload: IpcStatusPayloadSchema
|
|
552
|
+
});
|
|
553
|
+
const IpcLoginMessageSchema = zod.z.object({
|
|
554
|
+
v: zod.z.literal(1),
|
|
555
|
+
type: zod.z.literal("login"),
|
|
556
|
+
payload: IpcLoginPayloadSchema
|
|
557
|
+
});
|
|
558
|
+
const IpcQrMessageSchema = zod.z.object({
|
|
559
|
+
v: zod.z.literal(1),
|
|
560
|
+
type: zod.z.literal("qr"),
|
|
561
|
+
payload: zod.z.object({
|
|
562
|
+
pngBase64: zod.z.string(),
|
|
563
|
+
qrcodeUrl: zod.z.string()
|
|
564
|
+
})
|
|
565
|
+
});
|
|
566
|
+
const IpcEventMessageSchema = zod.z.object({
|
|
567
|
+
v: zod.z.literal(1),
|
|
568
|
+
type: zod.z.literal("event"),
|
|
569
|
+
payload: IpcEventPayloadSchema
|
|
570
|
+
});
|
|
571
|
+
const IpcResultMessageSchema = zod.z.object({
|
|
572
|
+
v: zod.z.literal(1),
|
|
573
|
+
type: zod.z.literal("result"),
|
|
574
|
+
id: zod.z.number(),
|
|
575
|
+
payload: IpcResultPayloadSchema
|
|
576
|
+
});
|
|
577
|
+
const IpcLogMessageSchema = zod.z.object({
|
|
578
|
+
v: zod.z.literal(1),
|
|
579
|
+
type: zod.z.literal("log"),
|
|
580
|
+
payload: IpcLogPayloadSchema
|
|
581
|
+
});
|
|
582
|
+
const IpcPingMessageSchema = zod.z.object({
|
|
583
|
+
v: zod.z.literal(1),
|
|
584
|
+
type: zod.z.literal("ping")
|
|
585
|
+
});
|
|
586
|
+
const IpcPongMessageSchema = zod.z.object({
|
|
587
|
+
v: zod.z.literal(1),
|
|
588
|
+
type: zod.z.literal("pong")
|
|
589
|
+
});
|
|
590
|
+
const IpcActionMessageSchema = zod.z.object({
|
|
591
|
+
v: zod.z.literal(1),
|
|
592
|
+
type: zod.z.literal("action"),
|
|
593
|
+
id: zod.z.number(),
|
|
594
|
+
payload: IpcActionPayloadSchema
|
|
595
|
+
});
|
|
596
|
+
const IpcControlMessageSchema = zod.z.object({
|
|
597
|
+
v: zod.z.literal(1),
|
|
598
|
+
type: zod.z.literal("control"),
|
|
599
|
+
payload: IpcControlPayloadSchema
|
|
600
|
+
});
|
|
601
|
+
/** IPC 消息判别联合(协议边界,运行时经 safeParse 校验)。 */
|
|
602
|
+
const IpcMessageSchema = zod.z.discriminatedUnion("type", [
|
|
603
|
+
IpcStatusMessageSchema,
|
|
604
|
+
IpcLoginMessageSchema,
|
|
605
|
+
IpcQrMessageSchema,
|
|
606
|
+
IpcEventMessageSchema,
|
|
607
|
+
IpcResultMessageSchema,
|
|
608
|
+
IpcLogMessageSchema,
|
|
609
|
+
IpcPingMessageSchema,
|
|
610
|
+
IpcPongMessageSchema,
|
|
611
|
+
IpcActionMessageSchema,
|
|
612
|
+
IpcControlMessageSchema
|
|
476
613
|
]);
|
|
477
614
|
//#endregion
|
|
478
615
|
//#region src/host/ipc/ipc-sender.ts
|
|
@@ -615,22 +752,18 @@ function attachIpcServices(actions, services) {
|
|
|
615
752
|
/**
|
|
616
753
|
* ipc-codec.ts:IPC 消息编解码(JSON 行协议,与 koishi 插件侧 src/ipc/codec.ts 对齐)。
|
|
617
754
|
*
|
|
618
|
-
* 每行一条 JSON 消息,`\n`
|
|
619
|
-
*
|
|
755
|
+
* 每行一条 JSON 消息,`\n` 结尾。解码用 IpcMessageSchema.safeParse 校验:
|
|
756
|
+
* 非法行 / 空行 / v 不匹配 / type 未知 / payload 形状非法 → null,调用方忽略,
|
|
757
|
+
* 不崩通道。
|
|
620
758
|
*/
|
|
621
|
-
/**
|
|
622
|
-
function isIpcMessage(value) {
|
|
623
|
-
if (typeof value !== "object" || value === null) return false;
|
|
624
|
-
const record = value;
|
|
625
|
-
return record["v"] === 1 && typeof record["type"] === "string" && IPC_MESSAGE_TYPES.has(record["type"]);
|
|
626
|
-
}
|
|
627
|
-
/** 解码一行 JSON;非法行/空行返回 null。 */
|
|
759
|
+
/** 解码一行 JSON;非法行/空行/形状不合法返回 null。 */
|
|
628
760
|
function decodeIpcMessage(line) {
|
|
629
761
|
const trimmed = line.trim();
|
|
630
762
|
if (trimmed === "") return null;
|
|
631
763
|
try {
|
|
632
764
|
const parsed = JSON.parse(trimmed);
|
|
633
|
-
|
|
765
|
+
const result = IpcMessageSchema.safeParse(parsed);
|
|
766
|
+
return result.success ? result.data : null;
|
|
634
767
|
} catch {
|
|
635
768
|
return null;
|
|
636
769
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
|
+
let zod = require("zod");
|
|
24
25
|
let node_fs = require("node:fs");
|
|
25
26
|
let node_path = require("node:path");
|
|
26
27
|
let node_process = require("node:process");
|
|
@@ -30,6 +31,171 @@ let node_url = require("node:url");
|
|
|
30
31
|
let node_fs_promises = require("node:fs/promises");
|
|
31
32
|
let node_crypto = require("node:crypto");
|
|
32
33
|
let node_https = require("node:https");
|
|
34
|
+
//#region src/host/ipc/ipc-types.ts
|
|
35
|
+
/**
|
|
36
|
+
* ipc-types.ts:IPC 协议消息(koishi 插件 ↔ self-host 子进程,单一来源)。
|
|
37
|
+
*
|
|
38
|
+
* 协议契约(koishi 插件 design.md §5.6):`{ v, type, id?, payload }` JSON 行。
|
|
39
|
+
* 用 zod v4 定义单一 schema,两侧(loader host + koishi 插件)import 同一份:
|
|
40
|
+
* 类型经 z.infer 派生、运行时经 safeParse 校验,消除「两份手写 types.ts」漂移。
|
|
41
|
+
*
|
|
42
|
+
* 领域字段(LoginState / SelfInfo / QrCodeData)与 kernel 同名类型结构等价,
|
|
43
|
+
* 在协议边界内联为 zod schema(kernel 不依赖 zod,故不在 kernel 定义)。
|
|
44
|
+
*/
|
|
45
|
+
/** IPC 协议版本(解码校验)。 */
|
|
46
|
+
const IPC_VERSION = 1;
|
|
47
|
+
/** 引导阶段(status 消息)。 */
|
|
48
|
+
const IpcBootPhaseSchema = zod.z.enum([
|
|
49
|
+
"booting",
|
|
50
|
+
"dlopening",
|
|
51
|
+
"logging",
|
|
52
|
+
"sessioning",
|
|
53
|
+
"ready",
|
|
54
|
+
"failed"
|
|
55
|
+
]);
|
|
56
|
+
/** 结构化日志级别(pino level)。 */
|
|
57
|
+
const IpcLogLevelSchema = zod.z.enum([
|
|
58
|
+
"trace",
|
|
59
|
+
"debug",
|
|
60
|
+
"info",
|
|
61
|
+
"warn",
|
|
62
|
+
"error",
|
|
63
|
+
"fatal"
|
|
64
|
+
]);
|
|
65
|
+
/** 登录状态(与 kernel LoginState 结构等价)。 */
|
|
66
|
+
const LoginStateSchema = zod.z.enum([
|
|
67
|
+
"idle",
|
|
68
|
+
"waiting_scan",
|
|
69
|
+
"scanned",
|
|
70
|
+
"logged_in",
|
|
71
|
+
"failed"
|
|
72
|
+
]);
|
|
73
|
+
/** selfInfo(与 kernel SelfInfo 结构等价)。 */
|
|
74
|
+
const SelfInfoSchema = zod.z.object({
|
|
75
|
+
uin: zod.z.string(),
|
|
76
|
+
uid: zod.z.string(),
|
|
77
|
+
nick: zod.z.string()
|
|
78
|
+
});
|
|
79
|
+
/** status 消息 payload。 */
|
|
80
|
+
const IpcStatusPayloadSchema = zod.z.object({
|
|
81
|
+
phase: IpcBootPhaseSchema,
|
|
82
|
+
message: zod.z.string().optional(),
|
|
83
|
+
error: zod.z.object({
|
|
84
|
+
code: zod.z.string(),
|
|
85
|
+
message: zod.z.string()
|
|
86
|
+
}).optional()
|
|
87
|
+
});
|
|
88
|
+
/** login 消息 payload。 */
|
|
89
|
+
const IpcLoginPayloadSchema = zod.z.object({
|
|
90
|
+
state: LoginStateSchema,
|
|
91
|
+
selfInfo: SelfInfoSchema.optional(),
|
|
92
|
+
/** 失败原因(state=failed 时;如「登录超时,请刷新页面重试」)。 */
|
|
93
|
+
message: zod.z.string().optional()
|
|
94
|
+
});
|
|
95
|
+
/** event 消息 payload(kernel 事件通道形状,翻译层按 service/name 断言具体类型)。 */
|
|
96
|
+
const IpcEventPayloadSchema = zod.z.object({
|
|
97
|
+
service: zod.z.string(),
|
|
98
|
+
name: zod.z.string(),
|
|
99
|
+
args: zod.z.array(zod.z.unknown())
|
|
100
|
+
});
|
|
101
|
+
/** log 消息 payload。 */
|
|
102
|
+
const IpcLogPayloadSchema = zod.z.object({
|
|
103
|
+
level: IpcLogLevelSchema,
|
|
104
|
+
message: zod.z.string()
|
|
105
|
+
});
|
|
106
|
+
/** 动作响应 payload(result 消息)。 */
|
|
107
|
+
const IpcResultPayloadSchema = zod.z.union([zod.z.object({
|
|
108
|
+
ok: zod.z.literal(true),
|
|
109
|
+
value: zod.z.unknown().optional()
|
|
110
|
+
}), zod.z.object({
|
|
111
|
+
ok: zod.z.literal(false),
|
|
112
|
+
error: zod.z.object({
|
|
113
|
+
code: zod.z.string(),
|
|
114
|
+
message: zod.z.string()
|
|
115
|
+
})
|
|
116
|
+
})]);
|
|
117
|
+
/** 动作请求 payload(action 消息)。 */
|
|
118
|
+
const IpcActionPayloadSchema = zod.z.object({
|
|
119
|
+
action: zod.z.string(),
|
|
120
|
+
params: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
121
|
+
});
|
|
122
|
+
/** 控制指令 payload(control 消息,父→子)。 */
|
|
123
|
+
const IpcControlPayloadSchema = zod.z.union([
|
|
124
|
+
zod.z.object({ command: zod.z.literal("stop") }),
|
|
125
|
+
zod.z.object({ command: zod.z.literal("restart") }),
|
|
126
|
+
zod.z.object({
|
|
127
|
+
command: zod.z.literal("login"),
|
|
128
|
+
uin: zod.z.string().optional(),
|
|
129
|
+
qr: zod.z.boolean().optional()
|
|
130
|
+
})
|
|
131
|
+
]);
|
|
132
|
+
const IpcStatusMessageSchema = zod.z.object({
|
|
133
|
+
v: zod.z.literal(1),
|
|
134
|
+
type: zod.z.literal("status"),
|
|
135
|
+
payload: IpcStatusPayloadSchema
|
|
136
|
+
});
|
|
137
|
+
const IpcLoginMessageSchema = zod.z.object({
|
|
138
|
+
v: zod.z.literal(1),
|
|
139
|
+
type: zod.z.literal("login"),
|
|
140
|
+
payload: IpcLoginPayloadSchema
|
|
141
|
+
});
|
|
142
|
+
const IpcQrMessageSchema = zod.z.object({
|
|
143
|
+
v: zod.z.literal(1),
|
|
144
|
+
type: zod.z.literal("qr"),
|
|
145
|
+
payload: zod.z.object({
|
|
146
|
+
pngBase64: zod.z.string(),
|
|
147
|
+
qrcodeUrl: zod.z.string()
|
|
148
|
+
})
|
|
149
|
+
});
|
|
150
|
+
const IpcEventMessageSchema = zod.z.object({
|
|
151
|
+
v: zod.z.literal(1),
|
|
152
|
+
type: zod.z.literal("event"),
|
|
153
|
+
payload: IpcEventPayloadSchema
|
|
154
|
+
});
|
|
155
|
+
const IpcResultMessageSchema = zod.z.object({
|
|
156
|
+
v: zod.z.literal(1),
|
|
157
|
+
type: zod.z.literal("result"),
|
|
158
|
+
id: zod.z.number(),
|
|
159
|
+
payload: IpcResultPayloadSchema
|
|
160
|
+
});
|
|
161
|
+
const IpcLogMessageSchema = zod.z.object({
|
|
162
|
+
v: zod.z.literal(1),
|
|
163
|
+
type: zod.z.literal("log"),
|
|
164
|
+
payload: IpcLogPayloadSchema
|
|
165
|
+
});
|
|
166
|
+
const IpcPingMessageSchema = zod.z.object({
|
|
167
|
+
v: zod.z.literal(1),
|
|
168
|
+
type: zod.z.literal("ping")
|
|
169
|
+
});
|
|
170
|
+
const IpcPongMessageSchema = zod.z.object({
|
|
171
|
+
v: zod.z.literal(1),
|
|
172
|
+
type: zod.z.literal("pong")
|
|
173
|
+
});
|
|
174
|
+
const IpcActionMessageSchema = zod.z.object({
|
|
175
|
+
v: zod.z.literal(1),
|
|
176
|
+
type: zod.z.literal("action"),
|
|
177
|
+
id: zod.z.number(),
|
|
178
|
+
payload: IpcActionPayloadSchema
|
|
179
|
+
});
|
|
180
|
+
const IpcControlMessageSchema = zod.z.object({
|
|
181
|
+
v: zod.z.literal(1),
|
|
182
|
+
type: zod.z.literal("control"),
|
|
183
|
+
payload: IpcControlPayloadSchema
|
|
184
|
+
});
|
|
185
|
+
/** IPC 消息判别联合(协议边界,运行时经 safeParse 校验)。 */
|
|
186
|
+
const IpcMessageSchema = zod.z.discriminatedUnion("type", [
|
|
187
|
+
IpcStatusMessageSchema,
|
|
188
|
+
IpcLoginMessageSchema,
|
|
189
|
+
IpcQrMessageSchema,
|
|
190
|
+
IpcEventMessageSchema,
|
|
191
|
+
IpcResultMessageSchema,
|
|
192
|
+
IpcLogMessageSchema,
|
|
193
|
+
IpcPingMessageSchema,
|
|
194
|
+
IpcPongMessageSchema,
|
|
195
|
+
IpcActionMessageSchema,
|
|
196
|
+
IpcControlMessageSchema
|
|
197
|
+
]);
|
|
198
|
+
//#endregion
|
|
33
199
|
//#region src/instance-lock.ts
|
|
34
200
|
/**
|
|
35
201
|
* instance-lock.ts:单实例锁(2026-08-07 根治「多实例抢数据目录锁挂起」)
|
|
@@ -909,6 +1075,17 @@ async function ensureQqFiles(options = {}) {
|
|
|
909
1075
|
exports.DownloadError = DownloadError;
|
|
910
1076
|
exports.ENV = ENV;
|
|
911
1077
|
exports.INSTANCE_LOCK_FILE = INSTANCE_LOCK_FILE;
|
|
1078
|
+
exports.IPC_VERSION = IPC_VERSION;
|
|
1079
|
+
exports.IpcActionPayloadSchema = IpcActionPayloadSchema;
|
|
1080
|
+
exports.IpcBootPhaseSchema = IpcBootPhaseSchema;
|
|
1081
|
+
exports.IpcControlPayloadSchema = IpcControlPayloadSchema;
|
|
1082
|
+
exports.IpcEventPayloadSchema = IpcEventPayloadSchema;
|
|
1083
|
+
exports.IpcLogLevelSchema = IpcLogLevelSchema;
|
|
1084
|
+
exports.IpcLogPayloadSchema = IpcLogPayloadSchema;
|
|
1085
|
+
exports.IpcLoginPayloadSchema = IpcLoginPayloadSchema;
|
|
1086
|
+
exports.IpcMessageSchema = IpcMessageSchema;
|
|
1087
|
+
exports.IpcResultPayloadSchema = IpcResultPayloadSchema;
|
|
1088
|
+
exports.IpcStatusPayloadSchema = IpcStatusPayloadSchema;
|
|
912
1089
|
exports.QQ_FILES_DIR_NAME = QQ_FILES_DIR_NAME;
|
|
913
1090
|
exports.QqReleasesError = QqReleasesError;
|
|
914
1091
|
exports.WIN_NODE_DIR_NAME = WIN_NODE_DIR_NAME;
|