moost 0.2.0 → 0.2.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.cjs +1 -1181
- package/dist/index.mjs +1 -1181
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useEventContext, useEventId, useRouteParams } from '@wooksjs/event-core';
|
|
2
2
|
import 'url';
|
|
3
3
|
import 'stream';
|
|
4
|
+
import 'wooks';
|
|
4
5
|
import 'http';
|
|
5
6
|
import { Mate, getConstructor, isConstructor } from '@prostojs/mate';
|
|
6
7
|
import { Infact, createProvideRegistry } from '@prostojs/infact';
|
|
@@ -31,1187 +32,6 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
const dim = '[2m';
|
|
35
|
-
const reset = '[0m';
|
|
36
|
-
class ProstoTree {
|
|
37
|
-
constructor(options) {
|
|
38
|
-
var _a, _b, _c, _d;
|
|
39
|
-
const label = (options === null || options === void 0 ? void 0 : options.label) || 'label';
|
|
40
|
-
const children = (options === null || options === void 0 ? void 0 : options.children) || 'children';
|
|
41
|
-
const branchWidth = typeof (options === null || options === void 0 ? void 0 : options.branchWidth) === 'number' ? options === null || options === void 0 ? void 0 : options.branchWidth : 2;
|
|
42
|
-
const hLine = (((_a = options === null || options === void 0 ? void 0 : options.branches) === null || _a === void 0 ? void 0 : _a.hLine) || '─').repeat(branchWidth - 1);
|
|
43
|
-
const branches = {
|
|
44
|
-
end: ((_b = options === null || options === void 0 ? void 0 : options.branches) === null || _b === void 0 ? void 0 : _b.end) || dim + '└',
|
|
45
|
-
middle: ((_c = options === null || options === void 0 ? void 0 : options.branches) === null || _c === void 0 ? void 0 : _c.middle) || dim + '├',
|
|
46
|
-
vLine: ((_d = options === null || options === void 0 ? void 0 : options.branches) === null || _d === void 0 ? void 0 : _d.vLine) || dim + '│',
|
|
47
|
-
hLine,
|
|
48
|
-
};
|
|
49
|
-
this.options = {
|
|
50
|
-
label: label,
|
|
51
|
-
children: children,
|
|
52
|
-
renderLabel: (options === null || options === void 0 ? void 0 : options.renderLabel) || (n => typeof n === 'string' ? n : n[label]),
|
|
53
|
-
branches,
|
|
54
|
-
branchWidth,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
_render(root, opts) {
|
|
58
|
-
const { children, renderLabel } = this.options;
|
|
59
|
-
let s = `${renderLabel(root, '')}\n`;
|
|
60
|
-
const { end, middle, vLine, hLine } = this.options.branches;
|
|
61
|
-
const endBranch = end + hLine + reset + ' ';
|
|
62
|
-
const middleBranch = middle + hLine + reset + ' ';
|
|
63
|
-
const { branchWidth } = this.options;
|
|
64
|
-
if (root) {
|
|
65
|
-
treeNode(root);
|
|
66
|
-
}
|
|
67
|
-
function treeNode(node, behind = '', level = 1) {
|
|
68
|
-
const items = (node && node[children]);
|
|
69
|
-
const count = items && items.length || 0;
|
|
70
|
-
if (items) {
|
|
71
|
-
if ((opts === null || opts === void 0 ? void 0 : opts.level) && opts.level < level) {
|
|
72
|
-
s += behind + endBranch + renderCollapsedChildren(items.length) + '\n';
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
let itemsToRender = items;
|
|
76
|
-
const collapsedCount = Math.max(0, count - ((opts === null || opts === void 0 ? void 0 : opts.childrenLimit) || count));
|
|
77
|
-
if ((opts === null || opts === void 0 ? void 0 : opts.childrenLimit) && count > opts.childrenLimit) {
|
|
78
|
-
itemsToRender = opts.showLast ? items.slice(count - opts.childrenLimit) : items.slice(0, opts.childrenLimit);
|
|
79
|
-
}
|
|
80
|
-
if (collapsedCount && (opts === null || opts === void 0 ? void 0 : opts.showLast))
|
|
81
|
-
s += behind + middleBranch + renderCollapsedChildren(collapsedCount) + '\n';
|
|
82
|
-
itemsToRender.forEach((childNode, i) => {
|
|
83
|
-
const last = i + 1 === count;
|
|
84
|
-
const branch = last ? endBranch : middleBranch;
|
|
85
|
-
const nextBehind = behind + (last ? ' ' : vLine) + ' '.repeat(branchWidth);
|
|
86
|
-
s += behind + branch + renderLabel(childNode, nextBehind) + '\n';
|
|
87
|
-
if (typeof childNode === 'object') {
|
|
88
|
-
treeNode(childNode, nextBehind, level + 1);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
if (collapsedCount && !(opts === null || opts === void 0 ? void 0 : opts.showLast))
|
|
92
|
-
s += behind + endBranch + renderCollapsedChildren(collapsedCount) + '\n';
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return s;
|
|
97
|
-
}
|
|
98
|
-
render(root, opts) {
|
|
99
|
-
return this._render(root, opts);
|
|
100
|
-
}
|
|
101
|
-
print(root, opts) {
|
|
102
|
-
const s = this.render(root, opts);
|
|
103
|
-
console.log(s);
|
|
104
|
-
return s;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
function renderCollapsedChildren(count) {
|
|
108
|
-
return dim + '+ ' + '[3m' + count.toString() + ` item${count === 1 ? '' : 's'}` + reset;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function renderCodeFragment(lines, options) {
|
|
112
|
-
const row = (options.row || 1) - 1;
|
|
113
|
-
const rowEnd = options.rowEnd ? options.rowEnd - 1 : -1;
|
|
114
|
-
const limit = Math.min(options.limit || 6, lines.length);
|
|
115
|
-
const offset = Math.min(options.offset || 3, lines.length);
|
|
116
|
-
const error = options.error;
|
|
117
|
-
const errorEnd = options.errorEnd;
|
|
118
|
-
let output = '';
|
|
119
|
-
const delta = rowEnd - row;
|
|
120
|
-
const maxIndex = lines.length;
|
|
121
|
-
if (delta > limit) {
|
|
122
|
-
let longestLine = 0;
|
|
123
|
-
const newLimit = Math.floor(limit / 2);
|
|
124
|
-
for (let i = 0; i < newLimit + offset; i++) {
|
|
125
|
-
const index = row + i - offset;
|
|
126
|
-
const line = lines[index] || '';
|
|
127
|
-
longestLine = Math.max(line.length, longestLine);
|
|
128
|
-
output += renderLine(line, index < maxIndex ? index + 1 : '', index === row ? error : undefined, index === row || index === rowEnd ? 'bold' : '');
|
|
129
|
-
}
|
|
130
|
-
let output2 = '';
|
|
131
|
-
for (let i = newLimit + offset; i > 0; i--) {
|
|
132
|
-
const index = rowEnd - i + offset;
|
|
133
|
-
const line = lines[index] || '';
|
|
134
|
-
longestLine = Math.max(line.length, longestLine);
|
|
135
|
-
output2 += renderLine(line, index < maxIndex ? index + 1 : '', index === rowEnd ? errorEnd : undefined, index === row || index === rowEnd ? 'bold' : '');
|
|
136
|
-
}
|
|
137
|
-
output += renderLine('—'.repeat(longestLine), '———', undefined, 'dim') + output2;
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
for (let i = 0; i < limit + offset; i++) {
|
|
141
|
-
const index = row + i - offset;
|
|
142
|
-
if (index <= lines.length + 1) {
|
|
143
|
-
const errorCol = index === row ? error : index === rowEnd ? errorEnd : undefined;
|
|
144
|
-
output += renderLine(lines[index], index < maxIndex ? index + 1 : '', errorCol, index === row || index === rowEnd ? 'bold' : '');
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return output;
|
|
149
|
-
}
|
|
150
|
-
function lineStyles(s) {
|
|
151
|
-
return '[94m' + (s || '')
|
|
152
|
-
.replace(/([a-z_]+)/ig, '[32m' + '$1' + '\x1b[39;33m')
|
|
153
|
-
.replace(/([\=\.\/'"`\:\+]+)/ig, '[36m' + '$1' + '[39m');
|
|
154
|
-
}
|
|
155
|
-
function lineStylesError(s) {
|
|
156
|
-
return '[31m' + (s || '') + '[0m';
|
|
157
|
-
}
|
|
158
|
-
function renderLine(line, index, error, style = '') {
|
|
159
|
-
const st = (style === 'bold' ? '[1m' : '') + (style === 'dim' ? '[2m' : '');
|
|
160
|
-
if (typeof error === 'number') {
|
|
161
|
-
const errorLength = (/[\.-\s\(\)\*\/\+\{\}\[\]\?\'\"\`\<\>]/.exec(line.slice(error + 1)) || { index: line.length - error }).index + 1;
|
|
162
|
-
return renderLineNumber(index, true) +
|
|
163
|
-
st +
|
|
164
|
-
lineStyles(line.slice(0, error)) +
|
|
165
|
-
lineStylesError(line.slice(error, error + errorLength)) +
|
|
166
|
-
lineStyles(line.slice(error + errorLength)) +
|
|
167
|
-
renderLineNumber('', true) + ' '.repeat(error) + '[31m' + '[1m' + '~'.repeat(Math.max(1, errorLength));
|
|
168
|
-
}
|
|
169
|
-
return renderLineNumber(index, undefined, style === 'bold') + st + lineStyles(line);
|
|
170
|
-
}
|
|
171
|
-
function renderLineNumber(i, isError = false, bold = false) {
|
|
172
|
-
let s = ' ';
|
|
173
|
-
const sep = i === '———';
|
|
174
|
-
if (i && i > 0 || typeof i === 'string') {
|
|
175
|
-
s = ' ' + String(i);
|
|
176
|
-
}
|
|
177
|
-
s = s.slice(s.length - 5);
|
|
178
|
-
return '\n' + '[0m' + (sep ? '[34m' : '') +
|
|
179
|
-
(isError ? '[31m' + '[1m' : (bold ? '[1m' : '[2m')) +
|
|
180
|
-
s + (sep ? i : ' | ') + '[0m';
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
function escapeRegex(s) {
|
|
184
|
-
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
class ProstoParserNodeBase {
|
|
188
|
-
addRecognizes(...args) {
|
|
189
|
-
for (const node of args) {
|
|
190
|
-
if (!this.options.recognizes)
|
|
191
|
-
this.options.recognizes = [];
|
|
192
|
-
if (!this.options.recognizes.includes(node)) {
|
|
193
|
-
this.options.recognizes.push(node);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return this;
|
|
197
|
-
}
|
|
198
|
-
addAbsorbs(node, rule = 'append') {
|
|
199
|
-
this.options.absorbs = this.options.absorbs || {};
|
|
200
|
-
if (Array.isArray(node)) {
|
|
201
|
-
node.forEach(n => {
|
|
202
|
-
this.options.absorbs[n.id] = rule;
|
|
203
|
-
this.addRecognizes(n);
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
this.options.absorbs[node.id] = rule;
|
|
208
|
-
this.addRecognizes(node);
|
|
209
|
-
}
|
|
210
|
-
return this;
|
|
211
|
-
}
|
|
212
|
-
addPopsAfterNode(...args) {
|
|
213
|
-
for (const node of args) {
|
|
214
|
-
if (!this.options.popsAfterNode)
|
|
215
|
-
this.options.popsAfterNode = [];
|
|
216
|
-
if (!this.options.popsAfterNode.includes(node)) {
|
|
217
|
-
this.options.popsAfterNode.push(node);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
this.addRecognizes(...args);
|
|
221
|
-
return this;
|
|
222
|
-
}
|
|
223
|
-
addHoistChildren(...args) {
|
|
224
|
-
if (!this.options.hoistChildren)
|
|
225
|
-
this.options.hoistChildren = [];
|
|
226
|
-
this.options.hoistChildren.push(...args);
|
|
227
|
-
return this;
|
|
228
|
-
}
|
|
229
|
-
set icon(value) {
|
|
230
|
-
this.options.icon = value;
|
|
231
|
-
}
|
|
232
|
-
set label(value) {
|
|
233
|
-
this.options.label = value;
|
|
234
|
-
}
|
|
235
|
-
get startsWith() {
|
|
236
|
-
return this.options.startsWith;
|
|
237
|
-
}
|
|
238
|
-
set startsWith(value) {
|
|
239
|
-
this.options.startsWith = value;
|
|
240
|
-
}
|
|
241
|
-
get endsWith() {
|
|
242
|
-
return this.options.endsWith;
|
|
243
|
-
}
|
|
244
|
-
set endsWith(value) {
|
|
245
|
-
this.options.endsWith = value;
|
|
246
|
-
}
|
|
247
|
-
getPopsAtEOFSource() {
|
|
248
|
-
return this.options.popsAtEOFSource;
|
|
249
|
-
}
|
|
250
|
-
popsAtEOFSource(value) {
|
|
251
|
-
this.options.popsAtEOFSource = value;
|
|
252
|
-
return this;
|
|
253
|
-
}
|
|
254
|
-
get absorbs() {
|
|
255
|
-
return this.options.absorbs;
|
|
256
|
-
}
|
|
257
|
-
get badToken() {
|
|
258
|
-
return this.options.badToken;
|
|
259
|
-
}
|
|
260
|
-
set badToken(value) {
|
|
261
|
-
this.options.badToken = value;
|
|
262
|
-
}
|
|
263
|
-
get skipToken() {
|
|
264
|
-
return this.options.skipToken;
|
|
265
|
-
}
|
|
266
|
-
set skipToken(value) {
|
|
267
|
-
this.options.skipToken = value;
|
|
268
|
-
}
|
|
269
|
-
get recognizes() {
|
|
270
|
-
return this.options.recognizes || [];
|
|
271
|
-
}
|
|
272
|
-
set recognizes(value) {
|
|
273
|
-
this.options.recognizes = value;
|
|
274
|
-
}
|
|
275
|
-
get hoistChildren() {
|
|
276
|
-
return this.options.hoistChildren || [];
|
|
277
|
-
}
|
|
278
|
-
set hoistChildren(value) {
|
|
279
|
-
this.options.hoistChildren = value;
|
|
280
|
-
}
|
|
281
|
-
getMapContent() {
|
|
282
|
-
return this.options.mapContent;
|
|
283
|
-
}
|
|
284
|
-
mapContent(key, value = 'copy') {
|
|
285
|
-
this.options.mapContent = this.options.mapContent || {};
|
|
286
|
-
this.options.mapContent[key] = value;
|
|
287
|
-
return this;
|
|
288
|
-
}
|
|
289
|
-
onMatch(value) {
|
|
290
|
-
this.options.onMatch = value;
|
|
291
|
-
return this;
|
|
292
|
-
}
|
|
293
|
-
onAppendContent(value) {
|
|
294
|
-
this.options.onAppendContent = value;
|
|
295
|
-
return this;
|
|
296
|
-
}
|
|
297
|
-
onAfterChildParse(value) {
|
|
298
|
-
this.options.onAfterChildParse = value;
|
|
299
|
-
return this;
|
|
300
|
-
}
|
|
301
|
-
onBeforeChildParse(value) {
|
|
302
|
-
this.options.onBeforeChildParse = value;
|
|
303
|
-
return this;
|
|
304
|
-
}
|
|
305
|
-
onMatchStartToken(value) {
|
|
306
|
-
if (this.options.startsWith) {
|
|
307
|
-
this.options.startsWith.onMatchToken = value;
|
|
308
|
-
}
|
|
309
|
-
return this;
|
|
310
|
-
}
|
|
311
|
-
onMatchEndToken(value) {
|
|
312
|
-
if (this.options.endsWith) {
|
|
313
|
-
this.options.endsWith.onMatchToken = value;
|
|
314
|
-
}
|
|
315
|
-
return this;
|
|
316
|
-
}
|
|
317
|
-
initCustomData(value) {
|
|
318
|
-
this.options.initCustomData = value;
|
|
319
|
-
return this;
|
|
320
|
-
}
|
|
321
|
-
onPop(value) {
|
|
322
|
-
this.options.onPop = value;
|
|
323
|
-
return this;
|
|
324
|
-
}
|
|
325
|
-
get popsAfterNode() {
|
|
326
|
-
return this.options.popsAfterNode || [];
|
|
327
|
-
}
|
|
328
|
-
set popsAfterNode(nodes) {
|
|
329
|
-
this.options.popsAfterNode = nodes;
|
|
330
|
-
}
|
|
331
|
-
clearStartsWith() {
|
|
332
|
-
delete this.options.startsWith;
|
|
333
|
-
return this;
|
|
334
|
-
}
|
|
335
|
-
clearEndsWith() {
|
|
336
|
-
delete this.options.endsWith;
|
|
337
|
-
return this;
|
|
338
|
-
}
|
|
339
|
-
clearPopsAtEOFSource() {
|
|
340
|
-
delete this.options.popsAtEOFSource;
|
|
341
|
-
return this;
|
|
342
|
-
}
|
|
343
|
-
clearBadToken() {
|
|
344
|
-
delete this.options.badToken;
|
|
345
|
-
return this;
|
|
346
|
-
}
|
|
347
|
-
clearSkipToken() {
|
|
348
|
-
delete this.options.skipToken;
|
|
349
|
-
return this;
|
|
350
|
-
}
|
|
351
|
-
clearAbsorbs(node) {
|
|
352
|
-
if (this.options.absorbs) {
|
|
353
|
-
if (node && Array.isArray(node)) {
|
|
354
|
-
for (const n of node) {
|
|
355
|
-
delete this.options.absorbs[n.id];
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
else if (node) {
|
|
359
|
-
delete this.options.absorbs[node.id];
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
362
|
-
this.options.absorbs = {};
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
return this;
|
|
366
|
-
}
|
|
367
|
-
clearRecognizes(...args) {
|
|
368
|
-
var _a;
|
|
369
|
-
if (args.length) {
|
|
370
|
-
this.options.recognizes = (_a = this.options.recognizes) === null || _a === void 0 ? void 0 : _a.filter(n => !args.includes(n));
|
|
371
|
-
}
|
|
372
|
-
else {
|
|
373
|
-
this.options.recognizes = [];
|
|
374
|
-
}
|
|
375
|
-
return this;
|
|
376
|
-
}
|
|
377
|
-
clearHoistChildren() {
|
|
378
|
-
delete this.options.hoistChildren;
|
|
379
|
-
return this;
|
|
380
|
-
}
|
|
381
|
-
clearMapContent() {
|
|
382
|
-
delete this.options.mapContent;
|
|
383
|
-
return this;
|
|
384
|
-
}
|
|
385
|
-
removeOnPop() {
|
|
386
|
-
delete this.options.onPop;
|
|
387
|
-
return this;
|
|
388
|
-
}
|
|
389
|
-
removeOnMatch() {
|
|
390
|
-
delete this.options.onMatch;
|
|
391
|
-
return this;
|
|
392
|
-
}
|
|
393
|
-
removeOnAppendContent() {
|
|
394
|
-
delete this.options.onAppendContent;
|
|
395
|
-
return this;
|
|
396
|
-
}
|
|
397
|
-
removeOnBeforeChildParse() {
|
|
398
|
-
delete this.options.onBeforeChildParse;
|
|
399
|
-
return this;
|
|
400
|
-
}
|
|
401
|
-
removeOnAfterChildParse() {
|
|
402
|
-
delete this.options.onAfterChildParse;
|
|
403
|
-
return this;
|
|
404
|
-
}
|
|
405
|
-
fireNodeMatched(matched, cbData) {
|
|
406
|
-
return this.options.startsWith ? this.fireMatched(this.options.startsWith, matched, cbData) : { confirmed: true };
|
|
407
|
-
}
|
|
408
|
-
fireNodeEndMatched(matched, cbData) {
|
|
409
|
-
return this.options.endsWith ? this.fireMatched(this.options.endsWith, matched, cbData) : { confirmed: true };
|
|
410
|
-
}
|
|
411
|
-
fireMatched(descr, matched, cbData) {
|
|
412
|
-
const { omit, eject, onMatchToken } = descr;
|
|
413
|
-
let cbResult = true;
|
|
414
|
-
if (onMatchToken) {
|
|
415
|
-
cbResult = onMatchToken({
|
|
416
|
-
...cbData,
|
|
417
|
-
matched,
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
const cbOmit = typeof cbResult === 'object' ? cbResult.omit : undefined;
|
|
421
|
-
const cbEject = typeof cbResult === 'object' ? cbResult.eject : undefined;
|
|
422
|
-
return {
|
|
423
|
-
omit: cbOmit !== undefined ? cbOmit : omit,
|
|
424
|
-
eject: cbEject !== undefined ? cbEject : eject,
|
|
425
|
-
confirmed: cbResult !== false,
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
getStartTokenRg() {
|
|
429
|
-
return this.getRgOutOfTokenDescriptor(this.options.startsWith);
|
|
430
|
-
}
|
|
431
|
-
getEndTokenRg() {
|
|
432
|
-
return this.getRgOutOfTokenDescriptor(this.options.endsWith);
|
|
433
|
-
}
|
|
434
|
-
getConstraintTokens() {
|
|
435
|
-
return {
|
|
436
|
-
skip: this.getRgOutOfTokenDescriptor(this.options.skipToken ? { token: this.options.skipToken } : undefined) || undefined,
|
|
437
|
-
bad: this.getRgOutOfTokenDescriptor(this.options.badToken ? { token: this.options.badToken } : undefined) || undefined,
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
getRgOutOfTokenDescriptor(descr) {
|
|
441
|
-
if (descr) {
|
|
442
|
-
const prefix = descr.ignoreBackSlashed ? /(?<=(?:^|[^\\])(?:\\\\)*)/.source : '';
|
|
443
|
-
let token;
|
|
444
|
-
if (typeof descr.token === 'function') {
|
|
445
|
-
token = descr.token(this);
|
|
446
|
-
}
|
|
447
|
-
else {
|
|
448
|
-
token = descr.token;
|
|
449
|
-
}
|
|
450
|
-
if (token instanceof RegExp) {
|
|
451
|
-
return new RegExp(prefix + token.source, token.flags);
|
|
452
|
-
}
|
|
453
|
-
else {
|
|
454
|
-
return new RegExp(`${prefix}(?:${[token].flat().map(t => escapeRegex(t)).join('|')})`);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
class ProstoHoistManager {
|
|
461
|
-
constructor() {
|
|
462
|
-
this.data = {};
|
|
463
|
-
}
|
|
464
|
-
addHoistOptions(ctx) {
|
|
465
|
-
if (ctx.hoistChildren) {
|
|
466
|
-
ctx.hoistChildren.forEach(options => {
|
|
467
|
-
const nodeId = typeof options.node === 'object' ? options.node.id : options.node;
|
|
468
|
-
const hoist = this.data[nodeId] = (this.data[nodeId] || {});
|
|
469
|
-
if (hoist) {
|
|
470
|
-
hoist[ctx.index] = {
|
|
471
|
-
options,
|
|
472
|
-
context: ctx,
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
removeHoistOptions(ctx) {
|
|
479
|
-
if (ctx.hoistChildren) {
|
|
480
|
-
ctx.hoistChildren.forEach(options => {
|
|
481
|
-
const nodeId = typeof options.node === 'object' ? options.node.id : options.node;
|
|
482
|
-
const hoist = this.data[nodeId];
|
|
483
|
-
if (hoist) {
|
|
484
|
-
delete hoist[ctx.index];
|
|
485
|
-
}
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
processHoistOptions(ctx) {
|
|
490
|
-
const id = ctx.node.id;
|
|
491
|
-
const hoist = this.data[id];
|
|
492
|
-
if (hoist) {
|
|
493
|
-
Object.keys(hoist).map(i => hoist[i]).forEach(({ options, context }) => {
|
|
494
|
-
const customData = context.getCustomData();
|
|
495
|
-
if (options.deep === true || Number(options.deep) >= (ctx.level - context.level)) {
|
|
496
|
-
if (options.asArray) {
|
|
497
|
-
const hoisted = customData[options.as] = (customData[options.as] || []);
|
|
498
|
-
if (!Array.isArray(hoisted)) {
|
|
499
|
-
if (!options.onConflict || options.onConflict === 'error') {
|
|
500
|
-
throw new Error(`Can not hoist "${ctx.node.name}" to "${context.node.name}" as "${options.as}". "${options.as}" already exists and it is not an Array Type.`);
|
|
501
|
-
}
|
|
502
|
-
else if (options.onConflict === 'overwrite') {
|
|
503
|
-
customData[options.as] = [doTheMapRule(options, ctx)];
|
|
504
|
-
}
|
|
505
|
-
else if (options.onConflict !== 'ignore') {
|
|
506
|
-
throw new Error(`Unsupported hoisting option onConflict "${options.onConflict}"`);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
else {
|
|
510
|
-
hoisted.push(doTheMapRule(options, ctx));
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
else {
|
|
514
|
-
if (customData[options.as]) {
|
|
515
|
-
if (!options.onConflict || options.onConflict === 'error') {
|
|
516
|
-
throw new Error(`Can not hoist multiple "${ctx.node.name}" to "${context.node.name}" as "${options.as}". "${options.as}" already exists.`);
|
|
517
|
-
}
|
|
518
|
-
else if (options.onConflict === 'overwrite') {
|
|
519
|
-
customData[options.as] = doTheMapRule(options, ctx);
|
|
520
|
-
}
|
|
521
|
-
else if (options.onConflict !== 'ignore') {
|
|
522
|
-
throw new Error(`Unsupported hoisting option onConflict "${options.onConflict}"`);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
else {
|
|
526
|
-
customData[options.as] = doTheMapRule(options, ctx);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
if (options.removeChildFromContent) {
|
|
530
|
-
context.content = context.content.filter(c => c !== ctx);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
function doTheMapRule(options, ctx) {
|
|
536
|
-
var _a;
|
|
537
|
-
if (typeof options.mapRule === 'function') {
|
|
538
|
-
return options.mapRule(ctx);
|
|
539
|
-
}
|
|
540
|
-
if (options.mapRule === 'content.join') {
|
|
541
|
-
return ctx.content.join('');
|
|
542
|
-
}
|
|
543
|
-
if ((_a = options.mapRule) === null || _a === void 0 ? void 0 : _a.startsWith('customData')) {
|
|
544
|
-
const key = options.mapRule.slice(11);
|
|
545
|
-
if (key) {
|
|
546
|
-
return ctx.getCustomData()[key];
|
|
547
|
-
}
|
|
548
|
-
else {
|
|
549
|
-
return ctx.getCustomData();
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
return ctx;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
const banner$1 = '[31m' + '[parser]' + '[39m';
|
|
558
|
-
class ProstoParserContext {
|
|
559
|
-
constructor(root) {
|
|
560
|
-
this.root = root;
|
|
561
|
-
this.nodes = {};
|
|
562
|
-
this.pos = 0;
|
|
563
|
-
this.index = 0;
|
|
564
|
-
this.behind = '';
|
|
565
|
-
this.here = '';
|
|
566
|
-
this.src = '';
|
|
567
|
-
this.stack = [];
|
|
568
|
-
this.l = 0;
|
|
569
|
-
this.hoistManager = new ProstoHoistManager();
|
|
570
|
-
this.context = root;
|
|
571
|
-
}
|
|
572
|
-
parse(src) {
|
|
573
|
-
this.src = src,
|
|
574
|
-
this.here = src,
|
|
575
|
-
this.l = src.length;
|
|
576
|
-
const cache = {};
|
|
577
|
-
while (this.pos < this.l) {
|
|
578
|
-
const searchTokens = this.context.getSearchTokens();
|
|
579
|
-
let closestIndex = Number.MAX_SAFE_INTEGER;
|
|
580
|
-
let closestToken;
|
|
581
|
-
let matched;
|
|
582
|
-
for (const t of searchTokens) {
|
|
583
|
-
const key = t.g.source;
|
|
584
|
-
t.g.lastIndex = this.pos;
|
|
585
|
-
let cached = cache[key];
|
|
586
|
-
if (cached === null)
|
|
587
|
-
continue;
|
|
588
|
-
if (cached && cached.index < this.pos) {
|
|
589
|
-
cached = null;
|
|
590
|
-
delete cache[key];
|
|
591
|
-
}
|
|
592
|
-
if (!cached) {
|
|
593
|
-
cached = t.g.exec(this.src);
|
|
594
|
-
if (cached || (this.pos === 0 && !cached)) {
|
|
595
|
-
cache[key] = cached;
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
if (cached && cached.index < closestIndex) {
|
|
599
|
-
closestIndex = cached.index;
|
|
600
|
-
matched = cached;
|
|
601
|
-
closestToken = t;
|
|
602
|
-
if (closestIndex === this.pos)
|
|
603
|
-
break;
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
if (closestToken && matched) {
|
|
607
|
-
const toAppend = this.src.slice(this.pos, closestIndex);
|
|
608
|
-
if (toAppend) {
|
|
609
|
-
this.context.appendContent(toAppend);
|
|
610
|
-
this.jump(toAppend.length);
|
|
611
|
-
}
|
|
612
|
-
const matchedToken = matched[0];
|
|
613
|
-
if (closestToken.node) {
|
|
614
|
-
const { omit, eject, confirmed } = closestToken.node.fireNodeMatched(matched, this.getCallbackData(matched));
|
|
615
|
-
if (!confirmed)
|
|
616
|
-
continue;
|
|
617
|
-
let toAppend = '';
|
|
618
|
-
if (eject) {
|
|
619
|
-
this.context.appendContent(matchedToken);
|
|
620
|
-
}
|
|
621
|
-
else if (!omit) {
|
|
622
|
-
toAppend = matchedToken;
|
|
623
|
-
}
|
|
624
|
-
this.jump(matchedToken.length);
|
|
625
|
-
this.pushNewContext(closestToken.node, toAppend ? [toAppend] : []);
|
|
626
|
-
this.context.fireOnMatch(matched);
|
|
627
|
-
continue;
|
|
628
|
-
}
|
|
629
|
-
else {
|
|
630
|
-
const { omit, eject, confirmed } = this.context.fireNodeEndMatched(matched, this.getCallbackData(matched));
|
|
631
|
-
if (!confirmed)
|
|
632
|
-
continue;
|
|
633
|
-
if (!eject && !omit) {
|
|
634
|
-
this.context.appendContent(matchedToken);
|
|
635
|
-
}
|
|
636
|
-
if (!eject) {
|
|
637
|
-
this.jump(matchedToken.length);
|
|
638
|
-
}
|
|
639
|
-
this.context.mapNamedGroups(matched);
|
|
640
|
-
this.pop();
|
|
641
|
-
continue;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
else {
|
|
645
|
-
this.context.appendContent(this.here);
|
|
646
|
-
this.jump(this.here.length);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
if (this.context !== this.root) {
|
|
650
|
-
while (this.context.getPopsAtEOFSource() && this.stack.length > 0)
|
|
651
|
-
this.pop();
|
|
652
|
-
}
|
|
653
|
-
if (this.context !== this.root) {
|
|
654
|
-
this.panicBlock(`Unexpected end of the source string while parsing "${this.context.node.name}" (${this.context.index}) node.`);
|
|
655
|
-
}
|
|
656
|
-
return this.root;
|
|
657
|
-
}
|
|
658
|
-
pop() {
|
|
659
|
-
const parentContext = this.stack.pop();
|
|
660
|
-
this.context.fireOnPop();
|
|
661
|
-
if (parentContext) {
|
|
662
|
-
parentContext.fireAfterChildParse(this.context);
|
|
663
|
-
parentContext.fireAbsorb(this.context);
|
|
664
|
-
this.context.cleanup();
|
|
665
|
-
const node = this.context.node;
|
|
666
|
-
this.context = parentContext;
|
|
667
|
-
if (parentContext.popsAfterNode.includes(node)) {
|
|
668
|
-
this.pop();
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
else {
|
|
672
|
-
this.context.cleanup();
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
pushNewContext(newNode, content) {
|
|
676
|
-
this.index++;
|
|
677
|
-
const ctx = newNode.createContext(this.index, this.stack.length + 1, this);
|
|
678
|
-
ctx.content = content;
|
|
679
|
-
this.context.fireBeforeChildParse(ctx);
|
|
680
|
-
this.context.pushChild(ctx);
|
|
681
|
-
this.stack.push(this.context);
|
|
682
|
-
this.hoistManager.addHoistOptions(this.context);
|
|
683
|
-
this.context = ctx;
|
|
684
|
-
return ctx;
|
|
685
|
-
}
|
|
686
|
-
fromStack(depth = 0) {
|
|
687
|
-
return this.stack[this.stack.length - depth - 1];
|
|
688
|
-
}
|
|
689
|
-
jump(n = 1) {
|
|
690
|
-
this.pos += n;
|
|
691
|
-
this.behind = this.src.slice(0, this.pos);
|
|
692
|
-
this.here = this.src.slice(this.pos, this.l);
|
|
693
|
-
return this.pos;
|
|
694
|
-
}
|
|
695
|
-
getCallbackData(matched) {
|
|
696
|
-
return {
|
|
697
|
-
parserContext: this,
|
|
698
|
-
context: this.context,
|
|
699
|
-
matched,
|
|
700
|
-
customData: this.context.getCustomData(),
|
|
701
|
-
};
|
|
702
|
-
}
|
|
703
|
-
getPosition(offset = 0) {
|
|
704
|
-
var _a;
|
|
705
|
-
const past = this.src.slice(0, this.pos + offset).split('\n');
|
|
706
|
-
const row = past.length;
|
|
707
|
-
const col = ((_a = past.pop()) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
708
|
-
return {
|
|
709
|
-
row, col, pos: this.pos,
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
panic(message, errorBackOffset = 0) {
|
|
713
|
-
if (this.pos > 0) {
|
|
714
|
-
const { row, col } = this.getPosition(-errorBackOffset);
|
|
715
|
-
console.error(banner$1 + '[91m', message, '[0m');
|
|
716
|
-
console.log(this.context.toTree({ childrenLimit: 5, showLast: true, level: 1 }));
|
|
717
|
-
console.error(renderCodeFragment(this.src.split('\n'), {
|
|
718
|
-
row: row,
|
|
719
|
-
error: col,
|
|
720
|
-
}));
|
|
721
|
-
}
|
|
722
|
-
throw new Error(message);
|
|
723
|
-
}
|
|
724
|
-
panicBlock(message, topBackOffset = 0, bottomBackOffset = 0) {
|
|
725
|
-
if (this.pos > 0) {
|
|
726
|
-
const { row, col } = this.getPosition(-bottomBackOffset);
|
|
727
|
-
console.error(banner$1 + '[91m', message, '[0m');
|
|
728
|
-
console.log(this.context.toTree({ childrenLimit: 13, showLast: true, level: 12 }));
|
|
729
|
-
console.error(renderCodeFragment(this.src.split('\n'), {
|
|
730
|
-
row: this.context.startPos.row,
|
|
731
|
-
error: this.context.startPos.col - topBackOffset,
|
|
732
|
-
rowEnd: row,
|
|
733
|
-
errorEnd: col,
|
|
734
|
-
}));
|
|
735
|
-
}
|
|
736
|
-
throw new Error(message);
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
const styles = {
|
|
741
|
-
banner: (s) => '[31m' + s + '[39m',
|
|
742
|
-
text: (s) => '[32m' + s + '[39m',
|
|
743
|
-
valuesDim: (s) => '[36m' + '[2m' + s + '[39m' + '[22m',
|
|
744
|
-
boolean: (s) => '[94m' + s + '[39m',
|
|
745
|
-
booleanDim: (s) => '[94m' + '[2m' + s + '[39m' + '[22m',
|
|
746
|
-
underscore: (s) => '[4m' + s + '[24m',
|
|
747
|
-
values: (s) => (typeof s === 'string' ? '[96m' : '[93m') + cut(s.toString(), 30) + '[39m',
|
|
748
|
-
nodeDim: (s) => '[33m' + '[2m' + s + '[39m' + '[22m',
|
|
749
|
-
node: (s) => '[33m' + s + '[39m',
|
|
750
|
-
};
|
|
751
|
-
const stringOutputLimit = 70;
|
|
752
|
-
const parserTree = new ProstoTree({
|
|
753
|
-
children: 'content',
|
|
754
|
-
renderLabel: (context) => {
|
|
755
|
-
if (typeof context === 'string') {
|
|
756
|
-
return styles.text('«' + cut(context, stringOutputLimit) + '[32m' + '»');
|
|
757
|
-
}
|
|
758
|
-
else if (typeof context === 'object' && context instanceof ProstoParserNodeContext) {
|
|
759
|
-
let keys = '';
|
|
760
|
-
const data = context.getCustomData();
|
|
761
|
-
Object.keys(data).forEach(key => {
|
|
762
|
-
const val = data[key];
|
|
763
|
-
if (typeof val === 'string' || typeof val === 'number') {
|
|
764
|
-
keys += ' ' + styles.valuesDim(key + '(') + styles.values(val) + styles.valuesDim(')');
|
|
765
|
-
}
|
|
766
|
-
else if (Array.isArray(val)) {
|
|
767
|
-
keys += ' ' + styles.valuesDim(key + `[${val.length}]`);
|
|
768
|
-
}
|
|
769
|
-
else if (typeof val === 'object') {
|
|
770
|
-
keys += ' ' + styles.valuesDim(`{ ${key} }`);
|
|
771
|
-
}
|
|
772
|
-
else if (typeof val === 'boolean' && val) {
|
|
773
|
-
const st = key ? styles.boolean : styles.booleanDim;
|
|
774
|
-
keys += ' ' + `${styles.underscore(st(key))}${st(val ? '☑' : '☐')}`;
|
|
775
|
-
}
|
|
776
|
-
});
|
|
777
|
-
return styles.node(context.icon + (context.label ? ' ' : '')) + styles.nodeDim(context.label) + keys;
|
|
778
|
-
}
|
|
779
|
-
return '';
|
|
780
|
-
},
|
|
781
|
-
});
|
|
782
|
-
function cut(s, n) {
|
|
783
|
-
const c = s.replace(/\n/g, '\\n');
|
|
784
|
-
if (c.length <= n)
|
|
785
|
-
return c;
|
|
786
|
-
return c.slice(0, n) + '[33m' + '…';
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
class ProstoParserNodeContext extends ProstoParserNodeBase {
|
|
790
|
-
constructor(_node, index, level, parserContext) {
|
|
791
|
-
super();
|
|
792
|
-
this._node = _node;
|
|
793
|
-
this.index = index;
|
|
794
|
-
this.level = level;
|
|
795
|
-
this.content = [];
|
|
796
|
-
this._customData = {};
|
|
797
|
-
this.hasNodes = [];
|
|
798
|
-
this.count = {};
|
|
799
|
-
this.mapContentRules = {
|
|
800
|
-
'first': (content) => content[0],
|
|
801
|
-
'shift': (content) => content.shift(),
|
|
802
|
-
'pop': (content) => content.pop(),
|
|
803
|
-
'last': (content) => content[content.length - 1],
|
|
804
|
-
'join': (content) => content.join(''),
|
|
805
|
-
'join-clear': (content) => content.splice(0).join(''),
|
|
806
|
-
'copy': (content) => content,
|
|
807
|
-
};
|
|
808
|
-
this.options = _node.getOptions();
|
|
809
|
-
if (this.options.initCustomData) {
|
|
810
|
-
this._customData = this.options.initCustomData();
|
|
811
|
-
}
|
|
812
|
-
this._label = this.options.label || '';
|
|
813
|
-
this._icon = this.options.icon || '◦';
|
|
814
|
-
this.parserContext = parserContext || new ProstoParserContext(this);
|
|
815
|
-
if (parserContext) {
|
|
816
|
-
this.parent = parserContext.context || parserContext.root;
|
|
817
|
-
}
|
|
818
|
-
this.startPos = this.parserContext.getPosition();
|
|
819
|
-
this.endPos = this.parserContext.getPosition();
|
|
820
|
-
}
|
|
821
|
-
getOptions() {
|
|
822
|
-
return this.options;
|
|
823
|
-
}
|
|
824
|
-
extractCustomDataTree() {
|
|
825
|
-
let content = this.content;
|
|
826
|
-
if (this.contentCopiedTo) {
|
|
827
|
-
content = this.customData[this.contentCopiedTo];
|
|
828
|
-
}
|
|
829
|
-
if (Array.isArray(content)) {
|
|
830
|
-
return content.map(c => {
|
|
831
|
-
if (typeof c === 'string') {
|
|
832
|
-
return c;
|
|
833
|
-
}
|
|
834
|
-
else {
|
|
835
|
-
return extract(c);
|
|
836
|
-
}
|
|
837
|
-
});
|
|
838
|
-
}
|
|
839
|
-
else {
|
|
840
|
-
const c = content;
|
|
841
|
-
if (c instanceof ProstoParserNodeContext) {
|
|
842
|
-
return extract(c);
|
|
843
|
-
}
|
|
844
|
-
else {
|
|
845
|
-
return content;
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
function extract(c) {
|
|
849
|
-
const cd = { ...c.getCustomData() };
|
|
850
|
-
if (c.contentCopiedTo) {
|
|
851
|
-
cd[c.contentCopiedTo] = c.extractCustomDataTree();
|
|
852
|
-
}
|
|
853
|
-
return cd;
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
getPrevNode(n = 1) {
|
|
857
|
-
if (this.parent) {
|
|
858
|
-
const index = this.parent.content.findIndex(n => n === this) - n;
|
|
859
|
-
if (index >= 0)
|
|
860
|
-
return this.parent.content[index];
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
getPrevContext(n = 1) {
|
|
864
|
-
if (this.parent) {
|
|
865
|
-
const contexts = this.parent.content.filter(n => n instanceof ProstoParserNodeContext);
|
|
866
|
-
const index = contexts.findIndex(n => n === this) - n;
|
|
867
|
-
if (index >= 0)
|
|
868
|
-
return contexts[index];
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
set icon(value) {
|
|
872
|
-
this._icon = value;
|
|
873
|
-
}
|
|
874
|
-
get icon() {
|
|
875
|
-
return this._icon;
|
|
876
|
-
}
|
|
877
|
-
set label(value) {
|
|
878
|
-
this._label = value;
|
|
879
|
-
}
|
|
880
|
-
get label() {
|
|
881
|
-
return this._label;
|
|
882
|
-
}
|
|
883
|
-
getCustomData() {
|
|
884
|
-
return this._customData;
|
|
885
|
-
}
|
|
886
|
-
get customData() {
|
|
887
|
-
return this._customData;
|
|
888
|
-
}
|
|
889
|
-
get nodeId() {
|
|
890
|
-
return this._node.id;
|
|
891
|
-
}
|
|
892
|
-
get node() {
|
|
893
|
-
return this._node;
|
|
894
|
-
}
|
|
895
|
-
toTree(options) {
|
|
896
|
-
return parserTree.render(this, options);
|
|
897
|
-
}
|
|
898
|
-
getSearchTokens() {
|
|
899
|
-
var _a;
|
|
900
|
-
const rg = this.getEndTokenRg();
|
|
901
|
-
const tokens = rg ? [{
|
|
902
|
-
rg,
|
|
903
|
-
y: addFlag(rg, 'y'),
|
|
904
|
-
g: addFlag(rg, 'g'),
|
|
905
|
-
}] : [];
|
|
906
|
-
(_a = this.options.recognizes) === null || _a === void 0 ? void 0 : _a.forEach(node => {
|
|
907
|
-
const rg = node.getStartTokenRg();
|
|
908
|
-
if (rg) {
|
|
909
|
-
tokens.push({
|
|
910
|
-
rg,
|
|
911
|
-
y: addFlag(rg, 'y'),
|
|
912
|
-
g: addFlag(rg, 'g'),
|
|
913
|
-
node,
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
});
|
|
917
|
-
function addFlag(rg, f) {
|
|
918
|
-
return new RegExp(rg.source, rg.flags + f);
|
|
919
|
-
}
|
|
920
|
-
return tokens;
|
|
921
|
-
}
|
|
922
|
-
appendContent(input) {
|
|
923
|
-
let s = input;
|
|
924
|
-
this.endPos = this.parserContext.getPosition();
|
|
925
|
-
let { skip, bad } = this.getConstraintTokens();
|
|
926
|
-
skip = skip ? new RegExp(skip.source, skip.flags + 'g') : skip;
|
|
927
|
-
bad = bad ? new RegExp(bad.source, bad.flags + 'g') : bad;
|
|
928
|
-
if (skip) {
|
|
929
|
-
s = s.replace(skip, '');
|
|
930
|
-
}
|
|
931
|
-
if (bad) {
|
|
932
|
-
const m = bad.exec(s);
|
|
933
|
-
if (m) {
|
|
934
|
-
this.parserContext.jump(m.index);
|
|
935
|
-
this.parserContext.panic(`The token "${m[0].replace(/"/g, '\\"')}" is not allowed in "${this.node.name}".`);
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
s = this.fireOnAppendContent(s);
|
|
939
|
-
if (s) {
|
|
940
|
-
this.content.push(s);
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
cleanup() {
|
|
944
|
-
this.options = null;
|
|
945
|
-
}
|
|
946
|
-
pushChild(child) {
|
|
947
|
-
const absorbRule = this.options.absorbs && this.options.absorbs[child.node.id];
|
|
948
|
-
if (!absorbRule) {
|
|
949
|
-
this.content.push(child);
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
fireAbsorb(child) {
|
|
953
|
-
const absorbRule = this.options.absorbs && this.options.absorbs[child.node.id];
|
|
954
|
-
if (absorbRule) {
|
|
955
|
-
switch (absorbRule) {
|
|
956
|
-
case 'append':
|
|
957
|
-
this.content.push(...child.content);
|
|
958
|
-
break;
|
|
959
|
-
case 'join':
|
|
960
|
-
this.appendContent(child.content.join(''));
|
|
961
|
-
break;
|
|
962
|
-
default:
|
|
963
|
-
const [action, target] = absorbRule.split('->');
|
|
964
|
-
const cd = this.getCustomData();
|
|
965
|
-
if (action === 'copy') {
|
|
966
|
-
cd[target] = child.content;
|
|
967
|
-
}
|
|
968
|
-
else if (action === 'join') {
|
|
969
|
-
cd[target] = child.content.join('');
|
|
970
|
-
}
|
|
971
|
-
else {
|
|
972
|
-
this.parserContext.panic(`Absorb action "${action}" is not supported.`);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
has(node) {
|
|
978
|
-
return this.hasNodes.includes(node);
|
|
979
|
-
}
|
|
980
|
-
countOf(node) {
|
|
981
|
-
return this.count[node.id] || 0;
|
|
982
|
-
}
|
|
983
|
-
mapNamedGroups(matched) {
|
|
984
|
-
if (matched.groups) {
|
|
985
|
-
const cd = this.getCustomData();
|
|
986
|
-
for (const [key, value] of Object.entries(matched.groups)) {
|
|
987
|
-
if (key === 'content') {
|
|
988
|
-
this.appendContent(value);
|
|
989
|
-
}
|
|
990
|
-
else {
|
|
991
|
-
cd[key] = value;
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
fireOnPop() {
|
|
997
|
-
this.endPos = this.parserContext.getPosition();
|
|
998
|
-
this.processMappings();
|
|
999
|
-
const data = this.parserContext.getCallbackData();
|
|
1000
|
-
this.node.beforeOnPop(data);
|
|
1001
|
-
if (this.options.onPop) {
|
|
1002
|
-
this.options.onPop(data);
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
fireOnMatch(matched) {
|
|
1006
|
-
this.mapNamedGroups(matched);
|
|
1007
|
-
const data = this.parserContext.getCallbackData(matched);
|
|
1008
|
-
this.node.beforeOnMatch(data);
|
|
1009
|
-
if (this.options.onMatch) {
|
|
1010
|
-
return this.options.onMatch(data);
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
fireBeforeChildParse(child) {
|
|
1014
|
-
const data = this.parserContext.getCallbackData();
|
|
1015
|
-
this.node.beforeOnBeforeChildParse(child, data);
|
|
1016
|
-
if (this.options.onBeforeChildParse) {
|
|
1017
|
-
return this.options.onBeforeChildParse(child, data);
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
fireAfterChildParse(child) {
|
|
1021
|
-
if (!this.hasNodes.includes(child.node)) {
|
|
1022
|
-
this.hasNodes.push(child.node);
|
|
1023
|
-
}
|
|
1024
|
-
this.count[child.node.id] = this.count[child.node.id] || 0;
|
|
1025
|
-
this.count[child.node.id]++;
|
|
1026
|
-
const data = this.parserContext.getCallbackData();
|
|
1027
|
-
this.node.beforeOnAfterChildParse(child, data);
|
|
1028
|
-
if (this.options.onAfterChildParse) {
|
|
1029
|
-
return this.options.onAfterChildParse(child, data);
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
fireOnAppendContent(s) {
|
|
1033
|
-
let _s = s;
|
|
1034
|
-
const data = this.parserContext.getCallbackData();
|
|
1035
|
-
_s = this.node.beforeOnAppendContent(_s, data);
|
|
1036
|
-
if (this.options.onAppendContent) {
|
|
1037
|
-
_s = this.options.onAppendContent(_s, data);
|
|
1038
|
-
}
|
|
1039
|
-
return _s;
|
|
1040
|
-
}
|
|
1041
|
-
processMappings() {
|
|
1042
|
-
this.parserContext.hoistManager.removeHoistOptions(this);
|
|
1043
|
-
this.parserContext.hoistManager.processHoistOptions(this);
|
|
1044
|
-
this.processMapContent();
|
|
1045
|
-
}
|
|
1046
|
-
processMapContent() {
|
|
1047
|
-
const targetNodeOptions = this.options;
|
|
1048
|
-
if (targetNodeOptions.mapContent) {
|
|
1049
|
-
Object.keys(targetNodeOptions.mapContent).forEach((key) => {
|
|
1050
|
-
const keyOfT = key;
|
|
1051
|
-
if (targetNodeOptions.mapContent && targetNodeOptions.mapContent[keyOfT]) {
|
|
1052
|
-
const mapRule = targetNodeOptions.mapContent[keyOfT];
|
|
1053
|
-
if (typeof mapRule === 'function') {
|
|
1054
|
-
this._customData[keyOfT] = mapRule(this.content);
|
|
1055
|
-
}
|
|
1056
|
-
else {
|
|
1057
|
-
const ruleKey = mapRule;
|
|
1058
|
-
if (ruleKey === 'copy')
|
|
1059
|
-
this.contentCopiedTo = keyOfT;
|
|
1060
|
-
this._customData[keyOfT] = this.mapContentRules[ruleKey](this.content);
|
|
1061
|
-
}
|
|
1062
|
-
if (!this.contentCopiedTo && (typeof mapRule === 'function' || ['first', 'shift', 'pop', 'last'].includes(mapRule))) {
|
|
1063
|
-
this.contentCopiedTo = keyOfT;
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
});
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
let idCounter = 0;
|
|
1072
|
-
class ProstoParserNode extends ProstoParserNodeBase {
|
|
1073
|
-
constructor(options) {
|
|
1074
|
-
super();
|
|
1075
|
-
this.options = options;
|
|
1076
|
-
this.id = idCounter++;
|
|
1077
|
-
}
|
|
1078
|
-
getOptions() {
|
|
1079
|
-
return {
|
|
1080
|
-
label: this.options.label || '',
|
|
1081
|
-
icon: this.options.icon || '',
|
|
1082
|
-
startsWith: (this.options.startsWith ? { ...this.options.startsWith } : this.options.startsWith),
|
|
1083
|
-
endsWith: (this.options.endsWith ? { ...this.options.endsWith } : this.options.endsWith),
|
|
1084
|
-
popsAfterNode: [...(this.options.popsAfterNode || [])],
|
|
1085
|
-
popsAtEOFSource: this.options.popsAtEOFSource || false,
|
|
1086
|
-
badToken: this.options.badToken || '',
|
|
1087
|
-
skipToken: this.options.skipToken || '',
|
|
1088
|
-
recognizes: [...(this.options.recognizes || [])],
|
|
1089
|
-
hoistChildren: [...(this.options.hoistChildren || [])],
|
|
1090
|
-
mapContent: {
|
|
1091
|
-
...this.options.mapContent,
|
|
1092
|
-
},
|
|
1093
|
-
onPop: this.options.onPop,
|
|
1094
|
-
onMatch: this.options.onMatch,
|
|
1095
|
-
onAppendContent: this.options.onAppendContent,
|
|
1096
|
-
onAfterChildParse: this.options.onAfterChildParse,
|
|
1097
|
-
onBeforeChildParse: this.options.onBeforeChildParse,
|
|
1098
|
-
initCustomData: this.options.initCustomData,
|
|
1099
|
-
absorbs: this.options.absorbs,
|
|
1100
|
-
};
|
|
1101
|
-
}
|
|
1102
|
-
createContext(index, level, rootContext) {
|
|
1103
|
-
return new ProstoParserNodeContext(this, index, level, rootContext);
|
|
1104
|
-
}
|
|
1105
|
-
get name() {
|
|
1106
|
-
return this.constructor.name + '[' + this.id.toString() + ']' + '(' + (this.options.label || this.options.icon || '') + ')';
|
|
1107
|
-
}
|
|
1108
|
-
parse(source) {
|
|
1109
|
-
return this.createContext(0, 0).parserContext.parse(source);
|
|
1110
|
-
}
|
|
1111
|
-
beforeOnPop(data) {
|
|
1112
|
-
}
|
|
1113
|
-
beforeOnMatch(data) {
|
|
1114
|
-
}
|
|
1115
|
-
beforeOnAppendContent(s, data) {
|
|
1116
|
-
return s;
|
|
1117
|
-
}
|
|
1118
|
-
beforeOnAfterChildParse(child, data) {
|
|
1119
|
-
}
|
|
1120
|
-
beforeOnBeforeChildParse(child, data) {
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
class BasicNode extends ProstoParserNode {
|
|
1125
|
-
constructor(options) {
|
|
1126
|
-
var _a, _b;
|
|
1127
|
-
const startsWith = (options === null || options === void 0 ? void 0 : options.tokens) ? { token: options === null || options === void 0 ? void 0 : options.tokens[0] } : undefined;
|
|
1128
|
-
const endsWith = (options === null || options === void 0 ? void 0 : options.tokens) ? { token: options === null || options === void 0 ? void 0 : options.tokens[1] } : undefined;
|
|
1129
|
-
const [startOption, endOption] = ((_a = options.tokenOE) === null || _a === void 0 ? void 0 : _a.split('-')) || [];
|
|
1130
|
-
const [startBSlash, endBSlash] = ((_b = options.backSlash) === null || _b === void 0 ? void 0 : _b.split('-')) || [];
|
|
1131
|
-
if (startsWith) {
|
|
1132
|
-
startsWith.omit = startOption === 'omit';
|
|
1133
|
-
startsWith.eject = startOption === 'eject';
|
|
1134
|
-
startsWith.ignoreBackSlashed = startBSlash === 'ignore';
|
|
1135
|
-
}
|
|
1136
|
-
if (endsWith) {
|
|
1137
|
-
endsWith.omit = endOption === 'omit';
|
|
1138
|
-
endsWith.eject = endOption === 'eject';
|
|
1139
|
-
endsWith.ignoreBackSlashed = endBSlash === 'ignore';
|
|
1140
|
-
}
|
|
1141
|
-
super({
|
|
1142
|
-
icon: options.icon || '',
|
|
1143
|
-
label: typeof options.label === 'string' ? options.label : '',
|
|
1144
|
-
startsWith,
|
|
1145
|
-
endsWith,
|
|
1146
|
-
badToken: options.badToken,
|
|
1147
|
-
skipToken: options.skipToken,
|
|
1148
|
-
});
|
|
1149
|
-
if (options.recursive) {
|
|
1150
|
-
this.addAbsorbs(this, 'join');
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
class ParametricNodeWithRegex extends BasicNode {
|
|
1156
|
-
constructor(options, rgNode) {
|
|
1157
|
-
super(options);
|
|
1158
|
-
const hoistRegex = {
|
|
1159
|
-
as: 'regex',
|
|
1160
|
-
node: regexNode,
|
|
1161
|
-
onConflict: 'overwrite',
|
|
1162
|
-
removeChildFromContent: true,
|
|
1163
|
-
deep: 1,
|
|
1164
|
-
mapRule: ({ content }) => content.join('').replace(/^\(\^/, '(').replace(/\$\)$/, ')'),
|
|
1165
|
-
};
|
|
1166
|
-
this.mapContent('value', content => content.shift())
|
|
1167
|
-
.popsAtEOFSource(true)
|
|
1168
|
-
.addRecognizes(rgNode)
|
|
1169
|
-
.addPopsAfterNode(rgNode)
|
|
1170
|
-
.addHoistChildren(hoistRegex);
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
const regexNode = new BasicNode({
|
|
1174
|
-
label: 'RegEx',
|
|
1175
|
-
tokens: ['(', ')'],
|
|
1176
|
-
backSlash: 'ignore-ignore',
|
|
1177
|
-
recursive: true,
|
|
1178
|
-
}).onMatch(({ parserContext, context }) => {
|
|
1179
|
-
var _a;
|
|
1180
|
-
if (((_a = parserContext.fromStack()) === null || _a === void 0 ? void 0 : _a.node) === context.node) {
|
|
1181
|
-
if (!parserContext.here.startsWith('?:')) {
|
|
1182
|
-
context.content[0] += '?:';
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
});
|
|
1186
|
-
const paramNode = new ParametricNodeWithRegex({
|
|
1187
|
-
label: 'Parameter',
|
|
1188
|
-
tokens: [':', /[\/\-]/],
|
|
1189
|
-
tokenOE: 'omit-eject',
|
|
1190
|
-
backSlash: 'ignore-',
|
|
1191
|
-
}, regexNode).initCustomData(() => ({ type: EPathSegmentType.VARIABLE, value: '', regex: '([^\\/]*)' }));
|
|
1192
|
-
const wildcardNode = new ParametricNodeWithRegex({
|
|
1193
|
-
label: 'Wildcard',
|
|
1194
|
-
tokens: ['*', /[^*\()]/],
|
|
1195
|
-
tokenOE: '-eject',
|
|
1196
|
-
}, regexNode).initCustomData(() => ({ type: EPathSegmentType.WILDCARD, value: '*', regex: '(.*)' }));
|
|
1197
|
-
const staticNode = new BasicNode({
|
|
1198
|
-
label: 'Static',
|
|
1199
|
-
tokens: [/[^:\*]/, /[:\*]/],
|
|
1200
|
-
backSlash: '-ignore',
|
|
1201
|
-
tokenOE: '-eject',
|
|
1202
|
-
}).initCustomData(() => ({ type: EPathSegmentType.STATIC, value: '' }))
|
|
1203
|
-
.mapContent('value', content => content.splice(0).join('').replace(/\\:/g, ':'))
|
|
1204
|
-
.popsAtEOFSource(true);
|
|
1205
|
-
new BasicNode({}).addRecognizes(staticNode, paramNode, wildcardNode);
|
|
1206
|
-
|
|
1207
|
-
var EPathSegmentType;
|
|
1208
|
-
(function (EPathSegmentType) {
|
|
1209
|
-
EPathSegmentType[EPathSegmentType["STATIC"] = 0] = "STATIC";
|
|
1210
|
-
EPathSegmentType[EPathSegmentType["VARIABLE"] = 1] = "VARIABLE";
|
|
1211
|
-
EPathSegmentType[EPathSegmentType["REGEX"] = 2] = "REGEX";
|
|
1212
|
-
EPathSegmentType[EPathSegmentType["WILDCARD"] = 3] = "WILDCARD";
|
|
1213
|
-
})(EPathSegmentType || (EPathSegmentType = {}));
|
|
1214
|
-
|
|
1215
35
|
function useHttpContext() {
|
|
1216
36
|
return useEventContext('HTTP');
|
|
1217
37
|
}
|