New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

cherrytree

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cherrytree - npm Package Compare versions

Comparing version 2.3.2 to 2.4.0

.npmignore

4

CHANGELOG.md

@@ -0,1 +1,5 @@

### v2.4.0
* Make it possible to `transitionTo('anAbstractRoute')` and `generate('anAbstractRoute')` in cases where the abstract route has a corresponding index route. This can be more intuitive in some cases.
### v2.3.2

@@ -2,0 +6,0 @@

101

lib/dash.js

@@ -1,80 +0,39 @@

'use strict';
let toString = Object.prototype.toString
let keys = Object.keys
let assoc = (obj, attr, val) => { obj[attr] = val; return obj }
let isArray = obj => toString.call(obj) === '[object Array]'
Object.defineProperty(exports, '__esModule', {
value: true
});
var toString = Object.prototype.toString;
var keys = Object.keys;
var assoc = function assoc(obj, attr, val) {
obj[attr] = val;return obj;
};
var isArray = function isArray(obj) {
return toString.call(obj) === '[object Array]';
};
export let clone = obj =>
obj
? isArray(obj)
? obj.slice(0)
: extend({}, obj)
: obj
var clone = function clone(obj) {
return obj ? isArray(obj) ? obj.slice(0) : extend({}, obj) : obj;
};
export let pick = (obj, attrs) =>
attrs.reduce((acc, attr) =>
obj[attr] === undefined
? acc
: assoc(acc, attr, obj[attr]), {})
exports.clone = clone;
var pick = function pick(obj, attrs) {
return attrs.reduce(function (acc, attr) {
return obj[attr] === undefined ? acc : assoc(acc, attr, obj[attr]);
}, {});
};
export let isEqual = (obj1, obj2) =>
keys(obj1).length === keys(obj2).length &&
keys(obj1).reduce((acc, key) => acc && obj2[key] === obj1[key], true)
exports.pick = pick;
var isEqual = function isEqual(obj1, obj2) {
return keys(obj1).length === keys(obj2).length && keys(obj1).reduce(function (acc, key) {
return acc && obj2[key] === obj1[key];
}, true);
};
exports.isEqual = isEqual;
var extend = function extend(obj) {
for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
rest[_key - 1] = arguments[_key];
}
rest.forEach(function (source) {
export let extend = (obj, ...rest) => {
rest.forEach(source => {
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
for (let prop in source) {
obj[prop] = source[prop]
}
}
});
return obj;
};
})
return obj
}
exports.extend = extend;
var find = function find(list, pred) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
export let find = (list, pred) => {
for (let x of list) if (pred(x)) return x
}
try {
for (var _iterator = list[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var x = _step.value;
if (pred(x)) return x;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator['return']) {
_iterator['return']();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
};
exports.find = find;
var isString = function isString(obj) {
return Object.prototype.toString.call(obj) === '[object String]';
};
exports.isString = isString;
export let isString = obj =>
Object.prototype.toString.call(obj) === '[object String]'

@@ -1,40 +0,28 @@

'use strict';
import { clone } from './dash'
import invariant from './invariant'
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = dsl;
export default function dsl (callback) {
let ancestors = []
let matches = {}
let names = {}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
callback(function route (name, options, callback) {
let routes
var _dash = require('./dash');
invariant(!names[name], 'Route names must be unique, but route "%s" is declared multiple times', name)
var _invariant = require('./invariant');
names[name] = true
var _invariant2 = _interopRequireDefault(_invariant);
function dsl(callback) {
var ancestors = [];
var matches = {};
var names = {};
callback(function route(name, options, callback) {
var routes = undefined;
(0, _invariant2['default'])(!names[name], 'Route names must be unique, but route "%s" is declared multiple times', name);
names[name] = true;
if (arguments.length === 1) {
options = {};
options = {}
}
if (arguments.length === 2 && typeof options === 'function') {
callback = options;
options = {};
callback = options
options = {}
}
if (typeof options.path !== 'string') {
var parts = name.split('.');
options.path = parts[parts.length - 1];
let parts = name.split('.')
options.path = parts[parts.length - 1]
}

@@ -44,6 +32,6 @@

if (callback) {
ancestors = ancestors.concat(name);
callback();
routes = pop();
ancestors.splice(-1);
ancestors = ancestors.concat(name)
callback()
routes = pop()
ancestors.splice(-1)
}

@@ -57,22 +45,20 @@

options: options,
ancestors: (0, _dash.clone)(ancestors)
});
});
ancestors: clone(ancestors)
})
})
function pop() {
return matches[currentLevel()] || [];
function pop () {
return matches[currentLevel()] || []
}
function push(route) {
matches[currentLevel()] = matches[currentLevel()] || [];
matches[currentLevel()].push(route);
function push (route) {
matches[currentLevel()] = matches[currentLevel()] || []
matches[currentLevel()].push(route)
}
function currentLevel() {
return ancestors.join('.');
function currentLevel () {
return ancestors.join('.')
}
return pop();
return pop()
}
module.exports = exports['default'];

@@ -1,15 +0,10 @@

'use strict';
let events = createEvents()
Object.defineProperty(exports, '__esModule', {
value: true
});
var events = createEvents();
export default events
exports['default'] = events;
function createEvents () {
let exp = {}
function createEvents() {
var exp = {};
if (typeof window === 'undefined') {
return exp;
return exp
}

@@ -21,5 +16,5 @@

var bind = window.addEventListener ? 'addEventListener' : 'attachEvent';
var unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent';
var prefix = bind !== 'addEventListener' ? 'on' : '';
let bind = window.addEventListener ? 'addEventListener' : 'attachEvent'
let unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent'
let prefix = bind !== 'addEventListener' ? 'on' : ''

@@ -38,5 +33,5 @@ /**

exp.bind = function (el, type, fn, capture) {
el[bind](prefix + type, fn, capture || false);
return fn;
};
el[bind](prefix + type, fn, capture || false)
return fn
}

@@ -55,8 +50,7 @@ /**

exp.unbind = function (el, type, fn, capture) {
el[unbind](prefix + type, fn, capture || false);
return fn;
};
el[unbind](prefix + type, fn, capture || false)
return fn
}
return exp;
return exp
}
module.exports = exports['default'];

@@ -1,22 +0,12 @@

'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = invariant;
function invariant(condition, format, a, b, c, d, e, f) {
export default function invariant (condition, format, a, b, c, d, e, f) {
if (!condition) {
(function () {
var args = [a, b, c, d, e, f];
var argIndex = 0;
var error = new Error('Invariant Violation: ' + format.replace(/%s/g, function () {
return args[argIndex++];
}));
error.framesToPop = 1; // we don't care about invariant's own frame
throw error;
})();
let args = [a, b, c, d, e, f]
let argIndex = 0
let error = new Error(
'Invariant Violation: ' +
format.replace(/%s/g, () => args[argIndex++])
)
error.framesToPop = 1 // we don't care about invariant's own frame
throw error
}
}
module.exports = exports['default'];

@@ -1,14 +0,3 @@

'use strict';
import events from './events'
Object.defineProperty(exports, '__esModule', {
value: true
});
exports.intercept = intercept;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _events = require('./events');
var _events2 = _interopRequireDefault(_events);
/**

@@ -23,22 +12,22 @@ * Handle link delegation on `el` or the document,

function intercept(el, fn) {
export function intercept (el, fn) {
// default to document
if (typeof el === 'function') {
fn = el;
el = document;
fn = el
el = document
}
var cb = delegate(el, 'click', function (e, el) {
if (clickable(e, el)) fn(e, el);
});
let cb = delegate(el, 'click', function (e, el) {
if (clickable(e, el)) fn(e, el)
})
return function dispose() {
undelegate(el, 'click', cb);
};
return function dispose () {
undelegate(el, 'click', cb)
}
}
function link(element) {
element = { parentNode: element };
function link (element) {
element = {parentNode: element}
var root = document;
let root = document

@@ -49,3 +38,3 @@ // Make sure `element !== document` and `element != null`

if (element.tagName.toLowerCase() === 'a') {
return element;
return element
}

@@ -56,3 +45,3 @@ // After `matches` on the edge case that

if (element === root) {
return;
return
}

@@ -76,10 +65,10 @@ }

function delegate(el, type, fn) {
return _events2['default'].bind(el, type, function (e) {
var target = e.target || e.srcElement;
var el = link(target);
function delegate (el, type, fn) {
return events.bind(el, type, function (e) {
let target = e.target || e.srcElement
let el = link(target)
if (el) {
fn(e, el);
fn(e, el)
}
});
})
}

@@ -97,4 +86,4 @@

function undelegate(el, type, fn) {
_events2['default'].unbind(el, type, fn);
function undelegate (el, type, fn) {
events.unbind(el, type, fn)
}

@@ -106,28 +95,28 @@

function clickable(e, el) {
if (which(e) !== 1) return;
if (e.metaKey || e.ctrlKey || e.shiftKey) return;
if (e.defaultPrevented) return;
function clickable (e, el) {
if (which(e) !== 1) return
if (e.metaKey || e.ctrlKey || e.shiftKey) return
if (e.defaultPrevented) return
// check target
if (el.target) return;
if (el.target) return
// check for data-bypass attribute
if (el.getAttribute('data-bypass') !== null) return;
if (el.getAttribute('data-bypass') !== null) return
// inspect the href
var href = el.getAttribute('href');
if (!href || href.length === 0) return;
let href = el.getAttribute('href')
if (!href || href.length === 0) return
// don't handle hash links
if (href[0] === '#') return;
if (href[0] === '#') return
// external/absolute links
if (href.indexOf('http://') === 0 || href.indexOf('https://') === 0) return;
if (href.indexOf('http://') === 0 || href.indexOf('https://') === 0) return
// email links
if (href.indexOf('mailto:') === 0) return;
if (href.indexOf('mailto:') === 0) return
// don't intercept javascript links
/* eslint-disable no-script-url */
if (href.indexOf('javascript:') === 0) return;
if (href.indexOf('javascript:') === 0) return
/* eslint-enable no-script-url */
return true;
return true
}

@@ -139,5 +128,5 @@

function which(e) {
e = e || window.event;
return e.which === null ? e.button : e.which;
}
function which (e) {
e = e || window.event
return e.which === null ? e.button : e.which
}

@@ -1,34 +0,23 @@

'use strict';
import { extend } from '../dash'
import LocationBar from 'location-bar'
Object.defineProperty(exports, '__esModule', {
value: true
});
export default BrowserLocation
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function BrowserLocation (options) {
this.path = options.path || ''
var _dash = require('../dash');
var _locationBar = require('location-bar');
var _locationBar2 = _interopRequireDefault(_locationBar);
exports['default'] = BrowserLocation;
function BrowserLocation(options) {
this.path = options.path || '';
this.options = (0, _dash.extend)({
this.options = extend({
pushState: false,
root: '/'
}, options);
}, options)
// we're using the location-bar module for actual
// URL management
var self = this;
this.locationBar = new _locationBar2['default']();
let self = this
this.locationBar = new LocationBar()
this.locationBar.onChange(function (path) {
self.handleURL('/' + (path || ''));
});
self.handleURL('/' + (path || ''))
})
this.locationBar.start((0, _dash.extend)({}, options));
this.locationBar.start(extend({}, options))
}

@@ -44,4 +33,4 @@

BrowserLocation.prototype.usesPushState = function () {
return this.options.pushState && this.locationBar.hasPushState();
};
return this.options.pushState && this.locationBar.hasPushState()
}

@@ -53,4 +42,4 @@ /**

BrowserLocation.prototype.getURL = function () {
return this.path;
};
return this.path
}

@@ -64,6 +53,6 @@ /**

if (this.path !== path) {
this.path = path;
this.locationBar.update(path, (0, _dash.extend)({ trigger: true }, options));
this.path = path
this.locationBar.update(path, extend({trigger: true}, options))
}
};
}

@@ -77,6 +66,6 @@ /**

if (this.path !== path) {
this.path = path;
this.locationBar.update(path, (0, _dash.extend)({ trigger: true, replace: true }, options));
this.path = path
this.locationBar.update(path, extend({trigger: true, replace: true}, options))
}
};
}

@@ -88,4 +77,4 @@ /**

BrowserLocation.prototype.onChange = function (callback) {
this.changeCallback = callback;
};
this.changeCallback = callback
}

@@ -98,14 +87,14 @@ /**

if (this.locationBar.hasPushState()) {
var rootURL = this.options.root;
let rootURL = this.options.root
if (path !== '') {
rootURL = rootURL.replace(/\/$/, '');
rootURL = rootURL.replace(/\/$/, '')
}
return rootURL + path;
return rootURL + path
} else {
if (path[0] === '/') {
path = path.substr(1);
path = path.substr(1)
}
return '#' + path;
return '#' + path
}
};
}

@@ -122,7 +111,7 @@ /**

if (this.options.pushState && this.options.root && this.options.root !== '/') {
return url.replace(this.options.root, '');
return url.replace(this.options.root, '')
} else {
return url;
return url
}
};
}

@@ -133,4 +122,4 @@ /**

BrowserLocation.prototype.destroy = function () {
this.locationBar.stop();
};
this.locationBar.stop()
}

@@ -147,7 +136,6 @@ /**

BrowserLocation.prototype.handleURL = function (url) {
this.path = url;
this.path = url
if (this.changeCallback) {
this.changeCallback(url);
this.changeCallback(url)
}
};
module.exports = exports['default'];
}

@@ -1,55 +0,48 @@

'use strict';
import { extend } from '../dash'
Object.defineProperty(exports, '__esModule', {
value: true
});
export default MemoryLocation
var _dash = require('../dash');
exports['default'] = MemoryLocation;
function MemoryLocation(options) {
this.path = options.path || '';
function MemoryLocation (options) {
this.path = options.path || ''
}
MemoryLocation.prototype.getURL = function () {
return this.path;
};
return this.path
}
MemoryLocation.prototype.setURL = function (path, options) {
if (this.path !== path) {
this.path = path;
this.handleURL(this.getURL(), options);
this.path = path
this.handleURL(this.getURL(), options)
}
};
}
MemoryLocation.prototype.replaceURL = function (path, options) {
if (this.path !== path) {
this.setURL(path, options);
this.setURL(path, options)
}
};
}
MemoryLocation.prototype.onChange = function (callback) {
this.changeCallback = callback;
};
this.changeCallback = callback
}
MemoryLocation.prototype.handleURL = function (url, options) {
this.path = url;
options = (0, _dash.extend)({ trigger: true }, options);
this.path = url
options = extend({trigger: true}, options)
if (this.changeCallback && options.trigger) {
this.changeCallback(url);
this.changeCallback(url)
}
};
}
MemoryLocation.prototype.usesPushState = function () {
return false;
};
return false
}
MemoryLocation.prototype.removeRoot = function (url) {
return url;
};
return url
}
MemoryLocation.prototype.formatURL = function (url) {
return url;
};
module.exports = exports['default'];
return url
}

@@ -1,21 +0,12 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = createLogger;
function createLogger(log, options) {
options = options || {};
export default function createLogger (log, options) {
options = options || {}
// falsy means no logging
if (!log) return function () {};
if (!log) return () => {}
// custom logging function
if (log !== true) return log;
if (log !== true) return log
// true means use the default logger - console
var fn = options.error ? console.error : console.info;
let fn = options.error ? console.error : console.info
return function () {
fn.apply(console, arguments);
};
fn.apply(console, arguments)
}
}
module.exports = exports["default"];

@@ -1,45 +0,30 @@

'use strict';
import invariant from './invariant'
import pathToRegexp from 'path-to-regexp'
Object.defineProperty(exports, '__esModule', {
value: true
});
let paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?+*]?)/g
let specialParamChars = /[+*?]$/g
let queryMatcher = /\?(.+)/
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
let _compiledPatterns = {}
var _invariant = require('./invariant');
var _invariant2 = _interopRequireDefault(_invariant);
var _pathToRegexp = require('path-to-regexp');
var _pathToRegexp2 = _interopRequireDefault(_pathToRegexp);
var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?+*]?)/g;
var specialParamChars = /[+*?]$/g;
var queryMatcher = /\?(.+)/;
var _compiledPatterns = {};
function compilePattern(pattern) {
function compilePattern (pattern) {
if (!(pattern in _compiledPatterns)) {
var paramNames = [];
var re = (0, _pathToRegexp2['default'])(pattern, paramNames);
let paramNames = []
let re = pathToRegexp(pattern, paramNames)
_compiledPatterns[pattern] = {
matcher: re,
paramNames: paramNames.map(function (p) {
return p.name;
})
};
paramNames: paramNames.map(p => p.name)
}
}
return _compiledPatterns[pattern];
return _compiledPatterns[pattern]
}
var Path = {
let Path = {
/**
* Returns true if the given path is absolute.
*/
isAbsolute: function isAbsolute(path) {
return path.charAt(0) === '/';
isAbsolute: function (path) {
return path.charAt(0) === '/'
},

@@ -50,4 +35,4 @@

*/
join: function join(a, b) {
return a.replace(/\/*$/, '/') + b;
join: function (a, b) {
return a.replace(/\/*$/, '/') + b
},

@@ -58,4 +43,4 @@

*/
extractParamNames: function extractParamNames(pattern) {
return compilePattern(pattern).paramNames;
extractParamNames: function (pattern) {
return compilePattern(pattern).paramNames
},

@@ -68,19 +53,19 @@

*/
extractParams: function extractParams(pattern, path) {
var cp = compilePattern(pattern);
var matcher = cp.matcher;
var paramNames = cp.paramNames;
var match = path.match(matcher);
extractParams: function (pattern, path) {
let cp = compilePattern(pattern)
let matcher = cp.matcher
let paramNames = cp.paramNames
let match = path.match(matcher)
if (!match) {
return null;
return null
}
var params = {};
let params = {}
paramNames.forEach(function (paramName, index) {
params[paramName] = match[index + 1] && decodeURIComponent(match[index + 1]);
});
params[paramName] = match[index + 1] && decodeURIComponent(match[index + 1])
})
return params;
return params
},

@@ -92,8 +77,8 @@

*/
injectParams: function injectParams(pattern, params) {
params = params || {};
injectParams: function (pattern, params) {
params = params || {}
return pattern.replace(paramInjectMatcher, function (match, param) {
var paramName = param.replace(specialParamChars, '');
var lastChar = param.slice(-1);
let paramName = param.replace(specialParamChars, '')
let lastChar = param.slice(-1)

@@ -103,15 +88,19 @@ // If param is optional don't check for existence

if (params[paramName] == null) {
return '';
return ''
}
} else {
(0, _invariant2['default'])(params[paramName] != null, "Missing '%s' parameter for path '%s'", paramName, pattern);
invariant(
params[paramName] != null,
"Missing '%s' parameter for path '%s'",
paramName, pattern
)
}
var paramValue = encodeURIComponent(params[paramName]);
let paramValue = encodeURIComponent(params[paramName])
if (lastChar === '*' || lastChar === '+') {
// restore / for splats
paramValue = paramValue.replace('%2F', '/');
paramValue = paramValue.replace('%2F', '/')
}
return paramValue;
});
return paramValue
})
},

@@ -123,5 +112,5 @@

*/
extractQuery: function extractQuery(qs, path) {
var match = path.match(queryMatcher);
return match && qs.parse(match[1]);
extractQuery: function (qs, path) {
let match = path.match(queryMatcher)
return match && qs.parse(match[1])
},

@@ -133,10 +122,10 @@

*/
withQuery: function withQuery(qs, path, query) {
var queryString = qs.stringify(query, { indices: false });
withQuery: function (qs, path, query) {
let queryString = qs.stringify(query, { indices: false })
if (queryString) {
return Path.withoutQuery(path) + '?' + queryString;
return Path.withoutQuery(path) + '?' + queryString
}
return path;
return path
},

@@ -147,8 +136,7 @@

*/
withoutQuery: function withoutQuery(path) {
return path.replace(queryMatcher, '');
withoutQuery: function (path) {
return path.replace(queryMatcher, '')
}
};
}
exports['default'] = Path;
module.exports = exports['default'];
export default Path

@@ -1,24 +0,18 @@

'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = {
parse: function parse(querystring) {
return querystring.split('&').reduce(function (acc, pair) {
var parts = pair.split('=');
acc[parts[0]] = decodeURIComponent(parts[1]);
return acc;
}, {});
export default {
parse (querystring) {
return querystring.split('&').reduce((acc, pair) => {
let parts = pair.split('=')
acc[parts[0]] = decodeURIComponent(parts[1])
return acc
}, {})
},
stringify: function stringify(params) {
return Object.keys(params).reduce(function (acc, key) {
stringify (params) {
return Object.keys(params).reduce((acc, key) => {
if (params[key] !== undefined) {
acc.push(key + '=' + encodeURIComponent(params[key]));
acc.push(key + '=' + encodeURIComponent(params[key]))
}
return acc;
}, []).join('&');
return acc
}, []).join('&')
}
};
module.exports = exports['default'];
}

@@ -1,48 +0,14 @@

'use strict';
import { pick, clone, extend, isEqual, isString, find } from './dash'
import dsl from './dsl'
import Path from './path'
import invariant from './invariant'
import BrowserLocation from './locations/browser'
import MemoryLocation from './locations/memory'
import transition from './transition'
import { intercept } from './links'
import createLogger from './logger'
import qs from './qs'
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = cherrytree;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _dash = require('./dash');
var _dsl = require('./dsl');
var _dsl2 = _interopRequireDefault(_dsl);
var _path = require('./path');
var _path2 = _interopRequireDefault(_path);
var _invariant = require('./invariant');
var _invariant2 = _interopRequireDefault(_invariant);
var _locationsBrowser = require('./locations/browser');
var _locationsBrowser2 = _interopRequireDefault(_locationsBrowser);
var _locationsMemory = require('./locations/memory');
var _locationsMemory2 = _interopRequireDefault(_locationsMemory);
var _transition = require('./transition');
var _transition2 = _interopRequireDefault(_transition);
var _links = require('./links');
var _logger = require('./logger');
var _logger2 = _interopRequireDefault(_logger);
var _qs = require('./qs');
var _qs2 = _interopRequireDefault(_qs);
function Cherrytree() {
this.initialize.apply(this, arguments);
function Cherrytree () {
this.initialize.apply(this, arguments)
}

@@ -55,6 +21,6 @@

Cherrytree.prototype.initialize = function (options) {
this.nextId = 1;
this.state = {};
this.middleware = [];
this.options = (0, _dash.extend)({
this.nextId = 1
this.state = {}
this.middleware = []
this.options = extend({
location: 'browser',

@@ -64,9 +30,11 @@ interceptLinks: true,

Promise: Promise,
qs: _qs2['default']
}, options);
this.log = (0, _logger2['default'])(this.options.log);
this.logError = (0, _logger2['default'])(this.options.logError, { error: true });
qs: qs
}, options)
this.log = createLogger(this.options.log)
this.logError = createLogger(this.options.logError, { error: true })
(0, _invariant2['default'])(typeof this.options.Promise === 'function', 'Cherrytree requires an ES6 Promise implementation, ' + 'either as an explicit option or a global Promise');
};
invariant(typeof this.options.Promise === 'function',
'Cherrytree requires an ES6 Promise implementation, ' +
'either as an explicit option or a global Promise')
}

@@ -80,5 +48,5 @@ /**

Cherrytree.prototype.use = function (middleware) {
this.middleware.push(middleware);
return this;
};
this.middleware.push(middleware)
return this
}

@@ -93,55 +61,79 @@ /**

// create the route tree
this.routes = (0, _dsl2['default'])(routes);
this.routes = dsl(routes)
// create the matcher list, which is like a flattened
// list of routes = a list of all branches of the route tree
var matchers = this.matchers = [];
let matchers = this.matchers = []
// keep track of whether duplicate paths have been created,
// in which case we'll warn the dev
var dupes = {};
let dupes = {}
// keep track of abstract routes to build index route forwarding
let abstracts = {}
eachBranch({ routes: this.routes }, [], function (routes) {
eachBranch({routes: this.routes}, [], function (routes) {
// concatenate the paths of the list of routes
var path = routes.reduce(function (memo, r) {
let path = routes.reduce(function (memo, r) {
// reset if there's a leading slash, otherwise concat
// and keep resetting the trailing slash
return (r.path[0] === '/' ? r.path : memo + '/' + r.path).replace(/\/$/, '');
}, '');
return (r.path[0] === '/' ? r.path : memo + '/' + r.path).replace(/\/$/, '')
}, '')
// ensure we have a leading slash
if (path === '') {
path = '/';
path = '/'
}
let lastRoute = routes[routes.length - 1]
if (lastRoute.options.abstract) {
abstracts[path] = lastRoute.name
return
}
// register routes
matchers.push({
routes: routes,
name: routes[routes.length - 1].name,
name: lastRoute.name,
path: path
});
})
// dupe detection
var lastRoute = routes[routes.length - 1];
if (dupes[path]) {
throw new Error('Routes ' + dupes[path] + ' and ' + lastRoute.name + ' have the same url path \'' + path + '\'');
throw new Error('Routes ' + dupes[path] + ' and ' + lastRoute.name +
' have the same url path \'' + path + '\'')
}
dupes[path] = lastRoute.name;
});
dupes[path] = lastRoute.name
})
function eachBranch(node, memo, fn) {
// check if there is an index route for each abstract route
Object.keys(abstracts).forEach(function (path) {
let matcher
if (!dupes[path]) return
matchers.some(function (m) {
if (m.path === path) {
matcher = m
return true
}
})
matchers.push({
routes: matcher.routes,
name: abstracts[path],
path: path
})
})
function eachBranch (node, memo, fn) {
node.routes.forEach(function (route) {
if (!abstract(route)) {
fn(memo.concat(route));
fn(memo.concat(route))
if (route.routes.length) {
eachBranch(route, memo.concat(route), fn)
}
if (route.routes && route.routes.length > 0) {
eachBranch(route, memo.concat(route), fn);
}
});
})
}
function abstract(route) {
return route.options && route.options.abstract;
}
return this
}
return this;
};
/**

@@ -155,16 +147,12 @@ * Starts listening to the location changes.

Cherrytree.prototype.listen = function (path) {
var _this = this;
var location = this.location = this.createLocation(path || '');
let location = this.location = this.createLocation(path || '')
// setup the location onChange handler
location.onChange(function (url) {
return _this.dispatch(url);
});
location.onChange((url) => this.dispatch(url))
// start intercepting links
if (this.options.interceptLinks && location.usesPushState()) {
this.interceptLinks();
this.interceptLinks()
}
// and also kick off the initial transition
return this.dispatch(location.getURL());
};
return this.dispatch(location.getURL())
}

@@ -180,12 +168,8 @@ /**

*/
Cherrytree.prototype.transitionTo = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
Cherrytree.prototype.transitionTo = function (...args) {
if (this.state.activeTransition) {
return this.replaceWith.apply(this, args);
return this.replaceWith.apply(this, args)
}
return this.doTransition('setURL', args);
};
return this.doTransition('setURL', args)
}

@@ -202,10 +186,6 @@ /**

*/
Cherrytree.prototype.replaceWith = function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
Cherrytree.prototype.replaceWith = function (...args) {
return this.doTransition('replaceURL', args)
}
return this.doTransition('replaceURL', args);
};
/**

@@ -221,16 +201,16 @@ * Create an href

Cherrytree.prototype.generate = function (name, params, query) {
(0, _invariant2['default'])(this.location, 'call .listen() before using .generate()');
var matcher = undefined;
invariant(this.location, 'call .listen() before using .generate()')
let matcher
params = params || {};
query = query || {};
params = params || {}
query = query || {}
this.matchers.forEach(function (m) {
if (m.name === name) {
matcher = m;
matcher = m
}
});
})
if (!matcher) {
throw new Error('No route is named ' + name);
throw new Error('No route is named ' + name)
}

@@ -243,11 +223,11 @@

// reaching out to the router.state if that's what they want.
var currentParams = (0, _dash.clone)(this.state.params || {});
let currentParams = clone(this.state.params || {})
if (this.state.activeTransition) {
currentParams = (0, _dash.clone)(this.state.activeTransition.params || {});
currentParams = clone(this.state.activeTransition.params || {})
}
params = (0, _dash.extend)(currentParams, params);
params = extend(currentParams, params)
var url = _path2['default'].withQuery(this.options.qs, _path2['default'].injectParams(matcher.path, params), query);
return this.location.formatURL(url);
};
let url = Path.withQuery(this.options.qs, Path.injectParams(matcher.path, params), query)
return this.location.formatURL(url)
}

@@ -259,13 +239,13 @@ /**

Cherrytree.prototype.destroy = function () {
if (this.location && this.location.destroy && this.location.destroy) {
this.location.destroy();
if (this.location && this.location.destroy) {
this.location.destroy()
}
if (this.disposeIntercept) {
this.disposeIntercept();
this.disposeIntercept()
}
if (this.state.activeTransition) {
this.state.activeTransition.cancel();
this.state.activeTransition.cancel()
}
this.state = {};
};
this.state = {}
}

@@ -282,21 +262,15 @@ /**

Cherrytree.prototype.isActive = function (name, params, query) {
params = params || {};
query = query || {};
params = params || {}
query = query || {}
var activeRoutes = this.state.routes || [];
var activeParams = this.state.params || {};
var activeQuery = this.state.query || [];
let activeRoutes = this.state.routes || []
let activeParams = this.state.params || {}
let activeQuery = this.state.query || {}
var isNameActive = !!(0, _dash.find)(activeRoutes, function (route) {
return route.name === name;
});
var areParamsActive = !!Object.keys(params).every(function (key) {
return activeParams[key] === params[key];
});
var isQueryActive = !!Object.keys(query).every(function (key) {
return activeQuery[key] === query[key];
});
let isActive = !!find(activeRoutes, route => route.name === name)
isActive = isActive && !!Object.keys(params).every(key => activeParams[key] === params[key])
isActive = isActive && !!Object.keys(query).every(key => activeQuery[key] === query[key])
return isNameActive && areParamsActive && isQueryActive;
};
return isActive
}

@@ -307,30 +281,28 @@ /**

Cherrytree.prototype.doTransition = function (method, params) {
var _this2 = this;
let previousUrl = this.location.getURL()
var previousUrl = this.location.getURL();
var url = params[0];
let url = params[0]
if (url[0] !== '/') {
url = this.generate.apply(this, params);
url = url.replace(/^#/, '/');
url = this.generate.apply(this, params)
url = url.replace(/^#/, '/')
}
if (this.options.pushState) {
url = this.location.removeRoot(url);
url = this.location.removeRoot(url)
}
var transition = this.dispatch(url);
let transition = this.dispatch(url)
transition['catch'](function (err) {
transition.catch((err) => {
if (err && err.type === 'TransitionCancelled') {
// reset the URL in case the transition has been cancelled
_this2.location.replaceURL(previousUrl, { trigger: false });
this.location.replaceURL(previousUrl, {trigger: false})
}
return err;
});
return err
})
this.location[method](url, { trigger: false });
this.location[method](url, {trigger: false})
return transition;
};
return transition
}

@@ -345,22 +317,20 @@ /**

Cherrytree.prototype.match = function (path) {
path = (path || '').replace(/\/$/, '') || '/';
var found = false;
var params = undefined;
var routes = [];
var pathWithoutQuery = _path2['default'].withoutQuery(path);
var qs = this.options.qs;
this.matchers.forEach(function (matcher) {
if (!found) {
params = _path2['default'].extractParams(matcher.path, pathWithoutQuery);
if (params) {
found = true;
routes = matcher.routes;
}
path = (path || '').replace(/\/$/, '') || '/'
let params
let routes = []
let pathWithoutQuery = Path.withoutQuery(path)
let qs = this.options.qs
this.matchers.some(function (matcher) {
params = Path.extractParams(matcher.path, pathWithoutQuery)
if (params) {
routes = matcher.routes
return true
}
});
})
return {
routes: routes.map(descriptor),
params: params || {},
query: _path2['default'].extractQuery(qs, path) || {}
};
pathname: pathWithoutQuery,
query: Path.extractQuery(qs, path) || {}
}

@@ -373,23 +343,25 @@ // clone the data (only a shallow clone of options)

// will get to use pristine data.
function descriptor(route) {
function descriptor (route) {
return {
name: route.name,
path: route.path,
params: (0, _dash.pick)(params, _path2['default'].extractParamNames(route.path)),
options: (0, _dash.clone)(route.options)
};
params: pick(params, Path.extractParamNames(route.path)),
options: clone(route.options)
}
}
};
}
Cherrytree.prototype.dispatch = function (path) {
var match = this.match(path);
var query = match.query;
var pathname = _path2['default'].withoutQuery(path);
let match = this.match(path)
let query = match.query
let pathname = match.pathname
var activeTransition = this.state.activeTransition;
let activeTransition = this.state.activeTransition
// if we already have an active transition with all the same
// params - return that and don't do anything else
if (activeTransition && activeTransition.pathname === pathname && (0, _dash.isEqual)(activeTransition.query, query)) {
return activeTransition;
if (activeTransition &&
activeTransition.pathname === pathname &&
isEqual(activeTransition.query, query)) {
return activeTransition
}

@@ -400,6 +372,6 @@

if (activeTransition) {
var err = new Error('TransitionRedirected');
err.type = 'TransitionRedirected';
err.nextPath = path;
activeTransition.cancel(err);
let err = new Error('TransitionRedirected')
err.type = 'TransitionRedirected'
err.nextPath = path
activeTransition.cancel(err)
}

@@ -412,4 +384,5 @@

if (!activeTransition) {
if (this.state.pathname === pathname && (0, _dash.isEqual)(this.state.query, query)) {
return (0, _transition2['default'])({
if (this.state.pathname === pathname &&
isEqual(this.state.query, query)) {
return transition({
id: this.nextId++,

@@ -420,7 +393,7 @@ path: path,

router: this
}, this.options.Promise);
}, this.options.Promise)
}
}
var t = (0, _transition2['default'])({
let t = transition({
id: this.nextId++,

@@ -430,8 +403,8 @@ path: path,

router: this
}, this.options.Promise);
}, this.options.Promise)
this.state.activeTransition = t;
this.state.activeTransition = t
return t;
};
return t
}

@@ -447,14 +420,14 @@ /**

Cherrytree.prototype.createLocation = function (path) {
var location = this.options.location;
if (!(0, _dash.isString)(location)) {
return location;
let location = this.options.location
if (!isString(location)) {
return location
}
if (location === 'browser') {
return new _locationsBrowser2['default']((0, _dash.pick)(this.options, ['pushState', 'root']));
return new BrowserLocation(pick(this.options, ['pushState', 'root']))
} else if (location === 'memory') {
return new _locationsMemory2['default']({ path: path });
return new MemoryLocation({path})
} else {
throw new Error('Location can be `browser`, `memory` or a custom implementation');
throw new Error('Location can be `browser`, `memory` or a custom implementation')
}
};
}

@@ -467,21 +440,18 @@ /**

Cherrytree.prototype.interceptLinks = function () {
var _this3 = this;
let clickHandler = typeof this.options.interceptLinks === 'function'
? this.options.interceptLinks
: defaultClickHandler
this.disposeIntercept = intercept((event, link) => clickHandler(event, link, this))
var clickHandler = typeof this.options.interceptLinks === 'function' ? this.options.interceptLinks : defaultClickHandler;
this.disposeIntercept = (0, _links.intercept)(function (event, link) {
return clickHandler(event, link, _this3);
});
function defaultClickHandler(event, link, router) {
event.preventDefault();
router.transitionTo(router.location.removeRoot(link.getAttribute('href')));
function defaultClickHandler (event, link, router) {
event.preventDefault()
router.transitionTo(router.location.removeRoot(link.getAttribute('href')))
}
};
}
function cherrytree(options) {
return new Cherrytree(options);
export default function cherrytree (options) {
return new Cherrytree(options)
}
cherrytree.BrowserLocation = _locationsBrowser2['default'];
cherrytree.MemoryLocation = _locationsMemory2['default'];
module.exports = exports['default'];
cherrytree.BrowserLocation = BrowserLocation
cherrytree.MemoryLocation = MemoryLocation

@@ -1,50 +0,32 @@

'use strict';
import { clone } from './dash'
import invariant from './invariant'
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = transition;
export default function transition (options, Promise) {
options = options || {}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
let router = options.router
let log = router.log
let logError = router.logError
var _dash = require('./dash');
let path = options.path
let match = options.match
let routes = match.routes
let params = match.params
let pathname = match.pathname
let query = match.query
var _invariant = require('./invariant');
let id = options.id
let startTime = Date.now()
log('---')
log('Transition #' + id, 'to', path)
log('Transition #' + id, 'routes:', routes.map(r => r.name))
log('Transition #' + id, 'params:', params)
log('Transition #' + id, 'query:', query)
var _invariant2 = _interopRequireDefault(_invariant);
var _path = require('./path');
var _path2 = _interopRequireDefault(_path);
function transition(options, Promise) {
options = options || {};
var router = options.router;
var log = router.log;
var logError = router.logError;
var path = options.path;
var match = options.match;
var routes = match.routes;
var params = match.params;
var query = match.query;
var id = options.id;
var startTime = Date.now();
log('---');
log('Transition #' + id, 'to', path);
log('Transition #' + id, 'routes:', routes.map(function (r) {
return r.name;
}));
log('Transition #' + id, 'params:', params);
log('Transition #' + id, 'query:', query);
// create the transition promise
var resolve = undefined,
reject = undefined;
var promise = new Promise(function (res, rej) {
resolve = res;
reject = rej;
});
let resolve, reject
let promise = new Promise(function (res, rej) {
resolve = res
reject = rej
})

@@ -56,97 +38,99 @@ // 1. make transition errors loud

promise.then(function () {
log('Transition #' + id, 'completed in', Date.now() - startTime + 'ms');
})['catch'](function (err) {
log('Transition #' + id, 'completed in', (Date.now() - startTime) + 'ms')
}).catch(function (err) {
if (err.type !== 'TransitionRedirected' && err.type !== 'TransitionCancelled') {
log('Transition #' + id, 'FAILED');
logError(err.stack);
log('Transition #' + id, 'FAILED')
logError(err.stack)
}
});
})
var cancelled = false;
let cancelled = false
var transition = {
let transition = {
id: id,
prev: {
routes: (0, _dash.clone)(router.state.routes) || [],
routes: clone(router.state.routes) || [],
path: router.state.path || '',
pathname: router.state.pathname || '',
params: (0, _dash.clone)(router.state.params) || {},
query: (0, _dash.clone)(router.state.query) || {}
params: clone(router.state.params) || {},
query: clone(router.state.query) || {}
},
routes: (0, _dash.clone)(routes),
routes: clone(routes),
path: path,
pathname: _path2['default'].withoutQuery(path),
params: (0, _dash.clone)(params),
query: (0, _dash.clone)(query),
redirectTo: function redirectTo() {
return router.transitionTo.apply(router, arguments);
pathname: pathname,
params: clone(params),
query: clone(query),
redirectTo: function () {
return router.transitionTo.apply(router, arguments)
},
retry: function retry() {
return router.transitionTo(path);
retry: function () {
return router.transitionTo(path)
},
cancel: function cancel(err) {
cancel: function (err) {
if (router.state.activeTransition !== transition) {
return;
return
}
if (transition.isCancelled) {
return;
return
}
router.state.activeTransition = null;
transition.isCancelled = true;
cancelled = true;
router.state.activeTransition = null
transition.isCancelled = true
cancelled = true
if (!err) {
err = new Error('TransitionCancelled');
err.type = 'TransitionCancelled';
err = new Error('TransitionCancelled')
err.type = 'TransitionCancelled'
}
if (err.type === 'TransitionCancelled') {
log('Transition #' + id, 'cancelled');
log('Transition #' + id, 'cancelled')
}
if (err.type === 'TransitionRedirected') {
log('Transition #' + id, 'redirected');
log('Transition #' + id, 'redirected')
}
reject(err);
reject(err)
},
followRedirects: function followRedirects() {
followRedirects: function () {
return promise['catch'](function (reason) {
if (router.state.activeTransition) {
return router.state.activeTransition.followRedirects();
return router.state.activeTransition.followRedirects()
}
return Promise.reject(reason);
});
return Promise.reject(reason)
})
},
then: promise.then.bind(promise),
'catch': promise['catch'].bind(promise)
};
catch: promise.catch.bind(promise)
}
// here we handle calls to all of the middlewares
function callNext(i, prevResult) {
var middlewareName = undefined;
function callNext (i, prevResult) {
let middlewareName
// if transition has been cancelled - nothing left to do
if (cancelled) {
return;
return
}
// done
if (i < router.middleware.length) {
middlewareName = router.middleware[i].name || 'anonymous';
log('Transition #' + id, 'resolving middleware:', middlewareName);
var middlewarePromise = undefined;
middlewareName = router.middleware[i].name || 'anonymous'
log('Transition #' + id, 'resolving middleware:', middlewareName)
let middlewarePromise
try {
middlewarePromise = router.middleware[i](transition, prevResult);
(0, _invariant2['default'])(transition !== middlewarePromise, 'Middleware %s returned a transition which resulted in a deadlock', middlewareName);
middlewarePromise = router.middleware[i](transition, prevResult)
invariant(transition !== middlewarePromise, 'Middleware %s returned a transition which resulted in a deadlock', middlewareName)
} catch (err) {
router.state.activeTransition = null;
return reject(err);
router.state.activeTransition = null
return reject(err)
}
Promise.resolve(middlewarePromise).then(function (result) {
callNext(i + 1, result);
})['catch'](function (err) {
log('Transition #' + id, 'resolving middleware:', middlewareName, 'FAILED');
router.state.activeTransition = null;
reject(err);
});
Promise.resolve(middlewarePromise)
.then(function (result) {
callNext(i + 1, result)
})
.catch(function (err) {
log('Transition #' + id, 'resolving middleware:', middlewareName, 'FAILED')
router.state.activeTransition = null
reject(err)
})
} else {

@@ -157,7 +141,7 @@ router.state = {

path: path,
pathname: _path2['default'].withoutQuery(path),
pathname: pathname,
params: params,
query: query
};
resolve();
}
resolve()
}

@@ -167,16 +151,12 @@ }

if (!options.noop) {
Promise.resolve().then(function () {
return callNext(0);
});
Promise.resolve().then(() => callNext(0))
} else {
resolve();
resolve()
}
if (options.noop) {
transition.noop = true;
transition.noop = true
}
return transition;
return transition
}
module.exports = exports['default'];
{
"name": "cherrytree",
"version": "2.3.2",
"version": "2.4.0",
"description": "Cherrytree - a flexible hierarchical client side router",

@@ -5,0 +5,0 @@ "main": "index",

@@ -126,3 +126,3 @@ # <img src="https://cloud.githubusercontent.com/assets/324440/11302251/2c573b4a-8f94-11e5-9df6-889b19c2ad48.png" width="320" />

[![Build Status](https://travis-ci.org/QubitProducts/cherrytree.svg?branch=master)](https://travis-ci.org/QubitProducts/cherrytree)
[![build status](https://www.codeship.io/projects/aa5e37b0-aeb1-0131-dd5f-06fd12e6a611/status?branch=master)](https://codeship.com/projects/19734)
[![build status](https://codeship.com/projects/aa5e37b0-aeb1-0131-dd5f-06fd12e6a611/status?branch=master)](https://codeship.com/projects/19734)

@@ -129,0 +129,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc