@fraqjs/fraq 0.8.0 → 0.8.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 CHANGED
@@ -5444,12 +5444,14 @@ declare class Tokenizer {
5444
5444
  next(): Token | undefined;
5445
5445
  isGreedyAvailable(): boolean;
5446
5446
  greedy(): string;
5447
+ isCatchAllAvailable(): boolean;
5448
+ catchAll(): IncomingSegment[];
5447
5449
  private findNextPosition;
5448
5450
  private findTextTokenStart;
5449
5451
  private readTextToken;
5450
5452
  }
5451
5453
  //#endregion
5452
- //#region src/routing/capturer.d.ts
5454
+ //#region src/routing/parameter.d.ts
5453
5455
  interface Capturer<T> {
5454
5456
  typeInstruction: TypeInstruction;
5455
5457
  capture(tokenizer: Tokenizer): T | undefined;
@@ -5468,6 +5470,9 @@ type TypeInstruction =
5468
5470
  | {
5469
5471
  type: 'greedy';
5470
5472
  }
5473
+ | {
5474
+ type: 'catchAll';
5475
+ }
5471
5476
  | {
5472
5477
  type: 'union';
5473
5478
  members: string[];
@@ -5476,8 +5481,6 @@ type TypeInstruction =
5476
5481
  type: 'segment';
5477
5482
  segmentType: Exclude<Token, string>['type'];
5478
5483
  };
5479
- //#endregion
5480
- //#region src/routing/parameter.d.ts
5481
5484
  declare class Parameter<T> {
5482
5485
  readonly capturer: Capturer<T>;
5483
5486
  description?: string;
@@ -5489,6 +5492,7 @@ declare namespace param {
5489
5492
  function num(): Parameter<number>;
5490
5493
  function str(): Parameter<string>;
5491
5494
  function greedy(): Parameter<string>;
5495
+ function catchAll(): Parameter<IncomingSegment[]>;
5492
5496
  function union<T extends string>(...literals: T[]): Parameter<T>;
5493
5497
  function segment<T extends Exclude<Token, string>['type']>(
5494
5498
  type: T,
@@ -5580,6 +5584,7 @@ declare class Router {
5580
5584
  private matchGroup;
5581
5585
  private matchRawPattern;
5582
5586
  private branchesFrom;
5587
+ private validatePattern;
5583
5588
  private capturePattern;
5584
5589
  }
5585
5590
  //#endregion
@@ -5589,7 +5594,9 @@ declare namespace filter {
5589
5594
  function define(filter: Filter): Filter;
5590
5595
  function allPass(): Filter;
5591
5596
  function friend(...uinList: number[]): Filter;
5597
+ function allFriends(): Filter;
5592
5598
  function group(...uinList: number[]): Filter;
5599
+ function allGroups(): Filter;
5593
5600
  function admin(): Filter;
5594
5601
  function or(...filters: Filter[]): Filter;
5595
5602
  function and(...filters: Filter[]): Filter;
@@ -5775,6 +5782,7 @@ declare namespace seg {
5775
5782
  //#endregion
5776
5783
  export {
5777
5784
  ApiEndpoints,
5785
+ Capturer,
5778
5786
  Command,
5779
5787
  Context,
5780
5788
  ContextOptions,
@@ -5803,6 +5811,7 @@ export {
5803
5811
  ServiceClass,
5804
5812
  Session,
5805
5813
  SessionPredicate,
5814
+ TypeInstruction,
5806
5815
  combineLogHandlers,
5807
5816
  createMilkyClient,
5808
5817
  definePlugin,
package/dist/index.mjs CHANGED
@@ -115,21 +115,48 @@ var Tokenizer = class {
115
115
  return token;
116
116
  }
117
117
  isGreedyAvailable() {
118
- if (this.offset !== this.segments.length - 1) return false;
119
- const segment = this.segments[this.offset];
118
+ const position = this.findNextPosition();
119
+ if (position === void 0) return false;
120
+ const segment = this.segments[position.offset];
120
121
  if (segment?.type !== "text") return false;
121
- return this.findTextTokenStart(segment.data.text, this.subOffset ?? 0) < segment.data.text.length;
122
+ return this.findTextTokenStart(segment.data.text, position.subOffset ?? 0) < segment.data.text.length;
122
123
  }
123
124
  greedy() {
124
- if (!this.isGreedyAvailable()) throw new Error("Greedy token is not available");
125
- const segment = this.segments[this.offset];
125
+ const position = this.findNextPosition();
126
+ if (position === void 0) throw new Error("Greedy token is not available");
127
+ const segment = this.segments[position.offset];
126
128
  if (segment.type !== "text") throw new Error("Greedy token is not available");
127
- const tokenStart = this.findTextTokenStart(segment.data.text, this.subOffset ?? 0);
129
+ const tokenStart = this.findTextTokenStart(segment.data.text, position.subOffset ?? 0);
130
+ if (tokenStart >= segment.data.text.length) throw new Error("Greedy token is not available");
128
131
  const token = segment.data.text.slice(tokenStart);
129
- this.offset = this.segments.length;
132
+ this.offset = position.offset + 1;
130
133
  this.subOffset = void 0;
131
134
  return token;
132
135
  }
136
+ isCatchAllAvailable() {
137
+ return this.findNextPosition() !== void 0;
138
+ }
139
+ catchAll() {
140
+ const position = this.findNextPosition();
141
+ if (position === void 0) throw new Error("Catch-all token is not available");
142
+ const segment = this.segments[position.offset];
143
+ const segments = [];
144
+ if (segment.type === "text") {
145
+ const textStart = this.findTextTokenStart(segment.data.text, position.subOffset ?? 0);
146
+ const text = segment.data.text.slice(textStart);
147
+ if (text.length > 0) segments.push({
148
+ ...segment,
149
+ data: {
150
+ ...segment.data,
151
+ text
152
+ }
153
+ });
154
+ segments.push(...this.segments.slice(position.offset + 1));
155
+ } else segments.push(...this.segments.slice(position.offset));
156
+ this.offset = this.segments.length;
157
+ this.subOffset = void 0;
158
+ return segments;
159
+ }
133
160
  findNextPosition() {
134
161
  let offset = this.offset;
135
162
  let subOffset = this.subOffset;
@@ -165,6 +192,7 @@ var Router = class Router {
165
192
  entries = [];
166
193
  groups = /* @__PURE__ */ new Map();
167
194
  command(command) {
195
+ this.validatePattern(command.pattern);
168
196
  this.entries.push({
169
197
  type: "command",
170
198
  command
@@ -172,9 +200,7 @@ var Router = class Router {
172
200
  return this;
173
201
  }
174
202
  rawPattern(rawPattern) {
175
- if (Object.keys(rawPattern.pattern).length === 0) throw new Error("Raw pattern must have at least one parameter.");
176
- const firstKey = Object.keys(rawPattern.pattern)[0];
177
- if (rawPattern.pattern[firstKey].capturer.typeInstruction.type === "literal") throw new Error("The first parameter of a raw pattern cannot be a literal, as it would conflict with command patterns.");
203
+ this.validatePattern(rawPattern.pattern, { rawPattern: true });
178
204
  this.entries.push({
179
205
  type: "rawPattern",
180
206
  rawPattern
@@ -300,6 +326,15 @@ var Router = class Router {
300
326
  }
301
327
  return branches;
302
328
  }
329
+ validatePattern(pattern, options) {
330
+ const entries = Object.entries(pattern);
331
+ if (options?.rawPattern && entries.length === 0) throw new Error("Raw pattern must have at least one parameter.");
332
+ if (options?.rawPattern && entries[0]?.[1].capturer.typeInstruction.type === "literal") throw new Error("The first parameter of a raw pattern cannot be a literal, as it would conflict with command patterns.");
333
+ const catchAllEntryIndex = entries.findIndex(([, parameter]) => {
334
+ return parameter.capturer.typeInstruction.type === "catchAll";
335
+ });
336
+ if (catchAllEntryIndex !== -1 && catchAllEntryIndex !== entries.length - 1) throw new Error("Catch-all parameters must be the last parameter in a pattern.");
337
+ }
303
338
  capturePattern(pattern, tokenizer) {
304
339
  const initialState = tokenizer.getState();
305
340
  const params = {};
@@ -843,6 +878,17 @@ let filter;
843
878
  };
844
879
  }
845
880
  _filter.friend = friend;
881
+ function allFriends() {
882
+ return {
883
+ message_receive: ({ data }) => data.message_scene === "friend",
884
+ message_recall: ({ data }) => data.message_scene === "friend",
885
+ peer_pin_change: ({ data }) => data.message_scene === "friend",
886
+ group_invitation: () => true,
887
+ friend_nudge: () => true,
888
+ friend_file_upload: () => true
889
+ };
890
+ }
891
+ _filter.allFriends = allFriends;
846
892
  function group(...uinList) {
847
893
  const uinSet = new Set(uinList);
848
894
  return {
@@ -864,6 +910,26 @@ let filter;
864
910
  };
865
911
  }
866
912
  _filter.group = group;
913
+ function allGroups() {
914
+ return {
915
+ message_receive: ({ data }) => data.message_scene === "group",
916
+ message_recall: ({ data }) => data.message_scene === "group",
917
+ peer_pin_change: ({ data }) => data.message_scene === "group",
918
+ group_join_request: () => true,
919
+ group_invited_join_request: () => true,
920
+ group_admin_change: () => true,
921
+ group_essence_message_change: () => true,
922
+ group_member_increase: () => true,
923
+ group_member_decrease: () => true,
924
+ group_name_change: () => true,
925
+ group_message_reaction: () => true,
926
+ group_mute: () => true,
927
+ group_whole_mute: () => true,
928
+ group_nudge: () => true,
929
+ group_file_upload: () => true
930
+ };
931
+ }
932
+ _filter.allGroups = allGroups;
867
933
  function admin() {
868
934
  return { message_receive: ({ data }) => data.message_scene === "group" && data.group_member.role !== "member" };
869
935
  }
@@ -1052,11 +1118,22 @@ let seg;
1052
1118
  const milkyVersion = "1.3";
1053
1119
  const milkyPackageVersion = "1.3.0-rc.1";
1054
1120
  //#endregion
1055
- //#region src/routing/capturer.ts
1056
- let capturer;
1057
- (function(_capturer) {
1121
+ //#region src/routing/parameter.ts
1122
+ var Parameter = class {
1123
+ capturer;
1124
+ description;
1125
+ constructor(capturer) {
1126
+ this.capturer = capturer;
1127
+ }
1128
+ describe(description) {
1129
+ this.description = description;
1130
+ return this;
1131
+ }
1132
+ };
1133
+ let param;
1134
+ (function(_param) {
1058
1135
  function literal(literal) {
1059
- return {
1136
+ return new Parameter({
1060
1137
  typeInstruction: {
1061
1138
  type: "literal",
1062
1139
  literal
@@ -1068,44 +1145,62 @@ let capturer;
1068
1145
  return token;
1069
1146
  }
1070
1147
  }
1071
- };
1148
+ });
1149
+ }
1150
+ _param.literal = literal;
1151
+ function num() {
1152
+ return new Parameter({
1153
+ typeInstruction: { type: "number" },
1154
+ capture(tokenizer) {
1155
+ const token = tokenizer.peek();
1156
+ if (typeof token === "string") {
1157
+ const parsed = Number(token);
1158
+ if (!Number.isNaN(parsed)) {
1159
+ tokenizer.next();
1160
+ return parsed;
1161
+ }
1162
+ }
1163
+ }
1164
+ });
1072
1165
  }
1073
- _capturer.literal = literal;
1074
- _capturer.num = {
1075
- typeInstruction: { type: "number" },
1076
- capture(tokenizer) {
1077
- const token = tokenizer.peek();
1078
- if (typeof token === "string") {
1079
- const parsed = Number(token);
1080
- if (!Number.isNaN(parsed)) {
1166
+ _param.num = num;
1167
+ function str() {
1168
+ return new Parameter({
1169
+ typeInstruction: { type: "string" },
1170
+ capture(tokenizer) {
1171
+ const token = tokenizer.peek();
1172
+ if (typeof token === "string") {
1081
1173
  tokenizer.next();
1082
- return parsed;
1174
+ return token;
1083
1175
  }
1084
1176
  }
1085
- }
1086
- };
1087
- _capturer.str = {
1088
- typeInstruction: { type: "string" },
1089
- capture(tokenizer) {
1090
- const token = tokenizer.peek();
1091
- if (typeof token === "string") {
1092
- tokenizer.next();
1093
- return token;
1177
+ });
1178
+ }
1179
+ _param.str = str;
1180
+ function greedy() {
1181
+ return new Parameter({
1182
+ typeInstruction: { type: "greedy" },
1183
+ capture(tokenizer) {
1184
+ if (tokenizer.isGreedyAvailable()) return tokenizer.greedy();
1094
1185
  }
1095
- }
1096
- };
1097
- _capturer.greedy = {
1098
- typeInstruction: { type: "greedy" },
1099
- capture(tokenizer) {
1100
- if (tokenizer.isGreedyAvailable()) return tokenizer.greedy();
1101
- }
1102
- };
1103
- function union(...members) {
1104
- const literalSet = new Set(members);
1105
- return {
1186
+ });
1187
+ }
1188
+ _param.greedy = greedy;
1189
+ function catchAll() {
1190
+ return new Parameter({
1191
+ typeInstruction: { type: "catchAll" },
1192
+ capture(tokenizer) {
1193
+ if (tokenizer.isCatchAllAvailable()) return tokenizer.catchAll();
1194
+ }
1195
+ });
1196
+ }
1197
+ _param.catchAll = catchAll;
1198
+ function union(...literals) {
1199
+ const literalSet = new Set(literals);
1200
+ return new Parameter({
1106
1201
  typeInstruction: {
1107
1202
  type: "union",
1108
- members
1203
+ members: literals
1109
1204
  },
1110
1205
  capture(tokenizer) {
1111
1206
  const token = tokenizer.peek();
@@ -1114,11 +1209,11 @@ let capturer;
1114
1209
  return token;
1115
1210
  }
1116
1211
  }
1117
- };
1212
+ });
1118
1213
  }
1119
- _capturer.union = union;
1214
+ _param.union = union;
1120
1215
  function segment(type) {
1121
- return {
1216
+ return new Parameter({
1122
1217
  typeInstruction: {
1123
1218
  type: "segment",
1124
1219
  segmentType: type
@@ -1130,47 +1225,7 @@ let capturer;
1130
1225
  return token;
1131
1226
  }
1132
1227
  }
1133
- };
1134
- }
1135
- _capturer.segment = segment;
1136
- })(capturer || (capturer = {}));
1137
- //#endregion
1138
- //#region src/routing/parameter.ts
1139
- var Parameter = class {
1140
- capturer;
1141
- description;
1142
- constructor(capturer) {
1143
- this.capturer = capturer;
1144
- }
1145
- describe(description) {
1146
- this.description = description;
1147
- return this;
1148
- }
1149
- };
1150
- let param;
1151
- (function(_param) {
1152
- function literal(literal) {
1153
- return new Parameter(capturer.literal(literal));
1154
- }
1155
- _param.literal = literal;
1156
- function num() {
1157
- return new Parameter(capturer.num);
1158
- }
1159
- _param.num = num;
1160
- function str() {
1161
- return new Parameter(capturer.str);
1162
- }
1163
- _param.str = str;
1164
- function greedy() {
1165
- return new Parameter(capturer.greedy);
1166
- }
1167
- _param.greedy = greedy;
1168
- function union(...literals) {
1169
- return new Parameter(capturer.union(...literals));
1170
- }
1171
- _param.union = union;
1172
- function segment(type) {
1173
- return new Parameter(capturer.segment(type));
1228
+ });
1174
1229
  }
1175
1230
  _param.segment = segment;
1176
1231
  })(param || (param = {}));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fraqjs/fraq",
3
3
  "type": "module",
4
- "version": "0.8.0",
4
+ "version": "0.8.2",
5
5
  "description": "Milky Bot framework",
6
6
  "files": [
7
7
  "dist"