orator 3.0.10 → 4.0.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/orator.js CHANGED
@@ -1,3 +1,13 @@
1
+ "use strict";
2
+
3
+ const _excluded = ["version", "host"];
4
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
5
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
7
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
8
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
10
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
1
11
  (function (f) {
2
12
  if (typeof exports === "object" && typeof module !== "undefined") {
3
13
  module.exports = f();
@@ -507,7 +517,7 @@
507
517
  }).call(this);
508
518
  }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
509
519
  }, {
510
- "object-assign": 36,
520
+ "object-assign": 23,
511
521
  "util/": 4
512
522
  }],
513
523
  2: [function (require, module, exports) {
@@ -528,7 +538,7 @@
528
538
  // old school shim for old browsers
529
539
  module.exports = function inherits(ctor, superCtor) {
530
540
  ctor.super_ = superCtor;
531
- var TempCtor = function () {};
541
+ var TempCtor = function TempCtor() {};
532
542
  TempCtor.prototype = superCtor.prototype;
533
543
  ctor.prototype = new TempCtor();
534
544
  ctor.prototype.constructor = ctor;
@@ -1046,736 +1056,69 @@
1046
1056
  }).call(this, require('_process'), typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
1047
1057
  }, {
1048
1058
  "./support/isBuffer": 3,
1049
- "_process": 37,
1059
+ "_process": 24,
1050
1060
  "inherits": 2
1051
1061
  }],
1052
1062
  5: [function (require, module, exports) {
1053
- 'use strict';
1054
-
1055
- Object.defineProperty(exports, "__esModule", {
1056
- value: true
1057
- });
1058
- exports.default = asyncify;
1059
- var _initialParams = require('./internal/initialParams.js');
1060
- var _initialParams2 = _interopRequireDefault(_initialParams);
1061
- var _setImmediate = require('./internal/setImmediate.js');
1062
- var _setImmediate2 = _interopRequireDefault(_setImmediate);
1063
- var _wrapAsync = require('./internal/wrapAsync.js');
1064
- function _interopRequireDefault(obj) {
1065
- return obj && obj.__esModule ? obj : {
1066
- default: obj
1067
- };
1068
- }
1069
-
1070
- /**
1071
- * Take a sync function and make it async, passing its return value to a
1072
- * callback. This is useful for plugging sync functions into a waterfall,
1073
- * series, or other async functions. Any arguments passed to the generated
1074
- * function will be passed to the wrapped function (except for the final
1075
- * callback argument). Errors thrown will be passed to the callback.
1076
- *
1077
- * If the function passed to `asyncify` returns a Promise, that promises's
1078
- * resolved/rejected state will be used to call the callback, rather than simply
1079
- * the synchronous return value.
1080
- *
1081
- * This also means you can asyncify ES2017 `async` functions.
1082
- *
1083
- * @name asyncify
1084
- * @static
1085
- * @memberOf module:Utils
1086
- * @method
1087
- * @alias wrapSync
1088
- * @category Util
1089
- * @param {Function} func - The synchronous function, or Promise-returning
1090
- * function to convert to an {@link AsyncFunction}.
1091
- * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
1092
- * invoked with `(args..., callback)`.
1093
- * @example
1094
- *
1095
- * // passing a regular synchronous function
1096
- * async.waterfall([
1097
- * async.apply(fs.readFile, filename, "utf8"),
1098
- * async.asyncify(JSON.parse),
1099
- * function (data, next) {
1100
- * // data is the result of parsing the text.
1101
- * // If there was a parsing error, it would have been caught.
1102
- * }
1103
- * ], callback);
1104
- *
1105
- * // passing a function returning a promise
1106
- * async.waterfall([
1107
- * async.apply(fs.readFile, filename, "utf8"),
1108
- * async.asyncify(function (contents) {
1109
- * return db.model.create(contents);
1110
- * }),
1111
- * function (model, next) {
1112
- * // `model` is the instantiated model object.
1113
- * // If there was an error, this function would be skipped.
1114
- * }
1115
- * ], callback);
1116
- *
1117
- * // es2017 example, though `asyncify` is not needed if your JS environment
1118
- * // supports async functions out of the box
1119
- * var q = async.queue(async.asyncify(async function(file) {
1120
- * var intermediateStep = await processFile(file);
1121
- * return await somePromise(intermediateStep)
1122
- * }));
1123
- *
1124
- * q.push(files);
1125
- */
1126
- function asyncify(func) {
1127
- if ((0, _wrapAsync.isAsync)(func)) {
1128
- return function (...args /*, callback*/) {
1129
- const callback = args.pop();
1130
- const promise = func.apply(this, args);
1131
- return handlePromise(promise, callback);
1132
- };
1133
- }
1134
- return (0, _initialParams2.default)(function (args, callback) {
1135
- var result;
1136
- try {
1137
- result = func.apply(this, args);
1138
- } catch (e) {
1139
- return callback(e);
1140
- }
1141
- // if result is Promise object
1142
- if (result && typeof result.then === 'function') {
1143
- return handlePromise(result, callback);
1144
- } else {
1145
- callback(null, result);
1146
- }
1147
- });
1148
- }
1149
- function handlePromise(promise, callback) {
1150
- return promise.then(value => {
1151
- invokeCallback(callback, null, value);
1152
- }, err => {
1153
- invokeCallback(callback, err && err.message ? err : new Error(err));
1154
- });
1155
- }
1156
- function invokeCallback(callback, error, value) {
1157
- try {
1158
- callback(error, value);
1159
- } catch (err) {
1160
- (0, _setImmediate2.default)(e => {
1161
- throw e;
1162
- }, err);
1163
- }
1164
- }
1165
- module.exports = exports['default'];
1166
- }, {
1167
- "./internal/initialParams.js": 13,
1168
- "./internal/setImmediate.js": 18,
1169
- "./internal/wrapAsync.js": 19
1170
- }],
1171
- 6: [function (require, module, exports) {
1172
- 'use strict';
1173
-
1174
- Object.defineProperty(exports, "__esModule", {
1175
- value: true
1176
- });
1177
- var _eachOfLimit2 = require('./internal/eachOfLimit.js');
1178
- var _eachOfLimit3 = _interopRequireDefault(_eachOfLimit2);
1179
- var _wrapAsync = require('./internal/wrapAsync.js');
1180
- var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
1181
- var _awaitify = require('./internal/awaitify.js');
1182
- var _awaitify2 = _interopRequireDefault(_awaitify);
1183
- function _interopRequireDefault(obj) {
1184
- return obj && obj.__esModule ? obj : {
1185
- default: obj
1186
- };
1187
- }
1188
-
1189
- /**
1190
- * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
1191
- * time.
1192
- *
1193
- * @name eachOfLimit
1194
- * @static
1195
- * @memberOf module:Collections
1196
- * @method
1197
- * @see [async.eachOf]{@link module:Collections.eachOf}
1198
- * @alias forEachOfLimit
1199
- * @category Collection
1200
- * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1201
- * @param {number} limit - The maximum number of async operations at a time.
1202
- * @param {AsyncFunction} iteratee - An async function to apply to each
1203
- * item in `coll`. The `key` is the item's key, or index in the case of an
1204
- * array.
1205
- * Invoked with (item, key, callback).
1206
- * @param {Function} [callback] - A callback which is called when all
1207
- * `iteratee` functions have finished, or an error occurs. Invoked with (err).
1208
- * @returns {Promise} a promise, if a callback is omitted
1209
- */
1210
- function eachOfLimit(coll, limit, iteratee, callback) {
1211
- return (0, _eachOfLimit3.default)(limit)(coll, (0, _wrapAsync2.default)(iteratee), callback);
1212
- }
1213
- exports.default = (0, _awaitify2.default)(eachOfLimit, 4);
1214
- module.exports = exports['default'];
1215
- }, {
1216
- "./internal/awaitify.js": 9,
1217
- "./internal/eachOfLimit.js": 11,
1218
- "./internal/wrapAsync.js": 19
1219
- }],
1220
- 7: [function (require, module, exports) {
1221
- 'use strict';
1222
-
1223
- Object.defineProperty(exports, "__esModule", {
1224
- value: true
1225
- });
1226
- var _eachOfLimit = require('./eachOfLimit.js');
1227
- var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
1228
- var _awaitify = require('./internal/awaitify.js');
1229
- var _awaitify2 = _interopRequireDefault(_awaitify);
1230
- function _interopRequireDefault(obj) {
1231
- return obj && obj.__esModule ? obj : {
1232
- default: obj
1233
- };
1234
- }
1235
-
1236
1063
  /**
1237
- * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
1238
- *
1239
- * @name eachOfSeries
1240
- * @static
1241
- * @memberOf module:Collections
1242
- * @method
1243
- * @see [async.eachOf]{@link module:Collections.eachOf}
1244
- * @alias forEachOfSeries
1245
- * @category Collection
1246
- * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1247
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
1248
- * `coll`.
1249
- * Invoked with (item, key, callback).
1250
- * @param {Function} [callback] - A callback which is called when all `iteratee`
1251
- * functions have finished, or an error occurs. Invoked with (err).
1252
- * @returns {Promise} a promise, if a callback is omitted
1253
- */
1254
- function eachOfSeries(coll, iteratee, callback) {
1255
- return (0, _eachOfLimit2.default)(coll, 1, iteratee, callback);
1256
- }
1257
- exports.default = (0, _awaitify2.default)(eachOfSeries, 3);
1258
- module.exports = exports['default'];
1259
- }, {
1260
- "./eachOfLimit.js": 6,
1261
- "./internal/awaitify.js": 9
1262
- }],
1263
- 8: [function (require, module, exports) {
1264
- 'use strict';
1265
-
1266
- Object.defineProperty(exports, "__esModule", {
1267
- value: true
1268
- });
1269
- exports.default = asyncEachOfLimit;
1270
- var _breakLoop = require('./breakLoop.js');
1271
- var _breakLoop2 = _interopRequireDefault(_breakLoop);
1272
- function _interopRequireDefault(obj) {
1273
- return obj && obj.__esModule ? obj : {
1274
- default: obj
1275
- };
1276
- }
1064
+ * Fable Core Pre-initialization Service Base
1065
+ *
1066
+ * For a couple services, we need to be able to instantiate them before the Fable object is fully initialized.
1067
+ * This is a base class for those services.
1068
+ *
1069
+ * @author <steven@velozo.com>
1070
+ */
1277
1071
 
1278
- // for async generators
1279
- function asyncEachOfLimit(generator, limit, iteratee, callback) {
1280
- let done = false;
1281
- let canceled = false;
1282
- let awaiting = false;
1283
- let running = 0;
1284
- let idx = 0;
1285
- function replenish() {
1286
- //console.log('replenish')
1287
- if (running >= limit || awaiting || done) return;
1288
- //console.log('replenish awaiting')
1289
- awaiting = true;
1290
- generator.next().then(({
1291
- value,
1292
- done: iterDone
1293
- }) => {
1294
- //console.log('got value', value)
1295
- if (canceled || done) return;
1296
- awaiting = false;
1297
- if (iterDone) {
1298
- done = true;
1299
- if (running <= 0) {
1300
- //console.log('done nextCb')
1301
- callback(null);
1302
- }
1303
- return;
1304
- }
1305
- running++;
1306
- iteratee(value, idx, iterateeCallback);
1307
- idx++;
1308
- replenish();
1309
- }).catch(handleError);
1310
- }
1311
- function iterateeCallback(err, result) {
1312
- //console.log('iterateeCallback')
1313
- running -= 1;
1314
- if (canceled) return;
1315
- if (err) return handleError(err);
1316
- if (err === false) {
1317
- done = true;
1318
- canceled = true;
1319
- return;
1320
- }
1321
- if (result === _breakLoop2.default || done && running <= 0) {
1322
- done = true;
1323
- //console.log('done iterCb')
1324
- return callback(null);
1325
- }
1326
- replenish();
1327
- }
1328
- function handleError(err) {
1329
- if (canceled) return;
1330
- awaiting = false;
1331
- done = true;
1332
- callback(err);
1333
- }
1334
- replenish();
1335
- }
1336
- module.exports = exports['default'];
1337
- }, {
1338
- "./breakLoop.js": 10
1339
- }],
1340
- 9: [function (require, module, exports) {
1341
- 'use strict';
1072
+ class FableCoreServiceProviderBase {
1073
+ constructor(pOptions, pServiceHash) {
1074
+ this.fable = false;
1075
+ this.options = typeof pOptions === 'object' ? pOptions : {};
1076
+ this.serviceType = 'Unknown';
1342
1077
 
1343
- Object.defineProperty(exports, "__esModule", {
1344
- value: true
1345
- });
1346
- exports.default = awaitify;
1347
- // conditionally promisify a function.
1348
- // only return a promise if a callback is omitted
1349
- function awaitify(asyncFn, arity = asyncFn.length) {
1350
- if (!arity) throw new Error('arity is undefined');
1351
- function awaitable(...args) {
1352
- if (typeof args[arity - 1] === 'function') {
1353
- return asyncFn.apply(this, args);
1354
- }
1355
- return new Promise((resolve, reject) => {
1356
- args[arity - 1] = (err, ...cbArgs) => {
1357
- if (err) return reject(err);
1358
- resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
1359
- };
1360
- asyncFn.apply(this, args);
1361
- });
1078
+ // The hash will be a non-standard UUID ... the UUID service uses this base class!
1079
+ this.UUID = "CORESVC-".concat(Math.floor(Math.random() * (99999 - 10000) + 10000));
1080
+ this.Hash = typeof pServiceHash === 'string' ? pServiceHash : "".concat(this.UUID);
1362
1081
  }
1363
- return awaitable;
1364
- }
1365
- module.exports = exports['default'];
1366
- }, {}],
1367
- 10: [function (require, module, exports) {
1368
- "use strict";
1369
-
1370
- Object.defineProperty(exports, "__esModule", {
1371
- value: true
1372
- });
1373
- // A temporary value used to identify if the loop should be broken.
1374
- // See #1064, #1293
1375
- const breakLoop = {};
1376
- exports.default = breakLoop;
1377
- module.exports = exports["default"];
1378
- }, {}],
1379
- 11: [function (require, module, exports) {
1380
- 'use strict';
1381
-
1382
- Object.defineProperty(exports, "__esModule", {
1383
- value: true
1384
- });
1385
- var _once = require('./once.js');
1386
- var _once2 = _interopRequireDefault(_once);
1387
- var _iterator = require('./iterator.js');
1388
- var _iterator2 = _interopRequireDefault(_iterator);
1389
- var _onlyOnce = require('./onlyOnce.js');
1390
- var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
1391
- var _wrapAsync = require('./wrapAsync.js');
1392
- var _asyncEachOfLimit = require('./asyncEachOfLimit.js');
1393
- var _asyncEachOfLimit2 = _interopRequireDefault(_asyncEachOfLimit);
1394
- var _breakLoop = require('./breakLoop.js');
1395
- var _breakLoop2 = _interopRequireDefault(_breakLoop);
1396
- function _interopRequireDefault(obj) {
1397
- return obj && obj.__esModule ? obj : {
1398
- default: obj
1399
- };
1400
- }
1401
- exports.default = limit => {
1402
- return (obj, iteratee, callback) => {
1403
- callback = (0, _once2.default)(callback);
1404
- if (limit <= 0) {
1405
- throw new RangeError('concurrency limit cannot be less than 1');
1406
- }
1407
- if (!obj) {
1408
- return callback(null);
1409
- }
1410
- if ((0, _wrapAsync.isAsyncGenerator)(obj)) {
1411
- return (0, _asyncEachOfLimit2.default)(obj, limit, iteratee, callback);
1412
- }
1413
- if ((0, _wrapAsync.isAsyncIterable)(obj)) {
1414
- return (0, _asyncEachOfLimit2.default)(obj[Symbol.asyncIterator](), limit, iteratee, callback);
1415
- }
1416
- var nextElem = (0, _iterator2.default)(obj);
1417
- var done = false;
1418
- var canceled = false;
1419
- var running = 0;
1420
- var looping = false;
1421
- function iterateeCallback(err, value) {
1422
- if (canceled) return;
1423
- running -= 1;
1424
- if (err) {
1425
- done = true;
1426
- callback(err);
1427
- } else if (err === false) {
1428
- done = true;
1429
- canceled = true;
1430
- } else if (value === _breakLoop2.default || done && running <= 0) {
1431
- done = true;
1432
- return callback(null);
1433
- } else if (!looping) {
1434
- replenish();
1435
- }
1436
- }
1437
- function replenish() {
1438
- looping = true;
1439
- while (running < limit && !done) {
1440
- var elem = nextElem();
1441
- if (elem === null) {
1442
- done = true;
1443
- if (running <= 0) {
1444
- callback(null);
1445
- }
1446
- return;
1447
- }
1448
- running += 1;
1449
- iteratee(elem.value, elem.key, (0, _onlyOnce2.default)(iterateeCallback));
1450
- }
1451
- looping = false;
1452
- }
1453
- replenish();
1454
- };
1455
- };
1456
- module.exports = exports['default'];
1457
- }, {
1458
- "./asyncEachOfLimit.js": 8,
1459
- "./breakLoop.js": 10,
1460
- "./iterator.js": 15,
1461
- "./once.js": 16,
1462
- "./onlyOnce.js": 17,
1463
- "./wrapAsync.js": 19
1464
- }],
1465
- 12: [function (require, module, exports) {
1466
- "use strict";
1467
-
1468
- Object.defineProperty(exports, "__esModule", {
1469
- value: true
1470
- });
1471
- exports.default = function (coll) {
1472
- return coll[Symbol.iterator] && coll[Symbol.iterator]();
1473
- };
1474
- module.exports = exports["default"];
1475
- }, {}],
1476
- 13: [function (require, module, exports) {
1477
- "use strict";
1478
-
1479
- Object.defineProperty(exports, "__esModule", {
1480
- value: true
1481
- });
1482
- exports.default = function (fn) {
1483
- return function (...args /*, callback*/) {
1484
- var callback = args.pop();
1485
- return fn.call(this, args, callback);
1486
- };
1487
- };
1488
- module.exports = exports["default"];
1489
- }, {}],
1490
- 14: [function (require, module, exports) {
1491
- 'use strict';
1492
-
1493
- Object.defineProperty(exports, "__esModule", {
1494
- value: true
1495
- });
1496
- exports.default = isArrayLike;
1497
- function isArrayLike(value) {
1498
- return value && typeof value.length === 'number' && value.length >= 0 && value.length % 1 === 0;
1499
- }
1500
- module.exports = exports['default'];
1501
- }, {}],
1502
- 15: [function (require, module, exports) {
1503
- 'use strict';
1504
-
1505
- Object.defineProperty(exports, "__esModule", {
1506
- value: true
1507
- });
1508
- exports.default = createIterator;
1509
- var _isArrayLike = require('./isArrayLike.js');
1510
- var _isArrayLike2 = _interopRequireDefault(_isArrayLike);
1511
- var _getIterator = require('./getIterator.js');
1512
- var _getIterator2 = _interopRequireDefault(_getIterator);
1513
- function _interopRequireDefault(obj) {
1514
- return obj && obj.__esModule ? obj : {
1515
- default: obj
1516
- };
1517
- }
1518
- function createArrayIterator(coll) {
1519
- var i = -1;
1520
- var len = coll.length;
1521
- return function next() {
1522
- return ++i < len ? {
1523
- value: coll[i],
1524
- key: i
1525
- } : null;
1526
- };
1527
- }
1528
- function createES2015Iterator(iterator) {
1529
- var i = -1;
1530
- return function next() {
1531
- var item = iterator.next();
1532
- if (item.done) return null;
1533
- i++;
1534
- return {
1535
- value: item.value,
1536
- key: i
1537
- };
1538
- };
1539
- }
1540
- function createObjectIterator(obj) {
1541
- var okeys = obj ? Object.keys(obj) : [];
1542
- var i = -1;
1543
- var len = okeys.length;
1544
- return function next() {
1545
- var key = okeys[++i];
1546
- if (key === '__proto__') {
1547
- return next();
1548
- }
1549
- return i < len ? {
1550
- value: obj[key],
1551
- key
1552
- } : null;
1553
- };
1554
- }
1555
- function createIterator(coll) {
1556
- if ((0, _isArrayLike2.default)(coll)) {
1557
- return createArrayIterator(coll);
1082
+ // After fable is initialized, it would be expected to be wired in as a normal service.
1083
+ connectFable(pFable) {
1084
+ this.fable = pFable;
1085
+ return true;
1558
1086
  }
1559
- var iterator = (0, _getIterator2.default)(coll);
1560
- return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);
1561
- }
1562
- module.exports = exports['default'];
1563
- }, {
1564
- "./getIterator.js": 12,
1565
- "./isArrayLike.js": 14
1566
- }],
1567
- 16: [function (require, module, exports) {
1568
- "use strict";
1569
-
1570
- Object.defineProperty(exports, "__esModule", {
1571
- value: true
1572
- });
1573
- exports.default = once;
1574
- function once(fn) {
1575
- function wrapper(...args) {
1576
- if (fn === null) return;
1577
- var callFn = fn;
1578
- fn = null;
1579
- callFn.apply(this, args);
1580
- }
1581
- Object.assign(wrapper, fn);
1582
- return wrapper;
1583
- }
1584
- module.exports = exports["default"];
1585
- }, {}],
1586
- 17: [function (require, module, exports) {
1587
- "use strict";
1588
-
1589
- Object.defineProperty(exports, "__esModule", {
1590
- value: true
1591
- });
1592
- exports.default = onlyOnce;
1593
- function onlyOnce(fn) {
1594
- return function (...args) {
1595
- if (fn === null) throw new Error("Callback was already called.");
1596
- var callFn = fn;
1597
- fn = null;
1598
- callFn.apply(this, args);
1599
- };
1600
1087
  }
1601
- module.exports = exports["default"];
1088
+ _defineProperty(FableCoreServiceProviderBase, "isFableService", true);
1089
+ module.exports = FableCoreServiceProviderBase;
1602
1090
  }, {}],
1603
- 18: [function (require, module, exports) {
1604
- (function (process, setImmediate) {
1605
- (function () {
1606
- 'use strict';
1091
+ 6: [function (require, module, exports) {
1092
+ /**
1093
+ * Fable Service Base
1094
+ * @author <steven@velozo.com>
1095
+ */
1607
1096
 
1608
- Object.defineProperty(exports, "__esModule", {
1609
- value: true
1610
- });
1611
- exports.fallback = fallback;
1612
- exports.wrap = wrap;
1613
- /* istanbul ignore file */
1614
-
1615
- var hasQueueMicrotask = exports.hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask;
1616
- var hasSetImmediate = exports.hasSetImmediate = typeof setImmediate === 'function' && setImmediate;
1617
- var hasNextTick = exports.hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';
1618
- function fallback(fn) {
1619
- setTimeout(fn, 0);
1620
- }
1621
- function wrap(defer) {
1622
- return (fn, ...args) => defer(() => fn(...args));
1623
- }
1624
- var _defer;
1625
- if (hasQueueMicrotask) {
1626
- _defer = queueMicrotask;
1627
- } else if (hasSetImmediate) {
1628
- _defer = setImmediate;
1629
- } else if (hasNextTick) {
1630
- _defer = process.nextTick;
1097
+ class FableServiceProviderBase {
1098
+ constructor(pFable, pOptions, pServiceHash) {
1099
+ this.fable = pFable;
1100
+ this.options = typeof pOptions === 'object' ? pOptions : typeof pFable === 'object' && !pFable.isFable ? pFable : {};
1101
+ this.serviceType = 'Unknown';
1102
+ if (typeof pFable.getUUID == 'function') {
1103
+ this.UUID = pFable.getUUID();
1631
1104
  } else {
1632
- _defer = fallback;
1105
+ this.UUID = "NoFABLESVC-".concat(Math.floor(Math.random() * (99999 - 10000) + 10000));
1633
1106
  }
1634
- exports.default = wrap(_defer);
1635
- }).call(this);
1636
- }).call(this, require('_process'), require("timers").setImmediate);
1637
- }, {
1638
- "_process": 37,
1639
- "timers": 44
1640
- }],
1641
- 19: [function (require, module, exports) {
1642
- 'use strict';
1643
-
1644
- Object.defineProperty(exports, "__esModule", {
1645
- value: true
1646
- });
1647
- exports.isAsyncIterable = exports.isAsyncGenerator = exports.isAsync = undefined;
1648
- var _asyncify = require('../asyncify.js');
1649
- var _asyncify2 = _interopRequireDefault(_asyncify);
1650
- function _interopRequireDefault(obj) {
1651
- return obj && obj.__esModule ? obj : {
1652
- default: obj
1653
- };
1654
- }
1655
- function isAsync(fn) {
1656
- return fn[Symbol.toStringTag] === 'AsyncFunction';
1657
- }
1658
- function isAsyncGenerator(fn) {
1659
- return fn[Symbol.toStringTag] === 'AsyncGenerator';
1660
- }
1661
- function isAsyncIterable(obj) {
1662
- return typeof obj[Symbol.asyncIterator] === 'function';
1663
- }
1664
- function wrapAsync(asyncFn) {
1665
- if (typeof asyncFn !== 'function') throw new Error('expected a function');
1666
- return isAsync(asyncFn) ? (0, _asyncify2.default)(asyncFn) : asyncFn;
1667
- }
1668
- exports.default = wrapAsync;
1669
- exports.isAsync = isAsync;
1670
- exports.isAsyncGenerator = isAsyncGenerator;
1671
- exports.isAsyncIterable = isAsyncIterable;
1672
- }, {
1673
- "../asyncify.js": 5
1674
- }],
1675
- 20: [function (require, module, exports) {
1676
- 'use strict';
1677
-
1678
- Object.defineProperty(exports, "__esModule", {
1679
- value: true
1680
- });
1681
- var _once = require('./internal/once.js');
1682
- var _once2 = _interopRequireDefault(_once);
1683
- var _onlyOnce = require('./internal/onlyOnce.js');
1684
- var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
1685
- var _wrapAsync = require('./internal/wrapAsync.js');
1686
- var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
1687
- var _awaitify = require('./internal/awaitify.js');
1688
- var _awaitify2 = _interopRequireDefault(_awaitify);
1689
- function _interopRequireDefault(obj) {
1690
- return obj && obj.__esModule ? obj : {
1691
- default: obj
1692
- };
1693
- }
1107
+ this.Hash = typeof pServiceHash === 'string' ? pServiceHash : "".concat(this.UUID);
1694
1108
 
1695
- /**
1696
- * Runs the `tasks` array of functions in series, each passing their results to
1697
- * the next in the array. However, if any of the `tasks` pass an error to their
1698
- * own callback, the next function is not executed, and the main `callback` is
1699
- * immediately called with the error.
1700
- *
1701
- * @name waterfall
1702
- * @static
1703
- * @memberOf module:ControlFlow
1704
- * @method
1705
- * @category Control Flow
1706
- * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}
1707
- * to run.
1708
- * Each function should complete with any number of `result` values.
1709
- * The `result` values will be passed as arguments, in order, to the next task.
1710
- * @param {Function} [callback] - An optional callback to run once all the
1711
- * functions have completed. This will be passed the results of the last task's
1712
- * callback. Invoked with (err, [results]).
1713
- * @returns {Promise} a promise, if a callback is omitted
1714
- * @example
1715
- *
1716
- * async.waterfall([
1717
- * function(callback) {
1718
- * callback(null, 'one', 'two');
1719
- * },
1720
- * function(arg1, arg2, callback) {
1721
- * // arg1 now equals 'one' and arg2 now equals 'two'
1722
- * callback(null, 'three');
1723
- * },
1724
- * function(arg1, callback) {
1725
- * // arg1 now equals 'three'
1726
- * callback(null, 'done');
1727
- * }
1728
- * ], function (err, result) {
1729
- * // result now equals 'done'
1730
- * });
1731
- *
1732
- * // Or, with named functions:
1733
- * async.waterfall([
1734
- * myFirstFunction,
1735
- * mySecondFunction,
1736
- * myLastFunction,
1737
- * ], function (err, result) {
1738
- * // result now equals 'done'
1739
- * });
1740
- * function myFirstFunction(callback) {
1741
- * callback(null, 'one', 'two');
1742
- * }
1743
- * function mySecondFunction(arg1, arg2, callback) {
1744
- * // arg1 now equals 'one' and arg2 now equals 'two'
1745
- * callback(null, 'three');
1746
- * }
1747
- * function myLastFunction(arg1, callback) {
1748
- * // arg1 now equals 'three'
1749
- * callback(null, 'done');
1750
- * }
1751
- */
1752
- function waterfall(tasks, callback) {
1753
- callback = (0, _once2.default)(callback);
1754
- if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));
1755
- if (!tasks.length) return callback();
1756
- var taskIndex = 0;
1757
- function nextTask(args) {
1758
- var task = (0, _wrapAsync2.default)(tasks[taskIndex++]);
1759
- task(...args, (0, _onlyOnce2.default)(next));
1760
- }
1761
- function next(err, ...args) {
1762
- if (err === false) return;
1763
- if (err || taskIndex === tasks.length) {
1764
- return callback(err, ...args);
1765
- }
1766
- nextTask(args);
1767
- }
1768
- nextTask([]);
1109
+ // Pull back a few things
1110
+ this.log = this.fable.log;
1111
+ this.servicesMap = this.fable.servicesMap;
1112
+ this.services = this.fable.services;
1113
+ }
1769
1114
  }
1770
- exports.default = (0, _awaitify2.default)(waterfall);
1771
- module.exports = exports['default'];
1115
+ _defineProperty(FableServiceProviderBase, "isFableService", true);
1116
+ module.exports = FableServiceProviderBase;
1117
+ module.exports.CoreServiceProviderBase = require('./Fable-ServiceProviderBase-Preinit.js');
1772
1118
  }, {
1773
- "./internal/awaitify.js": 9,
1774
- "./internal/once.js": 16,
1775
- "./internal/onlyOnce.js": 17,
1776
- "./internal/wrapAsync.js": 19
1119
+ "./Fable-ServiceProviderBase-Preinit.js": 5
1777
1120
  }],
1778
- 21: [function (require, module, exports) {
1121
+ 7: [function (require, module, exports) {
1779
1122
  'use strict';
1780
1123
 
1781
1124
  var UTF8_ACCEPT = 12;
@@ -1851,7 +1194,7 @@
1851
1194
  }
1852
1195
  module.exports = decodeURIComponent;
1853
1196
  }, {}],
1854
- 22: [function (require, module, exports) {
1197
+ 8: [function (require, module, exports) {
1855
1198
  'use strict';
1856
1199
 
1857
1200
  // do not edit .js files directly - edit src/index.jst
@@ -1884,7 +1227,7 @@
1884
1227
  return a !== a && b !== b;
1885
1228
  };
1886
1229
  }, {}],
1887
- 23: [function (require, module, exports) {
1230
+ 9: [function (require, module, exports) {
1888
1231
  "use strict";
1889
1232
 
1890
1233
  const parse = require("./parse");
@@ -1905,10 +1248,10 @@
1905
1248
  module.exports.parse = parse;
1906
1249
  module.exports.stringify = stringify;
1907
1250
  }, {
1908
- "./parse": 25,
1909
- "./stringify": 26
1251
+ "./parse": 11,
1252
+ "./stringify": 12
1910
1253
  }],
1911
- 24: [function (require, module, exports) {
1254
+ 10: [function (require, module, exports) {
1912
1255
  // This file is taken from Node.js project.
1913
1256
  // Full implementation can be found from https://github.com/nodejs/node/blob/main/lib/internal/querystring.js
1914
1257
 
@@ -1998,12 +1341,12 @@
1998
1341
  encodeString
1999
1342
  };
2000
1343
  }, {}],
2001
- 25: [function (require, module, exports) {
1344
+ 11: [function (require, module, exports) {
2002
1345
  "use strict";
2003
1346
 
2004
1347
  const fastDecode = require("fast-decode-uri-component");
2005
1348
  const plusRegex = /\+/g;
2006
- const Empty = function () {};
1349
+ const Empty = function Empty() {};
2007
1350
  Empty.prototype = Object.create(null);
2008
1351
 
2009
1352
  /**
@@ -2116,9 +1459,9 @@
2116
1459
  }
2117
1460
  module.exports = parse;
2118
1461
  }, {
2119
- "fast-decode-uri-component": 21
1462
+ "fast-decode-uri-component": 7
2120
1463
  }],
2121
- 26: [function (require, module, exports) {
1464
+ 12: [function (require, module, exports) {
2122
1465
  "use strict";
2123
1466
 
2124
1467
  const {
@@ -2181,318 +1524,9 @@
2181
1524
  }
2182
1525
  module.exports = stringify;
2183
1526
  }, {
2184
- "./internals/querystring": 24
1527
+ "./internals/querystring": 10
2185
1528
  }],
2186
- 27: [function (require, module, exports) {
2187
- 'use strict';
2188
-
2189
- const HandlerStorage = require('./handler_storage');
2190
- const NODE_TYPES = {
2191
- STATIC: 0,
2192
- PARAMETRIC: 1,
2193
- WILDCARD: 2
2194
- };
2195
- class Node {
2196
- constructor() {
2197
- this.handlerStorage = new HandlerStorage();
2198
- }
2199
- }
2200
- class ParentNode extends Node {
2201
- constructor() {
2202
- super();
2203
- this.staticChildren = {};
2204
- }
2205
- findStaticMatchingChild(path, pathIndex) {
2206
- const staticChild = this.staticChildren[path.charAt(pathIndex)];
2207
- if (staticChild === undefined || !staticChild.matchPrefix(path, pathIndex)) {
2208
- return null;
2209
- }
2210
- return staticChild;
2211
- }
2212
- createStaticChild(path) {
2213
- if (path.length === 0) {
2214
- return this;
2215
- }
2216
- let staticChild = this.staticChildren[path.charAt(0)];
2217
- if (staticChild) {
2218
- let i = 1;
2219
- for (; i < staticChild.prefix.length; i++) {
2220
- if (path.charCodeAt(i) !== staticChild.prefix.charCodeAt(i)) {
2221
- staticChild = staticChild.split(this, i);
2222
- break;
2223
- }
2224
- }
2225
- return staticChild.createStaticChild(path.slice(i));
2226
- }
2227
- const label = path.charAt(0);
2228
- this.staticChildren[label] = new StaticNode(path);
2229
- return this.staticChildren[label];
2230
- }
2231
- }
2232
- class StaticNode extends ParentNode {
2233
- constructor(prefix) {
2234
- super();
2235
- this.prefix = prefix;
2236
- this.wildcardChild = null;
2237
- this.parametricChildren = [];
2238
- this.kind = NODE_TYPES.STATIC;
2239
- this._compilePrefixMatch();
2240
- }
2241
- createParametricChild(regex, staticSuffix) {
2242
- const regexpSource = regex && regex.source;
2243
- let parametricChild = this.parametricChildren.find(child => {
2244
- const childRegexSource = child.regex && child.regex.source;
2245
- return childRegexSource === regexpSource;
2246
- });
2247
- if (parametricChild) {
2248
- return parametricChild;
2249
- }
2250
- parametricChild = new ParametricNode(regex, staticSuffix);
2251
- this.parametricChildren.push(parametricChild);
2252
- this.parametricChildren.sort((child1, child2) => {
2253
- if (!child1.isRegex) return 1;
2254
- if (!child2.isRegex) return -1;
2255
- if (child1.staticSuffix === null) return 1;
2256
- if (child2.staticSuffix === null) return -1;
2257
- if (child2.staticSuffix.endsWith(child1.staticSuffix)) return 1;
2258
- if (child1.staticSuffix.endsWith(child2.staticSuffix)) return -1;
2259
- return 0;
2260
- });
2261
- return parametricChild;
2262
- }
2263
- createWildcardChild() {
2264
- if (this.wildcardChild) {
2265
- return this.wildcardChild;
2266
- }
2267
- this.wildcardChild = new WildcardNode();
2268
- return this.wildcardChild;
2269
- }
2270
- split(parentNode, length) {
2271
- const parentPrefix = this.prefix.slice(0, length);
2272
- const childPrefix = this.prefix.slice(length);
2273
- this.prefix = childPrefix;
2274
- this._compilePrefixMatch();
2275
- const staticNode = new StaticNode(parentPrefix);
2276
- staticNode.staticChildren[childPrefix.charAt(0)] = this;
2277
- parentNode.staticChildren[parentPrefix.charAt(0)] = staticNode;
2278
- return staticNode;
2279
- }
2280
- getNextNode(path, pathIndex, nodeStack, paramsCount) {
2281
- let node = this.findStaticMatchingChild(path, pathIndex);
2282
- let parametricBrotherNodeIndex = 0;
2283
- if (node === null) {
2284
- if (this.parametricChildren.length === 0) {
2285
- return this.wildcardChild;
2286
- }
2287
- node = this.parametricChildren[0];
2288
- parametricBrotherNodeIndex = 1;
2289
- }
2290
- if (this.wildcardChild !== null) {
2291
- nodeStack.push({
2292
- paramsCount,
2293
- brotherPathIndex: pathIndex,
2294
- brotherNode: this.wildcardChild
2295
- });
2296
- }
2297
- for (let i = this.parametricChildren.length - 1; i >= parametricBrotherNodeIndex; i--) {
2298
- nodeStack.push({
2299
- paramsCount,
2300
- brotherPathIndex: pathIndex,
2301
- brotherNode: this.parametricChildren[i]
2302
- });
2303
- }
2304
- return node;
2305
- }
2306
- _compilePrefixMatch() {
2307
- if (this.prefix.length === 1) {
2308
- this.matchPrefix = () => true;
2309
- return;
2310
- }
2311
- const lines = [];
2312
- for (let i = 1; i < this.prefix.length; i++) {
2313
- const charCode = this.prefix.charCodeAt(i);
2314
- lines.push(`path.charCodeAt(i + ${i}) === ${charCode}`);
2315
- }
2316
- this.matchPrefix = new Function('path', 'i', `return ${lines.join(' && ')}`); // eslint-disable-line
2317
- }
2318
- }
2319
-
2320
- class ParametricNode extends ParentNode {
2321
- constructor(regex, staticSuffix) {
2322
- super();
2323
- this.isRegex = !!regex;
2324
- this.regex = regex || null;
2325
- this.staticSuffix = staticSuffix || null;
2326
- this.kind = NODE_TYPES.PARAMETRIC;
2327
- }
2328
- getNextNode(path, pathIndex) {
2329
- return this.findStaticMatchingChild(path, pathIndex);
2330
- }
2331
- }
2332
- class WildcardNode extends Node {
2333
- constructor() {
2334
- super();
2335
- this.kind = NODE_TYPES.WILDCARD;
2336
- }
2337
- getNextNode() {
2338
- return null;
2339
- }
2340
- }
2341
- module.exports = {
2342
- StaticNode,
2343
- ParametricNode,
2344
- WildcardNode,
2345
- NODE_TYPES
2346
- };
2347
- }, {
2348
- "./handler_storage": 28
2349
- }],
2350
- 28: [function (require, module, exports) {
2351
- 'use strict';
2352
-
2353
- class HandlerStorage {
2354
- constructor() {
2355
- this.unconstrainedHandler = null; // optimized reference to the handler that will match most of the time
2356
- this.constraints = [];
2357
- this.handlers = []; // unoptimized list of handler objects for which the fast matcher function will be compiled
2358
- this.constrainedHandlerStores = null;
2359
- }
2360
-
2361
- // This is the hot path for node handler finding -- change with care!
2362
- getMatchingHandler(derivedConstraints) {
2363
- if (derivedConstraints === undefined) {
2364
- return this.unconstrainedHandler;
2365
- }
2366
- return this._getHandlerMatchingConstraints(derivedConstraints);
2367
- }
2368
- addHandler(handler, params, store, constrainer, constraints) {
2369
- const handlerObject = {
2370
- handler,
2371
- params,
2372
- constraints,
2373
- store: store || null,
2374
- _createParamsObject: this._compileCreateParamsObject(params)
2375
- };
2376
- if (Object.keys(constraints).length === 0) {
2377
- this.unconstrainedHandler = handlerObject;
2378
- }
2379
- for (const constraint of Object.keys(constraints)) {
2380
- if (!this.constraints.includes(constraint)) {
2381
- if (constraint === 'version') {
2382
- // always check the version constraint first as it is the most selective
2383
- this.constraints.unshift(constraint);
2384
- } else {
2385
- this.constraints.push(constraint);
2386
- }
2387
- }
2388
- }
2389
- if (this.handlers.length >= 32) {
2390
- throw new Error('find-my-way supports a maximum of 32 route handlers per node when there are constraints, limit reached');
2391
- }
2392
- this.handlers.push(handlerObject);
2393
- // Sort the most constrained handlers to the front of the list of handlers so they are tested first.
2394
- this.handlers.sort((a, b) => Object.keys(a.constraints).length - Object.keys(b.constraints).length);
2395
- this._compileGetHandlerMatchingConstraints(constrainer, constraints);
2396
- }
2397
- _compileCreateParamsObject(params) {
2398
- const lines = [];
2399
- for (let i = 0; i < params.length; i++) {
2400
- lines.push(`'${params[i]}': paramsArray[${i}]`);
2401
- }
2402
- return new Function('paramsArray', `return {${lines.join(',')}}`); // eslint-disable-line
2403
- }
2404
-
2405
- _getHandlerMatchingConstraints() {
2406
- return null;
2407
- }
2408
-
2409
- // Builds a store object that maps from constraint values to a bitmap of handler indexes which pass the constraint for a value
2410
- // So for a host constraint, this might look like { "fastify.io": 0b0010, "google.ca": 0b0101 }, meaning the 3rd handler is constrainted to fastify.io, and the 2nd and 4th handlers are constrained to google.ca.
2411
- // The store's implementation comes from the strategies provided to the Router.
2412
- _buildConstraintStore(store, constraint) {
2413
- for (let i = 0; i < this.handlers.length; i++) {
2414
- const handler = this.handlers[i];
2415
- const constraintValue = handler.constraints[constraint];
2416
- if (constraintValue !== undefined) {
2417
- let indexes = store.get(constraintValue) || 0;
2418
- indexes |= 1 << i; // set the i-th bit for the mask because this handler is constrained by this value https://stackoverflow.com/questions/1436438/how-do-you-set-clear-and-toggle-a-single-bit-in-javascrip
2419
- store.set(constraintValue, indexes);
2420
- }
2421
- }
2422
- }
2423
-
2424
- // Builds a bitmask for a given constraint that has a bit for each handler index that is 0 when that handler *is* constrained and 1 when the handler *isnt* constrainted. This is opposite to what might be obvious, but is just for convienience when doing the bitwise operations.
2425
- _constrainedIndexBitmask(constraint) {
2426
- let mask = 0;
2427
- for (let i = 0; i < this.handlers.length; i++) {
2428
- const handler = this.handlers[i];
2429
- const constraintValue = handler.constraints[constraint];
2430
- if (constraintValue !== undefined) {
2431
- mask |= 1 << i;
2432
- }
2433
- }
2434
- return ~mask;
2435
- }
2436
-
2437
- // Compile a fast function to match the handlers for this node
2438
- // The function implements a general case multi-constraint matching algorithm.
2439
- // The general idea is this: we have a bunch of handlers, each with a potentially different set of constraints, and sometimes none at all. We're given a list of constraint values and we have to use the constraint-value-comparison strategies to see which handlers match the constraint values passed in.
2440
- // We do this by asking each constraint store which handler indexes match the given constraint value for each store. Trickily, the handlers that a store says match are the handlers constrained by that store, but handlers that aren't constrained at all by that store could still match just fine. So, each constraint store can only describe matches for it, and it won't have any bearing on the handlers it doesn't care about. For this reason, we have to ask each stores which handlers match and track which have been matched (or not cared about) by all of them.
2441
- // We use bitmaps to represent these lists of matches so we can use bitwise operations to implement this efficiently. Bitmaps are cheap to allocate, let us implement this masking behaviour in one CPU instruction, and are quite compact in memory. We start with a bitmap set to all 1s representing every handler that is a match candidate, and then for each constraint, see which handlers match using the store, and then mask the result by the mask of handlers that that store applies to, and bitwise AND with the candidate list. Phew.
2442
- // We consider all this compiling function complexity to be worth it, because the naive implementation that just loops over the handlers asking which stores match is quite a bit slower.
2443
- _compileGetHandlerMatchingConstraints(constrainer) {
2444
- this.constrainedHandlerStores = {};
2445
- for (const constraint of this.constraints) {
2446
- const store = constrainer.newStoreForConstraint(constraint);
2447
- this.constrainedHandlerStores[constraint] = store;
2448
- this._buildConstraintStore(store, constraint);
2449
- }
2450
- const lines = [];
2451
- lines.push(`
2452
- let candidates = ${(1 << this.handlers.length) - 1}
2453
- let mask, matches
2454
- `);
2455
- for (const constraint of this.constraints) {
2456
- // Setup the mask for indexes this constraint applies to. The mask bits are set to 1 for each position if the constraint applies.
2457
- lines.push(`
2458
- mask = ${this._constrainedIndexBitmask(constraint)}
2459
- value = derivedConstraints.${constraint}
2460
- `);
2461
-
2462
- // If there's no constraint value, none of the handlers constrained by this constraint can match. Remove them from the candidates.
2463
- // If there is a constraint value, get the matching indexes bitmap from the store, and mask it down to only the indexes this constraint applies to, and then bitwise and with the candidates list to leave only matching candidates left.
2464
- const strategy = constrainer.strategies[constraint];
2465
- const matchMask = strategy.mustMatchWhenDerived ? 'matches' : '(matches | mask)';
2466
- lines.push(`
2467
- if (value === undefined) {
2468
- candidates &= mask
2469
- } else {
2470
- matches = this.constrainedHandlerStores.${constraint}.get(value) || 0
2471
- candidates &= ${matchMask}
2472
- }
2473
- if (candidates === 0) return null;
2474
- `);
2475
- }
2476
-
2477
- // There are some constraints that can be derived and marked as "must match", where if they are derived, they only match routes that actually have a constraint on the value, like the SemVer version constraint.
2478
- // An example: a request comes in for version 1.x, and this node has a handler that matches the path, but there's no version constraint. For SemVer, the find-my-way semantics do not match this handler to that request.
2479
- // This function is used by Nodes with handlers to match when they don't have any constrained routes to exclude request that do have must match derived constraints present.
2480
- for (const constraint in constrainer.strategies) {
2481
- const strategy = constrainer.strategies[constraint];
2482
- if (strategy.mustMatchWhenDerived && !this.constraints.includes(constraint)) {
2483
- lines.push(`if (derivedConstraints.${constraint} !== undefined) return null`);
2484
- }
2485
- }
2486
-
2487
- // Return the first handler who's bit is set in the candidates https://stackoverflow.com/questions/18134985/how-to-find-index-of-first-set-bit
2488
- lines.push('return this.handlers[Math.floor(Math.log2(candidates))]');
2489
- this._getHandlerMatchingConstraints = new Function('derivedConstraints', lines.join('\n')); // eslint-disable-line
2490
- }
2491
- }
2492
-
2493
- module.exports = HandlerStorage;
2494
- }, {}],
2495
- 29: [function (require, module, exports) {
1529
+ 13: [function (require, module, exports) {
2496
1530
  'use strict';
2497
1531
 
2498
1532
  /*
@@ -2524,17 +1558,15 @@
2524
1558
  const isRegexSafe = require('safe-regex2');
2525
1559
  const deepEqual = require('fast-deep-equal');
2526
1560
  const {
2527
- flattenNode,
2528
- compressFlattenedNode,
2529
- prettyPrintFlattenedNode,
2530
- prettyPrintRoutesArray
1561
+ prettyPrintTree
2531
1562
  } = require('./lib/pretty-print');
2532
1563
  const {
2533
1564
  StaticNode,
2534
1565
  NODE_TYPES
2535
- } = require('./custom_node');
1566
+ } = require('./lib/node');
2536
1567
  const Constrainer = require('./lib/constrainer');
2537
1568
  const httpMethods = require('./lib/http-methods');
1569
+ const httpMethodStrategy = require('./lib/strategies/http-method');
2538
1570
  const {
2539
1571
  safeDecodeURI,
2540
1572
  safeDecodeURIComponent
@@ -2552,6 +1584,7 @@
2552
1584
  return new Router(opts);
2553
1585
  }
2554
1586
  opts = opts || {};
1587
+ this._opts = opts;
2555
1588
  if (opts.defaultRoute) {
2556
1589
  assert(typeof opts.defaultRoute === 'function', 'The default route must be a function');
2557
1590
  this.defaultRoute = opts.defaultRoute;
@@ -2581,10 +1614,9 @@
2581
1614
  this.ignoreDuplicateSlashes = opts.ignoreDuplicateSlashes || false;
2582
1615
  this.maxParamLength = opts.maxParamLength || 100;
2583
1616
  this.allowUnsafeRegex = opts.allowUnsafeRegex || false;
1617
+ this.constrainer = new Constrainer(opts.constraints);
2584
1618
  this.routes = [];
2585
1619
  this.trees = {};
2586
- this.constrainer = new Constrainer(opts.constraints);
2587
- this._routesPatterns = {};
2588
1620
  }
2589
1621
  Router.prototype.on = function on(method, path, opts, handler, store) {
2590
1622
  if (typeof opts === 'function') {
@@ -2620,19 +1652,12 @@
2620
1652
  }
2621
1653
  const methods = Array.isArray(method) ? method : [method];
2622
1654
  for (const method of methods) {
1655
+ assert(typeof method === 'string', 'Method should be a string');
1656
+ assert(httpMethods.includes(method), "Method '".concat(method, "' is not an http method."));
2623
1657
  this._on(method, path, opts, handler, store, route);
2624
- this.routes.push({
2625
- method,
2626
- path,
2627
- opts,
2628
- handler,
2629
- store
2630
- });
2631
1658
  }
2632
1659
  };
2633
1660
  Router.prototype._on = function _on(method, path, opts, handler, store) {
2634
- assert(typeof method === 'string', 'Method should be a string');
2635
- assert(httpMethods.includes(method), `Method '${method}' is not an http method.`);
2636
1661
  let constraints = {};
2637
1662
  if (opts.constraints !== undefined) {
2638
1663
  assert(typeof opts.constraints === 'object' && opts.constraints !== null, 'Constraints should be an object');
@@ -2647,9 +1672,9 @@
2647
1672
  // Boot the tree for this method if it doesn't exist yet
2648
1673
  if (this.trees[method] === undefined) {
2649
1674
  this.trees[method] = new StaticNode('/');
2650
- this._routesPatterns[method] = [];
2651
1675
  }
2652
- if (path === '*' && this.trees[method].prefix.length !== 0) {
1676
+ let pattern = path;
1677
+ if (pattern === '*' && this.trees[method].prefix.length !== 0) {
2653
1678
  const currentRoot = this.trees[method];
2654
1679
  this.trees[method] = new StaticNode('');
2655
1680
  this.trees[method].staticChildren['/'] = currentRoot;
@@ -2657,16 +1682,16 @@
2657
1682
  let currentNode = this.trees[method];
2658
1683
  let parentNodePathIndex = currentNode.prefix.length;
2659
1684
  const params = [];
2660
- for (let i = 0; i <= path.length; i++) {
2661
- if (path.charCodeAt(i) === 58 && path.charCodeAt(i + 1) === 58) {
1685
+ for (let i = 0; i <= pattern.length; i++) {
1686
+ if (pattern.charCodeAt(i) === 58 && pattern.charCodeAt(i + 1) === 58) {
2662
1687
  // It's a double colon
2663
1688
  i++;
2664
1689
  continue;
2665
1690
  }
2666
- const isParametricNode = path.charCodeAt(i) === 58 && path.charCodeAt(i + 1) !== 58;
2667
- const isWildcardNode = path.charCodeAt(i) === 42;
2668
- if (isParametricNode || isWildcardNode || i === path.length && i !== parentNodePathIndex) {
2669
- let staticNodePath = path.slice(parentNodePathIndex, i);
1691
+ const isParametricNode = pattern.charCodeAt(i) === 58 && pattern.charCodeAt(i + 1) !== 58;
1692
+ const isWildcardNode = pattern.charCodeAt(i) === 42;
1693
+ if (isParametricNode || isWildcardNode || i === pattern.length && i !== parentNodePathIndex) {
1694
+ let staticNodePath = pattern.slice(parentNodePathIndex, i);
2670
1695
  if (!this.caseSensitive) {
2671
1696
  staticNodePath = staticNodePath.toLowerCase();
2672
1697
  }
@@ -2680,19 +1705,19 @@
2680
1705
  const regexps = [];
2681
1706
  let lastParamStartIndex = i + 1;
2682
1707
  for (let j = lastParamStartIndex;; j++) {
2683
- const charCode = path.charCodeAt(j);
1708
+ const charCode = pattern.charCodeAt(j);
2684
1709
  const isRegexParam = charCode === 40;
2685
1710
  const isStaticPart = charCode === 45 || charCode === 46;
2686
- const isEndOfNode = charCode === 47 || j === path.length;
1711
+ const isEndOfNode = charCode === 47 || j === pattern.length;
2687
1712
  if (isRegexParam || isStaticPart || isEndOfNode) {
2688
- const paramName = path.slice(lastParamStartIndex, j);
1713
+ const paramName = pattern.slice(lastParamStartIndex, j);
2689
1714
  params.push(paramName);
2690
1715
  isRegexNode = isRegexNode || isRegexParam || isStaticPart;
2691
1716
  if (isRegexParam) {
2692
- const endOfRegexIndex = getClosingParenthensePosition(path, j);
2693
- const regexString = path.slice(j, endOfRegexIndex + 1);
1717
+ const endOfRegexIndex = getClosingParenthensePosition(pattern, j);
1718
+ const regexString = pattern.slice(j, endOfRegexIndex + 1);
2694
1719
  if (!this.allowUnsafeRegex) {
2695
- assert(isRegexSafe(new RegExp(regexString)), `The regex '${regexString}' is not safe!`);
1720
+ assert(isRegexSafe(new RegExp(regexString)), "The regex '".concat(regexString, "' is not safe!"));
2696
1721
  }
2697
1722
  regexps.push(trimRegExpStartAndEnd(regexString));
2698
1723
  j = endOfRegexIndex + 1;
@@ -2700,27 +1725,28 @@
2700
1725
  regexps.push('(.*?)');
2701
1726
  }
2702
1727
  const staticPartStartIndex = j;
2703
- for (; j < path.length; j++) {
2704
- const charCode = path.charCodeAt(j);
1728
+ for (; j < pattern.length; j++) {
1729
+ const charCode = pattern.charCodeAt(j);
2705
1730
  if (charCode === 47) break;
2706
1731
  if (charCode === 58) {
2707
- const nextCharCode = path.charCodeAt(j + 1);
1732
+ const nextCharCode = pattern.charCodeAt(j + 1);
2708
1733
  if (nextCharCode === 58) j++;else break;
2709
1734
  }
2710
1735
  }
2711
- let staticPart = path.slice(staticPartStartIndex, j);
1736
+ let staticPart = pattern.slice(staticPartStartIndex, j);
2712
1737
  if (staticPart) {
2713
1738
  staticPart = staticPart.split('::').join(':');
2714
1739
  staticPart = staticPart.split('%').join('%25');
2715
1740
  regexps.push(escapeRegExp(staticPart));
2716
1741
  }
2717
1742
  lastParamStartIndex = j + 1;
2718
- if (isEndOfNode || path.charCodeAt(j) === 47 || j === path.length) {
1743
+ if (isEndOfNode || pattern.charCodeAt(j) === 47 || j === pattern.length) {
2719
1744
  const nodePattern = isRegexNode ? '()' + staticPart : staticPart;
2720
- path = path.slice(0, i + 1) + nodePattern + path.slice(j);
1745
+ const nodePath = pattern.slice(i, j);
1746
+ pattern = pattern.slice(0, i + 1) + nodePattern + pattern.slice(j);
2721
1747
  i += nodePattern.length;
2722
1748
  const regex = isRegexNode ? new RegExp('^' + regexps.join('') + '$') : null;
2723
- currentNode = currentNode.createParametricChild(regex, staticPart || null);
1749
+ currentNode = currentNode.createParametricChild(regex, staticPart || null, nodePath);
2724
1750
  parentNodePathIndex = i + 1;
2725
1751
  break;
2726
1752
  }
@@ -2731,28 +1757,34 @@
2731
1757
  params.push('*');
2732
1758
  currentNode = currentNode.createWildcardChild();
2733
1759
  parentNodePathIndex = i + 1;
2734
- if (i !== path.length - 1) {
1760
+ if (i !== pattern.length - 1) {
2735
1761
  throw new Error('Wildcard must be the last character in the route');
2736
1762
  }
2737
1763
  }
2738
1764
  }
2739
1765
  if (!this.caseSensitive) {
2740
- path = path.toLowerCase();
1766
+ pattern = pattern.toLowerCase();
2741
1767
  }
2742
- if (path === '*') {
2743
- path = '/*';
1768
+ if (pattern === '*') {
1769
+ pattern = '/*';
2744
1770
  }
2745
- for (const existRoute of this._routesPatterns[method]) {
2746
- if (existRoute.path === path && deepEqual(existRoute.constraints, constraints)) {
2747
- throw new Error(`Method '${method}' already declared for route '${path}' with constraints '${JSON.stringify(constraints)}'`);
1771
+ for (const existRoute of this.routes) {
1772
+ const routeConstraints = existRoute.opts.constraints || {};
1773
+ if (existRoute.method === method && existRoute.pattern === pattern && deepEqual(routeConstraints, constraints)) {
1774
+ throw new Error("Method '".concat(method, "' already declared for route '").concat(pattern, "' with constraints '").concat(JSON.stringify(constraints), "'"));
2748
1775
  }
2749
1776
  }
2750
- this._routesPatterns[method].push({
1777
+ const route = {
1778
+ method,
2751
1779
  path,
1780
+ pattern,
2752
1781
  params,
2753
- constraints
2754
- });
2755
- currentNode.handlerStorage.addHandler(handler, params, store, this.constrainer, constraints);
1782
+ opts,
1783
+ handler,
1784
+ store
1785
+ };
1786
+ this.routes.push(route);
1787
+ currentNode.addRoute(route, this.constrainer);
2756
1788
  };
2757
1789
  Router.prototype.hasConstraintStrategy = function (strategyName) {
2758
1790
  return this.constrainer.hasConstraintStrategy(strategyName);
@@ -2764,7 +1796,6 @@
2764
1796
  Router.prototype.reset = function reset() {
2765
1797
  this.trees = {};
2766
1798
  this.routes = [];
2767
- this._routesPatterns = {};
2768
1799
  };
2769
1800
  Router.prototype.off = function off(method, path, constraints) {
2770
1801
  // path validation
@@ -2798,7 +1829,7 @@
2798
1829
  Router.prototype._off = function _off(method, path, constraints) {
2799
1830
  // method validation
2800
1831
  assert(typeof method === 'string', 'Method should be a string');
2801
- assert(httpMethods.includes(method), `Method '${method}' is not an http method.`);
1832
+ assert(httpMethods.includes(method), "Method '".concat(method, "' is not an http method."));
2802
1833
  function matcherWithoutConstraints(route) {
2803
1834
  return method !== route.method || path !== route.path;
2804
1835
  }
@@ -2877,7 +1908,7 @@
2877
1908
  const pathLen = path.length;
2878
1909
  const brothersNodesStack = [];
2879
1910
  while (true) {
2880
- if (pathIndex === pathLen) {
1911
+ if (pathIndex === pathLen && currentNode.isLeafNode) {
2881
1912
  const handle = currentNode.handlerStorage.getMatchingHandler(derivedConstraints);
2882
1913
  if (handle !== null) {
2883
1914
  return {
@@ -2954,13 +1985,6 @@
2954
1985
  store
2955
1986
  } = route;
2956
1987
  this._on(method, path, opts, handler, store);
2957
- this.routes.push({
2958
- method,
2959
- path,
2960
- opts,
2961
- handler,
2962
- store
2963
- });
2964
1988
  }
2965
1989
  };
2966
1990
  Router.prototype._defaultRoute = function (req, res, ctx) {
@@ -2982,22 +2006,40 @@
2982
2006
  store: null
2983
2007
  };
2984
2008
  };
2985
- Router.prototype.prettyPrint = function (opts = {}) {
2986
- opts.commonPrefix = opts.commonPrefix === undefined ? true : opts.commonPrefix; // default to original behaviour
2987
- if (!opts.commonPrefix) return prettyPrintRoutesArray.call(this, this.routes, opts);
2988
- const root = {
2989
- prefix: '/',
2990
- nodes: [],
2991
- children: {}
2992
- };
2993
- for (const method in this.trees) {
2994
- const node = this.trees[method];
2995
- if (node) {
2996
- flattenNode(root, node, method);
2997
- }
2009
+ Router.prototype.prettyPrint = function () {
2010
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2011
+ const method = options.method;
2012
+ options.buildPrettyMeta = this.buildPrettyMeta.bind(this);
2013
+ let tree = null;
2014
+ if (method === undefined) {
2015
+ const _this$constrainer$str = this.constrainer.strategies,
2016
+ {
2017
+ version,
2018
+ host
2019
+ } = _this$constrainer$str,
2020
+ constraints = _objectWithoutProperties(_this$constrainer$str, _excluded);
2021
+ constraints[httpMethodStrategy.name] = httpMethodStrategy;
2022
+ const mergedRouter = new Router(_objectSpread(_objectSpread({}, this._opts), {}, {
2023
+ constraints
2024
+ }));
2025
+ const mergedRoutes = this.routes.map(route => {
2026
+ const constraints = _objectSpread(_objectSpread({}, route.opts.constraints), {}, {
2027
+ [httpMethodStrategy.name]: route.method
2028
+ });
2029
+ return _objectSpread(_objectSpread({}, route), {}, {
2030
+ method: 'MERGED',
2031
+ opts: {
2032
+ constraints
2033
+ }
2034
+ });
2035
+ });
2036
+ mergedRouter._rebuild(mergedRoutes);
2037
+ tree = mergedRouter.trees.MERGED;
2038
+ } else {
2039
+ tree = this.trees[method];
2998
2040
  }
2999
- compressFlattenedNode(root);
3000
- return prettyPrintFlattenedNode.call(this, root, '', true, opts);
2041
+ if (tree == null) return '(empty tree)';
2042
+ return prettyPrintTree(tree, options);
3001
2043
  };
3002
2044
  for (var i in httpMethods) {
3003
2045
  /* eslint no-prototype-builtins: "off" */
@@ -3065,17 +2107,18 @@
3065
2107
  return Object.assign({}, route.store);
3066
2108
  }
3067
2109
  }, {
3068
- "./custom_node": 27,
3069
- "./lib/constrainer": 30,
3070
- "./lib/http-methods": 31,
3071
- "./lib/pretty-print": 32,
3072
- "./lib/url-sanitizer": 35,
2110
+ "./lib/constrainer": 14,
2111
+ "./lib/http-methods": 16,
2112
+ "./lib/node": 17,
2113
+ "./lib/pretty-print": 18,
2114
+ "./lib/strategies/http-method": 21,
2115
+ "./lib/url-sanitizer": 22,
3073
2116
  "assert": 1,
3074
- "fast-deep-equal": 22,
3075
- "fast-querystring": 23,
3076
- "safe-regex2": 38
2117
+ "fast-deep-equal": 8,
2118
+ "fast-querystring": 9,
2119
+ "safe-regex2": 25
3077
2120
  }],
3078
- 30: [function (require, module, exports) {
2121
+ 14: [function (require, module, exports) {
3079
2122
  'use strict';
3080
2123
 
3081
2124
  const acceptVersionStrategy = require('./strategies/accept-version');
@@ -3112,10 +2155,10 @@
3112
2155
  assert(strategy.storage && typeof strategy.storage === 'function', 'strategy.storage function is required.');
3113
2156
  assert(strategy.deriveConstraint && typeof strategy.deriveConstraint === 'function', 'strategy.deriveConstraint function is required.');
3114
2157
  if (this.strategies[strategy.name] && this.strategies[strategy.name].isCustom) {
3115
- throw new Error(`There already exists a custom constraint with the name ${strategy.name}.`);
2158
+ throw new Error("There already exists a custom constraint with the name ".concat(strategy.name, "."));
3116
2159
  }
3117
2160
  if (this.isStrategyUsed(strategy.name)) {
3118
- throw new Error(`There already exists a route with ${strategy.name} constraint.`);
2161
+ throw new Error("There already exists a route with ".concat(strategy.name, " constraint."));
3119
2162
  }
3120
2163
  strategy.isCustom = true;
3121
2164
  strategy.isAsync = strategy.deriveConstraint.length === 3;
@@ -3156,7 +2199,7 @@
3156
2199
  }
3157
2200
  newStoreForConstraint(constraint) {
3158
2201
  if (!this.strategies[constraint]) {
3159
- throw new Error(`No strategy registered for constraint key ${constraint}`);
2202
+ throw new Error("No strategy registered for constraint key ".concat(constraint));
3160
2203
  }
3161
2204
  return this.strategies[constraint].storage();
3162
2205
  }
@@ -3168,7 +2211,7 @@
3168
2211
  }
3169
2212
  const strategy = this.strategies[key];
3170
2213
  if (!strategy) {
3171
- throw new Error(`No strategy registered for constraint key ${key}`);
2214
+ throw new Error("No strategy registered for constraint key ".concat(key));
3172
2215
  }
3173
2216
  if (strategy.validate) {
3174
2217
  strategy.validate(value);
@@ -3215,7 +2258,7 @@
3215
2258
  throw new Error('unknown non-custom strategy for compiling constraint derivation function');
3216
2259
  }
3217
2260
  } else {
3218
- lines.push(` ${strategy.name}: this.strategies.${key}.deriveConstraint(req, ctx),`);
2261
+ lines.push(" ".concat(strategy.name, ": this.strategies.").concat(key, ".deriveConstraint(req, ctx),"));
3219
2262
  }
3220
2263
  }
3221
2264
  lines.push('}');
@@ -3225,30 +2268,359 @@
3225
2268
 
3226
2269
  module.exports = Constrainer;
3227
2270
  }, {
3228
- "./strategies/accept-host": 33,
3229
- "./strategies/accept-version": 34,
2271
+ "./strategies/accept-host": 19,
2272
+ "./strategies/accept-version": 20,
3230
2273
  "assert": 1
3231
2274
  }],
3232
- 31: [function (require, module, exports) {
2275
+ 15: [function (require, module, exports) {
2276
+ 'use strict';
2277
+
2278
+ const httpMethodStrategy = require('./strategies/http-method');
2279
+ class HandlerStorage {
2280
+ constructor() {
2281
+ this.unconstrainedHandler = null; // optimized reference to the handler that will match most of the time
2282
+ this.constraints = [];
2283
+ this.handlers = []; // unoptimized list of handler objects for which the fast matcher function will be compiled
2284
+ this.constrainedHandlerStores = null;
2285
+ }
2286
+
2287
+ // This is the hot path for node handler finding -- change with care!
2288
+ getMatchingHandler(derivedConstraints) {
2289
+ if (derivedConstraints === undefined) {
2290
+ return this.unconstrainedHandler;
2291
+ }
2292
+ return this._getHandlerMatchingConstraints(derivedConstraints);
2293
+ }
2294
+ addHandler(constrainer, route) {
2295
+ const params = route.params;
2296
+ const constraints = route.opts.constraints || {};
2297
+ const handlerObject = {
2298
+ params,
2299
+ constraints,
2300
+ handler: route.handler,
2301
+ store: route.store || null,
2302
+ _createParamsObject: this._compileCreateParamsObject(params)
2303
+ };
2304
+ const constraintsNames = Object.keys(constraints);
2305
+ if (constraintsNames.length === 0) {
2306
+ this.unconstrainedHandler = handlerObject;
2307
+ }
2308
+ for (const constraint of constraintsNames) {
2309
+ if (!this.constraints.includes(constraint)) {
2310
+ if (constraint === 'version') {
2311
+ // always check the version constraint first as it is the most selective
2312
+ this.constraints.unshift(constraint);
2313
+ } else {
2314
+ this.constraints.push(constraint);
2315
+ }
2316
+ }
2317
+ }
2318
+ const isMergedTree = constraintsNames.includes(httpMethodStrategy.name);
2319
+ if (!isMergedTree && this.handlers.length >= 32) {
2320
+ throw new Error('find-my-way supports a maximum of 32 route handlers per node when there are constraints, limit reached');
2321
+ }
2322
+ this.handlers.push(handlerObject);
2323
+ // Sort the most constrained handlers to the front of the list of handlers so they are tested first.
2324
+ this.handlers.sort((a, b) => Object.keys(a.constraints).length - Object.keys(b.constraints).length);
2325
+ if (!isMergedTree) {
2326
+ this._compileGetHandlerMatchingConstraints(constrainer, constraints);
2327
+ }
2328
+ }
2329
+ _compileCreateParamsObject(params) {
2330
+ const lines = [];
2331
+ for (let i = 0; i < params.length; i++) {
2332
+ lines.push("'".concat(params[i], "': paramsArray[").concat(i, "]"));
2333
+ }
2334
+ return new Function('paramsArray', "return {".concat(lines.join(','), "}")); // eslint-disable-line
2335
+ }
2336
+
2337
+ _getHandlerMatchingConstraints() {
2338
+ return null;
2339
+ }
2340
+
2341
+ // Builds a store object that maps from constraint values to a bitmap of handler indexes which pass the constraint for a value
2342
+ // So for a host constraint, this might look like { "fastify.io": 0b0010, "google.ca": 0b0101 }, meaning the 3rd handler is constrainted to fastify.io, and the 2nd and 4th handlers are constrained to google.ca.
2343
+ // The store's implementation comes from the strategies provided to the Router.
2344
+ _buildConstraintStore(store, constraint) {
2345
+ for (let i = 0; i < this.handlers.length; i++) {
2346
+ const handler = this.handlers[i];
2347
+ const constraintValue = handler.constraints[constraint];
2348
+ if (constraintValue !== undefined) {
2349
+ let indexes = store.get(constraintValue) || 0;
2350
+ indexes |= 1 << i; // set the i-th bit for the mask because this handler is constrained by this value https://stackoverflow.com/questions/1436438/how-do-you-set-clear-and-toggle-a-single-bit-in-javascrip
2351
+ store.set(constraintValue, indexes);
2352
+ }
2353
+ }
2354
+ }
2355
+
2356
+ // Builds a bitmask for a given constraint that has a bit for each handler index that is 0 when that handler *is* constrained and 1 when the handler *isnt* constrainted. This is opposite to what might be obvious, but is just for convienience when doing the bitwise operations.
2357
+ _constrainedIndexBitmask(constraint) {
2358
+ let mask = 0;
2359
+ for (let i = 0; i < this.handlers.length; i++) {
2360
+ const handler = this.handlers[i];
2361
+ const constraintValue = handler.constraints[constraint];
2362
+ if (constraintValue !== undefined) {
2363
+ mask |= 1 << i;
2364
+ }
2365
+ }
2366
+ return ~mask;
2367
+ }
2368
+
2369
+ // Compile a fast function to match the handlers for this node
2370
+ // The function implements a general case multi-constraint matching algorithm.
2371
+ // The general idea is this: we have a bunch of handlers, each with a potentially different set of constraints, and sometimes none at all. We're given a list of constraint values and we have to use the constraint-value-comparison strategies to see which handlers match the constraint values passed in.
2372
+ // We do this by asking each constraint store which handler indexes match the given constraint value for each store. Trickily, the handlers that a store says match are the handlers constrained by that store, but handlers that aren't constrained at all by that store could still match just fine. So, each constraint store can only describe matches for it, and it won't have any bearing on the handlers it doesn't care about. For this reason, we have to ask each stores which handlers match and track which have been matched (or not cared about) by all of them.
2373
+ // We use bitmaps to represent these lists of matches so we can use bitwise operations to implement this efficiently. Bitmaps are cheap to allocate, let us implement this masking behaviour in one CPU instruction, and are quite compact in memory. We start with a bitmap set to all 1s representing every handler that is a match candidate, and then for each constraint, see which handlers match using the store, and then mask the result by the mask of handlers that that store applies to, and bitwise AND with the candidate list. Phew.
2374
+ // We consider all this compiling function complexity to be worth it, because the naive implementation that just loops over the handlers asking which stores match is quite a bit slower.
2375
+ _compileGetHandlerMatchingConstraints(constrainer) {
2376
+ this.constrainedHandlerStores = {};
2377
+ for (const constraint of this.constraints) {
2378
+ const store = constrainer.newStoreForConstraint(constraint);
2379
+ this.constrainedHandlerStores[constraint] = store;
2380
+ this._buildConstraintStore(store, constraint);
2381
+ }
2382
+ const lines = [];
2383
+ lines.push("\n let candidates = ".concat((1 << this.handlers.length) - 1, "\n let mask, matches\n "));
2384
+ for (const constraint of this.constraints) {
2385
+ // Setup the mask for indexes this constraint applies to. The mask bits are set to 1 for each position if the constraint applies.
2386
+ lines.push("\n mask = ".concat(this._constrainedIndexBitmask(constraint), "\n value = derivedConstraints.").concat(constraint, "\n "));
2387
+
2388
+ // If there's no constraint value, none of the handlers constrained by this constraint can match. Remove them from the candidates.
2389
+ // If there is a constraint value, get the matching indexes bitmap from the store, and mask it down to only the indexes this constraint applies to, and then bitwise and with the candidates list to leave only matching candidates left.
2390
+ const strategy = constrainer.strategies[constraint];
2391
+ const matchMask = strategy.mustMatchWhenDerived ? 'matches' : '(matches | mask)';
2392
+ lines.push("\n if (value === undefined) {\n candidates &= mask\n } else {\n matches = this.constrainedHandlerStores.".concat(constraint, ".get(value) || 0\n candidates &= ").concat(matchMask, "\n }\n if (candidates === 0) return null;\n "));
2393
+ }
2394
+
2395
+ // There are some constraints that can be derived and marked as "must match", where if they are derived, they only match routes that actually have a constraint on the value, like the SemVer version constraint.
2396
+ // An example: a request comes in for version 1.x, and this node has a handler that matches the path, but there's no version constraint. For SemVer, the find-my-way semantics do not match this handler to that request.
2397
+ // This function is used by Nodes with handlers to match when they don't have any constrained routes to exclude request that do have must match derived constraints present.
2398
+ for (const constraint in constrainer.strategies) {
2399
+ const strategy = constrainer.strategies[constraint];
2400
+ if (strategy.mustMatchWhenDerived && !this.constraints.includes(constraint)) {
2401
+ lines.push("if (derivedConstraints.".concat(constraint, " !== undefined) return null"));
2402
+ }
2403
+ }
2404
+
2405
+ // Return the first handler who's bit is set in the candidates https://stackoverflow.com/questions/18134985/how-to-find-index-of-first-set-bit
2406
+ lines.push('return this.handlers[Math.floor(Math.log2(candidates))]');
2407
+ this._getHandlerMatchingConstraints = new Function('derivedConstraints', lines.join('\n')); // eslint-disable-line
2408
+ }
2409
+ }
2410
+
2411
+ module.exports = HandlerStorage;
2412
+ }, {
2413
+ "./strategies/http-method": 21
2414
+ }],
2415
+ 16: [function (require, module, exports) {
3233
2416
  'use strict';
3234
2417
 
3235
2418
  // defined by Node.js http module, a snapshot from Node.js 18.12.0
3236
2419
  const httpMethods = ['ACL', 'BIND', 'CHECKOUT', 'CONNECT', 'COPY', 'DELETE', 'GET', 'HEAD', 'LINK', 'LOCK', 'M-SEARCH', 'MERGE', 'MKACTIVITY', 'MKCALENDAR', 'MKCOL', 'MOVE', 'NOTIFY', 'OPTIONS', 'PATCH', 'POST', 'PROPFIND', 'PROPPATCH', 'PURGE', 'PUT', 'REBIND', 'REPORT', 'SEARCH', 'SOURCE', 'SUBSCRIBE', 'TRACE', 'UNBIND', 'UNLINK', 'UNLOCK', 'UNSUBSCRIBE'];
3237
2420
  module.exports = httpMethods;
3238
2421
  }, {}],
3239
- 32: [function (require, module, exports) {
2422
+ 17: [function (require, module, exports) {
3240
2423
  'use strict';
3241
2424
 
3242
- /* eslint-disable no-multi-spaces */
3243
- const indent = ' ';
3244
- const branchIndent = '│ ';
3245
- const midBranchIndent = '├── ';
3246
- const endBranchIndent = '└── ';
3247
- const wildcardDelimiter = '*';
3248
- const pathDelimiter = '/';
3249
- const pathRegExp = /(?=\/)/;
3250
- /* eslint-enable */
2425
+ const HandlerStorage = require('./handler-storage');
2426
+ const NODE_TYPES = {
2427
+ STATIC: 0,
2428
+ PARAMETRIC: 1,
2429
+ WILDCARD: 2
2430
+ };
2431
+ class Node {
2432
+ constructor() {
2433
+ this.isLeafNode = false;
2434
+ this.routes = null;
2435
+ this.handlerStorage = null;
2436
+ }
2437
+ addRoute(route, constrainer) {
2438
+ if (this.routes === null) {
2439
+ this.routes = [];
2440
+ }
2441
+ if (this.handlerStorage === null) {
2442
+ this.handlerStorage = new HandlerStorage();
2443
+ }
2444
+ this.isLeafNode = true;
2445
+ this.routes.push(route);
2446
+ this.handlerStorage.addHandler(constrainer, route);
2447
+ }
2448
+ }
2449
+ class ParentNode extends Node {
2450
+ constructor() {
2451
+ super();
2452
+ this.staticChildren = {};
2453
+ }
2454
+ findStaticMatchingChild(path, pathIndex) {
2455
+ const staticChild = this.staticChildren[path.charAt(pathIndex)];
2456
+ if (staticChild === undefined || !staticChild.matchPrefix(path, pathIndex)) {
2457
+ return null;
2458
+ }
2459
+ return staticChild;
2460
+ }
2461
+ createStaticChild(path) {
2462
+ if (path.length === 0) {
2463
+ return this;
2464
+ }
2465
+ let staticChild = this.staticChildren[path.charAt(0)];
2466
+ if (staticChild) {
2467
+ let i = 1;
2468
+ for (; i < staticChild.prefix.length; i++) {
2469
+ if (path.charCodeAt(i) !== staticChild.prefix.charCodeAt(i)) {
2470
+ staticChild = staticChild.split(this, i);
2471
+ break;
2472
+ }
2473
+ }
2474
+ return staticChild.createStaticChild(path.slice(i));
2475
+ }
2476
+ const label = path.charAt(0);
2477
+ this.staticChildren[label] = new StaticNode(path);
2478
+ return this.staticChildren[label];
2479
+ }
2480
+ }
2481
+ class StaticNode extends ParentNode {
2482
+ constructor(prefix) {
2483
+ super();
2484
+ this.prefix = prefix;
2485
+ this.wildcardChild = null;
2486
+ this.parametricChildren = [];
2487
+ this.kind = NODE_TYPES.STATIC;
2488
+ this._compilePrefixMatch();
2489
+ }
2490
+ createParametricChild(regex, staticSuffix, nodePath) {
2491
+ const regexpSource = regex && regex.source;
2492
+ let parametricChild = this.parametricChildren.find(child => {
2493
+ const childRegexSource = child.regex && child.regex.source;
2494
+ return childRegexSource === regexpSource;
2495
+ });
2496
+ if (parametricChild) {
2497
+ parametricChild.nodePaths.add(nodePath);
2498
+ return parametricChild;
2499
+ }
2500
+ parametricChild = new ParametricNode(regex, staticSuffix, nodePath);
2501
+ this.parametricChildren.push(parametricChild);
2502
+ this.parametricChildren.sort((child1, child2) => {
2503
+ if (!child1.isRegex) return 1;
2504
+ if (!child2.isRegex) return -1;
2505
+ if (child1.staticSuffix === null) return 1;
2506
+ if (child2.staticSuffix === null) return -1;
2507
+ if (child2.staticSuffix.endsWith(child1.staticSuffix)) return 1;
2508
+ if (child1.staticSuffix.endsWith(child2.staticSuffix)) return -1;
2509
+ return 0;
2510
+ });
2511
+ return parametricChild;
2512
+ }
2513
+ createWildcardChild() {
2514
+ if (this.wildcardChild) {
2515
+ return this.wildcardChild;
2516
+ }
2517
+ this.wildcardChild = new WildcardNode();
2518
+ return this.wildcardChild;
2519
+ }
2520
+ split(parentNode, length) {
2521
+ const parentPrefix = this.prefix.slice(0, length);
2522
+ const childPrefix = this.prefix.slice(length);
2523
+ this.prefix = childPrefix;
2524
+ this._compilePrefixMatch();
2525
+ const staticNode = new StaticNode(parentPrefix);
2526
+ staticNode.staticChildren[childPrefix.charAt(0)] = this;
2527
+ parentNode.staticChildren[parentPrefix.charAt(0)] = staticNode;
2528
+ return staticNode;
2529
+ }
2530
+ getNextNode(path, pathIndex, nodeStack, paramsCount) {
2531
+ let node = this.findStaticMatchingChild(path, pathIndex);
2532
+ let parametricBrotherNodeIndex = 0;
2533
+ if (node === null) {
2534
+ if (this.parametricChildren.length === 0) {
2535
+ return this.wildcardChild;
2536
+ }
2537
+ node = this.parametricChildren[0];
2538
+ parametricBrotherNodeIndex = 1;
2539
+ }
2540
+ if (this.wildcardChild !== null) {
2541
+ nodeStack.push({
2542
+ paramsCount,
2543
+ brotherPathIndex: pathIndex,
2544
+ brotherNode: this.wildcardChild
2545
+ });
2546
+ }
2547
+ for (let i = this.parametricChildren.length - 1; i >= parametricBrotherNodeIndex; i--) {
2548
+ nodeStack.push({
2549
+ paramsCount,
2550
+ brotherPathIndex: pathIndex,
2551
+ brotherNode: this.parametricChildren[i]
2552
+ });
2553
+ }
2554
+ return node;
2555
+ }
2556
+ _compilePrefixMatch() {
2557
+ if (this.prefix.length === 1) {
2558
+ this.matchPrefix = () => true;
2559
+ return;
2560
+ }
2561
+ const lines = [];
2562
+ for (let i = 1; i < this.prefix.length; i++) {
2563
+ const charCode = this.prefix.charCodeAt(i);
2564
+ lines.push("path.charCodeAt(i + ".concat(i, ") === ").concat(charCode));
2565
+ }
2566
+ this.matchPrefix = new Function('path', 'i', "return ".concat(lines.join(' && '))); // eslint-disable-line
2567
+ }
2568
+ }
3251
2569
 
2570
+ class ParametricNode extends ParentNode {
2571
+ constructor(regex, staticSuffix, nodePath) {
2572
+ super();
2573
+ this.isRegex = !!regex;
2574
+ this.regex = regex || null;
2575
+ this.staticSuffix = staticSuffix || null;
2576
+ this.kind = NODE_TYPES.PARAMETRIC;
2577
+ this.nodePaths = new Set([nodePath]);
2578
+ }
2579
+ getNextNode(path, pathIndex) {
2580
+ return this.findStaticMatchingChild(path, pathIndex);
2581
+ }
2582
+ }
2583
+ class WildcardNode extends Node {
2584
+ constructor() {
2585
+ super();
2586
+ this.kind = NODE_TYPES.WILDCARD;
2587
+ }
2588
+ getNextNode() {
2589
+ return null;
2590
+ }
2591
+ }
2592
+ module.exports = {
2593
+ StaticNode,
2594
+ ParametricNode,
2595
+ WildcardNode,
2596
+ NODE_TYPES
2597
+ };
2598
+ }, {
2599
+ "./handler-storage": 15
2600
+ }],
2601
+ 18: [function (require, module, exports) {
2602
+ 'use strict';
2603
+
2604
+ const deepEqual = require('fast-deep-equal');
2605
+ const httpMethodStrategy = require('./strategies/http-method');
2606
+ const treeDataSymbol = Symbol('treeData');
2607
+ function printObjectTree(obj) {
2608
+ let parentPrefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
2609
+ let tree = '';
2610
+ const keys = Object.keys(obj);
2611
+ for (let i = 0; i < keys.length; i++) {
2612
+ const key = keys[i];
2613
+ const value = obj[key];
2614
+ const isLast = i === keys.length - 1;
2615
+ const nodePrefix = isLast ? '└── ' : '├── ';
2616
+ const childPrefix = isLast ? ' ' : '│ ';
2617
+ const nodeData = value[treeDataSymbol] || '';
2618
+ const prefixedNodeData = nodeData.split('\n').join('\n' + parentPrefix + childPrefix);
2619
+ tree += parentPrefix + nodePrefix + key + prefixedNodeData + '\n';
2620
+ tree += printObjectTree(value, parentPrefix + childPrefix);
2621
+ }
2622
+ return tree;
2623
+ }
3252
2624
  function parseFunctionName(fn) {
3253
2625
  let fName = fn.name || '';
3254
2626
  fName = fName.replace('bound', '').trim();
@@ -3261,293 +2633,117 @@
3261
2633
  if (typeof meta === 'function') return parseFunctionName(meta);
3262
2634
  return meta;
3263
2635
  }
3264
- function buildMetaObject(route, metaArray) {
3265
- const out = {};
3266
- const cleanMeta = this.buildPrettyMeta(route);
3267
- if (!Array.isArray(metaArray)) metaArray = cleanMeta ? Reflect.ownKeys(cleanMeta) : [];
3268
- metaArray.forEach(m => {
3269
- const metaKey = typeof m === 'symbol' ? m.toString() : m;
3270
- if (cleanMeta && cleanMeta[m]) {
3271
- out[metaKey] = parseMeta(cleanMeta[m]);
3272
- }
3273
- });
3274
- return out;
2636
+ function getRouteMetaData(route, options) {
2637
+ if (!options.includeMeta) return {};
2638
+ const metaDataObject = options.buildPrettyMeta(route);
2639
+ const filteredMetaData = {};
2640
+ let includeMetaKeys = options.includeMeta;
2641
+ if (!Array.isArray(includeMetaKeys)) {
2642
+ includeMetaKeys = Reflect.ownKeys(metaDataObject);
2643
+ }
2644
+ for (const metaKey of includeMetaKeys) {
2645
+ if (!Object.prototype.hasOwnProperty.call(metaDataObject, metaKey)) continue;
2646
+ const serializedKey = metaKey.toString();
2647
+ const metaValue = metaDataObject[metaKey];
2648
+ if (metaValue !== undefined && metaValue !== null) {
2649
+ const serializedValue = JSON.stringify(parseMeta(metaValue));
2650
+ filteredMetaData[serializedKey] = serializedValue;
2651
+ }
2652
+ }
2653
+ return filteredMetaData;
3275
2654
  }
3276
- function prettyPrintRoutesArray(routeArray, opts = {}) {
3277
- if (!this.buildPrettyMeta) throw new Error('buildPrettyMeta not defined');
3278
- opts.includeMeta = opts.includeMeta || null; // array of meta objects to display
3279
- const mergedRouteArray = [];
3280
- let tree = '';
3281
- routeArray.sort((a, b) => {
3282
- if (!a.path || !b.path) return 0;
3283
- return a.path.localeCompare(b.path);
3284
- });
3285
-
3286
- // merge alike paths
3287
- for (let i = 0; i < routeArray.length; i++) {
3288
- const route = routeArray[i];
3289
- const pathExists = mergedRouteArray.find(r => route.path === r.path);
3290
- if (pathExists) {
3291
- // path already declared, add new method and break out of loop
3292
- pathExists.handlers.push({
3293
- method: route.method,
3294
- opts: route.opts.constraints || undefined,
3295
- meta: opts.includeMeta ? buildMetaObject.call(this, route, opts.includeMeta) : null
3296
- });
3297
- continue;
3298
- }
3299
- const routeHandler = {
3300
- method: route.method,
3301
- opts: route.opts.constraints || undefined,
3302
- meta: opts.includeMeta ? buildMetaObject.call(this, route, opts.includeMeta) : null
3303
- };
3304
- mergedRouteArray.push({
3305
- path: route.path,
3306
- methods: [route.method],
3307
- opts: [route.opts],
3308
- handlers: [routeHandler]
3309
- });
2655
+ function serializeMetaData(metaData) {
2656
+ let serializedMetaData = '';
2657
+ for (const [key, value] of Object.entries(metaData)) {
2658
+ serializedMetaData += "\n\u2022 (".concat(key, ") ").concat(value);
3310
2659
  }
3311
-
3312
- // insert root level path if none defined
3313
- if (!mergedRouteArray.filter(r => r.path === pathDelimiter).length) {
3314
- const rootPath = {
3315
- path: pathDelimiter,
3316
- truncatedPath: '',
3317
- methods: [],
3318
- opts: [],
3319
- handlers: [{}]
3320
- };
3321
-
3322
- // if wildcard route exists, insert root level after wildcard
3323
- if (mergedRouteArray.filter(r => r.path === wildcardDelimiter).length) {
3324
- mergedRouteArray.splice(1, 0, rootPath);
3325
- } else {
3326
- mergedRouteArray.unshift(rootPath);
3327
- }
3328
- }
3329
-
3330
- // build tree
3331
- const routeTree = buildRouteTree(mergedRouteArray);
3332
-
3333
- // draw tree
3334
- routeTree.forEach((rootBranch, idx) => {
3335
- tree += drawBranch(rootBranch, null, idx === routeTree.length - 1, false, true);
3336
- tree += '\n'; // newline characters inserted at beginning of drawing function to allow for nested paths
3337
- });
3338
-
3339
- return tree;
2660
+ return serializedMetaData;
3340
2661
  }
3341
- function buildRouteTree(mergedRouteArray) {
3342
- const result = [];
3343
- const temp = {
3344
- result
3345
- };
3346
- mergedRouteArray.forEach((route, idx) => {
3347
- let splitPath = route.path.split(pathRegExp);
3348
2662
 
3349
- // add preceding slash for proper nesting
3350
- if (splitPath[0] !== pathDelimiter) {
3351
- // handle wildcard route
3352
- if (splitPath[0] !== wildcardDelimiter) splitPath = [pathDelimiter, splitPath[0].slice(1), ...splitPath.slice(1)];
2663
+ // get original merged tree node route
2664
+ function normalizeRoute(route) {
2665
+ const constraints = _objectSpread({}, route.opts.constraints);
2666
+ const method = constraints[httpMethodStrategy.name];
2667
+ delete constraints[httpMethodStrategy.name];
2668
+ return _objectSpread(_objectSpread({}, route), {}, {
2669
+ method,
2670
+ opts: {
2671
+ constraints
3353
2672
  }
3354
-
3355
- // build tree
3356
- splitPath.reduce((acc, path, pidx) => {
3357
- if (!acc[path]) {
3358
- acc[path] = {
3359
- result: []
3360
- };
3361
- const pathSeg = {
3362
- path,
3363
- children: acc[path].result
3364
- };
3365
- if (pidx === splitPath.length - 1) pathSeg.handlers = route.handlers;
3366
- acc.result.push(pathSeg);
3367
- }
3368
- return acc[path];
3369
- }, temp);
3370
2673
  });
3371
-
3372
- // unfold root object from array
3373
- return result;
3374
2674
  }
3375
- function drawBranch(pathSeg, prefix, endBranch, noPrefix, rootBranch) {
3376
- let branch = '';
3377
- if (!noPrefix && !rootBranch) branch += '\n';
3378
- if (!noPrefix) branch += `${prefix || ''}${endBranch ? endBranchIndent : midBranchIndent}`;
3379
- branch += `${pathSeg.path}`;
3380
- if (pathSeg.handlers) {
3381
- const flatHandlers = pathSeg.handlers.reduce((acc, curr) => {
3382
- const match = acc.findIndex(h => JSON.stringify(h.opts) === JSON.stringify(curr.opts));
3383
- if (match !== -1) {
3384
- acc[match].method = [acc[match].method, curr.method].join(', ');
3385
- } else {
3386
- acc.push(curr);
3387
- }
3388
- return acc;
3389
- }, []);
3390
- flatHandlers.forEach((handler, idx) => {
3391
- if (idx > 0) branch += `${noPrefix ? '' : prefix || ''}${endBranch ? indent : branchIndent}${pathSeg.path}`;
3392
- branch += ` (${handler.method || '-'})`;
3393
- if (handler.opts && JSON.stringify(handler.opts) !== '{}') branch += ` ${JSON.stringify(handler.opts)}`;
3394
- if (handler.meta) {
3395
- Reflect.ownKeys(handler.meta).forEach((m, hidx) => {
3396
- branch += `\n${noPrefix ? '' : prefix || ''}${endBranch ? indent : branchIndent}`;
3397
- branch += `• (${m}) ${JSON.stringify(handler.meta[m])}`;
3398
- });
3399
- }
3400
- if (flatHandlers.length > 1 && idx !== flatHandlers.length - 1) branch += '\n';
3401
- });
3402
- } else {
3403
- if (pathSeg.children.length > 1) branch += ' (-)';
3404
- }
3405
- if (!noPrefix) prefix = `${prefix || ''}${endBranch ? indent : branchIndent}`;
3406
- pathSeg.children.forEach((child, idx) => {
3407
- const endBranch = idx === pathSeg.children.length - 1;
3408
- const skipPrefix = !pathSeg.handlers && pathSeg.children.length === 1;
3409
- branch += drawBranch(child, prefix, endBranch, skipPrefix);
3410
- });
3411
- return branch;
2675
+ function serializeRoute(route) {
2676
+ let serializedRoute = " (".concat(route.method, ")");
2677
+ const constraints = route.opts.constraints || {};
2678
+ if (Object.keys(constraints).length !== 0) {
2679
+ serializedRoute += ' ' + JSON.stringify(constraints);
2680
+ }
2681
+ serializedRoute += serializeMetaData(route.metaData);
2682
+ return serializedRoute;
3412
2683
  }
3413
- function prettyPrintFlattenedNode(flattenedNode, prefix, tail, opts) {
3414
- if (!this.buildPrettyMeta) throw new Error('buildPrettyMeta not defined');
3415
- opts.includeMeta = opts.includeMeta || null; // array of meta items to display
3416
- let paramName = '';
3417
- const printHandlers = [];
3418
- for (const {
3419
- node,
3420
- method
3421
- } of flattenedNode.nodes) {
3422
- for (const handler of node.handlerStorage.handlers) {
3423
- printHandlers.push({
3424
- method,
3425
- ...handler
3426
- });
3427
- }
3428
- }
3429
- if (printHandlers.length) {
3430
- printHandlers.forEach((handler, index) => {
3431
- let suffix = `(${handler.method || '-'})`;
3432
- if (Object.keys(handler.constraints).length > 0) {
3433
- suffix += ' ' + JSON.stringify(handler.constraints);
3434
- }
3435
- let name = '';
3436
- // find locations of parameters in prefix
3437
- const paramIndices = flattenedNode.prefix.split('').map((ch, idx) => ch === ':' ? idx : null).filter(idx => idx !== null);
3438
- if (paramIndices.length) {
3439
- let prevLoc = 0;
3440
- paramIndices.forEach((loc, idx) => {
3441
- // find parameter in prefix
3442
- name += flattenedNode.prefix.slice(prevLoc, loc + 1);
3443
- // insert parameters
3444
- name += handler.params[handler.params.length - paramIndices.length + idx];
3445
- if (idx === paramIndices.length - 1) name += flattenedNode.prefix.slice(loc + 1);
3446
- prevLoc = loc + 1;
3447
- });
3448
- } else {
3449
- // there are no parameters, return full object
3450
- name = flattenedNode.prefix;
2684
+ function mergeSimilarRoutes(routes) {
2685
+ return routes.reduce((mergedRoutes, route) => {
2686
+ for (const nodeRoute of mergedRoutes) {
2687
+ if (deepEqual(route.opts.constraints, nodeRoute.opts.constraints) && deepEqual(route.metaData, nodeRoute.metaData)) {
2688
+ nodeRoute.method += ', ' + route.method;
2689
+ return mergedRoutes;
3451
2690
  }
3452
- if (index === 0) {
3453
- paramName += `${name} ${suffix}`;
3454
- } else {
3455
- paramName += `\n${prefix}${tail ? indent : branchIndent}${name} ${suffix}`;
3456
- }
3457
- if (opts.includeMeta) {
3458
- const meta = buildMetaObject.call(this, handler, opts.includeMeta);
3459
- Object.keys(meta).forEach((m, hidx) => {
3460
- paramName += `\n${prefix || ''}${tail ? indent : branchIndent}`;
3461
- paramName += `• (${m}) ${JSON.stringify(meta[m])}`;
3462
- });
3463
- }
3464
- });
3465
- } else {
3466
- paramName = flattenedNode.prefix;
3467
- }
3468
- let tree = `${prefix}${tail ? endBranchIndent : midBranchIndent}${paramName}\n`;
3469
- prefix = `${prefix}${tail ? indent : branchIndent}`;
3470
- const labels = Object.keys(flattenedNode.children);
3471
- for (let i = 0; i < labels.length; i++) {
3472
- const child = flattenedNode.children[labels[i]];
3473
- tree += prettyPrintFlattenedNode.call(this, child, prefix, i === labels.length - 1, opts);
3474
- }
3475
- return tree;
3476
- }
3477
- function flattenNode(flattened, node, method) {
3478
- if (node.handlerStorage.handlers.length !== 0) {
3479
- flattened.nodes.push({
3480
- method,
3481
- node
3482
- });
3483
- }
3484
- if (node.parametricChildren && node.parametricChildren[0]) {
3485
- if (!flattened.children[':']) {
3486
- flattened.children[':'] = {
3487
- prefix: ':',
3488
- nodes: [],
3489
- children: {}
3490
- };
3491
2691
  }
3492
- flattenNode(flattened.children[':'], node.parametricChildren[0], method);
2692
+ mergedRoutes.push(route);
2693
+ return mergedRoutes;
2694
+ }, []);
2695
+ }
2696
+ function serializeNode(node, prefix, options) {
2697
+ let routes = node.routes;
2698
+ if (options.method === undefined) {
2699
+ routes = routes.map(normalizeRoute);
2700
+ }
2701
+ routes = routes.map(route => {
2702
+ route.metaData = getRouteMetaData(route, options);
2703
+ return route;
2704
+ });
2705
+ if (options.method === undefined) {
2706
+ routes = mergeSimilarRoutes(routes);
3493
2707
  }
3494
- if (node.wildcardChild) {
3495
- if (!flattened.children['*']) {
3496
- flattened.children['*'] = {
3497
- prefix: '*',
3498
- nodes: [],
3499
- children: {}
3500
- };
2708
+ return routes.map(serializeRoute).join("\n".concat(prefix));
2709
+ }
2710
+ function buildObjectTree(node, tree, prefix, options) {
2711
+ if (node.isLeafNode || options.commonPrefix !== false) {
2712
+ prefix = prefix || '(empty root node)';
2713
+ tree = tree[prefix] = {};
2714
+ if (node.isLeafNode) {
2715
+ tree[treeDataSymbol] = serializeNode(node, prefix, options);
3501
2716
  }
3502
- flattenNode(flattened.children['*'], node.wildcardChild, method);
2717
+ prefix = '';
3503
2718
  }
3504
2719
  if (node.staticChildren) {
3505
2720
  for (const child of Object.values(node.staticChildren)) {
3506
- // split on the slash separator but use a regex to lookahead and not actually match it, preserving it in the returned string segments
3507
- const childPrefixSegments = child.prefix.split(pathRegExp);
3508
- let cursor = flattened;
3509
- let parent;
3510
- for (const segment of childPrefixSegments) {
3511
- parent = cursor;
3512
- cursor = cursor.children[segment];
3513
- if (!cursor) {
3514
- cursor = {
3515
- prefix: segment,
3516
- nodes: [],
3517
- children: {}
3518
- };
3519
- parent.children[segment] = cursor;
3520
- }
3521
- }
3522
- flattenNode(cursor, child, method);
2721
+ buildObjectTree(child, tree, prefix + child.prefix, options);
2722
+ }
2723
+ }
2724
+ if (node.parametricChildren) {
2725
+ for (const child of Object.values(node.parametricChildren)) {
2726
+ const childPrefix = Array.from(child.nodePaths).join('|');
2727
+ buildObjectTree(child, tree, prefix + childPrefix, options);
3523
2728
  }
3524
2729
  }
2730
+ if (node.wildcardChild) {
2731
+ buildObjectTree(node.wildcardChild, tree, '*', options);
2732
+ }
3525
2733
  }
3526
- function compressFlattenedNode(flattenedNode) {
3527
- const childKeys = Object.keys(flattenedNode.children);
3528
- if (flattenedNode.nodes.length === 0 && childKeys.length === 1) {
3529
- const child = flattenedNode.children[childKeys[0]];
3530
- if (child.nodes.length <= 1) {
3531
- compressFlattenedNode(child);
3532
- flattenedNode.nodes = child.nodes;
3533
- flattenedNode.prefix += child.prefix;
3534
- flattenedNode.children = child.children;
3535
- return flattenedNode;
3536
- }
3537
- }
3538
- for (const key of Object.keys(flattenedNode.children)) {
3539
- compressFlattenedNode(flattenedNode.children[key]);
3540
- }
3541
- return flattenedNode;
2734
+ function prettyPrintTree(root, options) {
2735
+ const objectTree = {};
2736
+ buildObjectTree(root, objectTree, root.prefix, options);
2737
+ return printObjectTree(objectTree);
3542
2738
  }
3543
2739
  module.exports = {
3544
- flattenNode,
3545
- compressFlattenedNode,
3546
- prettyPrintFlattenedNode,
3547
- prettyPrintRoutesArray
2740
+ prettyPrintTree
3548
2741
  };
3549
- }, {}],
3550
- 33: [function (require, module, exports) {
2742
+ }, {
2743
+ "./strategies/http-method": 21,
2744
+ "fast-deep-equal": 8
2745
+ }],
2746
+ 19: [function (require, module, exports) {
3551
2747
  'use strict';
3552
2748
 
3553
2749
  const assert = require('assert');
@@ -3589,7 +2785,7 @@
3589
2785
  }, {
3590
2786
  "assert": 1
3591
2787
  }],
3592
- 34: [function (require, module, exports) {
2788
+ 20: [function (require, module, exports) {
3593
2789
  'use strict';
3594
2790
 
3595
2791
  const assert = require('assert');
@@ -3619,14 +2815,14 @@
3619
2815
  }
3620
2816
  if (minor >= (this.maxMinors[major] || 0)) {
3621
2817
  this.maxMinors[major] = minor;
3622
- this.store[`${major}.x`] = store;
3623
- this.store[`${major}.x.x`] = store;
2818
+ this.store["".concat(major, ".x")] = store;
2819
+ this.store["".concat(major, ".x.x")] = store;
3624
2820
  }
3625
- if (patch >= (this.store[`${major}.${minor}`] || 0)) {
3626
- this.maxPatches[`${major}.${minor}`] = patch;
3627
- this.store[`${major}.${minor}.x`] = store;
2821
+ if (patch >= (this.store["".concat(major, ".").concat(minor)] || 0)) {
2822
+ this.maxPatches["".concat(major, ".").concat(minor)] = patch;
2823
+ this.store["".concat(major, ".").concat(minor, ".x")] = store;
3628
2824
  }
3629
- this.store[`${major}.${minor}.${patch}`] = store;
2825
+ this.store["".concat(major, ".").concat(minor, ".").concat(patch)] = store;
3630
2826
  return this;
3631
2827
  };
3632
2828
  SemVerStore.prototype.get = function (version) {
@@ -3643,7 +2839,30 @@
3643
2839
  }, {
3644
2840
  "assert": 1
3645
2841
  }],
3646
- 35: [function (require, module, exports) {
2842
+ 21: [function (require, module, exports) {
2843
+ 'use strict';
2844
+
2845
+ module.exports = {
2846
+ name: '__fmw_internal_strategy_merged_tree_http_method__',
2847
+ storage: function storage() {
2848
+ const handlers = {};
2849
+ return {
2850
+ get: type => {
2851
+ return handlers[type] || null;
2852
+ },
2853
+ set: (type, store) => {
2854
+ handlers[type] = store;
2855
+ }
2856
+ };
2857
+ },
2858
+ deriveConstraint: req => {
2859
+ /* istanbul ignore next */
2860
+ return req.method;
2861
+ },
2862
+ mustMatchWhenDerived: true
2863
+ };
2864
+ }, {}],
2865
+ 22: [function (require, module, exports) {
3647
2866
  'use strict';
3648
2867
 
3649
2868
  // It must spot all the chars where decodeURIComponent(x) !== decodeURI(x)
@@ -3736,7 +2955,7 @@
3736
2955
  safeDecodeURIComponent
3737
2956
  };
3738
2957
  }, {}],
3739
- 36: [function (require, module, exports) {
2958
+ 23: [function (require, module, exports) {
3740
2959
  /*
3741
2960
  object-assign
3742
2961
  (c) Sindre Sorhus
@@ -3819,7 +3038,7 @@
3819
3038
  return to;
3820
3039
  };
3821
3040
  }, {}],
3822
- 37: [function (require, module, exports) {
3041
+ 24: [function (require, module, exports) {
3823
3042
  // shim for using process in browser
3824
3043
  var process = module.exports = {};
3825
3044
 
@@ -3996,7 +3215,7 @@
3996
3215
  return 0;
3997
3216
  };
3998
3217
  }, {}],
3999
- 38: [function (require, module, exports) {
3218
+ 25: [function (require, module, exports) {
4000
3219
  'use strict';
4001
3220
 
4002
3221
  var parse = require('ret');
@@ -4042,9 +3261,9 @@
4042
3261
  return {}.toString.call(x) === '[object RegExp]';
4043
3262
  }
4044
3263
  }, {
4045
- "ret": 39
3264
+ "ret": 26
4046
3265
  }],
4047
- 39: [function (require, module, exports) {
3266
+ 26: [function (require, module, exports) {
4048
3267
  const util = require('./util');
4049
3268
  const types = require('./types');
4050
3269
  const sets = require('./sets');
@@ -4062,7 +3281,7 @@
4062
3281
  last = start.stack,
4063
3282
  groupStack = [];
4064
3283
  var repeatErr = i => {
4065
- util.error(regexpStr, `Nothing to repeat at column ${i - 1}`);
3284
+ util.error(regexpStr, "Nothing to repeat at column ".concat(i - 1));
4066
3285
  };
4067
3286
 
4068
3287
  // Decode a few escaped characters.
@@ -4179,7 +3398,7 @@
4179
3398
  } else if (c === '!') {
4180
3399
  group.notFollowedBy = true;
4181
3400
  } else if (c !== ':') {
4182
- util.error(regexpStr, `Invalid group, character '${c}'` + ` after '?' at column ${i - 1}`);
3401
+ util.error(regexpStr, "Invalid group, character '".concat(c, "'") + " after '?' at column ".concat(i - 1));
4183
3402
  }
4184
3403
  group.remember = false;
4185
3404
  }
@@ -4198,7 +3417,7 @@
4198
3417
  // Pop group out of stack.
4199
3418
  case ')':
4200
3419
  if (groupStack.length === 0) {
4201
- util.error(regexpStr, `Unmatched ) at column ${i - 1}`);
3420
+ util.error(regexpStr, "Unmatched ) at column ".concat(i - 1));
4202
3421
  }
4203
3422
  lastGroup = groupStack.pop();
4204
3423
 
@@ -4302,12 +3521,12 @@
4302
3521
  };
4303
3522
  module.exports.types = types;
4304
3523
  }, {
4305
- "./positions": 40,
4306
- "./sets": 41,
4307
- "./types": 42,
4308
- "./util": 43
3524
+ "./positions": 27,
3525
+ "./sets": 28,
3526
+ "./types": 29,
3527
+ "./util": 30
4309
3528
  }],
4310
- 40: [function (require, module, exports) {
3529
+ 27: [function (require, module, exports) {
4311
3530
  const types = require('./types');
4312
3531
  exports.wordBoundary = () => ({
4313
3532
  type: types.POSITION,
@@ -4326,9 +3545,9 @@
4326
3545
  value: '$'
4327
3546
  });
4328
3547
  }, {
4329
- "./types": 42
3548
+ "./types": 29
4330
3549
  }],
4331
- 41: [function (require, module, exports) {
3550
+ 28: [function (require, module, exports) {
4332
3551
  const types = require('./types');
4333
3552
  const INTS = () => [{
4334
3553
  type: types.RANGE,
@@ -4451,9 +3670,9 @@
4451
3670
  not: true
4452
3671
  });
4453
3672
  }, {
4454
- "./types": 42
3673
+ "./types": 29
4455
3674
  }],
4456
- 42: [function (require, module, exports) {
3675
+ 29: [function (require, module, exports) {
4457
3676
  module.exports = {
4458
3677
  ROOT: 0,
4459
3678
  GROUP: 1,
@@ -4465,7 +3684,7 @@
4465
3684
  CHAR: 7
4466
3685
  };
4467
3686
  }, {}],
4468
- 43: [function (require, module, exports) {
3687
+ 30: [function (require, module, exports) {
4469
3688
  const types = require('./types');
4470
3689
  const sets = require('./sets');
4471
3690
  const CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?';
@@ -4558,102 +3777,10 @@
4558
3777
  throw new SyntaxError('Invalid regular expression: /' + regexp + '/: ' + msg);
4559
3778
  };
4560
3779
  }, {
4561
- "./sets": 41,
4562
- "./types": 42
4563
- }],
4564
- 44: [function (require, module, exports) {
4565
- (function (setImmediate, clearImmediate) {
4566
- (function () {
4567
- var nextTick = require('process/browser.js').nextTick;
4568
- var apply = Function.prototype.apply;
4569
- var slice = Array.prototype.slice;
4570
- var immediateIds = {};
4571
- var nextImmediateId = 0;
4572
-
4573
- // DOM APIs, for completeness
4574
-
4575
- exports.setTimeout = function () {
4576
- return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
4577
- };
4578
- exports.setInterval = function () {
4579
- return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
4580
- };
4581
- exports.clearTimeout = exports.clearInterval = function (timeout) {
4582
- timeout.close();
4583
- };
4584
- function Timeout(id, clearFn) {
4585
- this._id = id;
4586
- this._clearFn = clearFn;
4587
- }
4588
- Timeout.prototype.unref = Timeout.prototype.ref = function () {};
4589
- Timeout.prototype.close = function () {
4590
- this._clearFn.call(window, this._id);
4591
- };
4592
-
4593
- // Does not start the time, just sets up the members needed.
4594
- exports.enroll = function (item, msecs) {
4595
- clearTimeout(item._idleTimeoutId);
4596
- item._idleTimeout = msecs;
4597
- };
4598
- exports.unenroll = function (item) {
4599
- clearTimeout(item._idleTimeoutId);
4600
- item._idleTimeout = -1;
4601
- };
4602
- exports._unrefActive = exports.active = function (item) {
4603
- clearTimeout(item._idleTimeoutId);
4604
- var msecs = item._idleTimeout;
4605
- if (msecs >= 0) {
4606
- item._idleTimeoutId = setTimeout(function onTimeout() {
4607
- if (item._onTimeout) item._onTimeout();
4608
- }, msecs);
4609
- }
4610
- };
4611
-
4612
- // That's not how node.js implements it but the exposed api is the same.
4613
- exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function (fn) {
4614
- var id = nextImmediateId++;
4615
- var args = arguments.length < 2 ? false : slice.call(arguments, 1);
4616
- immediateIds[id] = true;
4617
- nextTick(function onNextTick() {
4618
- if (immediateIds[id]) {
4619
- // fn.call() is faster so we optimize for the common use-case
4620
- // @see http://jsperf.com/call-apply-segu
4621
- if (args) {
4622
- fn.apply(null, args);
4623
- } else {
4624
- fn.call(null);
4625
- }
4626
- // Prevent ids from leaking
4627
- exports.clearImmediate(id);
4628
- }
4629
- });
4630
- return id;
4631
- };
4632
- exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function (id) {
4633
- delete immediateIds[id];
4634
- };
4635
- }).call(this);
4636
- }).call(this, require("timers").setImmediate, require("timers").clearImmediate);
4637
- }, {
4638
- "process/browser.js": 37,
4639
- "timers": 44
4640
- }],
4641
- 45: [function (require, module, exports) {
4642
- /**
4643
- * Simple browser shim loader - assign the npm module to a window global automatically
4644
- *
4645
- * @license MIT
4646
- * @author <steven@velozo.com>
4647
- */
4648
- var libNPMModuleWrapper = require('./Orator.js');
4649
- if (typeof window === 'object' && !window.hasOwnProperty('Orator')) {
4650
- window.Orator = libNPMModuleWrapper;
4651
- }
4652
- module.exports = libNPMModuleWrapper;
4653
- }, {
4654
- "./Orator.js": 52
3780
+ "./sets": 28,
3781
+ "./types": 29
4655
3782
  }],
4656
- 46: [function (require, module, exports) {
3783
+ 31: [function (require, module, exports) {
4657
3784
  // Simple default configuration for application, when none is provided
4658
3785
 
4659
3786
  module.exports = {
@@ -4662,35 +3789,24 @@
4662
3789
  "ServicePort": 8080
4663
3790
  };
4664
3791
  }, {}],
4665
- 47: [function (require, module, exports) {
3792
+ 32: [function (require, module, exports) {
4666
3793
  /**
4667
- * Default Service Server Function
4668
- *
4669
- * @license MIT
4670
- *
4671
- * @author Steven Velozo <steven@velozo.com>
3794
+ * Default Service Server
4672
3795
  */
4673
-
4674
- // Return the servers that are available without extensions loaded
4675
- getDefaultServiceServers = () => {
4676
- let tmpDefaultServiceServers = {};
4677
- tmpDefaultServiceServers.ipc = require('./Orator-ServiceServer-IPC.js');
4678
- tmpDefaultServiceServers.default = tmpDefaultServiceServers.ipc;
4679
- return tmpDefaultServiceServers;
4680
- };
4681
- module.exports = getDefaultServiceServers();
3796
+ module.exports = require('./Orator-ServiceServer-IPC.js');
4682
3797
  }, {
4683
- "./Orator-ServiceServer-IPC.js": 51
3798
+ "./Orator-ServiceServer-IPC.js": 35
4684
3799
  }],
4685
- 48: [function (require, module, exports) {
4686
- class OratorServiceServerBase {
4687
- constructor(pOrator) {
4688
- this.orator = pOrator;
4689
- this.log = pOrator.log;
3800
+ 33: [function (require, module, exports) {
3801
+ const libFableServiceProviderBase = require('fable-serviceproviderbase');
3802
+ class OratorServiceServerBase extends libFableServiceProviderBase {
3803
+ constructor(pFable, pOptions, pServiceHash) {
3804
+ super(pFable, pOptions, pServiceHash);
3805
+ this.serviceType = 'OratorServiceServer';
4690
3806
  this.ServiceServerType = 'Base';
4691
- this.Name = this.orator.settings.Product;
3807
+ this.Name = this.fable.settings.Product;
4692
3808
  this.URL = 'BASE_SERVICE_SERVER';
4693
- this.Port = this.orator.settings.ServicePort;
3809
+ this.Port = this.options.ServicePort;
4694
3810
  this.Active = false;
4695
3811
  }
4696
3812
 
@@ -4743,100 +3859,139 @@
4743
3859
  *************************************************************************/
4744
3860
  use(fHandlerFunction) {
4745
3861
  if (typeof fHandlerFunction != 'function') {
4746
- this.log.error(`Orator USE global handler mapping failed -- parameter was expected to be a function with prototype function(Request, Response, Next) but type was ${typeof fHandlerFunction} instead of a string.`);
3862
+ this.log.error("Orator USE global handler mapping failed -- parameter was expected to be a function with prototype function(Request, Response, Next) but type was ".concat(typeof fHandlerFunction, " instead of a string."));
4747
3863
  return false;
4748
3864
  }
4749
3865
  return true;
4750
3866
  }
4751
- doGet(pRoute, ...fRouteProcessingFunctions) {
3867
+ doGet(pRoute) {
4752
3868
  return true;
4753
3869
  }
4754
- get(pRoute, ...fRouteProcessingFunctions) {
3870
+ get(pRoute) {
4755
3871
  if (typeof pRoute != 'string') {
4756
- this.log.error(`Orator GET Route mapping failed -- route parameter was ${typeof pRoute} instead of a string.`);
3872
+ this.log.error("Orator GET Route mapping failed -- route parameter was ".concat(typeof pRoute, " instead of a string."));
4757
3873
  return false;
4758
3874
  }
3875
+ for (var _len = arguments.length, fRouteProcessingFunctions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
3876
+ fRouteProcessingFunctions[_key - 1] = arguments[_key];
3877
+ }
4759
3878
  return this.doGet(pRoute, ...fRouteProcessingFunctions);
4760
3879
  }
4761
- getWithBodyParser(pRoute, ...fRouteProcessingFunctions) {
3880
+ getWithBodyParser(pRoute) {
3881
+ for (var _len2 = arguments.length, fRouteProcessingFunctions = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
3882
+ fRouteProcessingFunctions[_key2 - 1] = arguments[_key2];
3883
+ }
4762
3884
  return this.get(pRoute, this.bodyParser(), ...fRouteProcessingFunctions);
4763
3885
  }
4764
- doPut(pRoute, ...fRouteProcessingFunctions) {
3886
+ doPut(pRoute) {
4765
3887
  return true;
4766
3888
  }
4767
- put(pRoute, ...fRouteProcessingFunctions) {
3889
+ put(pRoute) {
4768
3890
  if (typeof pRoute != 'string') {
4769
- this.log.error(`Orator PUT Route mapping failed -- route parameter was ${typeof pRoute} instead of a string.`);
3891
+ this.log.error("Orator PUT Route mapping failed -- route parameter was ".concat(typeof pRoute, " instead of a string."));
4770
3892
  return false;
4771
3893
  }
3894
+ for (var _len3 = arguments.length, fRouteProcessingFunctions = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
3895
+ fRouteProcessingFunctions[_key3 - 1] = arguments[_key3];
3896
+ }
4772
3897
  return this.doPut(pRoute, ...fRouteProcessingFunctions);
4773
3898
  }
4774
- putWithBodyParser(pRoute, ...fRouteProcessingFunctions) {
3899
+ putWithBodyParser(pRoute) {
3900
+ for (var _len4 = arguments.length, fRouteProcessingFunctions = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
3901
+ fRouteProcessingFunctions[_key4 - 1] = arguments[_key4];
3902
+ }
4775
3903
  return this.put(pRoute, this.bodyParser(), ...fRouteProcessingFunctions);
4776
3904
  }
4777
- doPost(pRoute, ...fRouteProcessingFunctions) {
3905
+ doPost(pRoute) {
4778
3906
  return true;
4779
3907
  }
4780
- post(pRoute, ...fRouteProcessingFunctions) {
3908
+ post(pRoute) {
4781
3909
  if (typeof pRoute != 'string') {
4782
- this.log.error(`Orator POST Route mapping failed -- route parameter was ${typeof pRoute} instead of a string.`);
3910
+ this.log.error("Orator POST Route mapping failed -- route parameter was ".concat(typeof pRoute, " instead of a string."));
4783
3911
  return false;
4784
3912
  }
3913
+ for (var _len5 = arguments.length, fRouteProcessingFunctions = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
3914
+ fRouteProcessingFunctions[_key5 - 1] = arguments[_key5];
3915
+ }
4785
3916
  return this.doPost(pRoute, ...fRouteProcessingFunctions);
4786
3917
  }
4787
- postWithBodyParser(pRoute, ...fRouteProcessingFunctions) {
3918
+ postWithBodyParser(pRoute) {
3919
+ for (var _len6 = arguments.length, fRouteProcessingFunctions = new Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) {
3920
+ fRouteProcessingFunctions[_key6 - 1] = arguments[_key6];
3921
+ }
4788
3922
  return this.post(pRoute, this.bodyParser(), ...fRouteProcessingFunctions);
4789
3923
  }
4790
- doDel(pRoute, ...fRouteProcessingFunctions) {
3924
+ doDel(pRoute) {
4791
3925
  return true;
4792
3926
  }
4793
- del(pRoute, ...fRouteProcessingFunctions) {
3927
+ del(pRoute) {
4794
3928
  if (typeof pRoute != 'string') {
4795
- this.log.error(`Orator DEL Route mapping failed -- route parameter was ${typeof pRoute} instead of a string.`);
3929
+ this.log.error("Orator DEL Route mapping failed -- route parameter was ".concat(typeof pRoute, " instead of a string."));
4796
3930
  return false;
4797
3931
  }
3932
+ for (var _len7 = arguments.length, fRouteProcessingFunctions = new Array(_len7 > 1 ? _len7 - 1 : 0), _key7 = 1; _key7 < _len7; _key7++) {
3933
+ fRouteProcessingFunctions[_key7 - 1] = arguments[_key7];
3934
+ }
4798
3935
  return this.doDel(pRoute, ...fRouteProcessingFunctions);
4799
3936
  }
4800
- delWithBodyParser(pRoute, ...fRouteProcessingFunctions) {
3937
+ delWithBodyParser(pRoute) {
3938
+ for (var _len8 = arguments.length, fRouteProcessingFunctions = new Array(_len8 > 1 ? _len8 - 1 : 0), _key8 = 1; _key8 < _len8; _key8++) {
3939
+ fRouteProcessingFunctions[_key8 - 1] = arguments[_key8];
3940
+ }
4801
3941
  return this.del(pRoute, this.bodyParser(), ...fRouteProcessingFunctions);
4802
3942
  }
4803
- doPatch(pRoute, ...fRouteProcessingFunctions) {
3943
+ doPatch(pRoute) {
4804
3944
  return true;
4805
3945
  }
4806
- patch(pRoute, ...fRouteProcessingFunctions) {
3946
+ patch(pRoute) {
4807
3947
  if (typeof pRoute != 'string') {
4808
- this.log.error(`Orator PATCH Route mapping failed -- route parameter was ${typeof pRoute} instead of a string.`);
3948
+ this.log.error("Orator PATCH Route mapping failed -- route parameter was ".concat(typeof pRoute, " instead of a string."));
4809
3949
  return false;
4810
3950
  }
3951
+ for (var _len9 = arguments.length, fRouteProcessingFunctions = new Array(_len9 > 1 ? _len9 - 1 : 0), _key9 = 1; _key9 < _len9; _key9++) {
3952
+ fRouteProcessingFunctions[_key9 - 1] = arguments[_key9];
3953
+ }
4811
3954
  return this.doPatch(pRoute, ...fRouteProcessingFunctions);
4812
3955
  }
4813
- patchWithBodyParser(pRoute, ...fRouteProcessingFunctions) {
3956
+ patchWithBodyParser(pRoute) {
3957
+ for (var _len10 = arguments.length, fRouteProcessingFunctions = new Array(_len10 > 1 ? _len10 - 1 : 0), _key10 = 1; _key10 < _len10; _key10++) {
3958
+ fRouteProcessingFunctions[_key10 - 1] = arguments[_key10];
3959
+ }
4814
3960
  return this.patch(pRoute, this.bodyParser(), ...fRouteProcessingFunctions);
4815
3961
  }
4816
- doOpts(pRoute, ...fRouteProcessingFunctions) {
3962
+ doOpts(pRoute) {
4817
3963
  return true;
4818
3964
  }
4819
- opts(pRoute, ...fRouteProcessingFunctions) {
3965
+ opts(pRoute) {
4820
3966
  if (typeof pRoute != 'string') {
4821
- this.log.error(`Orator OPTS Route mapping failed -- route parameter was ${typeof pRoute} instead of a string.`);
3967
+ this.log.error("Orator OPTS Route mapping failed -- route parameter was ".concat(typeof pRoute, " instead of a string."));
4822
3968
  return false;
4823
3969
  }
3970
+ for (var _len11 = arguments.length, fRouteProcessingFunctions = new Array(_len11 > 1 ? _len11 - 1 : 0), _key11 = 1; _key11 < _len11; _key11++) {
3971
+ fRouteProcessingFunctions[_key11 - 1] = arguments[_key11];
3972
+ }
4824
3973
  return this.doOpts(pRoute, ...fRouteProcessingFunctions);
4825
3974
  }
4826
- optsWithBodyParser(pRoute, ...fRouteProcessingFunctions) {
3975
+ optsWithBodyParser(pRoute) {
3976
+ for (var _len12 = arguments.length, fRouteProcessingFunctions = new Array(_len12 > 1 ? _len12 - 1 : 0), _key12 = 1; _key12 < _len12; _key12++) {
3977
+ fRouteProcessingFunctions[_key12 - 1] = arguments[_key12];
3978
+ }
4827
3979
  return this.opts(pRoute, this.bodyParser(), ...fRouteProcessingFunctions);
4828
3980
  }
4829
- doHead(pRoute, ...fRouteProcessingFunctions) {
3981
+ doHead(pRoute) {
4830
3982
  return true;
4831
3983
  }
4832
- head(pRoute, ...fRouteProcessingFunctions) {
3984
+ head(pRoute) {
4833
3985
  if (typeof pRoute != 'string') {
4834
- this.log.error(`Orator HEAD Route mapping failed -- route parameter was ${typeof pRoute} instead of a string.`);
3986
+ this.log.error("Orator HEAD Route mapping failed -- route parameter was ".concat(typeof pRoute, " instead of a string."));
4835
3987
  return false;
4836
3988
  }
4837
3989
  return true;
4838
3990
  }
4839
- headWithBodyParser(pRoute, ...fRouteProcessingFunctions) {
3991
+ headWithBodyParser(pRoute) {
3992
+ for (var _len13 = arguments.length, fRouteProcessingFunctions = new Array(_len13 > 1 ? _len13 - 1 : 0), _key13 = 1; _key13 < _len13; _key13++) {
3993
+ fRouteProcessingFunctions[_key13 - 1] = arguments[_key13];
3994
+ }
4840
3995
  return this.head(pRoute, this.bodyParser(), ...fRouteProcessingFunctions);
4841
3996
  }
4842
3997
  /*************************************************************************
@@ -4846,47 +4001,28 @@
4846
4001
  // Programmatically invoke a route
4847
4002
  invoke(pMethod, pRoute, pData, fCallback) {
4848
4003
  // The base class version of this does nothing
4849
- this.log.debug(`Orator invoke called for route [${pRoute}] and landed on the base class; the service provider likely does not implement programmatic invoke capabilities.`, pData);
4004
+ this.log.debug("Orator invoke called for route [".concat(pRoute, "] and landed on the base class; the service provider likely does not implement programmatic invoke capabilities."), pData);
4850
4005
  return false;
4851
4006
  }
4852
4007
  }
4853
4008
  module.exports = OratorServiceServerBase;
4854
- }, {}],
4855
- 49: [function (require, module, exports) {
4856
- 'use strict';
4857
-
4858
- // This is taken directly from the find-my-way documentation for custom constraints and only mildly edited
4859
- const ipcResponseTypeStrategy = {
4860
- // strategy name for referencing in the route handler `constraints` options
4861
- name: 'ipc',
4862
- isAsync: true,
4863
- // storage factory for storing routes in the find-my-way route tree
4864
- storage: () => {
4865
- let handlers = {};
4866
- return {
4867
- get: type => {
4868
- return handlers[type] || null;
4869
- },
4870
- set: (type, store) => {
4871
- handlers[type] = store;
4872
- }
4873
- };
4874
- },
4875
- // function to get the value of the constraint from each incoming request
4876
- deriveConstraint: (pRequest, pContext, fDone) => {
4877
- // If we wanted to deny the IPC request based on a constraint, we would do:
4878
- // fDone(new Error(`The request was denied because ____ in the Request object wasn't right...`));
4879
- return fDone(null, 'IPC');
4880
- },
4881
- // optional flag marking if handlers without constraints can match requests that have a value for this constraint
4882
- mustMatchWhenDerived: true
4883
- };
4884
- module.exports = ipcResponseTypeStrategy;
4885
- }, {}],
4886
- 50: [function (require, module, exports) {
4009
+ }, {
4010
+ "fable-serviceproviderbase": 6
4011
+ }],
4012
+ 34: [function (require, module, exports) {
4887
4013
  class OratorServiceServerIPCSynthesizedResponse {
4888
- constructor(pLog, pRequestGUID) {
4014
+ constructor(pHandler, pLog, pRequestGUID) {
4889
4015
  this.log = pLog;
4016
+ if (pHandler.hasOwnProperty('params')) {
4017
+ this.params = pHandler.params;
4018
+ } else {
4019
+ this.params = {};
4020
+ }
4021
+ if (pHandler.hasOwnProperty('searchParams')) {
4022
+ this.searchParams = pHandler.searchParams;
4023
+ } else {
4024
+ this.searchParams = {};
4025
+ }
4890
4026
  this.requestGUID = pRequestGUID;
4891
4027
  this.responseData = null;
4892
4028
  this.responseStatus = -1;
@@ -4901,7 +4037,7 @@
4901
4037
  this.responseData = this.responseData + pData;
4902
4038
  return true;
4903
4039
  } else {
4904
- this.log(`Request ${this.requestGUID} has tried to send() a string value after send()ing data type ${typeof this.responseData}.`, pData);
4040
+ this.log("Request ".concat(this.requestGUID, " has tried to send() a string value after send()ing data type ").concat(typeof this.responseData, "."), pData);
4905
4041
  return false;
4906
4042
  }
4907
4043
  } else if (typeof pData == 'object') {
@@ -4913,7 +4049,7 @@
4913
4049
  this.responseData += this.responseData + JSON.stringify(pData);
4914
4050
  return true;
4915
4051
  } else {
4916
- this.log(`Request ${this.requestGUID} has tried to send() an object value to be auto stringified after send()ing data type ${typeof this.responseData}.`, pData);
4052
+ this.log("Request ".concat(this.requestGUID, " has tried to send() an object value to be auto stringified after send()ing data type ").concat(typeof this.responseData, "."), pData);
4917
4053
  return false;
4918
4054
  }
4919
4055
  }
@@ -4921,68 +4057,74 @@
4921
4057
  }
4922
4058
  module.exports = OratorServiceServerIPCSynthesizedResponse;
4923
4059
  }, {}],
4924
- 51: [function (require, module, exports) {
4060
+ 35: [function (require, module, exports) {
4925
4061
  const libOratorServiceServerBase = require('./Orator-ServiceServer-Base.js');
4926
4062
 
4927
4063
  // A synthesized response object, for simple IPC.
4928
4064
  const libOratorServiceServerIPCSynthesizedResponse = require('./Orator-ServiceServer-IPC-SynthesizedResponse.js');
4929
4065
  // A simple constrainer for the find-my-way router since we aren't using any kind of headers to pass version or host
4930
- const libOratorServiceServerIPCCustomConstrainer = require('./Orator-ServiceServer-IPC-RouterConstrainer.js');
4066
+ //const libOratorServiceServerIPCCustomConstrainer = require('./Orator-ServiceServer-IPC-RouterConstrainer.js');
4931
4067
 
4932
4068
  // This library is the default router for our services
4933
4069
  const libFindMyWay = require('find-my-way');
4934
- //const libAsync = require('async');
4935
- const libAsyncWaterfall = require("async/waterfall");
4936
- const libAsyncEachOfSeries = require('async/eachOfSeries');
4937
4070
  class OratorServiceServerIPC extends libOratorServiceServerBase {
4938
- constructor(pOrator) {
4939
- super(pOrator);
4940
- this.routerOptions = this.orator.settings.hasOwnProperty('router_options') && typeof this.orator.settings.router_options == 'object' ? this.orator.settings.router_options : {};
4941
- this.router = libFindMyWay(this.routerOptions);
4942
- this.router.addConstraintStrategy(libOratorServiceServerIPCCustomConstrainer);
4071
+ constructor(pFable, pOptions, pServiceHash) {
4072
+ super(pFable, pOptions, pServiceHash);
4073
+ this.router = libFindMyWay(this.options);
4074
+ //this.router.addConstraintStrategy(libOratorServiceServerIPCCustomConstrainer);
4075
+
4943
4076
  this.ServiceServerType = 'IPC';
4944
4077
  this.URL = 'IPC';
4078
+ this.Port = 0;
4945
4079
  this.preBehaviorFunctions = [];
4946
4080
  this.behaviorMap = {};
4947
4081
  this.postBehaviorFunctions = [];
4948
4082
  }
4949
4083
  use(fHandlerFunction) {
4950
- if (!super.use(fHandlerFunction)) {
4951
- this.log.error(`IPC provider failed to map USE handler function!`);
4952
- return false;
4953
- }
4954
- this.preBehaviorFunctions.push(fHandlerFunction);
4084
+ return this.addPreBehaviorFunction(fHandlerFunction);
4955
4085
  }
4956
- addPostBehaviorFunction(fHandlerFunction) {
4086
+ addPreBehaviorFunction(fHandlerFunction) {
4957
4087
  if (!super.use(fHandlerFunction)) {
4958
- this.log.error(`IPC provider failed to map USE handler function!`);
4088
+ this.log.error("IPC provider failed to map USE handler function!");
4959
4089
  return false;
4960
4090
  }
4961
4091
  this.preBehaviorFunctions.push(fHandlerFunction);
4092
+ return true;
4962
4093
  }
4963
4094
  executePreBehaviorFunctions(pRequest, pResponse, fNext) {
4964
- libAsyncEachOfSeries(this.preBehaviorFunctions, (fBehaviorFunction, pFunctionIndex, fCallback) => {
4965
- return fBehaviorFunction(pRequest, pResponse, fCallback);
4966
- }, pError => {
4095
+ let tmpAnticipate = this.fable.serviceManager.instantiateServiceProviderWithoutRegistration('Anticipate');
4096
+ for (let i = 0; i < this.preBehaviorFunctions.length; i++) {
4097
+ let tmpPreBehaviorFunction = this.preBehaviorFunctions[i];
4098
+ tmpAnticipate.anticipate(fStageComplete => {
4099
+ return tmpPreBehaviorFunction(pRequest, pResponse, fStageComplete);
4100
+ });
4101
+ }
4102
+ tmpAnticipate.wait(pError => {
4967
4103
  if (pError) {
4968
- this.log.error(`IPC Provider preBehaviorFunction ${pFunctionIndex} failed with error: ${pError}`, pError);
4104
+ this.log.error("IPC Provider preBehaviorFunction ".concat(pFunctionIndex, " failed with error: ").concat(pError), pError);
4969
4105
  }
4970
4106
  return fNext(pError);
4971
4107
  });
4972
4108
  }
4973
4109
  addPostBehaviorFunction(fHandlerFunction) {
4974
4110
  if (!super.use(fHandlerFunction)) {
4975
- this.log.error(`IPC provider failed to map USE handler function!`);
4111
+ this.log.error("IPC provider failed to map USE handler function!");
4976
4112
  return false;
4977
4113
  }
4978
- this.preBehaviorFunctions.push(fHandlerFunction);
4114
+ this.postBehaviorFunctions.push(fHandlerFunction);
4115
+ return true;
4979
4116
  }
4980
4117
  executePostBehaviorFunctions(pRequest, pResponse, fNext) {
4981
- libAsyncEachOfSeries(this.postBehaviorFunctions, (fBehaviorFunction, pFunctionIndex, fCallback) => {
4982
- return fBehaviorFunction(pRequest, pResponse, fCallback);
4983
- }, pError => {
4118
+ let tmpAnticipate = this.fable.serviceManager.instantiateServiceProviderWithoutRegistration('Anticipate');
4119
+ for (let i = 0; i < this.postBehaviorFunctions.length; i++) {
4120
+ let tmpPostBehaviorFunction = this.postBehaviorFunctions[i];
4121
+ tmpAnticipate.anticipate(fStageComplete => {
4122
+ return tmpPostBehaviorFunction(pRequest, pResponse, fStageComplete);
4123
+ });
4124
+ }
4125
+ tmpAnticipate.wait(pError => {
4984
4126
  if (pError) {
4985
- this.log.error(`IPC Provider postBehaviorFunction ${pFunctionIndex} failed with error: ${pError}`, pError);
4127
+ this.log.error("IPC Provider postBehaviorFunction ".concat(pFunctionIndex, " failed with error: ").concat(pError), pError);
4986
4128
  }
4987
4129
  return fNext(pError);
4988
4130
  });
@@ -5005,35 +4147,35 @@
5005
4147
  addRouteProcessor(pMethod, pRoute, pRouteFunctionArray) {
5006
4148
  // We have a constrainer on IPC so we can control channels eventually, if we like.
5007
4149
  // For now it just makes sure it was added with an IPC service server.
5008
- this.router.on(pMethod, pRoute, {
5009
- constraints: {
5010
- "ipc": "IPC"
4150
+ this.router.on(pMethod, pRoute, this.buildFindMyWayHandler(pRouteFunctionArray));
4151
+ return true;
4152
+ }
4153
+ buildFindMyWayHandler(pRouteFunctionArray) {
4154
+ let tmpRouteFunctionArray = pRouteFunctionArray;
4155
+ return (pRequest, pResponse, pData) => {
4156
+ let tmpAnticipate = this.fable.serviceManager.instantiateServiceProviderWithoutRegistration('Anticipate');
4157
+ tmpAnticipate.anticipate(fNext => {
4158
+ return this.executePreBehaviorFunctions(pRequest, pResponse, fNext);
4159
+ });
4160
+ for (let i = 0; i < tmpRouteFunctionArray.length; i++) {
4161
+ let tmpRouteFunction = tmpRouteFunctionArray[i];
4162
+ tmpAnticipate.anticipate(fNext => {
4163
+ return tmpRouteFunction(pRequest, pResponse, fNext);
4164
+ });
5011
4165
  }
5012
- }, (pRequest, pResponse, pParameters) => {
5013
- libAsyncWaterfall([fStageComplete => {
5014
- // Added to make this mimic what we saw with route parsing in the old restify
5015
- pRequest.params = pParameters;
5016
- return fStageComplete();
5017
- }, fStageComplete => {
5018
- return this.executePreBehaviorFunctions(pRequest, pResponse, fStageComplete);
5019
- }, fStageComplete => {
5020
- libAsyncEachOfSeries(pRouteFunctionArray, (fBehaviorFunction, pFunctionIndex, fCallback) => {
5021
- return fBehaviorFunction(pRequest, pResponse, fCallback);
5022
- }, pBehaviorFunctionError => {
4166
+ tmpAnticipate.anticipate(fStageComplete => {
4167
+ return this.executePostBehaviorFunctions(pRequest, pResponse, fStageComplete);
4168
+ });
4169
+ return new Promise((fResolve, fReject) => {
4170
+ tmpAnticipate.wait(pBehaviorFunctionError => {
5023
4171
  if (pBehaviorFunctionError) {
5024
- this.log.error(`IPC Provider behavior function ${pFunctionIndex} failed with error: ${pBehaviorFunctionError}`, pBehaviorFunctionError);
5025
- return fNext(pError);
4172
+ this.log.error("IPC Provider behavior function ".concat(pFunctionIndex, " failed with error: ").concat(pBehaviorFunctionError), pBehaviorFunctionError);
4173
+ return fReject(pBehaviorFunctionError);
5026
4174
  }
4175
+ return fResolve();
5027
4176
  });
5028
- }, fStageComplete => {
5029
- return this.executePostBehaviorFunctions(pRequest, pResponse, fStageComplete);
5030
- }], pRequestError => {
5031
- if (pRequestError) {
5032
- this.log.error(`IPC Provider behavior function ${pFunctionIndex} failed with error: ${pBehaviorFunctionError}`, pBehaviorFunctionError);
5033
- }
5034
4177
  });
5035
- });
5036
- return true;
4178
+ };
5037
4179
  }
5038
4180
 
5039
4181
  // This is the virtualized "body parser"
@@ -5042,25 +4184,46 @@
5042
4184
  return fNext();
5043
4185
  };
5044
4186
  }
5045
- doGet(pRoute, ...fRouteProcessingFunctions) {
4187
+ doGet(pRoute) {
4188
+ for (var _len14 = arguments.length, fRouteProcessingFunctions = new Array(_len14 > 1 ? _len14 - 1 : 0), _key14 = 1; _key14 < _len14; _key14++) {
4189
+ fRouteProcessingFunctions[_key14 - 1] = arguments[_key14];
4190
+ }
5046
4191
  return this.addRouteProcessor('GET', pRoute, Array.from(fRouteProcessingFunctions));
5047
4192
  }
5048
- doPut(pRoute, ...fRouteProcessingFunctions) {
4193
+ doPut(pRoute) {
4194
+ for (var _len15 = arguments.length, fRouteProcessingFunctions = new Array(_len15 > 1 ? _len15 - 1 : 0), _key15 = 1; _key15 < _len15; _key15++) {
4195
+ fRouteProcessingFunctions[_key15 - 1] = arguments[_key15];
4196
+ }
5049
4197
  return this.addRouteProcessor('PUT', pRoute, Array.from(fRouteProcessingFunctions));
5050
4198
  }
5051
- doPost(pRoute, ...fRouteProcessingFunctions) {
4199
+ doPost(pRoute) {
4200
+ for (var _len16 = arguments.length, fRouteProcessingFunctions = new Array(_len16 > 1 ? _len16 - 1 : 0), _key16 = 1; _key16 < _len16; _key16++) {
4201
+ fRouteProcessingFunctions[_key16 - 1] = arguments[_key16];
4202
+ }
5052
4203
  return this.addRouteProcessor('POST', pRoute, Array.from(fRouteProcessingFunctions));
5053
4204
  }
5054
- doDel(pRoute, ...fRouteProcessingFunctions) {
5055
- return this.addRouteProcessor('DEL', pRoute, Array.from(fRouteProcessingFunctions));
4205
+ doDel(pRoute) {
4206
+ for (var _len17 = arguments.length, fRouteProcessingFunctions = new Array(_len17 > 1 ? _len17 - 1 : 0), _key17 = 1; _key17 < _len17; _key17++) {
4207
+ fRouteProcessingFunctions[_key17 - 1] = arguments[_key17];
4208
+ }
4209
+ return this.addRouteProcessor('DELETE', pRoute, Array.from(fRouteProcessingFunctions));
5056
4210
  }
5057
- doPatch(pRoute, ...fRouteProcessingFunctions) {
4211
+ doPatch(pRoute) {
4212
+ for (var _len18 = arguments.length, fRouteProcessingFunctions = new Array(_len18 > 1 ? _len18 - 1 : 0), _key18 = 1; _key18 < _len18; _key18++) {
4213
+ fRouteProcessingFunctions[_key18 - 1] = arguments[_key18];
4214
+ }
5058
4215
  return this.addRouteProcessor('PATCH', pRoute, Array.from(fRouteProcessingFunctions));
5059
4216
  }
5060
- doOpts(pRoute, ...fRouteProcessingFunctions) {
5061
- return this.addRouteProcessor('OPTS', pRoute, Array.from(fRouteProcessingFunctions));
4217
+ doOpts(pRoute) {
4218
+ for (var _len19 = arguments.length, fRouteProcessingFunctions = new Array(_len19 > 1 ? _len19 - 1 : 0), _key19 = 1; _key19 < _len19; _key19++) {
4219
+ fRouteProcessingFunctions[_key19 - 1] = arguments[_key19];
4220
+ }
4221
+ return this.addRouteProcessor('OPTIONS', pRoute, Array.from(fRouteProcessingFunctions));
5062
4222
  }
5063
- doHead(pRoute, ...fRouteProcessingFunctions) {
4223
+ doHead(pRoute) {
4224
+ for (var _len20 = arguments.length, fRouteProcessingFunctions = new Array(_len20 > 1 ? _len20 - 1 : 0), _key20 = 1; _key20 < _len20; _key20++) {
4225
+ fRouteProcessingFunctions[_key20 - 1] = arguments[_key20];
4226
+ }
5064
4227
  return this.addRouteProcessor('HEAD', pRoute, Array.from(fRouteProcessingFunctions));
5065
4228
  }
5066
4229
  /*************************************************************************
@@ -5070,43 +4233,55 @@
5070
4233
  // Programmatically invoke a route
5071
4234
  invoke(pMethod, pRoute, pData, fCallback) {
5072
4235
  // If the data is skipped and a callback is parameter 3, do the right thing
5073
- let tmpCallback = typeof fCallback == 'function' ? fCallback : typeof pData == 'function' ? pData :
5074
- // This is here in case the developer passed no callback and just wants to fire and forget the IPC call which might not be async safe
5075
- () => {};
4236
+ let tmpCallback = typeof fCallback == 'function' ? fCallback : typeof pData == 'function' ? pData : false;
4237
+ if (!tmpCallback) {
4238
+ throw new Error("IPC Provider invoke() called without a callback function.");
4239
+ }
5076
4240
 
5077
4241
  // Create a bare minimum request object for IPC to pass to our router
5078
4242
  let tmpRequest = {
5079
4243
  method: pMethod,
5080
4244
  url: pRoute,
5081
- guid: this.orator.fable.getUUID()
4245
+ guid: this.fable.getUUID()
5082
4246
  };
5083
4247
 
4248
+ // For now, dealing with no handler constraints.
4249
+ let tmpHandler = this.router.find(tmpRequest.method, tmpRequest.url);
4250
+
5084
4251
  // Create a container for the IPC response data to be aggregated to from send() methodds
5085
- let tmpSynthesizedResponseData = new libOratorServiceServerIPCSynthesizedResponse(this.log, tmpRequest.guid);
5086
- return this.router.lookup(tmpRequest, tmpSynthesizedResponseData, (pError, pResults) => {
4252
+ let tmpSynthesizedResponseData = new libOratorServiceServerIPCSynthesizedResponse(tmpHandler, this.log, tmpRequest.guid);
4253
+
4254
+ // Map parsed params back to the request object
4255
+ tmpRequest.params = tmpSynthesizedResponseData.params;
4256
+ tmpRequest.searchParams = tmpSynthesizedResponseData.searchParams;
4257
+
4258
+ //params: handle._createParamsObject(params)//,
4259
+ //searchParams: this.querystringParser(querystring)
4260
+
4261
+ tmpHandler.handler(tmpRequest, tmpSynthesizedResponseData, pData).then(pResults => {
4262
+ return tmpCallback(null, tmpSynthesizedResponseData.responseData, tmpSynthesizedResponseData, pResults);
4263
+ }, pError => {
4264
+ this.log.trace('IPC Response Received', {
4265
+ Error: pError
4266
+ });
5087
4267
  if (pError) {
5088
- this.log.error(`IPC Request Error Request GUID [${tmpRequest.guid}] handling route [${pRoute}]: ${pError}`, {
4268
+ this.log.error("IPC Request Error Request GUID [".concat(tmpRequest.guid, "] handling route [").concat(pRoute, "]: ").concat(pError), {
5089
4269
  Error: pError,
5090
4270
  Route: pRoute,
5091
4271
  Data: pData
5092
4272
  });
5093
4273
  }
5094
-
5095
- // by default, send data back through
5096
- return tmpCallback(pError, tmpSynthesizedResponseData.responseData, tmpSynthesizedResponseData, pResults);
4274
+ return tmpCallback(pError, tmpSynthesizedResponseData.responseData, tmpSynthesizedResponseData);
5097
4275
  });
5098
4276
  }
5099
4277
  }
5100
4278
  module.exports = OratorServiceServerIPC;
5101
4279
  }, {
5102
- "./Orator-ServiceServer-Base.js": 48,
5103
- "./Orator-ServiceServer-IPC-RouterConstrainer.js": 49,
5104
- "./Orator-ServiceServer-IPC-SynthesizedResponse.js": 50,
5105
- "async/eachOfSeries": 7,
5106
- "async/waterfall": 20,
5107
- "find-my-way": 29
4280
+ "./Orator-ServiceServer-Base.js": 33,
4281
+ "./Orator-ServiceServer-IPC-SynthesizedResponse.js": 34,
4282
+ "find-my-way": 13
5108
4283
  }],
5109
- 52: [function (require, module, exports) {
4284
+ 36: [function (require, module, exports) {
5110
4285
  /**
5111
4286
  * Orator Service Abstraction
5112
4287
  *
@@ -5116,16 +4291,13 @@
5116
4291
  * @module Orator Service
5117
4292
  */
5118
4293
 
4294
+ const libFableServiceProviderBase = require('fable-serviceproviderbase');
4295
+ const libDefaultOratorServiceServer = require('./Orator-Default-ServiceServer.js');
5119
4296
  const defaultOratorConfiguration = require('./Orator-Default-Configuration.js');
5120
- const defaultOratorServiceServers = require('./Orator-Default-ServiceServers-Node.js');
5121
- class Orator {
5122
- constructor(pFable, pServiceProvider) {
5123
- // We were passed a fully operational fable -- use this
5124
- this.fable = pFable;
5125
-
5126
- // Carry core application requirements into the orator object for simplicity
5127
- this.settings = this.fable.settings;
5128
- this.log = this.fable.log;
4297
+ class Orator extends libFableServiceProviderBase {
4298
+ constructor(pFable, pOptions, pServiceHash) {
4299
+ super(pFable, pOptions, pServiceHash);
4300
+ this.serviceType = 'Orator';
5129
4301
 
5130
4302
  // Create the empty, important logic containers
5131
4303
  this.serviceServer = false;
@@ -5135,66 +4307,143 @@
5135
4307
  }
5136
4308
 
5137
4309
  // Now check to see that the ServicePort is set (this used to be APIServerPort)
5138
- if (!this.settings.hasOwnProperty('ServicePort')) {
5139
- if (this.settings.hasOwnProperty('APIServerPort')) {
4310
+ if (!this.options.hasOwnProperty('ServicePort')) {
4311
+ if (this.fable.settings.hasOwnProperty('APIServerPort')) {
5140
4312
  // Automatically migrate the legacy APIServerPort to ServicePort
5141
- this.settings.ServicePort = this.fable.settings.APIServerPort;
4313
+ this.options.ServicePort = this.fable.settings.APIServerPort;
5142
4314
  } else {
5143
4315
  // Default to whatever the ... default is!
5144
- this.settings.ServicePort = defaultOratorConfiguration.ServicePort;
4316
+ this.options.ServicePort = defaultOratorConfiguration.ServicePort;
5145
4317
  }
5146
4318
  }
5147
4319
 
5148
4320
  // Now check to see that the Product name is set
5149
- if (!this.settings.hasOwnProperty('Product')) {
5150
- this.settings.Product = defaultOratorConfiguration.Product;
4321
+ if (!this.options.hasOwnProperty('Product')) {
4322
+ this.options.Product = defaultOratorConfiguration.Product;
5151
4323
  }
5152
4324
  }
5153
- initializeServiceServer(fNext) {
5154
- var tmpNext = typeof fNext === 'function' ? fNext : () => {};
4325
+ onBeforeInitialize() {
4326
+ if (this.fable.settings.LogNoisiness > 3) {
4327
+ this.log.trace("Orator [".concat(this.UUID, "]::[").concat(this.Hash, "] ").concat(this.options.Product, " onBeforeInitialize:"));
4328
+ }
4329
+ }
4330
+ onBeforeInitializeAsync(fNext) {
4331
+ this.onBeforeInitialize();
4332
+ // Check to see if there is a service server active; if not instantiate one (and use IPC if none is registered with Fable as the default provider)
5155
4333
  if (!this.serviceServer) {
5156
4334
  // If the developer hasn't set this to a service provider class of their own choosing,
4335
+ // TODO: Give the developer a chance to set a service provider instantiation address of their own choosing.
5157
4336
  // use the built-in network-less one.
5158
- if (!this.serviceServerProvider) {
5159
- this.serviceServerProvider = defaultOratorServiceServers.default;
4337
+ if (!this.fable.OratorServiceServer) {
4338
+ // If there isn't a default Service Server setup, create one.
4339
+ let tmpServiceServerOptions = typeof this.options.ServiceServerOptions == 'undefined' ? {} : this.options.ServiceServerOptions;
4340
+ if (!this.fable.serviceManager.servicesMap.hasOwnProperty('OratorServiceServer')) {
4341
+ // Only register IPC if there isn't one yet.
4342
+ this.fable.serviceManager.addServiceType('OratorServiceServer', libDefaultOratorServiceServer);
4343
+ }
4344
+ this.fable.serviceManager.instantiateServiceProvider('OratorServiceServer', tmpServiceServerOptions, 'OratorServiceServer-AutoInit');
5160
4345
  }
5161
- this.serviceServer = new this.serviceServerProvider(this);
5162
-
4346
+ this.serviceServer = this.fable.OratorServiceServer;
5163
4347
  // For legacy reasons, we also will provide this under the "webServer" variable.
5164
4348
  this.webServer = this.serviceServer;
5165
4349
  } else {
5166
- this.log.warn(`Orator attempting to initialize a service server after initialization has already completed.`);
4350
+ this.log.warn("Orator attempting to initialize a service server after initialization has already completed.");
4351
+ }
4352
+ fNext();
4353
+ }
4354
+ onInitialize() {
4355
+ if (this.fable.settings.LogNoisiness > 3) {
4356
+ this.log.trace("Orator [".concat(this.UUID, "]::[").concat(this.Hash, "] ").concat(this.options.Product, " onInitialize:"));
4357
+ }
4358
+ }
4359
+ onInitializeAsync(fNext) {
4360
+ this.onInitialize();
4361
+ return fNext();
4362
+ }
4363
+ onAfterInitialize() {
4364
+ if (this.fable.settings.LogNoisiness > 3) {
4365
+ this.log.trace("Orator [".concat(this.UUID, "]::[").concat(this.Hash, "] ").concat(this.options.Product, " onAfterInitialize:"));
4366
+ }
4367
+ }
4368
+ onAfterInitializeAsync(fNext) {
4369
+ this.onAfterInitialize();
4370
+ return fNext();
4371
+ }
4372
+ initialize(fCallback) {
4373
+ // I hate this -- is there a reason to not require a callback?
4374
+ let tmpCallback = typeof fCallback === 'function' ? fCallback : () => {};
4375
+ if (!this.initializeTimestamp) {
4376
+ let tmpAnticipate = this.fable.serviceManager.instantiateServiceProviderWithoutRegistration('Anticipate');
4377
+ if (this.fable.LogNoisiness > 3) {
4378
+ this.log.trace("Orator [".concat(this.UUID, "]::[").concat(this.Hash, "] ").concat(this.options.Product, " beginning initialization steps..."));
4379
+ }
4380
+ tmpAnticipate.anticipate(this.onBeforeInitializeAsync.bind(this));
4381
+ tmpAnticipate.anticipate(this.onInitializeAsync.bind(this));
4382
+ tmpAnticipate.anticipate(this.onAfterInitializeAsync.bind(this));
4383
+ tmpAnticipate.wait(pError => {
4384
+ this.initializeTimestamp = this.fable.log.getTimeStamp();
4385
+ if (this.fable.LogNoisiness > 2) {
4386
+ this.log.trace("Orator [".concat(this.UUID, "]::[").concat(this.Hash, "] ").concat(this.options.Product, " initialization steps complete."));
4387
+ }
4388
+ return tmpCallback(pError);
4389
+ });
4390
+ } else {
4391
+ this.log.warn("Orator [".concat(this.UUID, "]::[").concat(this.Hash, "] ").concat(this.options.Product, " async initialize called but initialization is already completed. Aborting."));
4392
+ // TODO: Should this be returning an error?
4393
+ return tmpCallback();
5167
4394
  }
5168
- return tmpNext();
5169
4395
  }
5170
- _startServiceListener(fNext) {
5171
- return this.serviceServer.listen(this.settings.ServicePort, pError => {
5172
- this.log.info(`${this.serviceServer.Name} listening at ${this.serviceServer.URL} port ${this.serviceServer.Port}`);
4396
+ onBeforeStartService(fNext) {
4397
+ return fNext();
4398
+ }
4399
+ onStartService(fNext) {
4400
+ this.onAfterInitialize();
4401
+ return this.serviceServer.listen(this.options.ServicePort, pError => {
4402
+ this.log.info("".concat(this.serviceServer.Name, " listening at ").concat(this.serviceServer.URL, " port ").concat(this.serviceServer.Port));
5173
4403
  return fNext(pError);
5174
4404
  });
5175
4405
  }
4406
+ onAfterStartService(fNext) {
4407
+ return fNext();
4408
+ }
5176
4409
  startService(fNext) {
5177
4410
  var tmpNext = typeof fNext === 'function' ? fNext : () => {};
4411
+ let tmpAnticipate = this.fable.serviceManager.instantiateServiceProviderWithoutRegistration('Anticipate');
4412
+ if (this.fable.LogNoisiness > 3) {
4413
+ this.log.trace("Orator [".concat(this.UUID, "]::[").concat(this.Hash, "] ").concat(this.options.Product, " beginning startService steps..."));
4414
+ }
4415
+
4416
+ // Auto initialize if there is no serviceServer
5178
4417
  if (!this.serviceServer) {
5179
- this.initializeServiceServer();
4418
+ tmpAnticipate.anticipate(this.initialize.bind(this));
5180
4419
  }
5181
- return this._startServiceListener(tmpNext);
4420
+ tmpAnticipate.anticipate(this.onBeforeStartService.bind(this));
4421
+ tmpAnticipate.anticipate(this.onStartService.bind(this));
4422
+ tmpAnticipate.anticipate(this.onAfterStartService.bind(this));
4423
+ tmpAnticipate.wait(pError => {
4424
+ this.startServiceTimestamp = this.fable.log.getTimeStamp();
4425
+ if (this.fable.LogNoisiness > 2) {
4426
+ this.log.trace("Orator [".concat(this.UUID, "]::[").concat(this.Hash, "] ").concat(this.options.Product, " startService steps complete."));
4427
+ }
4428
+ return tmpNext(pError);
4429
+ });
5182
4430
  }
5183
- stopService(fNext) {
5184
- var tmpNext = typeof fNext === 'function' ? fNext : () => {};
4431
+ stopService(fCallback) {
4432
+ var tmpCallback = typeof fCallback === 'function' ? fCallback : () => {};
5185
4433
  if (!this.serviceServer) {
5186
- let tmpMessage = `Orator attempting to stop a service server but the service server has not been intialized yet.`;
4434
+ let tmpMessage = "Orator attempting to stop a service server but the service server has not been intialized yet.";
5187
4435
  this.log.warn(tmpMessage);
5188
- return tmpNext(tmpMessage);
4436
+ return tmpCallback(tmpMessage);
5189
4437
  }
5190
4438
  if (!this.serviceServer.Active) {
5191
- let tmpMessage = `Orator attempting to stop a service server but the service server is not actively running.`;
4439
+ let tmpMessage = "Orator attempting to stop a service server but the service server is not actively running.";
5192
4440
  this.log.warn(tmpMessage);
5193
- return tmpNext(tmpMessage);
4441
+ return tmpCallback(tmpMessage);
5194
4442
  }
5195
- return this.serviceServer.close(tmpNext);
4443
+ return this.serviceServer.close(tmpCallback);
5196
4444
  }
5197
4445
  invoke(pMethod, pRoute, pData, fCallback) {
4446
+ //this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} invoking ${pMethod} ${pRoute}`);
5198
4447
  return this.serviceServer.invoke(pMethod, pRoute, pData, fCallback);
5199
4448
  }
5200
4449
 
@@ -5226,10 +4475,13 @@
5226
4475
 
5227
4476
  module.exports = Orator;
5228
4477
  module.exports.ServiceServerBase = require('./Orator-ServiceServer-Base.js');
4478
+ module.exports.ServiceServerIPC = require('./Orator-ServiceServer-IPC.js');
5229
4479
  }, {
5230
- "./Orator-Default-Configuration.js": 46,
5231
- "./Orator-Default-ServiceServers-Node.js": 47,
5232
- "./Orator-ServiceServer-Base.js": 48
4480
+ "./Orator-Default-Configuration.js": 31,
4481
+ "./Orator-Default-ServiceServer.js": 32,
4482
+ "./Orator-ServiceServer-Base.js": 33,
4483
+ "./Orator-ServiceServer-IPC.js": 35,
4484
+ "fable-serviceproviderbase": 6
5233
4485
  }]
5234
- }, {}, [45])(45);
4486
+ }, {}, [36])(36);
5235
4487
  });