install gulp

This commit is contained in:
2018-05-28 13:26:25 +02:00
parent 2de92c908b
commit 04fab6ba46
8032 changed files with 709336 additions and 3100 deletions
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-2016, Jon Schlinkert.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+321
View File
@@ -0,0 +1,321 @@
# snapdragon [![NPM version](https://img.shields.io/npm/v/snapdragon.svg?style=flat)](https://www.npmjs.com/package/snapdragon) [![NPM downloads](https://img.shields.io/npm/dm/snapdragon.svg?style=flat)](https://npmjs.org/package/snapdragon) [![Build Status](https://img.shields.io/travis/jonschlinkert/snapdragon.svg?style=flat)](https://travis-ci.org/jonschlinkert/snapdragon)
> Fast, pluggable and easy-to-use parser-renderer factory.
## Install
Install with [npm](https://www.npmjs.com/):
```sh
$ npm install --save snapdragon
```
Created by [jonschlinkert](https://github.com/jonschlinkert) and [doowb](https://github.com/doowb).
**Features**
* Bootstrap your own parser, get sourcemap support for free
* All parsing and compiling is handled by simple, reusable middleware functions
* Inspired by the parsers in [pug](http://jade-lang.com) and [css](https://github.com/reworkcss/css).
## History
### v0.5.0
**Breaking changes**
Substantial breaking changes were made in v0.5.0! Most of these changes are part of a larger refactor that will be finished in 0.6.0, including the introduction of a `Lexer` class.
* Renderer was renamed to `Compiler`
* the `.render` method was renamed to `.compile`
* Many other smaller changes. A more detailed overview will be provided in 0.6.0. If you don't have to time review code, I recommend you wait for the 0.6.0 release.
## Usage examples
```js
var Snapdragon = require('snapdragon');
var snapdragon = new Snapdragon();
```
**Parse**
```js
var ast = snapdragon.parser('some string', options)
// parser middleware that can be called by other middleware
.set('foo', function () {})
// parser middleware, runs immediately in the order defined
.use(bar())
.use(baz())
```
**Render**
```js
// pass the `ast` from the parse method
var res = snapdragon.compiler(ast)
// compiler middleware, called when the name of the middleware
// matches the `node.type` (defined in a parser middleware)
.set('bar', function () {})
.set('baz', function () {})
.compile()
```
See the [examples](./examples/).
## Getting started
**Parsers**
Parsers are middleware functions used for parsing a string into an ast node.
```js
var ast = snapdragon.parser(str, options)
.use(function() {
var pos = this.position();
var m = this.match(/^\./);
if (!m) return;
return pos({
// `type` specifies the compiler to use
type: 'dot',
val: m[0]
});
})
```
**AST node**
When the parser finds a match, `pos()` is called, pushing a token for that node onto the ast that looks something like:
```js
{ type: 'dot',
val: '.',
position:
{ start: { lineno: 1, column: 1 },
end: { lineno: 1, column: 2 } }}
```
**Renderers**
Renderers are _named_ middleware functions that visit over an array of ast nodes to compile a string.
```js
var res = snapdragon.compiler(ast)
.set('dot', function (node) {
console.log(node.val)
//=> '.'
return this.emit(node.val);
})
```
**Source maps**
If you want source map support, make sure to emit the position as well.
```js
var res = snapdragon.compiler(ast)
.set('dot', function (node) {
return this.emit(node.val, node.position);
})
```
## Docs
### Parser middleware
A parser middleware is a function that returns an abject called a `token`. This token is pushed onto the AST as a node.
**Example token**
```js
{ type: 'dot',
val: '.',
position:
{ start: { lineno: 1, column: 1 },
end: { lineno: 1, column: 2 } }}
```
**Example parser middleware**
Match a single `.` in a string:
1. Get the starting position by calling `this.position()`
2. pass a regex for matching a single dot to the `.match` method
3. if **no match** is found, return `undefined`
4. if a **match** is found, `pos()` is called, which returns a token with:
- `type`: the name of the [compiler] to use
- `val`: The actual value captured by the regex. In this case, a `.`. Note that you can capture and return whatever will be needed by the corresponding [compiler].
- The ending position: automatically calculated by adding the length of the first capture group to the starting position.
## Renderer middleware
Renderers are run when the name of the compiler middleware matches the `type` defined on an ast `node` (which is defined in a parser).
**Example**
Exercise: Parse a dot, then compile it as an escaped dot.
```js
var ast = snapdragon.parser('.')
.use(function () {
var pos = this.position();
var m = this.match(/^\./);
if (!m) return;
return pos({
// define the `type` of compiler to use
type: 'dot',
val: m[0]
})
})
var result = snapdragon.compiler(ast)
.set('dot', function (node) {
return this.emit('\\' + node.val);
})
.compile()
console.log(result.output);
//=> '\.'
```
## API
### [Parser](lib/parser.js#L19)
Create a new `Parser` with the given `input` and `options`.
**Params**
* `input` **{String}**
* `options` **{Object}**
### [.define](lib/parser.js#L103)
Define a non-enumberable property on the `Parser` instance.
**Example**
```js
parser.define('foo', 'bar');
```
**Params**
* `key` **{String}**: propery name
* `val` **{any}**: property value
* `returns` **{Object}**: Returns the Parser instance for chaining.
Set parser `name` with the given `fn`
**Params**
* `name` **{String}**
* `fn` **{Function}**
Get parser `name`
**Params**
* `name` **{String}**
Push a `token` onto the `type` stack.
**Params**
* `type` **{String}**
* `returns` **{Object}** `token`
Pop a token off of the `type` stack
**Params**
* `type` **{String}**
* `returns` **{Object}**: Returns a token
Return true if inside a `stack` node. Types are `braces`, `parens` or `brackets`.
**Params**
* `type` **{String}**
* `returns` **{Boolean}**
**Example**
```js
parser.isType(node, 'brace');
```
**Params**
* `node` **{Object}**
* `type` **{String}**
* `returns` **{Boolean}**
### [.define](lib/compiler.js#L71)
Define a non-enumberable property on the `Compiler` instance.
**Example**
```js
compiler.define('foo', 'bar');
```
**Params**
* `key` **{String}**: propery name
* `val` **{any}**: property value
* `returns` **{Object}**: Returns the Compiler instance for chaining.
## About
### Related projects
* [braces](https://www.npmjs.com/package/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces… [more](https://github.com/jonschlinkert/braces) | [homepage](https://github.com/jonschlinkert/braces "Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.")
* [expand-brackets](https://www.npmjs.com/package/expand-brackets): Expand POSIX bracket expressions (character classes) in glob patterns. | [homepage](https://github.com/jonschlinkert/expand-brackets "Expand POSIX bracket expressions (character classes) in glob patterns.")
* [extglob](https://www.npmjs.com/package/extglob): Convert extended globs to regex-compatible strings. Add (almost) the expressive power of regular expressions to… [more](https://github.com/jonschlinkert/extglob) | [homepage](https://github.com/jonschlinkert/extglob "Convert extended globs to regex-compatible strings. Add (almost) the expressive power of regular expressions to glob patterns.")
* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/jonschlinkert/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.")
### Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
### Contributors
| **Commits** | **Contributor**<br/> |
| --- | --- |
| 106 | [jonschlinkert](https://github.com/jonschlinkert) |
| 2 | [doowb](https://github.com/doowb) |
### Building docs
_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_
To generate the readme and API documentation with [verb](https://github.com/verbose/verb):
```sh
$ npm install -g verb verb-generate-readme && verb
```
### Running tests
Install dev dependencies:
```sh
$ npm install -d && npm test
```
### Author
**Jon Schlinkert**
* [github/jonschlinkert](https://github.com/jonschlinkert)
* [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
### License
Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT license](https://github.com/jonschlinkert/snapdragon/blob/master/LICENSE).
***
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.1.31, on October 10, 2016._
+174
View File
@@ -0,0 +1,174 @@
'use strict';
var Base = require('base');
var define = require('define-property');
var Compiler = require('./lib/compiler');
var Parser = require('./lib/parser');
var utils = require('./lib/utils');
var regexCache = {};
var cache = {};
/**
* Create a new instance of `Snapdragon` with the given `options`.
*
* ```js
* var snapdragon = new Snapdragon();
* ```
*
* @param {Object} `options`
* @api public
*/
function Snapdragon(options) {
Base.call(this, null, options);
this.options = utils.extend({source: 'string'}, this.options);
this.compiler = new Compiler(this.options);
this.parser = new Parser(this.options);
Object.defineProperty(this, 'compilers', {
get: function() {
return this.compiler.compilers;
}
});
Object.defineProperty(this, 'parsers', {
get: function() {
return this.parser.parsers;
}
});
Object.defineProperty(this, 'regex', {
get: function() {
return this.parser.regex;
}
});
}
/**
* Inherit Base
*/
Base.extend(Snapdragon);
/**
* Add a parser to `snapdragon.parsers` for capturing the given `type` using
* the specified regex or parser function. A function is useful if you need
* to customize how the token is created and/or have access to the parser
* instance to check options, etc.
*
* ```js
* snapdragon
* .capture('slash', /^\//)
* .capture('dot', function() {
* var pos = this.position();
* var m = this.match(/^\./);
* if (!m) return;
* return pos({
* type: 'dot',
* val: m[0]
* });
* });
* ```
* @param {String} `type`
* @param {RegExp|Function} `regex`
* @return {Object} Returns the parser instance for chaining
* @api public
*/
Snapdragon.prototype.capture = function() {
return this.parser.capture.apply(this.parser, arguments);
};
/**
* Register a plugin `fn`.
*
* ```js
* var snapdragon = new Snapdgragon([options]);
* snapdragon.use(function() {
* console.log(this); //<= snapdragon instance
* console.log(this.parser); //<= parser instance
* console.log(this.compiler); //<= compiler instance
* });
* ```
* @param {Object} `fn`
* @api public
*/
Snapdragon.prototype.use = function(fn) {
fn.call(this, this);
return this;
};
/**
* Parse the given `str`.
*
* ```js
* var snapdragon = new Snapdgragon([options]);
* // register parsers
* snapdragon.parser.use(function() {});
*
* // parse
* var ast = snapdragon.parse('foo/bar');
* console.log(ast);
* ```
* @param {String} `str`
* @param {Object} `options` Set `options.sourcemap` to true to enable source maps.
* @return {Object} Returns an AST.
* @api public
*/
Snapdragon.prototype.parse = function(str, options) {
this.options = utils.extend({}, this.options, options);
var parsed = this.parser.parse(str, this.options);
// add non-enumerable parser reference
define(parsed, 'parser', this.parser);
return parsed;
};
/**
* Compile the given `AST`.
*
* ```js
* var snapdragon = new Snapdgragon([options]);
* // register plugins
* snapdragon.use(function() {});
* // register parser plugins
* snapdragon.parser.use(function() {});
* // register compiler plugins
* snapdragon.compiler.use(function() {});
*
* // parse
* var ast = snapdragon.parse('foo/bar');
*
* // compile
* var res = snapdragon.compile(ast);
* console.log(res.output);
* ```
* @param {Object} `ast`
* @param {Object} `options`
* @return {Object} Returns an object with an `output` property with the rendered string.
* @api public
*/
Snapdragon.prototype.compile = function(ast, options) {
this.options = utils.extend({}, this.options, options);
var compiled = this.compiler.compile(ast, this.options);
// add non-enumerable compiler reference
define(compiled, 'compiler', this.compiler);
return compiled;
};
/**
* Expose `Snapdragon`
*/
module.exports = Snapdragon;
/**
* Expose `Parser` and `Compiler`
*/
module.exports.Compiler = Compiler;
module.exports.Parser = Parser;
+177
View File
@@ -0,0 +1,177 @@
'use strict';
var use = require('use');
var define = require('define-property');
var debug = require('debug')('snapdragon:compiler');
var utils = require('./utils');
/**
* Create a new `Compiler` with the given `options`.
* @param {Object} `options`
*/
function Compiler(options, state) {
debug('initializing', __filename);
this.options = utils.extend({source: 'string'}, options);
this.state = state || {};
this.compilers = {};
this.output = '';
this.set('eos', function(node) {
return this.emit(node.val, node);
});
this.set('noop', function(node) {
return this.emit(node.val, node);
});
this.set('bos', function(node) {
return this.emit(node.val, node);
});
use(this);
}
/**
* Prototype methods
*/
Compiler.prototype = {
/**
* Throw an error message with details including the cursor position.
* @param {String} `msg` Message to use in the Error.
*/
error: function(msg, node) {
var pos = node.position || {start: {column: 0}};
var message = this.options.source + ' column:' + pos.start.column + ': ' + msg;
var err = new Error(message);
err.reason = msg;
err.column = pos.start.column;
err.source = this.pattern;
if (this.options.silent) {
this.errors.push(err);
} else {
throw err;
}
},
/**
* Define a non-enumberable property on the `Compiler` instance.
*
* ```js
* compiler.define('foo', 'bar');
* ```
* @name .define
* @param {String} `key` propery name
* @param {any} `val` property value
* @return {Object} Returns the Compiler instance for chaining.
* @api public
*/
define: function(key, val) {
define(this, key, val);
return this;
},
/**
* Emit `node.val`
*/
emit: function(str, node) {
this.output += str;
return str;
},
/**
* Add a compiler `fn` with the given `name`
*/
set: function(name, fn) {
this.compilers[name] = fn;
return this;
},
/**
* Get compiler `name`.
*/
get: function(name) {
return this.compilers[name];
},
/**
* Get the previous AST node.
*/
prev: function(n) {
return this.ast.nodes[this.idx - (n || 1)] || { type: 'bos', val: '' };
},
/**
* Get the next AST node.
*/
next: function(n) {
return this.ast.nodes[this.idx + (n || 1)] || { type: 'eos', val: '' };
},
/**
* Visit `node`.
*/
visit: function(node, nodes, i) {
var fn = this.compilers[node.type];
this.idx = i;
if (typeof fn !== 'function') {
throw this.error('compiler "' + node.type + '" is not registered', node);
}
return fn.call(this, node, nodes, i);
},
/**
* Map visit over array of `nodes`.
*/
mapVisit: function(nodes) {
if (!Array.isArray(nodes)) {
throw new TypeError('expected an array');
}
var len = nodes.length;
var idx = -1;
while (++idx < len) {
this.visit(nodes[idx], nodes, idx);
}
return this;
},
/**
* Compile `ast`.
*/
compile: function(ast, options) {
var opts = utils.extend({}, this.options, options);
this.ast = ast;
this.parsingErrors = this.ast.errors;
this.output = '';
// source map support
if (opts.sourcemap) {
var sourcemaps = require('./source-maps');
sourcemaps(this);
this.mapVisit(this.ast.nodes);
this.applySourceMaps();
this.map = opts.sourcemap === 'generator' ? this.map : this.map.toJSON();
return this;
}
this.mapVisit(this.ast.nodes);
return this;
}
};
/**
* Expose `Compiler`
*/
module.exports = Compiler;
+533
View File
@@ -0,0 +1,533 @@
'use strict';
var use = require('use');
var util = require('util');
var Cache = require('map-cache');
var define = require('define-property');
var debug = require('debug')('snapdragon:parser');
var Position = require('./position');
var utils = require('./utils');
/**
* Create a new `Parser` with the given `input` and `options`.
* @param {String} `input`
* @param {Object} `options`
* @api public
*/
function Parser(options) {
debug('initializing', __filename);
this.options = utils.extend({source: 'string'}, options);
this.init(this.options);
use(this);
}
/**
* Prototype methods
*/
Parser.prototype = {
constructor: Parser,
init: function(options) {
this.orig = '';
this.input = '';
this.parsed = '';
this.column = 1;
this.line = 1;
this.regex = new Cache();
this.errors = this.errors || [];
this.parsers = this.parsers || {};
this.types = this.types || [];
this.sets = this.sets || {};
this.fns = this.fns || [];
this.currentType = 'root';
var pos = this.position();
this.bos = pos({type: 'bos', val: ''});
this.ast = {
type: 'root',
errors: this.errors,
nodes: [this.bos]
};
define(this.bos, 'parent', this.ast);
this.nodes = [this.ast];
this.count = 0;
this.setCount = 0;
this.stack = [];
},
/**
* Throw a formatted error with the cursor column and `msg`.
* @param {String} `msg` Message to use in the Error.
*/
error: function(msg, node) {
var pos = node.position || {start: {column: 0, line: 0}};
var line = pos.start.line;
var column = pos.start.column;
var source = this.options.source;
var message = source + ' <line:' + line + ' column:' + column + '>: ' + msg;
var err = new Error(message);
err.source = source;
err.reason = msg;
err.pos = pos;
if (this.options.silent) {
this.errors.push(err);
} else {
throw err;
}
},
/**
* Define a non-enumberable property on the `Parser` instance.
*
* ```js
* parser.define('foo', 'bar');
* ```
* @name .define
* @param {String} `key` propery name
* @param {any} `val` property value
* @return {Object} Returns the Parser instance for chaining.
* @api public
*/
define: function(key, val) {
define(this, key, val);
return this;
},
/**
* Mark position and patch `node.position`.
*/
position: function() {
var start = { line: this.line, column: this.column };
var self = this;
return function(node) {
define(node, 'position', new Position(start, self));
return node;
};
},
/**
* Set parser `name` with the given `fn`
* @param {String} `name`
* @param {Function} `fn`
* @api public
*/
set: function(type, fn) {
if (this.types.indexOf(type) === -1) {
this.types.push(type);
}
this.parsers[type] = fn.bind(this);
return this;
},
/**
* Get parser `name`
* @param {String} `name`
* @api public
*/
get: function(name) {
return this.parsers[name];
},
/**
* Push a `token` onto the `type` stack.
*
* @param {String} `type`
* @return {Object} `token`
* @api public
*/
push: function(type, token) {
this.sets[type] = this.sets[type] || [];
this.count++;
this.stack.push(token);
return this.sets[type].push(token);
},
/**
* Pop a token off of the `type` stack
* @param {String} `type`
* @returns {Object} Returns a token
* @api public
*/
pop: function(type) {
this.sets[type] = this.sets[type] || [];
this.count--;
this.stack.pop();
return this.sets[type].pop();
},
/**
* Return true if inside a `stack` node. Types are `braces`, `parens` or `brackets`.
*
* @param {String} `type`
* @return {Boolean}
* @api public
*/
isInside: function(type) {
this.sets[type] = this.sets[type] || [];
return this.sets[type].length > 0;
},
/**
* Return true if `node` is the given `type`.
*
* ```js
* parser.isType(node, 'brace');
* ```
* @param {Object} `node`
* @param {String} `type`
* @return {Boolean}
* @api public
*/
isType: function(node, type) {
return node && node.type === type;
},
/**
* Get the previous AST node
* @return {Object}
*/
prev: function(n) {
return this.stack.length > 0
? utils.last(this.stack, n)
: utils.last(this.nodes, n);
},
/**
* Update line and column based on `str`.
*/
consume: function(len) {
this.input = this.input.substr(len);
},
/**
* Update column based on `str`.
*/
updatePosition: function(str, len) {
var lines = str.match(/\n/g);
if (lines) this.line += lines.length;
var i = str.lastIndexOf('\n');
this.column = ~i ? len - i : this.column + len;
this.parsed += str;
this.consume(len);
},
/**
* Match `regex`, return captures, and update the cursor position by `match[0]` length.
* @param {RegExp} `regex`
* @return {Object}
*/
match: function(regex) {
var m = regex.exec(this.input);
if (m) {
this.updatePosition(m[0], m[0].length);
return m;
}
},
/**
* Capture `type` with the given regex.
* @param {String} `type`
* @param {RegExp} `regex`
* @return {Function}
*/
capture: function(type, regex) {
if (typeof regex === 'function') {
return this.set.apply(this, arguments);
}
this.regex.set(type, regex);
this.set(type, function() {
var parsed = this.parsed;
var pos = this.position();
var m = this.match(regex);
if (!m || !m[0]) return;
var prev = this.prev();
var node = pos({
type: type,
val: m[0],
parsed: parsed,
rest: this.input
});
if (m[1]) {
node.inner = m[1];
}
define(node, 'inside', this.stack.length > 0);
define(node, 'parent', prev);
prev.nodes.push(node);
}.bind(this));
return this;
},
/**
* Create a parser with open and close for parens,
* brackets or braces
*/
capturePair: function(type, openRegex, closeRegex, fn) {
this.sets[type] = this.sets[type] || [];
/**
* Open
*/
this.set(type + '.open', function() {
var parsed = this.parsed;
var pos = this.position();
var m = this.match(openRegex);
if (!m || !m[0]) return;
var val = m[0];
this.setCount++;
this.specialChars = true;
var open = pos({
type: type + '.open',
val: val,
rest: this.input
});
if (typeof m[1] !== 'undefined') {
open.inner = m[1];
}
var prev = this.prev();
var node = pos({
type: type,
nodes: [open]
});
define(node, 'rest', this.input);
define(node, 'parsed', parsed);
define(node, 'prefix', m[1]);
define(node, 'parent', prev);
define(open, 'parent', node);
if (typeof fn === 'function') {
fn.call(this, open, node);
}
this.push(type, node);
prev.nodes.push(node);
});
/**
* Close
*/
this.set(type + '.close', function() {
var pos = this.position();
var m = this.match(closeRegex);
if (!m || !m[0]) return;
var parent = this.pop(type);
var node = pos({
type: type + '.close',
rest: this.input,
suffix: m[1],
val: m[0]
});
if (!this.isType(parent, type)) {
if (this.options.strict) {
throw new Error('missing opening "' + type + '"');
}
this.setCount--;
node.escaped = true;
return node;
}
if (node.suffix === '\\') {
parent.escaped = true;
node.escaped = true;
}
parent.nodes.push(node);
define(node, 'parent', parent);
});
return this;
},
/**
* Capture end-of-string
*/
eos: function() {
var pos = this.position();
if (this.input) return;
var prev = this.prev();
while (prev.type !== 'root' && !prev.visited) {
if (this.options.strict === true) {
throw new SyntaxError('invalid syntax:' + util.inspect(prev, null, 2));
}
if (!hasDelims(prev)) {
prev.parent.escaped = true;
prev.escaped = true;
}
visit(prev, function(node) {
if (!hasDelims(node.parent)) {
node.parent.escaped = true;
node.escaped = true;
}
});
prev = prev.parent;
}
var tok = pos({
type: 'eos',
val: this.append || ''
});
define(tok, 'parent', this.ast);
return tok;
},
/**
* Run parsers to advance the cursor position
*/
next: function() {
var parsed = this.parsed;
var len = this.types.length;
var idx = -1;
var tok;
while (++idx < len) {
if ((tok = this.parsers[this.types[idx]].call(this))) {
define(tok, 'rest', this.input);
define(tok, 'parsed', parsed);
this.last = tok;
return tok;
}
}
},
/**
* Parse the given string.
* @return {Array}
*/
parse: function(input) {
if (typeof input !== 'string') {
throw new TypeError('expected a string');
}
this.init(this.options);
this.orig = input;
this.input = input;
var self = this;
function parse() {
// check input before calling `.next()`
input = self.input;
// get the next AST ndoe
var node = self.next();
if (node) {
var prev = self.prev();
if (prev) {
define(node, 'parent', prev);
if (prev.nodes) {
prev.nodes.push(node);
}
}
if (self.sets.hasOwnProperty(prev.type)) {
self.currentType = prev.type;
}
}
// if we got here but input is not changed, throw an error
if (self.input && input === self.input) {
throw new Error('no parsers registered for: "' + self.input.slice(0, 5) + '"');
}
}
while (this.input) parse();
if (this.stack.length && this.options.strict) {
var node = this.stack.pop();
throw this.error('missing opening ' + node.type + ': "' + this.orig + '"');
}
var eos = this.eos();
var tok = this.prev();
if (tok.type !== 'eos') {
this.ast.nodes.push(eos);
}
return this.ast;
}
};
/**
* Visit `node` with the given `fn`
*/
function visit(node, fn) {
if (!node.visited) {
define(node, 'visited', true);
return node.nodes ? mapVisit(node.nodes, fn) : fn(node);
}
return node;
}
/**
* Map visit over array of `nodes`.
*/
function mapVisit(nodes, fn) {
var len = nodes.length;
var idx = -1;
while (++idx < len) {
visit(nodes[idx], fn);
}
}
function hasOpen(node) {
return node.nodes && node.nodes[0].type === (node.type + '.open');
}
function hasClose(node) {
return node.nodes && utils.last(node.nodes).type === (node.type + '.close');
}
function hasDelims(node) {
return hasOpen(node) && hasClose(node);
}
/**
* Expose `Parser`
*/
module.exports = Parser;
+14
View File
@@ -0,0 +1,14 @@
'use strict';
var define = require('define-property');
/**
* Store position for a node
*/
module.exports = function Position(start, parser) {
this.start = start;
this.end = { line: parser.line, column: parser.column };
define(this, 'content', parser.orig);
define(this, 'source', parser.options.source);
};
+145
View File
@@ -0,0 +1,145 @@
'use strict';
var fs = require('fs');
var path = require('path');
var define = require('define-property');
var utils = require('./utils');
/**
* Expose `mixin()`.
* This code is based on `source-maps-support.js` in reworkcss/css
* https://github.com/reworkcss/css/blob/master/lib/stringify/source-map-support.js
* Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
*/
module.exports = mixin;
/**
* Mixin source map support into `compiler`.
*
* @param {Object} `compiler`
* @api public
*/
function mixin(compiler) {
define(compiler, '_comment', compiler.comment);
compiler.map = new utils.SourceMap.SourceMapGenerator();
compiler.position = { line: 1, column: 1 };
compiler.content = {};
compiler.files = {};
for (var key in exports) {
define(compiler, key, exports[key]);
}
}
/**
* Update position.
*
* @param {String} str
*/
exports.updatePosition = function(str) {
var lines = str.match(/\n/g);
if (lines) this.position.line += lines.length;
var i = str.lastIndexOf('\n');
this.position.column = ~i ? str.length - i : this.position.column + str.length;
};
/**
* Emit `str` with `position`.
*
* @param {String} str
* @param {Object} [pos]
* @return {String}
*/
exports.emit = function(str, node) {
var position = node.position || {};
var source = position.source;
if (source) {
if (position.filepath) {
source = utils.unixify(position.filepath);
}
this.map.addMapping({
source: source,
generated: {
line: this.position.line,
column: Math.max(this.position.column - 1, 0)
},
original: {
line: position.start.line,
column: position.start.column - 1
}
});
if (position.content) {
this.addContent(source, position);
}
if (position.filepath) {
this.addFile(source, position);
}
this.updatePosition(str);
this.output += str;
}
return str;
};
/**
* Adds a file to the source map output if it has not already been added
* @param {String} `file`
* @param {Object} `pos`
*/
exports.addFile = function(file, position) {
if (typeof position.content !== 'string') return;
if (Object.prototype.hasOwnProperty.call(this.files, file)) return;
this.files[file] = position.content;
};
/**
* Adds a content source to the source map output if it has not already been added
* @param {String} `source`
* @param {Object} `position`
*/
exports.addContent = function(source, position) {
if (typeof position.content !== 'string') return;
if (Object.prototype.hasOwnProperty.call(this.content, source)) return;
this.map.setSourceContent(source, position.content);
};
/**
* Applies any original source maps to the output and embeds the source file
* contents in the source map.
*/
exports.applySourceMaps = function() {
Object.keys(this.files).forEach(function(file) {
var content = this.files[file];
this.map.setSourceContent(file, content);
if (this.options.inputSourcemaps === true) {
var originalMap = utils.sourceMapResolve.resolveSync(content, file, fs.readFileSync);
if (originalMap) {
var map = new utils.SourceMap.SourceMapConsumer(originalMap.map);
var relativeTo = originalMap.sourcesRelativeTo;
this.map.applySourceMap(map, file, utils.unixify(path.dirname(relativeTo)));
}
}
}, this);
};
/**
* Process comments, drops sourceMap comments.
* @param {Object} node
*/
exports.comment = function(node) {
if (/^# sourceMappingURL=/.test(node.comment)) {
return this.emit('', node.position);
}
return this._comment(node);
};
+48
View File
@@ -0,0 +1,48 @@
'use strict';
/**
* Module dependencies
*/
exports.extend = require('extend-shallow');
exports.SourceMap = require('source-map');
exports.sourceMapResolve = require('source-map-resolve');
/**
* Convert backslash in the given string to forward slashes
*/
exports.unixify = function(fp) {
return fp.split(/\\+/).join('/');
};
/**
* Return true if `val` is a non-empty string
*
* @param {String} `str`
* @return {Boolean}
*/
exports.isString = function(str) {
return str && typeof str === 'string';
};
/**
* Cast `val` to an array
* @return {Array}
*/
exports.arrayify = function(val) {
if (typeof val === 'string') return [val];
return val ? (Array.isArray(val) ? val : [val]) : [];
};
/**
* Get the last `n` element from the given `array`
* @param {Array} `array`
* @return {*}
*/
exports.last = function(arr, n) {
return arr[arr.length - (n || 1)];
};
+1
View File
@@ -0,0 +1 @@
../atob/bin/atob.js
@@ -0,0 +1,230 @@
At your option you may choose either of the following licenses:
* The MIT License (MIT)
* The Apache License 2.0 (Apache-2.0)
The MIT License (MIT)
Copyright (c) 2015 AJ ONeal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2015 AJ ONeal
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -0,0 +1,319 @@
Creative Commons Legal Code
Attribution 3.0 Unported
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
DAMAGES RESULTING FROM ITS USE.
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
CONDITIONS.
1. Definitions
a. "Adaptation" means a work based upon the Work, or upon the Work and
other pre-existing works, such as a translation, adaptation,
derivative work, arrangement of music or other alterations of a
literary or artistic work, or phonogram or performance and includes
cinematographic adaptations or any other form in which the Work may be
recast, transformed, or adapted including in any form recognizably
derived from the original, except that a work that constitutes a
Collection will not be considered an Adaptation for the purpose of
this License. For the avoidance of doubt, where the Work is a musical
work, performance or phonogram, the synchronization of the Work in
timed-relation with a moving image ("synching") will be considered an
Adaptation for the purpose of this License.
b. "Collection" means a collection of literary or artistic works, such as
encyclopedias and anthologies, or performances, phonograms or
broadcasts, or other works or subject matter other than works listed
in Section 1(f) below, which, by reason of the selection and
arrangement of their contents, constitute intellectual creations, in
which the Work is included in its entirety in unmodified form along
with one or more other contributions, each constituting separate and
independent works in themselves, which together are assembled into a
collective whole. A work that constitutes a Collection will not be
considered an Adaptation (as defined above) for the purposes of this
License.
c. "Distribute" means to make available to the public the original and
copies of the Work or Adaptation, as appropriate, through sale or
other transfer of ownership.
d. "Licensor" means the individual, individuals, entity or entities that
offer(s) the Work under the terms of this License.
e. "Original Author" means, in the case of a literary or artistic work,
the individual, individuals, entity or entities who created the Work
or if no individual or entity can be identified, the publisher; and in
addition (i) in the case of a performance the actors, singers,
musicians, dancers, and other persons who act, sing, deliver, declaim,
play in, interpret or otherwise perform literary or artistic works or
expressions of folklore; (ii) in the case of a phonogram the producer
being the person or legal entity who first fixes the sounds of a
performance or other sounds; and, (iii) in the case of broadcasts, the
organization that transmits the broadcast.
f. "Work" means the literary and/or artistic work offered under the terms
of this License including without limitation any production in the
literary, scientific and artistic domain, whatever may be the mode or
form of its expression including digital form, such as a book,
pamphlet and other writing; a lecture, address, sermon or other work
of the same nature; a dramatic or dramatico-musical work; a
choreographic work or entertainment in dumb show; a musical
composition with or without words; a cinematographic work to which are
assimilated works expressed by a process analogous to cinematography;
a work of drawing, painting, architecture, sculpture, engraving or
lithography; a photographic work to which are assimilated works
expressed by a process analogous to photography; a work of applied
art; an illustration, map, plan, sketch or three-dimensional work
relative to geography, topography, architecture or science; a
performance; a broadcast; a phonogram; a compilation of data to the
extent it is protected as a copyrightable work; or a work performed by
a variety or circus performer to the extent it is not otherwise
considered a literary or artistic work.
g. "You" means an individual or entity exercising rights under this
License who has not previously violated the terms of this License with
respect to the Work, or who has received express permission from the
Licensor to exercise rights under this License despite a previous
violation.
h. "Publicly Perform" means to perform public recitations of the Work and
to communicate to the public those public recitations, by any means or
process, including by wire or wireless means or public digital
performances; to make available to the public Works in such a way that
members of the public may access these Works from a place and at a
place individually chosen by them; to perform the Work to the public
by any means or process and the communication to the public of the
performances of the Work, including by public digital performance; to
broadcast and rebroadcast the Work by any means including signs,
sounds or images.
i. "Reproduce" means to make copies of the Work by any means including
without limitation by sound or visual recordings and the right of
fixation and reproducing fixations of the Work, including storage of a
protected performance or phonogram in digital form or other electronic
medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce,
limit, or restrict any uses free from copyright or rights arising from
limitations or exceptions that are provided for in connection with the
copyright protection under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License,
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
perpetual (for the duration of the applicable copyright) license to
exercise the rights in the Work as stated below:
a. to Reproduce the Work, to incorporate the Work into one or more
Collections, and to Reproduce the Work as incorporated in the
Collections;
b. to create and Reproduce Adaptations provided that any such Adaptation,
including any translation in any medium, takes reasonable steps to
clearly label, demarcate or otherwise identify that changes were made
to the original Work. For example, a translation could be marked "The
original work was translated from English to Spanish," or a
modification could indicate "The original work has been modified.";
c. to Distribute and Publicly Perform the Work including as incorporated
in Collections; and,
d. to Distribute and Publicly Perform Adaptations.
e. For the avoidance of doubt:
i. Non-waivable Compulsory License Schemes. In those jurisdictions in
which the right to collect royalties through any statutory or
compulsory licensing scheme cannot be waived, the Licensor
reserves the exclusive right to collect such royalties for any
exercise by You of the rights granted under this License;
ii. Waivable Compulsory License Schemes. In those jurisdictions in
which the right to collect royalties through any statutory or
compulsory licensing scheme can be waived, the Licensor waives the
exclusive right to collect such royalties for any exercise by You
of the rights granted under this License; and,
iii. Voluntary License Schemes. The Licensor waives the right to
collect royalties, whether individually or, in the event that the
Licensor is a member of a collecting society that administers
voluntary licensing schemes, via that society, from any exercise
by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now
known or hereafter devised. The above rights include the right to make
such modifications as are technically necessary to exercise the rights in
other media and formats. Subject to Section 8(f), all rights not expressly
granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made
subject to and limited by the following restrictions:
a. You may Distribute or Publicly Perform the Work only under the terms
of this License. You must include a copy of, or the Uniform Resource
Identifier (URI) for, this License with every copy of the Work You
Distribute or Publicly Perform. You may not offer or impose any terms
on the Work that restrict the terms of this License or the ability of
the recipient of the Work to exercise the rights granted to that
recipient under the terms of the License. You may not sublicense the
Work. You must keep intact all notices that refer to this License and
to the disclaimer of warranties with every copy of the Work You
Distribute or Publicly Perform. When You Distribute or Publicly
Perform the Work, You may not impose any effective technological
measures on the Work that restrict the ability of a recipient of the
Work from You to exercise the rights granted to that recipient under
the terms of the License. This Section 4(a) applies to the Work as
incorporated in a Collection, but this does not require the Collection
apart from the Work itself to be made subject to the terms of this
License. If You create a Collection, upon notice from any Licensor You
must, to the extent practicable, remove from the Collection any credit
as required by Section 4(b), as requested. If You create an
Adaptation, upon notice from any Licensor You must, to the extent
practicable, remove from the Adaptation any credit as required by
Section 4(b), as requested.
b. If You Distribute, or Publicly Perform the Work or any Adaptations or
Collections, You must, unless a request has been made pursuant to
Section 4(a), keep intact all copyright notices for the Work and
provide, reasonable to the medium or means You are utilizing: (i) the
name of the Original Author (or pseudonym, if applicable) if supplied,
and/or if the Original Author and/or Licensor designate another party
or parties (e.g., a sponsor institute, publishing entity, journal) for
attribution ("Attribution Parties") in Licensor's copyright notice,
terms of service or by other reasonable means, the name of such party
or parties; (ii) the title of the Work if supplied; (iii) to the
extent reasonably practicable, the URI, if any, that Licensor
specifies to be associated with the Work, unless such URI does not
refer to the copyright notice or licensing information for the Work;
and (iv) , consistent with Section 3(b), in the case of an Adaptation,
a credit identifying the use of the Work in the Adaptation (e.g.,
"French translation of the Work by Original Author," or "Screenplay
based on original Work by Original Author"). The credit required by
this Section 4 (b) may be implemented in any reasonable manner;
provided, however, that in the case of a Adaptation or Collection, at
a minimum such credit will appear, if a credit for all contributing
authors of the Adaptation or Collection appears, then as part of these
credits and in a manner at least as prominent as the credits for the
other contributing authors. For the avoidance of doubt, You may only
use the credit required by this Section for the purpose of attribution
in the manner set out above and, by exercising Your rights under this
License, You may not implicitly or explicitly assert or imply any
connection with, sponsorship or endorsement by the Original Author,
Licensor and/or Attribution Parties, as appropriate, of You or Your
use of the Work, without the separate, express prior written
permission of the Original Author, Licensor and/or Attribution
Parties.
c. Except as otherwise agreed in writing by the Licensor or as may be
otherwise permitted by applicable law, if You Reproduce, Distribute or
Publicly Perform the Work either by itself or as part of any
Adaptations or Collections, You must not distort, mutilate, modify or
take other derogatory action in relation to the Work which would be
prejudicial to the Original Author's honor or reputation. Licensor
agrees that in those jurisdictions (e.g. Japan), in which any exercise
of the right granted in Section 3(b) of this License (the right to
make Adaptations) would be deemed to be a distortion, mutilation,
modification or other derogatory action prejudicial to the Original
Author's honor and reputation, the Licensor will waive or not assert,
as appropriate, this Section, to the fullest extent permitted by the
applicable national law, to enable You to reasonably exercise Your
right under Section 3(b) of this License (right to make Adaptations)
but not otherwise.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
a. This License and the rights granted hereunder will terminate
automatically upon any breach by You of the terms of this License.
Individuals or entities who have received Adaptations or Collections
from You under this License, however, will not have their licenses
terminated provided such individuals or entities remain in full
compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
survive any termination of this License.
b. Subject to the above terms and conditions, the license granted here is
perpetual (for the duration of the applicable copyright in the Work).
Notwithstanding the above, Licensor reserves the right to release the
Work under different license terms or to stop distributing the Work at
any time; provided, however that any such election will not serve to
withdraw this License (or any other license that has been, or is
required to be, granted under the terms of this License), and this
License will continue in full force and effect unless terminated as
stated above.
8. Miscellaneous
a. Each time You Distribute or Publicly Perform the Work or a Collection,
the Licensor offers to the recipient a license to the Work on the same
terms and conditions as the license granted to You under this License.
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
offers to the recipient a license to the original Work on the same
terms and conditions as the license granted to You under this License.
c. If any provision of this License is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this License, and without further action
by the parties to this agreement, such provision shall be reformed to
the minimum extent necessary to make such provision valid and
enforceable.
d. No term or provision of this License shall be deemed waived and no
breach consented to unless such waiver or consent shall be in writing
and signed by the party to be charged with such waiver or consent.
e. This License constitutes the entire agreement between the parties with
respect to the Work licensed here. There are no understandings,
agreements or representations with respect to the Work not specified
here. Licensor shall not be bound by any additional provisions that
may appear in any communication from You. This License may not be
modified without the mutual written agreement of the Licensor and You.
f. The rights granted under, and the subject matter referenced, in this
License were drafted utilizing the terminology of the Berne Convention
for the Protection of Literary and Artistic Works (as amended on
September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
and the Universal Copyright Convention (as revised on July 24, 1971).
These rights and subject matter take effect in the relevant
jurisdiction in which the License terms are sought to be enforced
according to the corresponding provisions of the implementation of
those treaty provisions in the applicable national law. If the
standard suite of rights granted under applicable copyright law
includes additional rights not granted under this License, such
additional rights are deemed to be included in the License; this
License is not intended to restrict the license of any rights under
applicable law.
Creative Commons Notice
Creative Commons is not a party to this License, and makes no warranty
whatsoever in connection with the Work. Creative Commons will not be
liable to You or any party on any legal theory for any damages
whatsoever, including without limitation any general, special,
incidental or consequential damages arising in connection to this
license. Notwithstanding the foregoing two (2) sentences, if Creative
Commons has expressly identified itself as the Licensor hereunder, it
shall have all rights and obligations of Licensor.
Except for the limited purpose of indicating to the public that the
Work is licensed under the CCPL, Creative Commons does not authorize
the use by either party of the trademark "Creative Commons" or any
related trademark or logo of Creative Commons without the prior
written consent of Creative Commons. Any permitted use will be in
compliance with Creative Commons' then-current trademark usage
guidelines, as may be published on its website or otherwise made
available upon request from time to time. For the avoidance of doubt,
this trademark restriction does not form part of this License.
Creative Commons may be contacted at http://creativecommons.org/.
@@ -0,0 +1,49 @@
atob
===
| **atob**
| [btoa](https://git.coolaj86.com/coolaj86/btoa.js)
| [unibabel.js](https://git.coolaj86.com/coolaj86/unibabel.js)
| Sponsored by [ppl](https://ppl.family)
Uses `Buffer` to emulate the exact functionality of the browser's atob.
Note: Unicode may be handled incorrectly (like the browser).
It turns base64-encoded <strong>a</strong>scii data back **to** <strong>b</strong>inary.
```javascript
(function () {
"use strict";
var atob = require('atob');
var b64 = "SGVsbG8sIFdvcmxkIQ==";
var bin = atob(b64);
console.log(bin); // "Hello, World!"
}());
```
### Need Unicode and Binary Support in the Browser?
Check out [unibabel.js](https://git.coolaj86.com/coolaj86/unibabel.js)
Changelog
=======
* v2.1.0 address a few issues and PRs, update URLs
* v2.0.0 provide browser version for ios web workers
* v1.2.0 provide (empty) browser version
* v1.1.3 add MIT license
* v1.1.2 node only
LICENSE
=======
Code copyright 2012-2018 AJ ONeal
Dual-licensed MIT and Apache-2.0
Docs copyright 2012-2018 AJ ONeal
Docs released under [Creative Commons](https://git.coolaj86.com/coolaj86/atob.js/blob/master/LICENSE.DOCS).
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env node
'use strict';
var atob = require('../node-atob');
var str = process.argv[2];
console.log(atob(str));
@@ -0,0 +1,25 @@
{
"name": "atob",
"description": "atob for isomorphic environments",
"main": "browser-atob.js",
"authors": [
"AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com)"
],
"license": "(MIT OR Apache-2.0)",
"keywords": [
"atob",
"browser"
],
"homepage": "https://github.com/node-browser-compat/atob",
"moduleType": [
"globals"
],
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"version": "2.0.3"
}
@@ -0,0 +1,44 @@
(function (w) {
"use strict";
function findBest(atobNative) {
// normal window
if ('function' === typeof atobNative) { return atobNative; }
// browserify (web worker)
if ('function' === typeof Buffer) {
return function atobBrowserify(a) {
//!! Deliberately using an API that's deprecated in node.js because
//!! this file is for browsers and we expect them to cope with it.
//!! Discussion: github.com/node-browser-compat/atob/pull/9
return new Buffer(a, 'base64').toString('binary');
};
}
// ios web worker with base64js
if ('object' === typeof w.base64js) {
// bufferToBinaryString
// https://git.coolaj86.com/coolaj86/unibabel.js/blob/master/index.js#L50
return function atobWebWorker_iOS(a) {
var buf = w.base64js.b64ToByteArray(a);
return Array.prototype.map.call(buf, function (ch) {
return String.fromCharCode(ch);
}).join('');
};
}
return function () {
// ios web worker without base64js
throw new Error("You're probably in an old browser or an iOS webworker." +
" It might help to include beatgammit's base64-js.");
};
}
var atobBest = findBest(w.atob);
w.atob = atobBest;
if ((typeof module === 'object') && module && module.exports) {
module.exports = atobBest;
}
}(window));
@@ -0,0 +1,7 @@
"use strict";
function atob(str) {
return Buffer.from(str, 'base64').toString('binary');
}
module.exports = atob.atob = atob;
@@ -0,0 +1,53 @@
{
"_from": "atob@^2.1.1",
"_id": "atob@2.1.1",
"_inBundle": false,
"_integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
"_location": "/snapdragon/atob",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "atob@^2.1.1",
"name": "atob",
"escapedName": "atob",
"rawSpec": "^2.1.1",
"saveSpec": null,
"fetchSpec": "^2.1.1"
},
"_requiredBy": [
"/snapdragon/source-map-resolve"
],
"_resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
"_shasum": "ae2d5a729477f289d60dd7f96a6314a22dd6c22a",
"_spec": "atob@^2.1.1",
"_where": "/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah/node_modules/snapdragon/node_modules/source-map-resolve",
"author": {
"name": "AJ ONeal",
"email": "coolaj86@gmail.com",
"url": "https://coolaj86.com"
},
"bin": {
"atob": "bin/atob.js"
},
"browser": "browser-atob.js",
"bundleDependencies": false,
"deprecated": false,
"description": "atob for Node.JS and Linux / Mac / Windows CLI (it's a one-liner)",
"engines": {
"node": ">= 4.5.0"
},
"homepage": "https://git.coolaj86.com/coolaj86/atob.js.git",
"keywords": [
"atob",
"browser"
],
"license": "(MIT OR Apache-2.0)",
"main": "node-atob.js",
"name": "atob",
"repository": {
"type": "git",
"url": "git://git.coolaj86.com/coolaj86/atob.js.git"
},
"version": "2.1.1"
}
@@ -0,0 +1,18 @@
(function () {
"use strict";
var atob = require('.');
var encoded = "SGVsbG8sIFdvcmxkIQ=="
var unencoded = "Hello, World!";
/*
, encoded = "SGVsbG8sIBZM"
, unencoded = "Hello, 世界"
*/
if (unencoded !== atob(encoded)) {
console.log('[FAIL]', unencoded, atob(encoded));
return;
}
console.log('[PASS] all tests pass');
}());
@@ -0,0 +1 @@
repo_token: SIAeZjKYlHK74rbcFvNHMUzjRiMpflxve
@@ -0,0 +1,11 @@
{
"env": {
"browser": true,
"node": true
},
"rules": {
"no-console": 0,
"no-empty": [1, { "allowEmptyCatch": true }]
},
"extends": "eslint:recommended"
}
@@ -0,0 +1,9 @@
support
test
examples
example
*.sock
dist
yarn.lock
coverage
bower.json
@@ -0,0 +1,14 @@
language: node_js
node_js:
- "6"
- "5"
- "4"
install:
- make node_modules
script:
- make lint
- make test
- make coveralls
@@ -0,0 +1,362 @@
2.6.9 / 2017-09-22
==================
* remove ReDoS regexp in %o formatter (#504)
2.6.8 / 2017-05-18
==================
* Fix: Check for undefined on browser globals (#462, @marbemac)
2.6.7 / 2017-05-16
==================
* Fix: Update ms to 2.0.0 to fix regular expression denial of service vulnerability (#458, @hubdotcom)
* Fix: Inline extend function in node implementation (#452, @dougwilson)
* Docs: Fix typo (#455, @msasad)
2.6.5 / 2017-04-27
==================
* Fix: null reference check on window.documentElement.style.WebkitAppearance (#447, @thebigredgeek)
* Misc: clean up browser reference checks (#447, @thebigredgeek)
* Misc: add npm-debug.log to .gitignore (@thebigredgeek)
2.6.4 / 2017-04-20
==================
* Fix: bug that would occure if process.env.DEBUG is a non-string value. (#444, @LucianBuzzo)
* Chore: ignore bower.json in npm installations. (#437, @joaovieira)
* Misc: update "ms" to v0.7.3 (@tootallnate)
2.6.3 / 2017-03-13
==================
* Fix: Electron reference to `process.env.DEBUG` (#431, @paulcbetts)
* Docs: Changelog fix (@thebigredgeek)
2.6.2 / 2017-03-10
==================
* Fix: DEBUG_MAX_ARRAY_LENGTH (#420, @slavaGanzin)
* Docs: Add backers and sponsors from Open Collective (#422, @piamancini)
* Docs: Add Slackin invite badge (@tootallnate)
2.6.1 / 2017-02-10
==================
* Fix: Module's `export default` syntax fix for IE8 `Expected identifier` error
* Fix: Whitelist DEBUG_FD for values 1 and 2 only (#415, @pi0)
* Fix: IE8 "Expected identifier" error (#414, @vgoma)
* Fix: Namespaces would not disable once enabled (#409, @musikov)
2.6.0 / 2016-12-28
==================
* Fix: added better null pointer checks for browser useColors (@thebigredgeek)
* Improvement: removed explicit `window.debug` export (#404, @tootallnate)
* Improvement: deprecated `DEBUG_FD` environment variable (#405, @tootallnate)
2.5.2 / 2016-12-25
==================
* Fix: reference error on window within webworkers (#393, @KlausTrainer)
* Docs: fixed README typo (#391, @lurch)
* Docs: added notice about v3 api discussion (@thebigredgeek)
2.5.1 / 2016-12-20
==================
* Fix: babel-core compatibility
2.5.0 / 2016-12-20
==================
* Fix: wrong reference in bower file (@thebigredgeek)
* Fix: webworker compatibility (@thebigredgeek)
* Fix: output formatting issue (#388, @kribblo)
* Fix: babel-loader compatibility (#383, @escwald)
* Misc: removed built asset from repo and publications (@thebigredgeek)
* Misc: moved source files to /src (#378, @yamikuronue)
* Test: added karma integration and replaced babel with browserify for browser tests (#378, @yamikuronue)
* Test: coveralls integration (#378, @yamikuronue)
* Docs: simplified language in the opening paragraph (#373, @yamikuronue)
2.4.5 / 2016-12-17
==================
* Fix: `navigator` undefined in Rhino (#376, @jochenberger)
* Fix: custom log function (#379, @hsiliev)
* Improvement: bit of cleanup + linting fixes (@thebigredgeek)
* Improvement: rm non-maintainted `dist/` dir (#375, @freewil)
* Docs: simplified language in the opening paragraph. (#373, @yamikuronue)
2.4.4 / 2016-12-14
==================
* Fix: work around debug being loaded in preload scripts for electron (#368, @paulcbetts)
2.4.3 / 2016-12-14
==================
* Fix: navigation.userAgent error for react native (#364, @escwald)
2.4.2 / 2016-12-14
==================
* Fix: browser colors (#367, @tootallnate)
* Misc: travis ci integration (@thebigredgeek)
* Misc: added linting and testing boilerplate with sanity check (@thebigredgeek)
2.4.1 / 2016-12-13
==================
* Fix: typo that broke the package (#356)
2.4.0 / 2016-12-13
==================
* Fix: bower.json references unbuilt src entry point (#342, @justmatt)
* Fix: revert "handle regex special characters" (@tootallnate)
* Feature: configurable util.inspect()`options for NodeJS (#327, @tootallnate)
* Feature: %O`(big O) pretty-prints objects (#322, @tootallnate)
* Improvement: allow colors in workers (#335, @botverse)
* Improvement: use same color for same namespace. (#338, @lchenay)
2.3.3 / 2016-11-09
==================
* Fix: Catch `JSON.stringify()` errors (#195, Jovan Alleyne)
* Fix: Returning `localStorage` saved values (#331, Levi Thomason)
* Improvement: Don't create an empty object when no `process` (Nathan Rajlich)
2.3.2 / 2016-11-09
==================
* Fix: be super-safe in index.js as well (@TooTallNate)
* Fix: should check whether process exists (Tom Newby)
2.3.1 / 2016-11-09
==================
* Fix: Added electron compatibility (#324, @paulcbetts)
* Improvement: Added performance optimizations (@tootallnate)
* Readme: Corrected PowerShell environment variable example (#252, @gimre)
* Misc: Removed yarn lock file from source control (#321, @fengmk2)
2.3.0 / 2016-11-07
==================
* Fix: Consistent placement of ms diff at end of output (#215, @gorangajic)
* Fix: Escaping of regex special characters in namespace strings (#250, @zacronos)
* Fix: Fixed bug causing crash on react-native (#282, @vkarpov15)
* Feature: Enabled ES6+ compatible import via default export (#212 @bucaran)
* Feature: Added %O formatter to reflect Chrome's console.log capability (#279, @oncletom)
* Package: Update "ms" to 0.7.2 (#315, @DevSide)
* Package: removed superfluous version property from bower.json (#207 @kkirsche)
* Readme: fix USE_COLORS to DEBUG_COLORS
* Readme: Doc fixes for format string sugar (#269, @mlucool)
* Readme: Updated docs for DEBUG_FD and DEBUG_COLORS environment variables (#232, @mattlyons0)
* Readme: doc fixes for PowerShell (#271 #243, @exoticknight @unreadable)
* Readme: better docs for browser support (#224, @matthewmueller)
* Tooling: Added yarn integration for development (#317, @thebigredgeek)
* Misc: Renamed History.md to CHANGELOG.md (@thebigredgeek)
* Misc: Added license file (#226 #274, @CantemoInternal @sdaitzman)
* Misc: Updated contributors (@thebigredgeek)
2.2.0 / 2015-05-09
==================
* package: update "ms" to v0.7.1 (#202, @dougwilson)
* README: add logging to file example (#193, @DanielOchoa)
* README: fixed a typo (#191, @amir-s)
* browser: expose `storage` (#190, @stephenmathieson)
* Makefile: add a `distclean` target (#189, @stephenmathieson)
2.1.3 / 2015-03-13
==================
* Updated stdout/stderr example (#186)
* Updated example/stdout.js to match debug current behaviour
* Renamed example/stderr.js to stdout.js
* Update Readme.md (#184)
* replace high intensity foreground color for bold (#182, #183)
2.1.2 / 2015-03-01
==================
* dist: recompile
* update "ms" to v0.7.0
* package: update "browserify" to v9.0.3
* component: fix "ms.js" repo location
* changed bower package name
* updated documentation about using debug in a browser
* fix: security error on safari (#167, #168, @yields)
2.1.1 / 2014-12-29
==================
* browser: use `typeof` to check for `console` existence
* browser: check for `console.log` truthiness (fix IE 8/9)
* browser: add support for Chrome apps
* Readme: added Windows usage remarks
* Add `bower.json` to properly support bower install
2.1.0 / 2014-10-15
==================
* node: implement `DEBUG_FD` env variable support
* package: update "browserify" to v6.1.0
* package: add "license" field to package.json (#135, @panuhorsmalahti)
2.0.0 / 2014-09-01
==================
* package: update "browserify" to v5.11.0
* node: use stderr rather than stdout for logging (#29, @stephenmathieson)
1.0.4 / 2014-07-15
==================
* dist: recompile
* example: remove `console.info()` log usage
* example: add "Content-Type" UTF-8 header to browser example
* browser: place %c marker after the space character
* browser: reset the "content" color via `color: inherit`
* browser: add colors support for Firefox >= v31
* debug: prefer an instance `log()` function over the global one (#119)
* Readme: update documentation about styled console logs for FF v31 (#116, @wryk)
1.0.3 / 2014-07-09
==================
* Add support for multiple wildcards in namespaces (#122, @seegno)
* browser: fix lint
1.0.2 / 2014-06-10
==================
* browser: update color palette (#113, @gscottolson)
* common: make console logging function configurable (#108, @timoxley)
* node: fix %o colors on old node <= 0.8.x
* Makefile: find node path using shell/which (#109, @timoxley)
1.0.1 / 2014-06-06
==================
* browser: use `removeItem()` to clear localStorage
* browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
* package: add "contributors" section
* node: fix comment typo
* README: list authors
1.0.0 / 2014-06-04
==================
* make ms diff be global, not be scope
* debug: ignore empty strings in enable()
* node: make DEBUG_COLORS able to disable coloring
* *: export the `colors` array
* npmignore: don't publish the `dist` dir
* Makefile: refactor to use browserify
* package: add "browserify" as a dev dependency
* Readme: add Web Inspector Colors section
* node: reset terminal color for the debug content
* node: map "%o" to `util.inspect()`
* browser: map "%j" to `JSON.stringify()`
* debug: add custom "formatters"
* debug: use "ms" module for humanizing the diff
* Readme: add "bash" syntax highlighting
* browser: add Firebug color support
* browser: add colors for WebKit browsers
* node: apply log to `console`
* rewrite: abstract common logic for Node & browsers
* add .jshintrc file
0.8.1 / 2014-04-14
==================
* package: re-add the "component" section
0.8.0 / 2014-03-30
==================
* add `enable()` method for nodejs. Closes #27
* change from stderr to stdout
* remove unnecessary index.js file
0.7.4 / 2013-11-13
==================
* remove "browserify" key from package.json (fixes something in browserify)
0.7.3 / 2013-10-30
==================
* fix: catch localStorage security error when cookies are blocked (Chrome)
* add debug(err) support. Closes #46
* add .browser prop to package.json. Closes #42
0.7.2 / 2013-02-06
==================
* fix package.json
* fix: Mobile Safari (private mode) is broken with debug
* fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
0.7.1 / 2013-02-05
==================
* add repository URL to package.json
* add DEBUG_COLORED to force colored output
* add browserify support
* fix component. Closes #24
0.7.0 / 2012-05-04
==================
* Added .component to package.json
* Added debug.component.js build
0.6.0 / 2012-03-16
==================
* Added support for "-" prefix in DEBUG [Vinay Pulim]
* Added `.enabled` flag to the node version [TooTallNate]
0.5.0 / 2012-02-02
==================
* Added: humanize diffs. Closes #8
* Added `debug.disable()` to the CS variant
* Removed padding. Closes #10
* Fixed: persist client-side variant again. Closes #9
0.4.0 / 2012-02-01
==================
* Added browser variant support for older browsers [TooTallNate]
* Added `debug.enable('project:*')` to browser variant [TooTallNate]
* Added padding to diff (moved it to the right)
0.3.0 / 2012-01-26
==================
* Added millisecond diff when isatty, otherwise UTC string
0.2.0 / 2012-01-22
==================
* Added wildcard support
0.1.0 / 2011-12-02
==================
* Added: remove colors unless stderr isatty [TooTallNate]
0.0.1 / 2010-01-03
==================
* Initial release
@@ -0,0 +1,19 @@
(The MIT License)
Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the 'Software'), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,50 @@
# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
# BIN directory
BIN := $(THIS_DIR)/node_modules/.bin
# Path
PATH := node_modules/.bin:$(PATH)
SHELL := /bin/bash
# applications
NODE ?= $(shell which node)
YARN ?= $(shell which yarn)
PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm))
BROWSERIFY ?= $(NODE) $(BIN)/browserify
.FORCE:
install: node_modules
node_modules: package.json
@NODE_ENV= $(PKG) install
@touch node_modules
lint: .FORCE
eslint browser.js debug.js index.js node.js
test-node: .FORCE
istanbul cover node_modules/mocha/bin/_mocha -- test/**.js
test-browser: .FORCE
mkdir -p dist
@$(BROWSERIFY) \
--standalone debug \
. > dist/debug.js
karma start --single-run
rimraf dist
test: .FORCE
concurrently \
"make test-node" \
"make test-browser"
coveralls:
cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
.PHONY: all install clean distclean
@@ -0,0 +1,312 @@
# debug
[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug) [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master) [![Slack](https://visionmedia-community-slackin.now.sh/badge.svg)](https://visionmedia-community-slackin.now.sh/) [![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers)
[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)
A tiny node.js debugging utility modelled after node core's debugging technique.
**Discussion around the V3 API is under way [here](https://github.com/visionmedia/debug/issues/370)**
## Installation
```bash
$ npm install debug
```
## Usage
`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
Example _app.js_:
```js
var debug = require('debug')('http')
, http = require('http')
, name = 'My App';
// fake app
debug('booting %s', name);
http.createServer(function(req, res){
debug(req.method + ' ' + req.url);
res.end('hello\n');
}).listen(3000, function(){
debug('listening');
});
// fake worker of some kind
require('./worker');
```
Example _worker.js_:
```js
var debug = require('debug')('worker');
setInterval(function(){
debug('doing some work');
}, 1000);
```
The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)
![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)
#### Windows note
On Windows the environment variable is set using the `set` command.
```cmd
set DEBUG=*,-not_this
```
Note that PowerShell uses different syntax to set environment variables.
```cmd
$env:DEBUG = "*,-not_this"
```
Then, run the program to be debugged as usual.
## Millisecond diff
When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)
When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)
## Conventions
If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
## Wildcards
The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
## Environment Variables
When running through Node.js, you can set a few environment variables that will
change the behavior of the debug logging:
| Name | Purpose |
|-----------|-------------------------------------------------|
| `DEBUG` | Enables/disables specific debugging namespaces. |
| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
| `DEBUG_DEPTH` | Object inspection depth. |
| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
__Note:__ The environment variables beginning with `DEBUG_` end up being
converted into an Options object that gets used with `%o`/`%O` formatters.
See the Node.js documentation for
[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
for the complete list.
## Formatters
Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. Below are the officially supported formatters:
| Formatter | Representation |
|-----------|----------------|
| `%O` | Pretty-print an Object on multiple lines. |
| `%o` | Pretty-print an Object all on a single line. |
| `%s` | String. |
| `%d` | Number (both integer and float). |
| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
| `%%` | Single percent sign ('%'). This does not consume an argument. |
### Custom formatters
You can add custom formatters by extending the `debug.formatters` object. For example, if you wanted to add support for rendering a Buffer as hex with `%h`, you could do something like:
```js
const createDebug = require('debug')
createDebug.formatters.h = (v) => {
return v.toString('hex')
}
// …elsewhere
const debug = createDebug('foo')
debug('this is hex: %h', new Buffer('hello world'))
// foo this is hex: 68656c6c6f20776f726c6421 +0ms
```
## Browser support
You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
if you don't want to build it yourself.
Debug's enable state is currently persisted by `localStorage`.
Consider the situation shown below where you have `worker:a` and `worker:b`,
and wish to debug both. You can enable this using `localStorage.debug`:
```js
localStorage.debug = 'worker:*'
```
And then refresh the page.
```js
a = debug('worker:a');
b = debug('worker:b');
setInterval(function(){
a('doing some work');
}, 1000);
setInterval(function(){
b('doing some work');
}, 1200);
```
#### Web Inspector Colors
Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
option. These are WebKit web inspectors, Firefox ([since version
31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
and the Firebug plugin for Firefox (any version).
Colored output looks something like:
![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)
## Output streams
By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
Example _stdout.js_:
```js
var debug = require('debug');
var error = debug('app:error');
// by default stderr is used
error('goes to stderr!');
var log = debug('app:log');
// set this namespace to log via console.log
log.log = console.log.bind(console); // don't forget to bind to console!
log('goes to stdout');
error('still goes to stderr!');
// set all output to go via console.info
// overrides all per-namespace log settings
debug.log = console.info.bind(console);
error('now goes to stdout via console.info');
log('still goes to stdout, but via console.info now');
```
## Authors
- TJ Holowaychuk
- Nathan Rajlich
- Andrew Rhyne
## Backers
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
## License
(The MIT License)
Copyright (c) 2014-2016 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
{
"name": "debug",
"repo": "visionmedia/debug",
"description": "small debugging utility",
"version": "2.6.9",
"keywords": [
"debug",
"log",
"debugger"
],
"main": "src/browser.js",
"scripts": [
"src/browser.js",
"src/debug.js"
],
"dependencies": {
"rauchg/ms.js": "0.7.1"
}
}
@@ -0,0 +1,70 @@
// Karma configuration
// Generated on Fri Dec 16 2016 13:09:51 GMT+0000 (UTC)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha', 'chai', 'sinon'],
// list of files / patterns to load in the browser
files: [
'dist/debug.js',
'test/*spec.js'
],
// list of files to exclude
exclude: [
'src/node.js'
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
@@ -0,0 +1 @@
module.exports = require('./src/node');
@@ -0,0 +1,88 @@
{
"_from": "debug@^2.2.0",
"_id": "debug@2.6.9",
"_inBundle": false,
"_integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"_location": "/snapdragon/debug",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "debug@^2.2.0",
"name": "debug",
"escapedName": "debug",
"rawSpec": "^2.2.0",
"saveSpec": null,
"fetchSpec": "^2.2.0"
},
"_requiredBy": [
"/snapdragon"
],
"_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"_shasum": "5d128515df134ff327e90a4c93f4e077a536341f",
"_spec": "debug@^2.2.0",
"_where": "/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah/node_modules/snapdragon",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca"
},
"browser": "./src/browser.js",
"bugs": {
"url": "https://github.com/visionmedia/debug/issues"
},
"bundleDependencies": false,
"component": {
"scripts": {
"debug/index.js": "browser.js",
"debug/debug.js": "debug.js"
}
},
"contributors": [
{
"name": "Nathan Rajlich",
"email": "nathan@tootallnate.net",
"url": "http://n8.io"
},
{
"name": "Andrew Rhyne",
"email": "rhyneandrew@gmail.com"
}
],
"dependencies": {
"ms": "2.0.0"
},
"deprecated": false,
"description": "small debugging utility",
"devDependencies": {
"browserify": "9.0.3",
"chai": "^3.5.0",
"concurrently": "^3.1.0",
"coveralls": "^2.11.15",
"eslint": "^3.12.1",
"istanbul": "^0.4.5",
"karma": "^1.3.0",
"karma-chai": "^0.1.0",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.2",
"karma-sinon": "^1.0.5",
"mocha": "^3.2.0",
"mocha-lcov-reporter": "^1.2.0",
"rimraf": "^2.5.4",
"sinon": "^1.17.6",
"sinon-chai": "^2.8.0"
},
"homepage": "https://github.com/visionmedia/debug#readme",
"keywords": [
"debug",
"log",
"debugger"
],
"license": "MIT",
"main": "./src/index.js",
"name": "debug",
"repository": {
"type": "git",
"url": "git://github.com/visionmedia/debug.git"
},
"version": "2.6.9"
}
@@ -0,0 +1,185 @@
/**
* This is the web browser implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = 'undefined' != typeof chrome
&& 'undefined' != typeof chrome.storage
? chrome.storage.local
: localstorage();
/**
* Colors.
*/
exports.colors = [
'lightseagreen',
'forestgreen',
'goldenrod',
'dodgerblue',
'darkorchid',
'crimson'
];
/**
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
* and the Firebug extension (any Firefox version) are known
* to support "%c" CSS customizations.
*
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
return true;
}
// is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
// double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
exports.formatters.j = function(v) {
try {
return JSON.stringify(v);
} catch (err) {
return '[UnexpectedJSONParseError]: ' + err.message;
}
};
/**
* Colorize log arguments if enabled.
*
* @api public
*/
function formatArgs(args) {
var useColors = this.useColors;
args[0] = (useColors ? '%c' : '')
+ this.namespace
+ (useColors ? ' %c' : ' ')
+ args[0]
+ (useColors ? '%c ' : ' ')
+ '+' + exports.humanize(this.diff);
if (!useColors) return;
var c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit')
// the final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
var index = 0;
var lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, function(match) {
if ('%%' === match) return;
index++;
if ('%c' === match) {
// we only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
}
/**
* Invokes `console.log()` when available.
* No-op when `console.log` is not a "function".
*
* @api public
*/
function log() {
// this hackery is required for IE8/9, where
// the `console.log` function doesn't have 'apply'
return 'object' === typeof console
&& console.log
&& Function.prototype.apply.call(console.log, console, arguments);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (null == namespaces) {
exports.storage.removeItem('debug');
} else {
exports.storage.debug = namespaces;
}
} catch(e) {}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
var r;
try {
r = exports.storage.debug;
} catch(e) {}
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
return r;
}
/**
* Enable namespaces listed in `localStorage.debug` initially.
*/
exports.enable(load());
/**
* Localstorage attempts to return the localstorage.
*
* This is necessary because safari throws
* when a user disables cookies/localstorage
* and you attempt to access it.
*
* @return {LocalStorage}
* @api private
*/
function localstorage() {
try {
return window.localStorage;
} catch (e) {}
}
@@ -0,0 +1,202 @@
/**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
exports.humanize = require('ms');
/**
* The currently active debug mode names, and names to skip.
*/
exports.names = [];
exports.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
*/
exports.formatters = {};
/**
* Previous log timestamp.
*/
var prevTime;
/**
* Select a color.
* @param {String} namespace
* @return {Number}
* @api private
*/
function selectColor(namespace) {
var hash = 0, i;
for (i in namespace) {
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
hash |= 0; // Convert to 32bit integer
}
return exports.colors[Math.abs(hash) % exports.colors.length];
}
/**
* Create a debugger with the given `namespace`.
*
* @param {String} namespace
* @return {Function}
* @api public
*/
function createDebug(namespace) {
function debug() {
// disabled?
if (!debug.enabled) return;
var self = debug;
// set `diff` timestamp
var curr = +new Date();
var ms = curr - (prevTime || curr);
self.diff = ms;
self.prev = prevTime;
self.curr = curr;
prevTime = curr;
// turn the `arguments` into a proper Array
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
args[0] = exports.coerce(args[0]);
if ('string' !== typeof args[0]) {
// anything else let's inspect with %O
args.unshift('%O');
}
// apply any `formatters` transformations
var index = 0;
args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
// if we encounter an escaped % then don't increase the array index
if (match === '%%') return match;
index++;
var formatter = exports.formatters[format];
if ('function' === typeof formatter) {
var val = args[index];
match = formatter.call(self, val);
// now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1);
index--;
}
return match;
});
// apply env-specific formatting (colors, etc.)
exports.formatArgs.call(self, args);
var logFn = debug.log || exports.log || console.log.bind(console);
logFn.apply(self, args);
}
debug.namespace = namespace;
debug.enabled = exports.enabled(namespace);
debug.useColors = exports.useColors();
debug.color = selectColor(namespace);
// env-specific initialization logic for debug instances
if ('function' === typeof exports.init) {
exports.init(debug);
}
return debug;
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} namespaces
* @api public
*/
function enable(namespaces) {
exports.save(namespaces);
exports.names = [];
exports.skips = [];
var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
var len = split.length;
for (var i = 0; i < len; i++) {
if (!split[i]) continue; // ignore empty strings
namespaces = split[i].replace(/\*/g, '.*?');
if (namespaces[0] === '-') {
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
} else {
exports.names.push(new RegExp('^' + namespaces + '$'));
}
}
}
/**
* Disable debug output.
*
* @api public
*/
function disable() {
exports.enable('');
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*
* @param {String} name
* @return {Boolean}
* @api public
*/
function enabled(name) {
var i, len;
for (i = 0, len = exports.skips.length; i < len; i++) {
if (exports.skips[i].test(name)) {
return false;
}
}
for (i = 0, len = exports.names.length; i < len; i++) {
if (exports.names[i].test(name)) {
return true;
}
}
return false;
}
/**
* Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function coerce(val) {
if (val instanceof Error) return val.stack || val.message;
return val;
}
@@ -0,0 +1,10 @@
/**
* Detect Electron renderer process, which is node, but we should
* treat as a browser.
*/
if (typeof process !== 'undefined' && process.type === 'renderer') {
module.exports = require('./browser.js');
} else {
module.exports = require('./node.js');
}
@@ -0,0 +1,15 @@
module.exports = inspectorLog;
// black hole
const nullStream = new (require('stream').Writable)();
nullStream._write = () => {};
/**
* Outputs a `console.log()` to the Node.js Inspector console *only*.
*/
function inspectorLog() {
const stdout = console._stdout;
console._stdout = nullStream;
console.log.apply(console, arguments);
console._stdout = stdout;
}
@@ -0,0 +1,248 @@
/**
* Module dependencies.
*/
var tty = require('tty');
var util = require('util');
/**
* This is the Node.js implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.init = init;
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
/**
* Colors.
*/
exports.colors = [6, 2, 3, 4, 5, 1];
/**
* Build up the default `inspectOpts` object from the environment variables.
*
* $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
*/
exports.inspectOpts = Object.keys(process.env).filter(function (key) {
return /^debug_/i.test(key);
}).reduce(function (obj, key) {
// camel-case
var prop = key
.substring(6)
.toLowerCase()
.replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() });
// coerce string value into JS value
var val = process.env[key];
if (/^(yes|on|true|enabled)$/i.test(val)) val = true;
else if (/^(no|off|false|disabled)$/i.test(val)) val = false;
else if (val === 'null') val = null;
else val = Number(val);
obj[prop] = val;
return obj;
}, {});
/**
* The file descriptor to write the `debug()` calls to.
* Set the `DEBUG_FD` env variable to override with another value. i.e.:
*
* $ DEBUG_FD=3 node script.js 3>debug.log
*/
var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
if (1 !== fd && 2 !== fd) {
util.deprecate(function(){}, 'except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)')()
}
var stream = 1 === fd ? process.stdout :
2 === fd ? process.stderr :
createWritableStdioStream(fd);
/**
* Is stdout a TTY? Colored output is enabled when `true`.
*/
function useColors() {
return 'colors' in exports.inspectOpts
? Boolean(exports.inspectOpts.colors)
: tty.isatty(fd);
}
/**
* Map %o to `util.inspect()`, all on a single line.
*/
exports.formatters.o = function(v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts)
.split('\n').map(function(str) {
return str.trim()
}).join(' ');
};
/**
* Map %o to `util.inspect()`, allowing multiple lines if needed.
*/
exports.formatters.O = function(v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts);
};
/**
* Adds ANSI color escape codes if enabled.
*
* @api public
*/
function formatArgs(args) {
var name = this.namespace;
var useColors = this.useColors;
if (useColors) {
var c = this.color;
var prefix = ' \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m';
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
} else {
args[0] = new Date().toUTCString()
+ ' ' + name + ' ' + args[0];
}
}
/**
* Invokes `util.format()` with the specified arguments and writes to `stream`.
*/
function log() {
return stream.write(util.format.apply(util, arguments) + '\n');
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
if (null == namespaces) {
// If you set a process.env field to null or undefined, it gets cast to the
// string 'null' or 'undefined'. Just delete instead.
delete process.env.DEBUG;
} else {
process.env.DEBUG = namespaces;
}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
return process.env.DEBUG;
}
/**
* Copied from `node/src/node.js`.
*
* XXX: It's lame that node doesn't expose this API out-of-the-box. It also
* relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
*/
function createWritableStdioStream (fd) {
var stream;
var tty_wrap = process.binding('tty_wrap');
// Note stream._type is used for test-module-load-list.js
switch (tty_wrap.guessHandleType(fd)) {
case 'TTY':
stream = new tty.WriteStream(fd);
stream._type = 'tty';
// Hack to have stream not keep the event loop alive.
// See https://github.com/joyent/node/issues/1726
if (stream._handle && stream._handle.unref) {
stream._handle.unref();
}
break;
case 'FILE':
var fs = require('fs');
stream = new fs.SyncWriteStream(fd, { autoClose: false });
stream._type = 'fs';
break;
case 'PIPE':
case 'TCP':
var net = require('net');
stream = new net.Socket({
fd: fd,
readable: false,
writable: true
});
// FIXME Should probably have an option in net.Socket to create a
// stream from an existing fd which is writable only. But for now
// we'll just add this hack and set the `readable` member to false.
// Test: ./node test/fixtures/echo.js < /etc/passwd
stream.readable = false;
stream.read = null;
stream._type = 'pipe';
// FIXME Hack to have stream not keep the event loop alive.
// See https://github.com/joyent/node/issues/1726
if (stream._handle && stream._handle.unref) {
stream._handle.unref();
}
break;
default:
// Probably an error on in uv_guess_handle()
throw new Error('Implement me. Unknown stream file type!');
}
// For supporting legacy API we put the FD here.
stream.fd = fd;
stream._isStdio = true;
return stream;
}
/**
* Init logic for `debug` instances.
*
* Create a new `inspectOpts` object in case `useColors` is set
* differently for a particular `debug` instance.
*/
function init (debug) {
debug.inspectOpts = {};
var keys = Object.keys(exports.inspectOpts);
for (var i = 0; i < keys.length; i++) {
debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
}
}
/**
* Enable namespaces listed in `process.env.DEBUG` initially.
*/
exports.enable(load());
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015, Jon Schlinkert.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,77 @@
# define-property [![NPM version](https://badge.fury.io/js/define-property.svg)](http://badge.fury.io/js/define-property)
> Define a non-enumerable property on an object.
## Install
Install with [npm](https://www.npmjs.com/)
```sh
$ npm i define-property --save
```
## Usage
**Params**
* `obj`: The object on which to define the property.
* `prop`: The name of the property to be defined or modified.
* `descriptor`: The descriptor for the property being defined or modified.
```js
var define = require('define-property');
var obj = {};
define(obj, 'foo', function(val) {
return val.toUpperCase();
});
console.log(obj);
//=> {}
console.log(obj.foo('bar'));
//=> 'BAR'
```
**get/set**
```js
define(obj, 'foo', {
get: function() {},
set: function() {}
});
```
## Related projects
* [delegate-object](https://www.npmjs.com/package/delegate-object): Copy properties from an object to another object, where properties with function values will be… [more](https://www.npmjs.com/package/delegate-object) | [homepage](https://github.com/doowb/delegate-object)
* [forward-object](https://www.npmjs.com/package/forward-object): Copy properties from an object to another object, where properties with function values will be… [more](https://www.npmjs.com/package/forward-object) | [homepage](https://github.com/doowb/forward-object)
* [mixin-deep](https://www.npmjs.com/package/mixin-deep): Deeply mix the properties of objects into the first object. Like merge-deep, but doesn't clone. | [homepage](https://github.com/jonschlinkert/mixin-deep)
* [mixin-object](https://www.npmjs.com/package/mixin-object): Mixin the own and inherited properties of other objects onto the first object. Pass an… [more](https://www.npmjs.com/package/mixin-object) | [homepage](https://github.com/jonschlinkert/mixin-object)
## Running tests
Install dev dependencies:
```sh
$ npm i -d && npm test
```
## Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/define-property/issues/new).
## Author
**Jon Schlinkert**
+ [github/jonschlinkert](https://github.com/jonschlinkert)
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
## License
Copyright © 2015 Jon Schlinkert
Released under the MIT license.
***
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on August 31, 2015._
@@ -0,0 +1,31 @@
/*!
* define-property <https://github.com/jonschlinkert/define-property>
*
* Copyright (c) 2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var isDescriptor = require('is-descriptor');
module.exports = function defineProperty(obj, prop, val) {
if (typeof obj !== 'object' && typeof obj !== 'function') {
throw new TypeError('expected an object or function.');
}
if (typeof prop !== 'string') {
throw new TypeError('expected `prop` to be a string.');
}
if (isDescriptor(val) && ('set' in val || 'get' in val)) {
return Object.defineProperty(obj, prop, val);
}
return Object.defineProperty(obj, prop, {
configurable: true,
enumerable: false,
writable: true,
value: val
});
};
@@ -0,0 +1,82 @@
{
"_from": "define-property@^0.2.5",
"_id": "define-property@0.2.5",
"_inBundle": false,
"_integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
"_location": "/snapdragon/define-property",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "define-property@^0.2.5",
"name": "define-property",
"escapedName": "define-property",
"rawSpec": "^0.2.5",
"saveSpec": null,
"fetchSpec": "^0.2.5"
},
"_requiredBy": [
"/snapdragon"
],
"_resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
"_shasum": "c35b1ef918ec3c990f9a5bc57be04aacec5c8116",
"_spec": "define-property@^0.2.5",
"_where": "/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah/node_modules/snapdragon",
"author": {
"name": "Jon Schlinkert",
"url": "https://github.com/jonschlinkert"
},
"bugs": {
"url": "https://github.com/jonschlinkert/define-property/issues"
},
"bundleDependencies": false,
"dependencies": {
"is-descriptor": "^0.1.0"
},
"deprecated": false,
"description": "Define a non-enumerable property on an object.",
"devDependencies": {
"mocha": "*",
"should": "^7.0.4"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/jonschlinkert/define-property",
"keywords": [
"define",
"define-property",
"enumerable",
"key",
"non",
"non-enumerable",
"object",
"prop",
"property",
"value"
],
"license": "MIT",
"main": "index.js",
"name": "define-property",
"repository": {
"type": "git",
"url": "git+https://github.com/jonschlinkert/define-property.git"
},
"scripts": {
"test": "mocha"
},
"verb": {
"related": {
"list": [
"mixin-deep",
"mixin-object",
"delegate-object",
"forward-object"
]
}
},
"version": "0.2.5"
}
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2015, Jon Schlinkert.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,61 @@
# extend-shallow [![NPM version](https://badge.fury.io/js/extend-shallow.svg)](http://badge.fury.io/js/extend-shallow) [![Build Status](https://travis-ci.org/jonschlinkert/extend-shallow.svg)](https://travis-ci.org/jonschlinkert/extend-shallow)
> Extend an object with the properties of additional objects. node.js/javascript util.
## Install
Install with [npm](https://www.npmjs.com/)
```sh
$ npm i extend-shallow --save
```
## Usage
```js
var extend = require('extend-shallow');
extend({a: 'b'}, {c: 'd'})
//=> {a: 'b', c: 'd'}
```
Pass an empty object to shallow clone:
```js
var obj = {};
extend(obj, {a: 'b'}, {c: 'd'})
//=> {a: 'b', c: 'd'}
```
## Related
* [extend-shallow](https://github.com/jonschlinkert/extend-shallow): Extend an object with the properties of additional objects. node.js/javascript util.
* [for-own](https://github.com/jonschlinkert/for-own): Iterate over the own enumerable properties of an object, and return an object with properties… [more](https://github.com/jonschlinkert/for-own)
* [for-in](https://github.com/jonschlinkert/for-in): Iterate over the own and inherited enumerable properties of an objecte, and return an object… [more](https://github.com/jonschlinkert/for-in)
* [is-plain-object](https://github.com/jonschlinkert/is-plain-object): Returns true if an object was created by the `Object` constructor.
* [isobject](https://github.com/jonschlinkert/isobject): Returns true if the value is an object and not an array or null.
* [kind-of](https://github.com/jonschlinkert/kind-of): Get the native type of a value.
## Running tests
Install dev dependencies:
```sh
$ npm i -d && npm test
```
## Author
**Jon Schlinkert**
+ [github/jonschlinkert](https://github.com/jonschlinkert)
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
## License
Copyright © 2015 Jon Schlinkert
Released under the MIT license.
***
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on June 29, 2015._
@@ -0,0 +1,33 @@
'use strict';
var isObject = require('is-extendable');
module.exports = function extend(o/*, objects*/) {
if (!isObject(o)) { o = {}; }
var len = arguments.length;
for (var i = 1; i < len; i++) {
var obj = arguments[i];
if (isObject(obj)) {
assign(o, obj);
}
}
return o;
};
function assign(a, b) {
for (var key in b) {
if (hasOwn(b, key)) {
a[key] = b[key];
}
}
}
/**
* Returns true if the given `key` is an own property of `obj`.
*/
function hasOwn(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
@@ -0,0 +1,87 @@
{
"_from": "extend-shallow@^2.0.1",
"_id": "extend-shallow@2.0.1",
"_inBundle": false,
"_integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"_location": "/snapdragon/extend-shallow",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "extend-shallow@^2.0.1",
"name": "extend-shallow",
"escapedName": "extend-shallow",
"rawSpec": "^2.0.1",
"saveSpec": null,
"fetchSpec": "^2.0.1"
},
"_requiredBy": [
"/snapdragon"
],
"_resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"_shasum": "51af7d614ad9a9f610ea1bafbb989d6b1c56890f",
"_spec": "extend-shallow@^2.0.1",
"_where": "/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah/node_modules/snapdragon",
"author": {
"name": "Jon Schlinkert",
"url": "https://github.com/jonschlinkert"
},
"bugs": {
"url": "https://github.com/jonschlinkert/extend-shallow/issues"
},
"bundleDependencies": false,
"dependencies": {
"is-extendable": "^0.1.0"
},
"deprecated": false,
"description": "Extend an object with the properties of additional objects. node.js/javascript util.",
"devDependencies": {
"array-slice": "^0.2.3",
"benchmarked": "^0.1.4",
"chalk": "^1.0.0",
"for-own": "^0.1.3",
"glob": "^5.0.12",
"is-plain-object": "^2.0.1",
"kind-of": "^2.0.0",
"minimist": "^1.1.1",
"mocha": "^2.2.5",
"should": "^7.0.1"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/jonschlinkert/extend-shallow",
"keywords": [
"assign",
"extend",
"javascript",
"js",
"keys",
"merge",
"obj",
"object",
"prop",
"properties",
"property",
"props",
"shallow",
"util",
"utility",
"utils",
"value"
],
"license": "MIT",
"main": "index.js",
"name": "extend-shallow",
"repository": {
"type": "git",
"url": "git+https://github.com/jonschlinkert/extend-shallow.git"
},
"scripts": {
"test": "mocha"
},
"version": "2.0.1"
}
@@ -0,0 +1,46 @@
{
"bitwise": true,
"camelcase": true,
"curly": false,
"eqeqeq": true,
"es3": true,
"forin": true,
"immed": false,
"indent": false,
"latedef": "nofunc",
"newcap": false,
"noarg": true,
"noempty": true,
"nonew": false,
"plusplus": false,
"quotmark": false,
"undef": true,
"unused": "vars",
"strict": false,
"trailing": true,
"maxparams": 5,
"maxdepth": false,
"maxstatements": false,
"maxcomplexity": false,
"maxlen": 100,
"asi": true,
"expr": true,
"globalstrict": true,
"smarttabs": true,
"sub": true,
"node": true,
"globals": {
"describe": false,
"it": false,
"before": false,
"beforeEach": false,
"after": false,
"afterEach": false,
"define": false,
"window": false,
"atob": true,
"JSON": false
}
}
@@ -0,0 +1,3 @@
language: node_js
node_js:
- "node"
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014, 2015, 2016, 2017 Simon Lydell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,30 @@
{
"name": "source-map-resolve",
"version": "0.5.2",
"author": "Simon Lydell",
"license": "MIT",
"description": "Resolve the source map and/or sources for a generated file.",
"keywords": [
"source map",
"sourcemap",
"source",
"map",
"sourceMappingURL",
"resolve",
"resolver",
"locate",
"locator",
"find",
"finder"
],
"authors": [
"Simon Lydell"
],
"ignore": [
".*"
],
"dependencies": {
"source-map-url": "^0.4.0",
"resolve-url": "^0.2.1"
}
}
@@ -0,0 +1,100 @@
### Version 0.5.2 (2018-05-10) ###
- Improved: Updated the version range of `atob` to disallow depending on `2.0.3`
which as a [security
vulnerability](https://snyk.io/test/npm/atob/2.0.3?severity=high&severity=medium&severity=low).
### Version 0.5.1 (2017-10-21) ###
- Fixed: URLs are now decoded before being passed to `read` in Node.js. This
allows reading files with spaces, for example.
- Fixed: Missing or empty `sources` fields (such as `sources: []`) in source
maps are now handled. Previously, such source maps would cause crashes or
callbacks never bing called. Now, an empty result is produced:
```js
sourcesResolved: [],
sourcesContent: []
```
### Version 0.5.0 (2016-02-28) ###
- Improved: Errors now have a `sourceMapData` property that contain as much as
possible of the intended result of the function up until the error occurred.
- Changed: `resolveSources` and `resolve`, as well as their `*Sync`
alternatives, no longer fail when one single source fails to be fetched.
Instead, the `sourcesContent` array in the result object will contain error
objects for all failed sources, and strings otherwise. (Backwards-incompatible
change.)
### Version 0.4.0 (2015-08-29) ###
- Removed: The `ignoreSourceRoot` option of `resolveSources`. It has been
replaced with `sourceRoot: false`. (Backwards-incompatible change.)
- Added: The `sourceRoot` option of `resolveSources`. It not only allows to
ignore the source root, it also lets you replace it.
- Added: The `parseMapToJSON` method.
- Added: The `resolve` method now accepts `null, mapUrl, ...` as arguments, in
addition to the existing signature, which will read `mapUrl` instead of
looking for a sourceMappingURL in the code.
### Version 0.3.1 (2014-08-16) ###
- Improved: Updated the source-map-url dependency to 0.3.0.
### Version 0.3.0 (2014-07-02) ###
- Removed: Argument checking. It’s not worth it. (Possibly
backwards-incompatible change.)
- Added: The `sourceRoot` property of source maps may now be ignored, which can
be useful when resolving sources outside of the browser.
- Added: It is now possible to resolve only the URLs of sources, without
reading them.
### Version 0.2.0 (2014-06-22) ###
- Changed: The result of `resolveSources` is now an object, not an array. The
old result array is available in the `sourcesContent` property.
(Backwards-incompatible change.)
- Changed: `sources` has been renamed to `sourcesContent` in the result object
of `resolve`. (Backwards-incompatible change.)
- Added: `resolveSources` now also returns all sources fully resolved, in the
`sourcesResolved` property.
- Added: The result object of `resolve` now contains the `sourcesResolved`
property from `resolveSources`.
### Version 0.1.4 (2014-06-16) ###
- Fixed: `sourcesContent` was mis-typed as `sourceContents`, which meant that
the `sourcesContent` property of source maps never was used when resolving
sources.
### Version 0.1.3 (2014-05-06) ###
- Only documentation and meta-data changes.
### Version 0.1.2 (2014-03-23) ###
- Improved: Source maps starting with `)]}'` are now parsed correctly. The spec
allows source maps to start with that character sequence to prevent XSSI
attacks.
### Version 0.1.1 (2014-03-06) ###
- Improved: Make sourceRoot resolving more sensible.
A source root such as `/scripts/subdir` is now treated as `/scripts/subdir/`
— that is, as a directory called “subdir”, not a file called “subdir”.
Pointing to a file as source root does not makes sense.
### Version 0.1.0 (2014-03-03) ###
- Initial release.
@@ -0,0 +1,29 @@
{
"name": "source-map-resolve",
"version": "0.5.2",
"author": "Simon Lydell",
"license": "MIT",
"description": "Resolve the source map and/or sources for a generated file.",
"keywords": [
"source map",
"sourcemap",
"source",
"map",
"sourceMappingURL",
"resolve",
"resolver",
"locate",
"locator",
"find",
"finder"
],
"repo": "lydell/source-map-resolve",
"main": "source-map-resolve.js",
"scripts": [
"source-map-resolve.js"
],
"dependencies": {
"lydell/source-map-url": "~0.4.0",
"lydell/resolve-url": "~0.2.1"
}
}
@@ -0,0 +1,28 @@
// Copyright 2014, 2017 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var fs = require("fs")
var template = fs.readFileSync("source-map-resolve.js.template").toString()
var nodeCode = fs.readFileSync("lib/source-map-resolve-node.js").toString()
nodeCode = nodeCode
// Remove leading comments and `require`s.
.replace(/^\s*(?:\/\/.+\s+|var\s+\w+\s*=\s*require\([^)]+\).*\s+)*/, "")
// Remove `urix`.
.replace(/(\w+)\s*=\s*urix\(\1\)\s*/g, "")
// Remove `decode-uri-component`.
.replace(/(var readUrl = )decodeUriComponent\(([\w.]+)\)/g, "$1$2")
// Change `module.exports = {...}` to `return {...}`.
.replace(/module\.exports = (\{[^}]+\})\s*$/, "return $1")
// Indent.
.replace(/^(?!$)/gm, " ")
var code = template.replace(/[ \t]*\{\{source-map-resolve-node.js\}\}/, nodeCode)
fs.writeFileSync("source-map-resolve.js", code)
@@ -0,0 +1,11 @@
// Copyright 2017 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var decodeUriComponent = require("decode-uri-component")
function customDecodeUriComponent(string) {
// `decodeUriComponent` turns `+` into ` `, but that's not wanted.
return decodeUriComponent(string.replace(/\+/g, "%2B"))
}
module.exports = customDecodeUriComponent
@@ -0,0 +1,12 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var url = require("url")
function resolveUrl(/* ...urls */) {
return Array.prototype.reduce.call(arguments, function(resolved, nextUrl) {
return url.resolve(resolved, nextUrl)
})
}
module.exports = resolveUrl
@@ -0,0 +1,302 @@
// Copyright 2014, 2015, 2016, 2017 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var sourceMappingURL = require("source-map-url")
var resolveUrl = require("./resolve-url")
var decodeUriComponent = require("./decode-uri-component")
var urix = require("urix")
var atob = require("atob")
function callbackAsync(callback, error, result) {
setImmediate(function() { callback(error, result) })
}
function parseMapToJSON(string, data) {
try {
return JSON.parse(string.replace(/^\)\]\}'/, ""))
} catch (error) {
error.sourceMapData = data
throw error
}
}
function readSync(read, url, data) {
var readUrl = decodeUriComponent(url)
try {
return String(read(readUrl))
} catch (error) {
error.sourceMapData = data
throw error
}
}
function resolveSourceMap(code, codeUrl, read, callback) {
var mapData
try {
mapData = resolveSourceMapHelper(code, codeUrl)
} catch (error) {
return callbackAsync(callback, error)
}
if (!mapData || mapData.map) {
return callbackAsync(callback, null, mapData)
}
var readUrl = decodeUriComponent(mapData.url)
read(readUrl, function(error, result) {
if (error) {
error.sourceMapData = mapData
return callback(error)
}
mapData.map = String(result)
try {
mapData.map = parseMapToJSON(mapData.map, mapData)
} catch (error) {
return callback(error)
}
callback(null, mapData)
})
}
function resolveSourceMapSync(code, codeUrl, read) {
var mapData = resolveSourceMapHelper(code, codeUrl)
if (!mapData || mapData.map) {
return mapData
}
mapData.map = readSync(read, mapData.url, mapData)
mapData.map = parseMapToJSON(mapData.map, mapData)
return mapData
}
var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/
var jsonMimeTypeRegex = /^(?:application|text)\/json$/
function resolveSourceMapHelper(code, codeUrl) {
codeUrl = urix(codeUrl)
var url = sourceMappingURL.getFrom(code)
if (!url) {
return null
}
var dataUri = url.match(dataUriRegex)
if (dataUri) {
var mimeType = dataUri[1]
var lastParameter = dataUri[2] || ""
var encoded = dataUri[3] || ""
var data = {
sourceMappingURL: url,
url: null,
sourcesRelativeTo: codeUrl,
map: encoded
}
if (!jsonMimeTypeRegex.test(mimeType)) {
var error = new Error("Unuseful data uri mime type: " + (mimeType || "text/plain"))
error.sourceMapData = data
throw error
}
data.map = parseMapToJSON(
lastParameter === ";base64" ? atob(encoded) : decodeURIComponent(encoded),
data
)
return data
}
var mapUrl = resolveUrl(codeUrl, url)
return {
sourceMappingURL: url,
url: mapUrl,
sourcesRelativeTo: mapUrl,
map: null
}
}
function resolveSources(map, mapUrl, read, options, callback) {
if (typeof options === "function") {
callback = options
options = {}
}
var pending = map.sources ? map.sources.length : 0
var result = {
sourcesResolved: [],
sourcesContent: []
}
if (pending === 0) {
callbackAsync(callback, null, result)
return
}
var done = function() {
pending--
if (pending === 0) {
callback(null, result)
}
}
resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
result.sourcesResolved[index] = fullUrl
if (typeof sourceContent === "string") {
result.sourcesContent[index] = sourceContent
callbackAsync(done, null)
} else {
var readUrl = decodeUriComponent(fullUrl)
read(readUrl, function(error, source) {
result.sourcesContent[index] = error ? error : String(source)
done()
})
}
})
}
function resolveSourcesSync(map, mapUrl, read, options) {
var result = {
sourcesResolved: [],
sourcesContent: []
}
if (!map.sources || map.sources.length === 0) {
return result
}
resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
result.sourcesResolved[index] = fullUrl
if (read !== null) {
if (typeof sourceContent === "string") {
result.sourcesContent[index] = sourceContent
} else {
var readUrl = decodeUriComponent(fullUrl)
try {
result.sourcesContent[index] = String(read(readUrl))
} catch (error) {
result.sourcesContent[index] = error
}
}
}
})
return result
}
var endingSlash = /\/?$/
function resolveSourcesHelper(map, mapUrl, options, fn) {
options = options || {}
mapUrl = urix(mapUrl)
var fullUrl
var sourceContent
var sourceRoot
for (var index = 0, len = map.sources.length; index < len; index++) {
sourceRoot = null
if (typeof options.sourceRoot === "string") {
sourceRoot = options.sourceRoot
} else if (typeof map.sourceRoot === "string" && options.sourceRoot !== false) {
sourceRoot = map.sourceRoot
}
// If the sourceRoot is the empty string, it is equivalent to not setting
// the property at all.
if (sourceRoot === null || sourceRoot === '') {
fullUrl = resolveUrl(mapUrl, map.sources[index])
} else {
// Make sure that the sourceRoot ends with a slash, so that `/scripts/subdir` becomes
// `/scripts/subdir/<source>`, not `/scripts/<source>`. Pointing to a file as source root
// does not make sense.
fullUrl = resolveUrl(mapUrl, sourceRoot.replace(endingSlash, "/"), map.sources[index])
}
sourceContent = (map.sourcesContent || [])[index]
fn(fullUrl, sourceContent, index)
}
}
function resolve(code, codeUrl, read, options, callback) {
if (typeof options === "function") {
callback = options
options = {}
}
if (code === null) {
var mapUrl = codeUrl
var data = {
sourceMappingURL: null,
url: mapUrl,
sourcesRelativeTo: mapUrl,
map: null
}
var readUrl = decodeUriComponent(mapUrl)
read(readUrl, function(error, result) {
if (error) {
error.sourceMapData = data
return callback(error)
}
data.map = String(result)
try {
data.map = parseMapToJSON(data.map, data)
} catch (error) {
return callback(error)
}
_resolveSources(data)
})
} else {
resolveSourceMap(code, codeUrl, read, function(error, mapData) {
if (error) {
return callback(error)
}
if (!mapData) {
return callback(null, null)
}
_resolveSources(mapData)
})
}
function _resolveSources(mapData) {
resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) {
if (error) {
return callback(error)
}
mapData.sourcesResolved = result.sourcesResolved
mapData.sourcesContent = result.sourcesContent
callback(null, mapData)
})
}
}
function resolveSync(code, codeUrl, read, options) {
var mapData
if (code === null) {
var mapUrl = codeUrl
mapData = {
sourceMappingURL: null,
url: mapUrl,
sourcesRelativeTo: mapUrl,
map: null
}
mapData.map = readSync(read, mapUrl, mapData)
mapData.map = parseMapToJSON(mapData.map, mapData)
} else {
mapData = resolveSourceMapSync(code, codeUrl, read)
if (!mapData) {
return null
}
}
var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options)
mapData.sourcesResolved = result.sourcesResolved
mapData.sourcesContent = result.sourcesContent
return mapData
}
module.exports = {
resolveSourceMap: resolveSourceMap,
resolveSourceMapSync: resolveSourceMapSync,
resolveSources: resolveSources,
resolveSourcesSync: resolveSourcesSync,
resolve: resolve,
resolveSync: resolveSync,
parseMapToJSON: parseMapToJSON
}
@@ -0,0 +1,77 @@
{
"_from": "source-map-resolve@^0.5.0",
"_id": "source-map-resolve@0.5.2",
"_inBundle": false,
"_integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
"_location": "/snapdragon/source-map-resolve",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "source-map-resolve@^0.5.0",
"name": "source-map-resolve",
"escapedName": "source-map-resolve",
"rawSpec": "^0.5.0",
"saveSpec": null,
"fetchSpec": "^0.5.0"
},
"_requiredBy": [
"/snapdragon"
],
"_resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
"_shasum": "72e2cc34095543e43b2c62b2c4c10d4a9054f259",
"_spec": "source-map-resolve@^0.5.0",
"_where": "/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah/node_modules/snapdragon",
"author": {
"name": "Simon Lydell"
},
"browser": "source-map-resolve.js",
"bugs": {
"url": "https://github.com/lydell/source-map-resolve/issues"
},
"bundleDependencies": false,
"dependencies": {
"atob": "^2.1.1",
"decode-uri-component": "^0.2.0",
"resolve-url": "^0.2.1",
"source-map-url": "^0.4.0",
"urix": "^0.1.0"
},
"deprecated": false,
"description": "Resolve the source map and/or sources for a generated file.",
"devDependencies": {
"Base64": "1.0.1",
"jshint": "2.9.5",
"setimmediate": "1.0.5",
"simple-asyncify": "1.0.0",
"tape": "4.9.0"
},
"homepage": "https://github.com/lydell/source-map-resolve#readme",
"keywords": [
"source map",
"sourcemap",
"source",
"map",
"sourceMappingURL",
"resolve",
"resolver",
"locate",
"locator",
"find",
"finder"
],
"license": "MIT",
"main": "lib/source-map-resolve-node.js",
"name": "source-map-resolve",
"repository": {
"type": "git",
"url": "git+https://github.com/lydell/source-map-resolve.git"
},
"scripts": {
"build": "node generate-source-map-resolve.js",
"lint": "jshint lib/ test/",
"test": "npm run lint && npm run unit",
"unit": "node test/source-map-resolve.js && node test/windows.js"
},
"version": "0.5.2"
}
@@ -0,0 +1,231 @@
Overview [![Build Status](https://travis-ci.org/lydell/source-map-resolve.svg?branch=master)](https://travis-ci.org/lydell/source-map-resolve)
========
Resolve the source map and/or sources for a generated file.
```js
var sourceMapResolve = require("source-map-resolve")
var sourceMap = require("source-map")
var code = [
"!function(){...}();",
"/*# sourceMappingURL=foo.js.map */"
].join("\n")
sourceMapResolve.resolveSourceMap(code, "/js/foo.js", fs.readFile, function(error, result) {
if (error) {
return notifyFailure(error)
}
result
// {
// map: {file: "foo.js", mappings: "...", sources: ["/coffee/foo.coffee"], names: []},
// url: "/js/foo.js.map",
// sourcesRelativeTo: "/js/foo.js.map",
// sourceMappingURL: "foo.js.map"
// }
sourceMapResolve.resolveSources(result.map, result.sourcesRelativeTo, fs.readFile, function(error, result) {
if (error) {
return notifyFailure(error)
}
result
// {
// sourcesResolved: ["/coffee/foo.coffee"],
// sourcesContent: ["<contents of /coffee/foo.coffee>"]
// }
})
})
sourceMapResolve.resolve(code, "/js/foo.js", fs.readFile, function(error, result) {
if (error) {
return notifyFailure(error)
}
result
// {
// map: {file: "foo.js", mappings: "...", sources: ["/coffee/foo.coffee"], names: []},
// url: "/js/foo.js.map",
// sourcesRelativeTo: "/js/foo.js.map",
// sourceMappingURL: "foo.js.map",
// sourcesResolved: ["/coffee/foo.coffee"],
// sourcesContent: ["<contents of /coffee/foo.coffee>"]
// }
result.map.sourcesContent = result.sourcesContent
var map = new sourceMap.sourceMapConsumer(result.map)
map.sourceContentFor("/coffee/foo.coffee")
// "<contents of /coffee/foo.coffee>"
})
```
Installation
============
- `npm install source-map-resolve`
- `bower install source-map-resolve`
- `component install lydell/source-map-resolve`
Works with CommonJS, AMD and browser globals, through UMD.
Note: This module requires `setImmediate` and `atob`.
Use polyfills if needed, such as:
- <https://github.com/NobleJS/setImmediate>
- <https://github.com/davidchambers/Base64.js>
Usage
=====
### `sourceMapResolve.resolveSourceMap(code, codeUrl, read, callback)` ###
- `code` is a string of code that may or may not contain a sourceMappingURL
comment. Such a comment is used to resolve the source map.
- `codeUrl` is the url to the file containing `code`. If the sourceMappingURL
is relative, it is resolved against `codeUrl`.
- `read(url, callback)` is a function that reads `url` and responds using
`callback(error, content)`. In Node.js you might want to use `fs.readFile`,
while in the browser you might want to use an asynchronus `XMLHttpRequest`.
- `callback(error, result)` is a function that is invoked with either an error
or `null` and the result.
The result is an object with the following properties:
- `map`: The source map for `code`, as an object (not a string).
- `url`: The url to the source map. If the source map came from a data uri,
this property is `null`, since then there is no url to it.
- `sourcesRelativeTo`: The url that the sources of the source map are relative
to. Since the sources are relative to the source map, and the url to the
source map is provided as the `url` property, this property might seem
superfluos. However, remember that the `url` property can be `null` if the
source map came from a data uri. If so, the sources are relative to the file
containing the data uri—`codeUrl`. This property will be identical to the
`url` property or `codeUrl`, whichever is appropriate. This way you can
conveniently resolve the sources without having to think about where the
source map came from.
- `sourceMappingURL`: The url of the sourceMappingURL comment in `code`.
If `code` contains no sourceMappingURL, the result is `null`.
### `sourceMapResolve.resolveSources(map, mapUrl, read, [options], callback)` ###
- `map` is a source map, as an object (not a string).
- `mapUrl` is the url to the file containing `map`. Relative sources in the
source map, if any, are resolved against `mapUrl`.
- `read(url, callback)` is a function that reads `url` and responds using
`callback(error, content)`. In Node.js you might want to use `fs.readFile`,
while in the browser you might want to use an asynchronus `XMLHttpRequest`.
- `options` is an optional object with any of the following properties:
- `sourceRoot`: Override the `sourceRoot` property of the source map, which
might only be relevant when resolving sources in the browser. This lets you
bypass it when using the module outside of a browser, if needed. Pass a
string to replace the `sourceRoot` property with, or `false` to ignore it.
Defaults to `undefined`.
- `callback(error, result)` is a function that is invoked with either an error
or `null` and the result.
The result is an object with the following properties:
- `sourcesResolved`: The same as `map.sources`, except all the sources are
fully resolved.
- `sourcesContent`: An array with the contents of all sources in `map.sources`,
in the same order as `map.sources`. If getting the contents of a source fails,
an error object is put into the array instead.
### `sourceMapResolve.resolve(code, codeUrl, read, [options], callback)` ###
The arguments are identical to `sourceMapResolve.resolveSourceMap`, except that
you may also provide the same `options` as in `sourceMapResolve.resolveSources`.
This is a convenience method that first resolves the source map and then its
sources. You could also do this by first calling
`sourceMapResolve.resolveSourceMap` and then `sourceMapResolve.resolveSources`.
The result is identical to `sourceMapResolve.resolveSourceMap`, with the
properties from `sourceMapResolve.resolveSources` merged into it.
There is one extra feature available, though. If `code` is `null`, `codeUrl` is
treated as a url to the source map instead of to `code`, and will be read. This
is handy if you _sometimes_ get the source map url from the `SourceMap: <url>`
header (see the [Notes] section). In this case, the `sourceMappingURL` property
of the result is `null`.
[Notes]: #notes
### `sourceMapResolve.*Sync()` ###
There are also sync versions of the three previous functions. They are identical
to the async versions, except:
- They expect a sync reading function. In Node.js you might want to use
`fs.readFileSync`, while in the browser you might want to use a synchronus
`XMLHttpRequest`.
- They throw errors and return the result instead of using a callback.
`sourceMapResolve.resolveSourcesSync` also accepts `null` as the `read`
parameter. The result is the same as when passing a function as the `read
parameter`, except that the `sourcesContent` property of the result will be an
empty array. In other words, the sources aren’t read. You only get the
`sourcesResolved` property. (This only supported in the synchronus version, since
there is no point doing it asynchronusly.)
### `sourceMapResolve.parseMapToJSON(string, [data])` ###
The spec says that if a source map (as a string) starts with `)]}'`, it should
be stripped off. This is to prevent XSSI attacks. This function does that and
returns the result of `JSON.parse`ing what’s left.
If this function throws `error`, `error.sourceMapData === data`.
### Errors
All errors passed to callbacks or thrown by this module have a `sourceMapData`
property that contain as much as possible of the intended result of the function
up until the error occurred.
Note that while the `map` property of result objects always is an object,
`error.sourceMapData.map` will be a string if parsing that string fails.
Note
====
This module resolves the source map for a given generated file by looking for a
sourceMappingURL comment. The spec defines yet a way to provide the URL to the
source map: By sending the `SourceMap: <url>` header along with the generated
file. Since this module doesn’t retrive the generated code for you (instead
_you_ give the generated code to the module), it’s up to you to look for such a
header when you retrieve the file (should the need arise).
Development
===========
Tests
-----
First off, run `npm install` to install testing modules and browser polyfills.
`npm test` lints the code and runs the test suite in Node.js.
x-package.json5
---------------
package.json, component.json and bower.json are all generated from
x-package.json5 by using [`xpkg`]. Only edit x-package.json5, and remember to
run `xpkg` before commiting!
[`xpkg`]: https://github.com/kof/node-xpkg
Generating the browser version
------------------------------
source-map-resolve.js is generated from source-map-resolve-node.js and
source-map-resolve-template.js. Only edit the two latter files, _not_
source-map-resolve.js! To generate it, run `npm run build`.
License
=======
[The X11 (“MIT”) License](LICENSE).
@@ -0,0 +1,309 @@
// Copyright 2014, 2015, 2016, 2017 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
// Note: source-map-resolve.js is generated from source-map-resolve-node.js and
// source-map-resolve-template.js. Only edit the two latter files, _not_
// source-map-resolve.js!
void (function(root, factory) {
if (typeof define === "function" && define.amd) {
define(["source-map-url", "resolve-url"], factory)
} else if (typeof exports === "object") {
var sourceMappingURL = require("source-map-url")
var resolveUrl = require("resolve-url")
module.exports = factory(sourceMappingURL, resolveUrl)
} else {
root.sourceMapResolve = factory(root.sourceMappingURL, root.resolveUrl)
}
}(this, function(sourceMappingURL, resolveUrl) {
function callbackAsync(callback, error, result) {
setImmediate(function() { callback(error, result) })
}
function parseMapToJSON(string, data) {
try {
return JSON.parse(string.replace(/^\)\]\}'/, ""))
} catch (error) {
error.sourceMapData = data
throw error
}
}
function readSync(read, url, data) {
var readUrl = url
try {
return String(read(readUrl))
} catch (error) {
error.sourceMapData = data
throw error
}
}
function resolveSourceMap(code, codeUrl, read, callback) {
var mapData
try {
mapData = resolveSourceMapHelper(code, codeUrl)
} catch (error) {
return callbackAsync(callback, error)
}
if (!mapData || mapData.map) {
return callbackAsync(callback, null, mapData)
}
var readUrl = mapData.url
read(readUrl, function(error, result) {
if (error) {
error.sourceMapData = mapData
return callback(error)
}
mapData.map = String(result)
try {
mapData.map = parseMapToJSON(mapData.map, mapData)
} catch (error) {
return callback(error)
}
callback(null, mapData)
})
}
function resolveSourceMapSync(code, codeUrl, read) {
var mapData = resolveSourceMapHelper(code, codeUrl)
if (!mapData || mapData.map) {
return mapData
}
mapData.map = readSync(read, mapData.url, mapData)
mapData.map = parseMapToJSON(mapData.map, mapData)
return mapData
}
var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/
var jsonMimeTypeRegex = /^(?:application|text)\/json$/
function resolveSourceMapHelper(code, codeUrl) {
var url = sourceMappingURL.getFrom(code)
if (!url) {
return null
}
var dataUri = url.match(dataUriRegex)
if (dataUri) {
var mimeType = dataUri[1]
var lastParameter = dataUri[2] || ""
var encoded = dataUri[3] || ""
var data = {
sourceMappingURL: url,
url: null,
sourcesRelativeTo: codeUrl,
map: encoded
}
if (!jsonMimeTypeRegex.test(mimeType)) {
var error = new Error("Unuseful data uri mime type: " + (mimeType || "text/plain"))
error.sourceMapData = data
throw error
}
data.map = parseMapToJSON(
lastParameter === ";base64" ? atob(encoded) : decodeURIComponent(encoded),
data
)
return data
}
var mapUrl = resolveUrl(codeUrl, url)
return {
sourceMappingURL: url,
url: mapUrl,
sourcesRelativeTo: mapUrl,
map: null
}
}
function resolveSources(map, mapUrl, read, options, callback) {
if (typeof options === "function") {
callback = options
options = {}
}
var pending = map.sources ? map.sources.length : 0
var result = {
sourcesResolved: [],
sourcesContent: []
}
if (pending === 0) {
callbackAsync(callback, null, result)
return
}
var done = function() {
pending--
if (pending === 0) {
callback(null, result)
}
}
resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
result.sourcesResolved[index] = fullUrl
if (typeof sourceContent === "string") {
result.sourcesContent[index] = sourceContent
callbackAsync(done, null)
} else {
var readUrl = fullUrl
read(readUrl, function(error, source) {
result.sourcesContent[index] = error ? error : String(source)
done()
})
}
})
}
function resolveSourcesSync(map, mapUrl, read, options) {
var result = {
sourcesResolved: [],
sourcesContent: []
}
if (!map.sources || map.sources.length === 0) {
return result
}
resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
result.sourcesResolved[index] = fullUrl
if (read !== null) {
if (typeof sourceContent === "string") {
result.sourcesContent[index] = sourceContent
} else {
var readUrl = fullUrl
try {
result.sourcesContent[index] = String(read(readUrl))
} catch (error) {
result.sourcesContent[index] = error
}
}
}
})
return result
}
var endingSlash = /\/?$/
function resolveSourcesHelper(map, mapUrl, options, fn) {
options = options || {}
var fullUrl
var sourceContent
var sourceRoot
for (var index = 0, len = map.sources.length; index < len; index++) {
sourceRoot = null
if (typeof options.sourceRoot === "string") {
sourceRoot = options.sourceRoot
} else if (typeof map.sourceRoot === "string" && options.sourceRoot !== false) {
sourceRoot = map.sourceRoot
}
// If the sourceRoot is the empty string, it is equivalent to not setting
// the property at all.
if (sourceRoot === null || sourceRoot === '') {
fullUrl = resolveUrl(mapUrl, map.sources[index])
} else {
// Make sure that the sourceRoot ends with a slash, so that `/scripts/subdir` becomes
// `/scripts/subdir/<source>`, not `/scripts/<source>`. Pointing to a file as source root
// does not make sense.
fullUrl = resolveUrl(mapUrl, sourceRoot.replace(endingSlash, "/"), map.sources[index])
}
sourceContent = (map.sourcesContent || [])[index]
fn(fullUrl, sourceContent, index)
}
}
function resolve(code, codeUrl, read, options, callback) {
if (typeof options === "function") {
callback = options
options = {}
}
if (code === null) {
var mapUrl = codeUrl
var data = {
sourceMappingURL: null,
url: mapUrl,
sourcesRelativeTo: mapUrl,
map: null
}
var readUrl = mapUrl
read(readUrl, function(error, result) {
if (error) {
error.sourceMapData = data
return callback(error)
}
data.map = String(result)
try {
data.map = parseMapToJSON(data.map, data)
} catch (error) {
return callback(error)
}
_resolveSources(data)
})
} else {
resolveSourceMap(code, codeUrl, read, function(error, mapData) {
if (error) {
return callback(error)
}
if (!mapData) {
return callback(null, null)
}
_resolveSources(mapData)
})
}
function _resolveSources(mapData) {
resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) {
if (error) {
return callback(error)
}
mapData.sourcesResolved = result.sourcesResolved
mapData.sourcesContent = result.sourcesContent
callback(null, mapData)
})
}
}
function resolveSync(code, codeUrl, read, options) {
var mapData
if (code === null) {
var mapUrl = codeUrl
mapData = {
sourceMappingURL: null,
url: mapUrl,
sourcesRelativeTo: mapUrl,
map: null
}
mapData.map = readSync(read, mapUrl, mapData)
mapData.map = parseMapToJSON(mapData.map, mapData)
} else {
mapData = resolveSourceMapSync(code, codeUrl, read)
if (!mapData) {
return null
}
}
var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options)
mapData.sourcesResolved = result.sourcesResolved
mapData.sourcesContent = result.sourcesContent
return mapData
}
return {
resolveSourceMap: resolveSourceMap,
resolveSourceMapSync: resolveSourceMapSync,
resolveSources: resolveSources,
resolveSourcesSync: resolveSourcesSync,
resolve: resolve,
resolveSync: resolveSync,
parseMapToJSON: parseMapToJSON
}
}));
@@ -0,0 +1,22 @@
// Copyright 2014, 2015, 2016, 2017 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
// Note: source-map-resolve.js is generated from source-map-resolve-node.js and
// source-map-resolve-template.js. Only edit the two latter files, _not_
// source-map-resolve.js!
void (function(root, factory) {
if (typeof define === "function" && define.amd) {
define(["source-map-url", "resolve-url"], factory)
} else if (typeof exports === "object") {
var sourceMappingURL = require("source-map-url")
var resolveUrl = require("resolve-url")
module.exports = factory(sourceMappingURL, resolveUrl)
} else {
root.sourceMapResolve = factory(root.sourceMappingURL, root.resolveUrl)
}
}(this, function(sourceMappingURL, resolveUrl) {
{{source-map-resolve-node.js}}
}));
@@ -0,0 +1,27 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
function u(url) {
return "code\n/*# sourceMappingURL=" + url + " */"
}
function read(x) {
return function() {
return x
}
}
function Throws(x) {
throw new Error(x)
}
function identity(x) {
return x
}
module.exports = {
u: u,
read: read,
Throws: Throws,
identity: identity
}
@@ -0,0 +1,105 @@
// Copyright 2017 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var test = require("tape")
var asyncify = require("simple-asyncify")
var common = require("./common")
var u = common.u
var sourceMapResolve = require("../")
var mapUrl = "operators%20map.json"
var codeUrl = "./built files/operators:+-<>%25.js"
var sourceUrl = "../source files/operators:+-<>%25.coffee"
function readTest(t, files) {
return function(file, callback) {
var fileData = files[file]
t.ok(fileData, "decoded file name")
if (callback) {
callback(null, fileData)
} else {
return fileData
}
}
}
function testResolveSourceMap(method, sync) {
return function(t) {
t.plan(2)
if (sync) {
method = asyncify(method)
}
var read = readTest(t, {
"built files/operators map.json": "{}"
})
method(u(mapUrl), codeUrl, read, function(error) {
t.error(error)
})
}
}
test(".resolveSourceMap", testResolveSourceMap(sourceMapResolve.resolveSourceMap, false))
test(".resolveSourceMapSync", testResolveSourceMap(sourceMapResolve.resolveSourceMapSync, true))
function testResolveSources(method, sync) {
return function(t) {
t.plan(2)
if (sync) {
method = asyncify(method)
}
var map = {
sources: [sourceUrl]
}
var read = readTest(t, {
"../source files/operators:+-<>%.coffee": "source code"
})
method(map, mapUrl, read, function(error) {
t.error(error)
})
}
}
test(".resolveSources", testResolveSources(sourceMapResolve.resolveSources, false))
test(".resolveSourcesSync", testResolveSources(sourceMapResolve.resolveSourcesSync, true))
function testResolve(method, sync) {
return function(t) {
t.plan(3)
if (sync) {
method = asyncify(method)
}
var map = {
sources: [sourceUrl]
}
var read = readTest(t, {
"built files/operators map.json": JSON.stringify(map),
"source files/operators:+-<>%.coffee": "source code"
})
method(u(mapUrl), codeUrl, read, function(error) {
t.error(error)
})
}
}
test(".resolve", testResolve(sourceMapResolve.resolve, false))
test(".resolveSync", testResolve(sourceMapResolve.resolveSync, true))
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,166 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var path = require("path")
var test = require("tape")
var asyncify = require("simple-asyncify")
var common = require("./common")
var u = common.u
var read = common.read
var identity = common.identity
var sourceMapResolve = require("../")
path.sep = "\\"
function testResolveSourceMap(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var codeUrl = "c:\\a\\b\\c\\foo.js"
t.plan(3 * 2)
if (sync) {
method = asyncify(method)
}
var map = {}
var readMap = wrap(read(JSON.stringify(map)))
method(u("foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "foo.js.map",
url: "/a/b/c/foo.js.map",
sourcesRelativeTo: "/a/b/c/foo.js.map",
map: map
})
})
method(u("/foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "/foo.js.map",
url: "/foo.js.map",
sourcesRelativeTo: "/foo.js.map",
map: map
})
})
method(u("../foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "../foo.js.map",
url: "/a/b/foo.js.map",
sourcesRelativeTo: "/a/b/foo.js.map",
map: map
})
})
}
}
test(".resolveSourceMap", testResolveSourceMap(sourceMapResolve.resolveSourceMap, false))
test(".resolveSourceMapSync", testResolveSourceMap(sourceMapResolve.resolveSourceMapSync, true))
function testResolveSources(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var mapUrl = "c:\\a\\b\\c\\foo.js.map"
t.plan(1 * 3)
if (sync) {
method = asyncify(method)
}
var map = {
sources: ["foo.js", "/foo.js", "../foo.js"]
}
method(map, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, ["/a/b/c/foo.js", "/foo.js", "/a/b/foo.js"])
t.deepEqual(result.sourcesContent, ["/a/b/c/foo.js", "/foo.js", "/a/b/foo.js"])
})
}
}
test(".resolveSources", testResolveSources(sourceMapResolve.resolveSources, false))
test(".resolveSourcesSync", testResolveSources(sourceMapResolve.resolveSourcesSync, true))
function testResolve(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var wrapMap = function(mapFn, fn) {
return wrap(function(url) {
if (/\.map$/.test(url)) {
return mapFn(url)
}
return fn(url)
})
}
var codeUrl = "c:\\a\\b\\c\\foo.js"
t.plan(3 * 2)
if (sync) {
method = asyncify(method)
}
var map = {
sources: ["foo.js", "/foo.js", "../foo.js"]
}
var readMap = wrapMap(read(JSON.stringify(map)), identity)
method(u("foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "foo.js.map",
url: "/a/b/c/foo.js.map",
sourcesRelativeTo: "/a/b/c/foo.js.map",
map: map,
sourcesResolved: ["/a/b/c/foo.js", "/foo.js", "/a/b/foo.js"],
sourcesContent: ["/a/b/c/foo.js", "/foo.js", "/a/b/foo.js"]
})
})
method(u("/foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "/foo.js.map",
url: "/foo.js.map",
sourcesRelativeTo: "/foo.js.map",
map: map,
sourcesResolved: ["/foo.js", "/foo.js", "/foo.js"],
sourcesContent: ["/foo.js", "/foo.js", "/foo.js"]
})
})
method(u("../foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "../foo.js.map",
url: "/a/b/foo.js.map",
sourcesRelativeTo: "/a/b/foo.js.map",
map: map,
sourcesResolved: ["/a/b/foo.js", "/foo.js", "/a/foo.js"],
sourcesContent: ["/a/b/foo.js", "/foo.js", "/a/foo.js"]
})
})
}
}
test(".resolve", testResolve(sourceMapResolve.resolve, false))
test(".resolveSync", testResolve(sourceMapResolve.resolveSync, true))
@@ -0,0 +1,68 @@
{
name: "source-map-resolve",
version: "0.5.2",
author: "Simon Lydell",
license: "MIT",
description: "Resolve the source map and/or sources for a generated file.",
keywords: [
"source map",
"sourcemap",
"source",
"map",
"sourceMappingURL",
"resolve",
"resolver",
"locate",
"locator",
"find",
"finder"
],
overlay: {
npm: {
repository: "lydell/source-map-resolve",
main: "lib/source-map-resolve-node.js",
browser: "source-map-resolve.js",
scripts: {
lint: "jshint lib/ test/",
unit: "node test/source-map-resolve.js && node test/windows.js",
test: "npm run lint && npm run unit",
build: "node generate-source-map-resolve.js"
},
dependencies: {
"atob": "^2.1.1",
"decode-uri-component": "^0.2.0",
"resolve-url": "^0.2.1",
"source-map-url": "^0.4.0",
"urix": "^0.1.0"
},
devDependencies: {
"Base64": "1.0.1",
"jshint": "2.9.5",
"setimmediate": "1.0.5",
"simple-asyncify": "1.0.0",
"tape": "4.9.0"
}
},
component: {
repo: "lydell/source-map-resolve",
main: "source-map-resolve.js",
scripts: [
"source-map-resolve.js"
],
dependencies: {
"lydell/source-map-url": "~0.4.0",
"lydell/resolve-url": "~0.2.1"
}
},
bower: {
authors: ["Simon Lydell"],
ignore: [
".*"
],
dependencies: {
"source-map-url": "^0.4.0",
"resolve-url": "^0.2.1"
}
}
}
}
@@ -0,0 +1,43 @@
{
"bitwise": true,
"camelcase": true,
"curly": false,
"eqeqeq": true,
"es3": true,
"forin": true,
"immed": false,
"indent": false,
"latedef": "nofunc",
"newcap": false,
"noarg": true,
"noempty": true,
"nonew": false,
"plusplus": false,
"quotmark": false,
"undef": true,
"unused": "vars",
"strict": false,
"trailing": true,
"maxparams": 5,
"maxdepth": false,
"maxstatements": false,
"maxcomplexity": false,
"maxlen": 100,
"asi": true,
"expr": true,
"globalstrict": true,
"smarttabs": true,
"sub": true,
"node": true,
"globals": {
"describe": false,
"it": false,
"before": false,
"beforeEach": false,
"after": false,
"afterEach": false,
"define": false
}
}
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Simon Lydell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,20 @@
{
"name": "source-map-url",
"version": "0.4.0",
"author": "Simon Lydell",
"license": "MIT",
"description": "Tools for working with sourceMappingURL comments.",
"keywords": [
"source map",
"sourceMappingURL",
"comment",
"annotation"
],
"main": "source-map-url.js",
"authors": [
"Simon Lydell"
],
"ignore": [
".*"
]
}
@@ -0,0 +1,52 @@
### Version 0.4.0 (2015-11-12) ###
- Changed: sourceMappingURL comments used to be matched only when placed at
the end of the script. However, since several commonly used JavaScript
libraries do not follow this convention and all popular web browsers accept
non-trailing comments, this has been revised.
So now non-trailing SourceMappingURL comments are matched as well.
### Version 0.3.0 (2014-08-16) ###
- Changed: sourceMappingURL comments used to be matched only if they appeared
on their own line. However, the spec only says:
> The generated code may include a line at the end of the source, with the following form:
>
> //# sourceMappingURL=<url>
So now they are matched also when they appear on the same line as code.
- Removed: The `.set()` method. I couldn’t decide how it should work
considering the above change. Moreover, it was unnecessarily complex (and
would have gotten worse) for very little gain. It is much easier to run
`.remove()` if needed, and then simply `code += "\n//# sourceMappingURL=" +
url` (using the appropriate comment syntax and newline). KISS.
- Changed: The `.insertBefore()` method now always inserts the string exactly
before the sourceMappingURL comment; not before the newline before the
comment (if any). Moreover, it does not ensure that the comment will be on a
new line anymore. This is up to the caller. KISS.
- Changed: The `.remove()` method no longer removes the newline before the
sourceMappingURL (if any).
- Changed: Renamed `.get()` to `.getFrom()`.
- Changed: Renamed `.remove()` to `.removeFrom()`.
- Added: The `.existsIn()` method.
### Version 0.2.0 (2014-02-23) ###
- Changed: A space is no longer inserted before the closing comment syntax. If
such a space is desired, it needs to be put in the closing comment syntax
itself (such as `["/*", " */"]` instead of `["/*", "*/"]`). (Backwards
incompatible change.)
### Version 0.1.0 (2014-02-22) ###
- Initial release.
@@ -0,0 +1,18 @@
{
"name": "source-map-url",
"version": "0.4.0",
"author": "Simon Lydell",
"license": "MIT",
"description": "Tools for working with sourceMappingURL comments.",
"keywords": [
"source map",
"sourceMappingURL",
"comment",
"annotation"
],
"main": "source-map-url.js",
"repo": "lydell/source-map-url",
"scripts": [
"source-map-url.js"
]
}
@@ -0,0 +1,73 @@
{
"_from": "source-map-url@^0.4.0",
"_id": "source-map-url@0.4.0",
"_inBundle": false,
"_integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"_location": "/snapdragon/source-map-url",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "source-map-url@^0.4.0",
"name": "source-map-url",
"escapedName": "source-map-url",
"rawSpec": "^0.4.0",
"saveSpec": null,
"fetchSpec": "^0.4.0"
},
"_requiredBy": [
"/snapdragon/source-map-resolve"
],
"_resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
"_shasum": "3e935d7ddd73631b97659956d55128e87b5084a3",
"_spec": "source-map-url@^0.4.0",
"_where": "/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah/node_modules/snapdragon/node_modules/source-map-resolve",
"author": {
"name": "Simon Lydell"
},
"bugs": {
"url": "https://github.com/lydell/source-map-url/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Tools for working with sourceMappingURL comments.",
"devDependencies": {
"expect.js": "~0.3.1",
"jshint": "~2.4.3",
"mocha": "~1.17.1"
},
"homepage": "https://github.com/lydell/source-map-url#readme",
"keywords": [
"source map",
"sourceMappingURL",
"comment",
"annotation"
],
"license": "MIT",
"main": "source-map-url.js",
"name": "source-map-url",
"repository": {
"type": "git",
"url": "git+https://github.com/lydell/source-map-url.git"
},
"scripts": {
"lint": "jshint source-map-url.js test/ ",
"test": "npm run lint && npm run unit",
"unit": "mocha"
},
"testling": {
"harness": "mocha",
"files": "test/*.js",
"browsers": [
"ie/8..latest",
"chrome/latest",
"firefox/latest",
"opera/12",
"opera/latest",
"safari/5",
"iphone/6",
"android-browser/4"
]
},
"version": "0.4.0"
}
@@ -0,0 +1,97 @@
Overview [![Build Status](https://travis-ci.org/lydell/source-map-url.png?branch=master)](https://travis-ci.org/lydell/source-map-url)
========
[![browser support](https://ci.testling.com/lydell/source-map-url.png)](https://ci.testling.com/lydell/source-map-url)
Tools for working with sourceMappingURL comments.
```js
var sourceMappingURL = require("source-map-url")
var code = [
"!function(){...}();",
"/*# sourceMappingURL=foo.js.map */"
].join("\n")
sourceMappingURL.existsIn(code)
// true
sourceMappingURL.getFrom(code)
// foo.js.map
code = sourceMappingURL.insertBefore(code, "// License: MIT\n")
// !function(){...}();
// // License: MIT
// /*# sourceMappingURL=foo.js.map */
code = sourceMappingURL.removeFrom(code)
// !function(){...}();
// // License: MIT
sourceMappingURL.existsIn(code)
// false
sourceMappingURL.getFrom(code)
// null
code += "//# sourceMappingURL=/other/file.js.map"
// !function(){...}();
// // License: MIT
// //# sourceMappingURL=/other/file.js.map
```
Installation
============
- `npm install source-map-url`
- `bower install source-map-url`
- `component install lydell/source-map-url`
Works with CommonJS, AMD and browser globals, through UMD.
Usage
=====
### `sourceMappingURL.getFrom(code)` ###
Returns the url of the sourceMappingURL comment in `code`. Returns `null` if
there is no such comment.
### `sourceMappingURL.existsIn(code)` ###
Returns `true` if there is a sourceMappingURL comment in `code`, or `false`
otherwise.
### `sourceMappingURL.removeFrom(code)` ###
Removes the sourceMappingURL comment in `code`. Does nothing if there is no
such comment. Returns the updated `code`.
### `sourceMappingURL.insertBefore(code, string)` ###
Inserts `string` before the sourceMappingURL comment in `code`. Appends
`string` to `code` if there is no such comment.
Lets you append something to a file without worrying about burying the
sourceMappingURL comment (by keeping it at the end of the file).
### `sourceMappingURL.regex` ###
The regex that is used to match sourceMappingURL comments. It matches both `//`
and `/**/` comments, thus supporting both JavaScript and CSS.
Tests
=====
Start by running `npm test`, which lints the code and runs the test suite in Node.js.
To run the tests in a browser, run `testling` (`npm install -g testling`) or `testling -u`.
License
=======
[The X11 (“MIT”) License](LICENSE).
@@ -0,0 +1,57 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
void (function(root, factory) {
if (typeof define === "function" && define.amd) {
define(factory)
} else if (typeof exports === "object") {
module.exports = factory()
} else {
root.sourceMappingURL = factory()
}
}(this, function() {
var innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/
var regex = RegExp(
"(?:" +
"/\\*" +
"(?:\\s*\r?\n(?://)?)?" +
"(?:" + innerRegex.source + ")" +
"\\s*" +
"\\*/" +
"|" +
"//(?:" + innerRegex.source + ")" +
")" +
"\\s*"
)
return {
regex: regex,
_innerRegex: innerRegex,
getFrom: function(code) {
var match = code.match(regex)
return (match ? match[1] || match[2] || "" : null)
},
existsIn: function(code) {
return regex.test(code)
},
removeFrom: function(code) {
return code.replace(regex, "")
},
insertBefore: function(code, string) {
var match = code.match(regex)
if (match) {
return code.slice(0, match.index) + string + code.slice(match.index)
} else {
return code + string
}
}
}
}));
@@ -0,0 +1,402 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var expect = require("expect.js")
var sourceMappingURL = require("../")
var comments = {
universal: [
"/*# sourceMappingURL=foo.js.map */"
],
js: [
"//# sourceMappingURL=foo.js.map"
],
block: [
"/*",
"# sourceMappingURL=foo.js.map",
"*/"
],
mix: [
"/*",
"//# sourceMappingURL=foo.js.map",
"*/"
]
}
var nonTrailingComments = {
jsLeading: {
contents: [
"//# sourceMappingURL=foo.js.map",
"(function(){})"
],
solution: [
"(function(){})"
]
},
mixEmbedded: {
contents: [
"/*! Library Name v1.0.0",
"//# sourceMappingURL=foo.js.map",
"*/",
"(function(){})"
],
solution: [
"/*! Library Name v1.0.0",
"*/",
"(function(){})"
]
}
}
function forEachComment(fn) {
forOf(comments, function(name, comment) {
var description = "the '" + name + "' syntax with "
fn(comment.join("\n"), description + "regular newlines")
fn(comment.join("\r\n"), description + "Windows newlines")
})
}
function forEachNonTrailingComment(fn) {
forOf(nonTrailingComments, function(name, comment) {
var description = "the '" + name + "' syntax with "
fn({
contents: comment.contents.join("\n"),
solution: comment.solution.join("\n")
}, description + "regular newlines")
fn({
contents: comment.contents.join("\r\n"),
solution: comment.solution.join("\r\n")
}, description + "Windows newlines")
})
}
function forOf(obj, fn) {
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
fn(key, obj[key])
}
}
}
describe("sourceMappingURL", function() {
describe(".getFrom", function() {
forEachComment(function(comment, description) {
it("gets the url from " + description, function() {
expect(sourceMappingURL.getFrom("code\n" + comment))
.to.equal("foo.js.map")
expect(sourceMappingURL.getFrom("code" + comment))
.to.equal("foo.js.map")
expect(sourceMappingURL.getFrom(comment))
.to.equal("foo.js.map")
})
})
forEachNonTrailingComment(function(comment, description) {
it("gets the url from " + description, function() {
expect(sourceMappingURL.getFrom("code\n" + comment.contents))
.to.equal("foo.js.map")
expect(sourceMappingURL.getFrom("code" + comment.contents))
.to.equal("foo.js.map")
expect(sourceMappingURL.getFrom(comment.contents))
.to.equal("foo.js.map")
})
})
it("returns null if no comment", function() {
expect(sourceMappingURL.getFrom("code"))
.to.equal(null)
})
it("can return an empty string as url", function() {
expect(sourceMappingURL.getFrom("/*# sourceMappingURL= */"))
.to.equal("")
})
it("is detachable", function() {
var get = sourceMappingURL.getFrom
expect(get("/*# sourceMappingURL=foo */"))
.to.equal("foo")
})
})
describe(".existsIn", function() {
forEachComment(function(comment, description) {
it("returns true for " + description, function() {
expect(sourceMappingURL.existsIn("code\n" + comment))
.to.equal(true)
expect(sourceMappingURL.existsIn("code" + comment))
.to.equal(true)
expect(sourceMappingURL.existsIn(comment))
.to.equal(true)
})
})
forEachNonTrailingComment(function(comment, description) {
it("returns true for " + description, function() {
expect(sourceMappingURL.existsIn("code\n" + comment.contents))
.to.equal(true)
expect(sourceMappingURL.existsIn("code" + comment.contents))
.to.equal(true)
expect(sourceMappingURL.existsIn(comment.contents))
.to.equal(true)
})
})
it("returns false if no comment", function() {
expect(sourceMappingURL.existsIn("code"))
.to.equal(false)
})
it("is detachable", function() {
var has = sourceMappingURL.existsIn
expect(has("/*# sourceMappingURL=foo */"))
.to.equal(true)
})
})
describe(".removeFrom", function() {
forEachComment(function(comment, description) {
it("removes the comment for " + description, function() {
expect(sourceMappingURL.removeFrom("code\n" + comment))
.to.equal("code\n")
expect(sourceMappingURL.removeFrom("code" + comment))
.to.equal("code")
expect(sourceMappingURL.removeFrom(comment))
.to.equal("")
})
})
forEachNonTrailingComment(function(comment, description) {
it("removes the comment for " + description, function() {
expect(sourceMappingURL.removeFrom("code\n" + comment.contents))
.to.equal("code\n" + comment.solution)
expect(sourceMappingURL.removeFrom("code" + comment.contents))
.to.equal("code" + comment.solution)
expect(sourceMappingURL.removeFrom(comment.contents))
.to.equal(comment.solution)
})
})
it("does nothing if no comment", function() {
expect(sourceMappingURL.removeFrom("code\n"))
.to.equal("code\n")
})
it("is detachable", function() {
var remove = sourceMappingURL.removeFrom
expect(remove("/*# sourceMappingURL=foo */"))
.to.equal("")
})
})
describe(".insertBefore", function() {
forEachComment(function(comment, description) {
it("inserts a string before the comment for " + description, function() {
expect(sourceMappingURL.insertBefore("code\n" + comment, "more code\n"))
.to.equal("code\nmore code\n" + comment)
expect(sourceMappingURL.insertBefore("code" + comment, "\nmore code"))
.to.equal("code\nmore code" + comment)
expect(sourceMappingURL.insertBefore(comment, "some code"))
.to.equal("some code" + comment)
})
})
it("inserts a string before an embedded comment", function() {
expect(sourceMappingURL.insertBefore("/*! Library Name v1.0.0\n" +
"//# sourceMappingURL=foo.js.map\n*/\n(function(){})", "code\n"))
.to.equal("/*! Library Name v1.0.0\ncode\n" +
"//# sourceMappingURL=foo.js.map\n*/\n(function(){})")
})
it("inserts a string before a leading comment", function() {
expect(sourceMappingURL.insertBefore("//# sourceMappingURL=foo.js.map\n" +
"(function(){})", "code\n"))
.to.equal("code\n//# sourceMappingURL=foo.js.map\n" +
"(function(){})")
})
it("appends if no comment", function() {
expect(sourceMappingURL.insertBefore("code", "\nmore code"))
.to.equal("code\nmore code")
})
it("is detachable", function() {
var insertBefore = sourceMappingURL.insertBefore
expect(insertBefore("/*# sourceMappingURL=foo */", "bar"))
.to.equal("bar/*# sourceMappingURL=foo */")
})
})
describe(".regex", function() {
it("includes ._innerRegex", function() {
expect(sourceMappingURL.regex.source)
.to.contain(sourceMappingURL._innerRegex.source)
})
var match = function(code) {
expect(code)
.to.match(sourceMappingURL.regex)
}
var noMatch = function(code) {
expect(code)
.not.to.match(sourceMappingURL.regex)
}
forEachComment(function(comment, description) {
it("matches " + description, function() {
match("code\n" + comment)
match("code" + comment)
match(comment)
})
it("matches " + description + ", with trailing whitespace", function() {
match(comment + " ")
match(comment + "\n")
match(comment + "\n\n\t\n \t ")
})
})
it("does not match some cases that are easy to mess up", function() {
noMatch(
"/* # sourceMappingURL=foo */"
)
noMatch(
"// # sourceMappingURL=foo"
)
})
it("is liberal regarding inner whitespace", function() {
match(
"/*# sourceMappingURL=foo*/"
)
match(
"/*# sourceMappingURL=foo */"
)
match(
"/*# sourceMappingURL=foo \t\n" +
"*/"
)
match(
"/* \n" +
"# sourceMappingURL=foo\n" +
"*/"
)
match(
"/*\n" +
"# sourceMappingURL=foo\n" +
" */"
)
match(
"/*\n" +
"# sourceMappingURL=foo\n" +
"\n" +
"\t\n" +
"*/"
)
})
})
describe("._innerRegex", function() {
it("matches the contents of sourceMappingURL comments", function() {
expect("# sourceMappingURL=http://www.example.com/foo/bar.js.map")
.to.match(sourceMappingURL._innerRegex)
})
it("captures the url in the first capture group", function() {
expect(sourceMappingURL._innerRegex.exec("# sourceMappingURL=foo")[1])
.to.equal("foo")
})
it("supports the legacy syntax", function() {
expect("@ sourceMappingURL=http://www.example.com/foo/bar.js.map")
.to.match(sourceMappingURL._innerRegex)
})
})
})
@@ -0,0 +1,55 @@
{
name: "source-map-url",
version: "0.4.0",
author: "Simon Lydell",
license: "MIT",
description: "Tools for working with sourceMappingURL comments.",
keywords: [
"source map",
"sourceMappingURL",
"comment",
"annotation"
],
main: "source-map-url.js",
overlay: {
npm: {
repository: "lydell/source-map-url",
scripts: {
lint: "jshint source-map-url.js test/ ",
unit: "mocha",
test: "npm run lint && npm run unit"
},
devDependencies: {
"mocha": "~1.17.1",
"expect.js": "~0.3.1",
"jshint": "~2.4.3"
},
testling: {
harness: "mocha",
files: "test/*.js",
browsers: [
"ie/8..latest",
"chrome/latest",
"firefox/latest",
"opera/12",
"opera/latest",
"safari/5",
"iphone/6",
"android-browser/4"
]
}
},
component: {
repo: "lydell/source-map-url",
scripts: [
"source-map-url.js"
]
},
bower: {
authors: ["Simon Lydell"],
ignore: [
".*"
]
}
}
}
@@ -0,0 +1,301 @@
# Change Log
## 0.5.6
* Fix for regression when people were using numbers as names in source maps. See
#236.
## 0.5.5
* Fix "regression" of unsupported, implementation behavior that half the world
happens to have come to depend on. See #235.
* Fix regression involving function hoisting in SpiderMonkey. See #233.
## 0.5.4
* Large performance improvements to source-map serialization. See #228 and #229.
## 0.5.3
* Do not include unnecessary distribution files. See
commit ef7006f8d1647e0a83fdc60f04f5a7ca54886f86.
## 0.5.2
* Include browser distributions of the library in package.json's `files`. See
issue #212.
## 0.5.1
* Fix latent bugs in IndexedSourceMapConsumer.prototype._parseMappings. See
ff05274becc9e6e1295ed60f3ea090d31d843379.
## 0.5.0
* Node 0.8 is no longer supported.
* Use webpack instead of dryice for bundling.
* Big speedups serializing source maps. See pull request #203.
* Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that
explicitly start with the source root. See issue #199.
## 0.4.4
* Fix an issue where using a `SourceMapGenerator` after having created a
`SourceMapConsumer` from it via `SourceMapConsumer.fromSourceMap` failed. See
issue #191.
* Fix an issue with where `SourceMapGenerator` would mistakenly consider
different mappings as duplicates of each other and avoid generating them. See
issue #192.
## 0.4.3
* A very large number of performance improvements, particularly when parsing
source maps. Collectively about 75% of time shaved off of the source map
parsing benchmark!
* Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy
searching in the presence of a column option. See issue #177.
* Fix a bug with joining a source and its source root when the source is above
the root. See issue #182.
* Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to
determine when all sources' contents are inlined into the source map. See
issue #190.
## 0.4.2
* Add an `.npmignore` file so that the benchmarks aren't pulled down by
dependent projects. Issue #169.
* Add an optional `column` argument to
`SourceMapConsumer.prototype.allGeneratedPositionsFor` and better handle lines
with no mappings. Issues #172 and #173.
## 0.4.1
* Fix accidentally defining a global variable. #170.
## 0.4.0
* The default direction for fuzzy searching was changed back to its original
direction. See #164.
* There is now a `bias` option you can supply to `SourceMapConsumer` to control
the fuzzy searching direction. See #167.
* About an 8% speed up in parsing source maps. See #159.
* Added a benchmark for parsing and generating source maps.
## 0.3.0
* Change the default direction that searching for positions fuzzes when there is
not an exact match. See #154.
* Support for environments using json2.js for JSON serialization. See #156.
## 0.2.0
* Support for consuming "indexed" source maps which do not have any remote
sections. See pull request #127. This introduces a minor backwards
incompatibility if you are monkey patching `SourceMapConsumer.prototype`
methods.
## 0.1.43
* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue
#148 for some discussion and issues #150, #151, and #152 for implementations.
## 0.1.42
* Fix an issue where `SourceNode`s from different versions of the source-map
library couldn't be used in conjunction with each other. See issue #142.
## 0.1.41
* Fix a bug with getting the source content of relative sources with a "./"
prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768).
* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the
column span of each mapping.
* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find
all generated positions associated with a given original source and line.
## 0.1.40
* Performance improvements for parsing source maps in SourceMapConsumer.
## 0.1.39
* Fix a bug where setting a source's contents to null before any source content
had been set before threw a TypeError. See issue #131.
## 0.1.38
* Fix a bug where finding relative paths from an empty path were creating
absolute paths. See issue #129.
## 0.1.37
* Fix a bug where if the source root was an empty string, relative source paths
would turn into absolute source paths. Issue #124.
## 0.1.36
* Allow the `names` mapping property to be an empty string. Issue #121.
## 0.1.35
* A third optional parameter was added to `SourceNode.fromStringWithSourceMap`
to specify a path that relative sources in the second parameter should be
relative to. Issue #105.
* If no file property is given to a `SourceMapGenerator`, then the resulting
source map will no longer have a `null` file property. The property will
simply not exist. Issue #104.
* Fixed a bug where consecutive newlines were ignored in `SourceNode`s.
Issue #116.
## 0.1.34
* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103.
* Fix bug involving source contents and the
`SourceMapGenerator.prototype.applySourceMap`. Issue #100.
## 0.1.33
* Fix some edge cases surrounding path joining and URL resolution.
* Add a third parameter for relative path to
`SourceMapGenerator.prototype.applySourceMap`.
* Fix issues with mappings and EOLs.
## 0.1.32
* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns
(issue 92).
* Fixed test runner to actually report number of failed tests as its process
exit code.
* Fixed a typo when reporting bad mappings (issue 87).
## 0.1.31
* Delay parsing the mappings in SourceMapConsumer until queried for a source
location.
* Support Sass source maps (which at the time of writing deviate from the spec
in small ways) in SourceMapConsumer.
## 0.1.30
* Do not join source root with a source, when the source is a data URI.
* Extend the test runner to allow running single specific test files at a time.
* Performance improvements in `SourceNode.prototype.walk` and
`SourceMapConsumer.prototype.eachMapping`.
* Source map browser builds will now work inside Workers.
* Better error messages when attempting to add an invalid mapping to a
`SourceMapGenerator`.
## 0.1.29
* Allow duplicate entries in the `names` and `sources` arrays of source maps
(usually from TypeScript) we are parsing. Fixes github issue 72.
## 0.1.28
* Skip duplicate mappings when creating source maps from SourceNode; github
issue 75.
## 0.1.27
* Don't throw an error when the `file` property is missing in SourceMapConsumer,
we don't use it anyway.
## 0.1.26
* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70.
## 0.1.25
* Make compatible with browserify
## 0.1.24
* Fix issue with absolute paths and `file://` URIs. See
https://bugzilla.mozilla.org/show_bug.cgi?id=885597
## 0.1.23
* Fix issue with absolute paths and sourcesContent, github issue 64.
## 0.1.22
* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21.
## 0.1.21
* Fixed handling of sources that start with a slash so that they are relative to
the source root's host.
## 0.1.20
* Fixed github issue #43: absolute URLs aren't joined with the source root
anymore.
## 0.1.19
* Using Travis CI to run tests.
## 0.1.18
* Fixed a bug in the handling of sourceRoot.
## 0.1.17
* Added SourceNode.fromStringWithSourceMap.
## 0.1.16
* Added missing documentation.
* Fixed the generating of empty mappings in SourceNode.
## 0.1.15
* Added SourceMapGenerator.applySourceMap.
## 0.1.14
* The sourceRoot is now handled consistently.
## 0.1.13
* Added SourceMapGenerator.fromSourceMap.
## 0.1.12
* SourceNode now generates empty mappings too.
## 0.1.11
* Added name support to SourceNode.
## 0.1.10
* Added sourcesContent support to the customer and generator.
@@ -0,0 +1,28 @@
Copyright (c) 2009-2011, Mozilla Foundation and contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the Mozilla Foundation nor the names of project
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,729 @@
# Source Map
[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map)
[![NPM](https://nodei.co/npm/source-map.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/source-map)
This is a library to generate and consume the source map format
[described here][format].
[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
## Use with Node
$ npm install source-map
## Use on the Web
<script src="https://raw.githubusercontent.com/mozilla/source-map/master/dist/source-map.min.js" defer></script>
--------------------------------------------------------------------------------
<!-- `npm run toc` to regenerate the Table of Contents -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table of Contents
- [Examples](#examples)
- [Consuming a source map](#consuming-a-source-map)
- [Generating a source map](#generating-a-source-map)
- [With SourceNode (high level API)](#with-sourcenode-high-level-api)
- [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api)
- [API](#api)
- [SourceMapConsumer](#sourcemapconsumer)
- [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap)
- [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans)
- [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition)
- [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition)
- [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition)
- [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources)
- [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing)
- [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order)
- [SourceMapGenerator](#sourcemapgenerator)
- [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap)
- [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer)
- [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping)
- [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent)
- [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath)
- [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring)
- [SourceNode](#sourcenode)
- [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name)
- [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath)
- [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk)
- [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk)
- [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent)
- [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn)
- [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn)
- [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep)
- [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement)
- [SourceNode.prototype.toString()](#sourcenodeprototypetostring)
- [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Examples
### Consuming a source map
```js
var rawSourceMap = {
version: 3,
file: 'min.js',
names: ['bar', 'baz', 'n'],
sources: ['one.js', 'two.js'],
sourceRoot: 'http://example.com/www/js/',
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
};
var smc = new SourceMapConsumer(rawSourceMap);
console.log(smc.sources);
// [ 'http://example.com/www/js/one.js',
// 'http://example.com/www/js/two.js' ]
console.log(smc.originalPositionFor({
line: 2,
column: 28
}));
// { source: 'http://example.com/www/js/two.js',
// line: 2,
// column: 10,
// name: 'n' }
console.log(smc.generatedPositionFor({
source: 'http://example.com/www/js/two.js',
line: 2,
column: 10
}));
// { line: 2, column: 28 }
smc.eachMapping(function (m) {
// ...
});
```
### Generating a source map
In depth guide:
[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/)
#### With SourceNode (high level API)
```js
function compile(ast) {
switch (ast.type) {
case 'BinaryExpression':
return new SourceNode(
ast.location.line,
ast.location.column,
ast.location.source,
[compile(ast.left), " + ", compile(ast.right)]
);
case 'Literal':
return new SourceNode(
ast.location.line,
ast.location.column,
ast.location.source,
String(ast.value)
);
// ...
default:
throw new Error("Bad AST");
}
}
var ast = parse("40 + 2", "add.js");
console.log(compile(ast).toStringWithSourceMap({
file: 'add.js'
}));
// { code: '40 + 2',
// map: [object SourceMapGenerator] }
```
#### With SourceMapGenerator (low level API)
```js
var map = new SourceMapGenerator({
file: "source-mapped.js"
});
map.addMapping({
generated: {
line: 10,
column: 35
},
source: "foo.js",
original: {
line: 33,
column: 2
},
name: "christopher"
});
console.log(map.toString());
// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'
```
## API
Get a reference to the module:
```js
// Node.js
var sourceMap = require('source-map');
// Browser builds
var sourceMap = window.sourceMap;
// Inside Firefox
const sourceMap = require("devtools/toolkit/sourcemap/source-map.js");
```
### SourceMapConsumer
A SourceMapConsumer instance represents a parsed source map which we can query
for information about the original file positions by giving it a file position
in the generated source.
#### new SourceMapConsumer(rawSourceMap)
The only parameter is the raw source map (either as a string which can be
`JSON.parse`'d, or an object). According to the spec, source maps have the
following attributes:
* `version`: Which version of the source map spec this map is following.
* `sources`: An array of URLs to the original source files.
* `names`: An array of identifiers which can be referenced by individual
mappings.
* `sourceRoot`: Optional. The URL root from which all sources are relative.
* `sourcesContent`: Optional. An array of contents of the original source files.
* `mappings`: A string of base64 VLQs which contain the actual mappings.
* `file`: Optional. The generated filename this source map is associated with.
```js
var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData);
```
#### SourceMapConsumer.prototype.computeColumnSpans()
Compute the last column for each generated mapping. The last column is
inclusive.
```js
// Before:
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
// [ { line: 2,
// column: 1 },
// { line: 2,
// column: 10 },
// { line: 2,
// column: 20 } ]
consumer.computeColumnSpans();
// After:
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
// [ { line: 2,
// column: 1,
// lastColumn: 9 },
// { line: 2,
// column: 10,
// lastColumn: 19 },
// { line: 2,
// column: 20,
// lastColumn: Infinity } ]
```
#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition)
Returns the original source, line, and column information for the generated
source's line and column positions provided. The only argument is an object with
the following properties:
* `line`: The line number in the generated source.
* `column`: The column number in the generated source.
* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or
`SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest
element that is smaller than or greater than the one we are searching for,
respectively, if the exact element cannot be found. Defaults to
`SourceMapConsumer.GREATEST_LOWER_BOUND`.
and an object is returned with the following properties:
* `source`: The original source file, or null if this information is not
available.
* `line`: The line number in the original source, or null if this information is
not available.
* `column`: The column number in the original source, or null if this
information is not available.
* `name`: The original identifier, or null if this information is not available.
```js
consumer.originalPositionFor({ line: 2, column: 10 })
// { source: 'foo.coffee',
// line: 2,
// column: 2,
// name: null }
consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 })
// { source: null,
// line: null,
// column: null,
// name: null }
```
#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition)
Returns the generated line and column information for the original source,
line, and column positions provided. The only argument is an object with
the following properties:
* `source`: The filename of the original source.
* `line`: The line number in the original source.
* `column`: The column number in the original source.
and an object is returned with the following properties:
* `line`: The line number in the generated source, or null.
* `column`: The column number in the generated source, or null.
```js
consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 })
// { line: 1,
// column: 56 }
```
#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)
Returns all generated line and column information for the original source, line,
and column provided. If no column is provided, returns all mappings
corresponding to a either the line we are searching for or the next closest line
that has any mappings. Otherwise, returns all mappings corresponding to the
given line and either the column we are searching for or the next closest column
that has any offsets.
The only argument is an object with the following properties:
* `source`: The filename of the original source.
* `line`: The line number in the original source.
* `column`: Optional. The column number in the original source.
and an array of objects is returned, each with the following properties:
* `line`: The line number in the generated source, or null.
* `column`: The column number in the generated source, or null.
```js
consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" })
// [ { line: 2,
// column: 1 },
// { line: 2,
// column: 10 },
// { line: 2,
// column: 20 } ]
```
#### SourceMapConsumer.prototype.hasContentsOfAllSources()
Return true if we have the embedded source content for every source listed in
the source map, false otherwise.
In other words, if this method returns `true`, then
`consumer.sourceContentFor(s)` will succeed for every source `s` in
`consumer.sources`.
```js
// ...
if (consumer.hasContentsOfAllSources()) {
consumerReadyCallback(consumer);
} else {
fetchSources(consumer, consumerReadyCallback);
}
// ...
```
#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])
Returns the original source content for the source provided. The only
argument is the URL of the original source file.
If the source content for the given source is not found, then an error is
thrown. Optionally, pass `true` as the second param to have `null` returned
instead.
```js
consumer.sources
// [ "my-cool-lib.clj" ]
consumer.sourceContentFor("my-cool-lib.clj")
// "..."
consumer.sourceContentFor("this is not in the source map");
// Error: "this is not in the source map" is not in the source map
consumer.sourceContentFor("this is not in the source map", true);
// null
```
#### SourceMapConsumer.prototype.eachMapping(callback, context, order)
Iterate over each mapping between an original source/line/column and a
generated line/column in this source map.
* `callback`: The function that is called with each mapping. Mappings have the
form `{ source, generatedLine, generatedColumn, originalLine, originalColumn,
name }`
* `context`: Optional. If specified, this object will be the value of `this`
every time that `callback` is called.
* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or
`SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over
the mappings sorted by the generated file's line/column order or the
original's source/line/column order, respectively. Defaults to
`SourceMapConsumer.GENERATED_ORDER`.
```js
consumer.eachMapping(function (m) { console.log(m); })
// ...
// { source: 'illmatic.js',
// generatedLine: 1,
// generatedColumn: 0,
// originalLine: 1,
// originalColumn: 0,
// name: null }
// { source: 'illmatic.js',
// generatedLine: 2,
// generatedColumn: 0,
// originalLine: 2,
// originalColumn: 0,
// name: null }
// ...
```
### SourceMapGenerator
An instance of the SourceMapGenerator represents a source map which is being
built incrementally.
#### new SourceMapGenerator([startOfSourceMap])
You may pass an object with the following properties:
* `file`: The filename of the generated source that this source map is
associated with.
* `sourceRoot`: A root for all relative URLs in this source map.
* `skipValidation`: Optional. When `true`, disables validation of mappings as
they are added. This can improve performance but should be used with
discretion, as a last resort. Even then, one should avoid using this flag when
running tests, if possible.
```js
var generator = new sourceMap.SourceMapGenerator({
file: "my-generated-javascript-file.js",
sourceRoot: "http://example.com/app/js/"
});
```
#### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance.
* `sourceMapConsumer` The SourceMap.
```js
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);
```
#### SourceMapGenerator.prototype.addMapping(mapping)
Add a single mapping from original source line and column to the generated
source's line and column for this source map being created. The mapping object
should have the following properties:
* `generated`: An object with the generated line and column positions.
* `original`: An object with the original line and column positions.
* `source`: The original source file (relative to the sourceRoot).
* `name`: An optional original token name for this mapping.
```js
generator.addMapping({
source: "module-one.scm",
original: { line: 128, column: 0 },
generated: { line: 3, column: 456 }
})
```
#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)
Set the source content for an original source file.
* `sourceFile` the URL of the original source file.
* `sourceContent` the content of the source file.
```js
generator.setSourceContent("module-one.scm",
fs.readFileSync("path/to/module-one.scm"))
```
#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])
Applies a SourceMap for a source file to the SourceMap.
Each mapping to the supplied source file is rewritten using the
supplied SourceMap. Note: The resolution for the resulting mappings
is the minimum of this map and the supplied map.
* `sourceMapConsumer`: The SourceMap to be applied.
* `sourceFile`: Optional. The filename of the source file.
If omitted, sourceMapConsumer.file will be used, if it exists.
Otherwise an error will be thrown.
* `sourceMapPath`: Optional. The dirname of the path to the SourceMap
to be applied. If relative, it is relative to the SourceMap.
This parameter is needed when the two SourceMaps aren't in the same
directory, and the SourceMap to be applied contains relative source
paths. If so, those relative source paths need to be rewritten
relative to the SourceMap.
If omitted, it is assumed that both SourceMaps are in the same directory,
thus not needing any rewriting. (Supplying `'.'` has the same effect.)
#### SourceMapGenerator.prototype.toString()
Renders the source map being generated to a string.
```js
generator.toString()
// '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}'
```
### SourceNode
SourceNodes provide a way to abstract over interpolating and/or concatenating
snippets of generated JavaScript source code, while maintaining the line and
column information associated between those snippets and the original source
code. This is useful as the final intermediate representation a compiler might
use before outputting the generated JS and source map.
#### new SourceNode([line, column, source[, chunk[, name]]])
* `line`: The original line number associated with this source node, or null if
it isn't associated with an original line.
* `column`: The original column number associated with this source node, or null
if it isn't associated with an original column.
* `source`: The original source's filename; null if no filename is provided.
* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see
below.
* `name`: Optional. The original identifier.
```js
var node = new SourceNode(1, 2, "a.cpp", [
new SourceNode(3, 4, "b.cpp", "extern int status;\n"),
new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"),
new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"),
]);
```
#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])
Creates a SourceNode from generated code and a SourceMapConsumer.
* `code`: The generated code
* `sourceMapConsumer` The SourceMap for the generated code
* `relativePath` The optional path that relative sources in `sourceMapConsumer`
should be relative to.
```js
var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8"));
var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"),
consumer);
```
#### SourceNode.prototype.add(chunk)
Add a chunk of generated JS to this source node.
* `chunk`: A string snippet of generated JS code, another instance of
`SourceNode`, or an array where each member is one of those things.
```js
node.add(" + ");
node.add(otherNode);
node.add([leftHandOperandNode, " + ", rightHandOperandNode]);
```
#### SourceNode.prototype.prepend(chunk)
Prepend a chunk of generated JS to this source node.
* `chunk`: A string snippet of generated JS code, another instance of
`SourceNode`, or an array where each member is one of those things.
```js
node.prepend("/** Build Id: f783haef86324gf **/\n\n");
```
#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent)
Set the source content for a source file. This will be added to the
`SourceMap` in the `sourcesContent` field.
* `sourceFile`: The filename of the source file
* `sourceContent`: The content of the source file
```js
node.setSourceContent("module-one.scm",
fs.readFileSync("path/to/module-one.scm"))
```
#### SourceNode.prototype.walk(fn)
Walk over the tree of JS snippets in this node and its children. The walking
function is called once for each snippet of JS and is passed that snippet and
the its original associated source's line/column location.
* `fn`: The traversal function.
```js
var node = new SourceNode(1, 2, "a.js", [
new SourceNode(3, 4, "b.js", "uno"),
"dos",
[
"tres",
new SourceNode(5, 6, "c.js", "quatro")
]
]);
node.walk(function (code, loc) { console.log("WALK:", code, loc); })
// WALK: uno { source: 'b.js', line: 3, column: 4, name: null }
// WALK: dos { source: 'a.js', line: 1, column: 2, name: null }
// WALK: tres { source: 'a.js', line: 1, column: 2, name: null }
// WALK: quatro { source: 'c.js', line: 5, column: 6, name: null }
```
#### SourceNode.prototype.walkSourceContents(fn)
Walk over the tree of SourceNodes. The walking function is called for each
source file content and is passed the filename and source content.
* `fn`: The traversal function.
```js
var a = new SourceNode(1, 2, "a.js", "generated from a");
a.setSourceContent("a.js", "original a");
var b = new SourceNode(1, 2, "b.js", "generated from b");
b.setSourceContent("b.js", "original b");
var c = new SourceNode(1, 2, "c.js", "generated from c");
c.setSourceContent("c.js", "original c");
var node = new SourceNode(null, null, null, [a, b, c]);
node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); })
// WALK: a.js : original a
// WALK: b.js : original b
// WALK: c.js : original c
```
#### SourceNode.prototype.join(sep)
Like `Array.prototype.join` except for SourceNodes. Inserts the separator
between each of this source node's children.
* `sep`: The separator.
```js
var lhs = new SourceNode(1, 2, "a.rs", "my_copy");
var operand = new SourceNode(3, 4, "a.rs", "=");
var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()");
var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]);
var joinedNode = node.join(" ");
```
#### SourceNode.prototype.replaceRight(pattern, replacement)
Call `String.prototype.replace` on the very right-most source snippet. Useful
for trimming white space from the end of a source node, etc.
* `pattern`: The pattern to replace.
* `replacement`: The thing to replace the pattern with.
```js
// Trim trailing white space.
node.replaceRight(/\s*$/, "");
```
#### SourceNode.prototype.toString()
Return the string representation of this source node. Walks over the tree and
concatenates all the various snippets together to one string.
```js
var node = new SourceNode(1, 2, "a.js", [
new SourceNode(3, 4, "b.js", "uno"),
"dos",
[
"tres",
new SourceNode(5, 6, "c.js", "quatro")
]
]);
node.toString()
// 'unodostresquatro'
```
#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])
Returns the string representation of this tree of source nodes, plus a
SourceMapGenerator which contains all the mappings between the generated and
original sources.
The arguments are the same as those to `new SourceMapGenerator`.
```js
var node = new SourceNode(1, 2, "a.js", [
new SourceNode(3, 4, "b.js", "uno"),
"dos",
[
"tres",
new SourceNode(5, 6, "c.js", "quatro")
]
]);
node.toStringWithSourceMap({ file: "my-output-file.js" })
// { code: 'unodostresquatro',
// map: [object SourceMapGenerator] }
```
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,121 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = require('./util');
var has = Object.prototype.hasOwnProperty;
var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
* member is O(1), testing for membership is O(1), and finding the index of an
* element is O(1). Removing elements from the set is not supported. Only
* strings are supported for membership.
*/
function ArraySet() {
this._array = [];
this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
* Static method for creating ArraySet instances from an existing array.
*/
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
var set = new ArraySet();
for (var i = 0, len = aArray.length; i < len; i++) {
set.add(aArray[i], aAllowDuplicates);
}
return set;
};
/**
* Return how many unique items are in this ArraySet. If duplicates have been
* added, than those do not count towards the size.
*
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
* Add the given string to this set.
*
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
if (hasNativeMap) {
this._set.set(aStr, idx);
} else {
this._set[sStr] = idx;
}
}
};
/**
* Is the given string a member of this set?
*
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
if (hasNativeMap) {
return this._set.has(aStr);
} else {
var sStr = util.toSetString(aStr);
return has.call(this._set, sStr);
}
};
/**
* What is the index of the given string in the array?
*
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
if (hasNativeMap) {
var idx = this._set.get(aStr);
if (idx >= 0) {
return idx;
}
} else {
var sStr = util.toSetString(aStr);
if (has.call(this._set, sStr)) {
return this._set[sStr];
}
}
throw new Error('"' + aStr + '" is not in the set.');
};
/**
* What is the element at the given index?
*
* @param Number aIdx
*/
ArraySet.prototype.at = function ArraySet_at(aIdx) {
if (aIdx >= 0 && aIdx < this._array.length) {
return this._array[aIdx];
}
throw new Error('No element indexed by ' + aIdx);
};
/**
* Returns the array representation of this set (which has the proper indices
* indicated by indexOf). Note that this is a copy of the internal array used
* for storing the members so that no one can mess with internal state.
*/
ArraySet.prototype.toArray = function ArraySet_toArray() {
return this._array.slice();
};
exports.ArraySet = ArraySet;
@@ -0,0 +1,140 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*
* Based on the Base 64 VLQ implementation in Closure Compiler:
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
*
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var base64 = require('./base64');
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the
// continuation bit. The continuation bit tells us whether there are more
// digits in this value following this digit.
//
// Continuation
// | Sign
// | |
// V V
// 101011
var VLQ_BASE_SHIFT = 5;
// binary: 100000
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
// binary: 011111
var VLQ_BASE_MASK = VLQ_BASE - 1;
// binary: 100000
var VLQ_CONTINUATION_BIT = VLQ_BASE;
/**
* Converts from a two-complement value to a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
*/
function toVLQSigned(aValue) {
return aValue < 0
? ((-aValue) << 1) + 1
: (aValue << 1) + 0;
}
/**
* Converts to a two-complement value from a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
*/
function fromVLQSigned(aValue) {
var isNegative = (aValue & 1) === 1;
var shifted = aValue >> 1;
return isNegative
? -shifted
: shifted;
}
/**
* Returns the base 64 VLQ encoded value.
*/
exports.encode = function base64VLQ_encode(aValue) {
var encoded = "";
var digit;
var vlq = toVLQSigned(aValue);
do {
digit = vlq & VLQ_BASE_MASK;
vlq >>>= VLQ_BASE_SHIFT;
if (vlq > 0) {
// There are still more digits in this value, so we must make sure the
// continuation bit is marked.
digit |= VLQ_CONTINUATION_BIT;
}
encoded += base64.encode(digit);
} while (vlq > 0);
return encoded;
};
/**
* Decodes the next base 64 VLQ value from the given string and returns the
* value and the rest of the string via the out parameter.
*/
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
var strLen = aStr.length;
var result = 0;
var shift = 0;
var continuation, digit;
do {
if (aIndex >= strLen) {
throw new Error("Expected more digits in base 64 VLQ value.");
}
digit = base64.decode(aStr.charCodeAt(aIndex++));
if (digit === -1) {
throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
}
continuation = !!(digit & VLQ_CONTINUATION_BIT);
digit &= VLQ_BASE_MASK;
result = result + (digit << shift);
shift += VLQ_BASE_SHIFT;
} while (continuation);
aOutParam.value = fromVLQSigned(result);
aOutParam.rest = aIndex;
};
@@ -0,0 +1,67 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
/**
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
*/
exports.encode = function (number) {
if (0 <= number && number < intToCharMap.length) {
return intToCharMap[number];
}
throw new TypeError("Must be between 0 and 63: " + number);
};
/**
* Decode a single base 64 character code digit to an integer. Returns -1 on
* failure.
*/
exports.decode = function (charCode) {
var bigA = 65; // 'A'
var bigZ = 90; // 'Z'
var littleA = 97; // 'a'
var littleZ = 122; // 'z'
var zero = 48; // '0'
var nine = 57; // '9'
var plus = 43; // '+'
var slash = 47; // '/'
var littleOffset = 26;
var numberOffset = 52;
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
if (bigA <= charCode && charCode <= bigZ) {
return (charCode - bigA);
}
// 26 - 51: abcdefghijklmnopqrstuvwxyz
if (littleA <= charCode && charCode <= littleZ) {
return (charCode - littleA + littleOffset);
}
// 52 - 61: 0123456789
if (zero <= charCode && charCode <= nine) {
return (charCode - zero + numberOffset);
}
// 62: +
if (charCode == plus) {
return 62;
}
// 63: /
if (charCode == slash) {
return 63;
}
// Invalid base64 digit.
return -1;
};
@@ -0,0 +1,111 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.GREATEST_LOWER_BOUND = 1;
exports.LEAST_UPPER_BOUND = 2;
/**
* Recursive implementation of binary search.
*
* @param aLow Indices here and lower do not contain the needle.
* @param aHigh Indices here and higher do not contain the needle.
* @param aNeedle The element being searched for.
* @param aHaystack The non-empty array being searched.
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
* searching for, respectively, if the exact element cannot be found.
*/
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
// This function terminates when one of the following is true:
//
// 1. We find the exact element we are looking for.
//
// 2. We did not find the exact element, but we can return the index of
// the next-closest element.
//
// 3. We did not find the exact element, and there is no next-closest
// element than the one we are searching for, so we return -1.
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
var cmp = aCompare(aNeedle, aHaystack[mid], true);
if (cmp === 0) {
// Found the element we are looking for.
return mid;
}
else if (cmp > 0) {
// Our needle is greater than aHaystack[mid].
if (aHigh - mid > 1) {
// The element is in the upper half.
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
}
// The exact needle element was not found in this haystack. Determine if
// we are in termination case (3) or (2) and return the appropriate thing.
if (aBias == exports.LEAST_UPPER_BOUND) {
return aHigh < aHaystack.length ? aHigh : -1;
} else {
return mid;
}
}
else {
// Our needle is less than aHaystack[mid].
if (mid - aLow > 1) {
// The element is in the lower half.
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
}
// we are in termination case (3) or (2) and return the appropriate thing.
if (aBias == exports.LEAST_UPPER_BOUND) {
return mid;
} else {
return aLow < 0 ? -1 : aLow;
}
}
}
/**
* This is an implementation of binary search which will always try and return
* the index of the closest element if there is no exact hit. This is because
* mappings between original and generated line/col pairs are single points,
* and there is an implicit region between each of them, so a miss just means
* that you aren't on the very start of a region.
*
* @param aNeedle The element you are looking for.
* @param aHaystack The array that is being searched.
* @param aCompare A function which takes the needle and an element in the
* array and returns -1, 0, or 1 depending on whether the needle is less
* than, equal to, or greater than the element, respectively.
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
* searching for, respectively, if the exact element cannot be found.
* Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
*/
exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
if (aHaystack.length === 0) {
return -1;
}
var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,
aCompare, aBias || exports.GREATEST_LOWER_BOUND);
if (index < 0) {
return -1;
}
// We have found either the exact element, or the next-closest element than
// the one we are searching for. However, there may be more than one such
// element. Make sure we always return the smallest of these.
while (index - 1 >= 0) {
if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
break;
}
--index;
}
return index;
};
@@ -0,0 +1,79 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2014 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = require('./util');
/**
* Determine whether mappingB is after mappingA with respect to generated
* position.
*/
function generatedPositionAfter(mappingA, mappingB) {
// Optimized for most common case
var lineA = mappingA.generatedLine;
var lineB = mappingB.generatedLine;
var columnA = mappingA.generatedColumn;
var columnB = mappingB.generatedColumn;
return lineB > lineA || lineB == lineA && columnB >= columnA ||
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
}
/**
* A data structure to provide a sorted view of accumulated mappings in a
* performance conscious manner. It trades a neglibable overhead in general
* case for a large speedup in case of mappings being added in order.
*/
function MappingList() {
this._array = [];
this._sorted = true;
// Serves as infimum
this._last = {generatedLine: -1, generatedColumn: 0};
}
/**
* Iterate through internal items. This method takes the same arguments that
* `Array.prototype.forEach` takes.
*
* NOTE: The order of the mappings is NOT guaranteed.
*/
MappingList.prototype.unsortedForEach =
function MappingList_forEach(aCallback, aThisArg) {
this._array.forEach(aCallback, aThisArg);
};
/**
* Add the given source mapping.
*
* @param Object aMapping
*/
MappingList.prototype.add = function MappingList_add(aMapping) {
if (generatedPositionAfter(this._last, aMapping)) {
this._last = aMapping;
this._array.push(aMapping);
} else {
this._sorted = false;
this._array.push(aMapping);
}
};
/**
* Returns the flat, sorted array of mappings. The mappings are sorted by
* generated position.
*
* WARNING: This method returns internal data without copying, for
* performance. The return value must NOT be mutated, and should be treated as
* an immutable borrow. If you want to take ownership, you must make your own
* copy.
*/
MappingList.prototype.toArray = function MappingList_toArray() {
if (!this._sorted) {
this._array.sort(util.compareByGeneratedPositionsInflated);
this._sorted = true;
}
return this._array;
};
exports.MappingList = MappingList;
@@ -0,0 +1,114 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
// It turns out that some (most?) JavaScript engines don't self-host
// `Array.prototype.sort`. This makes sense because C++ will likely remain
// faster than JS when doing raw CPU-intensive sorting. However, when using a
// custom comparator function, calling back and forth between the VM's C++ and
// JIT'd JS is rather slow *and* loses JIT type information, resulting in
// worse generated code for the comparator function than would be optimal. In
// fact, when sorting with a comparator, these costs outweigh the benefits of
// sorting in C++. By using our own JS-implemented Quick Sort (below), we get
// a ~3500ms mean speed-up in `bench/bench.html`.
/**
* Swap the elements indexed by `x` and `y` in the array `ary`.
*
* @param {Array} ary
* The array.
* @param {Number} x
* The index of the first item.
* @param {Number} y
* The index of the second item.
*/
function swap(ary, x, y) {
var temp = ary[x];
ary[x] = ary[y];
ary[y] = temp;
}
/**
* Returns a random integer within the range `low .. high` inclusive.
*
* @param {Number} low
* The lower bound on the range.
* @param {Number} high
* The upper bound on the range.
*/
function randomIntInRange(low, high) {
return Math.round(low + (Math.random() * (high - low)));
}
/**
* The Quick Sort algorithm.
*
* @param {Array} ary
* An array to sort.
* @param {function} comparator
* Function to use to compare two items.
* @param {Number} p
* Start index of the array
* @param {Number} r
* End index of the array
*/
function doQuickSort(ary, comparator, p, r) {
// If our lower bound is less than our upper bound, we (1) partition the
// array into two pieces and (2) recurse on each half. If it is not, this is
// the empty array and our base case.
if (p < r) {
// (1) Partitioning.
//
// The partitioning chooses a pivot between `p` and `r` and moves all
// elements that are less than or equal to the pivot to the before it, and
// all the elements that are greater than it after it. The effect is that
// once partition is done, the pivot is in the exact place it will be when
// the array is put in sorted order, and it will not need to be moved
// again. This runs in O(n) time.
// Always choose a random pivot so that an input array which is reverse
// sorted does not cause O(n^2) running time.
var pivotIndex = randomIntInRange(p, r);
var i = p - 1;
swap(ary, pivotIndex, r);
var pivot = ary[r];
// Immediately after `j` is incremented in this loop, the following hold
// true:
//
// * Every element in `ary[p .. i]` is less than or equal to the pivot.
//
// * Every element in `ary[i+1 .. j-1]` is greater than the pivot.
for (var j = p; j < r; j++) {
if (comparator(ary[j], pivot) <= 0) {
i += 1;
swap(ary, i, j);
}
}
swap(ary, i + 1, j);
var q = i + 1;
// (2) Recurse on each half.
doQuickSort(ary, comparator, p, q - 1);
doQuickSort(ary, comparator, q + 1, r);
}
}
/**
* Sort the given array in-place with the given comparator function.
*
* @param {Array} ary
* An array to sort.
* @param {function} comparator
* Function to use to compare two items.
*/
exports.quickSort = function (ary, comparator) {
doQuickSort(ary, comparator, 0, ary.length - 1);
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,416 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var base64VLQ = require('./base64-vlq');
var util = require('./util');
var ArraySet = require('./array-set').ArraySet;
var MappingList = require('./mapping-list').MappingList;
/**
* An instance of the SourceMapGenerator represents a source map which is
* being built incrementally. You may pass an object with the following
* properties:
*
* - file: The filename of the generated source.
* - sourceRoot: A root for all relative URLs in this source map.
*/
function SourceMapGenerator(aArgs) {
if (!aArgs) {
aArgs = {};
}
this._file = util.getArg(aArgs, 'file', null);
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
this._sources = new ArraySet();
this._names = new ArraySet();
this._mappings = new MappingList();
this._sourcesContents = null;
}
SourceMapGenerator.prototype._version = 3;
/**
* Creates a new SourceMapGenerator based on a SourceMapConsumer
*
* @param aSourceMapConsumer The SourceMap.
*/
SourceMapGenerator.fromSourceMap =
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
var sourceRoot = aSourceMapConsumer.sourceRoot;
var generator = new SourceMapGenerator({
file: aSourceMapConsumer.file,
sourceRoot: sourceRoot
});
aSourceMapConsumer.eachMapping(function (mapping) {
var newMapping = {
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn
}
};
if (mapping.source != null) {
newMapping.source = mapping.source;
if (sourceRoot != null) {
newMapping.source = util.relative(sourceRoot, newMapping.source);
}
newMapping.original = {
line: mapping.originalLine,
column: mapping.originalColumn
};
if (mapping.name != null) {
newMapping.name = mapping.name;
}
}
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
}
});
return generator;
};
/**
* Add a single mapping from original source line and column to the generated
* source's line and column for this source map being created. The mapping
* object should have the following properties:
*
* - generated: An object with the generated line and column positions.
* - original: An object with the original line and column positions.
* - source: The original source file (relative to the sourceRoot).
* - name: An optional original token name for this mapping.
*/
SourceMapGenerator.prototype.addMapping =
function SourceMapGenerator_addMapping(aArgs) {
var generated = util.getArg(aArgs, 'generated');
var original = util.getArg(aArgs, 'original', null);
var source = util.getArg(aArgs, 'source', null);
var name = util.getArg(aArgs, 'name', null);
if (!this._skipValidation) {
this._validateMapping(generated, original, source, name);
}
if (source != null) {
source = String(source);
if (!this._sources.has(source)) {
this._sources.add(source);
}
}
if (name != null) {
name = String(name);
if (!this._names.has(name)) {
this._names.add(name);
}
}
this._mappings.add({
generatedLine: generated.line,
generatedColumn: generated.column,
originalLine: original != null && original.line,
originalColumn: original != null && original.column,
source: source,
name: name
});
};
/**
* Set the source content for a source file.
*/
SourceMapGenerator.prototype.setSourceContent =
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
var source = aSourceFile;
if (this._sourceRoot != null) {
source = util.relative(this._sourceRoot, source);
}
if (aSourceContent != null) {
// Add the source content to the _sourcesContents map.
// Create a new _sourcesContents map if the property is null.
if (!this._sourcesContents) {
this._sourcesContents = Object.create(null);
}
this._sourcesContents[util.toSetString(source)] = aSourceContent;
} else if (this._sourcesContents) {
// Remove the source file from the _sourcesContents map.
// If the _sourcesContents map is empty, set the property to null.
delete this._sourcesContents[util.toSetString(source)];
if (Object.keys(this._sourcesContents).length === 0) {
this._sourcesContents = null;
}
}
};
/**
* Applies the mappings of a sub-source-map for a specific source file to the
* source map being generated. Each mapping to the supplied source file is
* rewritten using the supplied source map. Note: The resolution for the
* resulting mappings is the minimium of this map and the supplied map.
*
* @param aSourceMapConsumer The source map to be applied.
* @param aSourceFile Optional. The filename of the source file.
* If omitted, SourceMapConsumer's file property will be used.
* @param aSourceMapPath Optional. The dirname of the path to the source map
* to be applied. If relative, it is relative to the SourceMapConsumer.
* This parameter is needed when the two source maps aren't in the same
* directory, and the source map to be applied contains relative source
* paths. If so, those relative source paths need to be rewritten
* relative to the SourceMapGenerator.
*/
SourceMapGenerator.prototype.applySourceMap =
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
var sourceFile = aSourceFile;
// If aSourceFile is omitted, we will use the file property of the SourceMap
if (aSourceFile == null) {
if (aSourceMapConsumer.file == null) {
throw new Error(
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
'or the source map\'s "file" property. Both were omitted.'
);
}
sourceFile = aSourceMapConsumer.file;
}
var sourceRoot = this._sourceRoot;
// Make "sourceFile" relative if an absolute Url is passed.
if (sourceRoot != null) {
sourceFile = util.relative(sourceRoot, sourceFile);
}
// Applying the SourceMap can add and remove items from the sources and
// the names array.
var newSources = new ArraySet();
var newNames = new ArraySet();
// Find mappings for the "sourceFile"
this._mappings.unsortedForEach(function (mapping) {
if (mapping.source === sourceFile && mapping.originalLine != null) {
// Check if it can be mapped by the source map, then update the mapping.
var original = aSourceMapConsumer.originalPositionFor({
line: mapping.originalLine,
column: mapping.originalColumn
});
if (original.source != null) {
// Copy mapping
mapping.source = original.source;
if (aSourceMapPath != null) {
mapping.source = util.join(aSourceMapPath, mapping.source)
}
if (sourceRoot != null) {
mapping.source = util.relative(sourceRoot, mapping.source);
}
mapping.originalLine = original.line;
mapping.originalColumn = original.column;
if (original.name != null) {
mapping.name = original.name;
}
}
}
var source = mapping.source;
if (source != null && !newSources.has(source)) {
newSources.add(source);
}
var name = mapping.name;
if (name != null && !newNames.has(name)) {
newNames.add(name);
}
}, this);
this._sources = newSources;
this._names = newNames;
// Copy sourcesContents of applied map.
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
if (aSourceMapPath != null) {
sourceFile = util.join(aSourceMapPath, sourceFile);
}
if (sourceRoot != null) {
sourceFile = util.relative(sourceRoot, sourceFile);
}
this.setSourceContent(sourceFile, content);
}
}, this);
};
/**
* A mapping can have one of the three levels of data:
*
* 1. Just the generated position.
* 2. The Generated position, original position, and original source.
* 3. Generated and original position, original source, as well as a name
* token.
*
* To maintain consistency, we validate that any new mapping being added falls
* in to one of these categories.
*/
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
// When aOriginal is truthy but has empty values for .line and .column,
// it is most likely a programmer error. In this case we throw a very
// specific error message to try to guide them the right way.
// For example: https://github.com/Polymer/polymer-bundler/pull/519
if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
throw new Error(
'original.line and original.column are not numbers -- you probably meant to omit ' +
'the original mapping entirely and only map the generated position. If so, pass ' +
'null for the original mapping instead of an object with empty or null values.'
);
}
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
// Case 1.
return;
}
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
&& aGenerated.line > 0 && aGenerated.column >= 0
&& aOriginal.line > 0 && aOriginal.column >= 0
&& aSource) {
// Cases 2 and 3.
return;
}
else {
throw new Error('Invalid mapping: ' + JSON.stringify({
generated: aGenerated,
source: aSource,
original: aOriginal,
name: aName
}));
}
};
/**
* Serialize the accumulated mappings in to the stream of base 64 VLQs
* specified by the source map format.
*/
SourceMapGenerator.prototype._serializeMappings =
function SourceMapGenerator_serializeMappings() {
var previousGeneratedColumn = 0;
var previousGeneratedLine = 1;
var previousOriginalColumn = 0;
var previousOriginalLine = 0;
var previousName = 0;
var previousSource = 0;
var result = '';
var next;
var mapping;
var nameIdx;
var sourceIdx;
var mappings = this._mappings.toArray();
for (var i = 0, len = mappings.length; i < len; i++) {
mapping = mappings[i];
next = ''
if (mapping.generatedLine !== previousGeneratedLine) {
previousGeneratedColumn = 0;
while (mapping.generatedLine !== previousGeneratedLine) {
next += ';';
previousGeneratedLine++;
}
}
else {
if (i > 0) {
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
continue;
}
next += ',';
}
}
next += base64VLQ.encode(mapping.generatedColumn
- previousGeneratedColumn);
previousGeneratedColumn = mapping.generatedColumn;
if (mapping.source != null) {
sourceIdx = this._sources.indexOf(mapping.source);
next += base64VLQ.encode(sourceIdx - previousSource);
previousSource = sourceIdx;
// lines are stored 0-based in SourceMap spec version 3
next += base64VLQ.encode(mapping.originalLine - 1
- previousOriginalLine);
previousOriginalLine = mapping.originalLine - 1;
next += base64VLQ.encode(mapping.originalColumn
- previousOriginalColumn);
previousOriginalColumn = mapping.originalColumn;
if (mapping.name != null) {
nameIdx = this._names.indexOf(mapping.name);
next += base64VLQ.encode(nameIdx - previousName);
previousName = nameIdx;
}
}
result += next;
}
return result;
};
SourceMapGenerator.prototype._generateSourcesContent =
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
return aSources.map(function (source) {
if (!this._sourcesContents) {
return null;
}
if (aSourceRoot != null) {
source = util.relative(aSourceRoot, source);
}
var key = util.toSetString(source);
return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
? this._sourcesContents[key]
: null;
}, this);
};
/**
* Externalize the source map.
*/
SourceMapGenerator.prototype.toJSON =
function SourceMapGenerator_toJSON() {
var map = {
version: this._version,
sources: this._sources.toArray(),
names: this._names.toArray(),
mappings: this._serializeMappings()
};
if (this._file != null) {
map.file = this._file;
}
if (this._sourceRoot != null) {
map.sourceRoot = this._sourceRoot;
}
if (this._sourcesContents) {
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
}
return map;
};
/**
* Render the source map being generated to a string.
*/
SourceMapGenerator.prototype.toString =
function SourceMapGenerator_toString() {
return JSON.stringify(this.toJSON());
};
exports.SourceMapGenerator = SourceMapGenerator;
@@ -0,0 +1,413 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;
var util = require('./util');
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).
var REGEX_NEWLINE = /(\r?\n)/;
// Newline character code for charCodeAt() comparisons
var NEWLINE_CODE = 10;
// Private symbol for identifying `SourceNode`s when multiple versions of
// the source-map library are loaded. This MUST NOT CHANGE across
// versions!
var isSourceNode = "$$$isSourceNode$$$";
/**
* SourceNodes provide a way to abstract over interpolating/concatenating
* snippets of generated JavaScript source code while maintaining the line and
* column information associated with the original source code.
*
* @param aLine The original line number.
* @param aColumn The original column number.
* @param aSource The original source's filename.
* @param aChunks Optional. An array of strings which are snippets of
* generated JS, or other SourceNodes.
* @param aName The original identifier.
*/
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
this.children = [];
this.sourceContents = {};
this.line = aLine == null ? null : aLine;
this.column = aColumn == null ? null : aColumn;
this.source = aSource == null ? null : aSource;
this.name = aName == null ? null : aName;
this[isSourceNode] = true;
if (aChunks != null) this.add(aChunks);
}
/**
* Creates a SourceNode from generated code and a SourceMapConsumer.
*
* @param aGeneratedCode The generated code
* @param aSourceMapConsumer The SourceMap for the generated code
* @param aRelativePath Optional. The path that relative sources in the
* SourceMapConsumer should be relative to.
*/
SourceNode.fromStringWithSourceMap =
function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
// The SourceNode we want to fill with the generated code
// and the SourceMap
var node = new SourceNode();
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
// Processed fragments are accessed by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
var remainingLinesIndex = 0;
var shiftNextLine = function() {
var lineContents = getNextLine();
// The last line of a file might not have a newline.
var newLine = getNextLine() || "";
return lineContents + newLine;
function getNextLine() {
return remainingLinesIndex < remainingLines.length ?
remainingLines[remainingLinesIndex++] : undefined;
}
};
// We need to remember the position of "remainingLines"
var lastGeneratedLine = 1, lastGeneratedColumn = 0;
// The generate SourceNodes we need a code range.
// To extract it current and last mapping is used.
// Here we store the last mapping.
var lastMapping = null;
aSourceMapConsumer.eachMapping(function (mapping) {
if (lastMapping !== null) {
// We add the code from "lastMapping" to "mapping":
// First check if there is a new line in between.
if (lastGeneratedLine < mapping.generatedLine) {
// Associate first line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
lastGeneratedLine++;
lastGeneratedColumn = 0;
// The remaining code is added without mapping
} else {
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
var nextLine = remainingLines[remainingLinesIndex];
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
// No more remaining code, continue
lastMapping = mapping;
return;
}
}
// We add the generated code until the first mapping
// to the SourceNode without any mapping.
// Each line is added as separate string.
while (lastGeneratedLine < mapping.generatedLine) {
node.add(shiftNextLine());
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
var nextLine = remainingLines[remainingLinesIndex];
node.add(nextLine.substr(0, mapping.generatedColumn));
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
if (remainingLinesIndex < remainingLines.length) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
}
// and add the remaining lines without any mapping
node.add(remainingLines.splice(remainingLinesIndex).join(""));
}
// Copy sourcesContent into SourceNode
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
if (aRelativePath != null) {
sourceFile = util.join(aRelativePath, sourceFile);
}
node.setSourceContent(sourceFile, content);
}
});
return node;
function addMappingWithCode(mapping, code) {
if (mapping === null || mapping.source === undefined) {
node.add(code);
} else {
var source = aRelativePath
? util.join(aRelativePath, mapping.source)
: mapping.source;
node.add(new SourceNode(mapping.originalLine,
mapping.originalColumn,
source,
code,
mapping.name));
}
}
};
/**
* Add a chunk of generated JS to this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
SourceNode.prototype.add = function SourceNode_add(aChunk) {
if (Array.isArray(aChunk)) {
aChunk.forEach(function (chunk) {
this.add(chunk);
}, this);
}
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
if (aChunk) {
this.children.push(aChunk);
}
}
else {
throw new TypeError(
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
);
}
return this;
};
/**
* Add a chunk of generated JS to the beginning of this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
if (Array.isArray(aChunk)) {
for (var i = aChunk.length-1; i >= 0; i--) {
this.prepend(aChunk[i]);
}
}
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
this.children.unshift(aChunk);
}
else {
throw new TypeError(
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
);
}
return this;
};
/**
* Walk over the tree of JS snippets in this node and its children. The
* walking function is called once for each snippet of JS and is passed that
* snippet and the its original associated source's line/column location.
*
* @param aFn The traversal function.
*/
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
var chunk;
for (var i = 0, len = this.children.length; i < len; i++) {
chunk = this.children[i];
if (chunk[isSourceNode]) {
chunk.walk(aFn);
}
else {
if (chunk !== '') {
aFn(chunk, { source: this.source,
line: this.line,
column: this.column,
name: this.name });
}
}
}
};
/**
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
* each of `this.children`.
*
* @param aSep The separator.
*/
SourceNode.prototype.join = function SourceNode_join(aSep) {
var newChildren;
var i;
var len = this.children.length;
if (len > 0) {
newChildren = [];
for (i = 0; i < len-1; i++) {
newChildren.push(this.children[i]);
newChildren.push(aSep);
}
newChildren.push(this.children[i]);
this.children = newChildren;
}
return this;
};
/**
* Call String.prototype.replace on the very right-most source snippet. Useful
* for trimming whitespace from the end of a source node, etc.
*
* @param aPattern The pattern to replace.
* @param aReplacement The thing to replace the pattern with.
*/
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
var lastChild = this.children[this.children.length - 1];
if (lastChild[isSourceNode]) {
lastChild.replaceRight(aPattern, aReplacement);
}
else if (typeof lastChild === 'string') {
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
}
else {
this.children.push(''.replace(aPattern, aReplacement));
}
return this;
};
/**
* Set the source content for a source file. This will be added to the SourceMapGenerator
* in the sourcesContent field.
*
* @param aSourceFile The filename of the source file
* @param aSourceContent The content of the source file
*/
SourceNode.prototype.setSourceContent =
function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
};
/**
* Walk over the tree of SourceNodes. The walking function is called for each
* source file content and is passed the filename and source content.
*
* @param aFn The traversal function.
*/
SourceNode.prototype.walkSourceContents =
function SourceNode_walkSourceContents(aFn) {
for (var i = 0, len = this.children.length; i < len; i++) {
if (this.children[i][isSourceNode]) {
this.children[i].walkSourceContents(aFn);
}
}
var sources = Object.keys(this.sourceContents);
for (var i = 0, len = sources.length; i < len; i++) {
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
}
};
/**
* Return the string representation of this source node. Walks over the tree
* and concatenates all the various snippets together to one string.
*/
SourceNode.prototype.toString = function SourceNode_toString() {
var str = "";
this.walk(function (chunk) {
str += chunk;
});
return str;
};
/**
* Returns the string representation of this source node along with a source
* map.
*/
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
var generated = {
code: "",
line: 1,
column: 0
};
var map = new SourceMapGenerator(aArgs);
var sourceMappingActive = false;
var lastOriginalSource = null;
var lastOriginalLine = null;
var lastOriginalColumn = null;
var lastOriginalName = null;
this.walk(function (chunk, original) {
generated.code += chunk;
if (original.source !== null
&& original.line !== null
&& original.column !== null) {
if(lastOriginalSource !== original.source
|| lastOriginalLine !== original.line
|| lastOriginalColumn !== original.column
|| lastOriginalName !== original.name) {
map.addMapping({
source: original.source,
original: {
line: original.line,
column: original.column
},
generated: {
line: generated.line,
column: generated.column
},
name: original.name
});
}
lastOriginalSource = original.source;
lastOriginalLine = original.line;
lastOriginalColumn = original.column;
lastOriginalName = original.name;
sourceMappingActive = true;
} else if (sourceMappingActive) {
map.addMapping({
generated: {
line: generated.line,
column: generated.column
}
});
lastOriginalSource = null;
sourceMappingActive = false;
}
for (var idx = 0, length = chunk.length; idx < length; idx++) {
if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
generated.line++;
generated.column = 0;
// Mappings end at eol
if (idx + 1 === length) {
lastOriginalSource = null;
sourceMappingActive = false;
} else if (sourceMappingActive) {
map.addMapping({
source: original.source,
original: {
line: original.line,
column: original.column
},
generated: {
line: generated.line,
column: generated.column
},
name: original.name
});
}
} else {
generated.column++;
}
}
});
this.walkSourceContents(function (sourceFile, sourceContent) {
map.setSourceContent(sourceFile, sourceContent);
});
return { code: generated.code, map: map };
};
exports.SourceNode = SourceNode;
@@ -0,0 +1,417 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
/**
* This is a helper function for getting values from parameter/options
* objects.
*
* @param args The object we are extracting values from
* @param name The name of the property we are getting.
* @param defaultValue An optional value to return if the property is missing
* from the object. If this is not specified and the property is missing, an
* error will be thrown.
*/
function getArg(aArgs, aName, aDefaultValue) {
if (aName in aArgs) {
return aArgs[aName];
} else if (arguments.length === 3) {
return aDefaultValue;
} else {
throw new Error('"' + aName + '" is a required argument.');
}
}
exports.getArg = getArg;
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
var match = aUrl.match(urlRegexp);
if (!match) {
return null;
}
return {
scheme: match[1],
auth: match[2],
host: match[3],
port: match[4],
path: match[5]
};
}
exports.urlParse = urlParse;
function urlGenerate(aParsedUrl) {
var url = '';
if (aParsedUrl.scheme) {
url += aParsedUrl.scheme + ':';
}
url += '//';
if (aParsedUrl.auth) {
url += aParsedUrl.auth + '@';
}
if (aParsedUrl.host) {
url += aParsedUrl.host;
}
if (aParsedUrl.port) {
url += ":" + aParsedUrl.port
}
if (aParsedUrl.path) {
url += aParsedUrl.path;
}
return url;
}
exports.urlGenerate = urlGenerate;
/**
* Normalizes a path, or the path portion of a URL:
*
* - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
* Based on code in the Node.js 'path' core module.
*
* @param aPath The path or url to normalize.
*/
function normalize(aPath) {
var path = aPath;
var url = urlParse(aPath);
if (url) {
if (!url.path) {
return aPath;
}
path = url.path;
}
var isAbsolute = exports.isAbsolute(path);
var parts = path.split(/\/+/);
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
part = parts[i];
if (part === '.') {
parts.splice(i, 1);
} else if (part === '..') {
up++;
} else if (up > 0) {
if (part === '') {
// The first part is blank if the path is absolute. Trying to go
// above the root is a no-op. Therefore we can remove all '..' parts
// directly after the root.
parts.splice(i + 1, up);
up = 0;
} else {
parts.splice(i, 2);
up--;
}
}
}
path = parts.join('/');
if (path === '') {
path = isAbsolute ? '/' : '.';
}
if (url) {
url.path = path;
return urlGenerate(url);
}
return path;
}
exports.normalize = normalize;
/**
* Joins two paths/URLs.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be joined with the root.
*
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
* first.
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
* is updated with the result and aRoot is returned. Otherwise the result
* is returned.
* - If aPath is absolute, the result is aPath.
* - Otherwise the two paths are joined with a slash.
* - Joining for example 'http://' and 'www.example.com' is also supported.
*/
function join(aRoot, aPath) {
if (aRoot === "") {
aRoot = ".";
}
if (aPath === "") {
aPath = ".";
}
var aPathUrl = urlParse(aPath);
var aRootUrl = urlParse(aRoot);
if (aRootUrl) {
aRoot = aRootUrl.path || '/';
}
// `join(foo, '//www.example.org')`
if (aPathUrl && !aPathUrl.scheme) {
if (aRootUrl) {
aPathUrl.scheme = aRootUrl.scheme;
}
return urlGenerate(aPathUrl);
}
if (aPathUrl || aPath.match(dataUrlRegexp)) {
return aPath;
}
// `join('http://', 'www.example.com')`
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
aRootUrl.host = aPath;
return urlGenerate(aRootUrl);
}
var joined = aPath.charAt(0) === '/'
? aPath
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
if (aRootUrl) {
aRootUrl.path = joined;
return urlGenerate(aRootUrl);
}
return joined;
}
exports.join = join;
exports.isAbsolute = function (aPath) {
return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
};
/**
* Make a path relative to a URL or another path.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be made relative to aRoot.
*/
function relative(aRoot, aPath) {
if (aRoot === "") {
aRoot = ".";
}
aRoot = aRoot.replace(/\/$/, '');
// It is possible for the path to be above the root. In this case, simply
// checking whether the root is a prefix of the path won't work. Instead, we
// need to remove components from the root one by one, until either we find
// a prefix that fits, or we run out of components to remove.
var level = 0;
while (aPath.indexOf(aRoot + '/') !== 0) {
var index = aRoot.lastIndexOf("/");
if (index < 0) {
return aPath;
}
// If the only part of the root that is left is the scheme (i.e. http://,
// file:///, etc.), one or more slashes (/), or simply nothing at all, we
// have exhausted all components, so the path is not relative to the root.
aRoot = aRoot.slice(0, index);
if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
return aPath;
}
++level;
}
// Make sure we add a "../" for each component we removed from the root.
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
}
exports.relative = relative;
var supportsNullProto = (function () {
var obj = Object.create(null);
return !('__proto__' in obj);
}());
function identity (s) {
return s;
}
/**
* Because behavior goes wacky when you set `__proto__` on objects, we
* have to prefix all the strings in our set with an arbitrary character.
*
* See https://github.com/mozilla/source-map/pull/31 and
* https://github.com/mozilla/source-map/issues/30
*
* @param String aStr
*/
function toSetString(aStr) {
if (isProtoString(aStr)) {
return '$' + aStr;
}
return aStr;
}
exports.toSetString = supportsNullProto ? identity : toSetString;
function fromSetString(aStr) {
if (isProtoString(aStr)) {
return aStr.slice(1);
}
return aStr;
}
exports.fromSetString = supportsNullProto ? identity : fromSetString;
function isProtoString(s) {
if (!s) {
return false;
}
var length = s.length;
if (length < 9 /* "__proto__".length */) {
return false;
}
if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
s.charCodeAt(length - 2) !== 95 /* '_' */ ||
s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
s.charCodeAt(length - 4) !== 116 /* 't' */ ||
s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
s.charCodeAt(length - 8) !== 95 /* '_' */ ||
s.charCodeAt(length - 9) !== 95 /* '_' */) {
return false;
}
for (var i = length - 10; i >= 0; i--) {
if (s.charCodeAt(i) !== 36 /* '$' */) {
return false;
}
}
return true;
}
/**
* Comparator between two mappings where the original positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same original source/line/column, but different generated
* line and column the same. Useful when searching for a mapping with a
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
var cmp = mappingA.source - mappingB.source;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0 || onlyCompareOriginal) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
return mappingA.name - mappingB.name;
}
exports.compareByOriginalPositions = compareByOriginalPositions;
/**
* Comparator between two mappings with deflated source and name indices where
* the generated positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same generated line and column, but different
* source/name/original line and column the same. Useful when searching for a
* mapping with a stubbed out mapping.
*/
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
var cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0 || onlyCompareGenerated) {
return cmp;
}
cmp = mappingA.source - mappingB.source;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0) {
return cmp;
}
return mappingA.name - mappingB.name;
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
function strcmp(aStr1, aStr2) {
if (aStr1 === aStr2) {
return 0;
}
if (aStr1 > aStr2) {
return 1;
}
return -1;
}
/**
* Comparator between two mappings with inflated source and name strings where
* the generated positions are compared.
*/
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
var cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0) {
return cmp;
}
cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0) {
return cmp;
}
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
@@ -0,0 +1,211 @@
{
"_from": "source-map@^0.5.6",
"_id": "source-map@0.5.7",
"_inBundle": false,
"_integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"_location": "/snapdragon/source-map",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "source-map@^0.5.6",
"name": "source-map",
"escapedName": "source-map",
"rawSpec": "^0.5.6",
"saveSpec": null,
"fetchSpec": "^0.5.6"
},
"_requiredBy": [
"/snapdragon"
],
"_resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"_shasum": "8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc",
"_spec": "source-map@^0.5.6",
"_where": "/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah/node_modules/snapdragon",
"author": {
"name": "Nick Fitzgerald",
"email": "nfitzgerald@mozilla.com"
},
"bugs": {
"url": "https://github.com/mozilla/source-map/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Tobias Koppers",
"email": "tobias.koppers@googlemail.com"
},
{
"name": "Duncan Beevers",
"email": "duncan@dweebd.com"
},
{
"name": "Stephen Crane",
"email": "scrane@mozilla.com"
},
{
"name": "Ryan Seddon",
"email": "seddon.ryan@gmail.com"
},
{
"name": "Miles Elam",
"email": "miles.elam@deem.com"
},
{
"name": "Mihai Bazon",
"email": "mihai.bazon@gmail.com"
},
{
"name": "Michael Ficarra",
"email": "github.public.email@michael.ficarra.me"
},
{
"name": "Todd Wolfson",
"email": "todd@twolfson.com"
},
{
"name": "Alexander Solovyov",
"email": "alexander@solovyov.net"
},
{
"name": "Felix Gnass",
"email": "fgnass@gmail.com"
},
{
"name": "Conrad Irwin",
"email": "conrad.irwin@gmail.com"
},
{
"name": "usrbincc",
"email": "usrbincc@yahoo.com"
},
{
"name": "David Glasser",
"email": "glasser@davidglasser.net"
},
{
"name": "Chase Douglas",
"email": "chase@newrelic.com"
},
{
"name": "Evan Wallace",
"email": "evan.exe@gmail.com"
},
{
"name": "Heather Arthur",
"email": "fayearthur@gmail.com"
},
{
"name": "Hugh Kennedy",
"email": "hughskennedy@gmail.com"
},
{
"name": "David Glasser",
"email": "glasser@davidglasser.net"
},
{
"name": "Simon Lydell",
"email": "simon.lydell@gmail.com"
},
{
"name": "Jmeas Smith",
"email": "jellyes2@gmail.com"
},
{
"name": "Michael Z Goddard",
"email": "mzgoddard@gmail.com"
},
{
"name": "azu",
"email": "azu@users.noreply.github.com"
},
{
"name": "John Gozde",
"email": "john@gozde.ca"
},
{
"name": "Adam Kirkton",
"email": "akirkton@truefitinnovation.com"
},
{
"name": "Chris Montgomery",
"email": "christopher.montgomery@dowjones.com"
},
{
"name": "J. Ryan Stinnett",
"email": "jryans@gmail.com"
},
{
"name": "Jack Herrington",
"email": "jherrington@walmartlabs.com"
},
{
"name": "Chris Truter",
"email": "jeffpalentine@gmail.com"
},
{
"name": "Daniel Espeset",
"email": "daniel@danielespeset.com"
},
{
"name": "Jamie Wong",
"email": "jamie.lf.wong@gmail.com"
},
{
"name": "Eddy Bruël",
"email": "ejpbruel@mozilla.com"
},
{
"name": "Hawken Rives",
"email": "hawkrives@gmail.com"
},
{
"name": "Gilad Peleg",
"email": "giladp007@gmail.com"
},
{
"name": "djchie",
"email": "djchie.dev@gmail.com"
},
{
"name": "Gary Ye",
"email": "garysye@gmail.com"
},
{
"name": "Nicolas Lalevée",
"email": "nicolas.lalevee@hibnet.org"
}
],
"deprecated": false,
"description": "Generates and consumes source maps",
"devDependencies": {
"doctoc": "^0.15.0",
"webpack": "^1.12.0"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"source-map.js",
"lib/",
"dist/source-map.debug.js",
"dist/source-map.js",
"dist/source-map.min.js",
"dist/source-map.min.js.map"
],
"homepage": "https://github.com/mozilla/source-map",
"license": "BSD-3-Clause",
"main": "./source-map.js",
"name": "source-map",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/mozilla/source-map.git"
},
"scripts": {
"build": "webpack --color",
"test": "npm run build && node test/run-tests.js",
"toc": "doctoc --title '## Table of Contents' README.md && doctoc --title '## Table of Contents' CONTRIBUTING.md"
},
"typings": "source-map",
"version": "0.5.7"
}
@@ -0,0 +1,8 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator;
exports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer;
exports.SourceNode = require('./lib/source-node').SourceNode;
+130
View File
@@ -0,0 +1,130 @@
{
"_from": "snapdragon@^0.8.1",
"_id": "snapdragon@0.8.2",
"_inBundle": false,
"_integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
"_location": "/snapdragon",
"_phantomChildren": {
"decode-uri-component": "0.2.0",
"is-descriptor": "0.1.6",
"is-extendable": "0.1.1",
"ms": "2.0.0",
"resolve-url": "0.2.1",
"urix": "0.1.0"
},
"_requested": {
"type": "range",
"registry": true,
"raw": "snapdragon@^0.8.1",
"name": "snapdragon",
"escapedName": "snapdragon",
"rawSpec": "^0.8.1",
"saveSpec": null,
"fetchSpec": "^0.8.1"
},
"_requiredBy": [
"/braces",
"/expand-brackets",
"/extglob",
"/micromatch",
"/nanomatch"
],
"_resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
"_shasum": "64922e7c565b0e14204ba1aa7d6964278d25182d",
"_spec": "snapdragon@^0.8.1",
"_where": "/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah/node_modules/micromatch",
"author": {
"name": "Jon Schlinkert",
"url": "https://github.com/jonschlinkert"
},
"bugs": {
"url": "https://github.com/jonschlinkert/snapdragon/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Brian Woodward",
"url": "https://twitter.com/doowb"
},
{
"name": "Edward Betts",
"url": "http://edwardbetts.com"
},
{
"name": "Jon Schlinkert",
"url": "http://twitter.com/jonschlinkert"
}
],
"dependencies": {
"base": "^0.11.1",
"debug": "^2.2.0",
"define-property": "^0.2.5",
"extend-shallow": "^2.0.1",
"map-cache": "^0.2.2",
"source-map": "^0.5.6",
"source-map-resolve": "^0.5.0",
"use": "^3.1.0"
},
"deprecated": false,
"description": "Fast, pluggable and easy-to-use parser-renderer factory.",
"devDependencies": {
"gulp": "^3.9.1",
"gulp-eslint": "^3.0.1",
"gulp-format-md": "^0.1.10",
"gulp-istanbul": "^1.1.1",
"gulp-mocha": "^3.0.1",
"gulp-unused": "^0.2.0",
"mocha": "^3.0.2"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js",
"lib"
],
"homepage": "https://github.com/jonschlinkert/snapdragon",
"keywords": [
"lexer",
"snapdragon"
],
"license": "MIT",
"main": "index.js",
"name": "snapdragon",
"repository": {
"type": "git",
"url": "git+https://github.com/jonschlinkert/snapdragon.git"
},
"scripts": {
"test": "mocha"
},
"verb": {
"toc": false,
"layout": "default",
"tasks": [
"readme"
],
"plugins": [
"gulp-format-md"
],
"related": {
"description": "These libraries use snapdragon:",
"list": [
"braces",
"expand-brackets",
"extglob",
"micromatch"
]
},
"reflinks": [
"css",
"pug",
"verb",
"verb-generate-readme"
],
"lint": {
"reflinks": true
}
},
"version": "0.8.2"
}