@moostjs/otel 0.4.22 → 0.5.0
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 +1968 -33
- package/dist/index.mjs +1968 -33
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -347,8 +347,8 @@ function isConstructor(v) {
|
|
|
347
347
|
return typeof v === 'function' && Object.getOwnPropertyNames(v).includes('prototype') && !Object.getOwnPropertyNames(v).includes('caller') && !!v.name;
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
-
|
|
351
|
-
|
|
350
|
+
let classMetadata = new WeakMap();
|
|
351
|
+
let paramMetadata = new WeakMap();
|
|
352
352
|
const root = typeof global === 'object' ? global : typeof self === 'object' ? self : {};
|
|
353
353
|
function getMetaObject(target, prop) {
|
|
354
354
|
const isParam = typeof prop !== 'undefined';
|
|
@@ -378,6 +378,10 @@ const _reflect = {
|
|
|
378
378
|
Reflect$1.defineMetadata(key, data, target, propKey);
|
|
379
379
|
});
|
|
380
380
|
},
|
|
381
|
+
_cleanup: (() => {
|
|
382
|
+
classMetadata = new WeakMap();
|
|
383
|
+
paramMetadata = new WeakMap();
|
|
384
|
+
}),
|
|
381
385
|
};
|
|
382
386
|
if (!root.Reflect) {
|
|
383
387
|
root.Reflect = _reflect;
|
|
@@ -397,31 +401,42 @@ else {
|
|
|
397
401
|
}
|
|
398
402
|
const Reflect$1 = _reflect;
|
|
399
403
|
|
|
400
|
-
const Reflect = (global === null || global === void 0 ? void 0 : global.Reflect) ||
|
|
404
|
+
const Reflect$2 = ((global === null || global === void 0 ? void 0 : global.Reflect) ||
|
|
405
|
+
(self === null || self === void 0 ? void 0 : self.Reflect) ||
|
|
406
|
+
Reflect$1);
|
|
401
407
|
class Mate {
|
|
402
408
|
constructor(workspace, options = {}) {
|
|
403
409
|
this.workspace = workspace;
|
|
404
410
|
this.options = options;
|
|
405
411
|
this.logger = options.logger || console;
|
|
406
412
|
}
|
|
413
|
+
_cleanup() {
|
|
414
|
+
var _a;
|
|
415
|
+
(_a = Reflect$2._cleanup) === null || _a === void 0 ? void 0 : _a.call(Reflect$2);
|
|
416
|
+
}
|
|
407
417
|
set(args, key, value, isArray) {
|
|
408
418
|
var _a;
|
|
409
419
|
let level = 'CLASS';
|
|
410
|
-
const newArgs = args.level === 'CLASS'
|
|
411
|
-
|
|
420
|
+
const newArgs = args.level === 'CLASS'
|
|
421
|
+
? { target: args.target }
|
|
422
|
+
: args.level === 'PROP'
|
|
423
|
+
? { target: args.target, propKey: args.propKey }
|
|
412
424
|
: args;
|
|
413
|
-
let meta = (Reflect.getOwnMetadata(this.workspace, newArgs.target, newArgs.propKey) || {});
|
|
414
|
-
if (newArgs.propKey &&
|
|
415
|
-
|
|
425
|
+
let meta = (Reflect$2.getOwnMetadata(this.workspace, newArgs.target, newArgs.propKey) || {});
|
|
426
|
+
if (newArgs.propKey &&
|
|
427
|
+
this.options.readReturnType &&
|
|
428
|
+
!meta.returnType &&
|
|
429
|
+
args.descriptor) {
|
|
430
|
+
meta.returnType = Reflect$2.getOwnMetadata('design:returntype', newArgs.target, newArgs.propKey);
|
|
416
431
|
}
|
|
417
432
|
if (newArgs.propKey && this.options.readType && !meta.type) {
|
|
418
|
-
meta.type = Reflect.getOwnMetadata('design:type', newArgs.target, newArgs.propKey);
|
|
433
|
+
meta.type = Reflect$2.getOwnMetadata('design:type', newArgs.target, newArgs.propKey);
|
|
419
434
|
}
|
|
420
435
|
const { index } = newArgs;
|
|
421
436
|
const cb = typeof key === 'function' ? key : undefined;
|
|
422
437
|
let data = meta;
|
|
423
438
|
if (!data.params) {
|
|
424
|
-
data.params = (_a = Reflect.getOwnMetadata('design:paramtypes', newArgs.target, newArgs.propKey)) === null || _a === void 0 ? void 0 : _a.map((f) => ({ type: f }));
|
|
439
|
+
data.params = (_a = Reflect$2.getOwnMetadata('design:paramtypes', newArgs.target, newArgs.propKey)) === null || _a === void 0 ? void 0 : _a.map((f) => ({ type: f }));
|
|
425
440
|
}
|
|
426
441
|
if (typeof index === 'number') {
|
|
427
442
|
level = 'PARAM';
|
|
@@ -436,7 +451,11 @@ class Mate {
|
|
|
436
451
|
data = data.params[index];
|
|
437
452
|
}
|
|
438
453
|
}
|
|
439
|
-
else if (!index &&
|
|
454
|
+
else if (!index &&
|
|
455
|
+
!args.descriptor &&
|
|
456
|
+
args.propKey &&
|
|
457
|
+
this.options.collectPropKeys &&
|
|
458
|
+
args.level !== 'CLASS') {
|
|
440
459
|
this.set({ ...args, level: 'CLASS' }, (meta) => {
|
|
441
460
|
if (!meta.properties) {
|
|
442
461
|
meta.properties = [args.propKey];
|
|
@@ -447,7 +466,14 @@ class Mate {
|
|
|
447
466
|
return meta;
|
|
448
467
|
});
|
|
449
468
|
}
|
|
450
|
-
level =
|
|
469
|
+
level =
|
|
470
|
+
typeof index === 'number'
|
|
471
|
+
? 'PARAM'
|
|
472
|
+
: newArgs.propKey && newArgs.descriptor
|
|
473
|
+
? 'METHOD'
|
|
474
|
+
: newArgs.propKey
|
|
475
|
+
? 'PROP'
|
|
476
|
+
: 'CLASS';
|
|
451
477
|
if (typeof key !== 'function') {
|
|
452
478
|
if (isArray) {
|
|
453
479
|
const newArray = (data[key] || []);
|
|
@@ -464,14 +490,14 @@ class Mate {
|
|
|
464
490
|
else if (cb && typeof index !== 'number') {
|
|
465
491
|
meta = cb(data, level, args.propKey, typeof args.index === 'number' ? args.index : undefined);
|
|
466
492
|
}
|
|
467
|
-
Reflect.defineMetadata(this.workspace, meta, newArgs.target, newArgs.propKey);
|
|
493
|
+
Reflect$2.defineMetadata(this.workspace, meta, newArgs.target, newArgs.propKey);
|
|
468
494
|
}
|
|
469
495
|
read(target, propKey) {
|
|
470
496
|
var _a;
|
|
471
497
|
const isConstr = isConstructor(target);
|
|
472
498
|
const constructor = isConstr ? target : getConstructor$1(target);
|
|
473
499
|
const proto = constructor.prototype;
|
|
474
|
-
let ownMeta = Reflect.getOwnMetadata(this.workspace, typeof propKey === 'string' ? proto : constructor, propKey);
|
|
500
|
+
let ownMeta = Reflect$2.getOwnMetadata(this.workspace, typeof propKey === 'string' ? proto : constructor, propKey);
|
|
475
501
|
if (ownMeta && propKey === undefined && ownMeta.params === undefined) {
|
|
476
502
|
const parent = Object.getPrototypeOf(constructor);
|
|
477
503
|
if (typeof parent === 'function' &&
|
|
@@ -487,7 +513,7 @@ class Mate {
|
|
|
487
513
|
let shouldInherit = this.options.inherit;
|
|
488
514
|
if (inheritFn) {
|
|
489
515
|
if (typeof propKey === 'string') {
|
|
490
|
-
const classMeta = Reflect.getOwnMetadata(this.workspace, constructor);
|
|
516
|
+
const classMeta = Reflect$2.getOwnMetadata(this.workspace, constructor);
|
|
491
517
|
shouldInherit = inheritFn(classMeta, ownMeta, 'PROP', propKey);
|
|
492
518
|
}
|
|
493
519
|
else {
|
|
@@ -507,8 +533,7 @@ class Mate {
|
|
|
507
533
|
ownParams &&
|
|
508
534
|
(inheritedMeta === null || inheritedMeta === void 0 ? void 0 : inheritedMeta.params)) {
|
|
509
535
|
for (let i = 0; i < ownParams.length; i++) {
|
|
510
|
-
if (typeof (inheritedMeta === null || inheritedMeta === void 0 ? void 0 : inheritedMeta.params[i]) !==
|
|
511
|
-
'undefined') {
|
|
536
|
+
if (typeof (inheritedMeta === null || inheritedMeta === void 0 ? void 0 : inheritedMeta.params[i]) !== 'undefined') {
|
|
512
537
|
const ownParam = ownParams[i];
|
|
513
538
|
if (ownMeta.params &&
|
|
514
539
|
inheritFn &&
|
|
@@ -550,7 +575,13 @@ class Mate {
|
|
|
550
575
|
decorateConditional(ccb) {
|
|
551
576
|
return ((target, propKey, descriptor) => {
|
|
552
577
|
const hasIndex = typeof descriptor === 'number';
|
|
553
|
-
const decoratorLevel = hasIndex
|
|
578
|
+
const decoratorLevel = hasIndex
|
|
579
|
+
? 'PARAM'
|
|
580
|
+
: propKey && descriptor
|
|
581
|
+
? 'METHOD'
|
|
582
|
+
: propKey
|
|
583
|
+
? 'PROP'
|
|
584
|
+
: 'CLASS';
|
|
554
585
|
const d = ccb(decoratorLevel);
|
|
555
586
|
if (d) {
|
|
556
587
|
d(target, propKey, descriptor);
|
|
@@ -589,20 +620,6 @@ function useAsyncEventContext(expectedTypes) {
|
|
|
589
620
|
if (!cc) {
|
|
590
621
|
throw new Error('Event context does not exist at this point.');
|
|
591
622
|
}
|
|
592
|
-
if (expectedTypes || typeof expectedTypes === 'string') {
|
|
593
|
-
const type = cc.event.type;
|
|
594
|
-
const types = typeof expectedTypes === 'string' ? [expectedTypes] : expectedTypes;
|
|
595
|
-
if (!types.includes(type)) {
|
|
596
|
-
if (cc.parentCtx?.event.type && types.includes(cc.parentCtx.event.type)) {
|
|
597
|
-
cc = cc.parentCtx;
|
|
598
|
-
}
|
|
599
|
-
else {
|
|
600
|
-
throw new Error(`Event context type mismatch: expected ${types
|
|
601
|
-
.map(t => `"${t}"`)
|
|
602
|
-
.join(', ')}, received "${type}"`);
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
623
|
return _getCtxHelpers(cc);
|
|
607
624
|
}
|
|
608
625
|
function _getCtxHelpers(cc) {
|
|
@@ -718,6 +735,11 @@ class Infact {
|
|
|
718
735
|
this._silent = false;
|
|
719
736
|
this.logger = options.logger || console;
|
|
720
737
|
}
|
|
738
|
+
_cleanup() {
|
|
739
|
+
this.registry = {};
|
|
740
|
+
this.instanceRegistries = new WeakMap();
|
|
741
|
+
this.scopes = {};
|
|
742
|
+
}
|
|
721
743
|
setLogger(logger) {
|
|
722
744
|
this.logger = logger;
|
|
723
745
|
}
|
|
@@ -834,7 +856,7 @@ class Infact {
|
|
|
834
856
|
for (let i = 0; i < params.length; i++) {
|
|
835
857
|
const param = params[i];
|
|
836
858
|
if (param.inject) {
|
|
837
|
-
if (mergedProvide
|
|
859
|
+
if (mergedProvide[param.inject]) {
|
|
838
860
|
resolvedParams[i] = getProvidedValue(mergedProvide[param.inject]);
|
|
839
861
|
}
|
|
840
862
|
else if (param.nullable || param.optional) {
|
|
@@ -1164,6 +1186,1919 @@ const resolvePipe = definePipeFn((_value, metas, level) => {
|
|
|
1164
1186
|
},
|
|
1165
1187
|
];
|
|
1166
1188
|
|
|
1189
|
+
function getAugmentedNamespace(n) {
|
|
1190
|
+
if (n.__esModule) return n;
|
|
1191
|
+
var f = n.default;
|
|
1192
|
+
if (typeof f == "function") {
|
|
1193
|
+
var a = function a () {
|
|
1194
|
+
if (this instanceof a) {
|
|
1195
|
+
return Reflect.construct(f, arguments, this.constructor);
|
|
1196
|
+
}
|
|
1197
|
+
return f.apply(this, arguments);
|
|
1198
|
+
};
|
|
1199
|
+
a.prototype = f.prototype;
|
|
1200
|
+
} else a = {};
|
|
1201
|
+
Object.defineProperty(a, '__esModule', {value: true});
|
|
1202
|
+
Object.keys(n).forEach(function (k) {
|
|
1203
|
+
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
1204
|
+
Object.defineProperty(a, k, d.get ? d : {
|
|
1205
|
+
enumerable: true,
|
|
1206
|
+
get: function () {
|
|
1207
|
+
return n[k];
|
|
1208
|
+
}
|
|
1209
|
+
});
|
|
1210
|
+
});
|
|
1211
|
+
return a;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
var router_cjs_prod = {};
|
|
1215
|
+
|
|
1216
|
+
class ProstoCache {
|
|
1217
|
+
constructor(options) {
|
|
1218
|
+
this.data = {};
|
|
1219
|
+
this.limits = [];
|
|
1220
|
+
this.expireOrder = [];
|
|
1221
|
+
this.expireSeries = {};
|
|
1222
|
+
this.options = {
|
|
1223
|
+
limit: 1000,
|
|
1224
|
+
...options,
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
set(key, value) {
|
|
1228
|
+
var _a, _b, _c;
|
|
1229
|
+
if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.limit) === 0)
|
|
1230
|
+
return;
|
|
1231
|
+
const expires = ((_b = this.options) === null || _b === void 0 ? void 0 : _b.ttl) ? Math.round(new Date().getTime() / 1) + ((_c = this.options) === null || _c === void 0 ? void 0 : _c.ttl) : null;
|
|
1232
|
+
if (expires) {
|
|
1233
|
+
this.del(key);
|
|
1234
|
+
}
|
|
1235
|
+
this.data[key] = {
|
|
1236
|
+
value: value,
|
|
1237
|
+
expires,
|
|
1238
|
+
};
|
|
1239
|
+
if (expires) {
|
|
1240
|
+
this.pushExpires(key, expires);
|
|
1241
|
+
}
|
|
1242
|
+
this.pushLimit(key);
|
|
1243
|
+
}
|
|
1244
|
+
get(key) {
|
|
1245
|
+
var _a;
|
|
1246
|
+
return (_a = this.data[key]) === null || _a === void 0 ? void 0 : _a.value;
|
|
1247
|
+
}
|
|
1248
|
+
del(key) {
|
|
1249
|
+
const entry = this.data[key];
|
|
1250
|
+
if (entry) {
|
|
1251
|
+
delete this.data[key];
|
|
1252
|
+
if (entry.expires) {
|
|
1253
|
+
let es = this.expireSeries[entry.expires];
|
|
1254
|
+
if (es) {
|
|
1255
|
+
es = this.expireSeries[entry.expires] = es.filter(k => k !== key);
|
|
1256
|
+
}
|
|
1257
|
+
if (!es || !es.length) {
|
|
1258
|
+
delete this.expireSeries[entry.expires];
|
|
1259
|
+
const { found, index } = this.searchExpireOrder(entry.expires);
|
|
1260
|
+
if (found) {
|
|
1261
|
+
this.expireOrder.splice(index, 1);
|
|
1262
|
+
if (index === 0) {
|
|
1263
|
+
console.log('calling prepareTimeout');
|
|
1264
|
+
this.prepareTimeout();
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
reset() {
|
|
1272
|
+
this.data = {};
|
|
1273
|
+
if (this.nextTimeout) {
|
|
1274
|
+
clearTimeout(this.nextTimeout);
|
|
1275
|
+
}
|
|
1276
|
+
this.expireOrder = [];
|
|
1277
|
+
this.expireSeries = {};
|
|
1278
|
+
this.limits = [];
|
|
1279
|
+
}
|
|
1280
|
+
searchExpireOrder(time) {
|
|
1281
|
+
return binarySearch(this.expireOrder, time);
|
|
1282
|
+
}
|
|
1283
|
+
pushLimit(key) {
|
|
1284
|
+
var _a;
|
|
1285
|
+
const limit = (_a = this.options) === null || _a === void 0 ? void 0 : _a.limit;
|
|
1286
|
+
if (limit) {
|
|
1287
|
+
const newObj = [key, ...(this.limits.filter(item => item !== key && this.data[item]))];
|
|
1288
|
+
const tail = newObj.slice(limit);
|
|
1289
|
+
this.limits = newObj.slice(0, limit);
|
|
1290
|
+
if (tail.length) {
|
|
1291
|
+
tail.forEach(tailItem => {
|
|
1292
|
+
this.del(tailItem);
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
prepareTimeout() {
|
|
1298
|
+
if (this.nextTimeout) {
|
|
1299
|
+
clearTimeout(this.nextTimeout);
|
|
1300
|
+
}
|
|
1301
|
+
const time = this.expireOrder[0];
|
|
1302
|
+
const del = (time) => {
|
|
1303
|
+
for (const key of (this.expireSeries[time] || [])) {
|
|
1304
|
+
delete this.data[key];
|
|
1305
|
+
}
|
|
1306
|
+
delete this.expireSeries[time];
|
|
1307
|
+
this.expireOrder = this.expireOrder.slice(1);
|
|
1308
|
+
this.prepareTimeout();
|
|
1309
|
+
};
|
|
1310
|
+
if (time) {
|
|
1311
|
+
const delta = time - Math.round(new Date().getTime() / 1);
|
|
1312
|
+
if (delta > 0) {
|
|
1313
|
+
this.nextTimeout = setTimeout(() => {
|
|
1314
|
+
del(time);
|
|
1315
|
+
}, delta);
|
|
1316
|
+
}
|
|
1317
|
+
else {
|
|
1318
|
+
del(time);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
pushExpires(key, time) {
|
|
1323
|
+
const { found, index } = this.searchExpireOrder(time);
|
|
1324
|
+
if (!found) {
|
|
1325
|
+
this.expireOrder.splice(index, 0, time);
|
|
1326
|
+
}
|
|
1327
|
+
const e = this.expireSeries[time] = this.expireSeries[time] || [];
|
|
1328
|
+
e.push(key);
|
|
1329
|
+
if (!found && index === 0) {
|
|
1330
|
+
this.prepareTimeout();
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
function binarySearch(a, n) {
|
|
1335
|
+
let start = 0;
|
|
1336
|
+
let end = a.length - 1;
|
|
1337
|
+
let mid = 0;
|
|
1338
|
+
while (start <= end) {
|
|
1339
|
+
mid = Math.floor((start + end) / 2);
|
|
1340
|
+
if (a[mid] === n) {
|
|
1341
|
+
return {
|
|
1342
|
+
found: true,
|
|
1343
|
+
index: mid,
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
if (n < a[mid]) {
|
|
1347
|
+
end = mid - 1;
|
|
1348
|
+
mid--;
|
|
1349
|
+
}
|
|
1350
|
+
else {
|
|
1351
|
+
start = mid + 1;
|
|
1352
|
+
mid++;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
return {
|
|
1356
|
+
found: false,
|
|
1357
|
+
index: mid,
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
var cache_esmBundler = /*#__PURE__*/Object.freeze({
|
|
1362
|
+
__proto__: null,
|
|
1363
|
+
ProstoCache: ProstoCache
|
|
1364
|
+
});
|
|
1365
|
+
|
|
1366
|
+
var require$$0 = /*@__PURE__*/getAugmentedNamespace(cache_esmBundler);
|
|
1367
|
+
|
|
1368
|
+
const dim = '[2m';
|
|
1369
|
+
const reset = '[0m';
|
|
1370
|
+
class ProstoTree {
|
|
1371
|
+
constructor(options) {
|
|
1372
|
+
var _a, _b, _c, _d;
|
|
1373
|
+
const label = (options === null || options === void 0 ? void 0 : options.label) || 'label';
|
|
1374
|
+
const children = (options === null || options === void 0 ? void 0 : options.children) || 'children';
|
|
1375
|
+
const branchWidth = typeof (options === null || options === void 0 ? void 0 : options.branchWidth) === 'number' ? options === null || options === void 0 ? void 0 : options.branchWidth : 2;
|
|
1376
|
+
const hLine = (((_a = options === null || options === void 0 ? void 0 : options.branches) === null || _a === void 0 ? void 0 : _a.hLine) || '─').repeat(branchWidth - 1);
|
|
1377
|
+
const branches = {
|
|
1378
|
+
end: ((_b = options === null || options === void 0 ? void 0 : options.branches) === null || _b === void 0 ? void 0 : _b.end) || dim + '└',
|
|
1379
|
+
middle: ((_c = options === null || options === void 0 ? void 0 : options.branches) === null || _c === void 0 ? void 0 : _c.middle) || dim + '├',
|
|
1380
|
+
vLine: ((_d = options === null || options === void 0 ? void 0 : options.branches) === null || _d === void 0 ? void 0 : _d.vLine) || dim + '│',
|
|
1381
|
+
hLine,
|
|
1382
|
+
};
|
|
1383
|
+
this.options = {
|
|
1384
|
+
label: label,
|
|
1385
|
+
children: children,
|
|
1386
|
+
renderLabel: (options === null || options === void 0 ? void 0 : options.renderLabel) || (n => typeof n === 'string' ? n : n[label]),
|
|
1387
|
+
branches,
|
|
1388
|
+
branchWidth,
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
_render(root, opts) {
|
|
1392
|
+
const { children, renderLabel } = this.options;
|
|
1393
|
+
let s = `${renderLabel(root, '')}\n`;
|
|
1394
|
+
const { end, middle, vLine, hLine } = this.options.branches;
|
|
1395
|
+
const endBranch = end + hLine + reset + ' ';
|
|
1396
|
+
const middleBranch = middle + hLine + reset + ' ';
|
|
1397
|
+
const { branchWidth } = this.options;
|
|
1398
|
+
if (root) {
|
|
1399
|
+
treeNode(root);
|
|
1400
|
+
}
|
|
1401
|
+
function treeNode(node, behind = '', level = 1) {
|
|
1402
|
+
const items = (node && node[children]);
|
|
1403
|
+
const count = items && items.length || 0;
|
|
1404
|
+
if (items) {
|
|
1405
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.level) && opts.level < level) {
|
|
1406
|
+
s += behind + endBranch + renderCollapsedChildren(items.length) + '\n';
|
|
1407
|
+
}
|
|
1408
|
+
else {
|
|
1409
|
+
let itemsToRender = items;
|
|
1410
|
+
const collapsedCount = Math.max(0, count - ((opts === null || opts === void 0 ? void 0 : opts.childrenLimit) || count));
|
|
1411
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.childrenLimit) && count > opts.childrenLimit) {
|
|
1412
|
+
itemsToRender = opts.showLast ? items.slice(count - opts.childrenLimit) : items.slice(0, opts.childrenLimit);
|
|
1413
|
+
}
|
|
1414
|
+
if (collapsedCount && (opts === null || opts === void 0 ? void 0 : opts.showLast))
|
|
1415
|
+
s += behind + middleBranch + renderCollapsedChildren(collapsedCount) + '\n';
|
|
1416
|
+
itemsToRender.forEach((childNode, i) => {
|
|
1417
|
+
const last = i + 1 === count;
|
|
1418
|
+
const branch = last ? endBranch : middleBranch;
|
|
1419
|
+
const nextBehind = behind + (last ? ' ' : vLine) + ' '.repeat(branchWidth);
|
|
1420
|
+
s += behind + branch + renderLabel(childNode, nextBehind) + '\n';
|
|
1421
|
+
if (typeof childNode === 'object') {
|
|
1422
|
+
treeNode(childNode, nextBehind, level + 1);
|
|
1423
|
+
}
|
|
1424
|
+
});
|
|
1425
|
+
if (collapsedCount && !(opts === null || opts === void 0 ? void 0 : opts.showLast))
|
|
1426
|
+
s += behind + endBranch + renderCollapsedChildren(collapsedCount) + '\n';
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return s;
|
|
1431
|
+
}
|
|
1432
|
+
render(root, opts) {
|
|
1433
|
+
return this._render(root, opts);
|
|
1434
|
+
}
|
|
1435
|
+
print(root, opts) {
|
|
1436
|
+
const s = this.render(root, opts);
|
|
1437
|
+
console.log(s);
|
|
1438
|
+
return s;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
function renderCollapsedChildren(count) {
|
|
1442
|
+
return dim + '+ ' + '[3m' + count.toString() + ` item${count === 1 ? '' : 's'}` + reset;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
var tree_esmBundler = /*#__PURE__*/Object.freeze({
|
|
1446
|
+
__proto__: null,
|
|
1447
|
+
ProstoTree: ProstoTree
|
|
1448
|
+
});
|
|
1449
|
+
|
|
1450
|
+
function renderCodeFragment(lines, options) {
|
|
1451
|
+
const row = (options.row || 1) - 1;
|
|
1452
|
+
const rowEnd = options.rowEnd ? options.rowEnd - 1 : -1;
|
|
1453
|
+
const limit = Math.min(options.limit || 6, lines.length);
|
|
1454
|
+
const offset = Math.min(options.offset || 3, lines.length);
|
|
1455
|
+
const error = options.error;
|
|
1456
|
+
const errorEnd = options.errorEnd;
|
|
1457
|
+
let output = '';
|
|
1458
|
+
const delta = rowEnd - row;
|
|
1459
|
+
const maxIndex = lines.length;
|
|
1460
|
+
if (delta > limit) {
|
|
1461
|
+
let longestLine = 0;
|
|
1462
|
+
const newLimit = Math.floor(limit / 2);
|
|
1463
|
+
for (let i = 0; i < newLimit + offset; i++) {
|
|
1464
|
+
const index = row + i - offset;
|
|
1465
|
+
const line = lines[index] || '';
|
|
1466
|
+
longestLine = Math.max(line.length, longestLine);
|
|
1467
|
+
output += renderLine(line, index < maxIndex ? index + 1 : '', index === row ? error : undefined, index === row || index === rowEnd ? 'bold' : '');
|
|
1468
|
+
}
|
|
1469
|
+
let output2 = '';
|
|
1470
|
+
for (let i = newLimit + offset; i > 0; i--) {
|
|
1471
|
+
const index = rowEnd - i + offset;
|
|
1472
|
+
const line = lines[index] || '';
|
|
1473
|
+
longestLine = Math.max(line.length, longestLine);
|
|
1474
|
+
output2 += renderLine(line, index < maxIndex ? index + 1 : '', index === rowEnd ? errorEnd : undefined, index === row || index === rowEnd ? 'bold' : '');
|
|
1475
|
+
}
|
|
1476
|
+
output += renderLine('—'.repeat(longestLine), '———', undefined, 'dim') + output2;
|
|
1477
|
+
}
|
|
1478
|
+
else {
|
|
1479
|
+
for (let i = 0; i < limit + offset; i++) {
|
|
1480
|
+
const index = row + i - offset;
|
|
1481
|
+
if (index <= lines.length + 1) {
|
|
1482
|
+
const errorCol = index === row ? error : index === rowEnd ? errorEnd : undefined;
|
|
1483
|
+
output += renderLine(lines[index], index < maxIndex ? index + 1 : '', errorCol, index === row || index === rowEnd ? 'bold' : '');
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
return output;
|
|
1488
|
+
}
|
|
1489
|
+
function lineStyles(s) {
|
|
1490
|
+
return '[94m' + (s || '')
|
|
1491
|
+
.replace(/([a-z_]+)/ig, '[32m' + '$1' + '\x1b[39;33m')
|
|
1492
|
+
.replace(/([\=\.\/'"`\:\+]+)/ig, '[36m' + '$1' + '[39m');
|
|
1493
|
+
}
|
|
1494
|
+
function lineStylesError(s) {
|
|
1495
|
+
return '[31m' + (s || '') + '[0m';
|
|
1496
|
+
}
|
|
1497
|
+
function renderLine(line, index, error, style = '') {
|
|
1498
|
+
const st = (style === 'bold' ? '[1m' : '') + (style === 'dim' ? '[2m' : '');
|
|
1499
|
+
if (typeof error === 'number') {
|
|
1500
|
+
const errorLength = (/[\.-\s\(\)\*\/\+\{\}\[\]\?\'\"\`\<\>]/.exec(line.slice(error + 1)) || { index: line.length - error }).index + 1;
|
|
1501
|
+
return renderLineNumber(index, true) +
|
|
1502
|
+
st +
|
|
1503
|
+
lineStyles(line.slice(0, error)) +
|
|
1504
|
+
lineStylesError(line.slice(error, error + errorLength)) +
|
|
1505
|
+
lineStyles(line.slice(error + errorLength)) +
|
|
1506
|
+
renderLineNumber('', true) + ' '.repeat(error) + '[31m' + '[1m' + '~'.repeat(Math.max(1, errorLength));
|
|
1507
|
+
}
|
|
1508
|
+
return renderLineNumber(index, undefined, style === 'bold') + st + lineStyles(line);
|
|
1509
|
+
}
|
|
1510
|
+
function renderLineNumber(i, isError = false, bold = false) {
|
|
1511
|
+
let s = ' ';
|
|
1512
|
+
const sep = i === '———';
|
|
1513
|
+
if (i && i > 0 || typeof i === 'string') {
|
|
1514
|
+
s = ' ' + String(i);
|
|
1515
|
+
}
|
|
1516
|
+
s = s.slice(s.length - 5);
|
|
1517
|
+
return '\n' + '[0m' + (sep ? '[34m' : '') +
|
|
1518
|
+
(isError ? '[31m' + '[1m' : (bold ? '[1m' : '[2m')) +
|
|
1519
|
+
s + (sep ? i : ' | ') + '[0m';
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
function escapeRegex(s) {
|
|
1523
|
+
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
class ProstoParserNodeBase {
|
|
1527
|
+
addRecognizes(...args) {
|
|
1528
|
+
for (const node of args) {
|
|
1529
|
+
if (!this.options.recognizes)
|
|
1530
|
+
this.options.recognizes = [];
|
|
1531
|
+
if (!this.options.recognizes.includes(node)) {
|
|
1532
|
+
this.options.recognizes.push(node);
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
return this;
|
|
1536
|
+
}
|
|
1537
|
+
addAbsorbs(node, rule = 'append') {
|
|
1538
|
+
this.options.absorbs = this.options.absorbs || {};
|
|
1539
|
+
if (Array.isArray(node)) {
|
|
1540
|
+
node.forEach(n => {
|
|
1541
|
+
this.options.absorbs[n.id] = rule;
|
|
1542
|
+
this.addRecognizes(n);
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
else {
|
|
1546
|
+
this.options.absorbs[node.id] = rule;
|
|
1547
|
+
this.addRecognizes(node);
|
|
1548
|
+
}
|
|
1549
|
+
return this;
|
|
1550
|
+
}
|
|
1551
|
+
addPopsAfterNode(...args) {
|
|
1552
|
+
for (const node of args) {
|
|
1553
|
+
if (!this.options.popsAfterNode)
|
|
1554
|
+
this.options.popsAfterNode = [];
|
|
1555
|
+
if (!this.options.popsAfterNode.includes(node)) {
|
|
1556
|
+
this.options.popsAfterNode.push(node);
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
this.addRecognizes(...args);
|
|
1560
|
+
return this;
|
|
1561
|
+
}
|
|
1562
|
+
addHoistChildren(...args) {
|
|
1563
|
+
if (!this.options.hoistChildren)
|
|
1564
|
+
this.options.hoistChildren = [];
|
|
1565
|
+
this.options.hoistChildren.push(...args);
|
|
1566
|
+
return this;
|
|
1567
|
+
}
|
|
1568
|
+
set icon(value) {
|
|
1569
|
+
this.options.icon = value;
|
|
1570
|
+
}
|
|
1571
|
+
set label(value) {
|
|
1572
|
+
this.options.label = value;
|
|
1573
|
+
}
|
|
1574
|
+
get startsWith() {
|
|
1575
|
+
return this.options.startsWith;
|
|
1576
|
+
}
|
|
1577
|
+
set startsWith(value) {
|
|
1578
|
+
this.options.startsWith = value;
|
|
1579
|
+
}
|
|
1580
|
+
get endsWith() {
|
|
1581
|
+
return this.options.endsWith;
|
|
1582
|
+
}
|
|
1583
|
+
set endsWith(value) {
|
|
1584
|
+
this.options.endsWith = value;
|
|
1585
|
+
}
|
|
1586
|
+
getPopsAtEOFSource() {
|
|
1587
|
+
return this.options.popsAtEOFSource;
|
|
1588
|
+
}
|
|
1589
|
+
popsAtEOFSource(value) {
|
|
1590
|
+
this.options.popsAtEOFSource = value;
|
|
1591
|
+
return this;
|
|
1592
|
+
}
|
|
1593
|
+
get absorbs() {
|
|
1594
|
+
return this.options.absorbs;
|
|
1595
|
+
}
|
|
1596
|
+
get badToken() {
|
|
1597
|
+
return this.options.badToken;
|
|
1598
|
+
}
|
|
1599
|
+
set badToken(value) {
|
|
1600
|
+
this.options.badToken = value;
|
|
1601
|
+
}
|
|
1602
|
+
get skipToken() {
|
|
1603
|
+
return this.options.skipToken;
|
|
1604
|
+
}
|
|
1605
|
+
set skipToken(value) {
|
|
1606
|
+
this.options.skipToken = value;
|
|
1607
|
+
}
|
|
1608
|
+
get recognizes() {
|
|
1609
|
+
return this.options.recognizes || [];
|
|
1610
|
+
}
|
|
1611
|
+
set recognizes(value) {
|
|
1612
|
+
this.options.recognizes = value;
|
|
1613
|
+
}
|
|
1614
|
+
get hoistChildren() {
|
|
1615
|
+
return this.options.hoistChildren || [];
|
|
1616
|
+
}
|
|
1617
|
+
set hoistChildren(value) {
|
|
1618
|
+
this.options.hoistChildren = value;
|
|
1619
|
+
}
|
|
1620
|
+
getMapContent() {
|
|
1621
|
+
return this.options.mapContent;
|
|
1622
|
+
}
|
|
1623
|
+
mapContent(key, value = 'copy') {
|
|
1624
|
+
this.options.mapContent = this.options.mapContent || {};
|
|
1625
|
+
this.options.mapContent[key] = value;
|
|
1626
|
+
return this;
|
|
1627
|
+
}
|
|
1628
|
+
onMatch(value) {
|
|
1629
|
+
this.options.onMatch = value;
|
|
1630
|
+
return this;
|
|
1631
|
+
}
|
|
1632
|
+
onAppendContent(value) {
|
|
1633
|
+
this.options.onAppendContent = value;
|
|
1634
|
+
return this;
|
|
1635
|
+
}
|
|
1636
|
+
onAfterChildParse(value) {
|
|
1637
|
+
this.options.onAfterChildParse = value;
|
|
1638
|
+
return this;
|
|
1639
|
+
}
|
|
1640
|
+
onBeforeChildParse(value) {
|
|
1641
|
+
this.options.onBeforeChildParse = value;
|
|
1642
|
+
return this;
|
|
1643
|
+
}
|
|
1644
|
+
onMatchStartToken(value) {
|
|
1645
|
+
if (this.options.startsWith) {
|
|
1646
|
+
this.options.startsWith.onMatchToken = value;
|
|
1647
|
+
}
|
|
1648
|
+
return this;
|
|
1649
|
+
}
|
|
1650
|
+
onMatchEndToken(value) {
|
|
1651
|
+
if (this.options.endsWith) {
|
|
1652
|
+
this.options.endsWith.onMatchToken = value;
|
|
1653
|
+
}
|
|
1654
|
+
return this;
|
|
1655
|
+
}
|
|
1656
|
+
initCustomData(value) {
|
|
1657
|
+
this.options.initCustomData = value;
|
|
1658
|
+
return this;
|
|
1659
|
+
}
|
|
1660
|
+
onPop(value) {
|
|
1661
|
+
this.options.onPop = value;
|
|
1662
|
+
return this;
|
|
1663
|
+
}
|
|
1664
|
+
get popsAfterNode() {
|
|
1665
|
+
return this.options.popsAfterNode || [];
|
|
1666
|
+
}
|
|
1667
|
+
set popsAfterNode(nodes) {
|
|
1668
|
+
this.options.popsAfterNode = nodes;
|
|
1669
|
+
}
|
|
1670
|
+
clearStartsWith() {
|
|
1671
|
+
delete this.options.startsWith;
|
|
1672
|
+
return this;
|
|
1673
|
+
}
|
|
1674
|
+
clearEndsWith() {
|
|
1675
|
+
delete this.options.endsWith;
|
|
1676
|
+
return this;
|
|
1677
|
+
}
|
|
1678
|
+
clearPopsAtEOFSource() {
|
|
1679
|
+
delete this.options.popsAtEOFSource;
|
|
1680
|
+
return this;
|
|
1681
|
+
}
|
|
1682
|
+
clearBadToken() {
|
|
1683
|
+
delete this.options.badToken;
|
|
1684
|
+
return this;
|
|
1685
|
+
}
|
|
1686
|
+
clearSkipToken() {
|
|
1687
|
+
delete this.options.skipToken;
|
|
1688
|
+
return this;
|
|
1689
|
+
}
|
|
1690
|
+
clearAbsorbs(node) {
|
|
1691
|
+
if (this.options.absorbs) {
|
|
1692
|
+
if (node && Array.isArray(node)) {
|
|
1693
|
+
for (const n of node) {
|
|
1694
|
+
delete this.options.absorbs[n.id];
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
else if (node) {
|
|
1698
|
+
delete this.options.absorbs[node.id];
|
|
1699
|
+
}
|
|
1700
|
+
else {
|
|
1701
|
+
this.options.absorbs = {};
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
return this;
|
|
1705
|
+
}
|
|
1706
|
+
clearRecognizes(...args) {
|
|
1707
|
+
var _a;
|
|
1708
|
+
if (args.length) {
|
|
1709
|
+
this.options.recognizes = (_a = this.options.recognizes) === null || _a === void 0 ? void 0 : _a.filter(n => !args.includes(n));
|
|
1710
|
+
}
|
|
1711
|
+
else {
|
|
1712
|
+
this.options.recognizes = [];
|
|
1713
|
+
}
|
|
1714
|
+
return this;
|
|
1715
|
+
}
|
|
1716
|
+
clearHoistChildren() {
|
|
1717
|
+
delete this.options.hoistChildren;
|
|
1718
|
+
return this;
|
|
1719
|
+
}
|
|
1720
|
+
clearMapContent() {
|
|
1721
|
+
delete this.options.mapContent;
|
|
1722
|
+
return this;
|
|
1723
|
+
}
|
|
1724
|
+
removeOnPop() {
|
|
1725
|
+
delete this.options.onPop;
|
|
1726
|
+
return this;
|
|
1727
|
+
}
|
|
1728
|
+
removeOnMatch() {
|
|
1729
|
+
delete this.options.onMatch;
|
|
1730
|
+
return this;
|
|
1731
|
+
}
|
|
1732
|
+
removeOnAppendContent() {
|
|
1733
|
+
delete this.options.onAppendContent;
|
|
1734
|
+
return this;
|
|
1735
|
+
}
|
|
1736
|
+
removeOnBeforeChildParse() {
|
|
1737
|
+
delete this.options.onBeforeChildParse;
|
|
1738
|
+
return this;
|
|
1739
|
+
}
|
|
1740
|
+
removeOnAfterChildParse() {
|
|
1741
|
+
delete this.options.onAfterChildParse;
|
|
1742
|
+
return this;
|
|
1743
|
+
}
|
|
1744
|
+
fireNodeMatched(matched, cbData) {
|
|
1745
|
+
return this.options.startsWith ? this.fireMatched(this.options.startsWith, matched, cbData) : { confirmed: true };
|
|
1746
|
+
}
|
|
1747
|
+
fireNodeEndMatched(matched, cbData) {
|
|
1748
|
+
return this.options.endsWith ? this.fireMatched(this.options.endsWith, matched, cbData) : { confirmed: true };
|
|
1749
|
+
}
|
|
1750
|
+
fireMatched(descr, matched, cbData) {
|
|
1751
|
+
const { omit, eject, onMatchToken } = descr;
|
|
1752
|
+
let cbResult = true;
|
|
1753
|
+
if (onMatchToken) {
|
|
1754
|
+
cbResult = onMatchToken({
|
|
1755
|
+
...cbData,
|
|
1756
|
+
matched,
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
const cbOmit = typeof cbResult === 'object' ? cbResult.omit : undefined;
|
|
1760
|
+
const cbEject = typeof cbResult === 'object' ? cbResult.eject : undefined;
|
|
1761
|
+
return {
|
|
1762
|
+
omit: cbOmit !== undefined ? cbOmit : omit,
|
|
1763
|
+
eject: cbEject !== undefined ? cbEject : eject,
|
|
1764
|
+
confirmed: cbResult !== false,
|
|
1765
|
+
};
|
|
1766
|
+
}
|
|
1767
|
+
getStartTokenRg() {
|
|
1768
|
+
return this.getRgOutOfTokenDescriptor(this.options.startsWith);
|
|
1769
|
+
}
|
|
1770
|
+
getEndTokenRg() {
|
|
1771
|
+
return this.getRgOutOfTokenDescriptor(this.options.endsWith);
|
|
1772
|
+
}
|
|
1773
|
+
getConstraintTokens() {
|
|
1774
|
+
return {
|
|
1775
|
+
skip: this.getRgOutOfTokenDescriptor(this.options.skipToken ? { token: this.options.skipToken } : undefined) || undefined,
|
|
1776
|
+
bad: this.getRgOutOfTokenDescriptor(this.options.badToken ? { token: this.options.badToken } : undefined) || undefined,
|
|
1777
|
+
};
|
|
1778
|
+
}
|
|
1779
|
+
getRgOutOfTokenDescriptor(descr) {
|
|
1780
|
+
if (descr) {
|
|
1781
|
+
const prefix = descr.ignoreBackSlashed ? /(?<=(?:^|[^\\])(?:\\\\)*)/.source : '';
|
|
1782
|
+
let token;
|
|
1783
|
+
if (typeof descr.token === 'function') {
|
|
1784
|
+
token = descr.token(this);
|
|
1785
|
+
}
|
|
1786
|
+
else {
|
|
1787
|
+
token = descr.token;
|
|
1788
|
+
}
|
|
1789
|
+
if (token instanceof RegExp) {
|
|
1790
|
+
return new RegExp(prefix + token.source, token.flags);
|
|
1791
|
+
}
|
|
1792
|
+
else {
|
|
1793
|
+
return new RegExp(`${prefix}(?:${[token].flat().map(t => escapeRegex(t)).join('|')})`);
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
class ProstoHoistManager {
|
|
1800
|
+
constructor() {
|
|
1801
|
+
this.data = {};
|
|
1802
|
+
}
|
|
1803
|
+
addHoistOptions(ctx) {
|
|
1804
|
+
if (ctx.hoistChildren) {
|
|
1805
|
+
ctx.hoistChildren.forEach(options => {
|
|
1806
|
+
const nodeId = typeof options.node === 'object' ? options.node.id : options.node;
|
|
1807
|
+
const hoist = this.data[nodeId] = (this.data[nodeId] || {});
|
|
1808
|
+
if (hoist) {
|
|
1809
|
+
hoist[ctx.index] = {
|
|
1810
|
+
options,
|
|
1811
|
+
context: ctx,
|
|
1812
|
+
};
|
|
1813
|
+
}
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
removeHoistOptions(ctx) {
|
|
1818
|
+
if (ctx.hoistChildren) {
|
|
1819
|
+
ctx.hoistChildren.forEach(options => {
|
|
1820
|
+
const nodeId = typeof options.node === 'object' ? options.node.id : options.node;
|
|
1821
|
+
const hoist = this.data[nodeId];
|
|
1822
|
+
if (hoist) {
|
|
1823
|
+
delete hoist[ctx.index];
|
|
1824
|
+
}
|
|
1825
|
+
});
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
processHoistOptions(ctx) {
|
|
1829
|
+
const id = ctx.node.id;
|
|
1830
|
+
const hoist = this.data[id];
|
|
1831
|
+
if (hoist) {
|
|
1832
|
+
Object.keys(hoist).map(i => hoist[i]).forEach(({ options, context }) => {
|
|
1833
|
+
const customData = context.getCustomData();
|
|
1834
|
+
if (options.deep === true || Number(options.deep) >= (ctx.level - context.level)) {
|
|
1835
|
+
if (options.asArray) {
|
|
1836
|
+
const hoisted = customData[options.as] = (customData[options.as] || []);
|
|
1837
|
+
if (!Array.isArray(hoisted)) {
|
|
1838
|
+
if (!options.onConflict || options.onConflict === 'error') {
|
|
1839
|
+
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.`);
|
|
1840
|
+
}
|
|
1841
|
+
else if (options.onConflict === 'overwrite') {
|
|
1842
|
+
customData[options.as] = [doTheMapRule(options, ctx)];
|
|
1843
|
+
}
|
|
1844
|
+
else if (options.onConflict !== 'ignore') {
|
|
1845
|
+
throw new Error(`Unsupported hoisting option onConflict "${options.onConflict}"`);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
else {
|
|
1849
|
+
hoisted.push(doTheMapRule(options, ctx));
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
else {
|
|
1853
|
+
if (customData[options.as]) {
|
|
1854
|
+
if (!options.onConflict || options.onConflict === 'error') {
|
|
1855
|
+
throw new Error(`Can not hoist multiple "${ctx.node.name}" to "${context.node.name}" as "${options.as}". "${options.as}" already exists.`);
|
|
1856
|
+
}
|
|
1857
|
+
else if (options.onConflict === 'overwrite') {
|
|
1858
|
+
customData[options.as] = doTheMapRule(options, ctx);
|
|
1859
|
+
}
|
|
1860
|
+
else if (options.onConflict !== 'ignore') {
|
|
1861
|
+
throw new Error(`Unsupported hoisting option onConflict "${options.onConflict}"`);
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
else {
|
|
1865
|
+
customData[options.as] = doTheMapRule(options, ctx);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
if (options.removeChildFromContent) {
|
|
1869
|
+
context.content = context.content.filter(c => c !== ctx);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
function doTheMapRule(options, ctx) {
|
|
1875
|
+
var _a;
|
|
1876
|
+
if (typeof options.mapRule === 'function') {
|
|
1877
|
+
return options.mapRule(ctx);
|
|
1878
|
+
}
|
|
1879
|
+
if (options.mapRule === 'content.join') {
|
|
1880
|
+
return ctx.content.join('');
|
|
1881
|
+
}
|
|
1882
|
+
if ((_a = options.mapRule) === null || _a === void 0 ? void 0 : _a.startsWith('customData')) {
|
|
1883
|
+
const key = options.mapRule.slice(11);
|
|
1884
|
+
if (key) {
|
|
1885
|
+
return ctx.getCustomData()[key];
|
|
1886
|
+
}
|
|
1887
|
+
else {
|
|
1888
|
+
return ctx.getCustomData();
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
return ctx;
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
const banner = '[31m' + '[parser]' + '[39m';
|
|
1897
|
+
class ProstoParserContext {
|
|
1898
|
+
constructor(root) {
|
|
1899
|
+
this.root = root;
|
|
1900
|
+
this.nodes = {};
|
|
1901
|
+
this.pos = 0;
|
|
1902
|
+
this.index = 0;
|
|
1903
|
+
this.behind = '';
|
|
1904
|
+
this.here = '';
|
|
1905
|
+
this.src = '';
|
|
1906
|
+
this.stack = [];
|
|
1907
|
+
this.l = 0;
|
|
1908
|
+
this.hoistManager = new ProstoHoistManager();
|
|
1909
|
+
this.context = root;
|
|
1910
|
+
}
|
|
1911
|
+
parse(src) {
|
|
1912
|
+
this.src = src,
|
|
1913
|
+
this.here = src,
|
|
1914
|
+
this.l = src.length;
|
|
1915
|
+
const cache = {};
|
|
1916
|
+
while (this.pos < this.l) {
|
|
1917
|
+
const searchTokens = this.context.getSearchTokens();
|
|
1918
|
+
let closestIndex = Number.MAX_SAFE_INTEGER;
|
|
1919
|
+
let closestToken;
|
|
1920
|
+
let matched;
|
|
1921
|
+
for (const t of searchTokens) {
|
|
1922
|
+
const key = t.g.source;
|
|
1923
|
+
t.g.lastIndex = this.pos;
|
|
1924
|
+
let cached = cache[key];
|
|
1925
|
+
if (cached === null)
|
|
1926
|
+
continue;
|
|
1927
|
+
if (cached && cached.index < this.pos) {
|
|
1928
|
+
cached = null;
|
|
1929
|
+
delete cache[key];
|
|
1930
|
+
}
|
|
1931
|
+
if (!cached) {
|
|
1932
|
+
cached = t.g.exec(this.src);
|
|
1933
|
+
if (cached || (this.pos === 0 && !cached)) {
|
|
1934
|
+
cache[key] = cached;
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
if (cached && cached.index < closestIndex) {
|
|
1938
|
+
closestIndex = cached.index;
|
|
1939
|
+
matched = cached;
|
|
1940
|
+
closestToken = t;
|
|
1941
|
+
if (closestIndex === this.pos)
|
|
1942
|
+
break;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
if (closestToken && matched) {
|
|
1946
|
+
const toAppend = this.src.slice(this.pos, closestIndex);
|
|
1947
|
+
if (toAppend) {
|
|
1948
|
+
this.context.appendContent(toAppend);
|
|
1949
|
+
this.jump(toAppend.length);
|
|
1950
|
+
}
|
|
1951
|
+
const matchedToken = matched[0];
|
|
1952
|
+
if (closestToken.node) {
|
|
1953
|
+
const { omit, eject, confirmed } = closestToken.node.fireNodeMatched(matched, this.getCallbackData(matched));
|
|
1954
|
+
if (!confirmed)
|
|
1955
|
+
continue;
|
|
1956
|
+
let toAppend = '';
|
|
1957
|
+
if (eject) {
|
|
1958
|
+
this.context.appendContent(matchedToken);
|
|
1959
|
+
}
|
|
1960
|
+
else if (!omit) {
|
|
1961
|
+
toAppend = matchedToken;
|
|
1962
|
+
}
|
|
1963
|
+
this.jump(matchedToken.length);
|
|
1964
|
+
this.pushNewContext(closestToken.node, toAppend ? [toAppend] : []);
|
|
1965
|
+
this.context.fireOnMatch(matched);
|
|
1966
|
+
continue;
|
|
1967
|
+
}
|
|
1968
|
+
else {
|
|
1969
|
+
const { omit, eject, confirmed } = this.context.fireNodeEndMatched(matched, this.getCallbackData(matched));
|
|
1970
|
+
if (!confirmed)
|
|
1971
|
+
continue;
|
|
1972
|
+
if (!eject && !omit) {
|
|
1973
|
+
this.context.appendContent(matchedToken);
|
|
1974
|
+
}
|
|
1975
|
+
if (!eject) {
|
|
1976
|
+
this.jump(matchedToken.length);
|
|
1977
|
+
}
|
|
1978
|
+
this.context.mapNamedGroups(matched);
|
|
1979
|
+
this.pop();
|
|
1980
|
+
continue;
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
else {
|
|
1984
|
+
this.context.appendContent(this.here);
|
|
1985
|
+
this.jump(this.here.length);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
if (this.context !== this.root) {
|
|
1989
|
+
while (this.context.getPopsAtEOFSource() && this.stack.length > 0)
|
|
1990
|
+
this.pop();
|
|
1991
|
+
}
|
|
1992
|
+
if (this.context !== this.root) {
|
|
1993
|
+
this.panicBlock(`Unexpected end of the source string while parsing "${this.context.node.name}" (${this.context.index}) node.`);
|
|
1994
|
+
}
|
|
1995
|
+
return this.root;
|
|
1996
|
+
}
|
|
1997
|
+
pop() {
|
|
1998
|
+
const parentContext = this.stack.pop();
|
|
1999
|
+
this.context.fireOnPop();
|
|
2000
|
+
if (parentContext) {
|
|
2001
|
+
parentContext.fireAfterChildParse(this.context);
|
|
2002
|
+
parentContext.fireAbsorb(this.context);
|
|
2003
|
+
this.context.cleanup();
|
|
2004
|
+
const node = this.context.node;
|
|
2005
|
+
this.context = parentContext;
|
|
2006
|
+
if (parentContext.popsAfterNode.includes(node)) {
|
|
2007
|
+
this.pop();
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
else {
|
|
2011
|
+
this.context.cleanup();
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
pushNewContext(newNode, content) {
|
|
2015
|
+
this.index++;
|
|
2016
|
+
const ctx = newNode.createContext(this.index, this.stack.length + 1, this);
|
|
2017
|
+
ctx.content = content;
|
|
2018
|
+
this.context.fireBeforeChildParse(ctx);
|
|
2019
|
+
this.context.pushChild(ctx);
|
|
2020
|
+
this.stack.push(this.context);
|
|
2021
|
+
this.hoistManager.addHoistOptions(this.context);
|
|
2022
|
+
this.context = ctx;
|
|
2023
|
+
return ctx;
|
|
2024
|
+
}
|
|
2025
|
+
fromStack(depth = 0) {
|
|
2026
|
+
return this.stack[this.stack.length - depth - 1];
|
|
2027
|
+
}
|
|
2028
|
+
jump(n = 1) {
|
|
2029
|
+
this.pos += n;
|
|
2030
|
+
this.behind = this.src.slice(0, this.pos);
|
|
2031
|
+
this.here = this.src.slice(this.pos, this.l);
|
|
2032
|
+
return this.pos;
|
|
2033
|
+
}
|
|
2034
|
+
getCallbackData(matched) {
|
|
2035
|
+
return {
|
|
2036
|
+
parserContext: this,
|
|
2037
|
+
context: this.context,
|
|
2038
|
+
matched,
|
|
2039
|
+
customData: this.context.getCustomData(),
|
|
2040
|
+
};
|
|
2041
|
+
}
|
|
2042
|
+
getPosition(offset = 0) {
|
|
2043
|
+
var _a;
|
|
2044
|
+
const past = this.src.slice(0, this.pos + offset).split('\n');
|
|
2045
|
+
const row = past.length;
|
|
2046
|
+
const col = ((_a = past.pop()) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
2047
|
+
return {
|
|
2048
|
+
row, col, pos: this.pos,
|
|
2049
|
+
};
|
|
2050
|
+
}
|
|
2051
|
+
panic(message, errorBackOffset = 0) {
|
|
2052
|
+
if (this.pos > 0) {
|
|
2053
|
+
const { row, col } = this.getPosition(-errorBackOffset);
|
|
2054
|
+
console.error(banner + '[91m', message, '[0m');
|
|
2055
|
+
console.log(this.context.toTree({ childrenLimit: 5, showLast: true, level: 1 }));
|
|
2056
|
+
console.error(renderCodeFragment(this.src.split('\n'), {
|
|
2057
|
+
row: row,
|
|
2058
|
+
error: col,
|
|
2059
|
+
}));
|
|
2060
|
+
}
|
|
2061
|
+
throw new Error(message);
|
|
2062
|
+
}
|
|
2063
|
+
panicBlock(message, topBackOffset = 0, bottomBackOffset = 0) {
|
|
2064
|
+
if (this.pos > 0) {
|
|
2065
|
+
const { row, col } = this.getPosition(-bottomBackOffset);
|
|
2066
|
+
console.error(banner + '[91m', message, '[0m');
|
|
2067
|
+
console.log(this.context.toTree({ childrenLimit: 13, showLast: true, level: 12 }));
|
|
2068
|
+
console.error(renderCodeFragment(this.src.split('\n'), {
|
|
2069
|
+
row: this.context.startPos.row,
|
|
2070
|
+
error: this.context.startPos.col - topBackOffset,
|
|
2071
|
+
rowEnd: row,
|
|
2072
|
+
errorEnd: col,
|
|
2073
|
+
}));
|
|
2074
|
+
}
|
|
2075
|
+
throw new Error(message);
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
const styles = {
|
|
2080
|
+
banner: (s) => '[31m' + s + '[39m',
|
|
2081
|
+
text: (s) => '[32m' + s + '[39m',
|
|
2082
|
+
valuesDim: (s) => '[36m' + '[2m' + s + '[39m' + '[22m',
|
|
2083
|
+
boolean: (s) => '[94m' + s + '[39m',
|
|
2084
|
+
booleanDim: (s) => '[94m' + '[2m' + s + '[39m' + '[22m',
|
|
2085
|
+
underscore: (s) => '[4m' + s + '[24m',
|
|
2086
|
+
values: (s) => (typeof s === 'string' ? '[96m' : '[93m') + cut(s.toString(), 30) + '[39m',
|
|
2087
|
+
nodeDim: (s) => '[33m' + '[2m' + s + '[39m' + '[22m',
|
|
2088
|
+
node: (s) => '[33m' + s + '[39m',
|
|
2089
|
+
};
|
|
2090
|
+
const stringOutputLimit = 70;
|
|
2091
|
+
const parserTree = new ProstoTree({
|
|
2092
|
+
children: 'content',
|
|
2093
|
+
renderLabel: (context) => {
|
|
2094
|
+
if (typeof context === 'string') {
|
|
2095
|
+
return styles.text('«' + cut(context, stringOutputLimit) + '[32m' + '»');
|
|
2096
|
+
}
|
|
2097
|
+
else if (typeof context === 'object' && context instanceof ProstoParserNodeContext) {
|
|
2098
|
+
let keys = '';
|
|
2099
|
+
const data = context.getCustomData();
|
|
2100
|
+
Object.keys(data).forEach(key => {
|
|
2101
|
+
const val = data[key];
|
|
2102
|
+
if (typeof val === 'string' || typeof val === 'number') {
|
|
2103
|
+
keys += ' ' + styles.valuesDim(key + '(') + styles.values(val) + styles.valuesDim(')');
|
|
2104
|
+
}
|
|
2105
|
+
else if (Array.isArray(val)) {
|
|
2106
|
+
keys += ' ' + styles.valuesDim(key + `[${val.length}]`);
|
|
2107
|
+
}
|
|
2108
|
+
else if (typeof val === 'object') {
|
|
2109
|
+
keys += ' ' + styles.valuesDim(`{ ${key} }`);
|
|
2110
|
+
}
|
|
2111
|
+
else if (typeof val === 'boolean' && val) {
|
|
2112
|
+
const st = key ? styles.boolean : styles.booleanDim;
|
|
2113
|
+
keys += ' ' + `${styles.underscore(st(key))}${st(val ? '☑' : '☐')}`;
|
|
2114
|
+
}
|
|
2115
|
+
});
|
|
2116
|
+
return styles.node(context.icon + (context.label ? ' ' : '')) + styles.nodeDim(context.label) + keys;
|
|
2117
|
+
}
|
|
2118
|
+
return '';
|
|
2119
|
+
},
|
|
2120
|
+
});
|
|
2121
|
+
function cut(s, n) {
|
|
2122
|
+
const c = s.replace(/\n/g, '\\n');
|
|
2123
|
+
if (c.length <= n)
|
|
2124
|
+
return c;
|
|
2125
|
+
return c.slice(0, n) + '[33m' + '…';
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2128
|
+
class ProstoParserNodeContext extends ProstoParserNodeBase {
|
|
2129
|
+
constructor(_node, index, level, parserContext) {
|
|
2130
|
+
super();
|
|
2131
|
+
this._node = _node;
|
|
2132
|
+
this.index = index;
|
|
2133
|
+
this.level = level;
|
|
2134
|
+
this.content = [];
|
|
2135
|
+
this._customData = {};
|
|
2136
|
+
this.hasNodes = [];
|
|
2137
|
+
this.count = {};
|
|
2138
|
+
this.mapContentRules = {
|
|
2139
|
+
'first': (content) => content[0],
|
|
2140
|
+
'shift': (content) => content.shift(),
|
|
2141
|
+
'pop': (content) => content.pop(),
|
|
2142
|
+
'last': (content) => content[content.length - 1],
|
|
2143
|
+
'join': (content) => content.join(''),
|
|
2144
|
+
'join-clear': (content) => content.splice(0).join(''),
|
|
2145
|
+
'copy': (content) => content,
|
|
2146
|
+
};
|
|
2147
|
+
this.options = _node.getOptions();
|
|
2148
|
+
if (this.options.initCustomData) {
|
|
2149
|
+
this._customData = this.options.initCustomData();
|
|
2150
|
+
}
|
|
2151
|
+
this._label = this.options.label || '';
|
|
2152
|
+
this._icon = this.options.icon || '◦';
|
|
2153
|
+
this.parserContext = parserContext || new ProstoParserContext(this);
|
|
2154
|
+
if (parserContext) {
|
|
2155
|
+
this.parent = parserContext.context || parserContext.root;
|
|
2156
|
+
}
|
|
2157
|
+
this.startPos = this.parserContext.getPosition();
|
|
2158
|
+
this.endPos = this.parserContext.getPosition();
|
|
2159
|
+
}
|
|
2160
|
+
getOptions() {
|
|
2161
|
+
return this.options;
|
|
2162
|
+
}
|
|
2163
|
+
extractCustomDataTree() {
|
|
2164
|
+
let content = this.content;
|
|
2165
|
+
if (this.contentCopiedTo) {
|
|
2166
|
+
content = this.customData[this.contentCopiedTo];
|
|
2167
|
+
}
|
|
2168
|
+
if (Array.isArray(content)) {
|
|
2169
|
+
return content.map(c => {
|
|
2170
|
+
if (typeof c === 'string') {
|
|
2171
|
+
return c;
|
|
2172
|
+
}
|
|
2173
|
+
else {
|
|
2174
|
+
return extract(c);
|
|
2175
|
+
}
|
|
2176
|
+
});
|
|
2177
|
+
}
|
|
2178
|
+
else {
|
|
2179
|
+
const c = content;
|
|
2180
|
+
if (c instanceof ProstoParserNodeContext) {
|
|
2181
|
+
return extract(c);
|
|
2182
|
+
}
|
|
2183
|
+
else {
|
|
2184
|
+
return content;
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
function extract(c) {
|
|
2188
|
+
const cd = { ...c.getCustomData() };
|
|
2189
|
+
if (c.contentCopiedTo) {
|
|
2190
|
+
cd[c.contentCopiedTo] = c.extractCustomDataTree();
|
|
2191
|
+
}
|
|
2192
|
+
return cd;
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
getPrevNode(n = 1) {
|
|
2196
|
+
if (this.parent) {
|
|
2197
|
+
const index = this.parent.content.findIndex(n => n === this) - n;
|
|
2198
|
+
if (index >= 0)
|
|
2199
|
+
return this.parent.content[index];
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
getPrevContext(n = 1) {
|
|
2203
|
+
if (this.parent) {
|
|
2204
|
+
const contexts = this.parent.content.filter(n => n instanceof ProstoParserNodeContext);
|
|
2205
|
+
const index = contexts.findIndex(n => n === this) - n;
|
|
2206
|
+
if (index >= 0)
|
|
2207
|
+
return contexts[index];
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
set icon(value) {
|
|
2211
|
+
this._icon = value;
|
|
2212
|
+
}
|
|
2213
|
+
get icon() {
|
|
2214
|
+
return this._icon;
|
|
2215
|
+
}
|
|
2216
|
+
set label(value) {
|
|
2217
|
+
this._label = value;
|
|
2218
|
+
}
|
|
2219
|
+
get label() {
|
|
2220
|
+
return this._label;
|
|
2221
|
+
}
|
|
2222
|
+
getCustomData() {
|
|
2223
|
+
return this._customData;
|
|
2224
|
+
}
|
|
2225
|
+
get customData() {
|
|
2226
|
+
return this._customData;
|
|
2227
|
+
}
|
|
2228
|
+
get nodeId() {
|
|
2229
|
+
return this._node.id;
|
|
2230
|
+
}
|
|
2231
|
+
get node() {
|
|
2232
|
+
return this._node;
|
|
2233
|
+
}
|
|
2234
|
+
toTree(options) {
|
|
2235
|
+
return parserTree.render(this, options);
|
|
2236
|
+
}
|
|
2237
|
+
getSearchTokens() {
|
|
2238
|
+
var _a;
|
|
2239
|
+
const rg = this.getEndTokenRg();
|
|
2240
|
+
const tokens = rg ? [{
|
|
2241
|
+
rg,
|
|
2242
|
+
y: addFlag(rg, 'y'),
|
|
2243
|
+
g: addFlag(rg, 'g'),
|
|
2244
|
+
}] : [];
|
|
2245
|
+
(_a = this.options.recognizes) === null || _a === void 0 ? void 0 : _a.forEach(node => {
|
|
2246
|
+
const rg = node.getStartTokenRg();
|
|
2247
|
+
if (rg) {
|
|
2248
|
+
tokens.push({
|
|
2249
|
+
rg,
|
|
2250
|
+
y: addFlag(rg, 'y'),
|
|
2251
|
+
g: addFlag(rg, 'g'),
|
|
2252
|
+
node,
|
|
2253
|
+
});
|
|
2254
|
+
}
|
|
2255
|
+
});
|
|
2256
|
+
function addFlag(rg, f) {
|
|
2257
|
+
return new RegExp(rg.source, rg.flags + f);
|
|
2258
|
+
}
|
|
2259
|
+
return tokens;
|
|
2260
|
+
}
|
|
2261
|
+
appendContent(input) {
|
|
2262
|
+
let s = input;
|
|
2263
|
+
this.endPos = this.parserContext.getPosition();
|
|
2264
|
+
let { skip, bad } = this.getConstraintTokens();
|
|
2265
|
+
skip = skip ? new RegExp(skip.source, skip.flags + 'g') : skip;
|
|
2266
|
+
bad = bad ? new RegExp(bad.source, bad.flags + 'g') : bad;
|
|
2267
|
+
if (skip) {
|
|
2268
|
+
s = s.replace(skip, '');
|
|
2269
|
+
}
|
|
2270
|
+
if (bad) {
|
|
2271
|
+
const m = bad.exec(s);
|
|
2272
|
+
if (m) {
|
|
2273
|
+
this.parserContext.jump(m.index);
|
|
2274
|
+
this.parserContext.panic(`The token "${m[0].replace(/"/g, '\\"')}" is not allowed in "${this.node.name}".`);
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
s = this.fireOnAppendContent(s);
|
|
2278
|
+
if (s) {
|
|
2279
|
+
this.content.push(s);
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
cleanup() {
|
|
2283
|
+
this.options = null;
|
|
2284
|
+
}
|
|
2285
|
+
pushChild(child) {
|
|
2286
|
+
const absorbRule = this.options.absorbs && this.options.absorbs[child.node.id];
|
|
2287
|
+
if (!absorbRule) {
|
|
2288
|
+
this.content.push(child);
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
fireAbsorb(child) {
|
|
2292
|
+
const absorbRule = this.options.absorbs && this.options.absorbs[child.node.id];
|
|
2293
|
+
if (absorbRule) {
|
|
2294
|
+
switch (absorbRule) {
|
|
2295
|
+
case 'append':
|
|
2296
|
+
this.content.push(...child.content);
|
|
2297
|
+
break;
|
|
2298
|
+
case 'join':
|
|
2299
|
+
this.appendContent(child.content.join(''));
|
|
2300
|
+
break;
|
|
2301
|
+
default:
|
|
2302
|
+
const [action, target] = absorbRule.split('->');
|
|
2303
|
+
const cd = this.getCustomData();
|
|
2304
|
+
if (action === 'copy') {
|
|
2305
|
+
cd[target] = child.content;
|
|
2306
|
+
}
|
|
2307
|
+
else if (action === 'join') {
|
|
2308
|
+
cd[target] = child.content.join('');
|
|
2309
|
+
}
|
|
2310
|
+
else {
|
|
2311
|
+
this.parserContext.panic(`Absorb action "${action}" is not supported.`);
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
has(node) {
|
|
2317
|
+
return this.hasNodes.includes(node);
|
|
2318
|
+
}
|
|
2319
|
+
countOf(node) {
|
|
2320
|
+
return this.count[node.id] || 0;
|
|
2321
|
+
}
|
|
2322
|
+
mapNamedGroups(matched) {
|
|
2323
|
+
if (matched.groups) {
|
|
2324
|
+
const cd = this.getCustomData();
|
|
2325
|
+
for (const [key, value] of Object.entries(matched.groups)) {
|
|
2326
|
+
if (key === 'content') {
|
|
2327
|
+
this.appendContent(value);
|
|
2328
|
+
}
|
|
2329
|
+
else {
|
|
2330
|
+
cd[key] = value;
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
fireOnPop() {
|
|
2336
|
+
this.endPos = this.parserContext.getPosition();
|
|
2337
|
+
this.processMappings();
|
|
2338
|
+
const data = this.parserContext.getCallbackData();
|
|
2339
|
+
this.node.beforeOnPop(data);
|
|
2340
|
+
if (this.options.onPop) {
|
|
2341
|
+
this.options.onPop(data);
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
fireOnMatch(matched) {
|
|
2345
|
+
this.mapNamedGroups(matched);
|
|
2346
|
+
const data = this.parserContext.getCallbackData(matched);
|
|
2347
|
+
this.node.beforeOnMatch(data);
|
|
2348
|
+
if (this.options.onMatch) {
|
|
2349
|
+
return this.options.onMatch(data);
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
fireBeforeChildParse(child) {
|
|
2353
|
+
const data = this.parserContext.getCallbackData();
|
|
2354
|
+
this.node.beforeOnBeforeChildParse(child, data);
|
|
2355
|
+
if (this.options.onBeforeChildParse) {
|
|
2356
|
+
return this.options.onBeforeChildParse(child, data);
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
fireAfterChildParse(child) {
|
|
2360
|
+
if (!this.hasNodes.includes(child.node)) {
|
|
2361
|
+
this.hasNodes.push(child.node);
|
|
2362
|
+
}
|
|
2363
|
+
this.count[child.node.id] = this.count[child.node.id] || 0;
|
|
2364
|
+
this.count[child.node.id]++;
|
|
2365
|
+
const data = this.parserContext.getCallbackData();
|
|
2366
|
+
this.node.beforeOnAfterChildParse(child, data);
|
|
2367
|
+
if (this.options.onAfterChildParse) {
|
|
2368
|
+
return this.options.onAfterChildParse(child, data);
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
fireOnAppendContent(s) {
|
|
2372
|
+
let _s = s;
|
|
2373
|
+
const data = this.parserContext.getCallbackData();
|
|
2374
|
+
_s = this.node.beforeOnAppendContent(_s, data);
|
|
2375
|
+
if (this.options.onAppendContent) {
|
|
2376
|
+
_s = this.options.onAppendContent(_s, data);
|
|
2377
|
+
}
|
|
2378
|
+
return _s;
|
|
2379
|
+
}
|
|
2380
|
+
processMappings() {
|
|
2381
|
+
this.parserContext.hoistManager.removeHoistOptions(this);
|
|
2382
|
+
this.parserContext.hoistManager.processHoistOptions(this);
|
|
2383
|
+
this.processMapContent();
|
|
2384
|
+
}
|
|
2385
|
+
processMapContent() {
|
|
2386
|
+
const targetNodeOptions = this.options;
|
|
2387
|
+
if (targetNodeOptions.mapContent) {
|
|
2388
|
+
Object.keys(targetNodeOptions.mapContent).forEach((key) => {
|
|
2389
|
+
const keyOfT = key;
|
|
2390
|
+
if (targetNodeOptions.mapContent && targetNodeOptions.mapContent[keyOfT]) {
|
|
2391
|
+
const mapRule = targetNodeOptions.mapContent[keyOfT];
|
|
2392
|
+
if (typeof mapRule === 'function') {
|
|
2393
|
+
this._customData[keyOfT] = mapRule(this.content);
|
|
2394
|
+
}
|
|
2395
|
+
else {
|
|
2396
|
+
const ruleKey = mapRule;
|
|
2397
|
+
if (ruleKey === 'copy')
|
|
2398
|
+
this.contentCopiedTo = keyOfT;
|
|
2399
|
+
this._customData[keyOfT] = this.mapContentRules[ruleKey](this.content);
|
|
2400
|
+
}
|
|
2401
|
+
if (!this.contentCopiedTo && (typeof mapRule === 'function' || ['first', 'shift', 'pop', 'last'].includes(mapRule))) {
|
|
2402
|
+
this.contentCopiedTo = keyOfT;
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
});
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2410
|
+
let idCounter = 0;
|
|
2411
|
+
class ProstoParserNode extends ProstoParserNodeBase {
|
|
2412
|
+
constructor(options) {
|
|
2413
|
+
super();
|
|
2414
|
+
this.options = options;
|
|
2415
|
+
this.id = idCounter++;
|
|
2416
|
+
}
|
|
2417
|
+
getOptions() {
|
|
2418
|
+
return {
|
|
2419
|
+
label: this.options.label || '',
|
|
2420
|
+
icon: this.options.icon || '',
|
|
2421
|
+
startsWith: (this.options.startsWith ? { ...this.options.startsWith } : this.options.startsWith),
|
|
2422
|
+
endsWith: (this.options.endsWith ? { ...this.options.endsWith } : this.options.endsWith),
|
|
2423
|
+
popsAfterNode: [...(this.options.popsAfterNode || [])],
|
|
2424
|
+
popsAtEOFSource: this.options.popsAtEOFSource || false,
|
|
2425
|
+
badToken: this.options.badToken || '',
|
|
2426
|
+
skipToken: this.options.skipToken || '',
|
|
2427
|
+
recognizes: [...(this.options.recognizes || [])],
|
|
2428
|
+
hoistChildren: [...(this.options.hoistChildren || [])],
|
|
2429
|
+
mapContent: {
|
|
2430
|
+
...this.options.mapContent,
|
|
2431
|
+
},
|
|
2432
|
+
onPop: this.options.onPop,
|
|
2433
|
+
onMatch: this.options.onMatch,
|
|
2434
|
+
onAppendContent: this.options.onAppendContent,
|
|
2435
|
+
onAfterChildParse: this.options.onAfterChildParse,
|
|
2436
|
+
onBeforeChildParse: this.options.onBeforeChildParse,
|
|
2437
|
+
initCustomData: this.options.initCustomData,
|
|
2438
|
+
absorbs: this.options.absorbs,
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
createContext(index, level, rootContext) {
|
|
2442
|
+
return new ProstoParserNodeContext(this, index, level, rootContext);
|
|
2443
|
+
}
|
|
2444
|
+
get name() {
|
|
2445
|
+
return this.constructor.name + '[' + this.id.toString() + ']' + '(' + (this.options.label || this.options.icon || '') + ')';
|
|
2446
|
+
}
|
|
2447
|
+
parse(source) {
|
|
2448
|
+
return this.createContext(0, 0).parserContext.parse(source);
|
|
2449
|
+
}
|
|
2450
|
+
beforeOnPop(data) {
|
|
2451
|
+
}
|
|
2452
|
+
beforeOnMatch(data) {
|
|
2453
|
+
}
|
|
2454
|
+
beforeOnAppendContent(s, data) {
|
|
2455
|
+
return s;
|
|
2456
|
+
}
|
|
2457
|
+
beforeOnAfterChildParse(child, data) {
|
|
2458
|
+
}
|
|
2459
|
+
beforeOnBeforeChildParse(child, data) {
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
class BasicNode extends ProstoParserNode {
|
|
2464
|
+
constructor(options) {
|
|
2465
|
+
var _a, _b;
|
|
2466
|
+
const startsWith = (options === null || options === void 0 ? void 0 : options.tokens) ? { token: options === null || options === void 0 ? void 0 : options.tokens[0] } : undefined;
|
|
2467
|
+
const endsWith = (options === null || options === void 0 ? void 0 : options.tokens) ? { token: options === null || options === void 0 ? void 0 : options.tokens[1] } : undefined;
|
|
2468
|
+
const [startOption, endOption] = ((_a = options.tokenOE) === null || _a === void 0 ? void 0 : _a.split('-')) || [];
|
|
2469
|
+
const [startBSlash, endBSlash] = ((_b = options.backSlash) === null || _b === void 0 ? void 0 : _b.split('-')) || [];
|
|
2470
|
+
if (startsWith) {
|
|
2471
|
+
startsWith.omit = startOption === 'omit';
|
|
2472
|
+
startsWith.eject = startOption === 'eject';
|
|
2473
|
+
startsWith.ignoreBackSlashed = startBSlash === 'ignore';
|
|
2474
|
+
}
|
|
2475
|
+
if (endsWith) {
|
|
2476
|
+
endsWith.omit = endOption === 'omit';
|
|
2477
|
+
endsWith.eject = endOption === 'eject';
|
|
2478
|
+
endsWith.ignoreBackSlashed = endBSlash === 'ignore';
|
|
2479
|
+
}
|
|
2480
|
+
super({
|
|
2481
|
+
icon: options.icon || '',
|
|
2482
|
+
label: typeof options.label === 'string' ? options.label : '',
|
|
2483
|
+
startsWith,
|
|
2484
|
+
endsWith,
|
|
2485
|
+
badToken: options.badToken,
|
|
2486
|
+
skipToken: options.skipToken,
|
|
2487
|
+
});
|
|
2488
|
+
if (options.recursive) {
|
|
2489
|
+
this.addAbsorbs(this, 'join');
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
var parser_esmBundler = /*#__PURE__*/Object.freeze({
|
|
2495
|
+
__proto__: null,
|
|
2496
|
+
BasicNode: BasicNode,
|
|
2497
|
+
ProstoParserContext: ProstoParserContext,
|
|
2498
|
+
ProstoParserNode: ProstoParserNode,
|
|
2499
|
+
ProstoParserNodeContext: ProstoParserNodeContext,
|
|
2500
|
+
renderCodeFragment: renderCodeFragment
|
|
2501
|
+
});
|
|
2502
|
+
|
|
2503
|
+
var require$$1 = /*@__PURE__*/getAugmentedNamespace(parser_esmBundler);
|
|
2504
|
+
|
|
2505
|
+
var require$$2 = /*@__PURE__*/getAugmentedNamespace(tree_esmBundler);
|
|
2506
|
+
|
|
2507
|
+
(function (exports) {
|
|
2508
|
+
|
|
2509
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2510
|
+
|
|
2511
|
+
var cache = require$$0;
|
|
2512
|
+
var parser$1 = require$$1;
|
|
2513
|
+
var tree = require$$2;
|
|
2514
|
+
|
|
2515
|
+
function parsePath(expr) {
|
|
2516
|
+
return parser.parse(expr).extractCustomDataTree();
|
|
2517
|
+
}
|
|
2518
|
+
class ParametricNodeWithRegex extends parser$1.BasicNode {
|
|
2519
|
+
constructor(options, rgNode) {
|
|
2520
|
+
super(options);
|
|
2521
|
+
const hoistRegex = {
|
|
2522
|
+
as: 'regex',
|
|
2523
|
+
node: regexNode,
|
|
2524
|
+
onConflict: 'overwrite',
|
|
2525
|
+
removeChildFromContent: true,
|
|
2526
|
+
deep: 1,
|
|
2527
|
+
mapRule: ({ content }) => content.join('').replace(/^\(\^/, '(').replace(/\$\)$/, ')'),
|
|
2528
|
+
};
|
|
2529
|
+
this.mapContent('name', 'join')
|
|
2530
|
+
.mapContent('value', content => content.shift())
|
|
2531
|
+
.popsAtEOFSource(true)
|
|
2532
|
+
.addRecognizes(rgNode)
|
|
2533
|
+
.addPopsAfterNode(rgNode)
|
|
2534
|
+
.addHoistChildren(hoistRegex);
|
|
2535
|
+
}
|
|
2536
|
+
beforeOnPop(data) {
|
|
2537
|
+
if (data.customData.name.endsWith('?')) {
|
|
2538
|
+
data.customData.name = data.customData.name.slice(0, -1);
|
|
2539
|
+
data.customData.value = data.customData.name;
|
|
2540
|
+
data.customData.optional = true;
|
|
2541
|
+
}
|
|
2542
|
+
else if (data.parserContext.here[0] === '?') {
|
|
2543
|
+
data.customData.optional = true;
|
|
2544
|
+
data.parserContext.jump();
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
const regexNode = new parser$1.BasicNode({
|
|
2549
|
+
label: 'RegEx',
|
|
2550
|
+
tokens: ['(', ')'],
|
|
2551
|
+
backSlash: 'ignore-ignore',
|
|
2552
|
+
recursive: true,
|
|
2553
|
+
}).onMatch(({ parserContext, context }) => {
|
|
2554
|
+
var _a;
|
|
2555
|
+
if (((_a = parserContext.fromStack()) === null || _a === void 0 ? void 0 : _a.node) === context.node) {
|
|
2556
|
+
if (!parserContext.here.startsWith('?:')) {
|
|
2557
|
+
context.content[0] += '?:';
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
});
|
|
2561
|
+
const paramNode = new ParametricNodeWithRegex({
|
|
2562
|
+
label: 'Parameter',
|
|
2563
|
+
tokens: [':', /[\/\-]/],
|
|
2564
|
+
tokenOE: 'omit-eject',
|
|
2565
|
+
backSlash: 'ignore-',
|
|
2566
|
+
}, regexNode).initCustomData(() => ({ type: exports.EPathSegmentType.VARIABLE, value: '', regex: '([^\\/]*)', name: '' }));
|
|
2567
|
+
const wildcardNode = new ParametricNodeWithRegex({
|
|
2568
|
+
label: 'Wildcard',
|
|
2569
|
+
tokens: ['*', /[^*\()]/],
|
|
2570
|
+
tokenOE: '-eject',
|
|
2571
|
+
}, regexNode).initCustomData(() => ({ type: exports.EPathSegmentType.WILDCARD, value: '*', regex: '(.*)', name: '' }));
|
|
2572
|
+
const staticNode = new parser$1.BasicNode({
|
|
2573
|
+
label: 'Static',
|
|
2574
|
+
tokens: [/[^:\*]/, /[:\*]/],
|
|
2575
|
+
backSlash: '-ignore',
|
|
2576
|
+
tokenOE: '-eject',
|
|
2577
|
+
}).initCustomData(() => ({ type: exports.EPathSegmentType.STATIC, value: '' }))
|
|
2578
|
+
.mapContent('value', content => content.splice(0).join('').replace(/\\:/g, ':'))
|
|
2579
|
+
.popsAtEOFSource(true);
|
|
2580
|
+
const parser = new parser$1.BasicNode({}).addRecognizes(staticNode, paramNode, wildcardNode);
|
|
2581
|
+
|
|
2582
|
+
exports.EPathSegmentType = void 0;
|
|
2583
|
+
(function (EPathSegmentType) {
|
|
2584
|
+
EPathSegmentType[EPathSegmentType["STATIC"] = 0] = "STATIC";
|
|
2585
|
+
EPathSegmentType[EPathSegmentType["VARIABLE"] = 1] = "VARIABLE";
|
|
2586
|
+
EPathSegmentType[EPathSegmentType["REGEX"] = 2] = "REGEX";
|
|
2587
|
+
EPathSegmentType[EPathSegmentType["WILDCARD"] = 3] = "WILDCARD";
|
|
2588
|
+
})(exports.EPathSegmentType || (exports.EPathSegmentType = {}));
|
|
2589
|
+
|
|
2590
|
+
function safeDecode(f, v) {
|
|
2591
|
+
try {
|
|
2592
|
+
return f(v);
|
|
2593
|
+
}
|
|
2594
|
+
catch (e) {
|
|
2595
|
+
return v;
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
function safeDecodeURIComponent(uri) {
|
|
2599
|
+
if (!uri || uri.indexOf('%') < 0)
|
|
2600
|
+
return uri;
|
|
2601
|
+
return safeDecode(decodeURIComponent, uri);
|
|
2602
|
+
}
|
|
2603
|
+
function safeDecodeURI(uri) {
|
|
2604
|
+
if (!uri || uri.indexOf('%') < 0)
|
|
2605
|
+
return uri;
|
|
2606
|
+
return safeDecode(decodeURI, uri);
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
function countOfSlashes(s) {
|
|
2610
|
+
let last = 0;
|
|
2611
|
+
let count = 0;
|
|
2612
|
+
let index = s.indexOf('/');
|
|
2613
|
+
last = index + 1;
|
|
2614
|
+
while (index >= 0) {
|
|
2615
|
+
count++;
|
|
2616
|
+
index = s.indexOf('/', last);
|
|
2617
|
+
last = index + 1;
|
|
2618
|
+
}
|
|
2619
|
+
return count;
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
class CodeString {
|
|
2623
|
+
constructor() {
|
|
2624
|
+
this.code = '';
|
|
2625
|
+
}
|
|
2626
|
+
append(s, newLine = false) {
|
|
2627
|
+
this.code += ['', s].flat().join(newLine ? '\n' : '');
|
|
2628
|
+
}
|
|
2629
|
+
prepend(s, newLine = false) {
|
|
2630
|
+
this.code = [s, ''].flat().join(newLine ? '\n' : '') + this.code;
|
|
2631
|
+
}
|
|
2632
|
+
generateFunction(...args) {
|
|
2633
|
+
return new Function(args.join(','), this.code);
|
|
2634
|
+
}
|
|
2635
|
+
toString() {
|
|
2636
|
+
return this.code;
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
|
|
2640
|
+
function escapeRegex(s) {
|
|
2641
|
+
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
function generateFullMatchRegex(segments, nonCapturing = false) {
|
|
2645
|
+
let regex = '';
|
|
2646
|
+
let optional = false;
|
|
2647
|
+
segments.forEach(segment => {
|
|
2648
|
+
switch (segment.type) {
|
|
2649
|
+
case exports.EPathSegmentType.STATIC:
|
|
2650
|
+
if (optional) {
|
|
2651
|
+
if (['-', '/'].includes(segment.value)) {
|
|
2652
|
+
regex += escapeRegex(segment.value) + '?';
|
|
2653
|
+
}
|
|
2654
|
+
else {
|
|
2655
|
+
throw new Error(`Static route segment "${segment.value}" is not allowed after optional parameters.`);
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
else {
|
|
2659
|
+
regex += escapeRegex(segment.value);
|
|
2660
|
+
}
|
|
2661
|
+
break;
|
|
2662
|
+
case exports.EPathSegmentType.VARIABLE:
|
|
2663
|
+
case exports.EPathSegmentType.WILDCARD:
|
|
2664
|
+
if (optional && !segment.optional)
|
|
2665
|
+
throw new Error('Obligatory route parameters are not allowed after optional parameters. Use "?" to mark it as an optional route parameter.');
|
|
2666
|
+
if (segment.optional && !optional) {
|
|
2667
|
+
if (regex.endsWith('/')) {
|
|
2668
|
+
regex += '?';
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
regex += nonCapturing ? segment.regex.replace(/^\(/, '(?:') : segment.regex;
|
|
2672
|
+
if (segment.optional) {
|
|
2673
|
+
optional = true;
|
|
2674
|
+
regex += '?';
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
});
|
|
2678
|
+
return regex;
|
|
2679
|
+
}
|
|
2680
|
+
function generateFullMatchFunc(segments, ignoreCase = false) {
|
|
2681
|
+
const str = new CodeString();
|
|
2682
|
+
const regex = generateFullMatchRegex(segments);
|
|
2683
|
+
let index = 0;
|
|
2684
|
+
const obj = {};
|
|
2685
|
+
segments.forEach(segment => {
|
|
2686
|
+
switch (segment.type) {
|
|
2687
|
+
case exports.EPathSegmentType.VARIABLE:
|
|
2688
|
+
case exports.EPathSegmentType.WILDCARD:
|
|
2689
|
+
index++;
|
|
2690
|
+
obj[segment.value] = obj[segment.value] || [];
|
|
2691
|
+
obj[segment.value].push(index);
|
|
2692
|
+
}
|
|
2693
|
+
});
|
|
2694
|
+
Object.keys(obj).forEach(key => {
|
|
2695
|
+
str.append(obj[key].length > 1
|
|
2696
|
+
? `\tparams['${key}'] = [${obj[key].map(i => `utils.safeDecodeURIComponent(a[${i}])`).join(', ')}]`
|
|
2697
|
+
: `\tparams['${key}'] = utils.safeDecodeURIComponent(a[${obj[key][0]}])`, true);
|
|
2698
|
+
});
|
|
2699
|
+
str.prepend([`const a = path.match(/^${regex}$/${ignoreCase ? 'i' : ''})`, 'if (a) {'], true);
|
|
2700
|
+
str.append(['}', 'return a'], true);
|
|
2701
|
+
return str.generateFunction('path', 'params', 'utils');
|
|
2702
|
+
}
|
|
2703
|
+
function generatePathBuilder(segments) {
|
|
2704
|
+
const str = new CodeString();
|
|
2705
|
+
const obj = {};
|
|
2706
|
+
const index = {};
|
|
2707
|
+
segments.forEach(segment => {
|
|
2708
|
+
switch (segment.type) {
|
|
2709
|
+
case exports.EPathSegmentType.VARIABLE:
|
|
2710
|
+
case exports.EPathSegmentType.WILDCARD:
|
|
2711
|
+
obj[segment.value] = obj[segment.value] || 0;
|
|
2712
|
+
obj[segment.value]++;
|
|
2713
|
+
index[segment.value] = 0;
|
|
2714
|
+
}
|
|
2715
|
+
});
|
|
2716
|
+
str.append('return `');
|
|
2717
|
+
segments.forEach(segment => {
|
|
2718
|
+
switch (segment.type) {
|
|
2719
|
+
case exports.EPathSegmentType.STATIC:
|
|
2720
|
+
str.append(segment.value.replace(/`/g, '\\`'));
|
|
2721
|
+
break;
|
|
2722
|
+
case exports.EPathSegmentType.VARIABLE:
|
|
2723
|
+
case exports.EPathSegmentType.WILDCARD:
|
|
2724
|
+
if (obj[segment.value] > 1) {
|
|
2725
|
+
str.append('${ params[\'' + segment.value + `\'][${index[segment.value]}] }`);
|
|
2726
|
+
index[segment.value]++;
|
|
2727
|
+
}
|
|
2728
|
+
else {
|
|
2729
|
+
str.append('${ params[\'' + segment.value + '\'] }');
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
});
|
|
2733
|
+
str.append('`');
|
|
2734
|
+
return str.generateFunction('params');
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
const banner = () => `[prostojs/router][${new Date().toISOString().replace('T', ' ').replace(/\.\d{3}z$/i, '')}] `;
|
|
2738
|
+
|
|
2739
|
+
const methods = ['GET', 'PUT', 'POST', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];
|
|
2740
|
+
const matcherFuncUtils = {
|
|
2741
|
+
safeDecodeURIComponent,
|
|
2742
|
+
};
|
|
2743
|
+
class ProstoRouter {
|
|
2744
|
+
constructor(_options) {
|
|
2745
|
+
this.root = {};
|
|
2746
|
+
this.routes = [];
|
|
2747
|
+
this.routesRegistry = {};
|
|
2748
|
+
this._options = {
|
|
2749
|
+
..._options,
|
|
2750
|
+
};
|
|
2751
|
+
if (!this._options.silent) {
|
|
2752
|
+
consoleInfo('The Router Initialized');
|
|
2753
|
+
}
|
|
2754
|
+
const cacheOpts = {
|
|
2755
|
+
limit: (_options === null || _options === void 0 ? void 0 : _options.cacheLimit) || 0,
|
|
2756
|
+
};
|
|
2757
|
+
if (_options === null || _options === void 0 ? void 0 : _options.cacheLimit) {
|
|
2758
|
+
this.cache = {
|
|
2759
|
+
GET: new cache.ProstoCache(cacheOpts),
|
|
2760
|
+
PUT: new cache.ProstoCache(cacheOpts),
|
|
2761
|
+
POST: new cache.ProstoCache(cacheOpts),
|
|
2762
|
+
PATCH: new cache.ProstoCache(cacheOpts),
|
|
2763
|
+
DELETE: new cache.ProstoCache(cacheOpts),
|
|
2764
|
+
HEAD: new cache.ProstoCache(cacheOpts),
|
|
2765
|
+
OPTIONS: new cache.ProstoCache(cacheOpts),
|
|
2766
|
+
};
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
refreshCache(method) {
|
|
2770
|
+
if (this._options.cacheLimit && this.cache) {
|
|
2771
|
+
if (method === '*') {
|
|
2772
|
+
this.cache.GET.reset();
|
|
2773
|
+
this.cache.PUT.reset();
|
|
2774
|
+
this.cache.POST.reset();
|
|
2775
|
+
this.cache.PATCH.reset();
|
|
2776
|
+
this.cache.DELETE.reset();
|
|
2777
|
+
this.cache.HEAD.reset();
|
|
2778
|
+
this.cache.OPTIONS.reset();
|
|
2779
|
+
}
|
|
2780
|
+
else if (this.cache && this.cache[method]) {
|
|
2781
|
+
this.cache[method].reset();
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
registerRoute(method, path, options, handler) {
|
|
2786
|
+
this.refreshCache(method);
|
|
2787
|
+
const opts = this.mergeOptions(options);
|
|
2788
|
+
const normalPath = ('/' + path)
|
|
2789
|
+
.replace(/^\/\//, '/')
|
|
2790
|
+
.replace(/\/$/, '')
|
|
2791
|
+
.replace(/%/g, '%25');
|
|
2792
|
+
const { root } = this;
|
|
2793
|
+
const segments = parsePath(normalPath);
|
|
2794
|
+
if (!root[method]) {
|
|
2795
|
+
root[method] = {
|
|
2796
|
+
statics: {},
|
|
2797
|
+
parametrics: {
|
|
2798
|
+
byParts: [],
|
|
2799
|
+
},
|
|
2800
|
+
wildcards: [],
|
|
2801
|
+
};
|
|
2802
|
+
}
|
|
2803
|
+
const rootMethod = root[method];
|
|
2804
|
+
const generalized = method + ':' + segments.map(s => {
|
|
2805
|
+
switch (s.type) {
|
|
2806
|
+
case exports.EPathSegmentType.STATIC: return s.value;
|
|
2807
|
+
case exports.EPathSegmentType.VARIABLE: return '<VAR' + (s.regex === '([^-\\/]*)' ? '' : s.regex) + '>';
|
|
2808
|
+
case exports.EPathSegmentType.WILDCARD: return s.value;
|
|
2809
|
+
}
|
|
2810
|
+
}).join('');
|
|
2811
|
+
let route = this.routesRegistry[generalized];
|
|
2812
|
+
if (route) {
|
|
2813
|
+
if (this._options.disableDuplicatePath) {
|
|
2814
|
+
const error = `Attempt to register duplicated path: "${path}". Duplicate paths are disabled.\nYou can enable duplicated paths removing 'disableDuplicatePath' option.`;
|
|
2815
|
+
consoleError(error);
|
|
2816
|
+
throw new Error(error);
|
|
2817
|
+
}
|
|
2818
|
+
if (route.handlers.includes(handler)) {
|
|
2819
|
+
consoleError('Duplicate route with same handler ignored ' + generalized);
|
|
2820
|
+
}
|
|
2821
|
+
else {
|
|
2822
|
+
consoleWarn('Duplicate route registered ' + generalized);
|
|
2823
|
+
route.handlers.push(handler);
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
else {
|
|
2827
|
+
const isStatic = segments.length === 1 && segments[0].type === exports.EPathSegmentType.STATIC || segments.length === 0;
|
|
2828
|
+
const isParametric = !!segments.find(p => p.type === exports.EPathSegmentType.VARIABLE);
|
|
2829
|
+
const firstOptional = segments.findIndex(p => p.optional);
|
|
2830
|
+
const isOptional = firstOptional >= 0;
|
|
2831
|
+
const isWildcard = !!segments.find(p => p.type === exports.EPathSegmentType.WILDCARD);
|
|
2832
|
+
const lengths = segments.slice(0, firstOptional >= 0 ? firstOptional : undefined).map(s => s.type === exports.EPathSegmentType.STATIC ? s.value.length : 0);
|
|
2833
|
+
const normalPathCase = segments[0] ? (this._options.ignoreCase ? segments[0].value.toLowerCase() : segments[0].value) : '/';
|
|
2834
|
+
this.routesRegistry[generalized] = route = {
|
|
2835
|
+
method,
|
|
2836
|
+
options: opts,
|
|
2837
|
+
path: normalPath,
|
|
2838
|
+
handlers: [handler],
|
|
2839
|
+
isStatic,
|
|
2840
|
+
isParametric,
|
|
2841
|
+
isOptional,
|
|
2842
|
+
isWildcard,
|
|
2843
|
+
segments,
|
|
2844
|
+
lengths,
|
|
2845
|
+
minLength: lengths.reduce((a, b) => a + b, 0),
|
|
2846
|
+
firstLength: lengths[0],
|
|
2847
|
+
firstStatic: normalPathCase.slice(0, lengths[0]),
|
|
2848
|
+
generalized,
|
|
2849
|
+
fullMatch: generateFullMatchFunc(segments, this._options.ignoreCase),
|
|
2850
|
+
pathBuilder: generatePathBuilder(segments),
|
|
2851
|
+
};
|
|
2852
|
+
this.routes.push(route);
|
|
2853
|
+
if (route.isStatic) {
|
|
2854
|
+
rootMethod.statics[normalPathCase] = route;
|
|
2855
|
+
}
|
|
2856
|
+
else {
|
|
2857
|
+
if (route.isParametric && !route.isWildcard && !route.isOptional) {
|
|
2858
|
+
const countOfParts = route.segments
|
|
2859
|
+
.filter(s => s.type === exports.EPathSegmentType.STATIC)
|
|
2860
|
+
.map(s => countOfSlashes(s.value)).reduce((a, b) => a + b, 1);
|
|
2861
|
+
const byParts = rootMethod.parametrics.byParts[countOfParts] = rootMethod.parametrics.byParts[countOfParts] || [];
|
|
2862
|
+
byParts.push(route);
|
|
2863
|
+
rootMethod.parametrics.byParts[countOfParts] = byParts.sort(routeSorter);
|
|
2864
|
+
}
|
|
2865
|
+
else if (route.isWildcard || route.isOptional) {
|
|
2866
|
+
if (route.isOptional && route.firstStatic.endsWith('/')) {
|
|
2867
|
+
route.firstStatic = route.firstStatic.slice(0, -1);
|
|
2868
|
+
route.firstLength--;
|
|
2869
|
+
route.minLength = Math.min(route.minLength, route.firstLength);
|
|
2870
|
+
}
|
|
2871
|
+
rootMethod.wildcards.push(route);
|
|
2872
|
+
rootMethod.wildcards = rootMethod.wildcards.sort(routeSorter);
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
}
|
|
2876
|
+
return {
|
|
2877
|
+
getPath: route.pathBuilder,
|
|
2878
|
+
getArgs: () => route.segments.filter(p => p.type === exports.EPathSegmentType.VARIABLE || p.type === exports.EPathSegmentType.WILDCARD).map(s => s.name),
|
|
2879
|
+
getStaticPart: () => route.firstStatic,
|
|
2880
|
+
test: route.fullMatch,
|
|
2881
|
+
isStatic: route.isStatic,
|
|
2882
|
+
isParametric: route.isParametric,
|
|
2883
|
+
isWildcard: route.isWildcard,
|
|
2884
|
+
generalized,
|
|
2885
|
+
};
|
|
2886
|
+
}
|
|
2887
|
+
mergeOptions(options) {
|
|
2888
|
+
return {
|
|
2889
|
+
...options,
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
sanitizePath(path, ignoreTrailingSlash) {
|
|
2893
|
+
const end = path.indexOf('?');
|
|
2894
|
+
let slicedPath = end >= 0 ? path.slice(0, end) : path;
|
|
2895
|
+
if ((ignoreTrailingSlash || this._options.ignoreTrailingSlash) && slicedPath[slicedPath.length - 1] === '/') {
|
|
2896
|
+
slicedPath = slicedPath.slice(0, slicedPath.length - 1);
|
|
2897
|
+
}
|
|
2898
|
+
const normalPath = safeDecodeURI(slicedPath
|
|
2899
|
+
.replace(/%25/g, '%2525'));
|
|
2900
|
+
return {
|
|
2901
|
+
normalPath,
|
|
2902
|
+
normalPathWithCase: this._options.ignoreCase ? normalPath.toLowerCase() : normalPath,
|
|
2903
|
+
};
|
|
2904
|
+
}
|
|
2905
|
+
lookup(method, path, ignoreTrailingSlash) {
|
|
2906
|
+
if (this._options.cacheLimit && this.cache && this.cache[method]) {
|
|
2907
|
+
const cached = this.cache[method].get(path);
|
|
2908
|
+
if (cached)
|
|
2909
|
+
return cached;
|
|
2910
|
+
}
|
|
2911
|
+
const { normalPath, normalPathWithCase } = this.sanitizePath(path, ignoreTrailingSlash);
|
|
2912
|
+
const rootMethod = this.root[method];
|
|
2913
|
+
const lookupResult = {
|
|
2914
|
+
route: null,
|
|
2915
|
+
ctx: { params: {} },
|
|
2916
|
+
};
|
|
2917
|
+
const cache = (result) => {
|
|
2918
|
+
if (this._options.cacheLimit && this.cache && this.cache[method]) {
|
|
2919
|
+
this.cache[method].set(path, result);
|
|
2920
|
+
}
|
|
2921
|
+
return result;
|
|
2922
|
+
};
|
|
2923
|
+
if (rootMethod) {
|
|
2924
|
+
lookupResult.route = rootMethod.statics[normalPathWithCase];
|
|
2925
|
+
if (lookupResult.route)
|
|
2926
|
+
return cache(lookupResult);
|
|
2927
|
+
const pathSegmentsCount = countOfSlashes(normalPath) + 1;
|
|
2928
|
+
const pathLength = normalPath.length;
|
|
2929
|
+
const { parametrics } = rootMethod;
|
|
2930
|
+
const bySegments = parametrics.byParts[pathSegmentsCount];
|
|
2931
|
+
if (bySegments) {
|
|
2932
|
+
for (let i = 0; i < bySegments.length; i++) {
|
|
2933
|
+
lookupResult.route = bySegments[i];
|
|
2934
|
+
if (pathLength >= lookupResult.route.minLength) {
|
|
2935
|
+
if (normalPathWithCase.startsWith(lookupResult.route.firstStatic)
|
|
2936
|
+
&& lookupResult.route.fullMatch(normalPath, lookupResult.ctx.params, matcherFuncUtils)) {
|
|
2937
|
+
return cache(lookupResult);
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
const { wildcards } = rootMethod;
|
|
2943
|
+
for (let i = 0; i < wildcards.length; i++) {
|
|
2944
|
+
lookupResult.route = wildcards[i];
|
|
2945
|
+
if (pathLength >= lookupResult.route.minLength) {
|
|
2946
|
+
if (normalPathWithCase.startsWith(lookupResult.route.firstStatic)
|
|
2947
|
+
&& lookupResult.route.fullMatch(normalPath, lookupResult.ctx.params, matcherFuncUtils)) {
|
|
2948
|
+
return cache(lookupResult);
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
find(method, path) {
|
|
2955
|
+
return this.lookup(method, path);
|
|
2956
|
+
}
|
|
2957
|
+
on(method, path, options, handler) {
|
|
2958
|
+
const { opts, func } = extractOptionsAndHandler(options, handler);
|
|
2959
|
+
if (method === '*') {
|
|
2960
|
+
return methods.map(m => this.registerRoute(m, path, opts, func))[0];
|
|
2961
|
+
}
|
|
2962
|
+
return this.registerRoute(method, path, opts, func);
|
|
2963
|
+
}
|
|
2964
|
+
all(path, options, handler) {
|
|
2965
|
+
const { opts, func } = extractOptionsAndHandler(options, handler);
|
|
2966
|
+
return this.on('*', path, opts, func);
|
|
2967
|
+
}
|
|
2968
|
+
get(path, options, handler) {
|
|
2969
|
+
const { opts, func } = extractOptionsAndHandler(options, handler);
|
|
2970
|
+
return this.on('GET', path, opts, func);
|
|
2971
|
+
}
|
|
2972
|
+
put(path, options, handler) {
|
|
2973
|
+
const { opts, func } = extractOptionsAndHandler(options, handler);
|
|
2974
|
+
return this.on('PUT', path, opts, func);
|
|
2975
|
+
}
|
|
2976
|
+
post(path, options, handler) {
|
|
2977
|
+
const { opts, func } = extractOptionsAndHandler(options, handler);
|
|
2978
|
+
return this.on('POST', path, opts, func);
|
|
2979
|
+
}
|
|
2980
|
+
patch(path, options, handler) {
|
|
2981
|
+
const { opts, func } = extractOptionsAndHandler(options, handler);
|
|
2982
|
+
return this.on('PATCH', path, opts, func);
|
|
2983
|
+
}
|
|
2984
|
+
delete(path, options, handler) {
|
|
2985
|
+
const { opts, func } = extractOptionsAndHandler(options, handler);
|
|
2986
|
+
return this.on('DELETE', path, opts, func);
|
|
2987
|
+
}
|
|
2988
|
+
options(path, options, handler) {
|
|
2989
|
+
const { opts, func } = extractOptionsAndHandler(options, handler);
|
|
2990
|
+
return this.on('OPTIONS', path, opts, func);
|
|
2991
|
+
}
|
|
2992
|
+
head(path, options, handler) {
|
|
2993
|
+
const { opts, func } = extractOptionsAndHandler(options, handler);
|
|
2994
|
+
return this.on('HEAD', path, opts, func);
|
|
2995
|
+
}
|
|
2996
|
+
getRoutes() {
|
|
2997
|
+
return this.routes;
|
|
2998
|
+
}
|
|
2999
|
+
toTree() {
|
|
3000
|
+
const rootStyle = (v) => '[1m' + v + '[22m';
|
|
3001
|
+
const paramStyle = (v) => '[36m' + '[1m' + ':' + v + '[39m' + '[22m';
|
|
3002
|
+
const regexStyle = (v) => '[36m' + '[2m' + v + '[22m' + '[39m';
|
|
3003
|
+
const handlerStyle = (v) => '[1m' + '[92m' + '→ ' + '[39m' + '[22m' + v;
|
|
3004
|
+
const methodStyle = (v) => '[22m' + '[92m' + '• (' + v + ') ' + '[39m';
|
|
3005
|
+
const data = {
|
|
3006
|
+
label: '⁕ Router',
|
|
3007
|
+
stylist: rootStyle,
|
|
3008
|
+
methods: [],
|
|
3009
|
+
children: [],
|
|
3010
|
+
};
|
|
3011
|
+
function toChild(d, label, stylist) {
|
|
3012
|
+
let found = d.children.find(c => c.label === label);
|
|
3013
|
+
if (!found) {
|
|
3014
|
+
found = {
|
|
3015
|
+
label,
|
|
3016
|
+
stylist,
|
|
3017
|
+
methods: [],
|
|
3018
|
+
children: [],
|
|
3019
|
+
};
|
|
3020
|
+
d.children.push(found);
|
|
3021
|
+
}
|
|
3022
|
+
return found;
|
|
3023
|
+
}
|
|
3024
|
+
this.routes.sort((a, b) => a.path > b.path ? 1 : -1).forEach(route => {
|
|
3025
|
+
let cur = data;
|
|
3026
|
+
let last = '';
|
|
3027
|
+
route.segments.forEach(s => {
|
|
3028
|
+
let parts;
|
|
3029
|
+
switch (s.type) {
|
|
3030
|
+
case exports.EPathSegmentType.STATIC:
|
|
3031
|
+
parts = s.value.split('/');
|
|
3032
|
+
last += parts.shift();
|
|
3033
|
+
for (let i = 0; i < parts.length; i++) {
|
|
3034
|
+
if (last) {
|
|
3035
|
+
cur = toChild(cur, last);
|
|
3036
|
+
}
|
|
3037
|
+
last = '/' + parts[i];
|
|
3038
|
+
}
|
|
3039
|
+
break;
|
|
3040
|
+
case exports.EPathSegmentType.VARIABLE:
|
|
3041
|
+
case exports.EPathSegmentType.WILDCARD:
|
|
3042
|
+
last += `${paramStyle(s.value)}${regexStyle(s.regex)}`;
|
|
3043
|
+
}
|
|
3044
|
+
});
|
|
3045
|
+
if (last) {
|
|
3046
|
+
cur = toChild(cur, last, handlerStyle);
|
|
3047
|
+
cur.methods.push(route.method);
|
|
3048
|
+
}
|
|
3049
|
+
});
|
|
3050
|
+
new tree.ProstoTree({
|
|
3051
|
+
renderLabel: (node, behind) => {
|
|
3052
|
+
const styledLabel = node.stylist ? node.stylist(node.label) : node.label;
|
|
3053
|
+
if (node.methods.length) {
|
|
3054
|
+
return styledLabel + '\n' + behind + node.methods.map(m => methodStyle(m)).join('\n' + behind);
|
|
3055
|
+
}
|
|
3056
|
+
return styledLabel;
|
|
3057
|
+
},
|
|
3058
|
+
}).print(data);
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
function extractOptionsAndHandler(options, handler) {
|
|
3062
|
+
let opts = {};
|
|
3063
|
+
let func = handler;
|
|
3064
|
+
if (typeof options === 'function') {
|
|
3065
|
+
func = options;
|
|
3066
|
+
}
|
|
3067
|
+
else {
|
|
3068
|
+
opts = options;
|
|
3069
|
+
}
|
|
3070
|
+
return { opts, func };
|
|
3071
|
+
}
|
|
3072
|
+
function routeSorter(a, b) {
|
|
3073
|
+
if (a.isWildcard !== b.isWildcard) {
|
|
3074
|
+
return a.isWildcard ? 1 : -1;
|
|
3075
|
+
}
|
|
3076
|
+
const len = b.minLength - a.minLength;
|
|
3077
|
+
if (len)
|
|
3078
|
+
return len;
|
|
3079
|
+
for (let i = 0; i < a.lengths.length; i++) {
|
|
3080
|
+
const len = b.lengths[i] - a.lengths[i];
|
|
3081
|
+
if (len)
|
|
3082
|
+
return len;
|
|
3083
|
+
}
|
|
3084
|
+
return 0;
|
|
3085
|
+
}
|
|
3086
|
+
function consoleError(v) {
|
|
3087
|
+
console.info('[91m' + banner() + v + '[39m');
|
|
3088
|
+
}
|
|
3089
|
+
function consoleWarn(v) {
|
|
3090
|
+
console.info('[33m' + banner() + v + '[39m');
|
|
3091
|
+
}
|
|
3092
|
+
function consoleInfo(v) {
|
|
3093
|
+
console.info('[32m' + '[2m' + banner() + v + '[39m' + '[22m');
|
|
3094
|
+
}
|
|
3095
|
+
|
|
3096
|
+
exports.ProstoRouter = ProstoRouter;
|
|
3097
|
+
exports.escapeRegex = escapeRegex;
|
|
3098
|
+
exports.safeDecodeURI = safeDecodeURI;
|
|
3099
|
+
exports.safeDecodeURIComponent = safeDecodeURIComponent;
|
|
3100
|
+
} (router_cjs_prod));
|
|
3101
|
+
|
|
1167
3102
|
function getOtelMate() {
|
|
1168
3103
|
return getMoostMate();
|
|
1169
3104
|
}
|