# add dist

This commit is contained in:
Mario Romano
2016-04-21 11:56:31 +01:00
parent 5914688467
commit 07807e7bc3
13499 changed files with 1808930 additions and 5 deletions

View File

@@ -0,0 +1,15 @@
Contributing Guidelines
=======================
When implementing a new feature or a bugfix, consider these points:
* Is this thing useful to other people, or is it just catering for an obscure corner case resulting from e.g. weirdness in personal dev environment?
* Should the thing be live-server's responsibility at all, or is it better served by other tools?
* Am I introducing unnecessary dependencies when the same thing could easily be done using normal JavaScript / node.js features?
* Does the naming (e.g. command line parameters) make sense and uses same style as other similar ones?
* Does my code adhere to the project's coding style (observable from surrounding code)?
A few guiding principles: keep the app simple and small, focusing on what it's meant to provide: live reloading development web server. Avoid extra dependencies and the need to do configuration when possible and it makes sense. Minimize bloat.
**Run `npm test` to check that you are not introducing new bugs or style issues!**

View File

@@ -0,0 +1,193 @@
[![view on npm](http://img.shields.io/npm/v/live-server.svg)](https://www.npmjs.org/package/live-server)
[![npm module downloads per month](http://img.shields.io/npm/dm/live-server.svg)](https://www.npmjs.org/package/live-server)
Live Server
===========
This is a little development server with live reload capability. Use it for hacking your HTML/JavaScript/CSS files, but not for deploying the final site.
There are two reasons for using this:
1. AJAX requests don't work with the `file://` protocol due to security restrictions, i.e. you need a server if your site fetches content through JavaScript.
2. Having the page reload automatically after changes to files can accelerate development.
If you don't want/need the live reload, you should probably use something simpler, like the following Python-based one-liner:
python -m SimpleHTTPServer
Installation
------------
You need node.js and npm. You should probably install this globally.
**Npm way**
npm install -g live-server
**Manual way**
git clone https://github.com/tapio/live-server
cd live-server
npm install # Local dependencies if you want to hack
npm install -g # Install globally
Usage from command line
-----------------------
Issue the command `live-server` in your project's directory. Alternatively you can add the path to serve as a command line parameter.
This will automatically launch the default browser. When you make a change to any file, the browser will reload the page - unless it was a CSS file in which case the changes are applied without a reload.
Command line parameters:
* `--port=NUMBER` - select port to use (can also be done with PORT environment variable)
* `--host=ADDRESS` - select host address to bind to, default: 0.0.0.0 ("any address")
* `--no-browser` - suppress automatic web browser launching
* `--browser=BROWSER` - specify browser to use instead of system default
* `--quiet` - suppress logging
* `--open=PATH` - launch browser to PATH instead of server root
* `--watch=PATH` - comma-separated string of paths to exclusively watch for changes (default: watch everything)
* `--ignore=PATH` - comma-separated string of paths to ignore
* `--ignorePattern=RGXP` - Regular expression of files to ignore (ie `.*\.jade`)
* `--entry-file=PATH` - serve this file in place of missing files (useful for single page apps)
* `--mount=ROUTE:PATH` - serve the paths contents under the defined route (multiple definitions possible)
* `--wait=MILLISECONDS` - wait for all changes, before reloading
* `--help | -h` - display terse usage hint and exit
* `--version | -v` - display version and exit
Default options:
If a file `~/.live-server.json` exists it will be loaded and used as default options for live-server on the command line. See "Usage from node" for option names.
Usage from node
---------------
```javascript
var liveServer = require("live-server");
var params = {
port: 8181, // Set the server port. Defaults to 8080.
host: "0.0.0.0", // Set the address to bind to. Defaults to 0.0.0.0.
root: "/public", // Set root directory that's being server. Defaults to cwd.
open: false, // When false, it won't load your browser by default.
ignore: 'scss,my/templates', // comma-separated string for paths to ignore
file: "index.html", // When set, serve this file for every 404 (useful for single-page applications)
wait: 1000, // Waits for all changes, before reloading. Defaults to 0 sec.
mount: [['/components', './node_modules']] // Mount a directory to a route.
};
liveServer.start(params);
```
Troubleshooting
---------------
Open your browser's console: there should be a message at the top stating that live reload is enabled. Note that you will need a browser that supports WebSockets. If there are errors, deal with them. If it's still not working, [file an issue](https://github.com/tapio/live-server/issues).
How it works
------------
The server is a simple node app that serves the working directory and its subdirectories. It also watches the files for changes and when that happens, it sends a message through a web socket connection to the browser instructing it to reload. In order for the client side to support this, the server injects a small piece of JavaScript code to each requested html file. This script establishes the web socket connection and listens to the reload requests. CSS files can be refreshed without a full page reload by finding the referenced stylesheets from the DOM and tricking the browser to fetch and parse them again.
Contributing
------------
We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
Version history
---------------
* v0.9.2
- Updated most dependencies to latest versions
- `--quiet` now silences warning about injection failure
- Giving explicit `--watch` paths now disables adding mounted paths to watching
* v0.9.1
- `--ignorePattern=RGXP` exclude files from watching by regexp (@psi-4ward)
- `--watch=PATH` cli option to only watch given paths
* v0.9.0
- `--mount=ROUTE:PATH` cli option to specify alternative routes to paths (@pmentz)
- `--browser=BROWSER` cli option to specify browser to use (@sakiv)
- Improved error reporting
- Basic support for injecting the reload code to SVG files (@dotnetCarpenter, @tapio)
- LiveServer.shutdown() function to close down the server and file watchers
- If host parameter is given, use it for browser URL instead of resolved IP
- Initial testing framework (@harrytruong, @evanplaice, @tapio)
* v0.8.2
- Load initial settings from `~/.live-server.json` if exists (@mikker)
- Allow `--port=0` to select random port (@viqueen)
- Fix injecting when file extension is not lower case (@gusgard)
- Fail gracefully if browser does not support WebSockets (@mattymaloney)
- Switched to a more maintained browser opening library
* v0.8.1
- Add `--version / -v` command line flags to display version
- Add `--host` cli option to mirror the API parameter
- Once again use 127.0.0.1 instead of 0.0.0.0 as the browser URL
* v0.8.0
- Support multiple clients simultaneously (@dvv)
- Pick a random available port if the default is in use (@oliverzy, @harrytruong)
- Fix Chrome sometimes not applying CSS changes (@harrytruong)
- `--ignore=PATH` cli option to not watch given server root relative paths (@richardgoater)
- `--entry-file=PATH` cli option to specify file to use when request is not found (@izeau)
- `--wait=MSECS` cli option to wait specified time before reloading (@leolower, @harrytruong)
* v0.7.1
- Fix hang caused by trying to inject into fragment html files without `</body>`
- `logLevel` parameter in library to control amount of console spam
- `--quiet` cli option to suppress console spam
- `--open=PATH` cli option to launch browser in specified path instead of root (@richardgoater)
- Library's `noBrowser: true` option is deprecated in favor of `open: false`
* v0.7.0
- API BREAKAGE: LiveServer library now takes parameters in an object
- Add possibility to specify host to the lib
- Only inject to host page when working with web components (e.g. Polymer) (@davej)
- Open browser to 127.0.0.1, as 0.0.0.0 has issues
- `--no-browser` command line flag to suppress browser launch
- `--help` command line flag to display usage
* v0.6.4
- Allow specifying port from the command line: `live-server --port=3000` (@Pomax)
- Don't inject script as the first thing so that DOCTYPE remains valid (@wmira)
- Be more explicit with listening to all interfaces (@inadarei)
* v0.6.3
- Fix multiple _cacheOverride parameters polluting css requests
- Don't create global variables in the injected script
* v0.6.2
- Fix a deprecation warning from `send`
* v0.6.1
- Republish to fix npm troubles
* v0.6.0
- Support for using as node library (@dpgraham)
* v0.5.0
- Watching was broken with new versions of `watchr` > 2.3.3
- Added some logging to console
* v0.4.0
- Allow specifying directory to serve from command line
* v0.3.0
- Directory listings
* v0.2.0
- On-the-fly CSS refresh (no page reload)
- Refactoring
* v0.1.1
- Documentation and meta tweaks
* v0.1.0
- Initial release
License
-------
Uses MIT licensed code from [Connect](https://github.com/senchalabs/connect/) and [Roots](https://github.com/jenius/roots).
(MIT License)
Copyright (c) 2012 Tapio Vierros
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.

View File

@@ -0,0 +1,274 @@
#!/usr/bin/env node
var fs = require('fs'),
connect = require('connect'),
serveIndex = require('serve-index'),
logger = require('morgan'),
WebSocket = require('faye-websocket'),
path = require('path'),
url = require('url'),
http = require('http'),
send = require('send'),
open = require('opn'),
es = require("event-stream"),
watchr = require('watchr');
require('colors');
var INJECTED_CODE = fs.readFileSync(path.join(__dirname, "injected.html"), "utf8");
var LiveServer = {
server: null,
watchers: [],
logLevel: 2
};
function escape(html){
return String(html)
.replace(/&(?!\w+;)/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
// Based on connect.static(), but streamlined and with added code injecter
function staticServer(root) {
return function(req, res, next) {
if (req.method !== "GET" && req.method !== "HEAD") return next();
var reqpath = url.parse(req.url).pathname;
var hasNoOrigin = !req.headers.origin;
var injectCandidates = [ "</body>", "</svg>" ];
var injectTag = null;
function directory() {
var pathname = url.parse(req.originalUrl).pathname;
res.statusCode = 301;
res.setHeader('Location', pathname + '/');
res.end('Redirecting to ' + escape(pathname) + '/');
}
function file(filepath, stat) {
var x = path.extname(filepath).toLocaleLowerCase(),
possibleExtensions = [ "", ".html", ".htm", ".xhtml", ".php", ".svg" ];
if (hasNoOrigin && (possibleExtensions.indexOf(x) > -1)) {
// TODO: Sync file read here is not nice, but we need to determine if the html should be injected or not
var contents = fs.readFileSync(filepath, "utf8");
for (var i = 0; i < injectCandidates.length; ++i) {
if (contents.indexOf(injectCandidates[i]) > -1) {
injectTag = injectCandidates[i];
break;
}
}
if (injectTag === null && LiveServer.logLevel >= 2) {
console.warn("Failed to inject refresh script!".yellow,
"Couldn't find any of the tags ", injectCandidates, "from", filepath);
}
}
}
function error(err) {
if (err.status === 404) return next();
next(err);
}
function inject(stream) {
if (injectTag) {
// We need to modify the length given to browser
var len = INJECTED_CODE.length + res.getHeader('Content-Length');
res.setHeader('Content-Length', len);
var originalPipe = stream.pipe;
stream.pipe = function(res) {
originalPipe.call(stream, es.replace(new RegExp(injectTag, "i"), INJECTED_CODE + injectTag)).pipe(res);
};
}
}
send(req, reqpath, { root: root })
.on('error', error)
.on('directory', directory)
.on('file', file)
.on('stream', inject)
.pipe(res);
};
}
/**
* Rewrite request URL and pass it back to the static handler.
* @param staticHandler {function} Next handler
* @param file {string} Path to the entry point file
*/
function entryPoint(staticHandler, file) {
if (!file) return function(req, res, next) { next(); };
return function(req, res, next) {
req.url = "/" + file;
staticHandler(req, res, next);
};
}
/**
* Start a live server with parameters given as an object
* @param host {string} Address to bind to (default: 0.0.0.0)
* @param port {number} Port number (default: 8080)
* @param root {string} Path to root directory (default: cwd)
* @param watch {array} Paths to exclusively watch for changes
* @param ignore {array} Paths to ignore when watching files for changes
* @param ignorePattern {regexp} Ignore files by RegExp
* @param open {string} Subpath to open in browser, use false to suppress launch (default: server root)
* @param mount {array} Mount directories onto a route, e.g. [['/components', './node_modules']].
* @param logLevel {number} 0 = errors only, 1 = some, 2 = lots
* @param file {string} Path to the entry point file
* @param wait {number} Server will wait for all changes, before reloading
*/
LiveServer.start = function(options) {
options = options || {};
var host = options.host || '0.0.0.0';
var port = options.port !== undefined ? options.port : 8080; // 0 means random
var root = options.root || process.cwd();
var mount = options.mount || [];
var watchPaths = options.watch || [root];
LiveServer.logLevel = options.logLevel === undefined ? 2 : options.logLevel;
var openPath = (options.open === undefined || options.open === true) ?
"" : ((options.open === null || options.open === false) ? null : options.open);
if (options.noBrowser) openPath = null; // Backwards compatibility with 0.7.0
var file = options.file;
var staticServerHandler = staticServer(root);
var wait = options.wait || 0;
var browser = options.browser || null;
// Setup a web server
var app = connect();
mount.forEach(function(mountRule) {
var mountPath = path.resolve(process.cwd(), mountRule[1]);
if (!options.watch) // Auto add mount paths to wathing but only if exclusive path option is not given
watchPaths.push(mountPath);
app.use(mountRule[0], staticServer(mountPath));
if (LiveServer.logLevel >= 1)
console.log('Mapping %s to "%s"', mountRule[0], mountPath);
});
app.use(staticServerHandler) // Custom static server
.use(entryPoint(staticServerHandler, file))
.use(serveIndex(root, { icons: true }));
if (LiveServer.logLevel >= 2)
app.use(logger('dev'));
var server = http.createServer(app);
// Handle server startup errors
server.addListener('error', function(e) {
if (e.code === 'EADDRINUSE') {
var serveURL = 'http://' + host + ':' + port;
console.log('%s is already in use. Trying another port.'.yellow, serveURL);
setTimeout(function() {
server.listen(0, host);
}, 1000);
} else {
console.error(e.toString().red);
LiveServer.shutdown();
}
});
// Handle successful server
server.addListener('listening', function(e) {
LiveServer.server = server;
var address = server.address();
var serveHost = address.address === "0.0.0.0" ? "127.0.0.1" : address.address;
var openHost = host === "0.0.0.0" ? "127.0.0.1" : host;
var serveURL = 'http://' + serveHost + ':' + address.port;
var openURL = 'http://' + openHost + ':' + address.port;
// Output
if (LiveServer.logLevel >= 1) {
if (serveURL === openURL)
console.log(("Serving \"%s\" at %s").green, root, serveURL);
else
console.log(("Serving \"%s\" at %s (%s)").green, root, openURL, serveURL);
}
// Launch browser
if (openPath !== null)
open(openURL + openPath, {app: browser});
});
// Setup server to listen at port
server.listen(port, host);
// WebSocket
var clients = [];
server.addListener('upgrade', function(request, socket, head) {
var ws = new WebSocket(request, socket, head);
ws.onopen = function() { ws.send('connected'); };
if (wait > 0) {
(function(ws) {
var wssend = ws.send;
var waitTimeout;
ws.send = function() {
var args = arguments;
if (waitTimeout) clearTimeout(waitTimeout);
waitTimeout = setTimeout(function(){
wssend.apply(ws, args);
}, wait);
};
})(ws);
}
ws.onclose = function() {
clients = clients.filter(function (x) {
return x !== ws;
});
};
clients.push(ws);
});
// Setup file watcher
watchr.watch({
paths: watchPaths,
ignorePaths: options.ignore || false,
ignoreCommonPatterns: true,
ignoreHiddenFiles: true,
ignoreCustomPatterns: options.ignorePattern || null,
preferredMethods: [ 'watchFile', 'watch' ],
interval: 1407,
listeners: {
error: function(err) {
console.log("ERROR:".red, err);
},
change: function(eventName, filePath, fileCurrentStat, filePreviousStat) {
clients.forEach(function(ws) {
if (!ws) return;
if (path.extname(filePath) === ".css") {
ws.send('refreshcss');
if (LiveServer.logLevel >= 1)
console.log("CSS change detected".magenta, filePath);
} else {
ws.send('reload');
if (LiveServer.logLevel >= 1)
console.log("File change detected".cyan, filePath);
}
});
}
},
next: function(err, watchers) {
if (err)
console.error("Error watching files:".red, err);
LiveServer.watchers = watchers;
}
});
return server;
};
LiveServer.shutdown = function() {
var watchers = LiveServer.watchers;
if (watchers) {
for (var i = 0; i < watchers.length; ++i)
watchers[i].close();
}
var server = LiveServer.server;
if (server)
server.close();
};
module.exports = LiveServer;

View File

@@ -0,0 +1,31 @@
<!-- Code injected by live-server -->
<script type="text/javascript">
// <![CDATA[ <-- For SVG support
if ('WebSocket' in window) {
(function() {
function refreshCSS() {
var sheets = [].slice.call(document.getElementsByTagName("link"));
var head = document.getElementsByTagName("head")[0];
for (var i = 0; i < sheets.length; ++i) {
var elem = sheets[i];
head.removeChild(elem);
var rel = elem.rel;
if (elem.href && typeof rel != "string" || rel.length == 0 || rel.toLowerCase() == "stylesheet") {
var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/, '');
elem.href = url + (url.indexOf('?') >= 0 ? '&' : '?') + '_cacheOverride=' + (new Date().valueOf());
}
head.appendChild(elem);
}
}
var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
var address = protocol + window.location.host + window.location.pathname + '/ws';
var socket = new WebSocket(address);
socket.onmessage = function(msg) {
if (msg.data == 'reload') window.location.reload();
else if (msg.data == 'refreshcss') refreshCSS();
};
console.log('Live reload enabled.');
})();
}
// ]]>
</script>

View File

@@ -0,0 +1,124 @@
#!/usr/bin/env node
var path = require('path');
var fs = require('fs');
var assign = require('object-assign');
var liveServer = require("./index");
var opts = {
port: process.env.PORT,
open: true,
mount: [],
logLevel: 2
};
var homeDir = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
var configPath = path.join(homeDir, '.live-server.json');
if (fs.existsSync(configPath)) {
var userConfig = fs.readFileSync(configPath, 'utf8');
assign(opts, JSON.parse(userConfig));
}
for (var i = process.argv.length - 1; i >= 2; --i) {
var arg = process.argv[i];
if (arg.indexOf("--port=") > -1) {
var portString = arg.substring(7);
var portNumber = parseInt(portString, 10);
if (portNumber == portString) {
opts.port = portNumber;
process.argv.splice(i, 1);
}
}
else if (arg.indexOf("--host=") > -1) {
opts.host = arg.substring(7);
process.argv.splice(i, 1);
}
else if (arg.indexOf("--open=") > -1) {
var open = arg.substring(7);
if (open.indexOf('/') !== 0) {
open = '/' + open;
}
opts.open = open;
process.argv.splice(i, 1);
}
else if (arg.indexOf("--watch=") > -1) {
// Will be modified later when cwd is known
opts.watch = arg.substring(8).split(",");
process.argv.splice(i, 1);
}
else if (arg.indexOf("--ignore=") > -1) {
// Will be modified later when cwd is known
opts.ignore = arg.substring(9).split(",");
process.argv.splice(i, 1);
}
else if (arg.indexOf("--ignorePattern=") > -1) {
opts.ignorePattern = new RegExp(arg.substring(16));
process.argv.splice(i, 1);
}
else if (arg == "--no-browser") {
opts.open = false;
process.argv.splice(i, 1);
}
else if (arg.indexOf("--browser=") > -1) {
opts.browser = arg.substring(10).split(",");
process.argv.splice(i, 1);
}
else if (arg.indexOf("--entry-file=") > -1) {
var file = arg.substring(13);
if (file.length) {
opts.file = file;
process.argv.splice(i, 1);
}
}
else if (arg == "--quiet" || arg == "-q") {
opts.logLevel = 0;
process.argv.splice(i, 1);
}
else if (arg.indexOf("--mount=") > -1) {
// e.g. "--mount=/components:./node_modules" will be ['/components', '<process.cwd()>/node_modules']
var mountRule = arg.substring(8).split(":");
mountRule[1] = path.resolve(process.cwd(), mountRule[1]);
opts.mount.push(mountRule);
process.argv.splice(i, 1);
}
else if (arg.indexOf("--wait=") > -1) {
var waitString = arg.substring(7);
var waitNumber = parseInt(waitString, 10);
if (waitNumber == waitString) {
opts.wait = waitNumber;
process.argv.splice(i, 1);
}
}
else if (arg == "--version" || arg == "-v") {
var packageJson = require('./package.json');
console.log(packageJson.name, packageJson.version);
process.exit();
}
else if (arg == "--help" || arg == "-h") {
console.log('Usage: live-server [-v|--version] [-h|--help] [-q|--quiet] [--port=PORT] [--host=HOST] [--open=PATH] [--no-browser] [--browser=BROWSER] [--ignore=PATH] [--ignorePattern=RGXP] [--entry-file=PATH] [--mount=ROUTE:PATH] [--wait=MILLISECONDS] [PATH]');
process.exit();
}
else if (arg == "--test") {
// Hidden param for tests to exit automatically
setTimeout(liveServer.shutdown, 500);
process.argv.splice(i, 1);
}
}
if (process.argv[2]) {
process.chdir(process.argv[2]);
}
// Patch paths
var cwd = process.cwd();
if (opts.watch) {
opts.watch = opts.watch.map(function(relativePath) {
return path.join(cwd, relativePath);
});
}
if (opts.ignore) {
opts.ignore = opts.ignore.map(function(relativePath) {
return path.join(cwd, relativePath);
});
}
liveServer.start(opts);

View File

@@ -0,0 +1,10 @@
(The MIT License)
Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me) <us@bevry.me>
Copyright © 2011-2012 [Benjamin Lupton](http://balupton.com) <b@lupton.cc>
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.

View File

@@ -0,0 +1,75 @@
# Ambi [![Build Status](https://secure.travis-ci.org/bevry/ambi.png?branch=master)](http://travis-ci.org/bevry/ambi)
Execute a function ambidextrously (normalizes the differences between synchronous and asynchronous functions).
Useful for treating synchronous functions as asynchronous functions (like supporting both synchronous and asynchronous event definitions automatically).
## Install
### Backend
1. [Install Node.js](http://bevry.me/node/install)
2. `npm install --save ambi`
### Frontend
1. [See Browserify](http://browserify.org)
## Usage
``` javascript
// Import
var ambi = require('ambi')
var result
// Sample methods
var syncMethod = function(x,y){
return x*y
}
var asyncMethod = function(x,y,next){
return setTimeout(function(){
next(null,x*y)
},0)
}
// Call the synchronous function asynchronously
result = ambi(syncMethod, 5, 2, function(err,result){ // ambi adds support for this asynchronous callback automatically
console.log(err, result) // null, 10
})
console.log(result) // 10 - just like normal
// Call the asynchronous function asynchronously
result = ambi(asyncMethod, 5, 2, function(err,result){ // ambi doesn't do anything special here
console.log(err, result) // null, 10
})
console.log(result) // setTimeout - just like normal
```
## Process
- Ambi accepts the arguments `(method, args...)`
- `method` is the function to execute
- `args...` is the arguments to send to the method
- the last argument is expected to be the completion callback
- the completion callback is optional, but if defined, is expected to have the signature of `(err, results...)`
- If the method has the same amount of arguments as those ambi received, then we assume it is an asynchronous method and let it handle calling of the completion callback itself
- If the method does not have the same amount of arguments as those ambi received, then we assume it is a synchronous method and we'll call the completion callback ourselves
- If the synchronous method throws an error or returns an error, we'll try to call the completion callback with a single `err` argument
- If the synchronous method executes without error, we'll try to call the completion callback with a `err` argument equal to null, and a `result` argument equal to the returned result of the synchronous method
- Ambi can also introspect a different method than the one it fires, by passing `[methodToFire, methodToIntrospect]` as the `method` argument
## History
You can discover the history inside the [History.md](https://github.com/bevry/ambi/blob/master/History.md#files) file
## License
Licensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)
<br/>Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me)
<br/>Copyright © 2011-2012 [Benjamin Arthur Lupton](http://balupton.com)

View File

@@ -0,0 +1,97 @@
{
"_args": [
[
"ambi@~2.0.0",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util"
]
],
"_from": "ambi@>=2.0.0 <2.1.0",
"_id": "ambi@2.0.0",
"_inCache": true,
"_installable": true,
"_location": "/live-server/ambi",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "1.2.15",
"_phantomChildren": {},
"_requested": {
"name": "ambi",
"raw": "ambi@~2.0.0",
"rawSpec": "~2.0.0",
"scope": null,
"spec": ">=2.0.0 <2.1.0",
"type": "range"
},
"_requiredBy": [
"/live-server/bal-util",
"/live-server/taskgroup"
],
"_resolved": "https://registry.npmjs.org/ambi/-/ambi-2.0.0.tgz",
"_shasum": "42c2bf98e8d101aa4da28a812678a5dbe36ada66",
"_shrinkwrap": null,
"_spec": "ambi@~2.0.0",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util",
"author": {
"email": "us@bevry.me",
"name": "Bevry Pty Ltd",
"url": "http://bevry.me"
},
"bugs": {
"url": "https://github.com/bevry/ambi/issues"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "https://github.com/balupton"
}
],
"dependencies": {
"typechecker": "~2.0.1"
},
"description": "Execute a function ambidextrously (normalizes the differences between synchronous and asynchronous functions). Useful for treating synchronous functions as asynchronous functions (like supporting both synchronous and asynchronous event definitions automat",
"devDependencies": {
"chai": "~1.5.0",
"coffee-script": "~1.6.2",
"joe": "~1.1.2"
},
"directories": {
"lib": "./out/lib"
},
"dist": {
"shasum": "42c2bf98e8d101aa4da28a812678a5dbe36ada66",
"tarball": "https://registry.npmjs.org/ambi/-/ambi-2.0.0.tgz"
},
"engines": {
"node": ">=0.4"
},
"homepage": "https://github.com/bevry/ambi",
"keywords": [
"sync",
"async",
"fire",
"exec",
"execute",
"ambidextrous"
],
"main": "./out/lib/ambi.js",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "ambi",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/bevry/ambi.git"
},
"scripts": {
"test": "node ./out/test/ambi-test.js"
},
"version": "2.0.0"
}

View File

@@ -0,0 +1,9 @@
(The MIT License)
Copyright (c) 2011+ Benjamin Lupton <b@lupton.cc>
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.

View File

@@ -0,0 +1,45 @@
# Balupton's Utility Functions [![Build Status](https://secure.travis-ci.org/balupton/bal-util.png?branch=master)](http://travis-ci.org/balupton/bal-util)
Common utility functions for Node.js used and maintained by Benjamin Lupton
## Install
### Backend
1. [Install Node.js](http://bevry.me/node/install)
2. `npm install --save bal-util`
### Frontend
1. [See Browserify](http://browserify.org/)
## Usage
Best off looking at source, it's well documented, and there are plenty of tests
## Future
We're in the process of abstracting the pieces of bal-util out into their own modules. So far, we've done the following:
- [ambi](https://github.com/bevry/ambi) < `balUtilFlow.fireWithOptionalCallback`
- [eachr](https://github.com/bevry/eachr) < `balUtilFlow.each`
- [extendr](https://github.com/bevry/extendr) < `balUtilFlow.(extend|clone|etc)`
- [getsetdeep](https://github.com/bevry/getsetdeep) < `balUtilFlow.(get|set)Deep`
- [safeCallback](https://github.com/bevry/safecallback) < b`alUtilFlow.safeCallback`
- [safefs](https://github.com/bevry/safefs) < `balUtilPaths.(openFile|closeFile|etc)`
- [TaskGroup](https://github.com/bevry/taskgroup) < `balUtilFlow.Group`
- [typeChecker](https://github.com/bevry/typechecker) < `balUtilTypes`
## History
You can discover the history inside the [History.md](https://github.com/balupton/bal-util/blob/master/History.md#files) file
## License
Licensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)
<br/>Copyright © 2011+ [Benjamin Arthur Lupton](http://balupton.com)

View File

@@ -0,0 +1,121 @@
{
"_args": [
[
"bal-util@~1.18.0",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/watchr"
]
],
"_from": "bal-util@>=1.18.0 <1.19.0",
"_id": "bal-util@1.18.0",
"_inCache": true,
"_installable": true,
"_location": "/live-server/bal-util",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "1.2.15",
"_phantomChildren": {},
"_requested": {
"name": "bal-util",
"raw": "bal-util@~1.18.0",
"rawSpec": "~1.18.0",
"scope": null,
"spec": ">=1.18.0 <1.19.0",
"type": "range"
},
"_requiredBy": [
"/live-server/watchr"
],
"_resolved": "https://registry.npmjs.org/bal-util/-/bal-util-1.18.0.tgz",
"_shasum": "4e2e2d90816d1a6b7e37174020042a2ce258421d",
"_shrinkwrap": null,
"_spec": "bal-util@~1.18.0",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/watchr",
"author": {
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "http://balupton.com"
},
"bugs": {
"url": "https://github.com/balupton/bal-util/issues"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "https://github.com/balupton"
},
{
"email": "fridman@mail.sfsu.edu",
"name": "Sean Fridman",
"url": "https://github.com/sfrdmn"
}
],
"dependencies": {
"ambi": "~2.0.0",
"eachr": "~2.0.2",
"extendr": "~2.0.1",
"getsetdeep": "~2.0.0",
"safecallback": "~1.0.1",
"safefs": "~2.0.3",
"taskgroup": "~2.0.0",
"typechecker": "~2.0.1"
},
"description": "Common utility functions for Node.js used and maintained by Benjamin Lupton",
"devDependencies": {
"chai": "~1.5.0",
"coffee-script": "~1.6.2",
"joe": "~1.1.2"
},
"directories": {
"lib": "./out/lib"
},
"dist": {
"shasum": "4e2e2d90816d1a6b7e37174020042a2ce258421d",
"tarball": "https://registry.npmjs.org/bal-util/-/bal-util-1.18.0.tgz"
},
"engines": {
"node": ">=0.4"
},
"homepage": "https://github.com/balupton/bal-util",
"keywords": [
"javascript",
"flow",
"control",
"async",
"sync",
"tasks",
"batch",
"utility",
"util",
"utilities",
"paths",
"path",
"events",
"event",
"module",
"modules",
"compare",
"comparison",
"html"
],
"main": "./out/lib/balutil",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "bal-util",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/balupton/bal-util.git"
},
"scripts": {
"test": "node ./out/test/everything-test.js --joe-reporter=list"
},
"version": "1.18.0"
}

View File

@@ -0,0 +1,23 @@
Original Library
- Copyright (c) Marak Squires
Additional Functionality
- Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
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.

View File

@@ -0,0 +1,178 @@
# colors.js [![Build Status](https://travis-ci.org/Marak/colors.js.svg?branch=master)](https://travis-ci.org/Marak/colors.js)
## get color and style in your node.js console
![Demo](https://raw.githubusercontent.com/Marak/colors.js/master/screenshots/colors.png)
## Installation
npm install colors
## colors and styles!
### text colors
- black
- red
- green
- yellow
- blue
- magenta
- cyan
- white
- gray
- grey
### background colors
- bgBlack
- bgRed
- bgGreen
- bgYellow
- bgBlue
- bgMagenta
- bgCyan
- bgWhite
### styles
- reset
- bold
- dim
- italic
- underline
- inverse
- hidden
- strikethrough
### extras
- rainbow
- zebra
- america
- trap
- random
## Usage
By popular demand, `colors` now ships with two types of usages!
The super nifty way
```js
var colors = require('colors');
console.log('hello'.green); // outputs green text
console.log('i like cake and pies'.underline.red) // outputs red underlined text
console.log('inverse the color'.inverse); // inverses the color
console.log('OMG Rainbows!'.rainbow); // rainbow
console.log('Run the trap'.trap); // Drops the bass
```
or a slightly less nifty way which doesn't extend `String.prototype`
```js
var colors = require('colors/safe');
console.log(colors.green('hello')); // outputs green text
console.log(colors.red.underline('i like cake and pies')) // outputs red underlined text
console.log(colors.inverse('inverse the color')); // inverses the color
console.log(colors.rainbow('OMG Rainbows!')); // rainbow
console.log(colors.trap('Run the trap')); // Drops the bass
```
I prefer the first way. Some people seem to be afraid of extending `String.prototype` and prefer the second way.
If you are writing good code you will never have an issue with the first approach. If you really don't want to touch `String.prototype`, the second usage will not touch `String` native object.
## Disabling Colors
To disable colors you can pass the following arguments in the command line to your application:
```bash
node myapp.js --no-color
```
## Console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data)
```js
var name = 'Marak';
console.log(colors.green('Hello %s'), name);
// outputs -> 'Hello Marak'
```
## Custom themes
### Using standard API
```js
var colors = require('colors');
colors.setTheme({
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
});
// outputs red text
console.log("this is an error".error);
// outputs yellow text
console.log("this is a warning".warn);
```
### Using string safe API
```js
var colors = require('colors/safe');
// set single property
var error = colors.red;
error('this is red');
// set theme
colors.setTheme({
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
});
// outputs red text
console.log(colors.error("this is an error"));
// outputs yellow text
console.log(colors.warn("this is a warning"));
```
You can also combine them:
```javascript
var colors = require('colors');
colors.setTheme({
custom: ['red', 'underline']
});
console.log('test'.custom);
```
*Protip: There is a secret undocumented style in `colors`. If you find the style you can summon him.*

View File

@@ -0,0 +1,74 @@
var colors = require('../lib/index');
console.log("First some yellow text".yellow);
console.log("Underline that text".yellow.underline);
console.log("Make it bold and red".red.bold);
console.log(("Double Raindows All Day Long").rainbow)
console.log("Drop the bass".trap)
console.log("DROP THE RAINBOW BASS".trap.rainbow)
console.log('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported
console.log('So '.green + 'are'.underline + ' ' + 'inverse'.inverse + ' styles! '.yellow.bold); // styles not widely supported
console.log("Zebras are so fun!".zebra);
//
// Remark: .strikethrough may not work with Mac OS Terminal App
//
console.log("This is " + "not".strikethrough + " fun.");
console.log('Background color attack!'.black.bgWhite)
console.log('Use random styles on everything!'.random)
console.log('America, Heck Yeah!'.america)
console.log('Setting themes is useful')
//
// Custom themes
//
console.log('Generic logging theme as JSON'.green.bold.underline);
// Load theme with JSON literal
colors.setTheme({
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
});
// outputs red text
console.log("this is an error".error);
// outputs yellow text
console.log("this is a warning".warn);
// outputs grey text
console.log("this is an input".input);
console.log('Generic logging theme as file'.green.bold.underline);
// Load a theme from file
colors.setTheme(__dirname + '/../themes/generic-logging.js');
// outputs red text
console.log("this is an error".error);
// outputs yellow text
console.log("this is a warning".warn);
// outputs grey text
console.log("this is an input".input);
//console.log("Don't summon".zalgo)

View File

@@ -0,0 +1,76 @@
var colors = require('../safe');
console.log(colors.yellow("First some yellow text"));
console.log(colors.yellow.underline("Underline that text"));
console.log(colors.red.bold("Make it bold and red"));
console.log(colors.rainbow("Double Raindows All Day Long"))
console.log(colors.trap("Drop the bass"))
console.log(colors.rainbow(colors.trap("DROP THE RAINBOW BASS")));
console.log(colors.bold.italic.underline.red('Chains are also cool.')); // styles not widely supported
console.log(colors.green('So ') + colors.underline('are') + ' ' + colors.inverse('inverse') + colors.yellow.bold(' styles! ')); // styles not widely supported
console.log(colors.zebra("Zebras are so fun!"));
console.log("This is " + colors.strikethrough("not") + " fun.");
console.log(colors.black.bgWhite('Background color attack!'));
console.log(colors.random('Use random styles on everything!'))
console.log(colors.america('America, Heck Yeah!'));
console.log('Setting themes is useful')
//
// Custom themes
//
//console.log('Generic logging theme as JSON'.green.bold.underline);
// Load theme with JSON literal
colors.setTheme({
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
});
// outputs red text
console.log(colors.error("this is an error"));
// outputs yellow text
console.log(colors.warn("this is a warning"));
// outputs grey text
console.log(colors.input("this is an input"));
// console.log('Generic logging theme as file'.green.bold.underline);
// Load a theme from file
colors.setTheme(__dirname + '/../themes/generic-logging.js');
// outputs red text
console.log(colors.error("this is an error"));
// outputs yellow text
console.log(colors.warn("this is a warning"));
// outputs grey text
console.log(colors.input("this is an input"));
// console.log(colors.zalgo("Don't summon him"))

View File

@@ -0,0 +1,86 @@
{
"_args": [
[
"colors@latest",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server"
]
],
"_from": "colors@latest",
"_id": "colors@1.1.2",
"_inCache": true,
"_installable": true,
"_location": "/live-server/colors",
"_nodeVersion": "0.11.13",
"_npmUser": {
"email": "marak.squires@gmail.com",
"name": "marak"
},
"_npmVersion": "2.1.8",
"_phantomChildren": {},
"_requested": {
"name": "colors",
"raw": "colors@latest",
"rawSpec": "latest",
"scope": null,
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"/live-server"
],
"_resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
"_shasum": "168a4701756b6a7f51a12ce0c97bfa28c084ed63",
"_shrinkwrap": null,
"_spec": "colors@latest",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server",
"author": {
"name": "Marak Squires"
},
"bugs": {
"url": "https://github.com/Marak/colors.js/issues"
},
"dependencies": {},
"description": "get colors in your node.js console",
"devDependencies": {},
"directories": {},
"dist": {
"shasum": "168a4701756b6a7f51a12ce0c97bfa28c084ed63",
"tarball": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz"
},
"engines": {
"node": ">=0.1.90"
},
"files": [
"examples",
"lib",
"LICENSE",
"safe.js",
"themes"
],
"gitHead": "8bf2ad9fa695dcb30b7e9fd83691b139fd6655c4",
"homepage": "https://github.com/Marak/colors.js",
"keywords": [
"ansi",
"terminal",
"colors"
],
"license": "MIT",
"main": "lib",
"maintainers": [
{
"email": "marak.squires@gmail.com",
"name": "marak"
}
],
"name": "colors",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/Marak/colors.js.git"
},
"scripts": {
"test": "node tests/basic-test.js && node tests/safe-test.js"
},
"version": "1.1.2"
}

View File

@@ -0,0 +1,9 @@
//
// Remark: Requiring this file will use the "safe" colors API which will not touch String.prototype
//
// var colors = require('colors/safe);
// colors.red("foo")
//
//
var colors = require('./lib/colors');
module['exports'] = colors;

View File

@@ -0,0 +1,12 @@
module['exports'] = {
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
};

View File

@@ -0,0 +1,84 @@
1.1.0 / 2015-09-14
==================
* Enable strict mode in more places
* Support io.js 3.x
* Support io.js 2.x
* Support web browser loading
- Requires bundler like Browserify or webpack
1.0.1 / 2015-04-07
==================
* Fix `TypeError`s when under `'use strict'` code
* Fix useless type name on auto-generated messages
* Support io.js 1.x
* Support Node.js 0.12
1.0.0 / 2014-09-17
==================
* No changes
0.4.5 / 2014-09-09
==================
* Improve call speed to functions using the function wrapper
* Support Node.js 0.6
0.4.4 / 2014-07-27
==================
* Work-around v8 generating empty stack traces
0.4.3 / 2014-07-26
==================
* Fix exception when global `Error.stackTraceLimit` is too low
0.4.2 / 2014-07-19
==================
* Correct call site for wrapped functions and properties
0.4.1 / 2014-07-19
==================
* Improve automatic message generation for function properties
0.4.0 / 2014-07-19
==================
* Add `TRACE_DEPRECATION` environment variable
* Remove non-standard grey color from color output
* Support `--no-deprecation` argument
* Support `--trace-deprecation` argument
* Support `deprecate.property(fn, prop, message)`
0.3.0 / 2014-06-16
==================
* Add `NO_DEPRECATION` environment variable
0.2.0 / 2014-06-15
==================
* Add `deprecate.property(obj, prop, message)`
* Remove `supports-color` dependency for node.js 0.8
0.1.0 / 2014-06-15
==================
* Add `deprecate.function(fn, message)`
* Add `process.on('deprecation', fn)` emitter
* Automatically generate message when omitted from `deprecate()`
0.0.1 / 2014-06-15
==================
* Fix warning for dynamic calls at singe call site
0.0.0 / 2014-06-15
==================
* Initial implementation

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014-2015 Douglas Christopher Wilson
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.

View File

@@ -0,0 +1,281 @@
# depd
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-image]][node-url]
[![Linux Build][travis-image]][travis-url]
[![Windows Build][appveyor-image]][appveyor-url]
[![Coverage Status][coveralls-image]][coveralls-url]
[![Gratipay][gratipay-image]][gratipay-url]
Deprecate all the things
> With great modules comes great responsibility; mark things deprecated!
## Install
This module is installed directly using `npm`:
```sh
$ npm install depd
```
This module can also be bundled with systems like
[Browserify](http://browserify.org/) or [webpack](https://webpack.github.io/),
though by default this module will alter it's API to no longer display or
track deprecations.
## API
```js
var deprecate = require('depd')('my-module')
```
This library allows you to display deprecation messages to your users.
This library goes above and beyond with deprecation warnings by
introspection of the call stack (but only the bits that it is interested
in).
Instead of just warning on the first invocation of a deprecated
function and never again, this module will warn on the first invocation
of a deprecated function per unique call site, making it ideal to alert
users of all deprecated uses across the code base, rather than just
whatever happens to execute first.
The deprecation warnings from this module also include the file and line
information for the call into the module that the deprecated function was
in.
**NOTE** this library has a similar interface to the `debug` module, and
this module uses the calling file to get the boundary for the call stacks,
so you should always create a new `deprecate` object in each file and not
within some central file.
### depd(namespace)
Create a new deprecate function that uses the given namespace name in the
messages and will display the call site prior to the stack entering the
file this function was called from. It is highly suggested you use the
name of your module as the namespace.
### deprecate(message)
Call this function from deprecated code to display a deprecation message.
This message will appear once per unique caller site. Caller site is the
first call site in the stack in a different file from the caller of this
function.
If the message is omitted, a message is generated for you based on the site
of the `deprecate()` call and will display the name of the function called,
similar to the name displayed in a stack trace.
### deprecate.function(fn, message)
Call this function to wrap a given function in a deprecation message on any
call to the function. An optional message can be supplied to provide a custom
message.
### deprecate.property(obj, prop, message)
Call this function to wrap a given property on object in a deprecation message
on any accessing or setting of the property. An optional message can be supplied
to provide a custom message.
The method must be called on the object where the property belongs (not
inherited from the prototype).
If the property is a data descriptor, it will be converted to an accessor
descriptor in order to display the deprecation message.
### process.on('deprecation', fn)
This module will allow easy capturing of deprecation errors by emitting the
errors as the type "deprecation" on the global `process`. If there are no
listeners for this type, the errors are written to STDERR as normal, but if
there are any listeners, nothing will be written to STDERR and instead only
emitted. From there, you can write the errors in a different format or to a
logging source.
The error represents the deprecation and is emitted only once with the same
rules as writing to STDERR. The error has the following properties:
- `message` - This is the message given by the library
- `name` - This is always `'DeprecationError'`
- `namespace` - This is the namespace the deprecation came from
- `stack` - This is the stack of the call to the deprecated thing
Example `error.stack` output:
```
DeprecationError: my-cool-module deprecated oldfunction
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (module.js:456:26)
at evalScript (node.js:532:25)
at startup (node.js:80:7)
at node.js:902:3
```
### process.env.NO_DEPRECATION
As a user of modules that are deprecated, the environment variable `NO_DEPRECATION`
is provided as a quick solution to silencing deprecation warnings from being
output. The format of this is similar to that of `DEBUG`:
```sh
$ NO_DEPRECATION=my-module,othermod node app.js
```
This will suppress deprecations from being output for "my-module" and "othermod".
The value is a list of comma-separated namespaces. To suppress every warning
across all namespaces, use the value `*` for a namespace.
Providing the argument `--no-deprecation` to the `node` executable will suppress
all deprecations (only available in Node.js 0.8 or higher).
**NOTE** This will not suppress the deperecations given to any "deprecation"
event listeners, just the output to STDERR.
### process.env.TRACE_DEPRECATION
As a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION`
is provided as a solution to getting more detailed location information in deprecation
warnings by including the entire stack trace. The format of this is the same as
`NO_DEPRECATION`:
```sh
$ TRACE_DEPRECATION=my-module,othermod node app.js
```
This will include stack traces for deprecations being output for "my-module" and
"othermod". The value is a list of comma-separated namespaces. To trace every
warning across all namespaces, use the value `*` for a namespace.
Providing the argument `--trace-deprecation` to the `node` executable will trace
all deprecations (only available in Node.js 0.8 or higher).
**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`.
## Display
![message](files/message.png)
When a user calls a function in your library that you mark deprecated, they
will see the following written to STDERR (in the given colors, similar colors
and layout to the `debug` module):
```
bright cyan bright yellow
| | reset cyan
| | | |
▼ ▼ ▼ ▼
my-cool-module deprecated oldfunction [eval]-wrapper:6:22
▲ ▲ ▲ ▲
| | | |
namespace | | location of mycoolmod.oldfunction() call
| deprecation message
the word "deprecated"
```
If the user redirects their STDERR to a file or somewhere that does not support
colors, they see (similar layout to the `debug` module):
```
Sun, 15 Jun 2014 05:21:37 GMT my-cool-module deprecated oldfunction at [eval]-wrapper:6:22
▲ ▲ ▲ ▲ ▲
| | | | |
timestamp of message namespace | | location of mycoolmod.oldfunction() call
| deprecation message
the word "deprecated"
```
## Examples
### Deprecating all calls to a function
This will display a deprecated message about "oldfunction" being deprecated
from "my-module" on STDERR.
```js
var deprecate = require('depd')('my-cool-module')
// message automatically derived from function name
// Object.oldfunction
exports.oldfunction = deprecate.function(function oldfunction() {
// all calls to function are deprecated
})
// specific message
exports.oldfunction = deprecate.function(function () {
// all calls to function are deprecated
}, 'oldfunction')
```
### Conditionally deprecating a function call
This will display a deprecated message about "weirdfunction" being deprecated
from "my-module" on STDERR when called with less than 2 arguments.
```js
var deprecate = require('depd')('my-cool-module')
exports.weirdfunction = function () {
if (arguments.length < 2) {
// calls with 0 or 1 args are deprecated
deprecate('weirdfunction args < 2')
}
}
```
When calling `deprecate` as a function, the warning is counted per call site
within your own module, so you can display different deprecations depending
on different situations and the users will still get all the warnings:
```js
var deprecate = require('depd')('my-cool-module')
exports.weirdfunction = function () {
if (arguments.length < 2) {
// calls with 0 or 1 args are deprecated
deprecate('weirdfunction args < 2')
} else if (typeof arguments[0] !== 'string') {
// calls with non-string first argument are deprecated
deprecate('weirdfunction non-string first arg')
}
}
```
### Deprecating property access
This will display a deprecated message about "oldprop" being deprecated
from "my-module" on STDERR when accessed. A deprecation will be displayed
when setting the value and when getting the value.
```js
var deprecate = require('depd')('my-cool-module')
exports.oldprop = 'something'
// message automatically derives from property name
deprecate.property(exports, 'oldprop')
// explicit message
deprecate.property(exports, 'oldprop', 'oldprop >= 0.10')
```
## License
[MIT](LICENSE)
[npm-version-image]: https://img.shields.io/npm/v/depd.svg
[npm-downloads-image]: https://img.shields.io/npm/dm/depd.svg
[npm-url]: https://npmjs.org/package/depd
[travis-image]: https://img.shields.io/travis/dougwilson/nodejs-depd/master.svg?label=linux
[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd
[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/nodejs-depd/master.svg?label=windows
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/nodejs-depd
[coveralls-image]: https://img.shields.io/coveralls/dougwilson/nodejs-depd/master.svg
[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master
[node-image]: https://img.shields.io/node/v/depd.svg
[node-url]: http://nodejs.org/download/
[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
[gratipay-url]: https://www.gratipay.com/dougwilson/

View File

@@ -0,0 +1,521 @@
/*!
* depd
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* Module dependencies.
*/
var callSiteToString = require('./lib/compat').callSiteToString
var eventListenerCount = require('./lib/compat').eventListenerCount
var relative = require('path').relative
/**
* Module exports.
*/
module.exports = depd
/**
* Get the path to base files on.
*/
var basePath = process.cwd()
/**
* Determine if namespace is contained in the string.
*/
function containsNamespace(str, namespace) {
var val = str.split(/[ ,]+/)
namespace = String(namespace).toLowerCase()
for (var i = 0 ; i < val.length; i++) {
if (!(str = val[i])) continue;
// namespace contained
if (str === '*' || str.toLowerCase() === namespace) {
return true
}
}
return false
}
/**
* Convert a data descriptor to accessor descriptor.
*/
function convertDataDescriptorToAccessor(obj, prop, message) {
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
var value = descriptor.value
descriptor.get = function getter() { return value }
if (descriptor.writable) {
descriptor.set = function setter(val) { return value = val }
}
delete descriptor.value
delete descriptor.writable
Object.defineProperty(obj, prop, descriptor)
return descriptor
}
/**
* Create arguments string to keep arity.
*/
function createArgumentsString(arity) {
var str = ''
for (var i = 0; i < arity; i++) {
str += ', arg' + i
}
return str.substr(2)
}
/**
* Create stack string from stack.
*/
function createStackString(stack) {
var str = this.name + ': ' + this.namespace
if (this.message) {
str += ' deprecated ' + this.message
}
for (var i = 0; i < stack.length; i++) {
str += '\n at ' + callSiteToString(stack[i])
}
return str
}
/**
* Create deprecate for namespace in caller.
*/
function depd(namespace) {
if (!namespace) {
throw new TypeError('argument namespace is required')
}
var stack = getStack()
var site = callSiteLocation(stack[1])
var file = site[0]
function deprecate(message) {
// call to self as log
log.call(deprecate, message)
}
deprecate._file = file
deprecate._ignored = isignored(namespace)
deprecate._namespace = namespace
deprecate._traced = istraced(namespace)
deprecate._warned = Object.create(null)
deprecate.function = wrapfunction
deprecate.property = wrapproperty
return deprecate
}
/**
* Determine if namespace is ignored.
*/
function isignored(namespace) {
/* istanbul ignore next: tested in a child processs */
if (process.noDeprecation) {
// --no-deprecation support
return true
}
var str = process.env.NO_DEPRECATION || ''
// namespace ignored
return containsNamespace(str, namespace)
}
/**
* Determine if namespace is traced.
*/
function istraced(namespace) {
/* istanbul ignore next: tested in a child processs */
if (process.traceDeprecation) {
// --trace-deprecation support
return true
}
var str = process.env.TRACE_DEPRECATION || ''
// namespace traced
return containsNamespace(str, namespace)
}
/**
* Display deprecation message.
*/
function log(message, site) {
var haslisteners = eventListenerCount(process, 'deprecation') !== 0
// abort early if no destination
if (!haslisteners && this._ignored) {
return
}
var caller
var callFile
var callSite
var i = 0
var seen = false
var stack = getStack()
var file = this._file
if (site) {
// provided site
callSite = callSiteLocation(stack[1])
callSite.name = site.name
file = callSite[0]
} else {
// get call site
i = 2
site = callSiteLocation(stack[i])
callSite = site
}
// get caller of deprecated thing in relation to file
for (; i < stack.length; i++) {
caller = callSiteLocation(stack[i])
callFile = caller[0]
if (callFile === file) {
seen = true
} else if (callFile === this._file) {
file = this._file
} else if (seen) {
break
}
}
var key = caller
? site.join(':') + '__' + caller.join(':')
: undefined
if (key !== undefined && key in this._warned) {
// already warned
return
}
this._warned[key] = true
// generate automatic message from call site
if (!message) {
message = callSite === site || !callSite.name
? defaultMessage(site)
: defaultMessage(callSite)
}
// emit deprecation if listeners exist
if (haslisteners) {
var err = DeprecationError(this._namespace, message, stack.slice(i))
process.emit('deprecation', err)
return
}
// format and write message
var format = process.stderr.isTTY
? formatColor
: formatPlain
var msg = format.call(this, message, caller, stack.slice(i))
process.stderr.write(msg + '\n', 'utf8')
return
}
/**
* Get call site location as array.
*/
function callSiteLocation(callSite) {
var file = callSite.getFileName() || '<anonymous>'
var line = callSite.getLineNumber()
var colm = callSite.getColumnNumber()
if (callSite.isEval()) {
file = callSite.getEvalOrigin() + ', ' + file
}
var site = [file, line, colm]
site.callSite = callSite
site.name = callSite.getFunctionName()
return site
}
/**
* Generate a default message from the site.
*/
function defaultMessage(site) {
var callSite = site.callSite
var funcName = site.name
// make useful anonymous name
if (!funcName) {
funcName = '<anonymous@' + formatLocation(site) + '>'
}
var context = callSite.getThis()
var typeName = context && callSite.getTypeName()
// ignore useless type name
if (typeName === 'Object') {
typeName = undefined
}
// make useful type name
if (typeName === 'Function') {
typeName = context.name || typeName
}
return typeName && callSite.getMethodName()
? typeName + '.' + funcName
: funcName
}
/**
* Format deprecation message without color.
*/
function formatPlain(msg, caller, stack) {
var timestamp = new Date().toUTCString()
var formatted = timestamp
+ ' ' + this._namespace
+ ' deprecated ' + msg
// add stack trace
if (this._traced) {
for (var i = 0; i < stack.length; i++) {
formatted += '\n at ' + callSiteToString(stack[i])
}
return formatted
}
if (caller) {
formatted += ' at ' + formatLocation(caller)
}
return formatted
}
/**
* Format deprecation message with color.
*/
function formatColor(msg, caller, stack) {
var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' // bold cyan
+ ' \x1b[33;1mdeprecated\x1b[22;39m' // bold yellow
+ ' \x1b[0m' + msg + '\x1b[39m' // reset
// add stack trace
if (this._traced) {
for (var i = 0; i < stack.length; i++) {
formatted += '\n \x1b[36mat ' + callSiteToString(stack[i]) + '\x1b[39m' // cyan
}
return formatted
}
if (caller) {
formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan
}
return formatted
}
/**
* Format call site location.
*/
function formatLocation(callSite) {
return relative(basePath, callSite[0])
+ ':' + callSite[1]
+ ':' + callSite[2]
}
/**
* Get the stack as array of call sites.
*/
function getStack() {
var limit = Error.stackTraceLimit
var obj = {}
var prep = Error.prepareStackTrace
Error.prepareStackTrace = prepareObjectStackTrace
Error.stackTraceLimit = Math.max(10, limit)
// capture the stack
Error.captureStackTrace(obj)
// slice this function off the top
var stack = obj.stack.slice(1)
Error.prepareStackTrace = prep
Error.stackTraceLimit = limit
return stack
}
/**
* Capture call site stack from v8.
*/
function prepareObjectStackTrace(obj, stack) {
return stack
}
/**
* Return a wrapped function in a deprecation message.
*/
function wrapfunction(fn, message) {
if (typeof fn !== 'function') {
throw new TypeError('argument fn must be a function')
}
var args = createArgumentsString(fn.length)
var deprecate = this
var stack = getStack()
var site = callSiteLocation(stack[1])
site.name = fn.name
var deprecatedfn = eval('(function (' + args + ') {\n'
+ '"use strict"\n'
+ 'log.call(deprecate, message, site)\n'
+ 'return fn.apply(this, arguments)\n'
+ '})')
return deprecatedfn
}
/**
* Wrap property in a deprecation message.
*/
function wrapproperty(obj, prop, message) {
if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
throw new TypeError('argument obj must be object')
}
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
if (!descriptor) {
throw new TypeError('must call property on owner object')
}
if (!descriptor.configurable) {
throw new TypeError('property must be configurable')
}
var deprecate = this
var stack = getStack()
var site = callSiteLocation(stack[1])
// set site name
site.name = prop
// convert data descriptor
if ('value' in descriptor) {
descriptor = convertDataDescriptorToAccessor(obj, prop, message)
}
var get = descriptor.get
var set = descriptor.set
// wrap getter
if (typeof get === 'function') {
descriptor.get = function getter() {
log.call(deprecate, message, site)
return get.apply(this, arguments)
}
}
// wrap setter
if (typeof set === 'function') {
descriptor.set = function setter() {
log.call(deprecate, message, site)
return set.apply(this, arguments)
}
}
Object.defineProperty(obj, prop, descriptor)
}
/**
* Create DeprecationError for deprecation
*/
function DeprecationError(namespace, message, stack) {
var error = new Error()
var stackString
Object.defineProperty(error, 'constructor', {
value: DeprecationError
})
Object.defineProperty(error, 'message', {
configurable: true,
enumerable: false,
value: message,
writable: true
})
Object.defineProperty(error, 'name', {
enumerable: false,
configurable: true,
value: 'DeprecationError',
writable: true
})
Object.defineProperty(error, 'namespace', {
configurable: true,
enumerable: false,
value: namespace,
writable: true
})
Object.defineProperty(error, 'stack', {
configurable: true,
enumerable: false,
get: function () {
if (stackString !== undefined) {
return stackString
}
// prepare stack trace
return stackString = createStackString.call(this, stack)
},
set: function setter(val) {
stackString = val
}
})
return error
}

View File

@@ -0,0 +1,95 @@
{
"_args": [
[
"depd@~1.1.0",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/serve-static/node_modules/send"
],
[
"depd@~1.1.0",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/send"
]
],
"_from": "depd@>=1.1.0 <1.2.0",
"_id": "depd@1.1.0",
"_inCache": true,
"_installable": true,
"_location": "/live-server/depd",
"_npmUser": {
"email": "doug@somethingdoug.com",
"name": "dougwilson"
},
"_npmVersion": "1.4.28",
"_phantomChildren": {},
"_requested": {
"name": "depd",
"raw": "depd@~1.1.0",
"rawSpec": "~1.1.0",
"scope": null,
"spec": ">=1.1.0 <1.2.0",
"type": "range"
},
"_requiredBy": [
"/live-server/send"
],
"_shrinkwrap": null,
"_spec": "depd@~1.1.0",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/send",
"author": {
"email": "doug@somethingdoug.com",
"name": "Douglas Christopher Wilson"
},
"browser": "lib/browser/index.js",
"bugs": {
"url": "https://github.com/dougwilson/nodejs-depd/issues"
},
"dependencies": {},
"description": "Deprecate all the things",
"devDependencies": {
"beautify-benchmark": "0.2.4",
"benchmark": "1.0.0",
"istanbul": "0.3.5",
"mocha": "~1.21.5"
},
"directories": {},
"dist": {
"shasum": "e1bd82c6aab6ced965b97b88b17ed3e528ca18c3",
"tarball": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz"
},
"engines": {
"node": ">= 0.6"
},
"files": [
"lib/",
"History.md",
"LICENSE",
"index.js",
"Readme.md"
],
"gitHead": "78c659de20283e3a6bee92bda455e6daff01686a",
"homepage": "https://github.com/dougwilson/nodejs-depd",
"keywords": [
"deprecate",
"deprecated"
],
"license": "MIT",
"maintainers": [
{
"email": "doug@somethingdoug.com",
"name": "dougwilson"
}
],
"name": "depd",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/dougwilson/nodejs-depd.git"
},
"scripts": {
"bench": "node benchmark/index.js",
"test": "mocha --reporter spec --bail test/",
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --no-exit test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/"
},
"version": "1.1.0"
}

View File

@@ -0,0 +1,508 @@
## History
## v2.0.4 March 11, 2015
- Updated dependencies
## v2.0.3 February 8th, 2014
- Updated dependencies
## v2.0.2 March 29, 2013
- Added missing `typechecker` dependency
## v2.0.1 March 29, 2013
- Returns the subject instead of `this`
## v2.0.0 March 29, 2013
- Split from bal-util
## v1.16.14 March 27, 2013
- Killed explicit browser support, use [Browserify](http://browserify.org/) instead
- Removed the `out` directory from git
- Now compiled with the coffee-script bare option
## v1.16.13 March 23, 2013
- `balUtilEvents` changes:
- `EventEmitterEnhanced` changes:
- Now works with `once` calls in node 0.10.0
- Closes [bevry/docpad#462](https://github.com/bevry/docpad/issues/462)
- Changed `emitSync` to be an alias to `emitSerial` and `emitAsync` to be an alias to `emitParallel`
- Added new `getListenerGroup` function
- `balUtilFlow` changes:
- `fireWithOptionalCallback` can now take the method as an array of `[fireMethod,introspectMethod]` useful for pesly binds
## v1.16.12 March 18, 2013
- `balUtilFlow` changes:
- `Groups::run` signature changed from no arguments to a single `mode` argument
## v1.16.11 March 10, 2013
- `balUtilModules` changes:
- Fixed `getCountryCode` and `getLanguageCode` failing when there is no locale code
## v1.16.10 March 8, 2013
- `balUtilModules` changes:
- Fixed `requireFresh` regression, added test
## v1.16.9 March 8, 2013
- `balUtilModules` changes:
- Added `getLocaleCode`
- Added `getCountryCode`
- Added `getLanguageCode`
## v1.16.8 February 16, 2013
- `balUtilModules` changes:
- `spawnMultiple`, `execMultiple`: now accept a `tasksMode` option that can be `serial` (default) or `parallel`
## v1.16.7 February 12, 2013
- `balUtilPaths` changes:
- `readPath`: do not prefer gzip, but still support it for decoding, as the zlib library is buggy
## v1.16.6 February 12, 2013
- `balUtilPaths` changes:
- `readPath`: add support for gzip decoding for node 0.6 and higher
## v1.16.5 February 6, 2013
- More [browserify](http://browserify.org/) support
## v1.16.4 February 6, 2013
- [Browserify](http://browserify.org/) support
## v1.16.3 February 5, 2013
- Node v0.4 support
- `balUtilPaths` changes:
- Removed deprecated `console.log`s when errors occur (they are now sent to the callback)
- Fixed `determineExecPath` when executable requires the environment configuration
- `balUtilTypes` changes:
- `isEmptyObject` now works for empty values (e.g. `null`)
- `balUtilFlow` changes:
- Added `clone`
- Added `deepClone`
- `setDeep` and `getDeep` now handle `undefined` values correctly
## v1.16.2 February 1, 2013
- `balUtilPaths` changes:
- Added timeout support to `readPath`
- `balUtilFlow` changes:
- Added `setDeep`
- Added `getDeep`
## v1.16.1 January 25, 2013
- `balUtilFlow` changes:
- Added `safeShallowExtendPlainObjects`
- Added `safeDeepExtendPlainObjects`
## v1.16.0 January 24, 2013
- Node v0.9 compatability
- `balUtilModules` changes:
- Added `getEnvironmentPaths`
- Added `getStandardExecPaths(execName)`
- `exec` now supports the `output` option
- `determineExecPath` now resolves the possible paths and checks for their existance
- This avoids Node v0.9's ENOENT crash when executing a path that doesn't exit
- `getExecPath` will now try for `.exe` paths as well when running on windows if an extension hasn't already been defined
- `getGitPath`, `getNodePath`, `getNpmPath` will now also check the environment paths
- `balUtilFlow` changes:
- Added `createSnore`
- Added `suffixArray`
- `flow` now accepts the signatures `({object,actions,action,args,tasks,next})`, `(object, action, args, next)` and `(actions,args,next)`
- `Group` changes:
- `mode` can now be either `parallel` or `serial`, rather than `async` and `sync`
- `async()` is now `parallel()` (aliased for b/c)
- `sync()` is now `serial()` (aliased for b/c)
- `balUtilTypes` changes:
- Added `isEmptyObject`
## v1.15.4 January 8, 2013
- `balUtilPaths` changes:
- Renamed `testIgnorePatterns` to `isIgnoredPath`
- Added aliases for b/c compatibility
- Added new `ignorePaths` option
## v1.15.3 December 24, 2012
- `balUtilModules` changes:
- Added `requireFresh`
## v1.15.2 December 16, 2012
- `balUtilPaths` changes:
- Fixed `scandir` not inheriting ignore patterns when recursing
## v1.15.1 December 15, 2012
- `balUtilPaths` changes:
- Fixed `testIgnorePatterns` when `ignoreCommonPatterns` is set to `true`
## v1.15.0 December 15, 2012
- `balUtilPaths` changes:
- Added `testIgnorePatterns`
- Renamed `ignorePatterns` to `ignoreCommonPatterns`, and added new `ignoreCustomPatterns`
- Affects `scandir` options
- Added emac cache files to `ignoreCommonPatterns`
## v1.14.1 December 14, 2012
- `balUtilModules` changes:
- Added `getExecPath` that will fetch an executable path based on the paths within the environment `PATH` variable
- Rebuilt with CoffeeScript 1.4.x
## v1.14.0 November 23, 2012
- `balUtilPaths` changes:
- `readPath` will now follow url redirects
## v1.13.13 October 26, 2012
- `balUtilPaths` changes:
- Files that start with `~` are now correctly ignored in `commonIgnorePatterns`
## v1.13.12 October 22, 2012
- `balUtilFlow` changes:
- `extend` is now an alias of `shallowExtendPlainObjects` as they were exactly the same
- `balUtilHTML` changes:
- `replaceElement` and `replaceElementAsync` changes:
- now accept arguments in object form as well
- accept a `removeIndentation` argument that defaults to `true`
## v1.13.11 October 22, 2012
- `balUtilPaths` changes:
- `ensurePath` now returns `err` and `exists` instead of just `err`
- `balUtilModules` changes:
- `initGitRepo` will now default `remote` to `origin` and `branch` to `master`
- Added `initOrPullGitRepo`
## v1.13.10 October 7, 2012
- `balUtilPaths` changes:
- Added `shallowExtendPlainObjects`
## v1.13.9 October 7, 2012
- `balUtilPaths` changes:
- VIM swap files now added to `commonIgnorePatterns`
- Thanks to [Sean Fridman](https://github.com/sfrdmn) for [pull request #4](https://github.com/balupton/bal-util/pull/4)
## v1.13.8 October 2, 2012
- `balUtilModules` changes:
- Added `openProcess` and `closeProcess`, and using them in `spawn` and `exec`, used to prevent `EMFILE` errors when there are too many open processes
- Max number of open processes is configurable via the `NODE_MAX_OPEN_PROCESSES` environment variable
` balUtilPaths` changes:
- Max number of open files is now configurable via the`NODE_MAX_OPEN_FILES` environment variable
## v1.13.7 September 24, 2012
- `balUtilPaths` changes:
- Added `textExtensions` and `binaryExtensions`
- The environment variables `TEXT_EXTENSIONS` and `BINARY_EXTENSIONS` will append to these arrays
- Added `isText` and `isTextSync`
## v1.13.6 September 18, 2012
- `balUtilPaths` changes:
- Improved `getEncoding`/`getEncodingSync` detection
- Will now scan start, middle and end, instead of just middle
## v1.13.5 September 13, 2012
- `balUtilPaths` changes:
- Added `getEncoding` and `getEncodingSync`
## v1.13.4 August 28, 2012
- `balUtilModules` changes:
- Failing to retrieve the path on `getGitPath`, `getNodePath` and `getNpmPath` will now result in an error
## v1.13.3 August 28, 2012
- `balUtilModules` changes:
- Fixed `exec` and `execMultiple`
- Added `gitCommands`, `nodeCommands` and `npmCommands`
- Dropped node v0.4 support, min required version now 0.6
## v1.13.2 August 16, 2012
- Repackaged
## v1.13.1 August 16, 2012
- `balUtilHTML` changes:
- Fixed `replaceElement` from mixing up elements that start with our desired selector, instead of being only our desired selector
## v1.13.0 August 3, 2012
- `balUtilModules` changes:
- Added `determineExecPath`, `getNpmPath`, `getTmpPath`, `nodeCommand` and `gitCommand`
- `initNodeModules` and `initGitRepo` will now get the determined path of the executable if a path isn't passed
- Re-added markdown files to npm distribution as they are required for the npm website
## v1.12.5 July 18, 2012
- `balUtilTypes` changes:
- Better checks for `isString` and `isNumber` under some environments
- `balUtilFlow` changes:
- Removed ambigious `clone` function, use `dereference` or `extend` or `deepExtendPlainObjects` instead
## v1.12.4 July 12, 2012
- `balUtilTypes` changes:
- `isObject` now also checks truthyness to avoid `null` and `undefined` from being objects
- `isPlainObject` got so good, it can't get better
- `balUtilFlow` changes:
- added `deepExtendPlainObjects`
## v1.12.3 July 12, 2012
- `balUtilModules` changes:
- `npmCommand` will now only prefix with the nodePath if the npmPath exists
- `npmCommand` and `initNodeModules` now use async fs calls instead of sync calls
## v1.12.2 July 12, 2012
- `balUtilFlow` changes:
- Added `dereference`
## v1.12.1 July 10, 2012
- `balUtilModules` changes:
- Added `stdin` option to `spawn`
## v1.12.0 July 7, 2012
- Rejigged `balUtilTypes` and now top level
- Other components now make use of this instead of inline `typeof` and `instanceof` checks
- `balUtilFlow` changes:
- `isArray` and `toString` moved to `balUtilTypes`
## v1.11.2 July 7, 2012
- `balUtilFlow` changes:
- Added `clone`
- `balUtilModules` changes:
- Fixed exists warning on `initNodeModules`
- `balUtilPaths` changes:
- Added `scanlist`
- `scandir` changes:
- If `readFiles` is `true`, then we will return the contents into the list entries as well as the tree entries (we weren't doing this for lists before)
## v1.11.1 July 4, 2012
- `balUtilFlow` changes:
- `Group` changes:
- Cleaned up the context handling code
- `Block` changes:
- Block constructor as well as `createSubBlock` arguments is now a single `opts` object, acceping the options `name`, `fn`, `parentBlock` and the new `complete`
- Fixed bug introduced in v1.11.0 causing blocks to complete instantly (instead of once their tasks are finished)
## v1.11.0 July 1, 2012
- Added `balUtilHTML`:
- `getAttribute(attributes,attribute)`
- `detectIndentation(source)`
- `removeIndentation(source)`
- `replaceElement(source, elementNameMatcher, replaceElementCallback)`
- `replaceElementAsync(source, elementNameMatcher, replaceElementCallback, next)`
- `balUtilFlow` changes:
- `wait(delay,fn)` introduced as an alternative to `setTimeout`
- `Group` changes:
- `push` and `pushAndRun` signatures are now `([context], task)`
- `context` is optional, and what we should bind to this
- it saves us having to often wrap our task pushing into for each scopes
- task completion callbacks are now optional, if not specified a task will be completed as soon as it finishes executing
- `balUtilEvents`, `balUtilModules` changes:
- Now make use of the `balUtilFlow.push|pushAndRun` new `context` argument to simplify some loops
## v1.10.3 June 26, 2012
- `balUtilModules` changes:
- `initNodeModules` will now install modules from cache, unless `force` is true
## v1.10.2 June 26, 2012
- `balUtilModules` changes:
- `initNodeModules` will now never install modules from cache
## v1.10.1 June 26, 2012
- `balUtilModules` changes:
- Fixed `npmCommand` under some situations
## v1.10.0 June 26, 2012
- `balUtilModules` changes:
- Added `spawnMultiple`, `execMultiple`, `gitGitPath`, `getNodePath`, and `npmCommand`
- `spawn` and `exec` are now only for single commands, use the new `spawnMultiple` and `execMultiple` for multiple commands instead
- error exit code is now anything that isnt `0`
## v1.9.4 June 22, 2012
- Fixed a problem with large asynchronous groups
## v1.9.3 June 22, 2012
- `balUtilFlow` changes:
- Added `extractOptsAndCallback` and `extend`
## v1.9.2 June 21, 2012
- `balUtilFlow` changes:
- Added `fireWithOptionalCallback`, updated groups and emitters to use this
## v1.9.1 June 21, 2012
- `balUtilModules` changes:
- `initNodeModules` now supports `output` option
## v1.9.0 June 21, 2012
- `balUtilEvents` changes:
- `EventEmitterEnhanced` changes:
- `emitSync` and `emitAsync` changes:
- The next callback is now optional, if it is not detected then we will automatically mark the listener as completed once we have executed it (in other words, if it doesn't have a next callback, then we treat it as a synchronous listener)
## v1.8.8 June 19, 2012
- Fixed a problem with large synchronous groups
## v1.8.7 June 19, 2012
- Defaulted `dependencies` to an empty object, to hopefully fix [npm issue #2540](https://github.com/isaacs/npm/pull/2540)
## v1.8.6 June 19, 2012
- `balUtilEvents` changes:
- Split `emitSync` and `emitAsync` out of `EventSystem` and into new `EventEmitterEnhanced` that `EventSystem` extends
## v1.8.5 June 11, 2012
- Made next callbacks necessary by default
## v1.8.4 June 11, 2012
- `balUtilModule` changes:
- `spawn`
- will now return results in the order of `err`, `stdout`, `stderr`, `code`, `signal`
- now splits string commands using `/ /`
- `balUtilFlow` changes:
- `Group` will now only return error as an array if we have more than one error
- Updated for Joe v1.0.0
## v1.8.3 June 9, 2012
- `balUtilCompare` changes:
- `packageCompare` will now fail gracefully if it receives malformed json
## v1.8.2 June 9, 2012
- Removed request dependency, we now use the native http/https modules
## v1.8.1 June 9, 2012
- Restructured directories
- Removed generated docs, use the wiki instead
- Moved tests from Mocha to [Joe](https://github.com/bevry/joe)
- Travis now tests against node v0.7
- `balUtilPaths` changes:
- Added `exists` and `existsSync` to normalize node's 0.6 to 0.8 api differences
- Made [request](https://github.com/mikeal/request) an optional dependency
## v1.8.0 June 9, 2012
- Added expiremental `balUtilFlow.Block`
- Possibly some undocumented `balUtilFlow.Group` changes
## v1.7.0 June 4, 2012
- `balUtilFlow` changes:
- `Group` changes:
- Constructor now supports `next` and `mode` arguments in any order
- `clear()` now clears everything
- Added `hasTasks()`
- Group completion callback's first argument (the error argument) is now an array of errors (or null if no errors)
- Added `breakOnError` option (defaults to `true`)
- Added `autoClear` option to clear once all tasks have run (defualts to `false`)
## v1.6.5 May 30, 2012
- `balUtilFlow` changes:
- `Group` changes:
- Reverted the change made in v1.6.4 where errors in callbacks still increment the complete count
- Instead, you should be using the `hasExited()` instead of `hasCompleted()` which is used to find out if everything passed successfully
## v1.6.4 May 30, 2012
- `balUtilFlow` changes:
- Added `flow({object,action,[args],[tasks],next})` to simplify calling a series of functions of an object
- `Group` changes:
- If complete callback is called with an error, it'll still increment the complete count (it didn't before)
- Added `hasExited()`
- `balUtilPaths` changes:
- `writeFile` will now call `ensurePath` before writing the file
## v1.6.3 May 22, 2012
- `balUtilPaths` changes:
- Fixed a problem introduced with v1.6.0 with `isDirectory` not opening the file before closing it
- If the number of open files becomes a negative number, we will now throw an error
- Decreased the max amount of allowed open files from `500` to `100`
- Increased the wait time for opening a file from `50` to `100`
- This is now customisable through the global `waitingToOpenFileDelay`
## v1.6.2 May 13, 2012
- Added support for `balUtilFlow` and `balUtilTypes` to be used inside web browsers
## v1.6.1 May 4, 2012
- `balUtilPaths` changes:
- Fixed `initNodeModules`
## v1.6.0 May 4, 2012
- We now pre-compile our coffee-script
- `balUtilPaths` changes:
- Added `readFile`, `writeFile`, `mkdir`, `stat`, `readdir`, `unlink`, `rmdir`
- Renamed `rmdir` to `rmdirDeep`
- `balUtilModules` changes:
- Removed `initGitSubmodules`, `gitPull`
- Added `initGitRepo`
- Rewrote `initNodeModules`
## v1.5.0 April 18, 2012
- `balUtilPaths` changes:
- `scan` was removed, not sure what it was used for
- `isDirectory` now returns the `fileStat` argument to the callback
- `scandir` changes:
- `ignorePatterns` option when set to true now uses the new `balUtilPaths.commonIgnorePatterns` property
- fixed error throwing when passed an invalid path
- now supports a new `stat` option
- will return the `fileStat` argument to the `fileAction` and `dirAction` callbacks
- `ignorePatterns` and `ignoreHiddenFiles` will now correctly be passed to child scandir calls
- `cpdir` and `rpdir` now uses `path.join` and support `ignoreHiddenFiles` and `ignorePatterns`
- `writetree` now uses `path.join`
## v1.4.3 April 14, 2012
- CoffeeScript dependency is now bundled
- Fixed incorrect octal `0700` should have been `700`
## v1.4.2 April 5, 2012
- Fixed a failing test due to the `bal-util.npm` to `bal-util` rename
- Improvements to `balUtilModules.spawn`
- will only return an error if the exit code was `1`
- will also contain the `code` and `signal` with the results
- `results[x][0]` is now the stderr string, rather than an error object
## v1.4.1 April 5, 2012
- Added `spawn` to `balUtilModules`
- Added `ignoreHiddenFiles` option to `balUtilPaths.scandir`
## v1.4.0 April 2, 2012
- Renamed `balUtilGroups` to `balUtilFlow`
- Added `toString`, `isArray` and `each` to `balUtilFlow`
- Added `rpdir`, `empty`, and `isPathOlderThan` to `balUtilPaths`
## v1.3.0 February 26, 2012
- Added `openFile` and `closeFile` to open and close files safely (always stays below the maximum number of allowed open files)
- Updated all path utilities to use `openFile` and `closeFile`
- Added npm scripts
## v1.2.0 February 14, 2012
- Removed single and multi modes from `exec`, now always returns the same consistent `callback(err,results)` instead
## v1.1.0 February 6, 2012
- Modularized
- Added [docco](http://jashkenas.github.com/docco/) docs
## v1.0 February 5, 2012
- Moved unit tests to [Mocha](http://visionmedia.github.com/mocha/)
- Offers more flexible unit testing
- Offers better guarantees that tests actually ran, and that they actually ran correctly
- Added `readPath` and `scantree`
- Added `readFiles` option to `scandir`
- `scandir` now supports arguments in object format
- Removed `parallel`
- Tasks inside groups now are passed `next` as there only argument
- Removed `resolvePath`, `expandPath` and `expandPaths`, they were essentially the same as `path.resolve`
- Most functions will now chain
- `comparePackage` now supports comparing two local, or two remote packages
- Added `gitPull`
## v0.9 January 18, 2012
- Added `exec`, `initNodeModules`, `initGitSubmodules`, `EventSystem.when`
- Added support for no callbacks
## v0.8 November 2, 2011
- Considerable improvements to `scandir`, `cpdir` and `rmdir`
- Note, passing `false` as the file or dir actions will now skip all of that type. Pass `null` if you do not want that.
- `dirAction` is now fired before we read the directories children, if you want it to fire after then in the next callback, pass a callback in the 3rd argument. See `rmdir` for an example of this.
- Fixed npm web to url warnings
## v0.7 October 3, 2011
- Added `versionCompare` and `packageCompare` functions
- Added `request` dependency
## v0.6 September 14, 2011
- Updated `util.Group` to support `async` and `sync` grouping
## v0.4 June 2, 2011
- Added util.type for testing the type of a variable
- Added util.expandPath and util.expandPaths
## v0.3 June 1, 2011
- Added util.Group class for your async needs :)
## v0.2 May 20, 2011
- Added some tests with expresso
- util.scandir now returns err,list,tree
- Added util.writetree
## v0.1 May 18, 2011
- Initial commit

View File

@@ -0,0 +1,23 @@
<!-- LICENSEFILE/ -->
# License
Unless stated otherwise all works are:
- Copyright &copy; Bevry Pty Ltd <us@bevry.me> (http://bevry.me)
and licensed under:
- The incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://opensource.org/licenses/mit-license.php)
## MIT License
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.
<!-- /LICENSEFILE -->

View File

@@ -0,0 +1,141 @@
<!-- TITLE/ -->
# Eachr
<!-- /TITLE -->
<!-- BADGES/ -->
[![Build Status](https://img.shields.io/travis/bevry/eachr/master.svg)](http://travis-ci.org/bevry/eachr "Check this project's build status on TravisCI")
[![NPM version](https://img.shields.io/npm/v/eachr.svg)](https://npmjs.org/package/eachr "View this project on NPM")
[![NPM downloads](https://img.shields.io/npm/dm/eachr.svg)](https://npmjs.org/package/eachr "View this project on NPM")
[![Dependency Status](https://img.shields.io/david/bevry/eachr.svg)](https://david-dm.org/bevry/eachr)
[![Dev Dependency Status](https://img.shields.io/david/dev/bevry/eachr.svg)](https://david-dm.org/bevry/eachr#info=devDependencies)<br/>
[![Gratipay donate button](https://img.shields.io/gratipay/bevry.svg)](https://www.gratipay.com/bevry/ "Donate weekly to this project using Gratipay")
[![Flattr donate button](https://img.shields.io/badge/flattr-donate-yellow.svg)](http://flattr.com/thing/344188/balupton-on-Flattr "Donate monthly to this project using Flattr")
[![PayPayl donate button](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QB8GQPZAH84N6 "Donate once-off to this project using Paypal")
[![BitCoin donate button](https://img.shields.io/badge/bitcoin-donate-yellow.svg)](https://coinbase.com/checkouts/9ef59f5479eec1d97d63382c9ebcb93a "Donate once-off to this project using BitCoin")
[![Wishlist browse button](https://img.shields.io/badge/wishlist-donate-yellow.svg)](http://amzn.com/w/2F8TXKSNAFG4V "Buy an item on our wishlist for us")
<!-- /BADGES -->
<!-- DESCRIPTION/ -->
Give eachr an array or object, and the iterator, in return eachr will give the iterator the value and key of each item, and will stop if the iterator returned false.
<!-- /DESCRIPTION -->
<!-- INSTALL/ -->
## Install
### [NPM](http://npmjs.org/)
- Use: `require('eachr')`
- Install: `npm install --save eachr`
### [Browserify](http://browserify.org/)
- Use: `require('eachr')`
- Install: `npm install --save eachr`
- CDN URL: `//wzrd.in/bundle/eachr@2.0.4`
### [Ender](http://enderjs.com)
- Use: `require('eachr')`
- Install: `ender add eachr`
<!-- /INSTALL -->
## Usage
``` javascript
// Prepare
var each = require("eachr");
var arr = ["first", "second", "third"];
var obj = {a:"first", b:"second", c:"third"};
var iterator = function(value,key){
console.log({value:value, key:key});
if ( value === "second" ) {
console.log("break");
return false;
}
};
// Cycle Array
each(arr, iterator);
// {"value":"first", "key":0}
// {"value":"second", "key":1}
// break
// Cycle Object
each(obj, iterator);
// {"value":"first", "key":"a"}
// {"value":"second", "key":"b"}
// break
```
<!-- HISTORY/ -->
## History
[Discover the change history by heading on over to the `HISTORY.md` file.](https://github.com/bevry/eachr/blob/master/HISTORY.md#files)
<!-- /HISTORY -->
<!-- CONTRIBUTE/ -->
## Contribute
[Discover how you can contribute by heading on over to the `CONTRIBUTING.md` file.](https://github.com/bevry/eachr/blob/master/CONTRIBUTING.md#files)
<!-- /CONTRIBUTE -->
<!-- BACKERS/ -->
## Backers
### Maintainers
These amazing people are maintaining this project:
- Benjamin Lupton <b@lupton.cc> (https://github.com/balupton)
### Sponsors
No sponsors yet! Will you be the first?
[![Gratipay donate button](https://img.shields.io/gratipay/bevry.svg)](https://www.gratipay.com/bevry/ "Donate weekly to this project using Gratipay")
[![Flattr donate button](https://img.shields.io/badge/flattr-donate-yellow.svg)](http://flattr.com/thing/344188/balupton-on-Flattr "Donate monthly to this project using Flattr")
[![PayPayl donate button](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QB8GQPZAH84N6 "Donate once-off to this project using Paypal")
[![BitCoin donate button](https://img.shields.io/badge/bitcoin-donate-yellow.svg)](https://coinbase.com/checkouts/9ef59f5479eec1d97d63382c9ebcb93a "Donate once-off to this project using BitCoin")
[![Wishlist browse button](https://img.shields.io/badge/wishlist-donate-yellow.svg)](http://amzn.com/w/2F8TXKSNAFG4V "Buy an item on our wishlist for us")
### Contributors
These amazing people have contributed code to this project:
- [Benjamin Lupton](https://github.com/balupton) <b@lupton.cc> — [view contributions](https://github.com/bevry/eachr/commits?author=balupton)
- [sfrdmn](https://github.com/sfrdmn) — [view contributions](https://github.com/bevry/eachr/commits?author=sfrdmn)
[Become a contributor!](https://github.com/bevry/eachr/blob/master/CONTRIBUTING.md#files)
<!-- /BACKERS -->
<!-- LICENSE/ -->
## License
Unless stated otherwise all works are:
- Copyright &copy; Bevry Pty Ltd <us@bevry.me> (http://bevry.me)
and licensed under:
- The incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://opensource.org/licenses/mit-license.php)
<!-- /LICENSE -->

View File

@@ -0,0 +1,23 @@
// Prepare
var each = require("./");
var arr = ["first", "second", "third"];
var obj = {a:"first", b:"second", c:"third"};
var iterator = function(value,key){
console.log({value:value, key:key});
if ( value === "second" ) {
console.log("break");
return false;
}
};
// Cycle Array
each(arr, iterator);
// {"value":"first", "key":0}
// {"value":"second", "key":1}
// break
// Cycle Object
each(obj, iterator);
// {"value":"first", "key":"a"}
// {"value":"second", "key":"b"}
// break

View File

@@ -0,0 +1,120 @@
{
"_args": [
[
"eachr@~2.0.2",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util"
]
],
"_from": "eachr@>=2.0.2 <2.1.0",
"_id": "eachr@2.0.4",
"_inCache": true,
"_installable": true,
"_location": "/live-server/eachr",
"_nodeVersion": "0.12.0",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "2.5.1",
"_phantomChildren": {},
"_requested": {
"name": "eachr",
"raw": "eachr@~2.0.2",
"rawSpec": "~2.0.2",
"scope": null,
"spec": ">=2.0.2 <2.1.0",
"type": "range"
},
"_requiredBy": [
"/live-server/bal-util"
],
"_resolved": "https://registry.npmjs.org/eachr/-/eachr-2.0.4.tgz",
"_shasum": "466f7caa10708f610509e32c807aafe57fc122bf",
"_shrinkwrap": null,
"_spec": "eachr@~2.0.2",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util",
"author": {
"email": "us@bevry.me",
"name": "Bevry Pty Ltd",
"url": "http://bevry.me"
},
"badges": {
"bitcoin": "https://coinbase.com/checkouts/9ef59f5479eec1d97d63382c9ebcb93a",
"david": true,
"daviddev": true,
"flattr": "344188/balupton-on-Flattr",
"gratipay": "bevry",
"npm": true,
"npmdownloads": true,
"paypal": "QB8GQPZAH84N6",
"travis": true,
"wishlist": "http://amzn.com/w/2F8TXKSNAFG4V"
},
"browsers": true,
"bugs": {
"url": "https://github.com/bevry/eachr/issues"
},
"cakeConfiguration": {
"COFFEE_SRC_PATH": "src"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "https://github.com/balupton"
},
{
"name": "sfrdmn",
"url": "https://github.com/sfrdmn"
}
],
"dependencies": {
"typechecker": "^2.0.8"
},
"description": "Give eachr an array or object, and the iterator, in return eachr will give the iterator the value and key of each item, and will stop if the iterator returned false.",
"devDependencies": {
"chai": "^2.1.1",
"coffee-script": "^1.9.1",
"joe": "^1.6.0",
"joe-reporter-console": "^1.2.1",
"projectz": "^0.5.0"
},
"directories": {
"lib": "./out/lib"
},
"dist": {
"shasum": "466f7caa10708f610509e32c807aafe57fc122bf",
"tarball": "https://registry.npmjs.org/eachr/-/eachr-2.0.4.tgz"
},
"engines": {
"node": ">=0.4"
},
"gitHead": "7d7ceddf3e9b9c41d13e99495bf3a2f6e4490b0f",
"homepage": "https://github.com/bevry/eachr",
"keywords": [
"flow",
"each",
"cycle"
],
"license": {
"type": "MIT"
},
"main": "./out/lib/eachr.js",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "eachr",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/bevry/eachr.git"
},
"scripts": {
"test": "node ./out/test/eachr-test.js"
},
"version": "2.0.4"
}

View File

@@ -0,0 +1,10 @@
(The MIT License)
Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me) <us@bevry.me>
Copyright © 2011-2012 [Benjamin Lupton](http://balupton.com) <b@lupton.cc>
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.

View File

@@ -0,0 +1,71 @@
# Extendr [![Build Status](https://secure.travis-ci.org/bevry/extendr.png?branch=master)](http://travis-ci.org/bevry/extendr)
Utilities for cloning, extending, and de-referencing objects in shallow, deep, and safe ways
## Install
### Backend
1. [Install Node.js](http://bevry.me/node/install)
2. `npm install --save extendr`
### Frontend
1. [See Browserify](http://browserify.org)
## Usage
### Example
``` javascript
// Shallow Clone
(function(){
var a = {a:1}, b = {b:2}
var c = require('extendr').clone(a,b)
console.log(a) // {a:1}
console.log(b) // {b:2}
console.log(c) // {a:1,b:2}
})()
// Shallow Extend
(function(){
var a = {a:1}, b = {b:2}
var c = require('extendr').extend(a,b)
console.log(a) // {a:1,b:2}
console.log(b) // {b:2}
console.log(c) // {a:1,b:2}
})()
```
### Methods
- `clone(args...)` - shallow extend the arguments into a new object, same as `extend({},args...)`
- `deepClone(args...)` - deep extend the arguments into a new object, same as `deepExtend({},args...)`
- `dereference(obj)` - return a copy of the object with all references destroyed, same as serializing then deserializing the object
- `extend(args...)` - alias for `shallowExtendPlainObjects`
- `deepExtend(args...)` - alias for `deepExtendPlainObjects`
- `shallowExtendPlainObjects(target, args...)` - shallow extend the arguments into the target
- `deepExtendPlainObjects(target, args...)` - deep extend the arguments into the target
- `safeShallowExtendPlainObjects(target, objs...)` - shallow extend defined values from the arguments into the target
- `safeDeepExtendPlainObjects(target, args...)` - deep extend defined values from the arguments into the target
### Explanation
- Use the clone methods when you don't want to modify your first object
- Use the extend methods when you want to modify the first argument
- Use the dereference method when you want to make sure that nothing has any references to the old object
- Use the safe methods when you don't want `null` and `undefined` values to overwrite a defined values
## History
You can discover the history inside the [History.md](https://github.com/bevry/extendr/blob/master/History.md#files) file
## License
Licensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)
<br/>Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me)
<br/>Copyright © 2011-2012 [Benjamin Arthur Lupton](http://balupton.com)

View File

@@ -0,0 +1,96 @@
{
"_args": [
[
"extendr@~2.0.1",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util"
]
],
"_from": "extendr@>=2.0.1 <2.1.0",
"_id": "extendr@2.0.1",
"_inCache": true,
"_installable": true,
"_location": "/live-server/extendr",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "1.2.15",
"_phantomChildren": {},
"_requested": {
"name": "extendr",
"raw": "extendr@~2.0.1",
"rawSpec": "~2.0.1",
"scope": null,
"spec": ">=2.0.1 <2.1.0",
"type": "range"
},
"_requiredBy": [
"/live-server/bal-util"
],
"_resolved": "https://registry.npmjs.org/extendr/-/extendr-2.0.1.tgz",
"_shasum": "d8ab375fcbb833e4ba2cd228540f04e4aa07de90",
"_shrinkwrap": null,
"_spec": "extendr@~2.0.1",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util",
"author": {
"email": "us@bevry.me",
"name": "Bevry Pty Ltd",
"url": "http://bevry.me"
},
"bugs": {
"url": "https://github.com/bevry/extendr/issues"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "https://github.com/balupton"
}
],
"dependencies": {
"typechecker": "~2.0.1"
},
"description": "Utilities for cloning, extending, and de-referencing objects in shallow, deep, and safe ways",
"devDependencies": {
"coffee-script": "~1.6.2",
"joe": "~1.1.2"
},
"directories": {
"lib": "./out/lib"
},
"dist": {
"shasum": "d8ab375fcbb833e4ba2cd228540f04e4aa07de90",
"tarball": "https://registry.npmjs.org/extendr/-/extendr-2.0.1.tgz"
},
"engines": {
"node": ">=0.4"
},
"homepage": "https://github.com/bevry/extendr",
"keywords": [
"extend",
"deepExtend",
"shallowExtend",
"safeExtend",
"clone",
"deepClone",
"dereference"
],
"main": "./out/lib/extendr.js",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "extendr",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/bevry/extendr.git"
},
"scripts": {
"test": "node ./out/test/extendr-test.js"
},
"version": "2.0.1"
}

View File

@@ -0,0 +1,115 @@
### 0.10.0 / 2015-07-08
* Add the standard `code` and `reason` parameters to the `close` method
### 0.9.4 / 2015-03-08
* Don't send input to the driver before `start()` is called
### 0.9.3 / 2015-02-19
* Make sure the TCP socket is not left open when closing the connection
### 0.9.2 / 2014-12-21
* Only emit `error` once, and don't emit it after `close`
### 0.9.1 / 2014-12-18
* Check that all options to the WebSocket constructor are recognized
### 0.9.0 / 2014-12-13
* Allow protocol extensions to be passed into websocket-extensions
### 0.8.1 / 2014-11-12
* Send the correct hostname when upgrading a connection to TLS
### 0.8.0 / 2014-11-08
* Support connections via HTTP proxies
* Close the connection cleanly if we're still waiting for a handshake response
### 0.7.3 / 2014-10-04
* Allow sockets to be closed when they are in any state other than `CLOSED`
### 0.7.2 / 2013-12-29
* Make sure the `close` event is emitted by clients on Node v0.10
### 0.7.1 / 2013-12-03
* Support the `maxLength` websocket-driver option
* Make the client emit `error` events on network errors
### 0.7.0 / 2013-09-09
* Allow the server to send custom headers with EventSource responses
### 0.6.1 / 2013-07-05
* Add `ca` option to the client for specifying certificate authorities
* Start the server driver asynchronously so that `onopen` handlers can be added
### 0.6.0 / 2013-05-12
* Add support for custom headers
### 0.5.0 / 2013-05-05
* Extract the protocol handlers into the `websocket-driver` library
* Support the Node streaming API
### 0.4.4 / 2013-02-14
* Emit the `close` event if TCP is closed before CLOSE frame is acked
### 0.4.3 / 2012-07-09
* Add `Connection: close` to EventSource response
* Handle situations where `request.socket` is undefined
### 0.4.2 / 2012-04-06
* Add WebSocket error code `1011`.
* Handle URLs with no path correctly by sending `GET /`
### 0.4.1 / 2012-02-26
* Treat anything other than a `Buffer` as a string when calling `send()`
### 0.4.0 / 2012-02-13
* Add `ping()` method to server-side `WebSocket` and `EventSource`
* Buffer `send()` calls until the draft-76 handshake is complete
* Fix HTTPS problems on Node 0.7
### 0.3.1 / 2012-01-16
* Call `setNoDelay(true)` on `net.Socket` objects to reduce latency
### 0.3.0 / 2012-01-13
* Add support for `EventSource` connections
### 0.2.0 / 2011-12-21
* Add support for `Sec-WebSocket-Protocol` negotiation
* Support `hixie-76` close frames and 75/76 ignored segments
* Improve performance of HyBi parsing/framing functions
* Decouple parsers from TCP and reduce write volume
### 0.1.2 / 2011-12-05
* Detect closed sockets on the server side when TCP connection breaks
* Make `hixie-76` sockets work through HAProxy
### 0.1.1 / 2011-11-30
* Fix `addEventListener()` interface methods
### 0.1.0 / 2011-11-27
* Initial release, based on WebSocket components from Faye

View File

@@ -0,0 +1,336 @@
# faye-websocket
* Travis CI build: [![Build
status](https://secure.travis-ci.org/faye/faye-websocket-node.svg)](http://travis-ci.org/faye/faye-websocket-node)
* Autobahn tests: [server](http://faye.jcoglan.com/autobahn/servers/),
[client](http://faye.jcoglan.com/autobahn/clients/)
This is a general-purpose WebSocket implementation extracted from the
[Faye](http://faye.jcoglan.com) project. It provides classes for easily building
WebSocket servers and clients in Node. It does not provide a server itself, but
rather makes it easy to handle WebSocket connections within an existing
[Node](http://nodejs.org/) application. It does not provide any abstraction
other than the standard [WebSocket API](http://dev.w3.org/html5/websockets/).
It also provides an abstraction for handling
[EventSource](http://dev.w3.org/html5/eventsource/) connections, which are
one-way connections that allow the server to push data to the client. They are
based on streaming HTTP responses and can be easier to access via proxies than
WebSockets.
## Installation
```
$ npm install faye-websocket
```
## Handling WebSocket connections in Node
You can handle WebSockets on the server side by listening for HTTP Upgrade
requests, and creating a new socket for the request. This socket object exposes
the usual WebSocket methods for receiving and sending messages. For example this
is how you'd implement an echo server:
```js
var WebSocket = require('faye-websocket'),
http = require('http');
var server = http.createServer();
server.on('upgrade', function(request, socket, body) {
if (WebSocket.isWebSocket(request)) {
var ws = new WebSocket(request, socket, body);
ws.on('message', function(event) {
ws.send(event.data);
});
ws.on('close', function(event) {
console.log('close', event.code, event.reason);
ws = null;
});
}
});
server.listen(8000);
```
`WebSocket` objects are also duplex streams, so you could replace the
`ws.on('message', ...)` line with:
```js
ws.pipe(ws);
```
Note that under certain circumstances (notably a draft-76 client connecting
through an HTTP proxy), the WebSocket handshake will not be complete after you
call `new WebSocket()` because the server will not have received the entire
handshake from the client yet. In this case, calls to `ws.send()` will buffer
the message in memory until the handshake is complete, at which point any
buffered messages will be sent to the client.
If you need to detect when the WebSocket handshake is complete, you can use the
`onopen` event.
If the connection's protocol version supports it, you can call `ws.ping()` to
send a ping message and wait for the client's response. This method takes a
message string, and an optional callback that fires when a matching pong message
is received. It returns `true` if and only if a ping message was sent. If the
client does not support ping/pong, this method sends no data and returns
`false`.
```js
ws.ping('Mic check, one, two', function() {
// fires when pong is received
});
```
## Using the WebSocket client
The client supports both the plain-text `ws` protocol and the encrypted `wss`
protocol, and has exactly the same interface as a socket you would use in a web
browser. On the wire it identifies itself as `hybi-13`.
```js
var WebSocket = require('faye-websocket'),
ws = new WebSocket.Client('ws://www.example.com/');
ws.on('open', function(event) {
console.log('open');
ws.send('Hello, world!');
});
ws.on('message', function(event) {
console.log('message', event.data);
});
ws.on('close', function(event) {
console.log('close', event.code, event.reason);
ws = null;
});
```
The WebSocket client also lets you inspect the status and headers of the
handshake response via its `statusCode` and `headers` properties.
To connect via a proxy, set the `proxy` option to the HTTP origin of the proxy,
including any authorization information, custom headers and TLS config you
require. Only the `origin` setting is required.
```js
var ws = new WebSocket.Client('ws://www.example.com/', [], {
proxy: {
origin: 'http://username:password@proxy.example.com',
headers: {'User-Agent': 'node'},
tls: {cert: fs.readFileSync('client.crt')}
}
});
```
The `tls` value is a Node 'TLS options' object that will be passed to
[`tls.connect()`](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
## Subprotocol negotiation
The WebSocket protocol allows peers to select and identify the application
protocol to use over the connection. On the client side, you can set which
protocols the client accepts by passing a list of protocol names when you
construct the socket:
```js
var ws = new WebSocket.Client('ws://www.example.com/', ['irc', 'amqp']);
```
On the server side, you can likewise pass in the list of protocols the server
supports after the other constructor arguments:
```js
var ws = new WebSocket(request, socket, body, ['irc', 'amqp']);
```
If the client and server agree on a protocol, both the client- and server-side
socket objects expose the selected protocol through the `ws.protocol` property.
## Protocol extensions
faye-websocket is based on the
[websocket-extensions](https://github.com/faye/websocket-extensions-node)
framework that allows extensions to be negotiated via the
`Sec-WebSocket-Extensions` header. To add extensions to a connection, pass an
array of extensions to the `:extensions` option. For example, to add
[permessage-deflate](https://github.com/faye/permessage-deflate-node):
```js
var deflate = require('permessage-deflate');
var ws = new WebSocket(request, socket, body, [], {extensions: [deflate]});
```
## Initialization options
Both the server- and client-side classes allow an options object to be passed in
at initialization time, for example:
```js
var ws = new WebSocket(request, socket, body, protocols, options);
var ws = new WebSocket.Client(url, protocols, options);
```
`protocols` is an array of subprotocols as described above, or `null`.
`options` is an optional object containing any of these fields:
* `extensions` - an array of
[websocket-extensions](https://github.com/faye/websocket-extensions-node)
compatible extensions, as described above
* `headers` - an object containing key-value pairs representing HTTP headers to
be sent during the handshake process
* `maxLength` - the maximum allowed size of incoming message frames, in bytes.
The default value is `2^26 - 1`, or 1 byte short of 64 MiB.
* `ping` - an integer that sets how often the WebSocket should send ping frames,
measured in seconds
The client accepts some additional options:
* `proxy` - settings for a proxy as described above
* `tls` - a Node 'TLS options' object containing TLS settings for the origin
server, this will be passed to
[`tls.connect()`](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback)
* `ca` - (legacy) a shorthand for passing `{tls: {ca: value}}`
## WebSocket API
Both server- and client-side `WebSocket` objects support the following API.
* <b>`on('open', function(event) {})`</b> fires when the socket connection is
established. Event has no attributes.
* <b>`on('message', function(event) {})`</b> fires when the socket receives a
message. Event has one attribute, <b>`data`</b>, which is either a `String`
(for text frames) or a `Buffer` (for binary frames).
* <b>`on('error', function(event) {})`</b> fires when there is a protocol error
due to bad data sent by the other peer. This event is purely informational,
you do not need to implement error recover.
* <b>`on('close', function(event) {})`</b> fires when either the client or the
server closes the connection. Event has two optional attributes, <b>`code`</b>
and <b>`reason`</b>, that expose the status code and message sent by the peer
that closed the connection.
* <b>`send(message)`</b> accepts either a `String` or a `Buffer` and sends a
text or binary message over the connection to the other peer.
* <b>`ping(message, function() {})`</b> sends a ping frame with an optional
message and fires the callback when a matching pong is received.
* <b>`close(code, reason)`</b> closes the connection, sending the given status
code and reason text, both of which are optional.
* <b>`version`</b> is a string containing the version of the `WebSocket`
protocol the connection is using.
* <b>`protocol`</b> is a string (which may be empty) identifying the subprotocol
the socket is using.
## Handling EventSource connections in Node
EventSource connections provide a very similar interface, although because they
only allow the server to send data to the client, there is no `onmessage` API.
EventSource allows the server to push text messages to the client, where each
message has an optional event-type and ID.
```js
var WebSocket = require('faye-websocket'),
EventSource = WebSocket.EventSource,
http = require('http');
var server = http.createServer();
server.on('request', function(request, response) {
if (EventSource.isEventSource(request)) {
var es = new EventSource(request, response);
console.log('open', es.url, es.lastEventId);
// Periodically send messages
var loop = setInterval(function() { es.send('Hello') }, 1000);
es.on('close', function() {
clearInterval(loop);
es = null;
});
} else {
// Normal HTTP request
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello');
}
});
server.listen(8000);
```
The `send` method takes two optional parameters, `event` and `id`. The default
event-type is `'message'` with no ID. For example, to send a `notification`
event with ID `99`:
```js
es.send('Breaking News!', {event: 'notification', id: '99'});
```
The `EventSource` object exposes the following properties:
* <b>`url`</b> is a string containing the URL the client used to create the
EventSource.
* <b>`lastEventId`</b> is a string containing the last event ID received by the
client. You can use this when the client reconnects after a dropped connection
to determine which messages need resending.
When you initialize an EventSource with ` new EventSource()`, you can pass
configuration options after the `response` parameter. Available options are:
* <b>`headers`</b> is an object containing custom headers to be set on the
EventSource response.
* <b>`retry`</b> is a number that tells the client how long (in seconds) it
should wait after a dropped connection before attempting to reconnect.
* <b>`ping`</b> is a number that tells the server how often (in seconds) to send
'ping' packets to the client to keep the connection open, to defeat timeouts
set by proxies. The client will ignore these messages.
For example, this creates a connection that allows access from any origin, pings
every 15 seconds and is retryable every 10 seconds if the connection is broken:
```js
var es = new EventSource(request, response, {
headers: {'Access-Control-Allow-Origin': '*'},
ping: 15,
retry: 10
});
```
You can send a ping message at any time by calling `es.ping()`. Unlike
WebSocket, the client does not send a response to this; it is merely to send
some data over the wire to keep the connection alive.
## License
(The MIT License)
Copyright (c) 2010-2015 James Coglan
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.

View File

@@ -0,0 +1,39 @@
var WebSocket = require('..').Client,
deflate = require('permessage-deflate'),
pace = require('pace');
var host = 'ws://localhost:9001',
agent = encodeURIComponent('node-' + process.version),
cases = 0,
options = {extensions: [deflate]};
var socket = new WebSocket(host + '/getCaseCount'),
url, progress;
socket.onmessage = function(event) {
console.log('Total cases to run: ' + event.data);
cases = parseInt(event.data);
progress = pace(cases);
};
var runCase = function(n) {
if (n > cases) {
url = host + '/updateReports?agent=' + agent;
socket = new WebSocket(url);
socket.onclose = process.exit;
return;
}
url = host + '/runCase?case=' + n + '&agent=' + agent;
socket = new WebSocket(url, [], options);
socket.pipe(socket);
socket.on('close', function() {
progress.op();
runCase(n + 1);
});
};
socket.onclose = function() {
runCase(1);
};

View File

@@ -0,0 +1,32 @@
var WebSocket = require('..').Client,
deflate = require('permessage-deflate'),
fs = require('fs');
var url = process.argv[2],
proxy = process.argv[3],
ca = fs.readFileSync(__dirname + '/../spec/server.crt'),
tls = {ca: ca};
var ws = new WebSocket(url, [], {
proxy: {origin: proxy, headers: {'User-Agent': 'Echo'}, tls: tls},
tls: tls,
headers: {Origin: 'http://faye.jcoglan.com'},
extensions: [deflate]
});
ws.onopen = function() {
console.log('[open]', ws.headers);
ws.send('mic check');
};
ws.onclose = function(close) {
console.log('[close]', close.code, close.reason);
};
ws.onerror = function(error) {
console.log('[error]', error.message);
};
ws.onmessage = function(message) {
console.log('[message]', message.data);
};

View File

@@ -0,0 +1,20 @@
defaults
mode http
timeout client 5s
timeout connect 5s
timeout server 5s
frontend all 0.0.0.0:3000
mode http
timeout client 120s
option forwardfor
option http-server-close
option http-pretend-keepalive
default_backend sockets
backend sockets
balance uri depth 2
timeout server 120s
server socket1 127.0.0.1:7000

View File

@@ -0,0 +1,7 @@
var ProxyServer = require('../spec/proxy_server');
var port = process.argv[2],
secure = process.argv[3] === 'tls',
proxy = new ProxyServer({debug: true, tls: secure});
proxy.listen(port);

View File

@@ -0,0 +1,69 @@
var WebSocket = require('..'),
deflate = require('permessage-deflate'),
fs = require('fs'),
http = require('http'),
https = require('https');
var port = process.argv[2] || 7000,
secure = process.argv[3] === 'tls',
options = {extensions: [deflate], ping: 5};
var upgradeHandler = function(request, socket, head) {
var ws = new WebSocket(request, socket, head, ['irc', 'xmpp'], options);
console.log('[open]', ws.url, ws.version, ws.protocol, request.headers);
ws.pipe(ws);
ws.onclose = function(event) {
console.log('[close]', event.code, event.reason);
ws = null;
};
};
var requestHandler = function(request, response) {
if (!WebSocket.EventSource.isEventSource(request))
return staticHandler(request, response);
var es = new WebSocket.EventSource(request, response),
time = parseInt(es.lastEventId, 10) || 0;
console.log('[open]', es.url, es.lastEventId);
var loop = setInterval(function() {
time += 1;
es.send('Time: ' + time);
setTimeout(function() {
if (es) es.send('Update!!', {event: 'update', id: time});
}, 1000);
}, 2000);
fs.createReadStream(__dirname + '/haproxy.conf').pipe(es, {end: false});
es.onclose = function() {
clearInterval(loop);
console.log('[close]', es.url);
es = null;
};
};
var staticHandler = function(request, response) {
var path = request.url;
fs.readFile(__dirname + path, function(err, content) {
var status = err ? 404 : 200;
response.writeHead(status, {'Content-Type': 'text/html'});
response.write(content || 'Not found');
response.end();
});
};
var server = secure
? https.createServer({
key: fs.readFileSync(__dirname + '/../spec/server.key'),
cert: fs.readFileSync(__dirname + '/../spec/server.crt')
})
: http.createServer();
server.on('request', requestHandler);
server.on('upgrade', upgradeHandler);
server.listen(port);

View File

@@ -0,0 +1,38 @@
<!doctype html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>EventSource test</title>
</head>
<body>
<h1>EventSource test</h1>
<ul></ul>
<script type="text/javascript">
var logger = document.getElementsByTagName('ul')[0],
socket = new EventSource('/');
var log = function(text) {
logger.innerHTML += '<li>' + text + '</li>';
};
socket.onopen = function() {
log('OPEN');
};
socket.onmessage = function(event) {
log('MESSAGE: ' + event.data);
};
socket.addEventListener('update', function(event) {
log('UPDATE(' + event.lastEventId + '): ' + event.data);
});
socket.onerror = function(event) {
log('ERROR: ' + event.message);
};
</script>
</body>
</html>

View File

@@ -0,0 +1,43 @@
<!doctype html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>WebSocket test</title>
</head>
<body>
<h1>WebSocket test</h1>
<ul></ul>
<script type="text/javascript">
var logger = document.getElementsByTagName('ul')[0],
Socket = window.MozWebSocket || window.WebSocket,
protos = ['foo', 'bar', 'xmpp'],
socket = new Socket('ws://' + location.hostname + ':' + location.port + '/', protos),
index = 0;
var log = function(text) {
logger.innerHTML += '<li>' + text + '</li>';
};
socket.addEventListener('open', function() {
log('OPEN: ' + socket.protocol);
socket.send('Hello, world');
});
socket.onerror = function(event) {
log('ERROR: ' + event.message);
};
socket.onmessage = function(event) {
log('MESSAGE: ' + event.data);
setTimeout(function() { socket.send(++index + ' ' + event.data) }, 2000);
};
socket.onclose = function(event) {
log('CLOSE: ' + event.code + ', ' + event.reason);
};
</script>
</body>
</html>

View File

@@ -0,0 +1,86 @@
{
"_args": [
[
"faye-websocket@0.10.x",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server"
]
],
"_from": "faye-websocket@>=0.10.0 <0.11.0",
"_id": "faye-websocket@0.10.0",
"_inCache": true,
"_installable": true,
"_location": "/live-server/faye-websocket",
"_nodeVersion": "0.12.6",
"_npmUser": {
"email": "jcoglan@gmail.com",
"name": "jcoglan"
},
"_npmVersion": "2.11.2",
"_phantomChildren": {},
"_requested": {
"name": "faye-websocket",
"raw": "faye-websocket@0.10.x",
"rawSpec": "0.10.x",
"scope": null,
"spec": ">=0.10.0 <0.11.0",
"type": "range"
},
"_requiredBy": [
"/live-server"
],
"_resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
"_shasum": "4e492f8d04dfb6f89003507f6edbf2d501e7c6f4",
"_shrinkwrap": null,
"_spec": "faye-websocket@0.10.x",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server",
"author": {
"email": "jcoglan@gmail.com",
"name": "James Coglan",
"url": "http://jcoglan.com/"
},
"bugs": {
"url": "http://github.com/faye/faye-websocket-node/issues"
},
"dependencies": {
"websocket-driver": ">=0.5.1"
},
"description": "Standards-compliant WebSocket server and client",
"devDependencies": {
"jstest": "",
"pace": "",
"permessage-deflate": ""
},
"directories": {},
"dist": {
"shasum": "4e492f8d04dfb6f89003507f6edbf2d501e7c6f4",
"tarball": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz"
},
"engines": {
"node": ">=0.4.0"
},
"gitHead": "854c0a96581d95d0f07db01ce48431a4098e7c60",
"homepage": "http://github.com/faye/faye-websocket-node",
"keywords": [
"websocket",
"eventsource"
],
"license": "MIT",
"main": "./lib/faye/websocket",
"maintainers": [
{
"email": "jcoglan@gmail.com",
"name": "jcoglan"
}
],
"name": "faye-websocket",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/faye/faye-websocket-node.git"
},
"scripts": {
"test": "jstest spec/runner.js"
},
"version": "0.10.0"
}

View File

@@ -0,0 +1,10 @@
(The MIT License)
Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me) <us@bevry.me>
Copyright © 2011-2012 [Benjamin Lupton](http://balupton.com) <b@lupton.cc>
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.

View File

@@ -0,0 +1,56 @@
# Get Set Deep [![Build Status](https://secure.travis-ci.org/bevry/getsetdeep.png?branch=master)](http://travis-ci.org/bevry/getsetdeep)
Get and set nested variables of an object, includes support for Backbone Models
## Install
### Backend
1. [Install Node.js](http://bevry.me/node/install)
2. `npm install --save getsetdeep`
### Frontend
1. [See Browserify](http://browserify.org)
## Usage
### Example
``` javascript
// Import
var getsetdeep = require('getsetdeep')
// Prepare
var obj = {
a: {
b: {
c: 3
}
}
}
// Get
getsetdeep.getDeep(obj, 'a.b.c') // returns 3
getsetdeep.setDeep(obj, 'a.b.c', 4) // returns 4
getsetdeep.getDeep(obj, 'a.b.c') // returns 4
```
### Notes
- `setDeep` also has a fourth argument called `setOnlyIfEmpty` which defaults to `false`, if specified to `true` then `setDeep` will only set the value if the current value is `null` or `undefined`
- We also work with Backbone Models (or rather any model that utilizes an `attributes` object)
## History
You can discover the history inside the [History.md](https://github.com/bevry/getsetdeep/blob/master/History.md#files) file
## License
Licensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)
<br/>Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me)
<br/>Copyright © 2011-2012 [Benjamin Arthur Lupton](http://balupton.com)

View File

@@ -0,0 +1,98 @@
{
"_args": [
[
"getsetdeep@~2.0.0",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util"
]
],
"_from": "getsetdeep@>=2.0.0 <2.1.0",
"_id": "getsetdeep@2.0.0",
"_inCache": true,
"_installable": true,
"_location": "/live-server/getsetdeep",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "1.2.15",
"_phantomChildren": {},
"_requested": {
"name": "getsetdeep",
"raw": "getsetdeep@~2.0.0",
"rawSpec": "~2.0.0",
"scope": null,
"spec": ">=2.0.0 <2.1.0",
"type": "range"
},
"_requiredBy": [
"/live-server/bal-util"
],
"_resolved": "https://registry.npmjs.org/getsetdeep/-/getsetdeep-2.0.0.tgz",
"_shasum": "f13384fe656d0a3f41c214cbdf31001a57c12492",
"_shrinkwrap": null,
"_spec": "getsetdeep@~2.0.0",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util",
"author": {
"email": "us@bevry.me",
"name": "Bevry Pty Ltd",
"url": "http://bevry.me"
},
"bugs": {
"url": "https://github.com/bevry/getsetdeep/issues"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "https://github.com/balupton"
}
],
"dependencies": {
"typechecker": "~2.0.1"
},
"description": "Get and set nested variables of an object, includes support for Backbone Models",
"devDependencies": {
"coffee-script": "~1.6.2",
"joe": "~1.1.2"
},
"directories": {
"lib": "./out/lib"
},
"dist": {
"shasum": "f13384fe656d0a3f41c214cbdf31001a57c12492",
"tarball": "https://registry.npmjs.org/getsetdeep/-/getsetdeep-2.0.0.tgz"
},
"engines": {
"node": ">=0.4"
},
"homepage": "https://github.com/bevry/getsetdeep",
"keywords": [
"setDeep",
"getDeep",
"set",
"get",
"getter",
"setter",
"backbone",
"backbone.js"
],
"main": "./out/lib/getsetdeep.js",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "getsetdeep",
"optionalDependencies": {},
"readme": "# Get Set Deep [![Build Status](https://secure.travis-ci.org/bevry/getsetdeep.png?branch=master)](http://travis-ci.org/bevry/getsetdeep)\nGet and set nested variables of an object, includes support for Backbone Models\n\n\n## Install\n\n### Backend\n\n1. [Install Node.js](http://bevry.me/node/install)\n2. `npm install --save getsetdeep`\n\n### Frontend\n\n1. [See Browserify](http://browserify.org)\n\n\n\n## Usage\n\n### Example\n\n``` javascript\n// Import\nvar getsetdeep = require('getsetdeep')\n\n// Prepare\nvar obj = {\n\ta: {\n\t\tb: {\n\t\t\tc: 3\n\t\t}\n\t}\n}\n\n// Get\ngetsetdeep.getDeep(obj, 'a.b.c') // returns 3\ngetsetdeep.setDeep(obj, 'a.b.c', 4) // returns 4\ngetsetdeep.getDeep(obj, 'a.b.c') // returns 4\n```\n\n\n### Notes\n\n- `setDeep` also has a fourth argument called `setOnlyIfEmpty` which defaults to `false`, if specified to `true` then `setDeep` will only set the value if the current value is `null` or `undefined`\n- We also work with Backbone Models (or rather any model that utilizes an `attributes` object)\n\n\n## History\nYou can discover the history inside the [History.md](https://github.com/bevry/getsetdeep/blob/master/History.md#files) file\n\n\n\n## License\nLicensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)\n<br/>Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me)\n<br/>Copyright © 2011-2012 [Benjamin Arthur Lupton](http://balupton.com)\n",
"readmeFilename": "README.md",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/bevry/getsetdeep.git"
},
"scripts": {
"test": "node ./out/test/getsetdeep-test.js"
},
"version": "2.0.0"
}

View File

@@ -0,0 +1,19 @@
Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
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.

View File

@@ -0,0 +1,90 @@
# mime
Comprehensive MIME type mapping API based on mime-db module.
## Install
Install with [npm](http://github.com/isaacs/npm):
npm install mime
## Contributing / Testing
npm run test
## Command Line
mime [path_string]
E.g.
> mime scripts/jquery.js
application/javascript
## API - Queries
### mime.lookup(path)
Get the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.
```js
var mime = require('mime');
mime.lookup('/path/to/file.txt'); // => 'text/plain'
mime.lookup('file.txt'); // => 'text/plain'
mime.lookup('.TXT'); // => 'text/plain'
mime.lookup('htm'); // => 'text/html'
```
### mime.default_type
Sets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)
### mime.extension(type)
Get the default extension for `type`
```js
mime.extension('text/html'); // => 'html'
mime.extension('application/octet-stream'); // => 'bin'
```
### mime.charsets.lookup()
Map mime-type to charset
```js
mime.charsets.lookup('text/plain'); // => 'UTF-8'
```
(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)
## API - Defining Custom Types
Custom type mappings can be added on a per-project basis via the following APIs.
### mime.define()
Add custom mime/extension mappings
```js
mime.define({
'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],
'application/x-my-type': ['x-mt', 'x-mtt'],
// etc ...
});
mime.lookup('x-sft'); // => 'text/x-some-format'
```
The first entry in the extensions array is returned by `mime.extension()`. E.g.
```js
mime.extension('text/x-some-format'); // => 'x-sf'
```
### mime.load(filepath)
Load mappings from an Apache ".types" format file
```js
mime.load('./my_project.types');
```
The .types file format is simple - See the `types` dir for examples.

View File

@@ -0,0 +1,8 @@
#!/usr/bin/env node
var mime = require('./mime.js');
var file = process.argv[2];
var type = mime.lookup(file);
process.stdout.write(type + '\n');

View File

@@ -0,0 +1,108 @@
var path = require('path');
var fs = require('fs');
function Mime() {
// Map of extension -> mime type
this.types = Object.create(null);
// Map of mime type -> extension
this.extensions = Object.create(null);
}
/**
* Define mimetype -> extension mappings. Each key is a mime-type that maps
* to an array of extensions associated with the type. The first extension is
* used as the default extension for the type.
*
* e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
*
* @param map (Object) type definitions
*/
Mime.prototype.define = function (map) {
for (var type in map) {
var exts = map[type];
for (var i = 0; i < exts.length; i++) {
if (process.env.DEBUG_MIME && this.types[exts]) {
console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
this.types[exts] + ' to ' + type);
}
this.types[exts[i]] = type;
}
// Default extension is the first one we encounter
if (!this.extensions[type]) {
this.extensions[type] = exts[0];
}
}
};
/**
* Load an Apache2-style ".types" file
*
* This may be called multiple times (it's expected). Where files declare
* overlapping types/extensions, the last file wins.
*
* @param file (String) path of file to load.
*/
Mime.prototype.load = function(file) {
this._loading = file;
// Read file and split into lines
var map = {},
content = fs.readFileSync(file, 'ascii'),
lines = content.split(/[\r\n]+/);
lines.forEach(function(line) {
// Clean up whitespace/comments, and split into fields
var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/);
map[fields.shift()] = fields;
});
this.define(map);
this._loading = null;
};
/**
* Lookup a mime type based on extension
*/
Mime.prototype.lookup = function(path, fallback) {
var ext = path.replace(/.*[\.\/\\]/, '').toLowerCase();
return this.types[ext] || fallback || this.default_type;
};
/**
* Return file extension associated with a mime type
*/
Mime.prototype.extension = function(mimeType) {
var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase();
return this.extensions[type];
};
// Default instance
var mime = new Mime();
// Define built-in types
mime.define(require('./types.json'));
// Default type
mime.default_type = mime.lookup('bin');
//
// Additional API specific to the default instance
//
mime.Mime = Mime;
/**
* Lookup a charset based on mime type.
*/
mime.charsets = {
lookup: function(mimeType, fallback) {
// Assume text types are utf8
return (/^text\//).test(mimeType) ? 'UTF-8' : fallback;
}
};
module.exports = mime;

View File

@@ -0,0 +1,98 @@
{
"_args": [
[
"mime@1.3.4",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/send"
]
],
"_from": "mime@1.3.4",
"_id": "mime@1.3.4",
"_inCache": true,
"_installable": true,
"_location": "/live-server/mime",
"_npmUser": {
"email": "robert@broofa.com",
"name": "broofa"
},
"_npmVersion": "1.4.28",
"_phantomChildren": {},
"_requested": {
"name": "mime",
"raw": "mime@1.3.4",
"rawSpec": "1.3.4",
"scope": null,
"spec": "1.3.4",
"type": "version"
},
"_requiredBy": [
"/live-server/send"
],
"_resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
"_shasum": "115f9e3b6b3daf2959983cb38f149a2d40eb5d53",
"_shrinkwrap": null,
"_spec": "mime@1.3.4",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/send",
"author": {
"email": "robert@broofa.com",
"name": "Robert Kieffer",
"url": "http://github.com/broofa"
},
"bin": {
"mime": "cli.js"
},
"bugs": {
"url": "https://github.com/broofa/node-mime/issues"
},
"contributors": [
{
"email": "benjamin@benjaminthomas.org",
"name": "Benjamin Thomas",
"url": "http://github.com/bentomas"
}
],
"dependencies": {},
"description": "A comprehensive library for mime-type mapping",
"devDependencies": {
"mime-db": "^1.2.0"
},
"directories": {},
"dist": {
"shasum": "115f9e3b6b3daf2959983cb38f149a2d40eb5d53",
"tarball": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz"
},
"gitHead": "1628f6e0187095009dcef4805c3a49706f137974",
"homepage": "https://github.com/broofa/node-mime",
"keywords": [
"util",
"mime"
],
"licenses": [
{
"type": "MIT",
"url": "https://raw.github.com/broofa/node-mime/master/LICENSE"
}
],
"main": "mime.js",
"maintainers": [
{
"email": "robert@broofa.com",
"name": "broofa"
},
{
"email": "benjamin@benjaminthomas.org",
"name": "bentomas"
}
],
"name": "mime",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/broofa/node-mime.git"
},
"scripts": {
"prepublish": "node build/build.js > types.json",
"test": "node build/test.js"
},
"version": "1.3.4"
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,39 @@
/* eslint-disable no-unused-vars */
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty;
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
function toObject(val) {
if (val === null || val === undefined) {
throw new TypeError('Object.assign cannot be called with null or undefined');
}
return Object(val);
}
module.exports = Object.assign || function (target, source) {
var from;
var to = toObject(target);
var symbols;
for (var s = 1; s < arguments.length; s++) {
from = Object(arguments[s]);
for (var key in from) {
if (hasOwnProperty.call(from, key)) {
to[key] = from[key];
}
}
if (Object.getOwnPropertySymbols) {
symbols = Object.getOwnPropertySymbols(from);
for (var i = 0; i < symbols.length; i++) {
if (propIsEnumerable.call(from, symbols[i])) {
to[symbols[i]] = from[symbols[i]];
}
}
}
}
return to;
};

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
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.

View File

@@ -0,0 +1,107 @@
{
"_args": [
[
"object-assign@^4.0.1",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/opn"
],
[
"object-assign@latest",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server"
]
],
"_from": "object-assign@latest",
"_id": "object-assign@4.0.1",
"_inCache": true,
"_installable": true,
"_location": "/live-server/object-assign",
"_nodeVersion": "3.0.0",
"_npmUser": {
"email": "sindresorhus@gmail.com",
"name": "sindresorhus"
},
"_npmVersion": "2.13.3",
"_phantomChildren": {},
"_requested": {
"name": "object-assign",
"raw": "object-assign@latest",
"rawSpec": "latest",
"scope": null,
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"/live-server",
"/live-server/opn"
],
"_shrinkwrap": null,
"_spec": "object-assign@latest",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server",
"author": {
"email": "sindresorhus@gmail.com",
"name": "Sindre Sorhus",
"url": "http://sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/object-assign/issues"
},
"dependencies": {},
"description": "ES6 Object.assign() ponyfill",
"devDependencies": {
"lodash": "^3.10.1",
"matcha": "^0.6.0",
"mocha": "*",
"xo": "*"
},
"directories": {},
"dist": {
"shasum": "99504456c3598b5cad4fc59c26e8a9bb107fe0bd",
"tarball": "https://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"gitHead": "b0c40d37cbc43e89ad3326a9bad4c6b3133ba6d3",
"homepage": "https://github.com/sindresorhus/object-assign#readme",
"keywords": [
"object",
"assign",
"extend",
"properties",
"es6",
"ecmascript",
"harmony",
"ponyfill",
"prollyfill",
"polyfill",
"shim",
"browser"
],
"license": "MIT",
"maintainers": [
{
"email": "sindresorhus@gmail.com",
"name": "sindresorhus"
}
],
"name": "object-assign",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/object-assign.git"
},
"scripts": {
"bench": "matcha bench.js",
"test": "xo && mocha"
},
"version": "4.0.1",
"xo": {
"envs": [
"node",
"mocha"
]
}
}

View File

@@ -0,0 +1,51 @@
# object-assign [![Build Status](https://travis-ci.org/sindresorhus/object-assign.svg?branch=master)](https://travis-ci.org/sindresorhus/object-assign)
> ES6 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) ponyfill
> Ponyfill: A polyfill that doesn't overwrite the native method
## Install
```sh
$ npm install --save object-assign
```
## Usage
```js
var objectAssign = require('object-assign');
objectAssign({foo: 0}, {bar: 1});
//=> {foo: 0, bar: 1}
// multiple sources
objectAssign({foo: 0}, {bar: 1}, {baz: 2});
//=> {foo: 0, bar: 1, baz: 2}
// overwrites equal keys
objectAssign({foo: 0}, {foo: 1}, {foo: 2});
//=> {foo: 2}
// ignores null and undefined sources
objectAssign({foo: 0}, null, {bar: 1}, undefined);
//=> {foo: 0, bar: 1}
```
## API
### objectAssign(target, source, [source, ...])
Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones.
## Resources
- [ES6 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign)
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@@ -0,0 +1,95 @@
'use strict';
var path = require('path');
var childProcess = require('child_process');
var objectAssign = require('object-assign');
var Promise = require('pinkie-promise');
module.exports = function (target, opts) {
if (typeof target !== 'string') {
return Promise.reject(new Error('Expected a `target`'));
}
opts = objectAssign({wait: true}, opts);
var cmd;
var appArgs = [];
var args = [];
var cpOpts = {};
if (Array.isArray(opts.app)) {
appArgs = opts.app.slice(1);
opts.app = opts.app[0];
}
if (process.platform === 'darwin') {
cmd = 'open';
if (opts.wait) {
args.push('-W');
}
if (opts.app) {
args.push('-a', opts.app);
}
if (appArgs.length > 0) {
args.push('--args');
args = args.concat(appArgs);
}
} else if (process.platform === 'win32') {
cmd = 'cmd';
args.push('/c', 'start', '""');
target = target.replace(/&/g, '^&');
if (opts.wait) {
args.push('/wait');
}
if (opts.app) {
args.push(opts.app);
}
if (appArgs.length > 0) {
args = args.concat(appArgs);
}
} else {
if (opts.app) {
cmd = opts.app;
} else {
cmd = path.join(__dirname, 'xdg-open');
}
if (appArgs.length > 0) {
args = args.concat(appArgs);
}
if (!opts.wait) {
// xdg-open will block the process unless
// stdio is ignored even if it's unref'd
cpOpts.stdio = 'ignore';
}
}
args.push(target);
var cp = childProcess.spawn(cmd, args, cpOpts);
if (opts.wait) {
return new Promise(function (resolve, reject) {
cp.once('error', reject);
cp.once('close', function (code) {
if (code > 0) {
reject(new Error('Exited with code ' + code));
return;
}
resolve(cp);
});
});
}
cp.unref();
return Promise.resolve(cp);
};

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com>
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.

View File

@@ -0,0 +1,116 @@
{
"_args": [
[
"opn@latest",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server"
]
],
"_from": "opn@latest",
"_id": "opn@4.0.1",
"_inCache": true,
"_installable": true,
"_location": "/live-server/opn",
"_nodeVersion": "4.3.0",
"_npmOperationalInternal": {
"host": "packages-13-west.internal.npmjs.com",
"tmp": "tmp/opn-4.0.1.tgz_1456989823472_0.5448145705740899"
},
"_npmUser": {
"email": "sindresorhus@gmail.com",
"name": "sindresorhus"
},
"_npmVersion": "2.14.12",
"_phantomChildren": {},
"_requested": {
"name": "opn",
"raw": "opn@latest",
"rawSpec": "latest",
"scope": null,
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"/live-server"
],
"_resolved": "https://registry.npmjs.org/opn/-/opn-4.0.1.tgz",
"_shasum": "9bd30ee3eba4fd533be2c83d56329a4e58913bf8",
"_shrinkwrap": null,
"_spec": "opn@latest",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server",
"author": {
"email": "sindresorhus@gmail.com",
"name": "Sindre Sorhus",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/opn/issues"
},
"dependencies": {
"object-assign": "^4.0.1",
"pinkie-promise": "^2.0.0"
},
"description": "A better node-open. Opens stuff like websites, files, executables. Cross-platform.",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"directories": {},
"dist": {
"shasum": "9bd30ee3eba4fd533be2c83d56329a4e58913bf8",
"tarball": "https://registry.npmjs.org/opn/-/opn-4.0.1.tgz"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js",
"xdg-open"
],
"gitHead": "34626da5fbb93e324b51ad281c60091d3bda9205",
"homepage": "https://github.com/sindresorhus/opn",
"keywords": [
"app",
"open",
"opn",
"opener",
"opens",
"launch",
"start",
"xdg-open",
"xdg",
"default",
"cmd",
"browser",
"editor",
"executable",
"exe",
"url",
"urls",
"arguments",
"args",
"spawn",
"exec",
"child",
"process",
"website",
"file"
],
"license": "MIT",
"maintainers": [
{
"email": "sindresorhus@gmail.com",
"name": "sindresorhus"
}
],
"name": "opn",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/opn.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "4.0.1"
}

View File

@@ -0,0 +1,89 @@
# opn
> A better [node-open](https://github.com/pwnall/node-open). Opens stuff like websites, files, executables. Cross-platform.
#### Why?
- Actively maintained
- Supports app arguments
- Safer as it uses `spawn` instead of `exec`
- Fixes most of the open `node-open` issues
- Includes the latest [`xdg-open` script](http://cgit.freedesktop.org/xdg/xdg-utils/commit/?id=c55122295c2a480fa721a9614f0e2d42b2949c18) for Linux
## Install
```
$ npm install --save opn
```
## Usage
```js
const opn = require('opn');
// opens the image in the default image viewer
opn('unicorn.png').then(() => {
// image viewer closed
});
// opens the url in the default browser
opn('http://sindresorhus.com');
// specify the app to open in
opn('http://sindresorhus.com', {app: 'firefox'});
// specify app arguments
opn('http://sindresorhus.com', {app: ['google chrome', '--incognito']});
```
## API
Uses the command `open` on OS X, `start` on Windows and `xdg-open` on other platforms.
### opn(target, [options])
Returns a promise for the [spawned child process](https://nodejs.org/api/child_process.html#child_process_class_childprocess). You'd normally not need to use this for anything, but it can be useful if you'd like to attach custom event listeners or perform other operations directly on the spawned process.
#### target
*Required*
Type: `string`
The thing you want to open. Can be a URL, file, or executable.
Opens in the default app for the file type. Eg. URLs opens in your default browser.
#### options
Type: `object`
##### wait
Type: `boolean`
Default: `true`
Wait for the opened app to exit before calling the `callback`. If `false` it's called immediately when opening the app.
On Windows you have to explicitly specify an app for it to be able to wait.
##### app
Type: `string`, `array`
Specify the app to open the `target` with, or an array with the app and app arguments.
The app name is platform dependent. Don't hard code it in reusable modules. Eg. Chrome is `google chrome` on OS X, `google-chrome` on Linux and `chrome` on Windows.
## Related
- [opn-cli](https://github.com/sindresorhus/opn-cli) - CLI for this module
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@@ -0,0 +1,861 @@
#!/bin/sh
#---------------------------------------------
# xdg-open
#
# Utility script to open a URL in the registered default application.
#
# Refer to the usage() function below for usage.
#
# Copyright 2009-2010, Fathi Boudra <fabo@freedesktop.org>
# Copyright 2009-2010, Rex Dieter <rdieter@fedoraproject.org>
# Copyright 2006, Kevin Krammer <kevin.krammer@gmx.at>
# Copyright 2006, Jeremy White <jwhite@codeweavers.com>
#
# LICENSE:
#
# 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.
#
#---------------------------------------------
manualpage()
{
cat << _MANUALPAGE
Name
xdg-open - opens a file or URL in the user's preferred
application
Synopsis
xdg-open { file | URL }
xdg-open { --help | --manual | --version }
Description
xdg-open opens a file or URL in the user's preferred
application. If a URL is provided the URL will be opened in the
user's preferred web browser. If a file is provided the file
will be opened in the preferred application for files of that
type. xdg-open supports file, ftp, http and https URLs.
xdg-open is for use inside a desktop session only. It is not
recommended to use xdg-open as root.
Options
--help
Show command synopsis.
--manual
Show this manual page.
--version
Show the xdg-utils version information.
Exit Codes
An exit code of 0 indicates success while a non-zero exit code
indicates failure. The following failure codes can be returned:
1
Error in command line syntax.
2
One of the files passed on the command line did not
exist.
3
A required tool could not be found.
4
The action failed.
Examples
xdg-open 'http://www.freedesktop.org/'
Opens the freedesktop.org website in the user's default
browser.
xdg-open /tmp/foobar.png
Opens the PNG image file /tmp/foobar.png in the user's default
image viewing application.
_MANUALPAGE
}
usage()
{
cat << _USAGE
xdg-open - opens a file or URL in the user's preferred
application
Synopsis
xdg-open { file | URL }
xdg-open { --help | --manual | --version }
_USAGE
}
#@xdg-utils-common@
#----------------------------------------------------------------------------
# Common utility functions included in all XDG wrapper scripts
#----------------------------------------------------------------------------
DEBUG()
{
[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0;
[ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0;
shift
echo "$@" >&2
}
# This handles backslashes but not quote marks.
first_word()
{
read first rest
echo "$first"
}
#-------------------------------------------------------------
# map a binary to a .desktop file
binary_to_desktop_file()
{
search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
binary="`which "$1"`"
binary="`readlink -f "$binary"`"
base="`basename "$binary"`"
IFS=:
for dir in $search; do
unset IFS
[ "$dir" ] || continue
[ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do
[ -r "$file" ] || continue
# Check to make sure it's worth the processing.
grep -q "^Exec.*$base" "$file" || continue
# Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop").
grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue
command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
command="`which "$command"`"
if [ x"`readlink -f "$command"`" = x"$binary" ]; then
# Fix any double slashes that got added path composition
echo "$file" | sed -e 's,//*,/,g'
return
fi
done
done
}
#-------------------------------------------------------------
# map a .desktop file to a binary
## FIXME: handle vendor dir case
desktop_file_to_binary()
{
search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
desktop="`basename "$1"`"
IFS=:
for dir in $search; do
unset IFS
[ "$dir" ] && [ -d "$dir/applications" ] || continue
file="$dir/applications/$desktop"
[ -r "$file" ] || continue
# Remove any arguments (%F, %f, %U, %u, etc.).
command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
command="`which "$command"`"
readlink -f "$command"
return
done
}
#-------------------------------------------------------------
# Exit script on successfully completing the desired operation
exit_success()
{
if [ $# -gt 0 ]; then
echo "$@"
echo
fi
exit 0
}
#-----------------------------------------
# Exit script on malformed arguments, not enough arguments
# or missing required option.
# prints usage information
exit_failure_syntax()
{
if [ $# -gt 0 ]; then
echo "xdg-open: $@" >&2
echo "Try 'xdg-open --help' for more information." >&2
else
usage
echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info."
fi
exit 1
}
#-------------------------------------------------------------
# Exit script on missing file specified on command line
exit_failure_file_missing()
{
if [ $# -gt 0 ]; then
echo "xdg-open: $@" >&2
fi
exit 2
}
#-------------------------------------------------------------
# Exit script on failure to locate necessary tool applications
exit_failure_operation_impossible()
{
if [ $# -gt 0 ]; then
echo "xdg-open: $@" >&2
fi
exit 3
}
#-------------------------------------------------------------
# Exit script on failure returned by a tool application
exit_failure_operation_failed()
{
if [ $# -gt 0 ]; then
echo "xdg-open: $@" >&2
fi
exit 4
}
#------------------------------------------------------------
# Exit script on insufficient permission to read a specified file
exit_failure_file_permission_read()
{
if [ $# -gt 0 ]; then
echo "xdg-open: $@" >&2
fi
exit 5
}
#------------------------------------------------------------
# Exit script on insufficient permission to write a specified file
exit_failure_file_permission_write()
{
if [ $# -gt 0 ]; then
echo "xdg-open: $@" >&2
fi
exit 6
}
check_input_file()
{
if [ ! -e "$1" ]; then
exit_failure_file_missing "file '$1' does not exist"
fi
if [ ! -r "$1" ]; then
exit_failure_file_permission_read "no permission to read file '$1'"
fi
}
check_vendor_prefix()
{
file_label="$2"
[ -n "$file_label" ] || file_label="filename"
file=`basename "$1"`
case "$file" in
[[:alpha:]]*-*)
return
;;
esac
echo "xdg-open: $file_label '$file' does not have a proper vendor prefix" >&2
echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2
echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2
echo "Use --novendor to override or 'xdg-open --manual' for additional info." >&2
exit 1
}
check_output_file()
{
# if the file exists, check if it is writeable
# if it does not exists, check if we are allowed to write on the directory
if [ -e "$1" ]; then
if [ ! -w "$1" ]; then
exit_failure_file_permission_write "no permission to write to file '$1'"
fi
else
DIR=`dirname "$1"`
if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then
exit_failure_file_permission_write "no permission to create file '$1'"
fi
fi
}
#----------------------------------------
# Checks for shared commands, e.g. --help
check_common_commands()
{
while [ $# -gt 0 ] ; do
parm="$1"
shift
case "$parm" in
--help)
usage
echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info."
exit_success
;;
--manual)
manualpage
exit_success
;;
--version)
echo "xdg-open 1.1.0 rc3"
exit_success
;;
esac
done
}
check_common_commands "$@"
[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then
# Be silent
xdg_redirect_output=" > /dev/null 2> /dev/null"
else
# All output to stderr
xdg_redirect_output=" >&2"
fi
#--------------------------------------
# Checks for known desktop environments
# set variable DE to the desktop environments name, lowercase
detectDE()
{
# see https://bugs.freedesktop.org/show_bug.cgi?id=34164
unset GREP_OPTIONS
if [ -n "${XDG_CURRENT_DESKTOP}" ]; then
case "${XDG_CURRENT_DESKTOP}" in
ENLIGHTENMENT)
DE=enlightenment;
;;
GNOME)
DE=gnome;
;;
KDE)
DE=kde;
;;
LXDE)
DE=lxde;
;;
MATE)
DE=mate;
;;
XFCE)
DE=xfce
;;
esac
fi
if [ x"$DE" = x"" ]; then
# classic fallbacks
if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde;
elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate;
elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome;
elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce
elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment;
fi
fi
if [ x"$DE" = x"" ]; then
# fallback to checking $DESKTOP_SESSION
case "$DESKTOP_SESSION" in
gnome)
DE=gnome;
;;
LXDE|Lubuntu)
DE=lxde;
;;
MATE)
DE=mate;
;;
xfce|xfce4|'Xfce Session')
DE=xfce;
;;
esac
fi
if [ x"$DE" = x"" ]; then
# fallback to uname output for other platforms
case "$(uname 2>/dev/null)" in
Darwin)
DE=darwin;
;;
esac
fi
if [ x"$DE" = x"gnome" ]; then
# gnome-default-applications-properties is only available in GNOME 2.x
# but not in GNOME 3.x
which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3"
fi
}
#----------------------------------------------------------------------------
# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4
# It also always returns 1 in KDE 3.4 and earlier
# Simply return 0 in such case
kfmclient_fix_exit_code()
{
version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'`
major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'`
minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'`
release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'`
test "$major" -gt 3 && return $1
test "$minor" -gt 5 && return $1
test "$release" -gt 4 && return $1
return 0
}
# This handles backslashes but not quote marks.
last_word()
{
read first rest
echo "$rest"
}
# Get the value of a key in a desktop file's Desktop Entry group.
# Example: Use get_key foo.desktop Exec
# to get the values of the Exec= key for the Desktop Entry group.
get_key()
{
local file="${1}"
local key="${2}"
local desktop_entry=""
IFS_="${IFS}"
IFS=""
while read line
do
case "$line" in
"[Desktop Entry]")
desktop_entry="y"
;;
# Reset match flag for other groups
"["*)
desktop_entry=""
;;
"${key}="*)
# Only match Desktop Entry group
if [ -n "${desktop_entry}" ]
then
echo "${line}" | cut -d= -f 2-
fi
esac
done < "${file}"
IFS="${IFS_}"
}
open_darwin()
{
open "$1"
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
open_kde()
{
if [ -n "${KDE_SESSION_VERSION}" ]; then
case "${KDE_SESSION_VERSION}" in
4)
kde-open "$1"
;;
5)
kde-open${KDE_SESSION_VERSION} "$1"
;;
esac
else
kfmclient exec "$1"
kfmclient_fix_exit_code $?
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
open_gnome()
{
if gvfs-open --help 2>/dev/null 1>&2; then
gvfs-open "$1"
else
gnome-open "$1"
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
open_mate()
{
if gvfs-open --help 2>/dev/null 1>&2; then
gvfs-open "$1"
else
mate-open "$1"
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
open_xfce()
{
exo-open "$1"
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
open_enlightenment()
{
enlightenment_open "$1"
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
#-----------------------------------------
# Recursively search .desktop file
search_desktop_file()
{
local default="$1"
local dir="$2"
local target="$3"
local file=""
# look for both vendor-app.desktop, vendor/app.desktop
if [ -r "$dir/$default" ]; then
file="$dir/$default"
elif [ -r "$dir/`echo $default | sed -e 's|-|/|'`" ]; then
file="$dir/`echo $default | sed -e 's|-|/|'`"
fi
if [ -r "$file" ] ; then
command="$(get_key "${file}" "Exec" | first_word)"
command_exec=`which $command 2>/dev/null`
icon="$(get_key "${file}" "Icon")"
# FIXME: Actually LC_MESSAGES should be used as described in
# http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html
localised_name="$(get_key "${file}" "Name")"
set -- $(get_key "${file}" "Exec" | last_word)
# We need to replace any occurrence of "%f", "%F" and
# the like by the target file. We examine each
# argument and append the modified argument to the
# end then shift.
local args=$#
local replaced=0
while [ $args -gt 0 ]; do
case $1 in
%[c])
replaced=1
arg="${localised_name}"
shift
set -- "$@" "$arg"
;;
%[fFuU])
replaced=1
arg="$target"
shift
set -- "$@" "$arg"
;;
%[i])
replaced=1
shift
set -- "$@" "--icon" "$icon"
;;
*)
arg="$1"
shift
set -- "$@" "$arg"
;;
esac
args=$(( $args - 1 ))
done
[ $replaced -eq 1 ] || set -- "$@" "$target"
"$command_exec" "$@"
if [ $? -eq 0 ]; then
exit_success
fi
fi
for d in $dir/*/; do
[ -d "$d" ] && search_desktop_file "$default" "$d" "$target"
done
}
open_generic_xdg_mime()
{
filetype="$2"
default=`xdg-mime query default "$filetype"`
if [ -n "$default" ] ; then
xdg_user_dir="$XDG_DATA_HOME"
[ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
xdg_system_dirs="$XDG_DATA_DIRS"
[ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/
DEBUG 3 "$xdg_user_dir:$xdg_system_dirs"
for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do
search_desktop_file "$default" "$x/applications/" "$1"
done
fi
}
open_generic_xdg_file_mime()
{
filetype=`xdg-mime query filetype "$1" | sed "s/;.*//"`
open_generic_xdg_mime "$1" "$filetype"
}
open_generic_xdg_x_scheme_handler()
{
scheme="`echo $1 | sed -n 's/\(^[[:alnum:]+\.-]*\):.*$/\1/p'`"
if [ -n $scheme ]; then
filetype="x-scheme-handler/$scheme"
open_generic_xdg_mime "$1" "$filetype"
fi
}
open_generic()
{
# Paths or file:// URLs
if (echo "$1" | grep -q '^file://' ||
! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:'); then
local file="$1"
# Decode URLs
if echo "$file" | grep -q '^file:///'; then
file=${file#file://}
file="$(printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')")"
fi
file_check=${file%%#*}
file_check=${file_check%%\?*}
check_input_file "$file_check"
filetype=`xdg-mime query filetype "$file_check" | sed "s/;.*//"`
open_generic_xdg_mime "$file" "$filetype"
if which run-mailcap 2>/dev/null 1>&2; then
run-mailcap --action=view "$file"
if [ $? -eq 0 ]; then
exit_success
fi
fi
if mimeopen -v 2>/dev/null 1>&2; then
mimeopen -L -n "$file"
if [ $? -eq 0 ]; then
exit_success
fi
fi
fi
open_generic_xdg_x_scheme_handler "$1"
IFS=":"
for browser in $BROWSER; do
if [ x"$browser" != x"" ]; then
browser_with_arg=`printf "$browser" "$1" 2>/dev/null`
if [ $? -ne 0 ]; then
browser_with_arg=$browser;
fi
if [ x"$browser_with_arg" = x"$browser" ]; then
eval '$browser "$1"'$xdg_redirect_output;
else eval '$browser_with_arg'$xdg_redirect_output;
fi
if [ $? -eq 0 ]; then
exit_success;
fi
fi
done
exit_failure_operation_impossible "no method available for opening '$1'"
}
open_lxde()
{
# pcmanfm only knows how to handle file:// urls and filepaths, it seems.
if (echo "$1" | grep -q '^file://' ||
! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:')
then
local file="$1"
# handle relative paths
if ! echo "$file" | egrep -q '^(file://)?/'; then
file="$(pwd)/$file"
fi
pcmanfm "$file"
else
open_generic "$1"
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
[ x"$1" != x"" ] || exit_failure_syntax
url=
while [ $# -gt 0 ] ; do
parm="$1"
shift
case "$parm" in
-*)
exit_failure_syntax "unexpected option '$parm'"
;;
*)
if [ -n "$url" ] ; then
exit_failure_syntax "unexpected argument '$parm'"
fi
url="$parm"
;;
esac
done
if [ -z "${url}" ] ; then
exit_failure_syntax "file or URL argument missing"
fi
detectDE
if [ x"$DE" = x"" ]; then
DE=generic
fi
DEBUG 2 "Selected DE $DE"
# sanitize BROWSER (avoid caling ourselves in particular)
case "${BROWSER}" in
*:"xdg-open"|"xdg-open":*)
BROWSER=$(echo $BROWSER | sed -e 's|:xdg-open||g' -e 's|xdg-open:||g')
;;
"xdg-open")
BROWSER=
;;
esac
# if BROWSER variable is not set, check some well known browsers instead
if [ x"$BROWSER" = x"" ]; then
BROWSER=links2:elinks:links:lynx:w3m
if [ -n "$DISPLAY" ]; then
BROWSER=x-www-browser:firefox:seamonkey:mozilla:epiphany:konqueror:chromium-browser:google-chrome:$BROWSER
fi
fi
case "$DE" in
kde)
open_kde "$url"
;;
gnome*)
open_gnome "$url"
;;
mate)
open_mate "$url"
;;
xfce)
open_xfce "$url"
;;
lxde)
open_lxde "$url"
;;
enlightenment)
open_enlightenment "$url"
;;
generic)
open_generic "$url"
;;
*)
exit_failure_operation_impossible "no method available for opening '$url'"
;;
esac

View File

@@ -0,0 +1,9 @@
(The MIT License)
Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me) <us@bevry.me>
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.

View File

@@ -0,0 +1,62 @@
# SafeCallback [![Build Status](https://secure.travis-ci.org/bevry/safecallback.png?branch=master)](http://travis-ci.org/bevry/safecallback)
Handle asynchronous callback errors safely and easily
## Install
### Backend
1. [Install Node.js](http://bevry.me/node/install)
1. `npm install --save safecallback`
### Frontend
1. [See Browserify](http://browserify.org/)
## Usage
### JavaScript
``` javascript
// Before
var getFileContentsUpperCased = function(path,next){
require('fs').readFile(path, function(err,data){
if(err) return next(err) // annoying check
return next(null, data.toString().toUpperCase())
})
}
// After
var safeCallback = require('safecallback')
var getFileContentsUpperCased = function(path,next){
require('fs').readFile(path, safeCallback(next, function(err,data){
return next(null, data.toString().toUpperCase())
}))
}
```
### CoffeeScript
``` coffeescript
# Before
getFileContentsUpperCased = (path,next) ->
require('fs').readFile path, (err,data) ->
return next(err) if err # annoying check
return next(null, data.toString().toUpperCase())
# After
safeCallback = require('safecallback')
getFileContentsUpperCased = (path,next) ->
require('fs').readFile path, safeCallback next, (err,data) ->
return next(null, data.toString().toUpperCase())
```
## History
You can discover the history inside the [History.md](https://github.com/bevry/safecallback/blob/master/History.md#files) file
## License
Licensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)
<br/>Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me) <us@bevry.me>

View File

@@ -0,0 +1,94 @@
{
"_args": [
[
"safecallback@~1.0.1",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util"
]
],
"_from": "safecallback@>=1.0.1 <1.1.0",
"_id": "safecallback@1.0.1",
"_inCache": true,
"_installable": true,
"_location": "/live-server/safecallback",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "1.2.15",
"_phantomChildren": {},
"_requested": {
"name": "safecallback",
"raw": "safecallback@~1.0.1",
"rawSpec": "~1.0.1",
"scope": null,
"spec": ">=1.0.1 <1.1.0",
"type": "range"
},
"_requiredBy": [
"/live-server/bal-util"
],
"_resolved": "https://registry.npmjs.org/safecallback/-/safecallback-1.0.1.tgz",
"_shasum": "07c7f12b4a8d9abf1b8fcddba7852eb0b8b6ed41",
"_shrinkwrap": null,
"_spec": "safecallback@~1.0.1",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util",
"author": {
"email": "us@bevry.me",
"name": "Bevry Pty Ltd",
"url": "http://bevry.me"
},
"bin": {},
"bugs": {
"url": "https://github.com/bevry/safecallback/issues"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "https://github.com/balupton"
}
],
"dependencies": {},
"description": "Handle callback errors safely and easily",
"devDependencies": {
"chai": "~1.5.0",
"joe": "~1.1.2"
},
"directories": {
"lib": "./lib"
},
"dist": {
"shasum": "07c7f12b4a8d9abf1b8fcddba7852eb0b8b6ed41",
"tarball": "https://registry.npmjs.org/safecallback/-/safecallback-1.0.1.tgz"
},
"engines": {
"node": ">=0.4"
},
"homepage": "https://github.com/bevry/safecallback",
"keywords": [
"callback",
"flow",
"async",
"errors",
"error"
],
"main": "./lib/safecallback.js",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "safecallback",
"optionalDependencies": {},
"readme": "# SafeCallback [![Build Status](https://secure.travis-ci.org/bevry/safecallback.png?branch=master)](http://travis-ci.org/bevry/safecallback)\n\nHandle asynchronous callback errors safely and easily\n\n## Install\n\n### Backend\n\n1. [Install Node.js](http://bevry.me/node/install)\n1. `npm install --save safecallback`\n\n### Frontend\n\n1. [See Browserify](http://browserify.org/)\n\n\n## Usage\n\n### JavaScript\n\n``` javascript\n// Before\nvar getFileContentsUpperCased = function(path,next){\n\trequire('fs').readFile(path, function(err,data){\n\t\tif(err) return next(err) // annoying check\n\t\treturn next(null, data.toString().toUpperCase())\n\t})\n}\n\n// After\nvar safeCallback = require('safecallback')\nvar getFileContentsUpperCased = function(path,next){\n\trequire('fs').readFile(path, safeCallback(next, function(err,data){\n\t\treturn next(null, data.toString().toUpperCase())\n\t}))\n}\n```\n\n### CoffeeScript\n\n``` coffeescript\n# Before\ngetFileContentsUpperCased = (path,next) ->\n\trequire('fs').readFile path, (err,data) ->\n\t\treturn next(err) if err # annoying check\n\t\treturn next(null, data.toString().toUpperCase())\n\n# After\nsafeCallback = require('safecallback')\ngetFileContentsUpperCased = (path,next) ->\n\trequire('fs').readFile path, safeCallback next, (err,data) ->\n\t\treturn next(null, data.toString().toUpperCase())\n```\n\n\n## History\nYou can discover the history inside the [History.md](https://github.com/bevry/safecallback/blob/master/History.md#files) file\n\n\n## License\nLicensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)\n<br/>Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me) <us@bevry.me>",
"readmeFilename": "README.md",
"repository": {
"type": "git",
"url": "git+https://github.com/bevry/safecallback.git"
},
"scripts": {
"test": "node ./test/everything-test.js"
},
"version": "1.0.1"
}

View File

@@ -0,0 +1,10 @@
(The MIT License)
Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me) <us@bevry.me>
Copyright © 2011-2012 [Benjamin Lupton](http://balupton.com) <b@lupton.cc>
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.

View File

@@ -0,0 +1,96 @@
# Safe FS [![Build Status](https://secure.travis-ci.org/bevry/safefs.png?branch=master)](http://travis-ci.org/bevry/safefs)
Say goodbye to EMFILE errors! Open only as many files as the operating system supports
## Install
### Backend
1. [Install Node.js](http://bevry.me/node/install)
2. `npm install --save safefs`
### Frontend
1. [See Browserify](http://browserify.org)
## Usage
### Example
``` javascript
// Import
var safefs = require('safefs');
// Indicate we're wanting to open a file and reserve our space in the queue
// If there is space in the pool, our callback will run right away
// If there isn't space, our callback will fire as soon as there is
safefs.openFile(function(){
// We just got some available space, lets do our stuff with the file
require('fs').writeFileSync('some-file', 'data')
// Once we're done, indicate it, so that other tasks can swim in the pool too
safefs.closeFile();
});
// If we're working with an asynchronous function, it'll look like this
safefs.openFile(function(){
require('fs').writeFile('some-file', 'data', function(err){
safefs.closeFile();
});
});
// as we only want to close file once we are completely done with it
// However, that's pretty annoying have to wrap all our calls in openFile and closeFile
// so it's a good thing that safefs provides wrappers for all the asynchronous fs methods for us
// allowing us to just do
safefs.writeFile('some-file', 'data', function(err){
// all done
});
// which will open and close the spot in the pool for us automatically, yay!
```
### Methods
Arguments suffixed with `?` are optional.
- Custom methods:
- `openFile(next)`
- `closeFile()`
- `getParentPathSync(path)`
- `ensurePath(path, options?, next)` - will attempt to ensure the path exists, options:
- `mode` - defaults to `null`
- Wrapped fs/path methods:
- `readFile(path, options?, next)`
- `writeFile(path, data, options?, next)` - will also attempt to ensure the path exists
- `appendFile(path, data, options?, next)` - will also attempt to ensure the path exists
- `mkdir(path, mode?, next)` - mode defaults to `0o777 & (~process.umask())`
- `stat(path, next)`
- `readdir(path, next)`
- `unlink(path, next)`
- `rmdir(path, next)`
- `exists(path, next)`
- `existsSync(path)`
### Notes
- You should call `openFile` before and `afterFile` after ALL file system interaction
- To make this possible, we maintain the following globals:
- `numberOfOpenFiles` - defaults to `0`
- `maxNumberOfOpenFiles` - defaults to `process.env.NODE_MAX_OPEN_FILES` if available, otherwise sets to `100`
- `waitingToOpenFileDelay` - defaults to `100`
## History
You can discover the history inside the [History.md](https://github.com/bevry/safefs/blob/master/History.md#files) file
## License
Licensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)
<br/>Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me)
<br/>Copyright © 2011-2012 [Benjamin Arthur Lupton](http://balupton.com)

View File

@@ -0,0 +1,94 @@
{
"_args": [
[
"safefs@~2.0.3",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util"
]
],
"_from": "safefs@>=2.0.3 <2.1.0",
"_id": "safefs@2.0.3",
"_inCache": true,
"_installable": true,
"_location": "/live-server/safefs",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "1.2.15",
"_phantomChildren": {},
"_requested": {
"name": "safefs",
"raw": "safefs@~2.0.3",
"rawSpec": "~2.0.3",
"scope": null,
"spec": ">=2.0.3 <2.1.0",
"type": "range"
},
"_requiredBy": [
"/live-server/bal-util"
],
"_resolved": "https://registry.npmjs.org/safefs/-/safefs-2.0.3.tgz",
"_shasum": "2db2b2de4c4161d6dba6609fee05ecab062c4de5",
"_shrinkwrap": null,
"_spec": "safefs@~2.0.3",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util",
"author": {
"email": "us@bevry.me",
"name": "Bevry Pty Ltd",
"url": "http://bevry.me"
},
"bugs": {
"url": "https://github.com/bevry/safefs/issues"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "https://github.com/balupton"
}
],
"dependencies": {},
"description": "Say goodbye to EMFILE errors! Open only as many files as the operating system supports",
"devDependencies": {
"chai": "~1.5.0",
"coffee-script": "~1.6.2",
"joe": "~1.1.2",
"taskgroup": "~2.0.0"
},
"directories": {
"lib": "./out/lib"
},
"dist": {
"shasum": "2db2b2de4c4161d6dba6609fee05ecab062c4de5",
"tarball": "https://registry.npmjs.org/safefs/-/safefs-2.0.3.tgz"
},
"engines": {
"node": ">=0.4"
},
"homepage": "https://github.com/bevry/safefs",
"keywords": [
"fs",
"path",
"openFile",
"closeFile",
"emfile"
],
"main": "./out/lib/safefs.js",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "safefs",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/bevry/safefs.git"
},
"scripts": {
"test": "node ./out/test/safefs-test.js"
},
"version": "2.0.3"
}

View File

@@ -0,0 +1,315 @@
0.13.2 / 2016-03-05
===================
* Fix invalid `Content-Type` header when `send.mime.default_type` unset
0.13.1 / 2016-01-16
===================
* deps: depd@~1.1.0
- Support web browser loading
- perf: enable strict mode
* deps: destroy@~1.0.4
- perf: enable strict mode
* deps: escape-html@~1.0.3
- perf: enable strict mode
- perf: optimize string replacement
- perf: use faster string coercion
* deps: range-parser@~1.0.3
- perf: enable strict mode
0.13.0 / 2015-06-16
===================
* Allow Node.js HTTP server to set `Date` response header
* Fix incorrectly removing `Content-Location` on 304 response
* Improve the default redirect response headers
* Send appropriate headers on default error response
* Use `http-errors` for standard emitted errors
* Use `statuses` instead of `http` module for status messages
* deps: escape-html@1.0.2
* deps: etag@~1.7.0
- Improve stat performance by removing hashing
* deps: fresh@0.3.0
- Add weak `ETag` matching support
* deps: on-finished@~2.3.0
- Add defined behavior for HTTP `CONNECT` requests
- Add defined behavior for HTTP `Upgrade` requests
- deps: ee-first@1.1.1
* perf: enable strict mode
* perf: remove unnecessary array allocations
0.12.3 / 2015-05-13
===================
* deps: debug@~2.2.0
- deps: ms@0.7.1
* deps: depd@~1.0.1
* deps: etag@~1.6.0
- Improve support for JXcore
- Support "fake" stats objects in environments without `fs`
* deps: ms@0.7.1
- Prevent extraordinarily long inputs
* deps: on-finished@~2.2.1
0.12.2 / 2015-03-13
===================
* Throw errors early for invalid `extensions` or `index` options
* deps: debug@~2.1.3
- Fix high intensity foreground color for bold
- deps: ms@0.7.0
0.12.1 / 2015-02-17
===================
* Fix regression sending zero-length files
0.12.0 / 2015-02-16
===================
* Always read the stat size from the file
* Fix mutating passed-in `options`
* deps: mime@1.3.4
0.11.1 / 2015-01-20
===================
* Fix `root` path disclosure
0.11.0 / 2015-01-05
===================
* deps: debug@~2.1.1
* deps: etag@~1.5.1
- deps: crc@3.2.1
* deps: ms@0.7.0
- Add `milliseconds`
- Add `msecs`
- Add `secs`
- Add `mins`
- Add `hrs`
- Add `yrs`
* deps: on-finished@~2.2.0
0.10.1 / 2014-10-22
===================
* deps: on-finished@~2.1.1
- Fix handling of pipelined requests
0.10.0 / 2014-10-15
===================
* deps: debug@~2.1.0
- Implement `DEBUG_FD` env variable support
* deps: depd@~1.0.0
* deps: etag@~1.5.0
- Improve string performance
- Slightly improve speed for weak ETags over 1KB
0.9.3 / 2014-09-24
==================
* deps: etag@~1.4.0
- Support "fake" stats objects
0.9.2 / 2014-09-15
==================
* deps: depd@0.4.5
* deps: etag@~1.3.1
* deps: range-parser@~1.0.2
0.9.1 / 2014-09-07
==================
* deps: fresh@0.2.4
0.9.0 / 2014-09-07
==================
* Add `lastModified` option
* Use `etag` to generate `ETag` header
* deps: debug@~2.0.0
0.8.5 / 2014-09-04
==================
* Fix malicious path detection for empty string path
0.8.4 / 2014-09-04
==================
* Fix a path traversal issue when using `root`
0.8.3 / 2014-08-16
==================
* deps: destroy@1.0.3
- renamed from dethroy
* deps: on-finished@2.1.0
0.8.2 / 2014-08-14
==================
* Work around `fd` leak in Node.js 0.10 for `fs.ReadStream`
* deps: dethroy@1.0.2
0.8.1 / 2014-08-05
==================
* Fix `extensions` behavior when file already has extension
0.8.0 / 2014-08-05
==================
* Add `extensions` option
0.7.4 / 2014-08-04
==================
* Fix serving index files without root dir
0.7.3 / 2014-07-29
==================
* Fix incorrect 403 on Windows and Node.js 0.11
0.7.2 / 2014-07-27
==================
* deps: depd@0.4.4
- Work-around v8 generating empty stack traces
0.7.1 / 2014-07-26
==================
* deps: depd@0.4.3
- Fix exception when global `Error.stackTraceLimit` is too low
0.7.0 / 2014-07-20
==================
* Deprecate `hidden` option; use `dotfiles` option
* Add `dotfiles` option
* deps: debug@1.0.4
* deps: depd@0.4.2
- Add `TRACE_DEPRECATION` environment variable
- Remove non-standard grey color from color output
- Support `--no-deprecation` argument
- Support `--trace-deprecation` argument
0.6.0 / 2014-07-11
==================
* Deprecate `from` option; use `root` option
* Deprecate `send.etag()` -- use `etag` in `options`
* Deprecate `send.hidden()` -- use `hidden` in `options`
* Deprecate `send.index()` -- use `index` in `options`
* Deprecate `send.maxage()` -- use `maxAge` in `options`
* Deprecate `send.root()` -- use `root` in `options`
* Cap `maxAge` value to 1 year
* deps: debug@1.0.3
- Add support for multiple wildcards in namespaces
0.5.0 / 2014-06-28
==================
* Accept string for `maxAge` (converted by `ms`)
* Add `headers` event
* Include link in default redirect response
* Use `EventEmitter.listenerCount` to count listeners
0.4.3 / 2014-06-11
==================
* Do not throw un-catchable error on file open race condition
* Use `escape-html` for HTML escaping
* deps: debug@1.0.2
- fix some debugging output colors on node.js 0.8
* deps: finished@1.2.2
* deps: fresh@0.2.2
0.4.2 / 2014-06-09
==================
* fix "event emitter leak" warnings
* deps: debug@1.0.1
* deps: finished@1.2.1
0.4.1 / 2014-06-02
==================
* Send `max-age` in `Cache-Control` in correct format
0.4.0 / 2014-05-27
==================
* Calculate ETag with md5 for reduced collisions
* Fix wrong behavior when index file matches directory
* Ignore stream errors after request ends
- Goodbye `EBADF, read`
* Skip directories in index file search
* deps: debug@0.8.1
0.3.0 / 2014-04-24
==================
* Fix sending files with dots without root set
* Coerce option types
* Accept API options in options object
* Set etags to "weak"
* Include file path in etag
* Make "Can't set headers after they are sent." catchable
* Send full entity-body for multi range requests
* Default directory access to 403 when index disabled
* Support multiple index paths
* Support "If-Range" header
* Control whether to generate etags
* deps: mime@1.2.11
0.2.0 / 2014-01-29
==================
* update range-parser and fresh
0.1.4 / 2013-08-11
==================
* update fresh
0.1.3 / 2013-07-08
==================
* Revert "Fix fd leak"
0.1.2 / 2013-07-03
==================
* Fix fd leak
0.1.0 / 2012-08-25
==================
* add options parameter to send() that is passed to fs.createReadStream() [kanongil]
0.0.4 / 2012-08-16
==================
* allow custom "Accept-Ranges" definition
0.0.3 / 2012-07-16
==================
* fix normalization of the root directory. Closes #3
0.0.2 / 2012-07-09
==================
* add passing of req explicitly for now (YUCK)
0.0.1 / 2010-01-03
==================
* Initial release

View File

@@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2012 TJ Holowaychuk
Copyright (c) 2014-2015 Douglas Christopher Wilson
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.

View File

@@ -0,0 +1,234 @@
# send
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Linux Build][travis-image]][travis-url]
[![Windows Build][appveyor-image]][appveyor-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![Gratipay][gratipay-image]][gratipay-url]
Send is a library for streaming files from the file system as a http response
supporting partial responses (Ranges), conditional-GET negotiation, high test
coverage, and granular events which may be leveraged to take appropriate actions
in your application or framework.
Looking to serve up entire folders mapped to URLs? Try [serve-static](https://www.npmjs.org/package/serve-static).
## Installation
```bash
$ npm install send
```
## API
```js
var send = require('send')
```
### send(req, path, [options])
Create a new `SendStream` for the given path to send to a `res`. The `req` is
the Node.js HTTP request and the `path` is a urlencoded path to send (urlencoded,
not the actual file-system path).
#### Options
##### dotfiles
Set how "dotfiles" are treated when encountered. A dotfile is a file
or directory that begins with a dot ("."). Note this check is done on
the path itself without checking if the path actually exists on the
disk. If `root` is specified, only the dotfiles above the root are
checked (i.e. the root itself can be within a dotfile when when set
to "deny").
- `'allow'` No special treatment for dotfiles.
- `'deny'` Send a 403 for any request for a dotfile.
- `'ignore'` Pretend like the dotfile does not exist and 404.
The default value is _similar_ to `'ignore'`, with the exception that
this default will not ignore the files within a directory that begins
with a dot, for backward-compatibility.
##### end
Byte offset at which the stream ends, defaults to the length of the file
minus 1. The end is inclusive in the stream, meaning `end: 3` will include
the 4th byte in the stream.
##### etag
Enable or disable etag generation, defaults to true.
##### extensions
If a given file doesn't exist, try appending one of the given extensions,
in the given order. By default, this is disabled (set to `false`). An
example value that will serve extension-less HTML files: `['html', 'htm']`.
This is skipped if the requested file already has an extension.
##### index
By default send supports "index.html" files, to disable this
set `false` or to supply a new index pass a string or an array
in preferred order.
##### lastModified
Enable or disable `Last-Modified` header, defaults to true. Uses the file
system's last modified value.
##### maxAge
Provide a max-age in milliseconds for http caching, defaults to 0.
This can also be a string accepted by the
[ms](https://www.npmjs.org/package/ms#readme) module.
##### root
Serve files relative to `path`.
##### start
Byte offset at which the stream starts, defaults to 0. The start is inclusive,
meaning `start: 2` will include the 3rd byte in the stream.
#### Events
The `SendStream` is an event emitter and will emit the following events:
- `error` an error occurred `(err)`
- `directory` a directory was requested
- `file` a file was requested `(path, stat)`
- `headers` the headers are about to be set on a file `(res, path, stat)`
- `stream` file streaming has started `(stream)`
- `end` streaming has completed
#### .pipe
The `pipe` method is used to pipe the response into the Node.js HTTP response
object, typically `send(req, path, options).pipe(res)`.
### .mime
The `mime` export is the global instance of of the
[`mime` npm module](https://www.npmjs.com/package/mime).
This is used to configure the MIME types that are associated with file extensions
as well as other options for how to resolve the MIME type of a file (like the
default type to use for an unknown file extension).
## Error-handling
By default when no `error` listeners are present an automatic response will be
made, otherwise you have full control over the response, aka you may show a 5xx
page etc.
## Caching
It does _not_ perform internal caching, you should use a reverse proxy cache
such as Varnish for this, or those fancy things called CDNs. If your
application is small enough that it would benefit from single-node memory
caching, it's small enough that it does not need caching at all ;).
## Debugging
To enable `debug()` instrumentation output export __DEBUG__:
```
$ DEBUG=send node app
```
## Running tests
```
$ npm install
$ npm test
```
## Examples
### Small example
```js
var http = require('http');
var send = require('send');
var app = http.createServer(function(req, res){
send(req, req.url).pipe(res);
}).listen(3000);
```
### Custom file types
```js
var http = require('http');
var send = require('send');
// Default unknown types to text/plain
send.mime.default_type = 'text/plain';
// Add a custom type
send.mime.define({
'application/x-my-type': ['x-mt', 'x-mtt']
});
var app = http.createServer(function(req, res){
send(req, req.url).pipe(res);
}).listen(3000);
```
### Serving from a root directory with custom error-handling
```js
var http = require('http');
var send = require('send');
var url = require('url');
var app = http.createServer(function(req, res){
// your custom error-handling logic:
function error(err) {
res.statusCode = err.status || 500;
res.end(err.message);
}
// your custom headers
function headers(res, path, stat) {
// serve all files for download
res.setHeader('Content-Disposition', 'attachment');
}
// your custom directory handling logic:
function redirect() {
res.statusCode = 301;
res.setHeader('Location', req.url + '/');
res.end('Redirecting to ' + req.url + '/');
}
// transfer arbitrary files from within
// /www/example.com/public/*
send(req, url.parse(req.url).pathname, {root: '/www/example.com/public'})
.on('error', error)
.on('directory', redirect)
.on('headers', headers)
.pipe(res);
}).listen(3000);
```
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/send.svg
[npm-url]: https://npmjs.org/package/send
[travis-image]: https://img.shields.io/travis/pillarjs/send/master.svg?label=linux
[travis-url]: https://travis-ci.org/pillarjs/send
[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/send/master.svg?label=windows
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/send
[coveralls-image]: https://img.shields.io/coveralls/pillarjs/send/master.svg
[coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master
[downloads-image]: https://img.shields.io/npm/dm/send.svg
[downloads-url]: https://npmjs.org/package/send
[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
[gratipay-url]: https://www.gratipay.com/dougwilson/

View File

@@ -0,0 +1,829 @@
/*!
* send
* Copyright(c) 2012 TJ Holowaychuk
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var createError = require('http-errors')
var debug = require('debug')('send')
var deprecate = require('depd')('send')
var destroy = require('destroy')
var escapeHtml = require('escape-html')
, parseRange = require('range-parser')
, Stream = require('stream')
, mime = require('mime')
, fresh = require('fresh')
, path = require('path')
, fs = require('fs')
, normalize = path.normalize
, join = path.join
var etag = require('etag')
var EventEmitter = require('events').EventEmitter;
var ms = require('ms');
var onFinished = require('on-finished')
var statuses = require('statuses')
/**
* Variables.
*/
var extname = path.extname
var maxMaxAge = 60 * 60 * 24 * 365 * 1000; // 1 year
var resolve = path.resolve
var sep = path.sep
var toString = Object.prototype.toString
var upPathRegexp = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/
/**
* Module exports.
* @public
*/
module.exports = send
module.exports.mime = mime
/**
* Shim EventEmitter.listenerCount for node.js < 0.10
*/
/* istanbul ignore next */
var listenerCount = EventEmitter.listenerCount
|| function(emitter, type){ return emitter.listeners(type).length; };
/**
* Return a `SendStream` for `req` and `path`.
*
* @param {object} req
* @param {string} path
* @param {object} [options]
* @return {SendStream}
* @public
*/
function send(req, path, options) {
return new SendStream(req, path, options);
}
/**
* Initialize a `SendStream` with the given `path`.
*
* @param {Request} req
* @param {String} path
* @param {object} [options]
* @private
*/
function SendStream(req, path, options) {
var opts = options || {}
this.options = opts
this.path = path
this.req = req
this._etag = opts.etag !== undefined
? Boolean(opts.etag)
: true
this._dotfiles = opts.dotfiles !== undefined
? opts.dotfiles
: 'ignore'
if (this._dotfiles !== 'ignore' && this._dotfiles !== 'allow' && this._dotfiles !== 'deny') {
throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"')
}
this._hidden = Boolean(opts.hidden)
if (opts.hidden !== undefined) {
deprecate('hidden: use dotfiles: \'' + (this._hidden ? 'allow' : 'ignore') + '\' instead')
}
// legacy support
if (opts.dotfiles === undefined) {
this._dotfiles = undefined
}
this._extensions = opts.extensions !== undefined
? normalizeList(opts.extensions, 'extensions option')
: []
this._index = opts.index !== undefined
? normalizeList(opts.index, 'index option')
: ['index.html']
this._lastModified = opts.lastModified !== undefined
? Boolean(opts.lastModified)
: true
this._maxage = opts.maxAge || opts.maxage
this._maxage = typeof this._maxage === 'string'
? ms(this._maxage)
: Number(this._maxage)
this._maxage = !isNaN(this._maxage)
? Math.min(Math.max(0, this._maxage), maxMaxAge)
: 0
this._root = opts.root
? resolve(opts.root)
: null
if (!this._root && opts.from) {
this.from(opts.from)
}
}
/**
* Inherits from `Stream.prototype`.
*/
SendStream.prototype.__proto__ = Stream.prototype;
/**
* Enable or disable etag generation.
*
* @param {Boolean} val
* @return {SendStream}
* @api public
*/
SendStream.prototype.etag = deprecate.function(function etag(val) {
val = Boolean(val);
debug('etag %s', val);
this._etag = val;
return this;
}, 'send.etag: pass etag as option');
/**
* Enable or disable "hidden" (dot) files.
*
* @param {Boolean} path
* @return {SendStream}
* @api public
*/
SendStream.prototype.hidden = deprecate.function(function hidden(val) {
val = Boolean(val);
debug('hidden %s', val);
this._hidden = val;
this._dotfiles = undefined
return this;
}, 'send.hidden: use dotfiles option');
/**
* Set index `paths`, set to a falsy
* value to disable index support.
*
* @param {String|Boolean|Array} paths
* @return {SendStream}
* @api public
*/
SendStream.prototype.index = deprecate.function(function index(paths) {
var index = !paths ? [] : normalizeList(paths, 'paths argument');
debug('index %o', paths);
this._index = index;
return this;
}, 'send.index: pass index as option');
/**
* Set root `path`.
*
* @param {String} path
* @return {SendStream}
* @api public
*/
SendStream.prototype.root = function(path){
path = String(path);
this._root = resolve(path)
return this;
};
SendStream.prototype.from = deprecate.function(SendStream.prototype.root,
'send.from: pass root as option');
SendStream.prototype.root = deprecate.function(SendStream.prototype.root,
'send.root: pass root as option');
/**
* Set max-age to `maxAge`.
*
* @param {Number} maxAge
* @return {SendStream}
* @api public
*/
SendStream.prototype.maxage = deprecate.function(function maxage(maxAge) {
maxAge = typeof maxAge === 'string'
? ms(maxAge)
: Number(maxAge);
if (isNaN(maxAge)) maxAge = 0;
if (Infinity == maxAge) maxAge = 60 * 60 * 24 * 365 * 1000;
debug('max-age %d', maxAge);
this._maxage = maxAge;
return this;
}, 'send.maxage: pass maxAge as option');
/**
* Emit error with `status`.
*
* @param {number} status
* @param {Error} [error]
* @private
*/
SendStream.prototype.error = function error(status, error) {
// emit if listeners instead of responding
if (listenerCount(this, 'error') !== 0) {
return this.emit('error', createError(error, status, {
expose: false
}))
}
var res = this.res
var msg = statuses[status]
// wipe all existing headers
res._headers = null
// send basic response
res.statusCode = status
res.setHeader('Content-Type', 'text/plain; charset=UTF-8')
res.setHeader('Content-Length', Buffer.byteLength(msg))
res.setHeader('X-Content-Type-Options', 'nosniff')
res.end(msg)
}
/**
* Check if the pathname ends with "/".
*
* @return {Boolean}
* @api private
*/
SendStream.prototype.hasTrailingSlash = function(){
return '/' == this.path[this.path.length - 1];
};
/**
* Check if this is a conditional GET request.
*
* @return {Boolean}
* @api private
*/
SendStream.prototype.isConditionalGET = function(){
return this.req.headers['if-none-match']
|| this.req.headers['if-modified-since'];
};
/**
* Strip content-* header fields.
*
* @private
*/
SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields() {
var res = this.res
var headers = Object.keys(res._headers || {})
for (var i = 0; i < headers.length; i++) {
var header = headers[i]
if (header.substr(0, 8) === 'content-' && header !== 'content-location') {
res.removeHeader(header)
}
}
}
/**
* Respond with 304 not modified.
*
* @api private
*/
SendStream.prototype.notModified = function(){
var res = this.res;
debug('not modified');
this.removeContentHeaderFields();
res.statusCode = 304;
res.end();
};
/**
* Raise error that headers already sent.
*
* @api private
*/
SendStream.prototype.headersAlreadySent = function headersAlreadySent(){
var err = new Error('Can\'t set headers after they are sent.');
debug('headers already sent');
this.error(500, err);
};
/**
* Check if the request is cacheable, aka
* responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}).
*
* @return {Boolean}
* @api private
*/
SendStream.prototype.isCachable = function(){
var res = this.res;
return (res.statusCode >= 200 && res.statusCode < 300) || 304 == res.statusCode;
};
/**
* Handle stat() error.
*
* @param {Error} error
* @private
*/
SendStream.prototype.onStatError = function onStatError(error) {
switch (error.code) {
case 'ENAMETOOLONG':
case 'ENOENT':
case 'ENOTDIR':
this.error(404, error)
break
default:
this.error(500, error)
break
}
}
/**
* Check if the cache is fresh.
*
* @return {Boolean}
* @api private
*/
SendStream.prototype.isFresh = function(){
return fresh(this.req.headers, this.res._headers);
};
/**
* Check if the range is fresh.
*
* @return {Boolean}
* @api private
*/
SendStream.prototype.isRangeFresh = function isRangeFresh(){
var ifRange = this.req.headers['if-range'];
if (!ifRange) return true;
return ~ifRange.indexOf('"')
? ~ifRange.indexOf(this.res._headers['etag'])
: Date.parse(this.res._headers['last-modified']) <= Date.parse(ifRange);
};
/**
* Redirect to path.
*
* @param {string} path
* @private
*/
SendStream.prototype.redirect = function redirect(path) {
if (listenerCount(this, 'directory') !== 0) {
this.emit('directory')
return
}
if (this.hasTrailingSlash()) {
this.error(403)
return
}
var loc = path + '/'
var msg = 'Redirecting to <a href="' + escapeHtml(loc) + '">' + escapeHtml(loc) + '</a>\n'
var res = this.res
// redirect
res.statusCode = 301
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
res.setHeader('Content-Length', Buffer.byteLength(msg))
res.setHeader('X-Content-Type-Options', 'nosniff')
res.setHeader('Location', loc)
res.end(msg)
}
/**
* Pipe to `res.
*
* @param {Stream} res
* @return {Stream} res
* @api public
*/
SendStream.prototype.pipe = function(res){
var self = this
, args = arguments
, root = this._root;
// references
this.res = res;
// decode the path
var path = decode(this.path)
if (path === -1) return this.error(400)
// null byte(s)
if (~path.indexOf('\0')) return this.error(400);
var parts
if (root !== null) {
// malicious path
if (upPathRegexp.test(normalize('.' + sep + path))) {
debug('malicious path "%s"', path)
return this.error(403)
}
// join / normalize from optional root dir
path = normalize(join(root, path))
root = normalize(root + sep)
// explode path parts
parts = path.substr(root.length).split(sep)
} else {
// ".." is malicious without "root"
if (upPathRegexp.test(path)) {
debug('malicious path "%s"', path)
return this.error(403)
}
// explode path parts
parts = normalize(path).split(sep)
// resolve the path
path = resolve(path)
}
// dotfile handling
if (containsDotFile(parts)) {
var access = this._dotfiles
// legacy support
if (access === undefined) {
access = parts[parts.length - 1][0] === '.'
? (this._hidden ? 'allow' : 'ignore')
: 'allow'
}
debug('%s dotfile "%s"', access, path)
switch (access) {
case 'allow':
break
case 'deny':
return this.error(403)
case 'ignore':
default:
return this.error(404)
}
}
// index file support
if (this._index.length && this.path[this.path.length - 1] === '/') {
this.sendIndex(path);
return res;
}
this.sendFile(path);
return res;
};
/**
* Transfer `path`.
*
* @param {String} path
* @api public
*/
SendStream.prototype.send = function(path, stat){
var len = stat.size;
var options = this.options
var opts = {}
var res = this.res;
var req = this.req;
var ranges = req.headers.range;
var offset = options.start || 0;
if (res._header) {
// impossible to send now
return this.headersAlreadySent();
}
debug('pipe "%s"', path)
// set header fields
this.setHeader(path, stat);
// set content-type
this.type(path);
// conditional GET support
if (this.isConditionalGET()
&& this.isCachable()
&& this.isFresh()) {
return this.notModified();
}
// adjust len to start/end options
len = Math.max(0, len - offset);
if (options.end !== undefined) {
var bytes = options.end - offset + 1;
if (len > bytes) len = bytes;
}
// Range support
if (ranges) {
ranges = parseRange(len, ranges);
// If-Range support
if (!this.isRangeFresh()) {
debug('range stale');
ranges = -2;
}
// unsatisfiable
if (-1 == ranges) {
debug('range unsatisfiable');
res.setHeader('Content-Range', 'bytes */' + stat.size);
return this.error(416);
}
// valid (syntactically invalid/multiple ranges are treated as a regular response)
if (-2 != ranges && ranges.length === 1) {
debug('range %j', ranges);
// Content-Range
res.statusCode = 206;
res.setHeader('Content-Range', 'bytes '
+ ranges[0].start
+ '-'
+ ranges[0].end
+ '/'
+ len);
offset += ranges[0].start;
len = ranges[0].end - ranges[0].start + 1;
}
}
// clone options
for (var prop in options) {
opts[prop] = options[prop]
}
// set read options
opts.start = offset
opts.end = Math.max(offset, offset + len - 1)
// content-length
res.setHeader('Content-Length', len);
// HEAD support
if ('HEAD' == req.method) return res.end();
this.stream(path, opts)
};
/**
* Transfer file for `path`.
*
* @param {String} path
* @api private
*/
SendStream.prototype.sendFile = function sendFile(path) {
var i = 0
var self = this
debug('stat "%s"', path);
fs.stat(path, function onstat(err, stat) {
if (err && err.code === 'ENOENT'
&& !extname(path)
&& path[path.length - 1] !== sep) {
// not found, check extensions
return next(err)
}
if (err) return self.onStatError(err)
if (stat.isDirectory()) return self.redirect(self.path)
self.emit('file', path, stat)
self.send(path, stat)
})
function next(err) {
if (self._extensions.length <= i) {
return err
? self.onStatError(err)
: self.error(404)
}
var p = path + '.' + self._extensions[i++]
debug('stat "%s"', p)
fs.stat(p, function (err, stat) {
if (err) return next(err)
if (stat.isDirectory()) return next()
self.emit('file', p, stat)
self.send(p, stat)
})
}
}
/**
* Transfer index for `path`.
*
* @param {String} path
* @api private
*/
SendStream.prototype.sendIndex = function sendIndex(path){
var i = -1;
var self = this;
function next(err){
if (++i >= self._index.length) {
if (err) return self.onStatError(err);
return self.error(404);
}
var p = join(path, self._index[i]);
debug('stat "%s"', p);
fs.stat(p, function(err, stat){
if (err) return next(err);
if (stat.isDirectory()) return next();
self.emit('file', p, stat);
self.send(p, stat);
});
}
next();
};
/**
* Stream `path` to the response.
*
* @param {String} path
* @param {Object} options
* @api private
*/
SendStream.prototype.stream = function(path, options){
// TODO: this is all lame, refactor meeee
var finished = false;
var self = this;
var res = this.res;
var req = this.req;
// pipe
var stream = fs.createReadStream(path, options);
this.emit('stream', stream);
stream.pipe(res);
// response finished, done with the fd
onFinished(res, function onfinished(){
finished = true;
destroy(stream);
});
// error handling code-smell
stream.on('error', function onerror(err){
// request already finished
if (finished) return;
// clean up stream
finished = true;
destroy(stream);
// error
self.onStatError(err);
});
// end
stream.on('end', function onend(){
self.emit('end');
});
};
/**
* Set content-type based on `path`
* if it hasn't been explicitly set.
*
* @param {String} path
* @api private
*/
SendStream.prototype.type = function type(path) {
var res = this.res;
if (res.getHeader('Content-Type')) return;
var type = mime.lookup(path);
if (!type) {
debug('no content-type');
return;
}
var charset = mime.charsets.lookup(type);
debug('content-type %s', type);
res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : ''));
};
/**
* Set response header fields, most
* fields may be pre-defined.
*
* @param {String} path
* @param {Object} stat
* @api private
*/
SendStream.prototype.setHeader = function setHeader(path, stat){
var res = this.res;
this.emit('headers', res, path, stat);
if (!res.getHeader('Accept-Ranges')) res.setHeader('Accept-Ranges', 'bytes');
if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + Math.floor(this._maxage / 1000));
if (this._lastModified && !res.getHeader('Last-Modified')) {
var modified = stat.mtime.toUTCString()
debug('modified %s', modified)
res.setHeader('Last-Modified', modified)
}
if (this._etag && !res.getHeader('ETag')) {
var val = etag(stat)
debug('etag %s', val)
res.setHeader('ETag', val)
}
};
/**
* Determine if path parts contain a dotfile.
*
* @api private
*/
function containsDotFile(parts) {
for (var i = 0; i < parts.length; i++) {
if (parts[i][0] === '.') {
return true
}
}
return false
}
/**
* decodeURIComponent.
*
* Allows V8 to only deoptimize this fn instead of all
* of send().
*
* @param {String} path
* @api private
*/
function decode(path) {
try {
return decodeURIComponent(path)
} catch (err) {
return -1
}
}
/**
* Normalize the index option into an array.
*
* @param {boolean|string|array} val
* @param {string} name
* @private
*/
function normalizeList(val, name) {
var list = [].concat(val || [])
for (var i = 0; i < list.length; i++) {
if (typeof list[i] !== 'string') {
throw new TypeError(name + ' must be array of strings or false')
}
}
return list
}

View File

@@ -0,0 +1,114 @@
{
"_args": [
[
"send@latest",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server"
]
],
"_from": "send@latest",
"_id": "send@0.13.2",
"_inCache": true,
"_installable": true,
"_location": "/live-server/send",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/send-0.13.2.tgz_1457238386348_0.8199156709015369"
},
"_npmUser": {
"email": "doug@somethingdoug.com",
"name": "dougwilson"
},
"_npmVersion": "1.4.28",
"_phantomChildren": {},
"_requested": {
"name": "send",
"raw": "send@latest",
"rawSpec": "latest",
"scope": null,
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"/live-server"
],
"_resolved": "https://registry.npmjs.org/send/-/send-0.13.2.tgz",
"_shasum": "765e7607c8055452bba6f0b052595350986036de",
"_shrinkwrap": null,
"_spec": "send@latest",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server",
"author": {
"email": "tj@vision-media.ca",
"name": "TJ Holowaychuk"
},
"bugs": {
"url": "https://github.com/pillarjs/send/issues"
},
"contributors": [
{
"email": "doug@somethingdoug.com",
"name": "Douglas Christopher Wilson"
}
],
"dependencies": {
"debug": "~2.2.0",
"depd": "~1.1.0",
"destroy": "~1.0.4",
"escape-html": "~1.0.3",
"etag": "~1.7.0",
"fresh": "0.3.0",
"http-errors": "~1.3.1",
"mime": "1.3.4",
"ms": "0.7.1",
"on-finished": "~2.3.0",
"range-parser": "~1.0.3",
"statuses": "~1.2.1"
},
"description": "Better streaming static file server with Range and conditional-GET support",
"devDependencies": {
"after": "0.8.1",
"istanbul": "0.4.2",
"mocha": "2.4.5",
"supertest": "1.1.0"
},
"directories": {},
"dist": {
"shasum": "765e7607c8055452bba6f0b052595350986036de",
"tarball": "https://registry.npmjs.org/send/-/send-0.13.2.tgz"
},
"engines": {
"node": ">= 0.8.0"
},
"files": [
"HISTORY.md",
"LICENSE",
"README.md",
"index.js"
],
"gitHead": "5a089701b1c49d96084716bdb5465edefa08c906",
"homepage": "https://github.com/pillarjs/send",
"keywords": [
"static",
"file",
"server"
],
"license": "MIT",
"maintainers": [
{
"email": "doug@somethingdoug.com",
"name": "dougwilson"
}
],
"name": "send",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/pillarjs/send.git"
},
"scripts": {
"test": "mocha --check-leaks --reporter spec --bail",
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot"
},
"version": "0.13.2"
}

View File

@@ -0,0 +1,10 @@
(The MIT License)
Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me) <us@bevry.me>
Copyright © 2011-2012 [Benjamin Lupton](http://balupton.com) <b@lupton.cc>
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.

View File

@@ -0,0 +1,51 @@
# Task Group [![Build Status](https://secure.travis-ci.org/bevry/taskgroup.png?branch=master)](http://travis-ci.org/bevry/taskgroup)
Group together synchronous and asynchronous tasks and execute them in either serial or parallel
## Install
### Backend
1. [Install Node.js](http://bevry.me/node/install)
2. `npm install --save taskgroup`
### Frontend
1. [See Browserify](http://browserify.org/)
## Usage
``` coffeescript
# Import
TaskGroup = require('taskgroup')
# Add tasks to the group and fire them in parallel
tasks = new TaskGroup (err,lastResult,results) -> console.log(err,lastResult,results)
tasks.push (complete) ->
someAsyncFunction(arg1, arg2, complete)
tasks.push ->
someSyncFunction(arg1, arg2)
tasks.run() # can also use tasks.run('parallel')
# Add tasks to the group and fire them in serial
tasks = new TaskGroup (err,lastResult,results) -> console.log(err,lastResult,results)
tasks.push (complete) ->
someAsyncFunction(arg1, arg2, complete)
tasks.push ->
someSyncFunction(arg1, arg2)
tasks.run('serial')
```
## History
You can discover the history inside the [History.md](https://github.com/bevry/taskgroup/blob/master/History.md#files) file
## License
Licensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)
<br/>Copyright © 2013+ [Bevry Pty Ltd](http://bevry.me)
<br/>Copyright © 2011-2012 [Benjamin Arthur Lupton](http://balupton.com)

View File

@@ -0,0 +1,96 @@
{
"_args": [
[
"taskgroup@~2.0.0",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util"
]
],
"_from": "taskgroup@>=2.0.0 <2.1.0",
"_id": "taskgroup@2.0.0",
"_inCache": true,
"_installable": true,
"_location": "/live-server/taskgroup",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "1.2.15",
"_phantomChildren": {},
"_requested": {
"name": "taskgroup",
"raw": "taskgroup@~2.0.0",
"rawSpec": "~2.0.0",
"scope": null,
"spec": ">=2.0.0 <2.1.0",
"type": "range"
},
"_requiredBy": [
"/live-server/bal-util"
],
"_resolved": "https://registry.npmjs.org/taskgroup/-/taskgroup-2.0.0.tgz",
"_shasum": "184944a42b5684aad751189a5263c030f6174446",
"_shrinkwrap": null,
"_spec": "taskgroup@~2.0.0",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util",
"author": {
"email": "us@bevry.me",
"name": "Bevry Pty Ltd",
"url": "http://bevry.me"
},
"bugs": {
"url": "https://github.com/bevry/taskgroup/issues"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "https://github.com/balupton"
}
],
"dependencies": {
"ambi": "~2.0.0",
"typechecker": "~2.0.1"
},
"description": "Group together synchronous and asynchronous tasks and execute them in either serial or parallel",
"devDependencies": {
"coffee-script": "~1.6.2",
"joe": "~1.1.2"
},
"directories": {
"lib": "./out/lib"
},
"dist": {
"shasum": "184944a42b5684aad751189a5263c030f6174446",
"tarball": "https://registry.npmjs.org/taskgroup/-/taskgroup-2.0.0.tgz"
},
"engines": {
"node": ">=0.4"
},
"homepage": "https://github.com/bevry/taskgroup",
"keywords": [
"flow",
"control",
"async",
"sync",
"tasks",
"batch"
],
"main": "./out/lib/taskgroup.js",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "taskgroup",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/bevry/taskgroup.git"
},
"scripts": {
"test": "node ./out/test/taskgroup-test.js --joe-reporter=list"
},
"version": "2.0.0"
}

View File

@@ -0,0 +1,522 @@
## History
- v2.0.8 November 1, 2013
- Dropped component.io and bower support, just use ender or browserify
- v2.0.7 October 27, 2013
- Re-packaged
- v2.0.6 September 18, 2013
- Fixed node release (since v2.0.5)
- Fixed bower release (since v2.0.4)
- v2.0.5 September 18, 2013
- Fixed node release (since v2.0.4)
- v2.0.4 September 18, 2013
- Fixed cyclic dependency problem on windows (since v2.0.3)
- Added bower support
- v2.0.3 September 18, 2013
- Attempt at fixing circular dependency infinite loop (since v2.0.2)
- v2.0.2 September 18, 2013
- Added component.io support
- v2.0.1 March 27, 2013
- Fixed some package.json properties
- v2.0.0 March 27, 2013
- Split typeChecker from bal-util
- v1.16.14 March 27, 2013
- Killed explicit browser support, use [Browserify](http://browserify.org/) instead
- Removed the `out` directory from git
- Now compiled with the coffee-script bare option
- v1.16.13 March 23, 2013
- `balUtilEvents` changes:
- `EventEmitterEnhanced` changes:
- Now works with `once` calls in node 0.10.0
- Closes [bevry/docpad#462](https://github.com/bevry/docpad/issues/462)
- Changed `emitSync` to be an alias to `emitSerial` and `emitAsync` to be an alias to `emitParallel`
- Added new `getListenerGroup` function
- `balUtilFlow` changes:
- `fireWithOptionalCallback` can now take the method as an array of `[fireMethod,introspectMethod]` useful for pesly binds
- v1.16.12 March 18, 2013
- `balUtilFlow` changes:
- `Groups::run` signature changed from no arguments to a single `mode` argument
- v1.16.11 March 10, 2013
- `balUtilModules` changes:
- Fixed `getCountryCode` and `getLanguageCode` failing when there is no locale code
- v1.16.10 March 8, 2013
- `balUtilModules` changes:
- Fixed `requireFresh` regression, added test
- v1.16.9 March 8, 2013
- `balUtilModules` changes:
- Added `getLocaleCode`
- Added `getCountryCode`
- Added `getLanguageCode`
- v1.16.8 February 16, 2013
- `balUtilModules` changes:
- `spawnMultiple`, `execMultiple`: now accept a `tasksMode` option that can be `serial` (default) or `parallel`
- v1.16.7 February 12, 2013
- `balUtilPaths` changes:
- `readPath`: do not prefer gzip, but still support it for decoding, as the zlib library is buggy
- v1.16.6 February 12, 2013
- `balUtilPaths` changes:
- `readPath`: add support for gzip decoding for node 0.6 and higher
- v1.16.5 February 6, 2013
- More [browserify](http://browserify.org/) support
- v1.16.4 February 6, 2013
- [Browserify](http://browserify.org/) support
- v1.16.3 February 5, 2013
- Node v0.4 support
- `balUtilPaths` changes:
- Removed deprecated `console.log`s when errors occur (they are now sent to the callback)
- Fixed `determineExecPath` when executable requires the environment configuration
- `balUtilTypes` changes:
- `isEmptyObject` now works for empty values (e.g. `null`)
- `balUtilFlow` changes:
- Added `clone`
- Added `deepClone`
- `setDeep` and `getDeep` now handle `undefined` values correctly
- v1.16.2 February 1, 2013
- `balUtilPaths` changes:
- Added timeout support to `readPath`
- `balUtilFlow` changes:
- Added `setDeep`
- Added `getDeep`
- v1.16.1 January 25, 2013
- `balUtilFlow` changes:
- Added `safeShallowExtendPlainObjects`
- Added `safeDeepExtendPlainObjects`
- v1.16.0 January 24, 2013
- Node v0.9 compatability
- `balUtilModules` changes:
- Added `getEnvironmentPaths`
- Added `getStandardExecPaths(execName)`
- `exec` now supports the `output` option
- `determineExecPath` now resolves the possible paths and checks for their existance
- This avoids Node v0.9's ENOENT crash when executing a path that doesn't exit
- `getExecPath` will now try for `.exe` paths as well when running on windows if an extension hasn't already been defined
- `getGitPath`, `getNodePath`, `getNpmPath` will now also check the environment paths
- `balUtilFlow` changes:
- Added `createSnore`
- Added `suffixArray`
- `flow` now accepts the signatures `({object,actions,action,args,tasks,next})`, `(object, action, args, next)` and `(actions,args,next)`
- `Group` changes:
- `mode` can now be either `parallel` or `serial`, rather than `async` and `sync`
- `async()` is now `parallel()` (aliased for b/c)
- `sync()` is now `serial()` (aliased for b/c)
- `balUtilTypes` changes:
- Added `isEmptyObject`
- v1.15.4 January 8, 2013
- `balUtilPaths` changes:
- Renamed `testIgnorePatterns` to `isIgnoredPath`
- Added aliases for b/c compatibility
- Added new `ignorePaths` option
- v1.15.3 December 24, 2012
- `balUtilModules` changes:
- Added `requireFresh`
- v1.15.2 December 16, 2012
- `balUtilPaths` changes:
- Fixed `scandir` not inheriting ignore patterns when recursing
- v1.15.1 December 15, 2012
- `balUtilPaths` changes:
- Fixed `testIgnorePatterns` when `ignoreCommonPatterns` is set to `true`
- v1.15.0 December 15, 2012
- `balUtilPaths` changes:
- Added `testIgnorePatterns`
- Renamed `ignorePatterns` to `ignoreCommonPatterns`, and added new `ignoreCustomPatterns`
- Affects `scandir` options
- Added emac cache files to `ignoreCommonPatterns`
- v1.14.1 December 14, 2012
- `balUtilModules` changes:
- Added `getExecPath` that will fetch an executable path based on the paths within the environment `PATH` variable
- Rebuilt with CoffeeScript 1.4.x
- v1.14.0 November 23, 2012
- `balUtilPaths` changes:
- `readPath` will now follow url redirects
- v1.13.13 October 26, 2012
- `balUtilPaths` changes:
- Files that start with `~` are now correctly ignored in `commonIgnorePatterns`
- v1.13.12 October 22, 2012
- `balUtilFlow` changes:
- `extend` is now an alias of `shallowExtendPlainObjects` as they were exactly the same
- `balUtilHTML` changes:
- `replaceElement` and `replaceElementAsync` changes:
- now accept arguments in object form as well
- accept a `removeIndentation` argument that defaults to `true`
- v1.13.11 October 22, 2012
- `balUtilPaths` changes:
- `ensurePath` now returns `err` and `exists` instead of just `err`
- `balUtilModules` changes:
- `initGitRepo` will now default `remote` to `origin` and `branch` to `master`
- Added `initOrPullGitRepo`
- v1.13.10 October 7, 2012
- `balUtilPaths` changes:
- Added `shallowExtendPlainObjects`
- v1.13.9 October 7, 2012
- `balUtilPaths` changes:
- VIM swap files now added to `commonIgnorePatterns`
- Thanks to [Sean Fridman](https://github.com/sfrdmn) for [pull request #4](https://github.com/balupton/bal-util/pull/4)
- v1.13.8 October 2, 2012
- `balUtilModules` changes:
- Added `openProcess` and `closeProcess`, and using them in `spawn` and `exec`, used to prevent `EMFILE` errors when there are too many open processes
- Max number of open processes is configurable via the `NODE_MAX_OPEN_PROCESSES` environment variable
` balUtilPaths` changes:
- Max number of open files is now configurable via the`NODE_MAX_OPEN_FILES` environment variable
- v1.13.7 September 24, 2012
- `balUtilPaths` changes:
- Added `textExtensions` and `binaryExtensions`
- The environment variables `TEXT_EXTENSIONS` and `BINARY_EXTENSIONS` will append to these arrays
- Added `isText` and `isTextSync`
- v1.13.6 September 18, 2012
- `balUtilPaths` changes:
- Improved `getEncoding`/`getEncodingSync` detection
- Will now scan start, middle and end, instead of just middle
- v1.13.5 September 13, 2012
- `balUtilPaths` changes:
- Added `getEncoding` and `getEncodingSync`
- v1.13.4 August 28, 2012
- `balUtilModules` changes:
- Failing to retrieve the path on `getGitPath`, `getNodePath` and `getNpmPath` will now result in an error
- v1.13.3 August 28, 2012
- `balUtilModules` changes:
- Fixed `exec` and `execMultiple`
- Added `gitCommands`, `nodeCommands` and `npmCommands`
- Dropped node v0.4 support, min required version now 0.6
- v1.13.2 August 16, 2012
- Repackaged
- v1.13.1 August 16, 2012
- `balUtilHTML` changes:
- Fixed `replaceElement` from mixing up elements that start with our desired selector, instead of being only our desired selector
- v1.13.0 August 3, 2012
- `balUtilModules` changes:
- Added `determineExecPath`, `getNpmPath`, `getTmpPath`, `nodeCommand` and `gitCommand`
- `initNodeModules` and `initGitRepo` will now get the determined path of the executable if a path isn't passed
- Re-added markdown files to npm distribution as they are required for the npm website
- v1.12.5 July 18, 2012
- `balUtilTypes` changes:
- Better checks for `isString` and `isNumber` under some environments
- `balUtilFlow` changes:
- Removed ambigious `clone` function, use `dereference` or `extend` or `deepExtendPlainObjects` instead
- v1.12.4 July 12, 2012
- `balUtilTypes` changes:
- `isObject` now also checks truthyness to avoid `null` and `undefined` from being objects
- `isPlainObject` got so good, it can't get better
- `balUtilFlow` changes:
- added `deepExtendPlainObjects`
- v1.12.3 July 12, 2012
- `balUtilModules` changes:
- `npmCommand` will now only prefix with the nodePath if the npmPath exists
- `npmCommand` and `initNodeModules` now use async fs calls instead of sync calls
- v1.12.2 July 12, 2012
- `balUtilFlow` changes:
- Added `dereference`
- v1.12.1 July 10, 2012
- `balUtilModules` changes:
- Added `stdin` option to `spawn`
- v1.12.0 July 7, 2012
- Rejigged `balUtilTypes` and now top level
- Other components now make use of this instead of inline `typeof` and `instanceof` checks
- `balUtilFlow` changes:
- `isArray` and `toString` moved to `balUtilTypes`
- v1.11.2 July 7, 2012
- `balUtilFlow` changes:
- Added `clone`
- `balUtilModules` changes:
- Fixed exists warning on `initNodeModules`
- `balUtilPaths` changes:
- Added `scanlist`
- `scandir` changes:
- If `readFiles` is `true`, then we will return the contents into the list entries as well as the tree entries (we weren't doing this for lists before)
- v1.11.1 July 4, 2012
- `balUtilFlow` changes:
- `Group` changes:
- Cleaned up the context handling code
- `Block` changes:
- Block constructor as well as `createSubBlock` arguments is now a single `opts` object, acceping the options `name`, `fn`, `parentBlock` and the new `complete`
- Fixed bug introduced in v1.11.0 causing blocks to complete instantly (instead of once their tasks are finished)
- v1.11.0 July 1, 2012
- Added `balUtilHTML`:
- `getAttribute(attributes,attribute)`
- `detectIndentation(source)`
- `removeIndentation(source)`
- `replaceElement(source, elementNameMatcher, replaceElementCallback)`
- `replaceElementAsync(source, elementNameMatcher, replaceElementCallback, next)`
- `balUtilFlow` changes:
- `wait(delay,fn)` introduced as an alternative to `setTimeout`
- `Group` changes:
- `push` and `pushAndRun` signatures are now `([context], task)`
- `context` is optional, and what we should bind to this
- it saves us having to often wrap our task pushing into for each scopes
- task completion callbacks are now optional, if not specified a task will be completed as soon as it finishes executing
- `balUtilEvents`, `balUtilModules` changes:
- Now make use of the `balUtilFlow.push|pushAndRun` new `context` argument to simplify some loops
- v1.10.3 June 26, 2012
- `balUtilModules` changes:
- `initNodeModules` will now install modules from cache, unless `force` is true
- v1.10.2 June 26, 2012
- `balUtilModules` changes:
- `initNodeModules` will now never install modules from cache
- v1.10.1 June 26, 2012
- `balUtilModules` changes:
- Fixed `npmCommand` under some situations
- v1.10.0 June 26, 2012
- `balUtilModules` changes:
- Added `spawnMultiple`, `execMultiple`, `gitGitPath`, `getNodePath`, and `npmCommand`
- `spawn` and `exec` are now only for single commands, use the new `spawnMultiple` and `execMultiple` for multiple commands instead
- error exit code is now anything that isnt `0`
- v1.9.4 June 22, 2012
- Fixed a problem with large asynchronous groups
- v1.9.3 June 22, 2012
- `balUtilFlow` changes:
- Added `extractOptsAndCallback` and `extend`
- v1.9.2 June 21, 2012
- `balUtilFlow` changes:
- Added `fireWithOptionalCallback`, updated groups and emitters to use this
- v1.9.1 June 21, 2012
- `balUtilModules` changes:
- `initNodeModules` now supports `output` option
- v1.9.0 June 21, 2012
- `balUtilEvents` changes:
- `EventEmitterEnhanced` changes:
- `emitSync` and `emitAsync` changes:
- The next callback is now optional, if it is not detected then we will automatically mark the listener as completed once we have executed it (in other words, if it doesn't have a next callback, then we treat it as a synchronous listener)
- v1.8.8 June 19, 2012
- Fixed a problem with large synchronous groups
- v1.8.7 June 19, 2012
- Defaulted `dependencies` to an empty object, to hopefully fix [npm issue #2540](https://github.com/isaacs/npm/pull/2540)
- v1.8.6 June 19, 2012
- `balUtilEvents` changes:
- Split `emitSync` and `emitAsync` out of `EventSystem` and into new `EventEmitterEnhanced` that `EventSystem` extends
- v1.8.5 June 11, 2012
- Made next callbacks necessary by default
- v1.8.4 June 11, 2012
- `balUtilModule` changes:
- `spawn`
- will now return results in the order of `err`, `stdout`, `stderr`, `code`, `signal`
- now splits string commands using `/ /`
- `balUtilFlow` changes:
- `Group` will now only return error as an array if we have more than one error
- Updated for Joe v1.0.0
- v1.8.3 June 9, 2012
- `balUtilCompare` changes:
- `packageCompare` will now fail gracefully if it receives malformed json
- v1.8.2 June 9, 2012
- Removed request dependency, we now use the native http/https modules
- v1.8.1 June 9, 2012
- Restructured directories
- Removed generated docs, use the wiki instead
- Moved tests from Mocha to [Joe](https://github.com/bevry/joe)
- Travis now tests against node v0.7
- `balUtilPaths` changes:
- Added `exists` and `existsSync` to normalize node's 0.6 to 0.8 api differences
- Made [request](https://github.com/mikeal/request) an optional dependency
- v1.8.0 June 9, 2012
- Added expiremental `balUtilFlow.Block`
- Possibly some undocumented `balUtilFlow.Group` changes
- v1.7.0 June 4, 2012
- `balUtilFlow` changes:
- `Group` changes:
- Constructor now supports `next` and `mode` arguments in any order
- `clear()` now clears everything
- Added `hasTasks()`
- Group completion callback's first argument (the error argument) is now an array of errors (or null if no errors)
- Added `breakOnError` option (defaults to `true`)
- Added `autoClear` option to clear once all tasks have run (defualts to `false`)
- v1.6.5 May 30, 2012
- `balUtilFlow` changes:
- `Group` changes:
- Reverted the change made in v1.6.4 where errors in callbacks still increment the complete count
- Instead, you should be using the `hasExited()` instead of `hasCompleted()` which is used to find out if everything passed successfully
- v1.6.4 May 30, 2012
- `balUtilFlow` changes:
- Added `flow({object,action,[args],[tasks],next})` to simplify calling a series of functions of an object
- `Group` changes:
- If complete callback is called with an error, it'll still increment the complete count (it didn't before)
- Added `hasExited()`
- `balUtilPaths` changes:
- `writeFile` will now call `ensurePath` before writing the file
- v1.6.3 May 22, 2012
- `balUtilPaths` changes:
- Fixed a problem introduced with v1.6.0 with `isDirectory` not opening the file before closing it
- If the number of open files becomes a negative number, we will now throw an error
- Decreased the max amount of allowed open files from `500` to `100`
- Increased the wait time for opening a file from `50` to `100`
- This is now customisable through the global `waitingToOpenFileDelay`
- v1.6.2 May 13, 2012
- Added support for `balUtilFlow` and `balUtilTypes` to be used inside web browsers
- v1.6.1 May 4, 2012
- `balUtilPaths` changes:
- Fixed `initNodeModules`
- v1.6.0 May 4, 2012
- We now pre-compile our coffee-script
- `balUtilPaths` changes:
- Added `readFile`, `writeFile`, `mkdir`, `stat`, `readdir`, `unlink`, `rmdir`
- Renamed `rmdir` to `rmdirDeep`
- `balUtilModules` changes:
- Removed `initGitSubmodules`, `gitPull`
- Added `initGitRepo`
- Rewrote `initNodeModules`
- v1.5.0 April 18, 2012
- `balUtilPaths` changes:
- `scan` was removed, not sure what it was used for
- `isDirectory` now returns the `fileStat` argument to the callback
- `scandir` changes:
- `ignorePatterns` option when set to true now uses the new `balUtilPaths.commonIgnorePatterns` property
- fixed error throwing when passed an invalid path
- now supports a new `stat` option
- will return the `fileStat` argument to the `fileAction` and `dirAction` callbacks
- `ignorePatterns` and `ignoreHiddenFiles` will now correctly be passed to child scandir calls
- `cpdir` and `rpdir` now uses `path.join` and support `ignoreHiddenFiles` and `ignorePatterns`
- `writetree` now uses `path.join`
- v1.4.3 April 14, 2012
- CoffeeScript dependency is now bundled
- Fixed incorrect octal `0700` should have been `700`
- v1.4.2 April 5, 2012
- Fixed a failing test due to the `bal-util.npm` to `bal-util` rename
- Improvements to `balUtilModules.spawn`
- will only return an error if the exit code was `1`
- will also contain the `code` and `signal` with the results
- `results[x][0]` is now the stderr string, rather than an error object
- v1.4.1 April 5, 2012
- Added `spawn` to `balUtilModules`
- Added `ignoreHiddenFiles` option to `balUtilPaths.scandir`
- v1.4.0 April 2, 2012
- Renamed `balUtilGroups` to `balUtilFlow`
- Added `toString`, `isArray` and `each` to `balUtilFlow`
- Added `rpdir`, `empty`, and `isPathOlderThan` to `balUtilPaths`
- v1.3.0 February 26, 2012
- Added `openFile` and `closeFile` to open and close files safely (always stays below the maximum number of allowed open files)
- Updated all path utilities to use `openFile` and `closeFile`
- Added npm scripts
- v1.2.0 February 14, 2012
- Removed single and multi modes from `exec`, now always returns the same consistent `callback(err,results)` instead
- v1.1.0 February 6, 2012
- Modularized
- Added [docco](http://jashkenas.github.com/docco/) docs
- v1.0 February 5, 2012
- Moved unit tests to [Mocha](http://visionmedia.github.com/mocha/)
- Offers more flexible unit testing
- Offers better guarantees that tests actually ran, and that they actually ran correctly
- Added `readPath` and `scantree`
- Added `readFiles` option to `scandir`
- `scandir` now supports arguments in object format
- Removed `parallel`
- Tasks inside groups now are passed `next` as there only argument
- Removed `resolvePath`, `expandPath` and `expandPaths`, they were essentially the same as `path.resolve`
- Most functions will now chain
- `comparePackage` now supports comparing two local, or two remote packages
- Added `gitPull`
- v0.9 January 18, 2012
- Added `exec`, `initNodeModules`, `initGitSubmodules`, `EventSystem.when`
- Added support for no callbacks
- v0.8 November 2, 2011
- Considerable improvements to `scandir`, `cpdir` and `rmdir`
- Note, passing `false` as the file or dir actions will now skip all of that type. Pass `null` if you do not want that.
- `dirAction` is now fired before we read the directories children, if you want it to fire after then in the next callback, pass a callback in the 3rd argument. See `rmdir` for an example of this.
- Fixed npm web to url warnings
- v0.7 October 3, 2011
- Added `versionCompare` and `packageCompare` functions
- Added `request` dependency
- v0.6 September 14, 2011
- Updated `util.Group` to support `async` and `sync` grouping
- v0.4 June 2, 2011
- Added util.type for testing the type of a variable
- Added util.expandPath and util.expandPaths
- v0.3 June 1, 2011
- Added util.Group class for your async needs :)
- v0.2 May 20, 2011
- Added some tests with expresso
- util.scandir now returns err,list,tree
- Added util.writetree
- v0.1 May 18, 2011
- Initial commit

View File

@@ -0,0 +1,18 @@
<!-- LICENSEFILE/ -->
# License
Copyright &copy; 2013+ Bevry Pty Ltd <us@bevry.me> (http://bevry.me)
<br/>Copyright &copy; 2011-2012 Benjamin Lupton <b@lupton.cc> (http://balupton.com)
## The MIT License
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.
<!-- /LICENSEFILE -->

View File

@@ -0,0 +1,136 @@
<!-- TITLE/ -->
# TypeChecker
<!-- /TITLE -->
<!-- BADGES/ -->
[![Build Status](http://img.shields.io/travis-ci/bevry/typechecker.png?branch=master)](http://travis-ci.org/bevry/typechecker "Check this project's build status on TravisCI")
[![NPM version](https://badge.fury.io/js/typechecker.png)](https://npmjs.org/package/typechecker "View this project on NPM")
[![Gittip donate button](http://img.shields.io/gittip/bevry.png)](https://www.gittip.com/bevry/ "Donate weekly to this project using Gittip")
[![Flattr donate button](https://raw.github.com/balupton/flattr-buttons/master/badge-89x18.gif)](http://flattr.com/thing/344188/balupton-on-Flattr "Donate monthly to this project using Flattr")
[![PayPayl donate button](https://www.paypalobjects.com/en_AU/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QB8GQPZAH84N6 "Donate once-off to this project using Paypal")
<!-- /BADGES -->
<!-- DESCRIPTION/ -->
Utilities to get and check variable types (isString, isPlainObject, isRegExp, etc)
<!-- /DESCRIPTION -->
<!-- INSTALL/ -->
## Install
### [Node](http://nodejs.org/), [Browserify](http://browserify.org/)
- Use: `require('typechecker')`
- Install: `npm install --save typechecker`
### [Ender](http://ender.jit.su/)
- Use: `require('typechecker')`
- Install: `ender add typechecker`
<!-- /INSTALL -->
## Usage
### Example
``` javascript
require('typechecker').isRegExp(/^a/) // returns true
```
### Methods
- `getObjectType` - returns the object string of the value, e.g. when passed `/^a/` it'll return `"[object RegExp]"`
- `getType` - returns lower case string of the type, e.g. when passed `/^a/` it'll return `"regex"`
- `isPlainObject` - returns `true` if the value doesn't have a custom prototype
- `isError` - returns `true` if the value an error, otherwise `false`
- `isDate` - returns `true` if the value is a date, otherwise `false`
- `isArguments` - returns `true` if the value is function arguments, otherwise `false`
- `isFunction` - returns `true` if the value is a function, otherwise `false`
- `isRegExp` - returns `true` if the value is a regular expression instance, otherwise `false`
- `isArray` - returns `true` if the value is an array, otherwise `false`
- `isNumber` - returns `true` if the value is a number (`"2"` is a string), otherwise `false`
- `isString` - returns `true` if the value is a string, otherwise `false`
- `isBoolean` - returns `true` if the value is a boolean, otherwise `false`
- `isNull` - returns `true` if the value is null, otherwise `false`
- `isUndefined` - returns `true` if the value is undefined, otherwise `false`
- `isEmpty` - returns `true` if the value is `null` or `undefined`
- `isEmptyObject` - returns `true` if the object has no keys that are its own
### Notes
Why should I use this instead of say `instanceof`? Under certain circumstances `instanceof` may not return the correct results.
This occurs with [node's vm module](http://nodejs.org/api/vm.html#vm_globals) especially, and circumstances where an object's prototype has been dereferenced from the original.
As such, for basic `==` and `===` checks (like `a === null`), you're fine not using this, but for checks when you would have done `instanceof` (like `err instanceof Error`), you should try to use this instead.
Plus things like `isEmptyObject` and `isPlainObject` are darn useful!
<!-- HISTORY/ -->
## History
[Discover the change history by heading on over to the `History.md` file.](https://github.com/bevry/typechecker/blob/master/History.md#files)
<!-- /HISTORY -->
<!-- CONTRIBUTE/ -->
## Contribute
[Discover how you can contribute by heading on over to the `Contributing.md` file.](https://github.com/bevry/typechecker/blob/master/Contributing.md#files)
<!-- /CONTRIBUTE -->
<!-- BACKERS/ -->
## Backers
### Maintainers
These amazing people are maintaining this project:
- Benjamin Lupton <b@lupton.cc> (https://github.com/balupton)
### Sponsors
No sponsors yet! Will you be the first?
[![Gittip donate button](http://img.shields.io/gittip/bevry.png)](https://www.gittip.com/bevry/ "Donate weekly to this project using Gittip")
[![Flattr donate button](https://raw.github.com/balupton/flattr-buttons/master/badge-89x18.gif)](http://flattr.com/thing/344188/balupton-on-Flattr "Donate monthly to this project using Flattr")
[![PayPayl donate button](https://www.paypalobjects.com/en_AU/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QB8GQPZAH84N6 "Donate once-off to this project using Paypal")
### Contributors
These amazing people have contributed code to this project:
- Benjamin Lupton <b@lupton.cc> (https://github.com/balupton) - [view contributions](https://github.com/bevry/typechecker/commits?author=balupton)
- sfrdmn (https://github.com/sfrdmn) - [view contributions](https://github.com/bevry/typechecker/commits?author=sfrdmn)
[Become a contributor!](https://github.com/bevry/typechecker/blob/master/Contributing.md#files)
<!-- /BACKERS -->
<!-- LICENSE/ -->
## License
Licensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT license](http://creativecommons.org/licenses/MIT/)
Copyright &copy; 2013+ Bevry Pty Ltd <us@bevry.me> (http://bevry.me)
<br/>Copyright &copy; 2011-2012 Benjamin Lupton <b@lupton.cc> (http://balupton.com)
<!-- /LICENSE -->

View File

@@ -0,0 +1,13 @@
// v1.3.7 November 1, 2013
// https://github.com/bevry/base
(function(){
var fsUtil = require('fs'),
name = require('./package.json').name;
if ( fsUtil.existsSync('.git') === true && fsUtil.existsSync('./node_modules/'+name) === false ) {
require('child_process').spawn(
process.platform.indexOf('win') === 0 ? process.execPath.replace('node.exe', 'npm.cmd') : 'npm',
['install', '--force', name],
{env:process.env, cwd:process.cwd(), stdio:'inherit'}
).on('error', console.log).on('close', console.log);
}
})()

View File

@@ -0,0 +1,128 @@
{
"_args": [
[
"typechecker@~2.0.1",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util"
]
],
"_from": "typechecker@>=2.0.1 <2.1.0",
"_id": "typechecker@2.0.8",
"_inCache": true,
"_installable": true,
"_location": "/live-server/typechecker",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "1.3.11",
"_phantomChildren": {},
"_requested": {
"name": "typechecker",
"raw": "typechecker@~2.0.1",
"rawSpec": "~2.0.1",
"scope": null,
"spec": ">=2.0.1 <2.1.0",
"type": "range"
},
"_requiredBy": [
"/live-server/ambi",
"/live-server/bal-util",
"/live-server/eachr",
"/live-server/extendr",
"/live-server/getsetdeep",
"/live-server/taskgroup"
],
"_resolved": "https://registry.npmjs.org/typechecker/-/typechecker-2.0.8.tgz",
"_shasum": "e83da84bb64c584ccb345838576c40b0337db82e",
"_shrinkwrap": null,
"_spec": "typechecker@~2.0.1",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/bal-util",
"author": {
"email": "us@bevry.me",
"name": "2013+ Bevry Pty Ltd",
"url": "http://bevry.me"
},
"badges": {
"flattr": "344188/balupton-on-Flattr",
"gittip": "bevry",
"npm": true,
"paypal": "QB8GQPZAH84N6",
"travis": true
},
"bugs": {
"url": "https://github.com/bevry/typechecker/issues"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "https://github.com/balupton"
},
{
"name": "sfrdmn",
"url": "https://github.com/sfrdmn"
}
],
"dependencies": {},
"description": "Utilities to get and check variable types (isString, isPlainObject, isRegExp, etc)",
"devDependencies": {
"coffee-script": "~1.6.2",
"joe": "~1.3.0",
"joe-reporter-console": "~1.2.1",
"projectz": "~0.2.3"
},
"directories": {
"lib": "./out/lib"
},
"dist": {
"shasum": "e83da84bb64c584ccb345838576c40b0337db82e",
"tarball": "https://registry.npmjs.org/typechecker/-/typechecker-2.0.8.tgz"
},
"engines": {
"node": ">=0.4"
},
"homepage": "https://github.com/bevry/typechecker",
"keywords": [
"types",
"type",
"check",
"gettype",
"isstring",
"isregexp",
"isregex",
"isplainobject",
"isobject",
"iserror",
"isnumber",
"isdate",
"isarguments",
"isarray",
"isnull",
"isempty",
"isundefined",
"isemptyobject"
],
"license": {
"type": "MIT"
},
"main": "./out/lib/typechecker.js",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "typechecker",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/bevry/typechecker.git"
},
"scripts": {
"preinstall": "node ./cyclic.js",
"test": "node ./out/test/typechecker-test.js"
},
"title": "TypeChecker",
"version": "2.0.8"
}

View File

@@ -0,0 +1,132 @@
# This file was originally created by Benjamin Lupton <b@lupton.cc> (http://balupton.com)
# and is currently licensed under the Creative Commons Zero (http://creativecommons.org/publicdomain/zero/1.0/)
# making it public domain so you can do whatever you wish with it without worry (you can even remove this notice!)
#
# If you change something here, be sure to reflect the changes in:
# - the scripts section of the package.json file
# - the .travis.yml file
# -----------------
# Variables
WINDOWS = process.platform.indexOf('win') is 0
NODE = process.execPath
NPM = if WINDOWS then process.execPath.replace('node.exe','npm.cmd') else 'npm'
EXT = (if WINDOWS then '.cmd' else '')
APP = process.cwd()
BIN = "#{APP}/node_modules/.bin"
CAKE = "#{BIN}/cake#{EXT}"
COFFEE = "#{BIN}/coffee#{EXT}"
OUT = "#{APP}/out"
SRC = "#{APP}/src"
# -----------------
# Requires
pathUtil = require('path')
{exec,spawn} = require('child_process')
safe = (next,fn) ->
return (err) ->
return next(err) if err
return fn()
# -----------------
# Actions
clean = (opts,next) ->
(next = opts; opts = {}) unless next?
args = [
'-Rf'
OUT
pathUtil.join(APP,'node_modules')
pathUtil.join(APP,'*out')
pathUtil.join(APP,'*log')
]
spawn('rm', args, {stdio:'inherit',cwd:APP}).on('exit',next)
compile = (opts,next) ->
(next = opts; opts = {}) unless next?
spawn(COFFEE, ['-bco', OUT, SRC], {stdio:'inherit',cwd:APP}).on('exit',next)
example = (opts,next) ->
(next = opts; opts = {}) unless next?
compile opts, safe next, ->
command = pathUtil.resolve("#{__dirname}/bin/watchr")
spawn(command, [], {stdio:'inherit',cwd:APP,env:process.env}).on('exit',next)
watch = (opts,next) ->
(next = opts; opts = {}) unless next?
spawn(COFFEE, ['-bwco', OUT, SRC], {stdio:'inherit',cwd:APP}).on('exit',next)
install = (opts,next) ->
(next = opts; opts = {}) unless next?
spawn(NPM, ['install'], {stdio:'inherit',cwd:APP}).on('exit',next)
reset = (opts,next) ->
(next = opts; opts = {}) unless next?
clean opts, safe next, ->
install opts, safe next, ->
compile opts, next
setup = (opts,next) ->
(next = opts; opts = {}) unless next?
install opts, safe next, ->
compile opts, next
test = (opts,next) ->
(next = opts; opts = {}) unless next?
spawn(NPM, ['test'], {stdio:'inherit',cwd:APP}).on('exit',next)
finish = (err) ->
throw err if err
console.log('OK')
# -----------------
# Commands
# clean
task 'clean', 'clean up instance', ->
clean finish
# compile
task 'compile', 'compile our files', ->
compile finish
# dev/watch
task 'dev', 'watch and recompile our files', ->
watch finish
task 'watch', 'watch and recompile our files', ->
watch finish
# example
task 'example', 'run the example file', ->
example finish
# install
task 'install', 'install dependencies', ->
install finish
# reset
task 'reset', 'reset instance', ->
reset finish
# setup
task 'setup', 'setup for development', ->
setup finish
# test
task 'test', 'run our tests', ->
test finish
# test-debug
task 'test-debug', 'run our tests in debug mode', ->
test {debug:true}, finish
# test-prepare
task 'test-prepare', 'prepare out tests', ->
setup finish

View File

@@ -0,0 +1,108 @@
## Watchr: better file system watching for Node.js [![Build Status](https://secure.travis-ci.org/bevry/watchr.png?branch=master)](http://travis-ci.org/bevry/watchr)
Watchr provides a normalised API the file watching APIs of different node versions, nested/recursive file and directory watching, and accurate detailed events for file/directory creations, updates, and deletions.
You install it via `npm install watchr` and use it via `require('watchr').watch(config)`. Available configuration options are:
- `path` a single path to watch
- `paths` an array of paths to watch
- `listener` a single change listener to fire when a change occurs
- `listeners` an array of listeners to fire when a change occurs, overloaded to accept the following values:
- `changeListener` a single change listener
- `[changeListener]` an array of change listeners
- `{eventName:eventListener}` an object keyed with the event names and valued with a single event listener
- `{eventName:[eventListener]}` an object keyed with the event names and valued with an array of event listeners
- `next` (optional, defaults to `null`) a completion callback to fire once the watchers have been setup, arguments are:
- when using the `path` configuration option: `err, watcherInstance`
- when using the `paths` configuration option: `err, [watcherInstance,...]`
- `stat` (optional, defaults to `null`) a file stat object to use for the path, instead of fetching a new one
- `interval` (optional, defaults to `5007`) for systems that poll to detect file changes, how often should it poll in millseconds
- `persistent` (optional, defaults to `true`) whether or not we should keep the node process alive for as long as files are still being watched
- `duplicateDelay` (optional, defaults to `1000`) sometimes events will fire really fast, this delay is set in place so we don't fire the same event within the timespan. Set to falsey to perform no duplicate detection.
- `preferredMethods` (optional, defaults to `['watch','watchFile']`) which order should we prefer our watching methods to be tried?
- `ignorePaths` (optional, defaults to `false`) an array of full paths to ignore
- `ignoreHiddenFiles` (optional, defaults to `false`) whether or not to ignored files which filename starts with a `.`
- `ignoreCommonPatterns` (optional, defaults to `true`) whether or not to ignore common undesirable file patterns (e.g. `.svn`, `.git`, `.DS_Store`, `thumbs.db`, etc)
- `ignoreCustomPatterns` (optional, defaults to `null`) any custom ignore patterns that you would also like to ignore along with the common patterns
The following events are available to your via the listeners:
- `log` for debugging, receives the arguments `logLevel ,args...`
- `error` for gracefully listening to error events, receives the arguments `err`
- `watching` for when watching of the path has completed, receives the arguments `err, isWatching`
- `change` for listening to change events, receives the arguments `changeType, fullPath, currentStat, previousStat`, received arguments will be:
- for updated files: `'update', fullPath, currentStat, previousStat`
- for created files: `'create', fullPath, currentStat, null`
- for deleted files: `'delete', fullPath, null, previousStat`
To wrap it all together, it would look like this:
``` javascript
// Require
var watchr = require('watchr');
// Watch a directory or file
console.log('Watch our paths');
watchr.watch({
paths: ['path1','path2','path3'],
listeners: {
log: function(logLevel){
console.log('a log message occured:', arguments);
},
error: function(err){
console.log('an error occured:', err);
},
watching: function(err,watcherInstance,isWatching){
if (err) {
console.log("watching the path " + watcherInstance.path + " failed with error", err);
} else {
console.log("watching the path " + watcherInstance.path + " completed");
}
},
change: function(changeType,filePath,fileCurrentStat,filePreviousStat){
console.log('a change event occured:',arguments);
}
},
next: function(err,watchers){
if (err) {
return console.log("watching everything failed with error", err);
} else {
console.log('watching everything completed', watchers);
}
// Close watchers after 60 seconds
setTimeout(function(){
var i;
console.log('Stop watching our paths');
for ( i=0; i<watchers.length; i++ ) {
watchers[i].close();
}
},60*1000);
}
});
```
You can test the above code snippet by running the following:
```
npm install -g watchr
watchr
```
## Support
Support can be found in the [GitHub Issue Tracker](https://github.com/bevry/watchr/issues)
## History
You can discover the history inside the [History.md](https://github.com/bevry/watchr/blob/master/History.md#files) file
## License
Licensed under the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT License](http://creativecommons.org/licenses/MIT/)
<br/>Copyright &copy; 2012+ [Bevry Pty Ltd](http://bevry.me)
<br/>Copyright &copy; 2011 [Benjamin Lupton](http://balupton.com)

View File

@@ -0,0 +1,43 @@
#!/usr/bin/env node
// Require
var watchr = require(__dirname+'/../out/lib/watchr');
// Watch a directory or file
console.log('Watch our paths');
watchr.watch({
paths: [process.cwd()],
listeners: {
log: function(logLevel){
console.log('a log message occured:', arguments);
},
error: function(err){
console.log('an error occured:', err);
},
watching: function(err,watcherInstance,isWatching){
if (err) {
console.log("watching the path " + watcherInstance.path + " failed with error", err);
} else {
console.log("watching the path " + watcherInstance.path + " completed");
}
},
change: function(changeType,filePath,fileCurrentStat,filePreviousStat){
console.log('a change event occured:',arguments);
}
},
next: function(err,watchers){
if (err) {
return console.log("watching everything failed with error", err);
} else {
console.log('watching everything completed', watchers);
}
// Close watchers after 60 seconds
setTimeout(function(){
var i;
console.log('Stop watching our paths');
for ( i=0; i<watchers.length; i++ ) {
watchers[i].close();
}
},60*1000);
}
});

View File

@@ -0,0 +1,106 @@
{
"_args": [
[
"watchr@2.3.x",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server"
]
],
"_from": "watchr@>=2.3.0 <2.4.0",
"_id": "watchr@2.3.10",
"_inCache": true,
"_installable": true,
"_location": "/live-server/watchr",
"_npmUser": {
"email": "b@lupton.cc",
"name": "balupton"
},
"_npmVersion": "1.2.15",
"_phantomChildren": {},
"_requested": {
"name": "watchr",
"raw": "watchr@2.3.x",
"rawSpec": "2.3.x",
"scope": null,
"spec": ">=2.3.0 <2.4.0",
"type": "range"
},
"_requiredBy": [
"/live-server"
],
"_resolved": "https://registry.npmjs.org/watchr/-/watchr-2.3.10.tgz",
"_shasum": "2fe0af537071cae6a776d4523356f8f3a230b7ce",
"_shrinkwrap": null,
"_spec": "watchr@2.3.x",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server",
"author": {
"email": "us@bevry.me",
"name": "Bevry Pty Ltd",
"url": "http://bevry.me"
},
"bin": {
"watchr": "./bin/watchr"
},
"bugs": {
"url": "https://github.com/bevry/watchr/issues"
},
"contributors": [
{
"email": "b@lupton.cc",
"name": "Benjamin Lupton",
"url": "http://balupton.com"
},
{
"name": "Casey Foster",
"url": "https://github.com/caseywebdev"
},
{
"email": "robsonpeixoto@gmail.com",
"name": "Robson Roberto Souza Peixoto",
"url": "https://github.com/robsonpeixoto"
}
],
"dependencies": {
"bal-util": "~1.18.0"
},
"description": "Better file system watching for Node.js",
"devDependencies": {
"coffee-script": "~1.6.2",
"joe": "~1.1.2"
},
"directories": {
"lib": "./out/lib"
},
"dist": {
"shasum": "2fe0af537071cae6a776d4523356f8f3a230b7ce",
"tarball": "https://registry.npmjs.org/watchr/-/watchr-2.3.10.tgz"
},
"engines": {
"node": ">=0.4"
},
"homepage": "https://github.com/bevry/watchr",
"keywords": [
"watching",
"watch",
"fswatcher",
"watchfile",
"fs"
],
"main": "./out/lib/watchr",
"maintainers": [
{
"email": "b@lupton.cc",
"name": "balupton"
}
],
"name": "watchr",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/bevry/watchr.git"
},
"scripts": {
"test": "node ./out/test/everything.test.js --joe-reporter=console"
},
"version": "2.3.10"
}

View File

@@ -0,0 +1,106 @@
### 0.6.4 / 2016-01-07
* If a number is given as input for a frame payload, send it as a string
### 0.6.3 / 2015-11-06
* Reject draft-76 handshakes if their Sec-WebSocket-Key headers are invalid
* Throw a more helpful error if a client is created with an invalid URL
### 0.6.2 / 2015-07-18
* When the peer sends a close frame with no error code, emit 1000
### 0.6.1 / 2015-07-13
* Use the `buffer.{read,write}UInt{16,32}BE` methods for reading/writing numbers
to buffers rather than including duplicate logic for this
### 0.6.0 / 2015-07-08
* Allow the parser to recover cleanly if event listeners raise an error
* Add a `pong` method for sending unsolicited pong frames
### 0.5.4 / 2015-03-29
* Don't emit extra close frames if we receive a close frame after we already
sent one
* Fail the connection when the driver receives an invalid
`Sec-WebSocket-Extensions` header
### 0.5.3 / 2015-02-22
* Don't treat incoming data as WebSocket frames if a client driver is closed
before receiving the server handshake
### 0.5.2 / 2015-02-19
* Fix compatibility with the HTTP parser on io.js
* Use `websocket-extensions` to make sure messages and close frames are kept in
order
* Don't emit multiple `error` events
### 0.5.1 / 2014-12-18
* Don't allow drivers to be created with unrecognized options
### 0.5.0 / 2014-12-13
* Support protocol extensions via the websocket-extensions module
### 0.4.0 / 2014-11-08
* Support connection via HTTP proxies using `CONNECT`
### 0.3.6 / 2014-10-04
* It is now possible to call `close()` before `start()` and close the driver
### 0.3.5 / 2014-07-06
* Don't hold references to frame buffers after a message has been emitted
* Make sure that `protocol` and `version` are exposed properly by the TCP driver
### 0.3.4 / 2014-05-08
* Don't hold memory-leaking references to I/O buffers after they have been
parsed
### 0.3.3 / 2014-04-24
* Correct the draft-76 status line reason phrase
### 0.3.2 / 2013-12-29
* Expand `maxLength` to cover sequences of continuation frames and
`draft-{75,76}`
* Decrease default maximum frame buffer size to 64MB
* Stop parsing when the protocol enters a failure mode, to save CPU cycles
### 0.3.1 / 2013-12-03
* Add a `maxLength` option to limit allowed frame size
* Don't pre-allocate a message buffer until the whole frame has arrived
* Fix compatibility with Node v0.11 `HTTPParser`
### 0.3.0 / 2013-09-09
* Support client URLs with Basic Auth credentials
### 0.2.2 / 2013-07-05
* No functional changes, just updates to package.json
### 0.2.1 / 2013-05-17
* Export the isSecureRequest() method since faye-websocket relies on it
* Queue sent messages in the client's initial state
### 0.2.0 / 2013-05-12
* Add API for setting and reading headers
* Add Driver.server() method for getting a driver for TCP servers
### 0.1.0 / 2013-05-04
* First stable release

View File

@@ -0,0 +1,4 @@
# Code of Conduct
All projects under the [Faye](https://github.com/faye) umbrella are covered by
the [Code of Conduct](https://github.com/faye/code-of-conduct).

View File

@@ -0,0 +1,383 @@
# websocket-driver [![Build Status](https://travis-ci.org/faye/websocket-driver-node.svg)](https://travis-ci.org/faye/websocket-driver-node)
This module provides a complete implementation of the WebSocket protocols that
can be hooked up to any I/O stream. It aims to simplify things by decoupling the
protocol details from the I/O layer, such that users only need to implement code
to stream data in and out of it without needing to know anything about how the
protocol actually works. Think of it as a complete WebSocket system with
pluggable I/O.
Due to this design, you get a lot of things for free. In particular, if you hook
this module up to some I/O object, it will do all of this for you:
* Select the correct server-side driver to talk to the client
* Generate and send both server- and client-side handshakes
* Recognize when the handshake phase completes and the WS protocol begins
* Negotiate subprotocol selection based on `Sec-WebSocket-Protocol`
* Negotiate and use extensions via the
[websocket-extensions](https://github.com/faye/websocket-extensions-node)
module
* Buffer sent messages until the handshake process is finished
* Deal with proxies that defer delivery of the draft-76 handshake body
* Notify you when the socket is open and closed and when messages arrive
* Recombine fragmented messages
* Dispatch text, binary, ping, pong and close frames
* Manage the socket-closing handshake process
* Automatically reply to ping frames with a matching pong
* Apply masking to messages sent by the client
This library was originally extracted from the [Faye](http://faye.jcoglan.com)
project but now aims to provide simple WebSocket support for any Node-based
project.
## Installation
```
$ npm install websocket-driver
```
## Usage
This module provides protocol drivers that have the same interface on the server
and on the client. A WebSocket driver is an object with two duplex streams
attached; one for incoming/outgoing messages and one for managing the wire
protocol over an I/O stream. The full API is described below.
### Server-side with HTTP
A Node webserver emits a special event for 'upgrade' requests, and this is where
you should handle WebSockets. You first check whether the request is a
WebSocket, and if so you can create a driver and attach the request's I/O stream
to it.
```js
var http = require('http'),
websocket = require('websocket-driver');
var server = http.createServer();
server.on('upgrade', function(request, socket, body) {
if (!websocket.isWebSocket(request)) return;
var driver = websocket.http(request);
driver.io.write(body);
socket.pipe(driver.io).pipe(socket);
driver.messages.on('data', function(message) {
console.log('Got a message', message);
});
driver.start();
});
```
Note the line `driver.io.write(body)` - you must pass the `body` buffer to the
socket driver in order to make certain versions of the protocol work.
### Server-side with TCP
You can also handle WebSocket connections in a bare TCP server, if you're not
using an HTTP server and don't want to implement HTTP parsing yourself.
The driver will emit a `connect` event when a request is received, and at this
point you can detect whether it's a WebSocket and handle it as such. Here's an
example using the Node `net` module:
```js
var net = require('net'),
websocket = require('websocket-driver');
var server = net.createServer(function(connection) {
var driver = websocket.server();
driver.on('connect', function() {
if (websocket.isWebSocket(driver)) {
driver.start();
} else {
// handle other HTTP requests
}
});
driver.on('close', function() { connection.end() });
connection.on('error', function() {});
connection.pipe(driver.io).pipe(connection);
driver.messages.pipe(driver.messages);
});
server.listen(4180);
```
In the `connect` event, the driver gains several properties to describe the
request, similar to a Node request object, such as `method`, `url` and
`headers`. However you should remember it's not a real request object; you
cannot write data to it, it only tells you what request data we parsed from the
input.
If the request has a body, it will be in the `driver.body` buffer, but only as
much of the body as has been piped into the driver when the `connect` event
fires.
### Client-side
Similarly, to implement a WebSocket client you just need to make a driver by
passing in a URL. After this you use the driver API as described below to
process incoming data and send outgoing data.
```js
var net = require('net'),
websocket = require('websocket-driver');
var driver = websocket.client('ws://www.example.com/socket'),
tcp = net.connect(80, 'www.example.com');
tcp.pipe(driver.io).pipe(tcp);
tcp.on('connect', function() {
driver.start();
});
driver.messages.on('data', function(message) {
console.log('Got a message', message);
});
```
Client drivers have two additional properties for reading the HTTP data that was
sent back by the server:
* `driver.statusCode` - the integer value of the HTTP status code
* `driver.headers` - an object containing the response headers
### HTTP Proxies
The client driver supports connections via HTTP proxies using the `CONNECT`
method. Instead of sending the WebSocket handshake immediately, it will send a
`CONNECT` request, wait for a `200` response, and then proceed as normal.
To use this feature, call `driver.proxy(url)` where `url` is the origin of the
proxy, including a username and password if required. This produces a duplex
stream that you should pipe in and out of your TCP connection to the proxy
server. When the proxy emits `connect`, you can then pipe `driver.io` to your
TCP stream and call `driver.start()`.
```js
var net = require('net'),
websocket = require('websocket-driver');
var driver = websocket.client('ws://www.example.com/socket'),
proxy = driver.proxy('http://username:password@proxy.example.com'),
tcp = net.connect(80, 'proxy.example.com');
tcp.pipe(proxy).pipe(tcp, {end: false});
tcp.on('connect', function() {
proxy.start();
});
proxy.on('connect', function() {
driver.io.pipe(tcp).pipe(driver.io);
driver.start();
});
driver.messages.on('data', function(message) {
console.log('Got a message', message);
});
```
The proxy's `connect` event is also where you should perform a TLS handshake on
your TCP stream, if you are connecting to a `wss:` endpoint.
In the event that proxy connection fails, `proxy` will emit an `error`. You can
inspect the proxy's response via `proxy.statusCode` and `proxy.headers`.
```js
proxy.on('error', function(error) {
console.error(error.message);
console.log(proxy.statusCode);
console.log(proxy.headers);
});
```
Before calling `proxy.start()` you can set custom headers using
`proxy.setHeader()`:
```js
proxy.setHeader('User-Agent', 'node');
proxy.start();
```
### Driver API
Drivers are created using one of the following methods:
```js
driver = websocket.http(request, options)
driver = websocket.server(options)
driver = websocket.client(url, options)
```
The `http` method returns a driver chosen using the headers from a Node HTTP
request object. The `server` method returns a driver that will parse an HTTP
request and then decide which driver to use for it using the `http` method. The
`client` method always returns a driver for the RFC version of the protocol with
masking enabled on outgoing frames.
The `options` argument is optional, and is an object. It may contain the
following fields:
* `maxLength` - the maximum allowed size of incoming message frames, in bytes.
The default value is `2^26 - 1`, or 1 byte short of 64 MiB.
* `protocols` - an array of strings representing acceptable subprotocols for use
over the socket. The driver will negotiate one of these to use via the
`Sec-WebSocket-Protocol` header if supported by the other peer.
A driver has two duplex streams attached to it:
* <b>`driver.io`</b> - this stream should be attached to an I/O socket like a
TCP stream. Pipe incoming TCP chunks to this stream for them to be parsed, and
pipe this stream back into TCP to send outgoing frames.
* <b>`driver.messages`</b> - this stream emits messages received over the
WebSocket. Writing to it sends messages to the other peer by emitting frames
via the `driver.io` stream.
All drivers respond to the following API methods, but some of them are no-ops
depending on whether the client supports the behaviour.
Note that most of these methods are commands: if they produce data that should
be sent over the socket, they will give this to you by emitting `data` events on
the `driver.io` stream.
#### `driver.on('open', function(event) {})`
Adds a callback to execute when the socket becomes open.
#### `driver.on('message', function(event) {})`
Adds a callback to execute when a message is received. `event` will have a
`data` attribute containing either a string in the case of a text message or a
`Buffer` in the case of a binary message.
You can also listen for messages using the `driver.messages.on('data')` event,
which emits strings for text messages and buffers for binary messages.
#### `driver.on('error', function(event) {})`
Adds a callback to execute when a protocol error occurs due to the other peer
sending an invalid byte sequence. `event` will have a `message` attribute
describing the error.
#### `driver.on('close', function(event) {})`
Adds a callback to execute when the socket becomes closed. The `event` object
has `code` and `reason` attributes.
#### `driver.addExtension(extension)`
Registers a protocol extension whose operation will be negotiated via the
`Sec-WebSocket-Extensions` header. `extension` is any extension compatible with
the [websocket-extensions](https://github.com/faye/websocket-extensions-node)
framework.
#### `driver.setHeader(name, value)`
Sets a custom header to be sent as part of the handshake response, either from
the server or from the client. Must be called before `start()`, since this is
when the headers are serialized and sent.
#### `driver.start()`
Initiates the protocol by sending the handshake - either the response for a
server-side driver or the request for a client-side one. This should be the
first method you invoke. Returns `true` if and only if a handshake was sent.
#### `driver.parse(string)`
Takes a string and parses it, potentially resulting in message events being
emitted (see `on('message')` above) or in data being sent to `driver.io`. You
should send all data you receive via I/O to this method by piping a stream into
`driver.io`.
#### `driver.text(string)`
Sends a text message over the socket. If the socket handshake is not yet
complete, the message will be queued until it is. Returns `true` if the message
was sent or queued, and `false` if the socket can no longer send messages.
This method is equivalent to `driver.messages.write(string)`.
#### `driver.binary(buffer)`
Takes a `Buffer` and sends it as a binary message. Will queue and return `true`
or `false` the same way as the `text` method. It will also return `false` if the
driver does not support binary messages.
This method is equivalent to `driver.messages.write(buffer)`.
#### `driver.ping(string = '', function() {})`
Sends a ping frame over the socket, queueing it if necessary. `string` and the
callback are both optional. If a callback is given, it will be invoked when the
socket receives a pong frame whose content matches `string`. Returns `false` if
frames can no longer be sent, or if the driver does not support ping/pong.
#### `driver.pong(string = '')`
Sends a pong frame over the socket, queueing it if necessary. `string` is
optional. Returns `false` if frames can no longer be sent, or if the driver does
not support ping/pong.
You don't need to call this when a ping frame is received; pings are replied to
automatically by the driver. This method is for sending unsolicited pongs.
#### `driver.close()`
Initiates the closing handshake if the socket is still open. For drivers with no
closing handshake, this will result in the immediate execution of the
`on('close')` driver. For drivers with a closing handshake, this sends a closing
frame and `emit('close')` will execute when a response is received or a protocol
error occurs.
#### `driver.version`
Returns the WebSocket version in use as a string. Will either be `hixie-75`,
`hixie-76` or `hybi-$version`.
#### `driver.protocol`
Returns a string containing the selected subprotocol, if any was agreed upon
using the `Sec-WebSocket-Protocol` mechanism. This value becomes available after
`emit('open')` has fired.
## License
(The MIT License)
Copyright (c) 2010-2016 James Coglan
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.

View File

@@ -0,0 +1,22 @@
var net = require('net'),
websocket = require('..'),
deflate = require('permessage-deflate');
var server = net.createServer(function(connection) {
var driver = websocket.server();
driver.addExtension(deflate);
driver.on('connect', function() {
if (websocket.isWebSocket(driver)) driver.start();
});
driver.on('close', function() { connection.end() });
connection.on('error', function() {});
connection.pipe(driver.io);
driver.io.pipe(connection);
driver.messages.pipe(driver.messages);
});
server.listen(process.argv[2]);

View File

@@ -0,0 +1,84 @@
{
"_args": [
[
"websocket-driver@>=0.5.1",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/faye-websocket"
]
],
"_from": "websocket-driver@>=0.5.1",
"_id": "websocket-driver@0.6.4",
"_inCache": true,
"_installable": true,
"_location": "/live-server/websocket-driver",
"_nodeVersion": "5.2.0",
"_npmUser": {
"email": "jcoglan@gmail.com",
"name": "jcoglan"
},
"_npmVersion": "3.3.12",
"_phantomChildren": {},
"_requested": {
"name": "websocket-driver",
"raw": "websocket-driver@>=0.5.1",
"rawSpec": ">=0.5.1",
"scope": null,
"spec": ">=0.5.1",
"type": "range"
},
"_requiredBy": [
"/live-server/faye-websocket"
],
"_resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.4.tgz",
"_shasum": "65b84d02113480d3fc05e63e809322042bdc940b",
"_shrinkwrap": null,
"_spec": "websocket-driver@>=0.5.1",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/faye-websocket",
"author": {
"email": "jcoglan@gmail.com",
"name": "James Coglan",
"url": "http://jcoglan.com/"
},
"bugs": {
"url": "https://github.com/faye/websocket-driver-node/issues"
},
"dependencies": {
"websocket-extensions": ">=0.1.1"
},
"description": "WebSocket protocol handler with pluggable I/O",
"devDependencies": {
"jstest": "",
"permessage-deflate": ""
},
"directories": {},
"dist": {
"shasum": "65b84d02113480d3fc05e63e809322042bdc940b",
"tarball": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.4.tgz"
},
"engines": {
"node": ">=0.6.0"
},
"gitHead": "2be829546b462aa7d552214e17d6f3e42b6a4bd0",
"homepage": "https://github.com/faye/websocket-driver-node",
"keywords": [
"websocket"
],
"license": "MIT",
"main": "./lib/websocket/driver",
"maintainers": [
{
"email": "jcoglan@gmail.com",
"name": "jcoglan"
}
],
"name": "websocket-driver",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/faye/websocket-driver-node.git"
},
"scripts": {
"test": "jstest spec/runner.js"
},
"version": "0.6.4"
}

View File

@@ -0,0 +1,8 @@
### 0.1.1 / 2015-02-19
* Prevent sessions being closed before they have finished processing messages
* Add a callback to `Extensions.close()` so the caller can tell when it's safe to close the socket
### 0.1.0 / 2014-12-12
* Initial release

View File

@@ -0,0 +1,354 @@
# websocket-extensions [![Build status](https://secure.travis-ci.org/faye/websocket-extensions-node.svg)](http://travis-ci.org/faye/websocket-extensions-node)
A minimal framework that supports the implementation of WebSocket extensions in
a way that's decoupled from the main protocol. This library aims to allow a
WebSocket extension to be written and used with any protocol library, by
defining abstract representations of frames and messages that allow modules to
co-operate.
`websocket-extensions` provides a container for registering extension plugins,
and provides all the functions required to negotiate which extensions to use
during a session via the `Sec-WebSocket-Extensions` header. By implementing the
APIs defined in this document, an extension may be used by any WebSocket library
based on this framework.
## Installation
```
$ npm install websocket-extensions
```
## Usage
There are two main audiences for this library: authors implementing the
WebSocket protocol, and authors implementing extensions. End users of a
WebSocket library or an extension should be able to use any extension by passing
it as an argument to their chosen protocol library, without needing to know how
either of them work, or how the `websocket-extensions` framework operates.
The library is designed with the aim that any protocol implementation and any
extension can be used together, so long as they support the same abstract
representation of frames and messages.
### Data types
The APIs provided by the framework rely on two data types; extensions will
expect to be given data and to be able to return data in these formats:
#### *Frame*
*Frame* is a structure representing a single WebSocket frame of any type. Frames
are simple objects that must have at least the following properties, which
represent the data encoded in the frame:
| property | description |
| ------------ | ------------------------------------------------------------------ |
| `final` | `true` if the `FIN` bit is set, `false` otherwise |
| `rsv1` | `true` if the `RSV1` bit is set, `false` otherwise |
| `rsv2` | `true` if the `RSV2` bit is set, `false` otherwise |
| `rsv3` | `true` if the `RSV3` bit is set, `false` otherwise |
| `opcode` | the numeric opcode (`0`, `1`, `2`, `8`, `9`, or `10`) of the frame |
| `masked` | `true` if the `MASK` bit is set, `false` otherwise |
| `maskingKey` | a 4-byte `Buffer` if `masked` is `true`, otherwise `null` |
| `payload` | a `Buffer` containing the (unmasked) application data |
#### *Message*
A *Message* represents a complete application message, which can be formed from
text, binary and continuation frames. It has the following properties:
| property | description |
| -------- | ----------------------------------------------------------------- |
| `rsv1` | `true` if the first frame of the message has the `RSV1` bit set |
| `rsv2` | `true` if the first frame of the message has the `RSV2` bit set |
| `rsv3` | `true` if the first frame of the message has the `RSV3` bit set |
| `opcode` | the numeric opcode (`1` or `2`) of the first frame of the message |
| `data` | the concatenation of all the frame payloads in the message |
### For driver authors
A driver author is someone implementing the WebSocket protocol proper, and who
wishes end users to be able to use WebSocket extensions with their library.
At the start of a WebSocket session, on both the client and the server side,
they should begin by creating an extension container and adding whichever
extensions they want to use.
```js
var Extensions = require('websocket-extensions'),
deflate = require('permessage-deflate');
var exts = new Extensions();
exts.add(deflate);
```
In the following examples, `exts` refers to this `Extensions` instance.
#### Client sessions
Clients will use the methods `generateOffer()` and `activate(header)`.
As part of the handshake process, the client must send a
`Sec-WebSocket-Extensions` header to advertise that it supports the registered
extensions. This header should be generated using:
```js
request.headers['sec-websocket-extensions'] = exts.generateOffer();
```
This returns a string, for example `"permessage-deflate;
client_max_window_bits"`, that represents all the extensions the client is
offering to use, and their parameters. This string may contain multiple offers
for the same extension.
When the client receives the handshake response from the server, it should pass
the incoming `Sec-WebSocket-Extensions` header in to `exts` to activate the
extensions the server has accepted:
```js
exts.activate(response.headers['sec-websocket-extensions']);
```
If the server has sent any extension responses that the client does not
recognize, or are in conflict with one another for use of RSV bits, or that use
invalid parameters for the named extensions, then `exts.activate()` will
`throw`. In this event, the client driver should fail the connection with
closing code `1010`.
#### Server sessions
Servers will use the method `generateResponse(header)`.
A server session needs to generate a `Sec-WebSocket-Extensions` header to send
in its handshake response:
```js
var clientOffer = request.headers['sec-websocket-extensions'],
extResponse = exts.generateResponse(clientOffer);
response.headers['sec-websocket-extensions'] = extResponse;
```
Calling `exts.generateResponse(header)` activates those extensions the client
has asked to use, if they are registered, asks each extension for a set of
response parameters, and returns a string containing the response parameters for
all accepted extensions.
#### In both directions
Both clients and servers will use the methods `validFrameRsv(frame)`,
`processIncomingMessage(message)` and `processOutgoingMessage(message)`.
The WebSocket protocol requires that frames do not have any of the `RSV` bits
set unless there is an extension in use that allows otherwise. When processing
an incoming frame, sessions should pass a *Frame* object to:
```js
exts.validFrameRsv(frame)
```
If this method returns `false`, the session should fail the WebSocket connection
with closing code `1002`.
To pass incoming messages through the extension stack, a session should
construct a *Message* object according to the above datatype definitions, and
call:
```js
exts.processIncomingMessage(message, function(error, msg) {
// hand the message off to the application
});
```
If any extensions fail to process the message, then the callback will yield an
error and the session should fail the WebSocket connection with closing code
`1010`. If `error` is `null`, then `msg` should be passed on to the application.
To pass outgoing messages through the extension stack, a session should
construct a *Message* as before, and call:
```js
exts.processOutgoingMessage(message, function(error, msg) {
// write message to the transport
});
```
If any extensions fail to process the message, then the callback will yield an
error and the session should fail the WebSocket connection with closing code
`1010`. If `error` is `null`, then `message` should be converted into frames
(with the message's `rsv1`, `rsv2`, `rsv3` and `opcode` set on the first frame)
and written to the transport.
At the end of the WebSocket session (either when the protocol is explicitly
ended or the transport connection disconnects), the driver should call:
```js
exts.close(function() {})
```
The callback is invoked when all extensions have finished processing any
messages in the pipeline and it's safe to close the socket.
### For extension authors
An extension author is someone implementing an extension that transforms
WebSocket messages passing between the client and server. They would like to
implement their extension once and have it work with any protocol library.
Extension authors will not install `websocket-extensions` or call it directly.
Instead, they should implement the following API to allow their extension to
plug into the `websocket-extensions` framework.
An `Extension` is any object that has the following properties:
| property | description |
| -------- | ---------------------------------------------------------------------------- |
| `name` | a string containing the name of the extension as used in negotiation headers |
| `type` | a string, must be `"permessage"` |
| `rsv1` | either `true` if the extension uses the RSV1 bit, `false` otherwise |
| `rsv2` | either `true` if the extension uses the RSV2 bit, `false` otherwise |
| `rsv3` | either `true` if the extension uses the RSV3 bit, `false` otherwise |
It must also implement the following methods:
```js
ext.createClientSession()
```
This returns a *ClientSession*, whose interface is defined below.
```js
ext.createServerSession(offers)
```
This takes an array of offer params and returns a *ServerSession*, whose
interface is defined below. For example, if the client handshake contains the
offer header:
```
Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; server_max_window_bits=8, \
permessage-deflate; server_max_window_bits=15
```
then the `permessage-deflate` extension will receive the call:
```js
ext.createServerSession([
{server_no_context_takeover: true, server_max_window_bits: 8},
{server_max_window_bits: 15}
]);
```
The extension must decide which set of parameters it wants to accept, if any,
and return a *ServerSession* if it wants to accept the parameters and `null`
otherwise.
#### *ClientSession*
A *ClientSession* is the type returned by `ext.createClientSession()`. It must
implement the following methods, as well as the *Session* API listed below.
```js
clientSession.generateOffer()
// e.g. -> [
// {server_no_context_takeover: true, server_max_window_bits: 8},
// {server_max_window_bits: 15}
// ]
```
This must return a set of parameters to include in the client's
`Sec-WebSocket-Extensions` offer header. If the session wants to offer multiple
configurations, it can return an array of sets of parameters as shown above.
```js
clientSession.activate(params) // -> true
```
This must take a single set of parameters from the server's handshake response
and use them to configure the client session. If the client accepts the given
parameters, then this method must return `true`. If it returns any other value,
the framework will interpret this as the client rejecting the response, and will
`throw`.
#### *ServerSession*
A *ServerSession* is the type returned by `ext.createServerSession(offers)`. It
must implement the following methods, as well as the *Session* API listed below.
```js
serverSession.generateResponse()
// e.g. -> {server_max_window_bits: 8}
```
This returns the set of parameters the server session wants to send in its
`Sec-WebSocket-Extensions` response header. Only one set of parameters is
returned to the client per extension. Server sessions that would confict on
their use of RSV bits are not activated.
#### *Session*
The *Session* API must be implemented by both client and server sessions. It
contains two methods, `processIncomingMessage(message)` and
`processOutgoingMessage(message)`.
```js
session.processIncomingMessage(message, function(error, msg) { ... })
```
The session must implement this method to take an incoming *Message* as defined
above, transform it in any way it needs, then return it via the callback. If
there is an error processing the message, this method should yield an error as
the first argument.
```js
session.processOutgoingMessage(message, function(error, msg) { ... })
```
The session must implement this method to take an outgoing *Message* as defined
above, transform it in any way it needs, then return it via the callback. If
there is an error processing the message, this method should yield an error as
the first argument.
Note that both `processIncomingMessage()` and `processOutgoingMessage()` can
perform their logic asynchronously, are allowed to process multiple messages
concurrently, and are not required to complete working on messages in the same
order the messages arrive. `websocket-extensions` will reorder messages as your
extension emits them and will make sure every extension is given messages in the
order they arrive from the driver. This allows extensions to maintain state that
depends on the messages' wire order, for example keeping a DEFLATE compression
context between messages.
```js
session.close()
```
The framework will call this method when the WebSocket session ends, allowing
the session to release any resources it's using.
## Examples
* Consumer: [websocket-driver](https://github.com/faye/websocket-driver-node)
* Provider: [permessage-deflate](https://github.com/faye/permessage-deflate-node)
## License
(The MIT License)
Copyright (c) 2014-2015 James Coglan
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.

View File

@@ -0,0 +1,81 @@
{
"_args": [
[
"websocket-extensions@>=0.1.1",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/websocket-driver"
]
],
"_from": "websocket-extensions@>=0.1.1",
"_id": "websocket-extensions@0.1.1",
"_inCache": true,
"_installable": true,
"_location": "/live-server/websocket-extensions",
"_nodeVersion": "0.12.0",
"_npmUser": {
"email": "jcoglan@gmail.com",
"name": "jcoglan"
},
"_npmVersion": "2.5.1",
"_phantomChildren": {},
"_requested": {
"name": "websocket-extensions",
"raw": "websocket-extensions@>=0.1.1",
"rawSpec": ">=0.1.1",
"scope": null,
"spec": ">=0.1.1",
"type": "range"
},
"_requiredBy": [
"/live-server/websocket-driver"
],
"_resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz",
"_shasum": "76899499c184b6ef754377c2dbb0cd6cb55d29e7",
"_shrinkwrap": null,
"_spec": "websocket-extensions@>=0.1.1",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist/node_modules/live-server/node_modules/websocket-driver",
"author": {
"email": "jcoglan@gmail.com",
"name": "James Coglan",
"url": "http://jcoglan.com/"
},
"bugs": {
"url": "http://github.com/faye/websocket-extensions-node/issues"
},
"dependencies": {},
"description": "Generic extension manager for WebSocket connections",
"devDependencies": {
"jstest": ""
},
"directories": {},
"dist": {
"shasum": "76899499c184b6ef754377c2dbb0cd6cb55d29e7",
"tarball": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz"
},
"engines": {
"node": ">=0.6.0"
},
"gitHead": "89104ddd48ccbbff20237e3fc5c123b4d4c5d9c1",
"homepage": "http://github.com/faye/websocket-extensions-node",
"keywords": [
"websocket"
],
"license": "MIT",
"main": "./lib/websocket_extensions",
"maintainers": [
{
"email": "jcoglan@gmail.com",
"name": "jcoglan"
}
],
"name": "websocket-extensions",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/faye/websocket-extensions-node.git"
},
"scripts": {
"test": "jstest spec/runner.js"
},
"version": "0.1.1"
}

View File

@@ -0,0 +1,129 @@
{
"_args": [
[
"live-server@^0.9.2",
"/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist"
]
],
"_from": "live-server@>=0.9.2 <0.10.0",
"_id": "live-server@0.9.2",
"_inCache": true,
"_installable": true,
"_location": "/live-server",
"_npmOperationalInternal": {
"host": "packages-9-west.internal.npmjs.com",
"tmp": "tmp/live-server-0.9.2.tgz_1455644619913_0.7115735381375998"
},
"_npmUser": {
"email": "tapiovierros@gmail.com",
"name": "tapio"
},
"_npmVersion": "1.4.21",
"_phantomChildren": {
"debug": "2.2.0",
"destroy": "1.0.4",
"escape-html": "1.0.3",
"etag": "1.7.0",
"fresh": "0.3.0",
"http-errors": "1.3.1",
"ms": "0.7.1",
"on-finished": "2.3.0",
"pinkie-promise": "2.0.1",
"range-parser": "1.0.3",
"statuses": "1.2.1"
},
"_requested": {
"name": "live-server",
"raw": "live-server@^0.9.2",
"rawSpec": "^0.9.2",
"scope": null,
"spec": ">=0.9.2 <0.10.0",
"type": "range"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/live-server/-/live-server-0.9.2.tgz",
"_shasum": "8bcb58e846331f3f2b6d172f95d4f70a4fcf3760",
"_shrinkwrap": null,
"_spec": "live-server@^0.9.2",
"_where": "/Users/mromano/dev/dev-platform-webcomponents/ng2-components/ng2-alfresco-documentslist",
"author": {
"name": "Tapio Vierros"
},
"bin": {
"live-server": "./live-server.js"
},
"bugs": {
"url": "https://github.com/tapio/live-server/issues"
},
"dependencies": {
"colors": "latest",
"connect": "3.4.x",
"event-stream": "latest",
"faye-websocket": "0.10.x",
"morgan": "^1.6.1",
"object-assign": "latest",
"opn": "latest",
"send": "latest",
"serve-index": "^1.7.2",
"watchr": "2.3.x"
},
"description": "simple development http server with live reload capability",
"devDependencies": {
"mocha": "^2.3.3",
"supertest": "^1.0.1"
},
"directories": {},
"dist": {
"shasum": "8bcb58e846331f3f2b6d172f95d4f70a4fcf3760",
"tarball": "https://registry.npmjs.org/live-server/-/live-server-0.9.2.tgz"
},
"engines": {
"node": ">=0.10.0"
},
"eslintConfig": {
"env": {
"node": true
},
"rules": {
"curly": 0,
"eqeqeq": 1,
"no-process-exit": 0,
"no-shadow": 1,
"no-unused-vars": 1,
"quotes": 0,
"strict": 0
}
},
"gitHead": "9b303b31234e8fa6e5dc3bbebab9ff02d1fc7760",
"homepage": "https://github.com/tapio/live-server#readme",
"keywords": [
"front-end",
"development",
"tool",
"server",
"http",
"cli"
],
"license": "MIT",
"maintainers": [
{
"email": "tapiovierros@gmail.com",
"name": "tapio"
}
],
"name": "live-server",
"optionalDependencies": {},
"preferGlobal": true,
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/tapio/live-server.git"
},
"scripts": {
"lint": "jshint *.js; eslint *.js",
"test": "npm run lint && mocha test"
},
"version": "0.9.2"
}

View File

@@ -0,0 +1,43 @@
var request = require('supertest');
var path = require('path');
var liveServer = require('..').start({
root: path.join(__dirname, "data"),
port: 0,
open: false
});
describe('basic functional tests', function(){
it('should respond with index.html', function(done){
request(liveServer)
.get('/')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/hello world/i)
.expect(200, done);
});
it('should have injected script', function(done){
request(liveServer)
.get('/')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/<script [^]+?live reload enabled[^]+?<\/script>/i)
.expect(200, done);
});
it('should inject also svg files', function(done){
request(liveServer)
.get('/test.svg')
.expect('Content-Type', 'image/svg+xml')
.expect(function(res) {
if (res.body.toString().indexOf("Live reload enabled") == -1)
throw new Error("injected code not found");
})
.expect(200, done);
});
xit('should have WebSocket connection', function(done){
done(); // todo
});
xit('should reload on page change', function(done){
done(); // todo
});
xit('should reload (without refreshing) on css change', function(done){
done(); // todo
});
});

View File

@@ -0,0 +1,48 @@
var assert = require('assert');
var path = require('path');
var exec = require('child_process').execFile;
var cmd = path.join(__dirname, "..", "live-server.js");
var opts = {
timeout: 2000,
maxBuffer: 1024
};
describe('command line usage', function() {
it('--version', function(done) {
exec(cmd, [ "--version" ], opts, function(error, stdout, stdin) {
assert(!error, error);
assert(stdout.indexOf("live-server") == 0, "version not found");
done();
});
});
it('--help', function(done) {
exec(cmd, [ "--help" ], opts, function(error, stdout, stdin) {
assert(!error, error);
assert(stdout.indexOf("Usage: live-server") == 0, "usage not found");
done();
});
});
it('--quiet', function(done) {
exec(cmd, [ "--quiet", "--no-browser", "--test" ], opts, function(error, stdout, stdin) {
assert(!error, error);
assert(stdout === "", "stdout not empty");
done();
});
});
it('--port', function(done) {
exec(cmd, [ "--port=16123", "--no-browser", "--test" ], opts, function(error, stdout, stdin) {
assert(!error, error);
assert(stdout.indexOf("Serving") == 0, "serving string not found");
assert(stdout.indexOf("at http://127.0.0.1:16123") != -1, "port string not found");
done();
});
});
it('--host', function(done) {
exec(cmd, [ "--host=localhost", "--no-browser", "--test" ], opts, function(error, stdout, stdin) {
assert(!error, error);
assert(stdout.indexOf("Serving") == 0, "serving string not found");
assert(stdout.indexOf("at http://localhost:") != -1, "host string not found");
done();
});
});
});

View File

@@ -0,0 +1 @@
{{this imitates some kind of template fragment}}

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Live-server Test Page</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Hello world.</h1>
<p>Edit my css for a live-reload without refreshing.</p>
</body>
</html>

View File

@@ -0,0 +1 @@
h1 { color: red; }

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Live-server Test Page</title>
</head>
<body>
<h1>Subdirectory</h1>
</body>
</html>

View File

@@ -0,0 +1,14 @@
<svg width="100%" height="100%" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">
// <![CDATA[
function change(evt) {
var target = evt.target;
var radius = target.getAttribute("r");
radius = (radius == 15) ? 45 : 15
target.setAttribute("r", radius);
}
// ]]>
</script>
<circle cx="50" cy="50" r="45" fill="green" onclick="change(evt)" />
</svg>

After

Width:  |  Height:  |  Size: 401 B

View File

@@ -0,0 +1,20 @@
var request = require('supertest');
var path = require('path');
var liveServer = require('..').start({
root: path.join(__dirname, "data"),
port: 0,
open: false,
mount: [[ "/mounted", path.join(__dirname, "data", "sub") ]]
});
describe('mount tests', function() {
it('should respond with sub.html', function(done) {
request(liveServer)
.get('/mounted/sub.html')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/Subdirectory/i)
.expect(200, done);
});
});

View File

@@ -0,0 +1,7 @@
describe('acceptance tests: ', function(){
require('./cli');
require('./acceptance');
require('./mount');
});