@fraqjs/fraq 0.9.1 → 0.9.2
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/index.d.mts +12 -1
- package/dist/index.mjs +163 -153
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -5522,9 +5522,19 @@ interface RawPattern<P extends Pattern> {
|
|
|
5522
5522
|
pattern: P;
|
|
5523
5523
|
execute: Executor<P>;
|
|
5524
5524
|
}
|
|
5525
|
+
interface SessionReplyOptions {
|
|
5526
|
+
withQuote?: boolean;
|
|
5527
|
+
withMention?: boolean;
|
|
5528
|
+
}
|
|
5525
5529
|
interface Session {
|
|
5526
5530
|
raw: IncomingMessage;
|
|
5527
|
-
reply(
|
|
5531
|
+
reply(
|
|
5532
|
+
segments: OutgoingSegment_ZodInput[],
|
|
5533
|
+
options?: SessionReplyOptions,
|
|
5534
|
+
): Promise<{
|
|
5535
|
+
messageSeq: number;
|
|
5536
|
+
}>;
|
|
5537
|
+
reaction(type: 'face' | 'emoji', reactionId: string): Promise<void>;
|
|
5528
5538
|
}
|
|
5529
5539
|
declare class CommandBuilder<P extends Pattern = {}, S = Command<P>> {
|
|
5530
5540
|
readonly name: string;
|
|
@@ -5846,6 +5856,7 @@ export {
|
|
|
5846
5856
|
ServiceClass,
|
|
5847
5857
|
Session,
|
|
5848
5858
|
SessionPredicate,
|
|
5859
|
+
SessionReplyOptions,
|
|
5849
5860
|
TypeInstruction,
|
|
5850
5861
|
combineLogHandlers,
|
|
5851
5862
|
createMilkyClient,
|
package/dist/index.mjs
CHANGED
|
@@ -64,6 +64,138 @@ function createMilkyClient(...params) {
|
|
|
64
64
|
} });
|
|
65
65
|
}
|
|
66
66
|
//#endregion
|
|
67
|
+
//#region src/protocol/segment.ts
|
|
68
|
+
function msg(strings, ...values) {
|
|
69
|
+
let buffer = "";
|
|
70
|
+
const segments = [];
|
|
71
|
+
for (let i = 0; i < strings.length; i++) {
|
|
72
|
+
buffer += strings[i];
|
|
73
|
+
if (i < values.length) {
|
|
74
|
+
const value = values[i];
|
|
75
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") buffer += value.toString();
|
|
76
|
+
else {
|
|
77
|
+
if (buffer) {
|
|
78
|
+
segments.push({
|
|
79
|
+
type: "text",
|
|
80
|
+
data: { text: buffer }
|
|
81
|
+
});
|
|
82
|
+
buffer = "";
|
|
83
|
+
}
|
|
84
|
+
segments.push(value);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (buffer) segments.push({
|
|
89
|
+
type: "text",
|
|
90
|
+
data: { text: buffer }
|
|
91
|
+
});
|
|
92
|
+
return trimBoundaryTextSegments(segments);
|
|
93
|
+
}
|
|
94
|
+
function isTextSegment(segment) {
|
|
95
|
+
return segment.type === "text";
|
|
96
|
+
}
|
|
97
|
+
function withText(segment, text) {
|
|
98
|
+
return {
|
|
99
|
+
...segment,
|
|
100
|
+
data: {
|
|
101
|
+
...segment.data,
|
|
102
|
+
text
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function trimBoundaryTextSegments(segments) {
|
|
107
|
+
const result = [...segments];
|
|
108
|
+
const first = result[0];
|
|
109
|
+
if (first && isTextSegment(first)) {
|
|
110
|
+
const text = first.data.text.trimStart();
|
|
111
|
+
if (text) result[0] = withText(first, text);
|
|
112
|
+
else result.shift();
|
|
113
|
+
}
|
|
114
|
+
const lastIndex = result.length - 1;
|
|
115
|
+
const last = result[lastIndex];
|
|
116
|
+
if (last && isTextSegment(last)) {
|
|
117
|
+
const text = last.data.text.trimEnd();
|
|
118
|
+
if (text) result[lastIndex] = withText(last, text);
|
|
119
|
+
else result.pop();
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
let seg;
|
|
124
|
+
(function(_seg) {
|
|
125
|
+
function mention(userId) {
|
|
126
|
+
return {
|
|
127
|
+
type: "mention",
|
|
128
|
+
data: { user_id: userId }
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
_seg.mention = mention;
|
|
132
|
+
function mentionAll() {
|
|
133
|
+
return {
|
|
134
|
+
type: "mention_all",
|
|
135
|
+
data: {}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
_seg.mentionAll = mentionAll;
|
|
139
|
+
function face(faceId, options) {
|
|
140
|
+
return {
|
|
141
|
+
type: "face",
|
|
142
|
+
data: {
|
|
143
|
+
face_id: faceId.toString(),
|
|
144
|
+
is_large: options?.isLarge ?? false
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
_seg.face = face;
|
|
149
|
+
function reply(messageSeq) {
|
|
150
|
+
return {
|
|
151
|
+
type: "reply",
|
|
152
|
+
data: { message_seq: messageSeq }
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
_seg.reply = reply;
|
|
156
|
+
function image(uri, options) {
|
|
157
|
+
return {
|
|
158
|
+
type: "image",
|
|
159
|
+
data: {
|
|
160
|
+
uri,
|
|
161
|
+
sub_type: options?.subType,
|
|
162
|
+
summary: options?.summary
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
_seg.image = image;
|
|
167
|
+
function record(uri) {
|
|
168
|
+
return {
|
|
169
|
+
type: "record",
|
|
170
|
+
data: { uri }
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
_seg.record = record;
|
|
174
|
+
function video(uri, options) {
|
|
175
|
+
return {
|
|
176
|
+
type: "video",
|
|
177
|
+
data: {
|
|
178
|
+
uri,
|
|
179
|
+
thumb_uri: options?.thumbUri
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
_seg.video = video;
|
|
184
|
+
function forward(messages, options) {
|
|
185
|
+
return {
|
|
186
|
+
type: "forward",
|
|
187
|
+
data: {
|
|
188
|
+
messages,
|
|
189
|
+
title: options?.title,
|
|
190
|
+
preview: options?.preview,
|
|
191
|
+
summary: options?.summary,
|
|
192
|
+
prompt: options?.prompt
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
_seg.forward = forward;
|
|
197
|
+
})(seg || (seg = {}));
|
|
198
|
+
//#endregion
|
|
67
199
|
//#region src/routing/command.ts
|
|
68
200
|
var CommandBuilder = class {
|
|
69
201
|
name;
|
|
@@ -592,25 +724,35 @@ and implement the dispose method to clean up resources when the context stops.
|
|
|
592
724
|
createSession(message) {
|
|
593
725
|
return {
|
|
594
726
|
raw: message,
|
|
595
|
-
reply: async (segments) => {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
727
|
+
reply: async (segments, options) => {
|
|
728
|
+
const actualSegments = [...segments];
|
|
729
|
+
if (options?.withMention && message.message_scene === "group") actualSegments.unshift(seg.mention(message.sender_id));
|
|
730
|
+
if (options?.withQuote) actualSegments.unshift(seg.reply(message.message_seq));
|
|
731
|
+
switch (message.message_scene) {
|
|
732
|
+
case "friend": {
|
|
733
|
+
const { message_seq } = await this.client.send_private_message({
|
|
734
|
+
user_id: message.peer_id,
|
|
735
|
+
message: actualSegments
|
|
736
|
+
});
|
|
737
|
+
return { messageSeq: message_seq };
|
|
738
|
+
}
|
|
739
|
+
case "group": {
|
|
740
|
+
const { message_seq } = await this.client.send_group_message({
|
|
741
|
+
group_id: message.peer_id,
|
|
742
|
+
message: actualSegments
|
|
743
|
+
});
|
|
744
|
+
return { messageSeq: message_seq };
|
|
610
745
|
}
|
|
611
|
-
} catch (error) {
|
|
612
|
-
this.logger.error(`Error sending reply (source msg: scene=${message.message_scene} peer=${message.peer_id} sender=${message.sender_id} seq=${message.message_seq})`, error);
|
|
613
746
|
}
|
|
747
|
+
return { messageSeq: 0 };
|
|
748
|
+
},
|
|
749
|
+
reaction: async (type, reactionId) => {
|
|
750
|
+
if (message.message_scene === "group") await this.client.send_group_message_reaction({
|
|
751
|
+
group_id: message.peer_id,
|
|
752
|
+
message_seq: message.message_seq,
|
|
753
|
+
reaction_type: type,
|
|
754
|
+
reaction: reactionId
|
|
755
|
+
});
|
|
614
756
|
}
|
|
615
757
|
};
|
|
616
758
|
}
|
|
@@ -726,15 +868,15 @@ and implement the dispose method to clean up resources when the context stops.
|
|
|
726
868
|
for (const installedPlugin of sortedPlugins) {
|
|
727
869
|
const { plugin, args } = installedPlugin;
|
|
728
870
|
const providedBeforeApply = new Set(this.services.keys());
|
|
729
|
-
let
|
|
871
|
+
let applyingMessage = `Applying plugin ${plugin.name}`;
|
|
730
872
|
const requiredServices = [];
|
|
731
873
|
const providedServices = [];
|
|
732
874
|
if (plugin.requires) for (const service of plugin.requires) requiredServices.push(service.name);
|
|
733
875
|
if (plugin.optionalRequires) for (const service of plugin.optionalRequires) requiredServices.push(`${service.name}?`);
|
|
734
876
|
if (plugin.provides) for (const service of plugin.provides) providedServices.push(service.name);
|
|
735
|
-
if (requiredServices.length > 0)
|
|
736
|
-
if (providedServices.length > 0)
|
|
737
|
-
this.logger.
|
|
877
|
+
if (requiredServices.length > 0) applyingMessage += `, requires: [${requiredServices.join(", ")}]`;
|
|
878
|
+
if (providedServices.length > 0) applyingMessage += `, provides: [${providedServices.join(", ")}]`;
|
|
879
|
+
this.logger.info(applyingMessage);
|
|
738
880
|
await plugin.apply(this.getPluginContext(installedPlugin), ...args);
|
|
739
881
|
for (const service of plugin.provides ?? []) if (!this.services.has(service) || providedBeforeApply.has(service)) throw new Error(`${plugin.name} declares service ${service.name} but did not provide it.`);
|
|
740
882
|
}
|
|
@@ -1063,138 +1205,6 @@ function definePlugin(plugin) {
|
|
|
1063
1205
|
return plugin;
|
|
1064
1206
|
}
|
|
1065
1207
|
//#endregion
|
|
1066
|
-
//#region src/protocol/segment.ts
|
|
1067
|
-
function msg(strings, ...values) {
|
|
1068
|
-
let buffer = "";
|
|
1069
|
-
const segments = [];
|
|
1070
|
-
for (let i = 0; i < strings.length; i++) {
|
|
1071
|
-
buffer += strings[i];
|
|
1072
|
-
if (i < values.length) {
|
|
1073
|
-
const value = values[i];
|
|
1074
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") buffer += value.toString();
|
|
1075
|
-
else {
|
|
1076
|
-
if (buffer) {
|
|
1077
|
-
segments.push({
|
|
1078
|
-
type: "text",
|
|
1079
|
-
data: { text: buffer }
|
|
1080
|
-
});
|
|
1081
|
-
buffer = "";
|
|
1082
|
-
}
|
|
1083
|
-
segments.push(value);
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
if (buffer) segments.push({
|
|
1088
|
-
type: "text",
|
|
1089
|
-
data: { text: buffer }
|
|
1090
|
-
});
|
|
1091
|
-
return trimBoundaryTextSegments(segments);
|
|
1092
|
-
}
|
|
1093
|
-
function isTextSegment(segment) {
|
|
1094
|
-
return segment.type === "text";
|
|
1095
|
-
}
|
|
1096
|
-
function withText(segment, text) {
|
|
1097
|
-
return {
|
|
1098
|
-
...segment,
|
|
1099
|
-
data: {
|
|
1100
|
-
...segment.data,
|
|
1101
|
-
text
|
|
1102
|
-
}
|
|
1103
|
-
};
|
|
1104
|
-
}
|
|
1105
|
-
function trimBoundaryTextSegments(segments) {
|
|
1106
|
-
const result = [...segments];
|
|
1107
|
-
const first = result[0];
|
|
1108
|
-
if (first && isTextSegment(first)) {
|
|
1109
|
-
const text = first.data.text.trimStart();
|
|
1110
|
-
if (text) result[0] = withText(first, text);
|
|
1111
|
-
else result.shift();
|
|
1112
|
-
}
|
|
1113
|
-
const lastIndex = result.length - 1;
|
|
1114
|
-
const last = result[lastIndex];
|
|
1115
|
-
if (last && isTextSegment(last)) {
|
|
1116
|
-
const text = last.data.text.trimEnd();
|
|
1117
|
-
if (text) result[lastIndex] = withText(last, text);
|
|
1118
|
-
else result.pop();
|
|
1119
|
-
}
|
|
1120
|
-
return result;
|
|
1121
|
-
}
|
|
1122
|
-
let seg;
|
|
1123
|
-
(function(_seg) {
|
|
1124
|
-
function mention(userId) {
|
|
1125
|
-
return {
|
|
1126
|
-
type: "mention",
|
|
1127
|
-
data: { user_id: userId }
|
|
1128
|
-
};
|
|
1129
|
-
}
|
|
1130
|
-
_seg.mention = mention;
|
|
1131
|
-
function mentionAll() {
|
|
1132
|
-
return {
|
|
1133
|
-
type: "mention_all",
|
|
1134
|
-
data: {}
|
|
1135
|
-
};
|
|
1136
|
-
}
|
|
1137
|
-
_seg.mentionAll = mentionAll;
|
|
1138
|
-
function face(faceId, options) {
|
|
1139
|
-
return {
|
|
1140
|
-
type: "face",
|
|
1141
|
-
data: {
|
|
1142
|
-
face_id: faceId.toString(),
|
|
1143
|
-
is_large: options?.isLarge ?? false
|
|
1144
|
-
}
|
|
1145
|
-
};
|
|
1146
|
-
}
|
|
1147
|
-
_seg.face = face;
|
|
1148
|
-
function reply(messageSeq) {
|
|
1149
|
-
return {
|
|
1150
|
-
type: "reply",
|
|
1151
|
-
data: { message_seq: messageSeq }
|
|
1152
|
-
};
|
|
1153
|
-
}
|
|
1154
|
-
_seg.reply = reply;
|
|
1155
|
-
function image(uri, options) {
|
|
1156
|
-
return {
|
|
1157
|
-
type: "image",
|
|
1158
|
-
data: {
|
|
1159
|
-
uri,
|
|
1160
|
-
sub_type: options?.subType,
|
|
1161
|
-
summary: options?.summary
|
|
1162
|
-
}
|
|
1163
|
-
};
|
|
1164
|
-
}
|
|
1165
|
-
_seg.image = image;
|
|
1166
|
-
function record(uri) {
|
|
1167
|
-
return {
|
|
1168
|
-
type: "record",
|
|
1169
|
-
data: { uri }
|
|
1170
|
-
};
|
|
1171
|
-
}
|
|
1172
|
-
_seg.record = record;
|
|
1173
|
-
function video(uri, options) {
|
|
1174
|
-
return {
|
|
1175
|
-
type: "video",
|
|
1176
|
-
data: {
|
|
1177
|
-
uri,
|
|
1178
|
-
thumb_uri: options?.thumbUri
|
|
1179
|
-
}
|
|
1180
|
-
};
|
|
1181
|
-
}
|
|
1182
|
-
_seg.video = video;
|
|
1183
|
-
function forward(messages, options) {
|
|
1184
|
-
return {
|
|
1185
|
-
type: "forward",
|
|
1186
|
-
data: {
|
|
1187
|
-
messages,
|
|
1188
|
-
title: options?.title,
|
|
1189
|
-
preview: options?.preview,
|
|
1190
|
-
summary: options?.summary,
|
|
1191
|
-
prompt: options?.prompt
|
|
1192
|
-
}
|
|
1193
|
-
};
|
|
1194
|
-
}
|
|
1195
|
-
_seg.forward = forward;
|
|
1196
|
-
})(seg || (seg = {}));
|
|
1197
|
-
//#endregion
|
|
1198
1208
|
//#region src/protocol/types.ts
|
|
1199
1209
|
const milkyVersion = "1.3";
|
|
1200
1210
|
const milkyPackageVersion = "1.3.0-rc.1";
|