This commit is contained in:
martin 2018-06-01 10:24:32 +01:00
parent 92fa8cef95
commit 8d592c458f
85 changed files with 10892 additions and 2428 deletions

File diff suppressed because it is too large Load Diff

29
news.js
View File

@ -12,6 +12,31 @@ var logger = log4js.getLogger();
// feeds.simple_test_feed = require("./config/feed").feed; // feeds.simple_test_feed = require("./config/feed").feed;
// Or define in-line // Or define in-line
const f = ["http://qz.com/feed/",
"http://feeds2.feedburner.com/businessinsider",
"http://feeds.reuters.com/reuters/UKTopNews",
"http://feeds.reuters.com/reuters/UKdomesticNews",
"http://feeds.reuters.com/reuters/UKWorldNews",
"http://feeds.reuters.com/reuters/topNews",
"http://feeds.reuters.com/Reuters/worldNews",
"http://hosted2.ap.org/atom/APDEFAULT/cae69a7523db45408eeb2b3a98c0c9c5",
"http://www.cityam.com/feeds/main.xml",
"http://www.londonlovesbusiness.com/navrss?navsectioncode=121",
"http://www.ibtimes.co.uk/rss/uk",
"http://feeds.bbci.co.uk/news/rss.xml?edition=uk",
"http://feeds.bbci.co.uk/news/scotland/rss.xml?edition=uk",
"http://news.google.com/?output=rss",
"http://feeds.feedburner.com/TheAtlantic",
"http://www.telegraph.co.uk/news/rss.xml",
"http://www.guardian.co.uk/rssfeed/0,,1,00.xml",
"http://feeds.marketwatch.com/marketwatch/topstories",
"http://feeds.feedburner.com/wingsoverscotland/FgKv",
"http://bellacaledonia.org.uk/feed/",
"http://www.theweek.co.uk/feeds/all",
"http://fivethirtyeight.com/all/feed"];
feeds.simple_test_feed = { feeds.simple_test_feed = {
'feed_name': 'feed', 'feed_name': 'feed',
'default_count': 1, 'default_count': 1,
@ -68,9 +93,9 @@ feeds.simple_test_feed = {
'count': 100, 'count': 100,
'feed_url': 'http://45.33.114.116:8080/http%3A%2F%2Fwww.theweek.co.uk%2Ffeeds%2Fall' 'feed_url': 'http://45.33.114.116:8080/http%3A%2F%2Fwww.theweek.co.uk%2Ffeeds%2Fall'
}, {'count': 100, 'feed_url': 'http://45.33.114.116:8080/http%3A%2F%2Ffivethirtyeight.com%2Fall%2Ffeed'}] }, {'count': 100, 'feed_url': 'http://45.33.114.116:8080/http%3A%2F%2Ffivethirtyeight.com%2Fall%2Ffeed'}]
} };
;
var braider_options = { var braider_options = {
feeds: feeds, feeds: feeds,
indent: ' ', indent: ' ',

78
node_modules/ejs/Jakefile generated vendored
View File

@ -1,10 +1,12 @@
var fs = require('fs') var fs = require('fs');
, buildOpts = { var execSync = require('child_process').execSync;
printStdout: true var exec = function (cmd) {
, printStderr: true execSync(cmd, {stdio: 'inherit'});
}; };
task('build', ['browserify', 'minify'], function () { /* global jake, task, desc, publishTask */
task('build', ['lint', 'clean', 'browserify', 'minify'], function () {
console.log('Build completed.'); console.log('Build completed.');
}); });
@ -12,35 +14,57 @@ desc('Cleans browerified/minified files and package files');
task('clean', ['clobber'], function () { task('clean', ['clobber'], function () {
jake.rmRf('./ejs.js'); jake.rmRf('./ejs.js');
jake.rmRf('./ejs.min.js'); jake.rmRf('./ejs.min.js');
console.log('Cleaned up compiled files.');
}); });
task('browserify', {async: true}, function () { desc('Lints the source code');
jake.exec('./node_modules/browserify/bin/cmd.js lib/ejs.js > ejs.js', task('lint', function () {
buildOpts, function () { exec('./node_modules/.bin/eslint "**/*.js" Jakefile');
console.log('Browserification completed.'); console.log('Linting completed.');
setTimeout(complete, 0);
});
}); });
task('minify', {async: true}, function () { task('browserify', function () {
jake.exec('./node_modules/uglify-js/bin/uglifyjs ejs.js > ejs.min.js', exec('./node_modules/browserify/bin/cmd.js --standalone ejs lib/ejs.js > ejs.js');
buildOpts, function () { console.log('Browserification completed.');
console.log('Minification completed.'); });
setTimeout(complete, 0);
}); task('minify', function () {
exec('./node_modules/uglify-js/bin/uglifyjs ejs.js > ejs.min.js');
console.log('Minification completed.');
});
task('doc', function (dev) {
jake.rmRf('out');
var p = dev ? '-p' : '';
exec('./node_modules/.bin/jsdoc ' + p + ' -c jsdoc.json lib/* docs/jsdoc/*');
console.log('Documentation generated.');
});
task('docPublish', ['doc'], function () {
fs.writeFileSync('out/CNAME', 'api.ejs.co');
console.log('Pushing docs to gh-pages...');
exec('./node_modules/.bin/git-directory-deploy --directory out/');
console.log('Docs published to gh-pages.');
});
task('test', ['lint'], function () {
exec('./node_modules/.bin/mocha');
}); });
publishTask('ejs', ['build'], function () { publishTask('ejs', ['build'], function () {
this.packageFiles.include([ this.packageFiles.include([
'Jakefile' 'Jakefile',
, 'README.md' 'README.md',
, 'LICENSE' 'LICENSE',
, 'package.json' 'package.json',
, 'ejs.js' 'ejs.js',
, 'ejs.min.js' 'ejs.min.js',
, 'lib/**' 'lib/**'
, 'test/**'
]); ]);
}); });
jake.Task.publish.on('complete', function () {
console.log('Updating hosted docs...');
console.log('If this fails, run jake docPublish to re-try.');
jake.Task.docPublish.invoke();
});

104
node_modules/ejs/README.md generated vendored
View File

@ -3,7 +3,8 @@
Embedded JavaScript templates Embedded JavaScript templates
[![Build Status](https://img.shields.io/travis/mde/ejs/master.svg?style=flat)](https://travis-ci.org/mde/ejs) [![Build Status](https://img.shields.io/travis/mde/ejs/master.svg?style=flat)](https://travis-ci.org/mde/ejs)
[![Developing Dependencies](https://img.shields.io/david/dev/mde/ejs.svg?style=flat)](https://david-dm.org/mde/ejs#info=devDependencies) [![Developing Dependencies](https://img.shields.io/david/dev/mde/ejs.svg?style=flat)](https://david-dm.org/mde/ejs?type=dev)
[![Known Vulnerabilities](https://snyk.io/test/npm/ejs/badge.svg?style=flat-square)](https://snyk.io/test/npm/ejs)
## Installation ## Installation
@ -18,7 +19,7 @@ $ npm install ejs
* Unescaped raw output with `<%- %>` * Unescaped raw output with `<%- %>`
* Newline-trim mode ('newline slurping') with `-%>` ending tag * Newline-trim mode ('newline slurping') with `-%>` ending tag
* Whitespace-trim mode (slurp all whitespace) for control flow with `<%_ _%>` * Whitespace-trim mode (slurp all whitespace) for control flow with `<%_ _%>`
* Custom delimiters (e.g., use '<? ?>' instead of '<% %>') * Custom delimiters (e.g., use `<? ?>` instead of `<% %>`)
* Includes * Includes
* Client-side support * Client-side support
* Static caching of intermediate JavaScript * Static caching of intermediate JavaScript
@ -33,10 +34,12 @@ $ npm install ejs
<% } %> <% } %>
``` ```
Try EJS online at: https://ionicabizau.github.io/ejs-playground/.
## Usage ## Usage
```javascript ```javascript
var template = ejs.compile(str, options); let template = ejs.compile(str, options);
template(data); template(data);
// => Rendered HTML string // => Rendered HTML string
@ -50,35 +53,43 @@ ejs.renderFile(filename, data, options, function(err, str){
It is also possible to use `ejs.render(dataAndOptions);` where you pass It is also possible to use `ejs.render(dataAndOptions);` where you pass
everything in a single object. In that case, you'll end up with local variables everything in a single object. In that case, you'll end up with local variables
for all the passed options. However, be aware that your code could break if we for all the passed options. However, be aware that your code could break if we
add an option with the same name as one of your data object's properties. add an option with the same name as one of your data object's properties.
Therefore, we do not recommend using this shortcut. Therefore, we do not recommend using this shortcut.
## Options ## Options
- `cache` Compiled functions are cached, requires `filename` - `cache` Compiled functions are cached, requires `filename`
- `filename` The name of the file being rendered. Not required if you - `filename` The name of the file being rendered. Not required if you
are using `renderFile()`. Used by `cache` to key caches, and for includes. are using `renderFile()`. Used by `cache` to key caches, and for includes.
- `context` Function execution context - `root` Set project root for includes with an absolute path (/file.ejs).
- `compileDebug` When `false` no debug instrumentation is compiled - `context` Function execution context
- `client` When `true`, compiles a function that can be rendered - `compileDebug` When `false` no debug instrumentation is compiled
in the browser without needing to load the EJS Runtime - `client` When `true`, compiles a function that can be rendered
in the browser without needing to load the EJS Runtime
([ejs.min.js](https://github.com/mde/ejs/releases/latest)). ([ejs.min.js](https://github.com/mde/ejs/releases/latest)).
- `delimiter` Character to use with angle brackets for open/close - `delimiter` Character to use with angle brackets for open/close
- `debug` Output generated function body - `debug` Output generated function body
- `strict` When set to `true`, generated function is in strict mode - `strict` When set to `true`, generated function is in strict mode
- `_with` Whether or not to use `with() {}` constructs. If `false` then the locals will be stored in the `locals` object. Set to `false` in strict mode. - `_with` Whether or not to use `with() {}` constructs. If `false`
- `localsName` Name to use for the object storing local variables when not using `with` Defaults to `locals` then the locals will be stored in the `locals` object. Set to `false` in strict mode.
- `rmWhitespace` Remove all safe-to-remove whitespace, including leading - `localsName` Name to use for the object storing local variables when not using
`with` Defaults to `locals`
- `rmWhitespace` Remove all safe-to-remove whitespace, including leading
and trailing whitespace. It also enables a safer version of `-%>` line and trailing whitespace. It also enables a safer version of `-%>` line
slurping for all scriptlet tags (it does not strip new lines of tags in slurping for all scriptlet tags (it does not strip new lines of tags in
the middle of a line). the middle of a line).
- `escape` The escaping function used with `<%=` construct. It is - `escape` The escaping function used with `<%=` construct. It is
used in rendering and is `.toString()`ed in the generation of client functions. (By default escapes XML). used in rendering and is `.toString()`ed in the generation of client functions.
(By default escapes XML).
- `outputFunctionName` Set to a string (e.g., 'echo' or 'print') for a function to print
output inside scriptlet tags.
- `async` When `true`, EJS will use an async function for rendering. (Depends
on async/await support in the JS runtime.
This project uses [JSDoc](http://usejsdoc.org/). For the full public API This project uses [JSDoc](http://usejsdoc.org/). For the full public API
documentation, clone the repository and run `npm run doc`. This will run JSDoc documentation, clone the repository and run `npm run doc`. This will run JSDoc
with the proper options and output the documentation to `out/`. If you want with the proper options and output the documentation to `out/`. If you want
the both the public & private API docs, run `npm run devdoc` instead. the both the public & private API docs, run `npm run devdoc` instead.
## Tags ## Tags
@ -89,6 +100,7 @@ the both the public & private API docs, run `npm run devdoc` instead.
- `<%-` Outputs the unescaped value into the template - `<%-` Outputs the unescaped value into the template
- `<%#` Comment tag, no execution, no output - `<%#` Comment tag, no execution, no output
- `<%%` Outputs a literal '<%' - `<%%` Outputs a literal '<%'
- `%%>` Outputs a literal '%>'
- `%>` Plain ending tag - `%>` Plain ending tag
- `-%>` Trim-mode ('newline slurp') tag, trims following newline - `-%>` Trim-mode ('newline slurp') tag, trims following newline
- `_%>` 'Whitespace Slurping' ending tag, removes all whitespace after it - `_%>` 'Whitespace Slurping' ending tag, removes all whitespace after it
@ -98,11 +110,11 @@ For the full syntax documentation, please see [docs/syntax.md](https://github.co
## Includes ## Includes
Includes either have to be an absolute path, or, if not, are assumed as Includes either have to be an absolute path, or, if not, are assumed as
relative to the template with the `include` call. For example if you are relative to the template with the `include` call. For example if you are
including `./views/user/show.ejs` from `./views/users.ejs` you would including `./views/user/show.ejs` from `./views/users.ejs` you would
use `<%- include('user/show') %>`. use `<%- include('user/show') %>`.
You must specify the `filename` option for the template with the `include` You must specify the `filename` option for the template with the `include`
call unless you are using `renderFile()`. call unless you are using `renderFile()`.
You'll likely want to use the raw output tag (`<%-`) with your include to avoid You'll likely want to use the raw output tag (`<%-`) with your include to avoid
@ -129,7 +141,7 @@ still supported.
Custom delimiters can be applied on a per-template basis, or globally: Custom delimiters can be applied on a per-template basis, or globally:
```javascript ```javascript
var ejs = require('ejs'), let ejs = require('ejs'),
users = ['geddy', 'neil', 'alex']; users = ['geddy', 'neil', 'alex'];
// Just one template // Just one template
@ -149,8 +161,8 @@ functions used to render templates. It's easy to plug in LRU caching using
Node's `lru-cache` library: Node's `lru-cache` library:
```javascript ```javascript
var ejs = require('ejs') let ejs = require('ejs'),
, LRU = require('lru-cache'); LRU = require('lru-cache');
ejs.cache = LRU(100); // LRU cache with 100-item limit ejs.cache = LRU(100); // LRU cache with 100-item limit
``` ```
@ -158,6 +170,21 @@ If you want to clear the EJS cache, call `ejs.clearCache`. If you're using the
LRU cache and need a different limit, simple reset `ejs.cache` to a new instance LRU cache and need a different limit, simple reset `ejs.cache` to a new instance
of the LRU. of the LRU.
## Custom file loader
The default file loader is `fs.readFileSync`, if you want to customize it, you can set ejs.fileLoader.
```javascript
let ejs = require('ejs');
let myFileLoad = function (filePath) {
return 'myFileLoad: ' + fs.readFileSync(filePath);
};
ejs.fileLoader = myFileLoad;
```
With this feature, you can preprocess the template before reading it.
## Layouts ## Layouts
EJS does not specifically support blocks, but layouts can be implemented by EJS does not specifically support blocks, but layouts can be implemented by
@ -178,8 +205,8 @@ including headers and footers, like so:
## Client-side support ## Client-side support
Go to the [Latest Release](https://github.com/mde/ejs/releases/latest), download Go to the [Latest Release](https://github.com/mde/ejs/releases/latest), download
`./ejs.js` or `./ejs.min.js`. Alternately, you can compile it yourself by cloning `./ejs.js` or `./ejs.min.js`. Alternately, you can compile it yourself by cloning
the repository and running `jake build` (or `$(npm bin)/jake build` if jake is the repository and running `jake build` (or `$(npm bin)/jake build` if jake is
not installed globally). not installed globally).
Include one of these files on your page, and `ejs` should be available globally. Include one of these files on your page, and `ejs` should be available globally.
@ -190,7 +217,7 @@ Include one of these files on your page, and `ejs` should be available globally.
<div id="output"></div> <div id="output"></div>
<script src="ejs.min.js"></script> <script src="ejs.min.js"></script>
<script> <script>
var people = ['geddy', 'neil', 'alex'], let people = ['geddy', 'neil', 'alex'],
html = ejs.render('<%= people.join(", "); %>', {people: people}); html = ejs.render('<%= people.join(", "); %>', {people: people});
// With jQuery: // With jQuery:
$('#output').html(html); $('#output').html(html);
@ -204,19 +231,23 @@ Include one of these files on your page, and `ejs` should be available globally.
Most of EJS will work as expected; however, there are a few things to note: Most of EJS will work as expected; however, there are a few things to note:
1. Obviously, since you do not have access to the filesystem, `ejs.renderFile()` won't work. 1. Obviously, since you do not have access to the filesystem, `ejs.renderFile()` won't work.
2. For the same reason, `include`s do not work unless you use an `IncludeCallback`. Here is an example: 2. For the same reason, `include`s do not work unless you use an `include callback`. Here is an example:
```javascript ```javascript
var str = "Hello <%= include('file', {person: 'John'}); %>", let str = "Hello <%= include('file', {person: 'John'}); %>",
fn = ejs.compile(str, {client: true}); fn = ejs.compile(str, {client: true});
fn(data, null, function(path, d){ // IncludeCallback fn(data, null, function(path, d){ // include callback
// path -> 'file' // path -> 'file'
// d -> {person: 'John'} // d -> {person: 'John'}
// Put your code here // Put your code here
// Return the contents of file as a string // Return the contents of file as a string
}); // returns rendered string }); // returns rendered string
``` ```
### IDE Integration with Syntax Highlighting
VSCode:Javascript EJS by *DigitalBrainstem*
## Related projects ## Related projects
There are a number of implementations of EJS: There are a number of implementations of EJS:
@ -226,6 +257,7 @@ There are a number of implementations of EJS:
* EJS Embedded JavaScript Framework on Google Code: https://code.google.com/p/embeddedjavascript/ * EJS Embedded JavaScript Framework on Google Code: https://code.google.com/p/embeddedjavascript/
* Sam Stephenson's Ruby implementation: https://rubygems.org/gems/ejs * Sam Stephenson's Ruby implementation: https://rubygems.org/gems/ejs
* Erubis, an ERB implementation which also runs JavaScript: http://www.kuwata-lab.com/erubis/users-guide.04.html#lang-javascript * Erubis, an ERB implementation which also runs JavaScript: http://www.kuwata-lab.com/erubis/users-guide.04.html#lang-javascript
* DigitalBrainstem EJS Language support: https://github.com/Digitalbrainstem/ejs-grammar
## License ## License
@ -235,5 +267,3 @@ Licensed under the Apache License, Version 2.0
- - - - - -
EJS Embedded JavaScript templates copyright 2112 EJS Embedded JavaScript templates copyright 2112
mde@fleegix.org. mde@fleegix.org.

976
node_modules/ejs/ejs.js generated vendored

File diff suppressed because it is too large Load Diff

2
node_modules/ejs/ejs.min.js generated vendored

File diff suppressed because one or more lines are too long

752
node_modules/ejs/lib/ejs.js generated vendored Normal file → Executable file
View File

@ -19,7 +19,7 @@
'use strict'; 'use strict';
/** /**
* @file Embedded JavaScript templating engine. * @file Embedded JavaScript templating engine. {@link http://ejs.co}
* @author Matthew Eernisse <mde@fleegix.org> * @author Matthew Eernisse <mde@fleegix.org>
* @author Tiancheng "Timothy" Gu <timothygu99@gmail.com> * @author Tiancheng "Timothy" Gu <timothygu99@gmail.com>
* @project EJS * @project EJS
@ -44,19 +44,23 @@
* @public * @public
*/ */
var fs = require('fs') var fs = require('fs');
, utils = require('./utils') var path = require('path');
, scopeOptionWarned = false var utils = require('./utils');
, _VERSION_STRING = require('../package.json').version
, _DEFAULT_DELIMITER = '%' var scopeOptionWarned = false;
, _DEFAULT_LOCALS_NAME = 'locals' var _VERSION_STRING = require('../package.json').version;
, _REGEX_STRING = '(<%%|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)' var _DEFAULT_DELIMITER = '%';
, _OPTS = [ 'cache', 'filename', 'delimiter', 'scope', 'context' var _DEFAULT_LOCALS_NAME = 'locals';
, 'debug', 'compileDebug', 'client', '_with', 'rmWhitespace' var _NAME = 'ejs';
, 'strict', 'localsName' var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)';
] var _OPTS_PASSABLE_WITH_DATA = ['delimiter', 'scope', 'context', 'debug', 'compileDebug',
, _TRAILING_SEMCOL = /;\s*$/ 'client', '_with', 'rmWhitespace', 'strict', 'filename', 'async'];
, _BOM = /^\uFEFF/; // We don't allow 'cache' option to be passed in the data obj for
// the normal `render` call, but this is where Express 2 & 3 put it
// so we make an exception for `renderFile`
var _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat('cache');
var _BOM = /^\uFEFF/;
/** /**
* EJS template function cache. This can be a LRU object from lru-cache NPM * EJS template function cache. This can be a LRU object from lru-cache NPM
@ -68,10 +72,19 @@ var fs = require('fs')
exports.cache = utils.cache; exports.cache = utils.cache;
/**
* Custom file loader. Useful for template preprocessing or restricting access
* to a certain part of the filesystem.
*
* @type {fileLoader}
*/
exports.fileLoader = fs.readFileSync;
/** /**
* Name of the object containing the locals. * Name of the object containing the locals.
* *
* This variable is overriden by {@link Options}`.localsName` if it is not * This variable is overridden by {@link Options}`.localsName` if it is not
* `undefined`. * `undefined`.
* *
* @type {String} * @type {String}
@ -80,28 +93,79 @@ exports.cache = utils.cache;
exports.localsName = _DEFAULT_LOCALS_NAME; exports.localsName = _DEFAULT_LOCALS_NAME;
/**
* Promise implementation -- defaults to the native implementation if available
* This is mostly just for testability
*
* @type {Function}
* @public
*/
exports.promiseImpl = (new Function('return this;'))().Promise;
/** /**
* Get the path to the included file from the parent file path and the * Get the path to the included file from the parent file path and the
* specified path. * specified path.
* *
* @param {String} name specified path * @param {String} name specified path
* @param {String} filename parent file path * @param {String} filename parent file path
* @param {Boolean} isDir parent file path whether is directory
* @return {String} * @return {String}
*/ */
exports.resolveInclude = function(name, filename, isDir) {
exports.resolveInclude = function(name, filename) { var dirname = path.dirname;
var path = require('path') var extname = path.extname;
, dirname = path.dirname var resolve = path.resolve;
, extname = path.extname var includePath = resolve(isDir ? filename : dirname(filename), name);
, resolve = path.resolve var ext = extname(name);
, includePath = resolve(dirname(filename), name)
, ext = extname(name);
if (!ext) { if (!ext) {
includePath += '.ejs'; includePath += '.ejs';
} }
return includePath; return includePath;
}; };
/**
* Get the path to the included file by Options
*
* @param {String} path specified path
* @param {Options} options compilation options
* @return {String}
*/
function getIncludePath(path, options) {
var includePath;
var filePath;
var views = options.views;
// Abs path
if (path.charAt(0) == '/') {
includePath = exports.resolveInclude(path.replace(/^\/*/,''), options.root || '/', true);
}
// Relative paths
else {
// Look relative to a passed filename first
if (options.filename) {
filePath = exports.resolveInclude(path, options.filename);
if (fs.existsSync(filePath)) {
includePath = filePath;
}
}
// Then look in any views directories
if (!includePath) {
if (Array.isArray(views) && views.some(function (v) {
filePath = exports.resolveInclude(path, v, true);
return fs.existsSync(filePath);
})) {
includePath = filePath;
}
}
if (!includePath) {
throw new Error('Could not find the include file "' +
options.escapeFunction(path) + '"');
}
}
return includePath;
}
/** /**
* Get the template from a string or a file, either compiled on-the-fly or * Get the template from a string or a file, either compiled on-the-fly or
* read from cache (if enabled), and cache the template if needed. * read from cache (if enabled), and cache the template if needed.
@ -121,35 +185,89 @@ exports.resolveInclude = function(name, filename) {
*/ */
function handleCache(options, template) { function handleCache(options, template) {
var fn var func;
, path = options.filename var filename = options.filename;
, hasTemplate = arguments.length > 1; var hasTemplate = arguments.length > 1;
if (options.cache) { if (options.cache) {
if (!path) { if (!filename) {
throw new Error('cache option requires a filename'); throw new Error('cache option requires a filename');
} }
fn = exports.cache.get(path); func = exports.cache.get(filename);
if (fn) { if (func) {
return fn; return func;
} }
if (!hasTemplate) { if (!hasTemplate) {
template = fs.readFileSync(path).toString().replace(_BOM, ''); template = fileLoader(filename).toString().replace(_BOM, '');
} }
} }
else if (!hasTemplate) { else if (!hasTemplate) {
// istanbul ignore if: should not happen at all // istanbul ignore if: should not happen at all
if (!path) { if (!filename) {
throw new Error('Internal EJS error: no file name or template ' throw new Error('Internal EJS error: no file name or template '
+ 'provided'); + 'provided');
} }
template = fs.readFileSync(path).toString().replace(_BOM, ''); template = fileLoader(filename).toString().replace(_BOM, '');
} }
fn = exports.compile(template, options); func = exports.compile(template, options);
if (options.cache) { if (options.cache) {
exports.cache.set(path, fn); exports.cache.set(filename, func);
} }
return fn; return func;
}
/**
* Try calling handleCache with the given options and data and call the
* callback with the result. If an error occurs, call the callback with
* the error. Used by renderFile().
*
* @memberof module:ejs-internal
* @param {Options} options compilation options
* @param {Object} data template data
* @param {RenderFileCallback} cb callback
* @static
*/
function tryHandleCache(options, data, cb) {
var result;
if (!cb) {
if (typeof exports.promiseImpl == 'function') {
return new exports.promiseImpl(function (resolve, reject) {
try {
result = handleCache(options)(data);
resolve(result);
}
catch (err) {
reject(err);
}
});
}
else {
throw new Error('Please provide a callback function');
}
}
else {
try {
result = handleCache(options)(data);
}
catch (err) {
return cb(err);
}
cb(null, result);
}
}
/**
* fileLoader is independent
*
* @param {String} filePath ejs file path.
* @return {String} The contents of the specified file.
* @static
*/
function fileLoader(filePath){
return exports.fileLoader(filePath);
} }
/** /**
@ -167,10 +285,7 @@ function handleCache(options, template) {
function includeFile(path, options) { function includeFile(path, options) {
var opts = utils.shallowCopy({}, options); var opts = utils.shallowCopy({}, options);
if (!opts.filename) { opts.filename = getIncludePath(path, opts);
throw new Error('`include` requires the \'filename\' option.');
}
opts.filename = exports.resolveInclude(path, opts.filename);
return handleCache(opts); return handleCache(opts);
} }
@ -180,24 +295,24 @@ function includeFile(path, options) {
* @memberof module:ejs-internal * @memberof module:ejs-internal
* @param {String} path path for the specified file * @param {String} path path for the specified file
* @param {Options} options compilation options * @param {Options} options compilation options
* @return {String} * @return {Object}
* @static * @static
*/ */
function includeSource(path, options) { function includeSource(path, options) {
var opts = utils.shallowCopy({}, options) var opts = utils.shallowCopy({}, options);
, includePath var includePath;
, template; var template;
if (!opts.filename) { includePath = getIncludePath(path, opts);
throw new Error('`include` requires the \'filename\' option.'); template = fileLoader(includePath).toString().replace(_BOM, '');
}
includePath = exports.resolveInclude(path, opts.filename);
template = fs.readFileSync(includePath).toString().replace(_BOM, '');
opts.filename = includePath; opts.filename = includePath;
var templ = new Template(template, opts); var templ = new Template(template, opts);
templ.generateSource(); templ.generateSource();
return templ.source; return {
source: templ.source,
filename: includePath,
template: template
};
} }
/** /**
@ -213,11 +328,11 @@ function includeSource(path, options) {
* @static * @static
*/ */
function rethrow(err, str, filename, lineno){ function rethrow(err, str, flnm, lineno, esc){
var lines = str.split('\n') var lines = str.split('\n');
, start = Math.max(lineno - 3, 0) var start = Math.max(lineno - 3, 0);
, end = Math.min(lines.length, lineno + 3); var end = Math.min(lines.length, lineno + 3);
var filename = esc(flnm); // eslint-disable-line
// Error context // Error context
var context = lines.slice(start, end).map(function (line, i){ var context = lines.slice(start, end).map(function (line, i){
var curr = i + start + 1; var curr = i + start + 1;
@ -237,24 +352,8 @@ function rethrow(err, str, filename, lineno){
throw err; throw err;
} }
/** function stripSemi(str){
* Copy properties in data object that are recognized as options to an return str.replace(/;(\s*$)/, '$1');
* options object.
*
* This is used for compatibility with earlier versions of EJS and Express.js.
*
* @memberof module:ejs-internal
* @param {Object} data data object
* @param {Options} opts options object
* @static
*/
function cpOptsInData(data, opts) {
_OPTS.forEach(function (p) {
if (typeof data[p] != 'undefined') {
opts[p] = data[p];
}
});
} }
/** /**
@ -266,6 +365,7 @@ function cpOptsInData(data, opts) {
* *
* @return {(TemplateFunction|ClientFunction)} * @return {(TemplateFunction|ClientFunction)}
* Depending on the value of `opts.client`, either type might be returned. * Depending on the value of `opts.client`, either type might be returned.
* Note that the return type of the function also depends on the value of `opts.async`.
* @public * @public
*/ */
@ -298,19 +398,19 @@ exports.compile = function compile(template, opts) {
* @param {String} template EJS template * @param {String} template EJS template
* @param {Object} [data={}] template data * @param {Object} [data={}] template data
* @param {Options} [opts={}] compilation and rendering options * @param {Options} [opts={}] compilation and rendering options
* @return {String} * @return {(String|Promise<String>)}
* Return value type depends on `opts.async`.
* @public * @public
*/ */
exports.render = function (template, data, opts) { exports.render = function (template, d, o) {
data = data || {}; var data = d || {};
opts = opts || {}; var opts = o || {};
var fn;
// No options object -- if there are optiony names // No options object -- if there are optiony names
// in the data, copy them to options // in the data, copy them to options
if (arguments.length == 2) { if (arguments.length == 2) {
cpOptsInData(data, opts); utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA);
} }
return handleCache(opts, template)(data); return handleCache(opts, template)(data);
@ -330,37 +430,56 @@ exports.render = function (template, data, opts) {
*/ */
exports.renderFile = function () { exports.renderFile = function () {
var args = Array.prototype.slice.call(arguments) var args = Array.prototype.slice.call(arguments);
, path = args.shift() var filename = args.shift();
, cb = args.pop() var cb;
, data = args.shift() || {} var opts = {filename: filename};
, opts = args.pop() || {} var data;
, result; var viewOpts;
// Don't pollute passed in opts obj with new vals // Do we have a callback?
opts = utils.shallowCopy({}, opts); if (typeof arguments[arguments.length - 1] == 'function') {
cb = args.pop();
// No options object -- if there are optiony names }
// in the data, copy them to options // Do we have data/opts?
if (arguments.length == 3) { if (args.length) {
// Express 4 // Should always have data obj
if (data.settings && data.settings['view options']) { data = args.shift();
cpOptsInData(data.settings['view options'], opts); // Normal passed opts (data obj + opts obj)
if (args.length) {
// Use shallowCopy so we don't pollute passed in opts obj with new vals
utils.shallowCopy(opts, args.pop());
} }
// Express 3 and lower // Special casing for Express (settings + opts-in-data)
else { else {
cpOptsInData(data, opts); // Express 3 and 4
if (data.settings) {
// Pull a few things from known locations
if (data.settings.views) {
opts.views = data.settings.views;
}
if (data.settings['view cache']) {
opts.cache = true;
}
// Undocumented after Express 2, but still usable, esp. for
// items that are unsafe to be passed along with data, like `root`
viewOpts = data.settings['view options'];
if (viewOpts) {
utils.shallowCopy(opts, viewOpts);
}
}
// Express 2 and lower, values set in app.locals, or people who just
// want to pass options in their data. NOTE: These values will override
// anything previously set in settings or settings['view options']
utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA_EXPRESS);
} }
opts.filename = filename;
}
else {
data = {};
} }
opts.filename = path;
try { return tryHandleCache(opts, data, cb);
result = handleCache(opts)(data);
}
catch(err) {
return cb(err);
}
return cb(null, result);
}; };
/** /**
@ -391,7 +510,11 @@ function Template(text, opts) {
options.context = opts.context; options.context = opts.context;
options.cache = opts.cache || false; options.cache = opts.cache || false;
options.rmWhitespace = opts.rmWhitespace; options.rmWhitespace = opts.rmWhitespace;
options.root = opts.root;
options.outputFunctionName = opts.outputFunctionName;
options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME; options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME;
options.views = opts.views;
options.async = opts.async;
if (options.strict) { if (options.strict) {
options._with = false; options._with = false;
@ -406,43 +529,36 @@ function Template(text, opts) {
} }
Template.modes = { Template.modes = {
EVAL: 'eval' EVAL: 'eval',
, ESCAPED: 'escaped' ESCAPED: 'escaped',
, RAW: 'raw' RAW: 'raw',
, COMMENT: 'comment' COMMENT: 'comment',
, LITERAL: 'literal' LITERAL: 'literal'
}; };
Template.prototype = { Template.prototype = {
createRegex: function () { createRegex: function () {
var str = _REGEX_STRING var str = _REGEX_STRING;
, delim = utils.escapeRegExpChars(this.opts.delimiter); var delim = utils.escapeRegExpChars(this.opts.delimiter);
str = str.replace(/%/g, delim); str = str.replace(/%/g, delim);
return new RegExp(str); return new RegExp(str);
} },
, compile: function () { compile: function () {
var src var src;
, fn var fn;
, opts = this.opts var opts = this.opts;
, prepended = '' var prepended = '';
, appended = '' var appended = '';
, escape = opts.escapeFunction; var escapeFn = opts.escapeFunction;
var asyncCtor;
if (opts.rmWhitespace) {
// Have to use two separate replace here as `^` and `$` operators don't
// work well with `\r`.
this.templateText =
this.templateText.replace(/\r/g, '').replace(/^\s+|\s+$/gm, '');
}
// Slurp spaces and tabs before <%_ and after _%>
this.templateText =
this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>');
if (!this.source) { if (!this.source) {
this.generateSource(); this.generateSource();
prepended += ' var __output = [], __append = __output.push.bind(__output);' + '\n'; prepended += ' var __output = [], __append = __output.push.bind(__output);' + '\n';
if (opts.outputFunctionName) {
prepended += ' var ' + opts.outputFunctionName + ' = __append;' + '\n';
}
if (opts._with !== false) { if (opts._with !== false) {
prepended += ' with (' + opts.localsName + ' || {}) {' + '\n'; prepended += ' with (' + opts.localsName + ' || {}) {' + '\n';
appended += ' }' + '\n'; appended += ' }' + '\n';
@ -453,25 +569,21 @@ Template.prototype = {
if (opts.compileDebug) { if (opts.compileDebug) {
src = 'var __line = 1' + '\n' src = 'var __line = 1' + '\n'
+ ' , __lines = ' + JSON.stringify(this.templateText) + '\n' + ' , __lines = ' + JSON.stringify(this.templateText) + '\n'
+ ' , __filename = ' + (opts.filename ? + ' , __filename = ' + (opts.filename ?
JSON.stringify(opts.filename) : 'undefined') + ';' + '\n' JSON.stringify(opts.filename) : 'undefined') + ';' + '\n'
+ 'try {' + '\n' + 'try {' + '\n'
+ this.source + this.source
+ '} catch (e) {' + '\n' + '} catch (e) {' + '\n'
+ ' rethrow(e, __lines, __filename, __line);' + '\n' + ' rethrow(e, __lines, __filename, __line, escapeFn);' + '\n'
+ '}' + '\n'; + '}' + '\n';
} }
else { else {
src = this.source; src = this.source;
} }
if (opts.debug) {
console.log(src);
}
if (opts.client) { if (opts.client) {
src = 'escape = escape || ' + escape.toString() + ';' + '\n' + src; src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src;
if (opts.compileDebug) { if (opts.compileDebug) {
src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src; src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src;
} }
@ -480,9 +592,30 @@ Template.prototype = {
if (opts.strict) { if (opts.strict) {
src = '"use strict";\n' + src; src = '"use strict";\n' + src;
} }
if (opts.debug) {
console.log(src);
}
try { try {
fn = new Function(opts.localsName + ', escape, include, rethrow', src); if (opts.async) {
// Have to use generated function for this, since in envs without support,
// it breaks in parsing
try {
asyncCtor = (new Function('return (async function(){}).constructor;'))();
}
catch(e) {
if (e instanceof SyntaxError) {
throw new Error('This environment does not support async/await');
}
else {
throw e;
}
}
}
else {
asyncCtor = Function;
}
fn = new asyncCtor(opts.localsName + ', escapeFn, include, rethrow', src);
} }
catch(e) { catch(e) {
// istanbul ignore else // istanbul ignore else
@ -490,7 +623,13 @@ Template.prototype = {
if (opts.filename) { if (opts.filename) {
e.message += ' in ' + opts.filename; e.message += ' in ' + opts.filename;
} }
e.message += ' while compiling ejs'; e.message += ' while compiling ejs\n\n';
e.message += 'If the above error is not helpful, you may want to try EJS-Lint:\n';
e.message += 'https://github.com/RyanZim/EJS-Lint';
if (!e.async) {
e.message += '\n';
e.message += 'Or, if you meant to create an async function, pass async: true as an option.';
}
} }
throw e; throw e;
} }
@ -511,28 +650,38 @@ Template.prototype = {
} }
return includeFile(path, opts)(d); return includeFile(path, opts)(d);
}; };
return fn.apply(opts.context, [data || {}, escape, include, rethrow]); return fn.apply(opts.context, [data || {}, escapeFn, include, rethrow]);
}; };
returnedFn.dependencies = this.dependencies; returnedFn.dependencies = this.dependencies;
return returnedFn; return returnedFn;
} },
, generateSource: function () { generateSource: function () {
var self = this var opts = this.opts;
, matches = this.parseTemplateText()
, d = this.opts.delimiter; if (opts.rmWhitespace) {
// Have to use two separate replace here as `^` and `$` operators don't
// work well with `\r`.
this.templateText =
this.templateText.replace(/\r/g, '').replace(/^\s+|\s+$/gm, '');
}
// Slurp spaces and tabs before <%_ and after _%>
this.templateText =
this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>');
var self = this;
var matches = this.parseTemplateText();
var d = this.opts.delimiter;
if (matches && matches.length) { if (matches && matches.length) {
if (this.opts.compileDebug && this.opts.filename) {
this.source = ' ; __lines = ' + JSON.stringify(this.templateText) + '\n';
this.source += ' ; __filename = "' + this.opts.filename.replace(/\\/g, '/') + '"\n';
}
matches.forEach(function (line, index) { matches.forEach(function (line, index) {
var opening var opening;
, closing var closing;
, include var include;
, includeOpts var includeOpts;
, includeSrc; var includeObj;
var includeSrc;
// If this is an opening tag, check for closing tags // If this is an opening tag, check for closing tags
// FIXME: May end up with some false positives here // FIXME: May end up with some false positives here
// Better to store modes as k/v with '<' + delimiter as key // Better to store modes as k/v with '<' + delimiter as key
@ -550,12 +699,26 @@ Template.prototype = {
// Must be in EVAL or RAW mode // Must be in EVAL or RAW mode
if (opening && (opening == '<' + d || opening == '<' + d + '-' || opening == '<' + d + '_')) { if (opening && (opening == '<' + d || opening == '<' + d + '-' || opening == '<' + d + '_')) {
includeOpts = utils.shallowCopy({}, self.opts); includeOpts = utils.shallowCopy({}, self.opts);
includeSrc = includeSource(include[1], includeOpts); includeObj = includeSource(include[1], includeOpts);
includeSrc = ' ; (function(){' + '\n' + includeSrc + if (self.opts.compileDebug) {
' ; })()' + '\n'; includeSrc =
' ; (function(){' + '\n'
+ ' var __line = 1' + '\n'
+ ' , __lines = ' + JSON.stringify(includeObj.template) + '\n'
+ ' , __filename = ' + JSON.stringify(includeObj.filename) + ';' + '\n'
+ ' try {' + '\n'
+ includeObj.source
+ ' } catch (e) {' + '\n'
+ ' rethrow(e, __lines, __filename, __line, escapeFn);' + '\n'
+ ' }' + '\n'
+ ' ; }).call(this)' + '\n';
}else{
includeSrc = ' ; (function(){' + '\n' + includeObj.source +
' ; }).call(this)' + '\n';
}
self.source += includeSrc; self.source += includeSrc;
self.dependencies.push(exports.resolveInclude(include[1], self.dependencies.push(exports.resolveInclude(include[1],
includeOpts.filename)); includeOpts.filename));
return; return;
} }
} }
@ -563,19 +726,17 @@ Template.prototype = {
}); });
} }
} },
, parseTemplateText: function () { parseTemplateText: function () {
var str = this.templateText var str = this.templateText;
, pat = this.regex var pat = this.regex;
, result = pat.exec(str) var result = pat.exec(str);
, arr = [] var arr = [];
, firstPos var firstPos;
, lastPos;
while (result) { while (result) {
firstPos = result.index; firstPos = result.index;
lastPos = pat.lastIndex;
if (firstPos !== 0) { if (firstPos !== 0) {
arr.push(str.substring(0, firstPos)); arr.push(str.substring(0, firstPos));
@ -592,116 +753,117 @@ Template.prototype = {
} }
return arr; return arr;
} },
, scanLine: function (line) { _addOutput: function (line) {
var self = this if (this.truncate) {
, d = this.opts.delimiter // Only replace single leading linebreak in the line after
, newLineCount = 0; // -%> tag -- this is the single, trailing linebreak
// after the tag that the truncation mode replaces
function _addOutput() { // Handle Win / Unix / old Mac linebreaks -- do the \r\n
if (self.truncate) { // combo first in the regex-or
// Only replace single leading linebreak in the line after line = line.replace(/^(?:\r\n|\r|\n)/, '');
// -%> tag -- this is the single, trailing linebreak this.truncate = false;
// after the tag that the truncation mode replaces
// Handle Win / Unix / old Mac linebreaks -- do the \r\n
// combo first in the regex-or
line = line.replace(/^(?:\r\n|\r|\n)/, '')
self.truncate = false;
}
else if (self.opts.rmWhitespace) {
// Gotta be more careful here.
// .replace(/^(\s*)\n/, '$1') might be more appropriate here but as
// rmWhitespace already removes trailing spaces anyway so meh.
line = line.replace(/^\n/, '');
}
if (!line) {
return;
}
// Preserve literal slashes
line = line.replace(/\\/g, '\\\\');
// Convert linebreaks
line = line.replace(/\n/g, '\\n');
line = line.replace(/\r/g, '\\r');
// Escape double-quotes
// - this will be the delimiter during execution
line = line.replace(/"/g, '\\"');
self.source += ' ; __append("' + line + '")' + '\n';
} }
else if (this.opts.rmWhitespace) {
// rmWhitespace has already removed trailing spaces, just need
// to remove linebreaks
line = line.replace(/^\n/, '');
}
if (!line) {
return line;
}
// Preserve literal slashes
line = line.replace(/\\/g, '\\\\');
// Convert linebreaks
line = line.replace(/\n/g, '\\n');
line = line.replace(/\r/g, '\\r');
// Escape double-quotes
// - this will be the delimiter during execution
line = line.replace(/"/g, '\\"');
this.source += ' ; __append("' + line + '")' + '\n';
},
scanLine: function (line) {
var self = this;
var d = this.opts.delimiter;
var newLineCount = 0;
newLineCount = (line.split('\n').length - 1); newLineCount = (line.split('\n').length - 1);
switch (line) { switch (line) {
case '<' + d: case '<' + d:
case '<' + d + '_': case '<' + d + '_':
this.mode = Template.modes.EVAL; this.mode = Template.modes.EVAL;
break; break;
case '<' + d + '=': case '<' + d + '=':
this.mode = Template.modes.ESCAPED; this.mode = Template.modes.ESCAPED;
break; break;
case '<' + d + '-': case '<' + d + '-':
this.mode = Template.modes.RAW; this.mode = Template.modes.RAW;
break; break;
case '<' + d + '#': case '<' + d + '#':
this.mode = Template.modes.COMMENT; this.mode = Template.modes.COMMENT;
break; break;
case '<' + d + d: case '<' + d + d:
this.mode = Template.modes.LITERAL; this.mode = Template.modes.LITERAL;
this.source += ' ; __append("' + line.replace('<' + d + d, '<' + d) + '")' + '\n'; this.source += ' ; __append("' + line.replace('<' + d + d, '<' + d) + '")' + '\n';
break; break;
case d + '>': case d + d + '>':
case '-' + d + '>': this.mode = Template.modes.LITERAL;
case '_' + d + '>': this.source += ' ; __append("' + line.replace(d + d + '>', d + '>') + '")' + '\n';
if (this.mode == Template.modes.LITERAL) { break;
_addOutput(); case d + '>':
} case '-' + d + '>':
case '_' + d + '>':
if (this.mode == Template.modes.LITERAL) {
this._addOutput(line);
}
this.mode = null; this.mode = null;
this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0; this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0;
break; break;
default: default:
// In script mode, depends on type of tag // In script mode, depends on type of tag
if (this.mode) { if (this.mode) {
// If '//' is found without a line break, add a line break. // If '//' is found without a line break, add a line break.
switch (this.mode) { switch (this.mode) {
case Template.modes.EVAL: case Template.modes.EVAL:
case Template.modes.ESCAPED: case Template.modes.ESCAPED:
case Template.modes.RAW: case Template.modes.RAW:
if (line.lastIndexOf('//') > line.lastIndexOf('\n')) { if (line.lastIndexOf('//') > line.lastIndexOf('\n')) {
line += '\n'; line += '\n';
}
}
switch (this.mode) {
// Just executing code
case Template.modes.EVAL:
this.source += ' ; ' + line + '\n';
break;
// Exec, esc, and output
case Template.modes.ESCAPED:
this.source += ' ; __append(escape(' +
line.replace(_TRAILING_SEMCOL, '').trim() + '))' + '\n';
break;
// Exec and output
case Template.modes.RAW:
this.source += ' ; __append(' +
line.replace(_TRAILING_SEMCOL, '').trim() + ')' + '\n';
break;
case Template.modes.COMMENT:
// Do nothing
break;
// Literal <%% mode, append as raw output
case Template.modes.LITERAL:
_addOutput();
break;
} }
} }
// In string mode, just add the output switch (this.mode) {
else { // Just executing code
_addOutput(); case Template.modes.EVAL:
this.source += ' ; ' + line + '\n';
break;
// Exec, esc, and output
case Template.modes.ESCAPED:
this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\n';
break;
// Exec and output
case Template.modes.RAW:
this.source += ' ; __append(' + stripSemi(line) + ')' + '\n';
break;
case Template.modes.COMMENT:
// Do nothing
break;
// Literal <%% mode, append as raw output
case Template.modes.LITERAL:
this._addOutput(line);
break;
} }
}
// In string mode, just add the output
else {
this._addOutput(line);
}
} }
if (self.opts.compileDebug && newLineCount) { if (self.opts.compileDebug && newLineCount) {
@ -711,9 +873,17 @@ Template.prototype = {
} }
}; };
/* /**
* Export the internal function for escaping XML so people * Escape characters reserved in XML.
* can use for manual escaping if needed *
* This is simply an export of {@link module:utils.escapeXML}.
*
* If `markup` is `undefined` or `null`, the empty string is returned.
*
* @param {String} markup Input string
* @return {String} Escaped string
* @public
* @func
* */ * */
exports.escapeXML = utils.escapeXML; exports.escapeXML = utils.escapeXML;
@ -731,14 +901,14 @@ exports.__express = exports.renderFile;
// Add require support // Add require support
/* istanbul ignore else */ /* istanbul ignore else */
if (require.extensions) { if (require.extensions) {
require.extensions['.ejs'] = function (module, filename) { require.extensions['.ejs'] = function (module, flnm) {
filename = filename || /* istanbul ignore next */ module.filename; var filename = flnm || /* istanbul ignore next */ module.filename;
var options = { var options = {
filename: filename filename: filename,
, client: true client: true
} };
, template = fs.readFileSync(filename).toString() var template = fileLoader(filename).toString();
, fn = exports.compile(template, options); var fn = exports.compile(template, options);
module._compile('module.exports = ' + fn.toString() + ';', filename); module._compile('module.exports = ' + fn.toString() + ';', filename);
}; };
} }
@ -753,6 +923,16 @@ if (require.extensions) {
exports.VERSION = _VERSION_STRING; exports.VERSION = _VERSION_STRING;
/**
* Name for detection of EJS.
*
* @readonly
* @type {String}
* @public
*/
exports.name = _NAME;
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof window != 'undefined') { if (typeof window != 'undefined') {
window.ejs = exports; window.ejs = exports;

47
node_modules/ejs/lib/utils.js generated vendored
View File

@ -45,17 +45,17 @@ exports.escapeRegExpChars = function (string) {
}; };
var _ENCODE_HTML_RULES = { var _ENCODE_HTML_RULES = {
'&': '&amp;' '&': '&amp;',
, '<': '&lt;' '<': '&lt;',
, '>': '&gt;' '>': '&gt;',
, '"': '&#34;' '"': '&#34;',
, "'": '&#39;' "'": '&#39;'
} };
, _MATCH_HTML = /[&<>\'"]/g; var _MATCH_HTML = /[&<>'"]/g;
function encode_char(c) { function encode_char(c) {
return _ENCODE_HTML_RULES[c] || c; return _ENCODE_HTML_RULES[c] || c;
}; }
/** /**
* Stringified version of constants used by {@link module:utils.escapeXML}. * Stringified version of constants used by {@link module:utils.escapeXML}.
@ -95,14 +95,16 @@ exports.escapeXML = function (markup) {
return markup == undefined return markup == undefined
? '' ? ''
: String(markup) : String(markup)
.replace(_MATCH_HTML, encode_char); .replace(_MATCH_HTML, encode_char);
}; };
exports.escapeXML.toString = function () { exports.escapeXML.toString = function () {
return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr;
}; };
/** /**
* Copy all properties from one object to another, in a shallow fashion. * Naive copy of properties from one object to another.
* Does not recurse into non-scalar properties
* Does not check to see if the property has a value before copying
* *
* @param {Object} to Destination object * @param {Object} to Destination object
* @param {Object} from Source object * @param {Object} from Source object
@ -118,6 +120,28 @@ exports.shallowCopy = function (to, from) {
return to; return to;
}; };
/**
* Naive copy of a list of key names, from one object to another.
* Only copies property if it is actually defined
* Does not recurse into non-scalar properties
*
* @param {Object} to Destination object
* @param {Object} from Source object
* @param {Array} list List of properties to copy
* @return {Object} Destination object
* @static
* @private
*/
exports.shallowCopyFromList = function (to, from, list) {
for (var i = 0; i < list.length; i++) {
var p = list[i];
if (typeof from[p] != 'undefined') {
to[p] = from[p];
}
}
return to;
};
/** /**
* Simple in-process cache implementation. Does not implement limits of any * Simple in-process cache implementation. Does not implement limits of any
* sort. * sort.
@ -138,4 +162,3 @@ exports.cache = {
this._data = {}; this._data = {};
} }
}; };

58
node_modules/ejs/package.json generated vendored
View File

@ -1,30 +1,27 @@
{ {
"_args": [ "_from": "ejs@*",
[ "_id": "ejs@2.6.1",
"ejs@http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz",
"/Users/martin/dev/Rinser"
]
],
"_from": "ejs@http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz",
"_id": "ejs@http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha1-cFfrSBKVj7cxhBzZyjUzQ+/ll7E=", "_integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==",
"_location": "/ejs", "_location": "/ejs",
"_phantomChildren": {}, "_phantomChildren": {},
"_requested": { "_requested": {
"type": "remote", "type": "range",
"raw": "ejs@http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz", "registry": true,
"raw": "ejs@*",
"name": "ejs", "name": "ejs",
"escapedName": "ejs", "escapedName": "ejs",
"rawSpec": "http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz", "rawSpec": "*",
"saveSpec": "http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz", "saveSpec": null,
"fetchSpec": "http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz" "fetchSpec": "*"
}, },
"_requiredBy": [ "_requiredBy": [
"/" "/"
], ],
"_spec": "http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz", "_resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz",
"_where": "/Users/martin/dev/Rinser", "_shasum": "498ec0d495655abc6f23cd61868d926464071aa0",
"_spec": "ejs@*",
"_where": "/Users/martin/dev/test/Rinser",
"author": { "author": {
"name": "Matthew Eernisse", "name": "Matthew Eernisse",
"email": "mde@fleegix.org", "email": "mde@fleegix.org",
@ -33,6 +30,7 @@
"bugs": { "bugs": {
"url": "https://github.com/mde/ejs/issues" "url": "https://github.com/mde/ejs/issues"
}, },
"bundleDependencies": false,
"contributors": [ "contributors": [
{ {
"name": "Timothy Gu", "name": "Timothy Gu",
@ -41,16 +39,18 @@
} }
], ],
"dependencies": {}, "dependencies": {},
"deprecated": false,
"description": "Embedded JavaScript templates", "description": "Embedded JavaScript templates",
"devDependencies": { "devDependencies": {
"browserify": "^8.0.3", "browserify": "^13.1.1",
"istanbul": "~0.3.5", "eslint": "^4.14.0",
"jake": "^8.0.0", "git-directory-deploy": "^1.5.1",
"jsdoc": "^3.3.0-beta1", "istanbul": "~0.4.3",
"lru-cache": "^2.5.0", "jake": "^8.0.16",
"mocha": "^2.1.0", "jsdoc": "^3.4.0",
"rimraf": "^2.2.8", "lru-cache": "^4.0.1",
"uglify-js": "^2.4.16" "mocha": "^5.0.5",
"uglify-js": "^3.3.16"
}, },
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
@ -70,10 +70,10 @@
}, },
"scripts": { "scripts": {
"coverage": "istanbul cover node_modules/mocha/bin/_mocha", "coverage": "istanbul cover node_modules/mocha/bin/_mocha",
"devdoc": "rimraf out && jsdoc -p -c jsdoc.json lib/* docs/jsdoc/*", "devdoc": "jake doc[dev]",
"doc": "rimraf out && jsdoc -c jsdoc.json lib/* docs/jsdoc/*", "doc": "jake doc",
"sample": "npm install express && node sample/index.js", "lint": "eslint \"**/*.js\" Jakefile",
"test": "mocha" "test": "jake test"
}, },
"version": "http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz" "version": "2.6.1"
} }

932
node_modules/ejs/test/ejs.js generated vendored
View File

@ -1,932 +0,0 @@
/* jshint mocha: true */
/**
* Module dependencies.
*/
var ejs = require('..')
, fs = require('fs')
, read = fs.readFileSync
, assert = require('assert')
, path = require('path')
, LRU = require('lru-cache');
try {
fs.mkdirSync(__dirname + '/tmp');
} catch (ex) {
if (ex.code !== 'EEXIST') {
throw ex;
}
}
// From https://gist.github.com/pguillory/729616
function hook_stdio(stream, callback) {
var old_write = stream.write;
stream.write = (function() {
return function(string, encoding, fd) {
callback(string, encoding, fd);
};
})(stream.write);
return function() {
stream.write = old_write;
};
}
/**
* Load fixture `name`.
*/
function fixture(name) {
return read('test/fixtures/' + name, 'utf8');
}
/**
* User fixtures.
*/
var users = [];
users.push({name: 'geddy'});
users.push({name: 'neil'});
users.push({name: 'alex'});
suite('ejs.compile(str, options)', function () {
test('compile to a function', function () {
var fn = ejs.compile('<p>yay</p>');
assert.equal(fn(), '<p>yay</p>');
});
test('empty input works', function () {
var fn = ejs.compile('');
assert.equal(fn(), '');
});
test('throw if there are syntax errors', function () {
try {
ejs.compile(fixture('fail.ejs'));
}
catch (err) {
assert.ok(err.message.indexOf('compiling ejs') > -1);
try {
ejs.compile(fixture('fail.ejs'), {filename: 'fail.ejs'});
}
catch (err) {
assert.ok(err.message.indexOf('fail.ejs') > -1);
return;
}
}
throw new Error('no error reported when there should be');
});
test('allow customizing delimiter local var', function () {
var fn;
fn = ejs.compile('<p><?= name ?></p>', {delimiter: '?'});
assert.equal(fn({name: 'geddy'}), '<p>geddy</p>');
fn = ejs.compile('<p><:= name :></p>', {delimiter: ':'});
assert.equal(fn({name: 'geddy'}), '<p>geddy</p>');
fn = ejs.compile('<p><$= name $></p>', {delimiter: '$'});
assert.equal(fn({name: 'geddy'}), '<p>geddy</p>');
});
test('default to using ejs.delimiter', function () {
var fn;
ejs.delimiter = '&';
fn = ejs.compile('<p><&= name &></p>');
assert.equal(fn({name: 'geddy'}), '<p>geddy</p>');
fn = ejs.compile('<p><|= name |></p>', {delimiter: '|'});
assert.equal(fn({name: 'geddy'}), '<p>geddy</p>');
delete ejs.delimiter;
});
test('have a working client option', function () {
var fn
, str
, preFn;
fn = ejs.compile('<p><%= foo %></p>', {client: true});
str = fn.toString();
if (!process.env.running_under_istanbul) {
eval('var preFn = ' + str);
assert.equal(preFn({foo: 'bar'}), '<p>bar</p>');
}
});
test('support client mode without locals', function () {
var fn
, str
, preFn;
fn = ejs.compile('<p><%= "foo" %></p>', {client: true});
str = fn.toString();
if (!process.env.running_under_istanbul) {
eval('var preFn = ' + str);
assert.equal(preFn(), '<p>foo</p>');
}
});
test('not include rethrow() in client mode if compileDebug is false', function () {
var fn = ejs.compile('<p><%= "foo" %></p>', {
client: true
, compileDebug: false
});
// There could be a `rethrow` in the function declaration
assert((fn.toString().match(/rethrow/g) || []).length <= 1);
});
test('support custom escape function', function () {
var customEscape
, fn;
customEscape = function customEscape(str) {
return !str ? '' : str.toUpperCase();
};
fn = ejs.compile('HELLO <%= name %>', {escape: customEscape});
assert.equal(fn({name: 'world'}), 'HELLO WORLD');
});
test('support custom escape function in client mode', function () {
var customEscape
, fn
, str;
customEscape = function customEscape(str) {
return !str ? '' : str.toUpperCase();
};
fn = ejs.compile('HELLO <%= name %>', {escape: customEscape, client: true});
str = fn.toString();
if (!process.env.running_under_istanbul) {
eval('var preFn = ' + str);
assert.equal(preFn({name: 'world'}), 'HELLO WORLD');
}
});
});
suite('ejs.render(str, data, opts)', function () {
test('render the template', function () {
assert.equal(ejs.render('<p>yay</p>'), '<p>yay</p>');
});
test('empty input works', function () {
assert.equal(ejs.render(''), '');
});
test('undefined renders nothing escaped', function () {
assert.equal(ejs.render('<%= undefined %>'), '');
});
test('undefined renders nothing raw', function () {
assert.equal(ejs.render('<%- undefined %>'), '');
});
test('null renders nothing escaped', function () {
assert.equal(ejs.render('<%= null %>'), '');
});
test('null renders nothing raw', function () {
assert.equal(ejs.render('<%- null %>'), '');
});
test('zero-value data item renders something escaped', function () {
assert.equal(ejs.render('<%= 0 %>'), '0');
});
test('zero-value data object renders something raw', function () {
assert.equal(ejs.render('<%- 0 %>'), '0');
});
test('accept locals', function () {
assert.equal(ejs.render('<p><%= name %></p>', {name: 'geddy'}),
'<p>geddy</p>');
});
test('accept locals without using with() {}', function () {
assert.equal(ejs.render('<p><%= locals.name %></p>', {name: 'geddy'},
{_with: false}),
'<p>geddy</p>');
assert.throws(function() {
ejs.render('<p><%= name %></p>', {name: 'geddy'},
{_with: false});
}, /name is not defined/);
});
test('accept custom name for locals', function () {
ejs.localsName = 'it';
assert.equal(ejs.render('<p><%= it.name %></p>', {name: 'geddy'},
{_with: false}),
'<p>geddy</p>');
assert.throws(function() {
ejs.render('<p><%= name %></p>', {name: 'geddy'},
{_with: false});
}, /name is not defined/);
ejs.localsName = 'locals';
});
test('support caching', function () {
var file = __dirname + '/tmp/render.ejs'
, options = {cache: true, filename: file}
, out = ejs.render('<p>Old</p>', {}, options)
, expected = '<p>Old</p>';
assert.equal(out, expected);
// Assert no change, still in cache
out = ejs.render('<p>New</p>', {}, options);
assert.equal(out, expected);
});
test('support LRU caching', function () {
var oldCache = ejs.cache
, file = __dirname + '/tmp/render.ejs'
, options = {cache: true, filename: file}
, out
, expected = '<p>Old</p>';
// Switch to LRU
ejs.cache = LRU();
out = ejs.render('<p>Old</p>', {}, options);
assert.equal(out, expected);
// Assert no change, still in cache
out = ejs.render('<p>New</p>', {}, options);
assert.equal(out, expected);
// Restore system cache
ejs.cache = oldCache;
});
test('opts.context', function () {
var ctxt = {foo: 'FOO'}
, out = ejs.render('<%= this.foo %>', {}, {context: ctxt});
assert.equal(out, ctxt.foo);
});
});
suite('ejs.renderFile(path, [data], [options], fn)', function () {
test('render a file', function(done) {
ejs.renderFile('test/fixtures/para.ejs', function(err, html) {
if (err) {
return done(err);
}
assert.equal(html, '<p>hey</p>\n');
done();
});
});
test('accept locals', function(done) {
var data = {name: 'fonebone'}
, options = {delimiter: '$'};
ejs.renderFile('test/fixtures/user.ejs', data, options, function(err, html) {
if (err) {
return done(err);
}
assert.equal(html, '<h1>fonebone</h1>\n');
done();
});
});
test('accept locals without using with() {}', function(done) {
var data = {name: 'fonebone'}
, options = {delimiter: '$', _with: false}
, doneCount = 0;
ejs.renderFile('test/fixtures/user-no-with.ejs', data, options,
function(err, html) {
if (err) {
if (doneCount === 2) {
return;
}
doneCount = 2;
return done(err);
}
assert.equal(html, '<h1>fonebone</h1>\n');
doneCount++;
if (doneCount === 2) {
done();
}
});
ejs.renderFile('test/fixtures/user.ejs', data, options, function(err) {
if (!err) {
if (doneCount === 2) {
return;
}
doneCount = 2;
return done(new Error('error not thrown'));
}
doneCount++;
if (doneCount === 2) {
done();
}
});
});
test('not catch err thrown by callback', function(done) {
var data = {name: 'fonebone'}
, options = {delimiter: '$'}
, counter = 0;
var d = require('domain').create();
d.on('error', function (err) {
assert.equal(counter, 1);
assert.equal(err.message, 'Exception in callback');
done();
});
d.run(function () {
// process.nextTick() needed to work around mochajs/mocha#513
//
// tl;dr: mocha doesn't support synchronous exception throwing in
// domains. Have to make it async. Ticket closed because: "domains are
// deprecated :D"
process.nextTick(function () {
ejs.renderFile('test/fixtures/user.ejs', data, options,
function(err) {
counter++;
if (err) {
assert.notEqual(err.message, 'Exception in callback');
return done(err);
}
throw new Error('Exception in callback');
});
});
});
});
test('support caching', function (done) {
var expected = '<p>Old</p>'
, file = __dirname + '/tmp/renderFile.ejs'
, options = {cache: true};
fs.writeFileSync(file, '<p>Old</p>');
ejs.renderFile(file, {}, options, function (err, out) {
if (err) {
done(err);
}
fs.writeFileSync(file, '<p>New</p>');
assert.equal(out, expected);
ejs.renderFile(file, {}, options, function (err, out) {
if (err) {
done(err);
}
// Assert no change, still in cache
assert.equal(out, expected);
done();
});
});
});
test('opts.context', function (done) {
var ctxt = {foo: 'FOO'};
ejs.renderFile('test/fixtures/with-context.ejs', {},
{context: ctxt}, function(err, html) {
if (err) {
return done(err);
}
assert.equal(html, ctxt.foo + '\n');
done();
});
});
});
suite('cache specific', function () {
test('`clearCache` work properly', function () {
var expected = '<p>Old</p>'
, file = __dirname + '/tmp/clearCache.ejs'
, options = {cache: true, filename: file}
, out = ejs.render('<p>Old</p>', {}, options);
assert.equal(out, expected);
ejs.clearCache();
expected = '<p>New</p>';
out = ejs.render('<p>New</p>', {}, options);
assert.equal(out, expected);
});
test('`clearCache` work properly, LRU', function () {
var expected = '<p>Old</p>'
, oldCache = ejs.cache
, file = __dirname + '/tmp/clearCache.ejs'
, options = {cache: true, filename: file}
, out;
ejs.cache = LRU();
out = ejs.render('<p>Old</p>', {}, options);
assert.equal(out, expected);
ejs.clearCache();
expected = '<p>New</p>';
out = ejs.render('<p>New</p>', {}, options);
assert.equal(out, expected);
ejs.cache = oldCache;
});
test('LRU with cache-size 1', function () {
var oldCache = ejs.cache
, options
, out
, expected
, file;
ejs.cache = LRU(1);
file = __dirname + '/tmp/render1.ejs';
options = {cache: true, filename: file};
out = ejs.render('<p>File1</p>', {}, options);
expected = '<p>File1</p>';
assert.equal(out, expected);
// Same filename, different template, but output
// should be the same because cache
file = __dirname + '/tmp/render1.ejs';
options = {cache: true, filename: file};
out = ejs.render('<p>ChangedFile1</p>', {}, options);
expected = '<p>File1</p>';
assert.equal(out, expected);
// Different filiename -- output should be different,
// and previous cache-entry should be evicted
file = __dirname + '/tmp/render2.ejs';
options = {cache: true, filename: file};
out = ejs.render('<p>File2</p>', {}, options);
expected = '<p>File2</p>';
assert.equal(out, expected);
// Entry with first filename should now be out of cache,
// results should be different
file = __dirname + '/tmp/render1.ejs';
options = {cache: true, filename: file};
out = ejs.render('<p>ChangedFile1</p>', {}, options);
expected = '<p>ChangedFile1</p>';
assert.equal(out, expected);
ejs.cache = oldCache;
});
});
suite('<%', function () {
test('without semicolons', function () {
assert.equal(ejs.render(fixture('no.semicolons.ejs')),
fixture('no.semicolons.html'));
});
});
suite('<%=', function () {
test('escape &amp;<script>', function () {
assert.equal(ejs.render('<%= name %>', {name: '&nbsp;<script>'}),
'&amp;nbsp;&lt;script&gt;');
});
test('should escape \'', function () {
assert.equal(ejs.render('<%= name %>', {name: 'The Jones\'s'}),
'The Jones&#39;s');
});
test('should escape &foo_bar;', function () {
assert.equal(ejs.render('<%= name %>', {name: '&foo_bar;'}),
'&amp;foo_bar;');
});
test('should accept custom function', function() {
var customEscape = function customEscape(str) {
return !str ? '' : str.toUpperCase();
};
assert.equal(
ejs.render('<%= name %>', {name: 'The Jones\'s'}, {escape: customEscape}),
'THE JONES\'S'
);
});
});
suite('<%-', function () {
test('not escape', function () {
assert.equal(ejs.render('<%- name %>', {name: '<script>'}),
'<script>');
});
test('terminate gracefully if no close tag is found', function () {
try {
ejs.compile('<h1>oops</h1><%- name ->');
throw new Error('Expected parse failure');
}
catch (err) {
assert.ok(err.message.indexOf('Could not find matching close tag for') > -1);
}
});
});
suite('%>', function () {
test('produce newlines', function () {
assert.equal(ejs.render(fixture('newlines.ejs'), {users: users}),
fixture('newlines.html'));
});
test('works with `-%>` interspersed', function () {
assert.equal(ejs.render(fixture('newlines.mixed.ejs'), {users: users}),
fixture('newlines.mixed.html'));
});
test('consecutive tags work', function () {
assert.equal(ejs.render(fixture('consecutive-tags.ejs')),
fixture('consecutive-tags.html'));
});
});
suite('-%>', function () {
test('not produce newlines', function () {
assert.equal(ejs.render(fixture('no.newlines.ejs'), {users: users}),
fixture('no.newlines.html'));
});
test('stack traces work', function () {
try {
ejs.render(fixture('no.newlines.error.ejs'));
}
catch (e) {
if (e.message.indexOf('>> 4| <%= qdata %>') > -1) {
return;
}
throw e;
}
throw new Error('Expected ReferenceError');
});
test('works with unix style', function () {
var content = "<ul><% -%>\n"
+ "<% users.forEach(function(user){ -%>\n"
+ "<li><%= user.name -%></li>\n"
+ "<% }) -%>\n"
+ "</ul><% -%>\n";
var expectedResult = "<ul><li>geddy</li>\n<li>neil</li>\n<li>alex</li>\n</ul>";
var fn;
fn = ejs.compile(content);
assert.equal(fn({users: users}),
expectedResult);
});
test('works with windows style', function () {
var content = "<ul><% -%>\r\n"
+ "<% users.forEach(function(user){ -%>\r\n"
+ "<li><%= user.name -%></li>\r\n"
+ "<% }) -%>\r\n"
+ "</ul><% -%>\r\n";
var expectedResult = "<ul><li>geddy</li>\r\n<li>neil</li>\r\n<li>alex</li>\r\n</ul>";
var fn;
fn = ejs.compile(content);
assert.equal(fn({users: users}),
expectedResult);
});
});
suite('<%%', function () {
test('produce literals', function () {
assert.equal(ejs.render('<%%- "foo" %>'),
'<%- "foo" %>');
});
test('work without an end tag', function () {
assert.equal(ejs.render('<%%'), '<%');
assert.equal(ejs.render(fixture('literal.ejs'), {}, {delimiter: ' '}),
fixture('literal.html'));
});
});
suite('<%_ and _%>', function () {
test('slurps spaces and tabs', function () {
assert.equal(ejs.render(fixture('space-and-tab-slurp.ejs'), {users: users}),
fixture('space-and-tab-slurp.html'));
});
});
suite('single quotes', function () {
test('not mess up the constructed function', function () {
assert.equal(ejs.render(fixture('single-quote.ejs')),
fixture('single-quote.html'));
});
});
suite('double quotes', function () {
test('not mess up the constructed function', function () {
assert.equal(ejs.render(fixture('double-quote.ejs')),
fixture('double-quote.html'));
});
});
suite('backslashes', function () {
test('escape', function () {
assert.equal(ejs.render(fixture('backslash.ejs')),
fixture('backslash.html'));
});
});
suite('messed up whitespace', function () {
test('work', function () {
assert.equal(ejs.render(fixture('messed.ejs'), {users: users}),
fixture('messed.html'));
});
});
suite('exceptions', function () {
test('produce useful stack traces', function () {
try {
ejs.render(fixture('error.ejs'), {}, {filename: 'error.ejs'});
}
catch (err) {
assert.equal(err.path, 'error.ejs');
assert.equal(err.stack.split('\n').slice(0, 8).join('\n'), fixture('error.out'));
return;
}
throw new Error('no error reported when there should be');
});
test('not include fancy stack info if compileDebug is false', function () {
try {
ejs.render(fixture('error.ejs'), {}, {
filename: 'error.ejs',
compileDebug: false
});
}
catch (err) {
assert.ok(!err.path);
assert.notEqual(err.stack.split('\n').slice(0, 8).join('\n'), fixture('error.out'));
return;
}
throw new Error('no error reported when there should be');
});
var unhook = null;
test('log JS source when debug is set', function (done) {
var out = ''
, needToExit = false;
unhook = hook_stdio(process.stdout, function (str) {
out += str;
if (needToExit) {
return;
}
if (out.indexOf('__output')) {
needToExit = true;
unhook();
unhook = null;
return done();
}
});
ejs.render(fixture('hello-world.ejs'), {}, {debug: true});
});
teardown(function() {
if (!unhook) {
return;
}
unhook();
unhook = null;
});
});
suite('rmWhitespace', function () {
test('works', function () {
assert.equal(ejs.render(fixture('rmWhitespace.ejs'), {}, {rmWhitespace: true}),
fixture('rmWhitespace.html'));
});
});
suite('include()', function () {
test('include ejs', function () {
var file = 'test/fixtures/include-simple.ejs';
assert.equal(ejs.render(fixture('include-simple.ejs'), {}, {filename: file}),
fixture('include-simple.html'));
});
test('include ejs fails without `filename`', function () {
try {
ejs.render(fixture('include-simple.ejs'));
}
catch (err) {
assert.ok(err.message.indexOf('requires the \'filename\' option') > -1);
return;
}
throw new Error('expected inclusion error');
});
test('strips BOM', function () {
assert.equal(
ejs.render('<%- include("fixtures/includes/bom.ejs") %>',
{}, {filename: path.join(__dirname, 'f.ejs')}),
'<p>This is a file with BOM.</p>\n');
});
test('include ejs with locals', function () {
var file = 'test/fixtures/include.ejs';
assert.equal(ejs.render(fixture('include.ejs'), {pets: users}, {filename: file, delimiter: '@'}),
fixture('include.html'));
});
test('include ejs with absolute path and locals', function () {
var file = 'test/fixtures/include-abspath.ejs';
assert.equal(ejs.render(fixture('include-abspath.ejs'),
{dir: path.join(__dirname, 'fixtures'), pets: users, path: path},
{filename: file, delimiter: '@'}),
fixture('include.html'));
});
test('work when nested', function () {
var file = 'test/fixtures/menu.ejs';
assert.equal(ejs.render(fixture('menu.ejs'), {pets: users}, {filename: file}),
fixture('menu.html'));
});
test('work with a variable path', function () {
var file = 'test/fixtures/menu_var.ejs',
includePath = 'includes/menu-item';
assert.equal(ejs.render(fixture('menu.ejs'), {pets: users, varPath: includePath}, {filename: file}),
fixture('menu.html'));
});
test('include arbitrary files as-is', function () {
var file = 'test/fixtures/include.css.ejs';
assert.equal(ejs.render(fixture('include.css.ejs'), {pets: users}, {filename: file}),
fixture('include.css.html'));
});
test('pass compileDebug to include', function () {
var file = 'test/fixtures/include.ejs'
, fn;
fn = ejs.compile(fixture('include.ejs'), {
filename: file
, delimiter: '@'
, compileDebug: false
});
try {
// Render without a required variable reference
fn({foo: 'asdf'});
}
catch(e) {
assert.equal(e.message, 'pets is not defined');
assert.ok(!e.path);
return;
}
throw new Error('no error reported when there should be');
});
test('is dynamic', function () {
fs.writeFileSync(__dirname + '/tmp/include.ejs', '<p>Old</p>');
var file = 'test/fixtures/include_cache.ejs'
, options = {filename: file}
, out = ejs.compile(fixture('include_cache.ejs'), options);
assert.equal(out(), '<p>Old</p>\n');
fs.writeFileSync(__dirname + '/tmp/include.ejs', '<p>New</p>');
assert.equal(out(), '<p>New</p>\n');
});
test('support caching', function () {
fs.writeFileSync(__dirname + '/tmp/include.ejs', '<p>Old</p>');
var file = 'test/fixtures/include_cache.ejs'
, options = {cache: true, filename: file}
, out = ejs.render(fixture('include_cache.ejs'), {}, options)
, expected = fixture('include_cache.html');
assert.equal(out, expected);
out = ejs.render(fixture('include_cache.ejs'), {}, options);
// No change, still in cache
assert.equal(out, expected);
fs.writeFileSync(__dirname + '/tmp/include.ejs', '<p>New</p>');
out = ejs.render(fixture('include_cache.ejs'), {}, options);
assert.equal(out, expected);
});
});
suite('preprocessor include', function () {
test('work', function () {
var file = 'test/fixtures/include_preprocessor.ejs';
assert.equal(ejs.render(fixture('include_preprocessor.ejs'), {pets: users}, {filename: file, delimiter: '@'}),
fixture('include_preprocessor.html'));
});
test('no false positives', function () {
assert.equal(ejs.render('<% %> include foo <% %>'), ' include foo ');
});
test('fails without `filename`', function () {
try {
ejs.render(fixture('include_preprocessor.ejs'), {pets: users}, {delimiter: '@'});
}
catch (err) {
assert.ok(err.message.indexOf('requires the \'filename\' option') > -1);
return;
}
throw new Error('expected inclusion error');
});
test('strips BOM', function () {
assert.equal(
ejs.render('<% include fixtures/includes/bom.ejs %>',
{}, {filename: path.join(__dirname, 'f.ejs')}),
'<p>This is a file with BOM.</p>\n');
});
test('work when nested', function () {
var file = 'test/fixtures/menu_preprocessor.ejs';
assert.equal(ejs.render(fixture('menu_preprocessor.ejs'), {pets: users}, {filename: file}),
fixture('menu_preprocessor.html'));
});
test('tracks dependency correctly', function () {
var file = 'test/fixtures/menu_preprocessor.ejs'
, fn = ejs.compile(fixture('menu_preprocessor.ejs'), {filename: file});
assert(fn.dependencies.length);
});
test('include arbitrary files as-is', function () {
var file = 'test/fixtures/include_preprocessor.css.ejs';
assert.equal(ejs.render(fixture('include_preprocessor.css.ejs'), {pets: users}, {filename: file}),
fixture('include_preprocessor.css.html'));
});
test('pass compileDebug to include', function () {
var file = 'test/fixtures/include_preprocessor.ejs'
, fn;
fn = ejs.compile(fixture('include_preprocessor.ejs'), {
filename: file
, delimiter: '@'
, compileDebug: false
});
try {
// Render without a required variable reference
fn({foo: 'asdf'});
}
catch(e) {
assert.equal(e.message, 'pets is not defined');
assert.ok(!e.path);
return;
}
throw new Error('no error reported when there should be');
});
test('is static', function () {
fs.writeFileSync(__dirname + '/tmp/include_preprocessor.ejs', '<p>Old</p>');
var file = 'test/fixtures/include_preprocessor_cache.ejs'
, options = {filename: file}
, out = ejs.compile(fixture('include_preprocessor_cache.ejs'), options);
assert.equal(out(), '<p>Old</p>\n');
fs.writeFileSync(__dirname + '/tmp/include_preprocessor.ejs', '<p>New</p>');
assert.equal(out(), '<p>Old</p>\n');
});
test('support caching', function () {
fs.writeFileSync(__dirname + '/tmp/include_preprocessor.ejs', '<p>Old</p>');
var file = 'test/fixtures/include_preprocessor_cache.ejs'
, options = {cache: true, filename: file}
, out = ejs.render(fixture('include_preprocessor_cache.ejs'), {}, options)
, expected = fixture('include_preprocessor_cache.html');
assert.equal(out, expected);
fs.writeFileSync(__dirname + '/tmp/include_preprocessor.ejs', '<p>New</p>');
out = ejs.render(fixture('include_preprocessor_cache.ejs'), {}, options);
assert.equal(out, expected);
});
});
suite('comments', function () {
test('fully render with comments removed', function () {
assert.equal(ejs.render(fixture('comments.ejs')),
fixture('comments.html'));
});
});
suite('require', function () {
// Only works with inline/preprocessor includes
test('allow ejs templates to be required as node modules', function () {
var file = 'test/fixtures/include_preprocessor.ejs'
, template = require(__dirname + '/fixtures/menu_preprocessor.ejs');
if (!process.env.running_under_istanbul) {
assert.equal(template({filename: file, pets: users}),
fixture('menu_preprocessor.html'));
}
});
});
suite('examples', function () {
function noop () {}
fs.readdirSync('examples').forEach(function (f) {
if (!/\.js$/.test(f)) {
return;
}
suite(f, function () {
test('doesn\'t throw any errors', function () {
var stderr = hook_stdio(process.stderr, noop)
, stdout = hook_stdio(process.stdout, noop);
try {
require('../examples/' + f);
}
catch (ex) {
stdout();
stderr();
throw ex;
}
stdout();
stderr();
});
});
});
});

View File

@ -1 +0,0 @@
\foo

View File

@ -1 +0,0 @@
\foo

View File

@ -1,7 +0,0 @@
<li><a href="foo"><% // double-slash comment %>foo</li>
<li><a href="bar"><% /* C-style comment */ %>bar</li>
<li><a href="baz"><% // double-slash comment with newline
%>baz</li>
<li><a href="qux"><% var x = 'qux'; // double-slash comment @ end of line %><%= x %></li>
<li><a href="fee"><%# ERB style comment %>fee</li>
<li><a href="bah"><%= 'not a ' + '//' + ' comment' %></a></li>

View File

@ -1,6 +0,0 @@
<li><a href="foo">foo</li>
<li><a href="bar">bar</li>
<li><a href="baz">baz</li>
<li><a href="qux">qux</li>
<li><a href="fee">fee</li>
<li><a href="bah">not a // comment</a></li>

View File

@ -1 +0,0 @@
<% var a = 'foo' %><% var b = 'bar' %><%= a %>

View File

@ -1 +0,0 @@
foo

View File

@ -1 +0,0 @@
<p><%= "lo" + 'ki' %>'s "wheelchair"</p>

View File

@ -1 +0,0 @@
<p>loki's "wheelchair"</p>

View File

@ -1,5 +0,0 @@
<ul>
<% if (users) { %>
<p>Has users</p>
<% } %>
</ul>

View File

@ -1,8 +0,0 @@
ReferenceError: error.ejs:2
1| <ul>
>> 2| <% if (users) { %>
3| <p>Has users</p>
4| <% } %>
5| </ul>
users is not defined

View File

@ -1 +0,0 @@
<% function foo() return 'foo'; %>

View File

@ -1 +0,0 @@
<p>Hello world!</p>

View File

@ -1,5 +0,0 @@
<ul>
<@ pets.forEach(function(pet){ @>
<@- include(path.join(dir, 'pet'), {pet: pet}); @>
<@ }); @>
</ul>

View File

@ -1,3 +0,0 @@
<ul>
<%- include('hello-world'); %>
</ul>

View File

@ -1,4 +0,0 @@
<ul>
<p>Hello world!</p>
</ul>

View File

@ -1 +0,0 @@
<style><%- include('style.css', {value: 'bar'}); %></style>

View File

@ -1,4 +0,0 @@
<style>body {
foo: 'bar';
}
</style>

View File

@ -1,5 +0,0 @@
<ul>
<@ pets.forEach(function(pet){ @>
<@- include('pet', {pet: pet}); @>
<@ }); @>
</ul>

View File

@ -1,12 +0,0 @@
<ul>
<li>geddy</li>
<li>neil</li>
<li>alex</li>
</ul>

View File

@ -1 +0,0 @@
<%- include('../tmp/include') %>

View File

@ -1 +0,0 @@
<p>Old</p>

View File

@ -1 +0,0 @@
<style><% var value = 'bar' %><% include style.css %></style>

View File

@ -1,4 +0,0 @@
<style>body {
foo: 'bar';
}
</style>

View File

@ -1,5 +0,0 @@
<ul>
<@ pets.forEach(function(pet){ @>
<@ include pet @>
<@ }) @>
</ul>

View File

@ -1,12 +0,0 @@
<ul>
<li>geddy</li>
<li>neil</li>
<li>alex</li>
</ul>

View File

@ -1 +0,0 @@
<%- include ../tmp/include_preprocessor %>

View File

@ -1 +0,0 @@
<p>Old</p>

View File

@ -1 +0,0 @@
<p>This is a file with BOM.</p>

View File

@ -1 +0,0 @@
<li><% include menu/item %></li>

View File

@ -1 +0,0 @@
<a href="/<%= url %>"><%= title %></a>

View File

@ -1,3 +0,0 @@
<pre>There should be a space followed by a less-than sign and then two more
spaces in the next line:
< .</pre>

View File

@ -1,3 +0,0 @@
<pre>There should be a space followed by a less-than sign and then two more
spaces in the next line:
< .</pre>

View File

@ -1,15 +0,0 @@
<%- include('includes/menu-item', {
url: '/foo'
, title: 'Foo'
}); -%>
<%- include('includes/menu-item', {
url: '/bar'
, title: 'Bar'
}); -%>
<%- include('includes/menu-item', {
url: '/baz'
, title: 'Baz'
}); -%>

View File

@ -1,9 +0,0 @@
<li><a href="//foo">Foo</a>
</li>
<li><a href="//bar">Bar</a>
</li>
<li><a href="//baz">Baz</a>
</li>

View File

@ -1,11 +0,0 @@
<% var url = '/foo' -%>
<% var title = 'Foo' -%>
<% include includes/menu-item -%>
<% var url = '/bar' -%>
<% var title = 'Bar' -%>
<% include includes/menu-item -%>
<% var url = '/baz' -%>
<% var title = 'Baz' -%>
<% include includes/menu-item -%>

View File

@ -1,8 +0,0 @@
<li><a href="//foo">Foo</a>
</li>
<li><a href="//bar">Bar</a>
</li>
<li><a href="//baz">Baz</a>
</li>

View File

@ -1,15 +0,0 @@
<%- include(varPath, {
url: '/foo'
, title: 'Foo'
}); -%>
<%- include(varPath, {
url: '/bar'
, title: 'Bar'
}); -%>
<%- include(varPath, {
url: '/baz'
, title: 'Baz'
}); -%>

View File

@ -1 +0,0 @@
<ul><%users.forEach(function(user){%><li><%=user.name%></li><%})%></ul>

View File

@ -1 +0,0 @@
<ul><li>geddy</li><li>neil</li><li>alex</li></ul>

View File

@ -1,5 +0,0 @@
<ul>
<% users.forEach(function(user){ %>
<li><%= user.name %></li>
<% }) %>
</ul>

View File

@ -1,9 +0,0 @@
<ul>
<li>geddy</li>
<li>neil</li>
<li>alex</li>
</ul>

View File

@ -1,6 +0,0 @@
<ul>
<% var unused1 = 'blah' -%>
<% var unused2 = 'bleh' %>
<% var unused3 = 'bloh' -%>
<% var unused4 = 'bluh' %>
</ul>

View File

@ -1,4 +0,0 @@
<ul>
</ul>

View File

@ -1,5 +0,0 @@
<ul>
<% users.forEach(function(user){ -%>
<li><%= user.name %></li>
<% }) -%>
</ul>

View File

@ -1,5 +0,0 @@
AAA
<% data = "test"; -%>
BBB
<%= qdata %>
CCC

View File

@ -1,5 +0,0 @@
<ul>
<li>geddy</li>
<li>neil</li>
<li>alex</li>
</ul>

View File

@ -1,8 +0,0 @@
This document does not use semicolons in scriptlets.
<%
var a = 'b'
var b = 'c'
var c
c = b
%>
The value of c is: <%= c %>

View File

@ -1,3 +0,0 @@
This document does not use semicolons in scriptlets.
The value of c is: c

View File

@ -1 +0,0 @@
<p>hey</p>

View File

@ -1 +0,0 @@
<li><@= pet.name @></li>

View File

@ -1,14 +0,0 @@
<tag1>
<tag2>
A very long piece of text very long piece of text very long piece of
text very long piece <% var f = 'f' %>of text very long piece of
tex t very long piece of<% %>text very long
adsffadsfadsfad<%= f %>
piece of text.
<% var a = 'a' %>
Text again.
<% var b = 'b' %>
<% var c = 'c'
var d = 'd' %>
Another text. <%= c %>

View File

@ -1,8 +0,0 @@
<tag1>
<tag2>
A very long piece of text very long piece of text very long piece of
text very long piece of text very long piece of
text very long piece oftext very long
adsffadsfadsfadfpiece of text.
Text again.
Another text. c

View File

@ -1 +0,0 @@
<p><%= 'loki' %>'s wheelchair</p>

View File

@ -1 +0,0 @@
<p>loki's wheelchair</p>

View File

@ -1,3 +0,0 @@
body {
foo: '<%= value %>';
}

View File

@ -1 +0,0 @@
<h1><$= locals.name $></h1>

View File

@ -1 +0,0 @@
<h1><$= name $></h1>

View File

@ -1 +0,0 @@
<%= this.foo %>

3
node_modules/ejs/test/mocha.opts generated vendored
View File

@ -1,3 +0,0 @@
--ui tdd
--reporter spec
--check-leaks

132
node_modules/express/History.md generated vendored
View File

@ -1,3 +1,135 @@
4.16.3 / 2018-03-12
===================
* deps: accepts@~1.3.5
- deps: mime-types@~2.1.18
* deps: depd@~1.1.2
- perf: remove argument reassignment
* deps: encodeurl@~1.0.2
- Fix encoding `%` as last character
* deps: finalhandler@1.1.1
- Fix 404 output for bad / missing pathnames
- deps: encodeurl@~1.0.2
- deps: statuses@~1.4.0
* deps: proxy-addr@~2.0.3
- deps: ipaddr.js@1.6.0
* deps: send@0.16.2
- Fix incorrect end tag in default error & redirects
- deps: depd@~1.1.2
- deps: encodeurl@~1.0.2
- deps: statuses@~1.4.0
* deps: serve-static@1.13.2
- Fix incorrect end tag in redirects
- deps: encodeurl@~1.0.2
- deps: send@0.16.2
* deps: statuses@~1.4.0
* deps: type-is@~1.6.16
- deps: mime-types@~2.1.18
4.16.2 / 2017-10-09
===================
* Fix `TypeError` in `res.send` when given `Buffer` and `ETag` header set
* perf: skip parsing of entire `X-Forwarded-Proto` header
4.16.1 / 2017-09-29
===================
* deps: send@0.16.1
* deps: serve-static@1.13.1
- Fix regression when `root` is incorrectly set to a file
- deps: send@0.16.1
4.16.0 / 2017-09-28
===================
* Add `"json escape"` setting for `res.json` and `res.jsonp`
* Add `express.json` and `express.urlencoded` to parse bodies
* Add `options` argument to `res.download`
* Improve error message when autoloading invalid view engine
* Improve error messages when non-function provided as middleware
* Skip `Buffer` encoding when not generating ETag for small response
* Use `safe-buffer` for improved Buffer API
* deps: accepts@~1.3.4
- deps: mime-types@~2.1.16
* deps: content-type@~1.0.4
- perf: remove argument reassignment
- perf: skip parameter parsing when no parameters
* deps: etag@~1.8.1
- perf: replace regular expression with substring
* deps: finalhandler@1.1.0
- Use `res.headersSent` when available
* deps: parseurl@~1.3.2
- perf: reduce overhead for full URLs
- perf: unroll the "fast-path" `RegExp`
* deps: proxy-addr@~2.0.2
- Fix trimming leading / trailing OWS in `X-Forwarded-For`
- deps: forwarded@~0.1.2
- deps: ipaddr.js@1.5.2
- perf: reduce overhead when no `X-Forwarded-For` header
* deps: qs@6.5.1
- Fix parsing & compacting very deep objects
* deps: send@0.16.0
- Add 70 new types for file extensions
- Add `immutable` option
- Fix missing `</html>` in default error & redirects
- Set charset as "UTF-8" for .js and .json
- Use instance methods on steam to check for listeners
- deps: mime@1.4.1
- perf: improve path validation speed
* deps: serve-static@1.13.0
- Add 70 new types for file extensions
- Add `immutable` option
- Set charset as "UTF-8" for .js and .json
- deps: send@0.16.0
* deps: setprototypeof@1.1.0
* deps: utils-merge@1.0.1
* deps: vary@~1.1.2
- perf: improve header token parsing speed
* perf: re-use options object when generating ETags
* perf: remove dead `.charset` set in `res.jsonp`
4.15.5 / 2017-09-24
===================
* deps: debug@2.6.9
* deps: finalhandler@~1.0.6
- deps: debug@2.6.9
- deps: parseurl@~1.3.2
* deps: fresh@0.5.2
- Fix handling of modified headers with invalid dates
- perf: improve ETag match loop
- perf: improve `If-None-Match` token parsing
* deps: send@0.15.6
- Fix handling of modified headers with invalid dates
- deps: debug@2.6.9
- deps: etag@~1.8.1
- deps: fresh@0.5.2
- perf: improve `If-Match` token parsing
* deps: serve-static@1.12.6
- deps: parseurl@~1.3.2
- deps: send@0.15.6
- perf: improve slash collapsing
4.15.4 / 2017-08-06
===================
* deps: debug@2.6.8
* deps: depd@~1.1.1
- Remove unnecessary `Buffer` loading
* deps: finalhandler@~1.0.4
- deps: debug@2.6.8
* deps: proxy-addr@~1.1.5
- Fix array argument being altered
- deps: ipaddr.js@1.4.0
* deps: qs@6.5.0
* deps: send@0.15.4
- deps: debug@2.6.8
- deps: depd@~1.1.1
- deps: http-errors@~1.6.2
* deps: serve-static@1.12.4
- deps: send@0.15.4
4.15.3 / 2017-05-16 4.15.3 / 2017-05-16
=================== ===================

18
node_modules/express/Readme.md generated vendored
View File

@ -21,10 +21,22 @@ app.listen(3000)
## Installation ## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/).
Before installing, [download and install Node.js](https://nodejs.org/en/download/).
Node.js 0.10 or higher is required.
Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```bash ```bash
$ npm install express $ npm install express
``` ```
Follow [our installing guide](http://expressjs.com/en/starter/installing.html)
for more information.
## Features ## Features
* Robust routing * Robust routing
@ -39,7 +51,7 @@ $ npm install express
* [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/expressjs/expressjs.com)] * [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/expressjs/expressjs.com)]
* [#express](https://webchat.freenode.net/?channels=express) on freenode IRC * [#express](https://webchat.freenode.net/?channels=express) on freenode IRC
* [Github Organization](https://github.com/expressjs) for Official Middleware & Modules * [GitHub Organization](https://github.com/expressjs) for Official Middleware & Modules
* Visit the [Wiki](https://github.com/expressjs/express/wiki) * Visit the [Wiki](https://github.com/expressjs/express/wiki)
* [Google Group](https://groups.google.com/group/express-js) for discussion * [Google Group](https://groups.google.com/group/express-js) for discussion
* [Gitter](https://gitter.im/expressjs/express) for support and discussion * [Gitter](https://gitter.im/expressjs/express) for support and discussion
@ -115,9 +127,9 @@ $ npm test
## People ## People
The original author of Express is [TJ Holowaychuk](https://github.com/tj) [![TJ's Gratipay][gratipay-image-visionmedia]][gratipay-url-visionmedia] The original author of Express is [TJ Holowaychuk](https://github.com/tj)
The current lead maintainer is [Douglas Christopher Wilson](https://github.com/dougwilson) [![Doug's Gratipay][gratipay-image-dougwilson]][gratipay-url-dougwilson] The current lead maintainer is [Douglas Christopher Wilson](https://github.com/dougwilson)
[List of all contributors](https://github.com/expressjs/express/graphs/contributors) [List of all contributors](https://github.com/expressjs/express/graphs/contributors)

View File

@ -207,7 +207,7 @@ app.use = function use(fn) {
var fns = flatten(slice.call(arguments, offset)); var fns = flatten(slice.call(arguments, offset));
if (fns.length === 0) { if (fns.length === 0) {
throw new TypeError('app.use() requires middleware functions'); throw new TypeError('app.use() requires a middleware function')
} }
// setup router // setup router
@ -338,7 +338,7 @@ app.param = function param(name, fn) {
* Assign `setting` to `val`, or return `setting`'s value. * Assign `setting` to `val`, or return `setting`'s value.
* *
* app.set('foo', 'bar'); * app.set('foo', 'bar');
* app.get('foo'); * app.set('foo');
* // => "bar" * // => "bar"
* *
* Mounted servers inherit their parent server's settings. * Mounted servers inherit their parent server's settings.

View File

@ -12,6 +12,7 @@
* Module dependencies. * Module dependencies.
*/ */
var bodyParser = require('body-parser')
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var mixin = require('merge-descriptors'); var mixin = require('merge-descriptors');
var proto = require('./application'); var proto = require('./application');
@ -74,16 +75,16 @@ exports.Router = Router;
* Expose middleware * Expose middleware
*/ */
exports.json = bodyParser.json
exports.query = require('./middleware/query'); exports.query = require('./middleware/query');
exports.static = require('serve-static'); exports.static = require('serve-static');
exports.urlencoded = bodyParser.urlencoded
/** /**
* Replace removed middleware with an appropriate error message. * Replace removed middleware with an appropriate error message.
*/ */
[ ;[
'json',
'urlencoded',
'bodyParser', 'bodyParser',
'compress', 'compress',
'cookieSession', 'cookieSession',

View File

@ -315,8 +315,12 @@ defineGetter(req, 'protocol', function protocol(){
// Note: X-Forwarded-Proto is normally only ever a // Note: X-Forwarded-Proto is normally only ever a
// single value, but this is to be safe. // single value, but this is to be safe.
proto = this.get('X-Forwarded-Proto') || proto; var header = this.get('X-Forwarded-Proto') || proto
return proto.split(/\s*,\s*/)[0]; var index = header.indexOf(',')
return index !== -1
? header.substring(0, index).trim()
: header.trim()
}); });
/** /**

99
node_modules/express/lib/response.js generated vendored
View File

@ -12,6 +12,7 @@
* @private * @private
*/ */
var Buffer = require('safe-buffer').Buffer
var contentDisposition = require('content-disposition'); var contentDisposition = require('content-disposition');
var deprecate = require('depd')('express'); var deprecate = require('depd')('express');
var encodeUrl = require('encodeurl'); var encodeUrl = require('encodeurl');
@ -95,7 +96,7 @@ res.links = function(links){
* *
* Examples: * Examples:
* *
* res.send(new Buffer('wahoo')); * res.send(Buffer.from('wahoo'));
* res.send({ some: 'json' }); * res.send({ some: 'json' });
* res.send('<p>some html</p>'); * res.send('<p>some html</p>');
* *
@ -106,7 +107,6 @@ res.links = function(links){
res.send = function send(body) { res.send = function send(body) {
var chunk = body; var chunk = body;
var encoding; var encoding;
var len;
var req = this.req; var req = this.req;
var type; var type;
@ -171,23 +171,33 @@ res.send = function send(body) {
} }
} }
// determine if ETag should be generated
var etagFn = app.get('etag fn')
var generateETag = !this.get('ETag') && typeof etagFn === 'function'
// populate Content-Length // populate Content-Length
var len
if (chunk !== undefined) { if (chunk !== undefined) {
if (!Buffer.isBuffer(chunk)) { if (Buffer.isBuffer(chunk)) {
// convert chunk to Buffer; saves later double conversions // get length of Buffer
chunk = new Buffer(chunk, encoding); len = chunk.length
} else if (!generateETag && chunk.length < 1000) {
// just calculate length when no ETag + small chunk
len = Buffer.byteLength(chunk, encoding)
} else {
// convert chunk to Buffer and calculate
chunk = Buffer.from(chunk, encoding)
encoding = undefined; encoding = undefined;
len = chunk.length
} }
len = chunk.length;
this.set('Content-Length', len); this.set('Content-Length', len);
} }
// populate ETag // populate ETag
var etag; var etag;
var generateETag = len !== undefined && app.get('etag fn'); if (generateETag && len !== undefined) {
if (typeof generateETag === 'function' && !this.get('ETag')) { if ((etag = etagFn(chunk, encoding))) {
if ((etag = generateETag(chunk, encoding))) {
this.set('ETag', etag); this.set('ETag', etag);
} }
} }
@ -244,9 +254,10 @@ res.json = function json(obj) {
// settings // settings
var app = this.app; var app = this.app;
var escape = app.get('json escape')
var replacer = app.get('json replacer'); var replacer = app.get('json replacer');
var spaces = app.get('json spaces'); var spaces = app.get('json spaces');
var body = stringify(val, replacer, spaces); var body = stringify(val, replacer, spaces, escape)
// content-type // content-type
if (!this.get('Content-Type')) { if (!this.get('Content-Type')) {
@ -286,9 +297,10 @@ res.jsonp = function jsonp(obj) {
// settings // settings
var app = this.app; var app = this.app;
var escape = app.get('json escape')
var replacer = app.get('json replacer'); var replacer = app.get('json replacer');
var spaces = app.get('json spaces'); var spaces = app.get('json spaces');
var body = stringify(val, replacer, spaces); var body = stringify(val, replacer, spaces, escape)
var callback = this.req.query[app.get('jsonp callback name')]; var callback = this.req.query[app.get('jsonp callback name')];
// content-type // content-type
@ -304,7 +316,6 @@ res.jsonp = function jsonp(obj) {
// jsonp // jsonp
if (typeof callback === 'string' && callback.length !== 0) { if (typeof callback === 'string' && callback.length !== 0) {
this.charset = 'utf-8';
this.set('X-Content-Type-Options', 'nosniff'); this.set('X-Content-Type-Options', 'nosniff');
this.set('Content-Type', 'text/javascript'); this.set('Content-Type', 'text/javascript');
@ -506,19 +517,29 @@ res.sendfile = deprecate.function(res.sendfile,
* when the data transfer is complete, or when an error has * when the data transfer is complete, or when an error has
* ocurred. Be sure to check `res.headersSent` if you plan to respond. * ocurred. Be sure to check `res.headersSent` if you plan to respond.
* *
* This method uses `res.sendfile()`. * Optionally providing an `options` object to use with `res.sendFile()`.
* This function will set the `Content-Disposition` header, overriding
* any `Content-Disposition` header passed as header options in order
* to set the attachment and filename.
*
* This method uses `res.sendFile()`.
* *
* @public * @public
*/ */
res.download = function download(path, filename, callback) { res.download = function download (path, filename, options, callback) {
var done = callback; var done = callback;
var name = filename; var name = filename;
var opts = options || null
// support function as second arg // support function as second or third arg
if (typeof filename === 'function') { if (typeof filename === 'function') {
done = filename; done = filename;
name = null; name = null;
opts = null
} else if (typeof options === 'function') {
done = options
opts = null
} }
// set Content-Disposition when file is sent // set Content-Disposition when file is sent
@ -526,10 +547,26 @@ res.download = function download(path, filename, callback) {
'Content-Disposition': contentDisposition(name || path) 'Content-Disposition': contentDisposition(name || path)
}; };
// merge user-provided headers
if (opts && opts.headers) {
var keys = Object.keys(opts.headers)
for (var i = 0; i < keys.length; i++) {
var key = keys[i]
if (key.toLowerCase() !== 'content-disposition') {
headers[key] = opts.headers[key]
}
}
}
// merge user-provided options
opts = Object.create(opts)
opts.headers = headers
// Resolve the full path for sendFile // Resolve the full path for sendFile
var fullPath = resolve(path); var fullPath = resolve(path);
return this.sendFile(fullPath, { headers: headers }, done); // send file
return this.sendFile(fullPath, opts, done)
}; };
/** /**
@ -1063,14 +1100,38 @@ function sendfile(res, file, options, callback) {
} }
/** /**
* Stringify JSON, like JSON.stringify, but v8 optimized. * Stringify JSON, like JSON.stringify, but v8 optimized, with the
* ability to escape characters that can trigger HTML sniffing.
*
* @param {*} value
* @param {function} replaces
* @param {number} spaces
* @param {boolean} escape
* @returns {string}
* @private * @private
*/ */
function stringify(value, replacer, spaces) { function stringify (value, replacer, spaces, escape) {
// v8 checks arguments.length for optimizing simple call // v8 checks arguments.length for optimizing simple call
// https://bugs.chromium.org/p/v8/issues/detail?id=4730 // https://bugs.chromium.org/p/v8/issues/detail?id=4730
return replacer || spaces var json = replacer || spaces
? JSON.stringify(value, replacer, spaces) ? JSON.stringify(value, replacer, spaces)
: JSON.stringify(value); : JSON.stringify(value);
if (escape) {
json = json.replace(/[<>&]/g, function (c) {
switch (c.charCodeAt(0)) {
case 0x3c:
return '\\u003c'
case 0x3e:
return '\\u003e'
case 0x26:
return '\\u0026'
default:
return c
}
})
}
return json
} }

View File

@ -448,14 +448,14 @@ proto.use = function use(fn) {
var callbacks = flatten(slice.call(arguments, offset)); var callbacks = flatten(slice.call(arguments, offset));
if (callbacks.length === 0) { if (callbacks.length === 0) {
throw new TypeError('Router.use() requires middleware functions'); throw new TypeError('Router.use() requires a middleware function')
} }
for (var i = 0; i < callbacks.length; i++) { for (var i = 0; i < callbacks.length; i++) {
var fn = callbacks[i]; var fn = callbacks[i];
if (typeof fn !== 'function') { if (typeof fn !== 'function') {
throw new TypeError('Router.use() requires middleware function but got a ' + gettype(fn)); throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
} }
// add the middleware // add the middleware

View File

@ -175,7 +175,7 @@ Route.prototype.all = function all() {
if (typeof handle !== 'function') { if (typeof handle !== 'function') {
var type = toString.call(handle); var type = toString.call(handle);
var msg = 'Route.all() requires callback functions but got a ' + type; var msg = 'Route.all() requires a callback function but got a ' + type
throw new TypeError(msg); throw new TypeError(msg);
} }
@ -198,7 +198,7 @@ methods.forEach(function(method){
if (typeof handle !== 'function') { if (typeof handle !== 'function') {
var type = toString.call(handle); var type = toString.call(handle);
var msg = 'Route.' + method + '() requires callback functions but got a ' + type; var msg = 'Route.' + method + '() requires a callback function but got a ' + type
throw new Error(msg); throw new Error(msg);
} }

37
node_modules/express/lib/utils.js generated vendored
View File

@ -12,12 +12,12 @@
* @api private * @api private
*/ */
var Buffer = require('safe-buffer').Buffer
var contentDisposition = require('content-disposition'); var contentDisposition = require('content-disposition');
var contentType = require('content-type'); var contentType = require('content-type');
var deprecate = require('depd')('express'); var deprecate = require('depd')('express');
var flatten = require('array-flatten'); var flatten = require('array-flatten');
var mime = require('send').mime; var mime = require('send').mime;
var basename = require('path').basename;
var etag = require('etag'); var etag = require('etag');
var proxyaddr = require('proxy-addr'); var proxyaddr = require('proxy-addr');
var qs = require('qs'); var qs = require('qs');
@ -32,13 +32,7 @@ var querystring = require('querystring');
* @api private * @api private
*/ */
exports.etag = function (body, encoding) { exports.etag = createETagGenerator({ weak: false })
var buf = !Buffer.isBuffer(body)
? new Buffer(body, encoding)
: body;
return etag(buf, {weak: false});
};
/** /**
* Return weak ETag for `body`. * Return weak ETag for `body`.
@ -49,13 +43,7 @@ exports.etag = function (body, encoding) {
* @api private * @api private
*/ */
exports.wetag = function wetag(body, encoding){ exports.wetag = createETagGenerator({ weak: true })
var buf = !Buffer.isBuffer(body)
? new Buffer(body, encoding)
: body;
return etag(buf, {weak: true});
};
/** /**
* Check if `path` looks absolute. * Check if `path` looks absolute.
@ -274,6 +262,25 @@ exports.setCharset = function setCharset(type, charset) {
return contentType.format(parsed); return contentType.format(parsed);
}; };
/**
* Create an ETag generator function, generating ETags with
* the given options.
*
* @param {object} options
* @return {function}
* @private
*/
function createETagGenerator (options) {
return function generateETag (body, encoding) {
var buf = !Buffer.isBuffer(body)
? Buffer.from(body, encoding)
: body
return etag(buf, options)
}
}
/** /**
* Parse an extended query string with qs. * Parse an extended query string with qs.
* *

11
node_modules/express/lib/view.js generated vendored
View File

@ -16,7 +16,6 @@
var debug = require('debug')('express:view'); var debug = require('debug')('express:view');
var path = require('path'); var path = require('path');
var fs = require('fs'); var fs = require('fs');
var utils = require('./utils');
/** /**
* Module variables. * Module variables.
@ -77,7 +76,15 @@ function View(name, options) {
// load engine // load engine
var mod = this.ext.substr(1) var mod = this.ext.substr(1)
debug('require "%s"', mod) debug('require "%s"', mod)
opts.engines[this.ext] = require(mod).__express
// default engine export
var fn = require(mod).__express
if (typeof fn !== 'function') {
throw new Error('Module "' + mod + '" does not provide a view engine.')
}
opts.engines[this.ext] = fn
} }
// store loaded engine // store loaded engine

114
node_modules/express/package.json generated vendored
View File

@ -1,46 +1,37 @@
{ {
"_args": [ "_from": "express@^4.15.3",
[ "_id": "express@4.16.3",
"express@4.15.3",
"/Users/martin/dev/Rinser"
]
],
"_from": "express@4.15.3",
"_id": "express@4.15.3",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha1-urZdDwOqgMNYQIly/HAPkWlEtmI=", "_integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
"_location": "/express", "_location": "/express",
"_phantomChildren": { "_phantomChildren": {
"debug": "2.6.7", "bytes": "3.0.0",
"depd": "1.1.0", "content-type": "1.0.4",
"destroy": "1.0.4", "debug": "2.6.9",
"encodeurl": "1.0.1", "depd": "1.1.2",
"escape-html": "1.0.3", "http-errors": "1.6.3",
"forwarded": "0.1.0", "inherits": "2.0.3",
"http-errors": "1.6.1",
"mime": "1.3.4",
"ms": "2.0.0",
"on-finished": "2.3.0", "on-finished": "2.3.0",
"parseurl": "1.3.1", "type-is": "1.6.16",
"statuses": "1.3.1",
"unpipe": "1.0.0" "unpipe": "1.0.0"
}, },
"_requested": { "_requested": {
"type": "version", "type": "range",
"registry": true, "registry": true,
"raw": "express@4.15.3", "raw": "express@^4.15.3",
"name": "express", "name": "express",
"escapedName": "express", "escapedName": "express",
"rawSpec": "4.15.3", "rawSpec": "^4.15.3",
"saveSpec": null, "saveSpec": null,
"fetchSpec": "4.15.3" "fetchSpec": "^4.15.3"
}, },
"_requiredBy": [ "_requiredBy": [
"/" "/"
], ],
"_resolved": "https://registry.npmjs.org/express/-/express-4.15.3.tgz", "_resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
"_spec": "4.15.3", "_shasum": "6af8a502350db3246ecc4becf6b5a34d22f7ed53",
"_where": "/Users/martin/dev/Rinser", "_spec": "express@^4.15.3",
"_where": "/Users/martin/dev/test/Rinser",
"author": { "author": {
"name": "TJ Holowaychuk", "name": "TJ Holowaychuk",
"email": "tj@vision-media.ca" "email": "tj@vision-media.ca"
@ -48,6 +39,7 @@
"bugs": { "bugs": {
"url": "https://github.com/expressjs/express/issues" "url": "https://github.com/expressjs/express/issues"
}, },
"bundleDependencies": false,
"contributors": [ "contributors": [
{ {
"name": "Aaron Heckmann", "name": "Aaron Heckmann",
@ -79,53 +71,56 @@
} }
], ],
"dependencies": { "dependencies": {
"accepts": "~1.3.3", "accepts": "~1.3.5",
"array-flatten": "1.1.1", "array-flatten": "1.1.1",
"body-parser": "1.18.2",
"content-disposition": "0.5.2", "content-disposition": "0.5.2",
"content-type": "~1.0.2", "content-type": "~1.0.4",
"cookie": "0.3.1", "cookie": "0.3.1",
"cookie-signature": "1.0.6", "cookie-signature": "1.0.6",
"debug": "2.6.7", "debug": "2.6.9",
"depd": "~1.1.0", "depd": "~1.1.2",
"encodeurl": "~1.0.1", "encodeurl": "~1.0.2",
"escape-html": "~1.0.3", "escape-html": "~1.0.3",
"etag": "~1.8.0", "etag": "~1.8.1",
"finalhandler": "~1.0.3", "finalhandler": "1.1.1",
"fresh": "0.5.0", "fresh": "0.5.2",
"merge-descriptors": "1.0.1", "merge-descriptors": "1.0.1",
"methods": "~1.1.2", "methods": "~1.1.2",
"on-finished": "~2.3.0", "on-finished": "~2.3.0",
"parseurl": "~1.3.1", "parseurl": "~1.3.2",
"path-to-regexp": "0.1.7", "path-to-regexp": "0.1.7",
"proxy-addr": "~1.1.4", "proxy-addr": "~2.0.3",
"qs": "6.4.0", "qs": "6.5.1",
"range-parser": "~1.2.0", "range-parser": "~1.2.0",
"send": "0.15.3", "safe-buffer": "5.1.1",
"serve-static": "1.12.3", "send": "0.16.2",
"setprototypeof": "1.0.3", "serve-static": "1.13.2",
"statuses": "~1.3.1", "setprototypeof": "1.1.0",
"type-is": "~1.6.15", "statuses": "~1.4.0",
"utils-merge": "1.0.0", "type-is": "~1.6.16",
"vary": "~1.1.1" "utils-merge": "1.0.1",
"vary": "~1.1.2"
}, },
"deprecated": false,
"description": "Fast, unopinionated, minimalist web framework", "description": "Fast, unopinionated, minimalist web framework",
"devDependencies": { "devDependencies": {
"after": "0.8.2", "after": "0.8.2",
"body-parser": "1.17.1",
"connect-redis": "~2.4.1", "connect-redis": "~2.4.1",
"cookie-parser": "~1.4.3", "cookie-parser": "~1.4.3",
"cookie-session": "~1.2.0", "cookie-session": "1.3.2",
"ejs": "2.5.6", "ejs": "2.5.7",
"express-session": "1.15.2", "eslint": "2.13.1",
"express-session": "1.15.6",
"hbs": "4.0.1", "hbs": "4.0.1",
"istanbul": "0.4.5", "istanbul": "0.4.5",
"marked": "0.3.6", "marked": "0.3.17",
"method-override": "2.3.8", "method-override": "2.3.10",
"mocha": "3.4.1", "mocha": "3.5.3",
"morgan": "1.8.1", "morgan": "1.9.0",
"multiparty": "4.1.3", "multiparty": "4.1.3",
"pbkdf2-password": "1.2.1", "pbkdf2-password": "1.2.1",
"should": "11.2.1", "should": "13.2.1",
"supertest": "1.2.0", "supertest": "1.2.0",
"vhost": "~3.0.2" "vhost": "~3.0.2"
}, },
@ -158,10 +153,11 @@
"url": "git+https://github.com/expressjs/express.git" "url": "git+https://github.com/expressjs/express.git"
}, },
"scripts": { "scripts": {
"test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/", "lint": "eslint .",
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/", "test": "mocha --require test/support/env --reporter spec --bail --check-leaks --no-exit test/ test/acceptance/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/", "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks --no-exit test/ test/acceptance/",
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/" "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks --no-exit test/ test/acceptance/",
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks --no-exit test/ test/acceptance/"
}, },
"version": "4.15.3" "version": "4.16.3"
} }

6
node_modules/lodash/README.md generated vendored
View File

@ -1,4 +1,4 @@
# lodash v4.17.4 # lodash v4.17.10
The [Lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules. The [Lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules.
@ -28,12 +28,12 @@ var at = require('lodash/at');
var curryN = require('lodash/fp/curryN'); var curryN = require('lodash/fp/curryN');
``` ```
See the [package source](https://github.com/lodash/lodash/tree/4.17.4-npm) for more details. See the [package source](https://github.com/lodash/lodash/tree/4.17.10-npm) for more details.
**Note:**<br> **Note:**<br>
Install [n_](https://www.npmjs.com/package/n_) for Lodash use in the Node.js < 6 REPL. Install [n_](https://www.npmjs.com/package/n_) for Lodash use in the Node.js < 6 REPL.
## Support ## Support
Tested in Chrome 54-55, Firefox 49-50, IE 11, Edge 14, Safari 9-10, Node.js 6-7, & PhantomJS 2.1.1.<br> Tested in Chrome 63-64, Firefox 57-58, IE 11, Edge 14, Safari 10-11, Node.js 4-9, & PhantomJS 2.1.1.<br>
Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available.

34
node_modules/lodash/package.json generated vendored
View File

@ -1,25 +1,19 @@
{ {
"_args": [ "_from": "lodash@^4.16.6",
[ "_id": "lodash@4.17.10",
"lodash@4.17.4",
"/Users/martin/dev/Rinser"
]
],
"_from": "lodash@4.17.4",
"_id": "lodash@4.17.4",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", "_integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
"_location": "/lodash", "_location": "/lodash",
"_phantomChildren": {}, "_phantomChildren": {},
"_requested": { "_requested": {
"type": "version", "type": "range",
"registry": true, "registry": true,
"raw": "lodash@4.17.4", "raw": "lodash@^4.16.6",
"name": "lodash", "name": "lodash",
"escapedName": "lodash", "escapedName": "lodash",
"rawSpec": "4.17.4", "rawSpec": "^4.16.6",
"saveSpec": null, "saveSpec": null,
"fetchSpec": "4.17.4" "fetchSpec": "^4.16.6"
}, },
"_requiredBy": [ "_requiredBy": [
"/", "/",
@ -32,14 +26,14 @@
"/gulp-uglify", "/gulp-uglify",
"/hipchat-notifier", "/hipchat-notifier",
"/inquirer", "/inquirer",
"/mailgun-js/async",
"/requestretry", "/requestretry",
"/rss-braider", "/rss-braider",
"/table" "/table"
], ],
"_resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", "_resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
"_spec": "4.17.4", "_shasum": "1b7793cf7259ea38fb3661d4d38b3260af8ae4e7",
"_where": "/Users/martin/dev/Rinser", "_spec": "lodash@^4.16.6",
"_where": "/Users/martin/dev/test/Rinser",
"author": { "author": {
"name": "John-David Dalton", "name": "John-David Dalton",
"email": "john.david.dalton@gmail.com", "email": "john.david.dalton@gmail.com",
@ -48,6 +42,7 @@
"bugs": { "bugs": {
"url": "https://github.com/lodash/lodash/issues" "url": "https://github.com/lodash/lodash/issues"
}, },
"bundleDependencies": false,
"contributors": [ "contributors": [
{ {
"name": "John-David Dalton", "name": "John-David Dalton",
@ -60,6 +55,7 @@
"url": "https://mathiasbynens.be/" "url": "https://mathiasbynens.be/"
} }
], ],
"deprecated": false,
"description": "Lodash modular utilities.", "description": "Lodash modular utilities.",
"homepage": "https://lodash.com/", "homepage": "https://lodash.com/",
"icon": "https://lodash.com/icon.svg", "icon": "https://lodash.com/icon.svg",
@ -76,7 +72,7 @@
"url": "git+https://github.com/lodash/lodash.git" "url": "git+https://github.com/lodash/lodash.git"
}, },
"scripts": { "scripts": {
"test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" "test": "echo \"See https://travis-ci.org/lodash-archive/lodash-cli for testing details.\""
}, },
"version": "4.17.4" "version": "4.17.10"
} }

View File

@ -2,7 +2,7 @@
"_from": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git", "_from": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
"_id": "rss-braider@1.2.2", "_id": "rss-braider@1.2.2",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha1-RwjGz4pf+NUkSQmupBC84F0Y2mc=", "_integrity": "",
"_location": "/rss-braider", "_location": "/rss-braider",
"_phantomChildren": {}, "_phantomChildren": {},
"_requested": { "_requested": {
@ -13,14 +13,14 @@
"rawSpec": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git", "rawSpec": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
"saveSpec": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git", "saveSpec": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
"fetchSpec": "https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git", "fetchSpec": "https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
"gitCommittish": "master" "gitCommittish": null
}, },
"_requiredBy": [ "_requiredBy": [
"/" "/"
], ],
"_resolved": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git#607d5aa96e76887c909f090957bc13afc69d859b", "_resolved": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git#607d5aa96e76887c909f090957bc13afc69d859b",
"_spec": "rss-braider@git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git", "_spec": "rss-braider@git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
"_where": "/Users/martin/dev/Rinser", "_where": "/Users/martin/dev/test/Rinser",
"author": { "author": {
"name": "Kip Gebhardt", "name": "Kip Gebhardt",
"email": "kgebhardt@kqed.org" "email": "kgebhardt@kqed.org"

8873
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,20 +2,20 @@
"name": "Rinser", "name": "Rinser",
"version": "0.1.1", "version": "0.1.1",
"devDependencies": { "devDependencies": {
"babel-eslint": "^7.2.3", "babel-eslint": "^8.2.3",
"cheerio": "^0.22.0", "cheerio": "^0.22.0",
"del": "^2.2.0", "del": "^3.0.0",
"eslint": "^4.2.0", "eslint": "^4.2.0",
"eslint-config-babel": "^7.0.1", "eslint-config-babel": "^7.0.1",
"eslint-config-defaults": "^9.0.0", "eslint-config-defaults": "^9.0.0",
"eslint-plugin-flowtype": "^2.35.0", "eslint-plugin-flowtype": "^2.35.0",
"gulp": "^3.9.1", "gulp": "^3.9.1",
"gulp-autoprefixer": "^4.0.0", "gulp-autoprefixer": "^5.0.0",
"gulp-cache": "^0.4.6", "gulp-cache": "^1.0.2",
"gulp-concat": "^2.6.1", "gulp-concat": "^2.6.1",
"gulp-cssnano": "^2.1.1", "gulp-cssnano": "^2.1.1",
"gulp-html-replace": "^1.6.2", "gulp-html-replace": "^1.6.2",
"gulp-htmlmin": "^3.0.0", "gulp-htmlmin": "^4.0.0",
"gulp-inject": "^4.2.0", "gulp-inject": "^4.2.0",
"gulp-jshint": "^2.0.4", "gulp-jshint": "^2.0.4",
"gulp-livereload": "^3.8.1", "gulp-livereload": "^3.8.1",
@ -35,12 +35,12 @@
"express": "^4.15.3", "express": "^4.15.3",
"express-session": "^1.15.3", "express-session": "^1.15.3",
"htmlparser": "^1.7.7", "htmlparser": "^1.7.7",
"jsonfile": "^3.0.1", "jsonfile": "^4.0.0",
"lodash": "^4.16.6", "lodash": "^4.16.6",
"method-override": "^2.3.9", "method-override": "^2.3.9",
"morgan": "^1.8.2", "morgan": "^1.8.2",
"request": "^2.81.0", "request": "^2.81.0",
"rss-braider": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git", "rss-braider": "git+https://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
"yargs": "^8.0.2" "yargs": "^11.0.0"
} }
} }