@fraqjs/fraq 0.8.0 → 0.8.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.
- package/dist/index.d.mts +10 -3
- package/dist/index.mjs +113 -89
- package/package.json +1 -1
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/
|
|
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
|
|
@@ -5775,6 +5780,7 @@ declare namespace seg {
|
|
|
5775
5780
|
//#endregion
|
|
5776
5781
|
export {
|
|
5777
5782
|
ApiEndpoints,
|
|
5783
|
+
Capturer,
|
|
5778
5784
|
Command,
|
|
5779
5785
|
Context,
|
|
5780
5786
|
ContextOptions,
|
|
@@ -5803,6 +5809,7 @@ export {
|
|
|
5803
5809
|
ServiceClass,
|
|
5804
5810
|
Session,
|
|
5805
5811
|
SessionPredicate,
|
|
5812
|
+
TypeInstruction,
|
|
5806
5813
|
combineLogHandlers,
|
|
5807
5814
|
createMilkyClient,
|
|
5808
5815
|
definePlugin,
|
package/dist/index.mjs
CHANGED
|
@@ -115,21 +115,48 @@ var Tokenizer = class {
|
|
|
115
115
|
return token;
|
|
116
116
|
}
|
|
117
117
|
isGreedyAvailable() {
|
|
118
|
-
|
|
119
|
-
|
|
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,
|
|
122
|
+
return this.findTextTokenStart(segment.data.text, position.subOffset ?? 0) < segment.data.text.length;
|
|
122
123
|
}
|
|
123
124
|
greedy() {
|
|
124
|
-
|
|
125
|
-
|
|
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,
|
|
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 =
|
|
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
|
-
|
|
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 = {};
|
|
@@ -1052,11 +1087,22 @@ let seg;
|
|
|
1052
1087
|
const milkyVersion = "1.3";
|
|
1053
1088
|
const milkyPackageVersion = "1.3.0-rc.1";
|
|
1054
1089
|
//#endregion
|
|
1055
|
-
//#region src/routing/
|
|
1056
|
-
|
|
1057
|
-
|
|
1090
|
+
//#region src/routing/parameter.ts
|
|
1091
|
+
var Parameter = class {
|
|
1092
|
+
capturer;
|
|
1093
|
+
description;
|
|
1094
|
+
constructor(capturer) {
|
|
1095
|
+
this.capturer = capturer;
|
|
1096
|
+
}
|
|
1097
|
+
describe(description) {
|
|
1098
|
+
this.description = description;
|
|
1099
|
+
return this;
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
let param;
|
|
1103
|
+
(function(_param) {
|
|
1058
1104
|
function literal(literal) {
|
|
1059
|
-
return {
|
|
1105
|
+
return new Parameter({
|
|
1060
1106
|
typeInstruction: {
|
|
1061
1107
|
type: "literal",
|
|
1062
1108
|
literal
|
|
@@ -1068,44 +1114,62 @@ let capturer;
|
|
|
1068
1114
|
return token;
|
|
1069
1115
|
}
|
|
1070
1116
|
}
|
|
1071
|
-
};
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
_param.literal = literal;
|
|
1120
|
+
function num() {
|
|
1121
|
+
return new Parameter({
|
|
1122
|
+
typeInstruction: { type: "number" },
|
|
1123
|
+
capture(tokenizer) {
|
|
1124
|
+
const token = tokenizer.peek();
|
|
1125
|
+
if (typeof token === "string") {
|
|
1126
|
+
const parsed = Number(token);
|
|
1127
|
+
if (!Number.isNaN(parsed)) {
|
|
1128
|
+
tokenizer.next();
|
|
1129
|
+
return parsed;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
});
|
|
1072
1134
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
if (!Number.isNaN(parsed)) {
|
|
1135
|
+
_param.num = num;
|
|
1136
|
+
function str() {
|
|
1137
|
+
return new Parameter({
|
|
1138
|
+
typeInstruction: { type: "string" },
|
|
1139
|
+
capture(tokenizer) {
|
|
1140
|
+
const token = tokenizer.peek();
|
|
1141
|
+
if (typeof token === "string") {
|
|
1081
1142
|
tokenizer.next();
|
|
1082
|
-
return
|
|
1143
|
+
return token;
|
|
1083
1144
|
}
|
|
1084
1145
|
}
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
tokenizer.
|
|
1093
|
-
return token;
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
_param.str = str;
|
|
1149
|
+
function greedy() {
|
|
1150
|
+
return new Parameter({
|
|
1151
|
+
typeInstruction: { type: "greedy" },
|
|
1152
|
+
capture(tokenizer) {
|
|
1153
|
+
if (tokenizer.isGreedyAvailable()) return tokenizer.greedy();
|
|
1094
1154
|
}
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
_param.greedy = greedy;
|
|
1158
|
+
function catchAll() {
|
|
1159
|
+
return new Parameter({
|
|
1160
|
+
typeInstruction: { type: "catchAll" },
|
|
1161
|
+
capture(tokenizer) {
|
|
1162
|
+
if (tokenizer.isCatchAllAvailable()) return tokenizer.catchAll();
|
|
1163
|
+
}
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
_param.catchAll = catchAll;
|
|
1167
|
+
function union(...literals) {
|
|
1168
|
+
const literalSet = new Set(literals);
|
|
1169
|
+
return new Parameter({
|
|
1106
1170
|
typeInstruction: {
|
|
1107
1171
|
type: "union",
|
|
1108
|
-
members
|
|
1172
|
+
members: literals
|
|
1109
1173
|
},
|
|
1110
1174
|
capture(tokenizer) {
|
|
1111
1175
|
const token = tokenizer.peek();
|
|
@@ -1114,11 +1178,11 @@ let capturer;
|
|
|
1114
1178
|
return token;
|
|
1115
1179
|
}
|
|
1116
1180
|
}
|
|
1117
|
-
};
|
|
1181
|
+
});
|
|
1118
1182
|
}
|
|
1119
|
-
|
|
1183
|
+
_param.union = union;
|
|
1120
1184
|
function segment(type) {
|
|
1121
|
-
return {
|
|
1185
|
+
return new Parameter({
|
|
1122
1186
|
typeInstruction: {
|
|
1123
1187
|
type: "segment",
|
|
1124
1188
|
segmentType: type
|
|
@@ -1130,47 +1194,7 @@ let capturer;
|
|
|
1130
1194
|
return token;
|
|
1131
1195
|
}
|
|
1132
1196
|
}
|
|
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));
|
|
1197
|
+
});
|
|
1174
1198
|
}
|
|
1175
1199
|
_param.segment = segment;
|
|
1176
1200
|
})(param || (param = {}));
|