updated npm
This commit is contained in:
parent
8f674d16f8
commit
2a2ec3c100
79
node_modules/ejs/Jakefile
generated
vendored
79
node_modules/ejs/Jakefile
generated
vendored
@ -1,10 +1,12 @@
|
||||
var fs = require('fs')
|
||||
, buildOpts = {
|
||||
printStdout: true
|
||||
, printStderr: true
|
||||
};
|
||||
var fs = require('fs');
|
||||
var execSync = require('child_process').execSync;
|
||||
var exec = function (cmd) {
|
||||
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.');
|
||||
});
|
||||
|
||||
@ -12,35 +14,58 @@ desc('Cleans browerified/minified files and package files');
|
||||
task('clean', ['clobber'], function () {
|
||||
jake.rmRf('./ejs.js');
|
||||
jake.rmRf('./ejs.min.js');
|
||||
console.log('Cleaned up compiled files.');
|
||||
});
|
||||
|
||||
task('browserify', {async: true}, function () {
|
||||
jake.exec('./node_modules/browserify/bin/cmd.js lib/ejs.js > ejs.js',
|
||||
buildOpts, function () {
|
||||
console.log('Browserification completed.');
|
||||
setTimeout(complete, 0);
|
||||
});
|
||||
desc('Lints the source code');
|
||||
task('lint', function () {
|
||||
exec('./node_modules/.bin/eslint \"**/*.js\" Jakefile');
|
||||
console.log('Linting completed.');
|
||||
});
|
||||
|
||||
task('minify', {async: true}, function () {
|
||||
jake.exec('./node_modules/uglify-js/bin/uglifyjs ejs.js > ejs.min.js',
|
||||
buildOpts, function () {
|
||||
console.log('Minification completed.');
|
||||
setTimeout(complete, 0);
|
||||
});
|
||||
task('browserify', function () {
|
||||
exec('./node_modules/browserify/bin/cmd.js --standalone ejs lib/ejs.js > ejs.js');
|
||||
console.log('Browserification completed.');
|
||||
});
|
||||
|
||||
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 () {
|
||||
this.packageFiles.include([
|
||||
'Jakefile'
|
||||
, 'README.md'
|
||||
, 'LICENSE'
|
||||
, 'package.json'
|
||||
, 'ejs.js'
|
||||
, 'ejs.min.js'
|
||||
, 'lib/**'
|
||||
, 'test/**'
|
||||
'Jakefile',
|
||||
'README.md',
|
||||
'LICENSE',
|
||||
'package.json',
|
||||
'ejs.js',
|
||||
'ejs.min.js',
|
||||
'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();
|
||||
});
|
||||
|
53
node_modules/ejs/README.md
generated
vendored
53
node_modules/ejs/README.md
generated
vendored
@ -3,7 +3,7 @@
|
||||
Embedded JavaScript templates
|
||||
|
||||
[![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)
|
||||
|
||||
## Installation
|
||||
|
||||
@ -18,7 +18,7 @@ $ npm install ejs
|
||||
* Unescaped raw output with `<%- %>`
|
||||
* Newline-trim mode ('newline slurping') with `-%>` ending tag
|
||||
* 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
|
||||
* Client-side support
|
||||
* Static caching of intermediate JavaScript
|
||||
@ -33,6 +33,8 @@ $ npm install ejs
|
||||
<% } %>
|
||||
```
|
||||
|
||||
Try EJS online at: https://ionicabizau.github.io/ejs-playground/.
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
@ -50,19 +52,20 @@ ejs.renderFile(filename, data, options, function(err, str){
|
||||
|
||||
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
|
||||
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.
|
||||
Therefore, we do not recommend using this shortcut.
|
||||
|
||||
## Options
|
||||
|
||||
- `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.
|
||||
- `root` Set project root for includes with an absolute path (/file.ejs).
|
||||
- `context` Function execution context
|
||||
- `compileDebug` When `false` no debug instrumentation is compiled
|
||||
- `client` When `true`, compiles a function that can be rendered
|
||||
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)).
|
||||
- `delimiter` Character to use with angle brackets for open/close
|
||||
- `debug` Output generated function body
|
||||
@ -76,9 +79,9 @@ Therefore, we do not recommend using this shortcut.
|
||||
- `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).
|
||||
|
||||
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
|
||||
with the proper options and output the documentation to `out/`. If you want
|
||||
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
|
||||
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.
|
||||
|
||||
## Tags
|
||||
@ -89,6 +92,7 @@ the both the public & private API docs, run `npm run devdoc` instead.
|
||||
- `<%-` Outputs the unescaped value into the template
|
||||
- `<%#` Comment tag, no execution, no output
|
||||
- `<%%` Outputs a literal '<%'
|
||||
- `%%>` Outputs a literal '%>'
|
||||
- `%>` Plain ending tag
|
||||
- `-%>` Trim-mode ('newline slurp') tag, trims following newline
|
||||
- `_%>` 'Whitespace Slurping' ending tag, removes all whitespace after it
|
||||
@ -98,11 +102,11 @@ For the full syntax documentation, please see [docs/syntax.md](https://github.co
|
||||
## Includes
|
||||
|
||||
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
|
||||
including `./views/user/show.ejs` from `./views/users.ejs` you would
|
||||
relative to the template with the `include` call. For example if you are
|
||||
including `./views/user/show.ejs` from `./views/users.ejs` you would
|
||||
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()`.
|
||||
|
||||
You'll likely want to use the raw output tag (`<%-`) with your include to avoid
|
||||
@ -158,6 +162,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
|
||||
of the LRU.
|
||||
|
||||
## Custom FileLoader
|
||||
|
||||
The default file loader is `fs.readFileSync`, if you want to customize it, you can set ejs.fileLoader.
|
||||
|
||||
```javascript
|
||||
var ejs = require('ejs');
|
||||
var myFileLoad = function (filePath) {
|
||||
return 'myFileLoad: ' + fs.readFileSync(filePath);
|
||||
};
|
||||
|
||||
ejs.fileLoader = myFileLoad;
|
||||
```
|
||||
|
||||
With this feature, you can preprocess the template before reading it.
|
||||
|
||||
## Layouts
|
||||
|
||||
EJS does not specifically support blocks, but layouts can be implemented by
|
||||
@ -178,8 +197,8 @@ including headers and footers, like so:
|
||||
## Client-side support
|
||||
|
||||
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
|
||||
the repository and running `jake build` (or `$(npm bin)/jake build` if jake is
|
||||
`./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
|
||||
not installed globally).
|
||||
|
||||
Include one of these files on your page, and `ejs` should be available globally.
|
||||
@ -208,11 +227,11 @@ Most of EJS will work as expected; however, there are a few things to note:
|
||||
```javascript
|
||||
var str = "Hello <%= include('file', {person: 'John'}); %>",
|
||||
fn = ejs.compile(str, {client: true});
|
||||
|
||||
|
||||
fn(data, null, function(path, d){ // IncludeCallback
|
||||
// path -> 'file'
|
||||
// d -> {person: 'John'}
|
||||
// Put your code here
|
||||
// Put your code here
|
||||
// Return the contents of file as a string
|
||||
}); // returns rendered string
|
||||
```
|
||||
@ -235,5 +254,3 @@ Licensed under the Apache License, Version 2.0
|
||||
- - -
|
||||
EJS Embedded JavaScript templates copyright 2112
|
||||
mde@fleegix.org.
|
||||
|
||||
|
||||
|
768
node_modules/ejs/ejs.js
generated
vendored
768
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
2
node_modules/ejs/ejs.min.js
generated
vendored
File diff suppressed because one or more lines are too long
554
node_modules/ejs/lib/ejs.js
generated
vendored
554
node_modules/ejs/lib/ejs.js
generated
vendored
@ -19,7 +19,7 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @file Embedded JavaScript templating engine.
|
||||
* @file Embedded JavaScript templating engine. {@link http://ejs.co}
|
||||
* @author Matthew Eernisse <mde@fleegix.org>
|
||||
* @author Tiancheng "Timothy" Gu <timothygu99@gmail.com>
|
||||
* @project EJS
|
||||
@ -44,19 +44,23 @@
|
||||
* @public
|
||||
*/
|
||||
|
||||
var fs = require('fs')
|
||||
, utils = require('./utils')
|
||||
, scopeOptionWarned = false
|
||||
, _VERSION_STRING = require('../package.json').version
|
||||
, _DEFAULT_DELIMITER = '%'
|
||||
, _DEFAULT_LOCALS_NAME = 'locals'
|
||||
, _REGEX_STRING = '(<%%|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)'
|
||||
, _OPTS = [ 'cache', 'filename', 'delimiter', 'scope', 'context'
|
||||
, 'debug', 'compileDebug', 'client', '_with', 'rmWhitespace'
|
||||
, 'strict', 'localsName'
|
||||
]
|
||||
, _TRAILING_SEMCOL = /;\s*$/
|
||||
, _BOM = /^\uFEFF/;
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var utils = require('./utils');
|
||||
|
||||
var scopeOptionWarned = false;
|
||||
var _VERSION_STRING = require('../package.json').version;
|
||||
var _DEFAULT_DELIMITER = '%';
|
||||
var _DEFAULT_LOCALS_NAME = 'locals';
|
||||
var _NAME = 'ejs';
|
||||
var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)';
|
||||
var _OPTS = ['delimiter', 'scope', 'context', 'debug', 'compileDebug',
|
||||
'client', '_with', 'rmWhitespace', 'strict', 'filename'];
|
||||
// We don't allow 'cache' option to be passed in the data obj
|
||||
// for the normal `render` call, but this is where Express puts it
|
||||
// so we make an exception for `renderFile`
|
||||
var _OPTS_EXPRESS = _OPTS.concat('cache');
|
||||
var _BOM = /^\uFEFF/;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* 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`.
|
||||
*
|
||||
* @type {String}
|
||||
@ -84,24 +97,44 @@ exports.localsName = _DEFAULT_LOCALS_NAME;
|
||||
* Get the path to the included file from the parent file path and the
|
||||
* specified path.
|
||||
*
|
||||
* @param {String} name specified path
|
||||
* @param {String} filename parent file path
|
||||
* @param {String} name specified path
|
||||
* @param {String} filename parent file path
|
||||
* @param {Boolean} isDir parent file path whether is directory
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
exports.resolveInclude = function(name, filename) {
|
||||
var path = require('path')
|
||||
, dirname = path.dirname
|
||||
, extname = path.extname
|
||||
, resolve = path.resolve
|
||||
, includePath = resolve(dirname(filename), name)
|
||||
, ext = extname(name);
|
||||
exports.resolveInclude = function(name, filename, isDir) {
|
||||
var dirname = path.dirname;
|
||||
var extname = path.extname;
|
||||
var resolve = path.resolve;
|
||||
var includePath = resolve(isDir ? filename : dirname(filename), name);
|
||||
var ext = extname(name);
|
||||
if (!ext) {
|
||||
includePath += '.ejs';
|
||||
}
|
||||
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;
|
||||
if (path.charAt(0) == '/') {
|
||||
includePath = exports.resolveInclude(path.replace(/^\/*/,''), options.root || '/', true);
|
||||
}
|
||||
else {
|
||||
if (!options.filename) {
|
||||
throw new Error('`include` use relative path requires the \'filename\' option.');
|
||||
}
|
||||
includePath = exports.resolveInclude(path, options.filename);
|
||||
}
|
||||
return includePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -121,35 +154,70 @@ exports.resolveInclude = function(name, filename) {
|
||||
*/
|
||||
|
||||
function handleCache(options, template) {
|
||||
var fn
|
||||
, path = options.filename
|
||||
, hasTemplate = arguments.length > 1;
|
||||
var func;
|
||||
var filename = options.filename;
|
||||
var hasTemplate = arguments.length > 1;
|
||||
|
||||
if (options.cache) {
|
||||
if (!path) {
|
||||
if (!filename) {
|
||||
throw new Error('cache option requires a filename');
|
||||
}
|
||||
fn = exports.cache.get(path);
|
||||
if (fn) {
|
||||
return fn;
|
||||
func = exports.cache.get(filename);
|
||||
if (func) {
|
||||
return func;
|
||||
}
|
||||
if (!hasTemplate) {
|
||||
template = fs.readFileSync(path).toString().replace(_BOM, '');
|
||||
template = fileLoader(filename).toString().replace(_BOM, '');
|
||||
}
|
||||
}
|
||||
else if (!hasTemplate) {
|
||||
// istanbul ignore if: should not happen at all
|
||||
if (!path) {
|
||||
if (!filename) {
|
||||
throw new Error('Internal EJS error: no file name or template '
|
||||
+ '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) {
|
||||
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;
|
||||
try {
|
||||
result = handleCache(options)(data);
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
return 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 +235,7 @@ function handleCache(options, template) {
|
||||
|
||||
function includeFile(path, options) {
|
||||
var opts = utils.shallowCopy({}, options);
|
||||
if (!opts.filename) {
|
||||
throw new Error('`include` requires the \'filename\' option.');
|
||||
}
|
||||
opts.filename = exports.resolveInclude(path, opts.filename);
|
||||
opts.filename = getIncludePath(path, opts);
|
||||
return handleCache(opts);
|
||||
}
|
||||
|
||||
@ -180,24 +245,24 @@ function includeFile(path, options) {
|
||||
* @memberof module:ejs-internal
|
||||
* @param {String} path path for the specified file
|
||||
* @param {Options} options compilation options
|
||||
* @return {String}
|
||||
* @return {Object}
|
||||
* @static
|
||||
*/
|
||||
|
||||
function includeSource(path, options) {
|
||||
var opts = utils.shallowCopy({}, options)
|
||||
, includePath
|
||||
, template;
|
||||
if (!opts.filename) {
|
||||
throw new Error('`include` requires the \'filename\' option.');
|
||||
}
|
||||
includePath = exports.resolveInclude(path, opts.filename);
|
||||
template = fs.readFileSync(includePath).toString().replace(_BOM, '');
|
||||
|
||||
var opts = utils.shallowCopy({}, options);
|
||||
var includePath;
|
||||
var template;
|
||||
includePath = getIncludePath(path, opts);
|
||||
template = fileLoader(includePath).toString().replace(_BOM, '');
|
||||
opts.filename = includePath;
|
||||
var templ = new Template(template, opts);
|
||||
templ.generateSource();
|
||||
return templ.source;
|
||||
return {
|
||||
source: templ.source,
|
||||
filename: includePath,
|
||||
template: template
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,11 +278,11 @@ function includeSource(path, options) {
|
||||
* @static
|
||||
*/
|
||||
|
||||
function rethrow(err, str, filename, lineno){
|
||||
var lines = str.split('\n')
|
||||
, start = Math.max(lineno - 3, 0)
|
||||
, end = Math.min(lines.length, lineno + 3);
|
||||
|
||||
function rethrow(err, str, flnm, lineno, esc){
|
||||
var lines = str.split('\n');
|
||||
var start = Math.max(lineno - 3, 0);
|
||||
var end = Math.min(lines.length, lineno + 3);
|
||||
var filename = esc(flnm); // eslint-disable-line
|
||||
// Error context
|
||||
var context = lines.slice(start, end).map(function (line, i){
|
||||
var curr = i + start + 1;
|
||||
@ -237,24 +302,8 @@ function rethrow(err, str, filename, lineno){
|
||||
throw err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy properties in data object that are recognized as options to an
|
||||
* 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];
|
||||
}
|
||||
});
|
||||
function stripSemi(str){
|
||||
return str.replace(/;(\s*$)/, '$1');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,15 +351,14 @@ exports.compile = function compile(template, opts) {
|
||||
* @public
|
||||
*/
|
||||
|
||||
exports.render = function (template, data, opts) {
|
||||
data = data || {};
|
||||
opts = opts || {};
|
||||
var fn;
|
||||
exports.render = function (template, d, o) {
|
||||
var data = d || {};
|
||||
var opts = o || {};
|
||||
|
||||
// No options object -- if there are optiony names
|
||||
// in the data, copy them to options
|
||||
if (arguments.length == 2) {
|
||||
cpOptsInData(data, opts);
|
||||
utils.shallowCopyFromList(opts, data, _OPTS);
|
||||
}
|
||||
|
||||
return handleCache(opts, template)(data);
|
||||
@ -330,37 +378,38 @@ exports.render = function (template, data, opts) {
|
||||
*/
|
||||
|
||||
exports.renderFile = function () {
|
||||
var args = Array.prototype.slice.call(arguments)
|
||||
, path = args.shift()
|
||||
, cb = args.pop()
|
||||
, data = args.shift() || {}
|
||||
, opts = args.pop() || {}
|
||||
, result;
|
||||
var filename = arguments[0];
|
||||
var cb = arguments[arguments.length - 1];
|
||||
var opts = {filename: filename};
|
||||
var data;
|
||||
|
||||
// Don't pollute passed in opts obj with new vals
|
||||
opts = utils.shallowCopy({}, opts);
|
||||
if (arguments.length > 2) {
|
||||
data = arguments[1];
|
||||
|
||||
// No options object -- if there are optiony names
|
||||
// in the data, copy them to options
|
||||
if (arguments.length == 3) {
|
||||
// Express 4
|
||||
if (data.settings && data.settings['view options']) {
|
||||
cpOptsInData(data.settings['view options'], opts);
|
||||
// No options object -- if there are optiony names
|
||||
// in the data, copy them to options
|
||||
if (arguments.length === 3) {
|
||||
// Express 4
|
||||
if (data.settings && data.settings['view options']) {
|
||||
utils.shallowCopyFromList(opts, data.settings['view options'], _OPTS_EXPRESS);
|
||||
}
|
||||
// Express 3 and lower
|
||||
else {
|
||||
utils.shallowCopyFromList(opts, data, _OPTS_EXPRESS);
|
||||
}
|
||||
}
|
||||
// Express 3 and lower
|
||||
else {
|
||||
cpOptsInData(data, opts);
|
||||
// Use shallowCopy so we don't pollute passed in opts obj with new vals
|
||||
utils.shallowCopy(opts, arguments[2]);
|
||||
}
|
||||
}
|
||||
opts.filename = path;
|
||||
|
||||
try {
|
||||
result = handleCache(opts)(data);
|
||||
opts.filename = filename;
|
||||
}
|
||||
catch(err) {
|
||||
return cb(err);
|
||||
else {
|
||||
data = {};
|
||||
}
|
||||
return cb(null, result);
|
||||
|
||||
return tryHandleCache(opts, data, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -391,6 +440,7 @@ function Template(text, opts) {
|
||||
options.context = opts.context;
|
||||
options.cache = opts.cache || false;
|
||||
options.rmWhitespace = opts.rmWhitespace;
|
||||
options.root = opts.root;
|
||||
options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME;
|
||||
|
||||
if (options.strict) {
|
||||
@ -406,39 +456,28 @@ function Template(text, opts) {
|
||||
}
|
||||
|
||||
Template.modes = {
|
||||
EVAL: 'eval'
|
||||
, ESCAPED: 'escaped'
|
||||
, RAW: 'raw'
|
||||
, COMMENT: 'comment'
|
||||
, LITERAL: 'literal'
|
||||
EVAL: 'eval',
|
||||
ESCAPED: 'escaped',
|
||||
RAW: 'raw',
|
||||
COMMENT: 'comment',
|
||||
LITERAL: 'literal'
|
||||
};
|
||||
|
||||
Template.prototype = {
|
||||
createRegex: function () {
|
||||
var str = _REGEX_STRING
|
||||
, delim = utils.escapeRegExpChars(this.opts.delimiter);
|
||||
var str = _REGEX_STRING;
|
||||
var delim = utils.escapeRegExpChars(this.opts.delimiter);
|
||||
str = str.replace(/%/g, delim);
|
||||
return new RegExp(str);
|
||||
}
|
||||
},
|
||||
|
||||
, compile: function () {
|
||||
var src
|
||||
, fn
|
||||
, opts = this.opts
|
||||
, prepended = ''
|
||||
, appended = ''
|
||||
, escape = opts.escapeFunction;
|
||||
|
||||
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, '_%>');
|
||||
compile: function () {
|
||||
var src;
|
||||
var fn;
|
||||
var opts = this.opts;
|
||||
var prepended = '';
|
||||
var appended = '';
|
||||
var escapeFn = opts.escapeFunction;
|
||||
|
||||
if (!this.source) {
|
||||
this.generateSource();
|
||||
@ -459,7 +498,7 @@ Template.prototype = {
|
||||
+ 'try {' + '\n'
|
||||
+ this.source
|
||||
+ '} catch (e) {' + '\n'
|
||||
+ ' rethrow(e, __lines, __filename, __line);' + '\n'
|
||||
+ ' rethrow(e, __lines, __filename, __line, escapeFn);' + '\n'
|
||||
+ '}' + '\n';
|
||||
}
|
||||
else {
|
||||
@ -471,7 +510,7 @@ Template.prototype = {
|
||||
}
|
||||
|
||||
if (opts.client) {
|
||||
src = 'escape = escape || ' + escape.toString() + ';' + '\n' + src;
|
||||
src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src;
|
||||
if (opts.compileDebug) {
|
||||
src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src;
|
||||
}
|
||||
@ -482,7 +521,7 @@ Template.prototype = {
|
||||
}
|
||||
|
||||
try {
|
||||
fn = new Function(opts.localsName + ', escape, include, rethrow', src);
|
||||
fn = new Function(opts.localsName + ', escapeFn, include, rethrow', src);
|
||||
}
|
||||
catch(e) {
|
||||
// istanbul ignore else
|
||||
@ -490,7 +529,9 @@ Template.prototype = {
|
||||
if (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';
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
@ -511,28 +552,38 @@ Template.prototype = {
|
||||
}
|
||||
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;
|
||||
return returnedFn;
|
||||
}
|
||||
},
|
||||
|
||||
, generateSource: function () {
|
||||
var self = this
|
||||
, matches = this.parseTemplateText()
|
||||
, d = this.opts.delimiter;
|
||||
generateSource: function () {
|
||||
var opts = this.opts;
|
||||
|
||||
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 (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) {
|
||||
var opening
|
||||
, closing
|
||||
, include
|
||||
, includeOpts
|
||||
, includeSrc;
|
||||
var opening;
|
||||
var closing;
|
||||
var include;
|
||||
var includeOpts;
|
||||
var includeObj;
|
||||
var includeSrc;
|
||||
// If this is an opening tag, check for closing tags
|
||||
// FIXME: May end up with some false positives here
|
||||
// Better to store modes as k/v with '<' + delimiter as key
|
||||
@ -550,9 +601,23 @@ Template.prototype = {
|
||||
// Must be in EVAL or RAW mode
|
||||
if (opening && (opening == '<' + d || opening == '<' + d + '-' || opening == '<' + d + '_')) {
|
||||
includeOpts = utils.shallowCopy({}, self.opts);
|
||||
includeSrc = includeSource(include[1], includeOpts);
|
||||
includeSrc = ' ; (function(){' + '\n' + includeSrc +
|
||||
' ; })()' + '\n';
|
||||
includeObj = includeSource(include[1], includeOpts);
|
||||
if (self.opts.compileDebug) {
|
||||
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);' + '\n'
|
||||
+ ' }' + '\n'
|
||||
+ ' ; }).call(this)' + '\n';
|
||||
}else{
|
||||
includeSrc = ' ; (function(){' + '\n' + includeObj.source +
|
||||
' ; }).call(this)' + '\n';
|
||||
}
|
||||
self.source += includeSrc;
|
||||
self.dependencies.push(exports.resolveInclude(include[1],
|
||||
includeOpts.filename));
|
||||
@ -563,19 +628,17 @@ Template.prototype = {
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
, parseTemplateText: function () {
|
||||
var str = this.templateText
|
||||
, pat = this.regex
|
||||
, result = pat.exec(str)
|
||||
, arr = []
|
||||
, firstPos
|
||||
, lastPos;
|
||||
parseTemplateText: function () {
|
||||
var str = this.templateText;
|
||||
var pat = this.regex;
|
||||
var result = pat.exec(str);
|
||||
var arr = [];
|
||||
var firstPos;
|
||||
|
||||
while (result) {
|
||||
firstPos = result.index;
|
||||
lastPos = pat.lastIndex;
|
||||
|
||||
if (firstPos !== 0) {
|
||||
arr.push(str.substring(0, firstPos));
|
||||
@ -592,12 +655,12 @@ Template.prototype = {
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
},
|
||||
|
||||
, scanLine: function (line) {
|
||||
var self = this
|
||||
, d = this.opts.delimiter
|
||||
, newLineCount = 0;
|
||||
scanLine: function (line) {
|
||||
var self = this;
|
||||
var d = this.opts.delimiter;
|
||||
var newLineCount = 0;
|
||||
|
||||
function _addOutput() {
|
||||
if (self.truncate) {
|
||||
@ -606,13 +669,12 @@ Template.prototype = {
|
||||
// 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)/, '')
|
||||
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.
|
||||
// rmWhitespace has already removed trailing spaces, just need
|
||||
// to remove linebreaks
|
||||
line = line.replace(/^\n/, '');
|
||||
}
|
||||
if (!line) {
|
||||
@ -635,73 +697,75 @@ Template.prototype = {
|
||||
newLineCount = (line.split('\n').length - 1);
|
||||
|
||||
switch (line) {
|
||||
case '<' + d:
|
||||
case '<' + d + '_':
|
||||
this.mode = Template.modes.EVAL;
|
||||
break;
|
||||
case '<' + d + '=':
|
||||
this.mode = Template.modes.ESCAPED;
|
||||
break;
|
||||
case '<' + d + '-':
|
||||
this.mode = Template.modes.RAW;
|
||||
break;
|
||||
case '<' + d + '#':
|
||||
this.mode = Template.modes.COMMENT;
|
||||
break;
|
||||
case '<' + d + d:
|
||||
this.mode = Template.modes.LITERAL;
|
||||
this.source += ' ; __append("' + line.replace('<' + d + d, '<' + d) + '")' + '\n';
|
||||
break;
|
||||
case d + '>':
|
||||
case '-' + d + '>':
|
||||
case '_' + d + '>':
|
||||
if (this.mode == Template.modes.LITERAL) {
|
||||
_addOutput();
|
||||
}
|
||||
case '<' + d:
|
||||
case '<' + d + '_':
|
||||
this.mode = Template.modes.EVAL;
|
||||
break;
|
||||
case '<' + d + '=':
|
||||
this.mode = Template.modes.ESCAPED;
|
||||
break;
|
||||
case '<' + d + '-':
|
||||
this.mode = Template.modes.RAW;
|
||||
break;
|
||||
case '<' + d + '#':
|
||||
this.mode = Template.modes.COMMENT;
|
||||
break;
|
||||
case '<' + d + d:
|
||||
this.mode = Template.modes.LITERAL;
|
||||
this.source += ' ; __append("' + line.replace('<' + d + d, '<' + d) + '")' + '\n';
|
||||
break;
|
||||
case d + d + '>':
|
||||
this.mode = Template.modes.LITERAL;
|
||||
this.source += ' ; __append("' + line.replace(d + d + '>', d + '>') + '")' + '\n';
|
||||
break;
|
||||
case d + '>':
|
||||
case '-' + d + '>':
|
||||
case '_' + d + '>':
|
||||
if (this.mode == Template.modes.LITERAL) {
|
||||
_addOutput();
|
||||
}
|
||||
|
||||
this.mode = null;
|
||||
this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0;
|
||||
break;
|
||||
default:
|
||||
this.mode = null;
|
||||
this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0;
|
||||
break;
|
||||
default:
|
||||
// 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.
|
||||
switch (this.mode) {
|
||||
case Template.modes.EVAL:
|
||||
case Template.modes.ESCAPED:
|
||||
case Template.modes.RAW:
|
||||
if (line.lastIndexOf('//') > line.lastIndexOf('\n')) {
|
||||
line += '\n';
|
||||
}
|
||||
switch (this.mode) {
|
||||
case Template.modes.EVAL:
|
||||
case Template.modes.ESCAPED:
|
||||
case Template.modes.RAW:
|
||||
if (line.lastIndexOf('//') > line.lastIndexOf('\n')) {
|
||||
line += '\n';
|
||||
}
|
||||
switch (this.mode) {
|
||||
}
|
||||
switch (this.mode) {
|
||||
// Just executing code
|
||||
case Template.modes.EVAL:
|
||||
this.source += ' ; ' + line + '\n';
|
||||
break;
|
||||
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;
|
||||
case Template.modes.ESCAPED:
|
||||
this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\n';
|
||||
break;
|
||||
// Exec and output
|
||||
case Template.modes.RAW:
|
||||
this.source += ' ; __append(' +
|
||||
line.replace(_TRAILING_SEMCOL, '').trim() + ')' + '\n';
|
||||
break;
|
||||
case Template.modes.COMMENT:
|
||||
case Template.modes.RAW:
|
||||
this.source += ' ; __append(' + stripSemi(line) + ')' + '\n';
|
||||
break;
|
||||
case Template.modes.COMMENT:
|
||||
// Do nothing
|
||||
break;
|
||||
break;
|
||||
// Literal <%% mode, append as raw output
|
||||
case Template.modes.LITERAL:
|
||||
_addOutput();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// In string mode, just add the output
|
||||
else {
|
||||
case Template.modes.LITERAL:
|
||||
_addOutput();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// In string mode, just add the output
|
||||
else {
|
||||
_addOutput();
|
||||
}
|
||||
}
|
||||
|
||||
if (self.opts.compileDebug && newLineCount) {
|
||||
@ -711,9 +775,17 @@ Template.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Export the internal function for escaping XML so people
|
||||
* can use for manual escaping if needed
|
||||
/**
|
||||
* Escape characters reserved in XML.
|
||||
*
|
||||
* 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;
|
||||
|
||||
@ -731,14 +803,14 @@ exports.__express = exports.renderFile;
|
||||
// Add require support
|
||||
/* istanbul ignore else */
|
||||
if (require.extensions) {
|
||||
require.extensions['.ejs'] = function (module, filename) {
|
||||
filename = filename || /* istanbul ignore next */ module.filename;
|
||||
require.extensions['.ejs'] = function (module, flnm) {
|
||||
var filename = flnm || /* istanbul ignore next */ module.filename;
|
||||
var options = {
|
||||
filename: filename
|
||||
, client: true
|
||||
}
|
||||
, template = fs.readFileSync(filename).toString()
|
||||
, fn = exports.compile(template, options);
|
||||
filename: filename,
|
||||
client: true
|
||||
};
|
||||
var template = fileLoader(filename).toString();
|
||||
var fn = exports.compile(template, options);
|
||||
module._compile('module.exports = ' + fn.toString() + ';', filename);
|
||||
};
|
||||
}
|
||||
@ -753,6 +825,16 @@ if (require.extensions) {
|
||||
|
||||
exports.VERSION = _VERSION_STRING;
|
||||
|
||||
/**
|
||||
* Name for detection of EJS.
|
||||
*
|
||||
* @readonly
|
||||
* @type {String}
|
||||
* @public
|
||||
*/
|
||||
|
||||
exports.name = _NAME;
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (typeof window != 'undefined') {
|
||||
window.ejs = exports;
|
||||
|
45
node_modules/ejs/lib/utils.js
generated
vendored
45
node_modules/ejs/lib/utils.js
generated
vendored
@ -45,17 +45,17 @@ exports.escapeRegExpChars = function (string) {
|
||||
};
|
||||
|
||||
var _ENCODE_HTML_RULES = {
|
||||
'&': '&'
|
||||
, '<': '<'
|
||||
, '>': '>'
|
||||
, '"': '"'
|
||||
, "'": '''
|
||||
}
|
||||
, _MATCH_HTML = /[&<>\'"]/g;
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": '''
|
||||
};
|
||||
var _MATCH_HTML = /[&<>\'"]/g;
|
||||
|
||||
function encode_char(c) {
|
||||
return _ENCODE_HTML_RULES[c] || c;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stringified version of constants used by {@link module:utils.escapeXML}.
|
||||
@ -98,11 +98,13 @@ exports.escapeXML = function (markup) {
|
||||
.replace(_MATCH_HTML, encode_char);
|
||||
};
|
||||
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} from Source object
|
||||
@ -118,6 +120,28 @@ exports.shallowCopy = function (to, from) {
|
||||
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
|
||||
* sort.
|
||||
@ -138,4 +162,3 @@ exports.cache = {
|
||||
this._data = {};
|
||||
}
|
||||
};
|
||||
|
||||
|
78
node_modules/ejs/package.json
generated
vendored
78
node_modules/ejs/package.json
generated
vendored
@ -1,42 +1,49 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"ejs@*",
|
||||
"/Users/martin/newdev/Rinser"
|
||||
{
|
||||
"name": "ejs",
|
||||
"raw": "ejs@2.5.6",
|
||||
"rawSpec": "2.5.6",
|
||||
"scope": null,
|
||||
"spec": "2.5.6",
|
||||
"type": "version"
|
||||
},
|
||||
"/home/martind2000/dev/Rinser"
|
||||
]
|
||||
],
|
||||
"_from": "ejs@*",
|
||||
"_id": "ejs@2.4.2",
|
||||
"_from": "ejs@2.5.6",
|
||||
"_id": "ejs@2.5.6",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/ejs",
|
||||
"_nodeVersion": "4.4.4",
|
||||
"_nodeVersion": "6.9.1",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-12-west.internal.npmjs.com",
|
||||
"tmp": "tmp/ejs-2.4.2.tgz_1464117640663_0.8193834638223052"
|
||||
"tmp": "tmp/ejs-2.5.6.tgz_1487277787176_0.4875628533773124"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "mde@fleegix.org",
|
||||
"name": "mde"
|
||||
},
|
||||
"_npmVersion": "2.15.1",
|
||||
"_npmVersion": "3.10.8",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "ejs",
|
||||
"raw": "ejs@*",
|
||||
"rawSpec": "*",
|
||||
"raw": "ejs@2.5.6",
|
||||
"rawSpec": "2.5.6",
|
||||
"scope": null,
|
||||
"spec": "*",
|
||||
"type": "range"
|
||||
"spec": "2.5.6",
|
||||
"type": "version"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz",
|
||||
"_shasum": "7057eb4812958fb731841cd9ca353343efe597b1",
|
||||
"_resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.6.tgz",
|
||||
"_shasum": "479636bfa3fe3b1debd52087f0acb204b4f19c88",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "ejs@*",
|
||||
"_where": "/Users/martin/newdev/Rinser",
|
||||
"_spec": "ejs@2.5.6",
|
||||
"_where": "/home/martind2000/dev/Rinser",
|
||||
"author": {
|
||||
"email": "mde@fleegix.org",
|
||||
"name": "Matthew Eernisse",
|
||||
@ -47,47 +54,44 @@
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Timothy Gu",
|
||||
"email": "timothygu99@gmail.com",
|
||||
"name": "Timothy Gu",
|
||||
"url": "https://timothygu.github.io"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"description": "Embedded JavaScript templates",
|
||||
"devDependencies": {
|
||||
"browserify": "^8.0.3",
|
||||
"istanbul": "~0.3.5",
|
||||
"browserify": "^13.0.1",
|
||||
"eslint": "^3.0.0",
|
||||
"git-directory-deploy": "^1.5.1",
|
||||
"istanbul": "~0.4.3",
|
||||
"jake": "^8.0.0",
|
||||
"jsdoc": "^3.3.0-beta1",
|
||||
"lru-cache": "^2.5.0",
|
||||
"mocha": "^2.1.0",
|
||||
"rimraf": "^2.2.8",
|
||||
"uglify-js": "^2.4.16"
|
||||
"jsdoc": "^3.4.0",
|
||||
"lru-cache": "^4.0.1",
|
||||
"mocha": "^3.0.2",
|
||||
"uglify-js": "^2.6.2"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "7057eb4812958fb731841cd9ca353343efe597b1",
|
||||
"tarball": "https://registry.npmjs.org/ejs/-/ejs-2.4.2.tgz"
|
||||
"shasum": "479636bfa3fe3b1debd52087f0acb204b4f19c88",
|
||||
"tarball": "https://registry.npmjs.org/ejs/-/ejs-2.5.6.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"homepage": "https://github.com/mde/ejs",
|
||||
"keywords": [
|
||||
"ejs",
|
||||
"template",
|
||||
"engine",
|
||||
"template"
|
||||
"ejs"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"main": "./lib/ejs.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "tjholowaychuk",
|
||||
"email": "tj@vision-media.ca"
|
||||
},
|
||||
{
|
||||
"name": "mde",
|
||||
"email": "mde@fleegix.org"
|
||||
"email": "mde@fleegix.org",
|
||||
"name": "mde"
|
||||
}
|
||||
],
|
||||
"name": "ejs",
|
||||
@ -99,10 +103,10 @@
|
||||
},
|
||||
"scripts": {
|
||||
"coverage": "istanbul cover node_modules/mocha/bin/_mocha",
|
||||
"devdoc": "rimraf out && jsdoc -p -c jsdoc.json lib/* docs/jsdoc/*",
|
||||
"doc": "rimraf out && jsdoc -c jsdoc.json lib/* docs/jsdoc/*",
|
||||
"sample": "npm install express && node sample/index.js",
|
||||
"devdoc": "jake doc[dev]",
|
||||
"doc": "jake doc",
|
||||
"lint": "eslint \"**/*.js\" Jakefile",
|
||||
"test": "mocha"
|
||||
},
|
||||
"version": "2.4.2"
|
||||
"version": "2.5.6"
|
||||
}
|
||||
|
345
node_modules/ejs/test/ejs.js
generated
vendored
345
node_modules/ejs/test/ejs.js
generated
vendored
@ -1,15 +1,16 @@
|
||||
/* jshint mocha: true */
|
||||
/* eslint-env node, mocha */
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var ejs = require('..')
|
||||
, fs = require('fs')
|
||||
, read = fs.readFileSync
|
||||
, assert = require('assert')
|
||||
, path = require('path')
|
||||
, LRU = require('lru-cache');
|
||||
var ejs = require('..');
|
||||
var fs = require('fs');
|
||||
var read = fs.readFileSync;
|
||||
var assert = require('assert');
|
||||
var path = require('path');
|
||||
var LRU = require('lru-cache');
|
||||
|
||||
try {
|
||||
fs.mkdirSync(__dirname + '/tmp');
|
||||
@ -103,10 +104,28 @@ suite('ejs.compile(str, options)', function () {
|
||||
delete ejs.delimiter;
|
||||
});
|
||||
|
||||
test('support custom escape function', function () {
|
||||
var customEscape;
|
||||
var fn;
|
||||
customEscape = function customEscape(str) {
|
||||
return !str ? '' : str.toUpperCase();
|
||||
};
|
||||
fn = ejs.compile('HELLO <%= name %>', {escape: customEscape});
|
||||
assert.equal(fn({name: 'world'}), 'HELLO WORLD');
|
||||
});
|
||||
|
||||
test('strict mode works', function () {
|
||||
assert.equal(ejs.render(fixture('strict.ejs'), {}, {strict: true}), 'true');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('client mode', function () {
|
||||
|
||||
test('have a working client option', function () {
|
||||
var fn
|
||||
, str
|
||||
, preFn;
|
||||
var fn;
|
||||
var str;
|
||||
var preFn;
|
||||
fn = ejs.compile('<p><%= foo %></p>', {client: true});
|
||||
str = fn.toString();
|
||||
if (!process.env.running_under_istanbul) {
|
||||
@ -116,9 +135,9 @@ suite('ejs.compile(str, options)', function () {
|
||||
});
|
||||
|
||||
test('support client mode without locals', function () {
|
||||
var fn
|
||||
, str
|
||||
, preFn;
|
||||
var fn;
|
||||
var str;
|
||||
var preFn;
|
||||
fn = ejs.compile('<p><%= "foo" %></p>', {client: true});
|
||||
str = fn.toString();
|
||||
if (!process.env.running_under_istanbul) {
|
||||
@ -129,27 +148,17 @@ suite('ejs.compile(str, options)', function () {
|
||||
|
||||
test('not include rethrow() in client mode if compileDebug is false', function () {
|
||||
var fn = ejs.compile('<p><%= "foo" %></p>', {
|
||||
client: true
|
||||
, compileDebug: false
|
||||
});
|
||||
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;
|
||||
var customEscape;
|
||||
var fn;
|
||||
var str;
|
||||
customEscape = function customEscape(str) {
|
||||
return !str ? '' : str.toUpperCase();
|
||||
};
|
||||
@ -157,10 +166,31 @@ suite('ejs.compile(str, options)', function () {
|
||||
str = fn.toString();
|
||||
if (!process.env.running_under_istanbul) {
|
||||
eval('var preFn = ' + str);
|
||||
assert.equal(preFn({name: 'world'}), 'HELLO WORLD');
|
||||
assert.equal(preFn({name: 'world'}), 'HELLO WORLD'); // eslint-disable-line no-undef
|
||||
}
|
||||
});
|
||||
|
||||
test('escape filename in errors in client mode', function () {
|
||||
assert.throws(function () {
|
||||
var fn = ejs.compile('<% throw new Error("whoops"); %>', {client: true, filename: '<script>'});
|
||||
fn();
|
||||
}, /Error: <script>/);
|
||||
});
|
||||
});
|
||||
|
||||
/* Old API -- remove when this shim goes away */
|
||||
suite('ejs.render(str, dataAndOpts)', function () {
|
||||
test('render the template with data/opts passed together', function () {
|
||||
assert.equal(ejs.render('<p><?= foo ?></p>', {foo: 'yay', delimiter: '?'}),
|
||||
'<p>yay</p>');
|
||||
});
|
||||
|
||||
test('disallow unsafe opts passed along in data', function () {
|
||||
assert.equal(ejs.render('<p><?= locals.foo ?></p>',
|
||||
// localsName should not get reset because it's blacklisted
|
||||
{_with: false, foo: 'yay', delimiter: '?', localsName: '_'}),
|
||||
'<p>yay</p>');
|
||||
});
|
||||
});
|
||||
|
||||
suite('ejs.render(str, data, opts)', function () {
|
||||
@ -224,10 +254,10 @@ suite('ejs.render(str, data, opts)', function () {
|
||||
});
|
||||
|
||||
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>';
|
||||
var file = __dirname + '/tmp/render.ejs';
|
||||
var options = {cache: true, filename: file};
|
||||
var out = ejs.render('<p>Old</p>', {}, options);
|
||||
var expected = '<p>Old</p>';
|
||||
assert.equal(out, expected);
|
||||
// Assert no change, still in cache
|
||||
out = ejs.render('<p>New</p>', {}, options);
|
||||
@ -235,11 +265,11 @@ suite('ejs.render(str, data, opts)', function () {
|
||||
});
|
||||
|
||||
test('support LRU caching', function () {
|
||||
var oldCache = ejs.cache
|
||||
, file = __dirname + '/tmp/render.ejs'
|
||||
, options = {cache: true, filename: file}
|
||||
, out
|
||||
, expected = '<p>Old</p>';
|
||||
var oldCache = ejs.cache;
|
||||
var file = __dirname + '/tmp/render.ejs';
|
||||
var options = {cache: true, filename: file};
|
||||
var out;
|
||||
var expected = '<p>Old</p>';
|
||||
|
||||
// Switch to LRU
|
||||
ejs.cache = LRU();
|
||||
@ -255,8 +285,8 @@ suite('ejs.render(str, data, opts)', function () {
|
||||
});
|
||||
|
||||
test('opts.context', function () {
|
||||
var ctxt = {foo: 'FOO'}
|
||||
, out = ejs.render('<%= this.foo %>', {}, {context: ctxt});
|
||||
var ctxt = {foo: 'FOO'};
|
||||
var out = ejs.render('<%= this.foo %>', {}, {context: ctxt});
|
||||
assert.equal(out, ctxt.foo);
|
||||
});
|
||||
});
|
||||
@ -273,8 +303,8 @@ suite('ejs.renderFile(path, [data], [options], fn)', function () {
|
||||
});
|
||||
|
||||
test('accept locals', function(done) {
|
||||
var data = {name: 'fonebone'}
|
||||
, options = {delimiter: '$'};
|
||||
var data = {name: 'fonebone'};
|
||||
var options = {delimiter: '$'};
|
||||
ejs.renderFile('test/fixtures/user.ejs', data, options, function(err, html) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
@ -285,11 +315,10 @@ suite('ejs.renderFile(path, [data], [options], fn)', function () {
|
||||
});
|
||||
|
||||
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) {
|
||||
var data = {name: 'fonebone'};
|
||||
var options = {delimiter: '$', _with: false};
|
||||
var doneCount = 0;
|
||||
ejs.renderFile('test/fixtures/user-no-with.ejs', data, options, function(err, html) {
|
||||
if (err) {
|
||||
if (doneCount === 2) {
|
||||
return;
|
||||
@ -319,9 +348,9 @@ suite('ejs.renderFile(path, [data], [options], fn)', function () {
|
||||
});
|
||||
|
||||
test('not catch err thrown by callback', function(done) {
|
||||
var data = {name: 'fonebone'}
|
||||
, options = {delimiter: '$'}
|
||||
, counter = 0;
|
||||
var data = {name: 'fonebone'};
|
||||
var options = {delimiter: '$'};
|
||||
var counter = 0;
|
||||
|
||||
var d = require('domain').create();
|
||||
d.on('error', function (err) {
|
||||
@ -336,8 +365,7 @@ suite('ejs.renderFile(path, [data], [options], fn)', function () {
|
||||
// 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) {
|
||||
ejs.renderFile('test/fixtures/user.ejs', data, options, function(err) {
|
||||
counter++;
|
||||
if (err) {
|
||||
assert.notEqual(err.message, 'Exception in callback');
|
||||
@ -350,9 +378,9 @@ suite('ejs.renderFile(path, [data], [options], fn)', function () {
|
||||
});
|
||||
|
||||
test('support caching', function (done) {
|
||||
var expected = '<p>Old</p>'
|
||||
, file = __dirname + '/tmp/renderFile.ejs'
|
||||
, options = {cache: true};
|
||||
var expected = '<p>Old</p>';
|
||||
var file = __dirname + '/tmp/renderFile.ejs';
|
||||
var options = {cache: true};
|
||||
fs.writeFileSync(file, '<p>Old</p>');
|
||||
|
||||
ejs.renderFile(file, {}, options, function (err, out) {
|
||||
@ -375,8 +403,7 @@ suite('ejs.renderFile(path, [data], [options], fn)', function () {
|
||||
|
||||
test('opts.context', function (done) {
|
||||
var ctxt = {foo: 'FOO'};
|
||||
ejs.renderFile('test/fixtures/with-context.ejs', {},
|
||||
{context: ctxt}, function(err, html) {
|
||||
ejs.renderFile('test/fixtures/with-context.ejs', {}, {context: ctxt}, function(err, html) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
@ -389,10 +416,10 @@ suite('ejs.renderFile(path, [data], [options], fn)', function () {
|
||||
|
||||
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);
|
||||
var expected = '<p>Old</p>';
|
||||
var file = __dirname + '/tmp/clearCache.ejs';
|
||||
var options = {cache: true, filename: file};
|
||||
var out = ejs.render('<p>Old</p>', {}, options);
|
||||
assert.equal(out, expected);
|
||||
|
||||
ejs.clearCache();
|
||||
@ -403,11 +430,11 @@ suite('cache specific', function () {
|
||||
});
|
||||
|
||||
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;
|
||||
var expected = '<p>Old</p>';
|
||||
var oldCache = ejs.cache;
|
||||
var file = __dirname + '/tmp/clearCache.ejs';
|
||||
var options = {cache: true, filename: file};
|
||||
var out;
|
||||
|
||||
ejs.cache = LRU();
|
||||
|
||||
@ -422,11 +449,11 @@ suite('cache specific', function () {
|
||||
});
|
||||
|
||||
test('LRU with cache-size 1', function () {
|
||||
var oldCache = ejs.cache
|
||||
, options
|
||||
, out
|
||||
, expected
|
||||
, file;
|
||||
var oldCache = ejs.cache;
|
||||
var options;
|
||||
var out;
|
||||
var expected;
|
||||
var file;
|
||||
|
||||
ejs.cache = LRU(1);
|
||||
|
||||
@ -472,6 +499,11 @@ suite('<%', function () {
|
||||
});
|
||||
|
||||
suite('<%=', function () {
|
||||
test('should not throw an error with a // comment on the final line', function () {
|
||||
assert.equal(ejs.render('<%=\n// a comment\nname\n// another comment %>', {name: ' <script>'}),
|
||||
'&nbsp;<script>');
|
||||
});
|
||||
|
||||
test('escape &<script>', function () {
|
||||
assert.equal(ejs.render('<%= name %>', {name: ' <script>'}),
|
||||
'&nbsp;<script>');
|
||||
@ -501,6 +533,11 @@ suite('<%=', function () {
|
||||
});
|
||||
|
||||
suite('<%-', function () {
|
||||
test('should not throw an error with a // comment on the final line', function () {
|
||||
assert.equal(ejs.render('<%-\n// a comment\nname\n// another comment %>', {name: ' <script>'}),
|
||||
' <script>');
|
||||
});
|
||||
|
||||
test('not escape', function () {
|
||||
assert.equal(ejs.render('<%- name %>', {name: '<script>'}),
|
||||
'<script>');
|
||||
@ -551,13 +588,13 @@ suite('-%>', function () {
|
||||
});
|
||||
|
||||
test('works with unix style', function () {
|
||||
var content = "<ul><% -%>\n"
|
||||
+ "<% users.forEach(function(user){ -%>\n"
|
||||
+ "<li><%= user.name -%></li>\n"
|
||||
+ "<% }) -%>\n"
|
||||
+ "</ul><% -%>\n";
|
||||
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 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}),
|
||||
@ -565,13 +602,13 @@ suite('-%>', function () {
|
||||
});
|
||||
|
||||
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 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 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}),
|
||||
@ -591,6 +628,15 @@ suite('<%%', function () {
|
||||
});
|
||||
});
|
||||
|
||||
suite('%%>', function () {
|
||||
test('produce literal', function () {
|
||||
assert.equal(ejs.render('%%>'),
|
||||
'%>');
|
||||
assert.equal(ejs.render(' >', {}, {delimiter: ' '}),
|
||||
' >');
|
||||
});
|
||||
});
|
||||
|
||||
suite('<%_ and _%>', function () {
|
||||
test('slurps spaces and tabs', function () {
|
||||
assert.equal(ejs.render(fixture('space-and-tab-slurp.ejs'), {users: users}),
|
||||
@ -656,8 +702,8 @@ suite('exceptions', function () {
|
||||
|
||||
var unhook = null;
|
||||
test('log JS source when debug is set', function (done) {
|
||||
var out = ''
|
||||
, needToExit = false;
|
||||
var out = '';
|
||||
var needToExit = false;
|
||||
unhook = hook_stdio(process.stdout, function (str) {
|
||||
out += str;
|
||||
if (needToExit) {
|
||||
@ -672,6 +718,22 @@ suite('exceptions', function () {
|
||||
});
|
||||
ejs.render(fixture('hello-world.ejs'), {}, {debug: true});
|
||||
});
|
||||
|
||||
test('escape filename in errors', function () {
|
||||
assert.throws(function () {
|
||||
ejs.render('<% throw new Error("whoops"); %>', {}, {filename: '<script>'});
|
||||
}, /Error: <script>/);
|
||||
});
|
||||
|
||||
test('filename in errors uses custom escape', function () {
|
||||
assert.throws(function () {
|
||||
ejs.render('<% throw new Error("whoops"); %>', {}, {
|
||||
filename: '<script>',
|
||||
escape: function () { return 'zooby'; }
|
||||
});
|
||||
}, /Error: zooby/);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
if (!unhook) {
|
||||
return;
|
||||
@ -727,6 +789,13 @@ suite('include()', function () {
|
||||
fixture('include.html'));
|
||||
});
|
||||
|
||||
test('include ejs with set root path', function () {
|
||||
var file = 'test/fixtures/include-root.ejs';
|
||||
var viewsPath = path.join(__dirname, 'fixtures');
|
||||
assert.equal(ejs.render(fixture('include-root.ejs'), {pets: users}, {filename: file, delimiter: '@',root:viewsPath}),
|
||||
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}),
|
||||
@ -734,8 +803,8 @@ suite('include()', function () {
|
||||
});
|
||||
|
||||
test('work with a variable path', function () {
|
||||
var file = 'test/fixtures/menu_var.ejs',
|
||||
includePath = 'includes/menu-item';
|
||||
var file = 'test/fixtures/menu_var.ejs';
|
||||
var includePath = 'includes/menu-item';
|
||||
assert.equal(ejs.render(fixture('menu.ejs'), {pets: users, varPath: includePath}, {filename: file}),
|
||||
fixture('menu.html'));
|
||||
});
|
||||
@ -747,12 +816,12 @@ suite('include()', function () {
|
||||
});
|
||||
|
||||
test('pass compileDebug to include', function () {
|
||||
var file = 'test/fixtures/include.ejs'
|
||||
, fn;
|
||||
var file = 'test/fixtures/include.ejs';
|
||||
var fn;
|
||||
fn = ejs.compile(fixture('include.ejs'), {
|
||||
filename: file
|
||||
, delimiter: '@'
|
||||
, compileDebug: false
|
||||
filename: file,
|
||||
delimiter: '@',
|
||||
compileDebug: false
|
||||
});
|
||||
try {
|
||||
// Render without a required variable reference
|
||||
@ -768,9 +837,9 @@ suite('include()', function () {
|
||||
|
||||
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);
|
||||
var file = 'test/fixtures/include_cache.ejs';
|
||||
var options = {filename: file};
|
||||
var out = ejs.compile(fixture('include_cache.ejs'), options);
|
||||
assert.equal(out(), '<p>Old</p>\n');
|
||||
|
||||
fs.writeFileSync(__dirname + '/tmp/include.ejs', '<p>New</p>');
|
||||
@ -779,10 +848,10 @@ suite('include()', function () {
|
||||
|
||||
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');
|
||||
var file = 'test/fixtures/include_cache.ejs';
|
||||
var options = {cache: true, filename: file};
|
||||
var out = ejs.render(fixture('include_cache.ejs'), {}, options);
|
||||
var expected = fixture('include_cache.html');
|
||||
assert.equal(out, expected);
|
||||
out = ejs.render(fixture('include_cache.ejs'), {}, options);
|
||||
// No change, still in cache
|
||||
@ -830,8 +899,8 @@ suite('preprocessor include', function () {
|
||||
});
|
||||
|
||||
test('tracks dependency correctly', function () {
|
||||
var file = 'test/fixtures/menu_preprocessor.ejs'
|
||||
, fn = ejs.compile(fixture('menu_preprocessor.ejs'), {filename: file});
|
||||
var file = 'test/fixtures/menu_preprocessor.ejs';
|
||||
var fn = ejs.compile(fixture('menu_preprocessor.ejs'), {filename: file});
|
||||
assert(fn.dependencies.length);
|
||||
});
|
||||
|
||||
@ -842,12 +911,12 @@ suite('preprocessor include', function () {
|
||||
});
|
||||
|
||||
test('pass compileDebug to include', function () {
|
||||
var file = 'test/fixtures/include_preprocessor.ejs'
|
||||
, fn;
|
||||
var file = 'test/fixtures/include_preprocessor.ejs';
|
||||
var fn;
|
||||
fn = ejs.compile(fixture('include_preprocessor.ejs'), {
|
||||
filename: file
|
||||
, delimiter: '@'
|
||||
, compileDebug: false
|
||||
filename: file,
|
||||
delimiter: '@',
|
||||
compileDebug: false
|
||||
});
|
||||
try {
|
||||
// Render without a required variable reference
|
||||
@ -863,9 +932,9 @@ suite('preprocessor include', function () {
|
||||
|
||||
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);
|
||||
var file = 'test/fixtures/include_preprocessor_cache.ejs';
|
||||
var options = {filename: file};
|
||||
var 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>');
|
||||
@ -874,16 +943,25 @@ suite('preprocessor include', function () {
|
||||
|
||||
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');
|
||||
var file = 'test/fixtures/include_preprocessor_cache.ejs';
|
||||
var options = {cache: true, filename: file};
|
||||
var out = ejs.render(fixture('include_preprocessor_cache.ejs'), {}, options);
|
||||
var 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);
|
||||
});
|
||||
|
||||
test('whitespace slurp and rmWhitespace work', function() {
|
||||
var file = 'test/fixtures/include_preprocessor_line_slurp.ejs';
|
||||
var template = fixture('include_preprocessor_line_slurp.ejs');
|
||||
var expected = fixture('include_preprocessor_line_slurp.html');
|
||||
var options = {rmWhitespace: true, filename: file};
|
||||
assert.equal(ejs.render(template, {}, options),
|
||||
expected);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('comments', function () {
|
||||
@ -897,12 +975,31 @@ 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}),
|
||||
var file = 'test/fixtures/include_preprocessor.ejs';
|
||||
var 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('test fileloader', function () {
|
||||
|
||||
var myFileLoad = function (filePath) {
|
||||
return 'myFileLoad: ' + fs.readFileSync(filePath);
|
||||
};
|
||||
|
||||
test('test custom fileload', function (done) {
|
||||
ejs.fileLoader = myFileLoad;
|
||||
ejs.renderFile('test/fixtures/para.ejs', function(err, html) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
assert.equal(html, 'myFileLoad: <p>hey</p>\n');
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@ -914,8 +1011,8 @@ suite('examples', function () {
|
||||
}
|
||||
suite(f, function () {
|
||||
test('doesn\'t throw any errors', function () {
|
||||
var stderr = hook_stdio(process.stderr, noop)
|
||||
, stdout = hook_stdio(process.stdout, noop);
|
||||
var stderr = hook_stdio(process.stderr, noop);
|
||||
var stdout = hook_stdio(process.stdout, noop);
|
||||
try {
|
||||
require('../examples/' + f);
|
||||
}
|
||||
@ -930,3 +1027,13 @@ suite('examples', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('meta information', function () {
|
||||
test('has a version', function () {
|
||||
assert.strictEqual(ejs.VERSION, require('../package.json').version);
|
||||
});
|
||||
|
||||
test('had a name', function () {
|
||||
assert.strictEqual(ejs.name, 'ejs');
|
||||
});
|
||||
});
|
||||
|
2
node_modules/ejs/test/fixtures/no.newlines.error.ejs
generated
vendored
2
node_modules/ejs/test/fixtures/no.newlines.error.ejs
generated
vendored
@ -1,5 +1,5 @@
|
||||
AAA
|
||||
<% data = "test"; -%>
|
||||
<% var data = "test"; -%>
|
||||
BBB
|
||||
<%= qdata %>
|
||||
CCC
|
||||
|
208
node_modules/express/History.md
generated
vendored
208
node_modules/express/History.md
generated
vendored
@ -1,3 +1,211 @@
|
||||
4.15.3 / 2017-05-16
|
||||
===================
|
||||
|
||||
* Fix error when `res.set` cannot add charset to `Content-Type`
|
||||
* deps: debug@2.6.7
|
||||
- Fix `DEBUG_MAX_ARRAY_LENGTH`
|
||||
- deps: ms@2.0.0
|
||||
* deps: finalhandler@~1.0.3
|
||||
- Fix missing `</html>` in HTML document
|
||||
- deps: debug@2.6.7
|
||||
* deps: proxy-addr@~1.1.4
|
||||
- deps: ipaddr.js@1.3.0
|
||||
* deps: send@0.15.3
|
||||
- deps: debug@2.6.7
|
||||
- deps: ms@2.0.0
|
||||
* deps: serve-static@1.12.3
|
||||
- deps: send@0.15.3
|
||||
* deps: type-is@~1.6.15
|
||||
- deps: mime-types@~2.1.15
|
||||
* deps: vary@~1.1.1
|
||||
- perf: hoist regular expression
|
||||
|
||||
4.15.2 / 2017-03-06
|
||||
===================
|
||||
|
||||
* deps: qs@6.4.0
|
||||
- Fix regression parsing keys starting with `[`
|
||||
|
||||
4.15.1 / 2017-03-05
|
||||
===================
|
||||
|
||||
* deps: send@0.15.1
|
||||
- Fix issue when `Date.parse` does not return `NaN` on invalid date
|
||||
- Fix strict violation in broken environments
|
||||
* deps: serve-static@1.12.1
|
||||
- Fix issue when `Date.parse` does not return `NaN` on invalid date
|
||||
- deps: send@0.15.1
|
||||
|
||||
4.15.0 / 2017-03-01
|
||||
===================
|
||||
|
||||
* Add debug message when loading view engine
|
||||
* Add `next("router")` to exit from router
|
||||
* Fix case where `router.use` skipped requests routes did not
|
||||
* Remove usage of `res._headers` private field
|
||||
- Improves compatibility with Node.js 8 nightly
|
||||
* Skip routing when `req.url` is not set
|
||||
* Use `%o` in path debug to tell types apart
|
||||
* Use `Object.create` to setup request & response prototypes
|
||||
* Use `setprototypeof` module to replace `__proto__` setting
|
||||
* Use `statuses` instead of `http` module for status messages
|
||||
* deps: debug@2.6.1
|
||||
- Allow colors in workers
|
||||
- Deprecated `DEBUG_FD` environment variable set to `3` or higher
|
||||
- Fix error when running under React Native
|
||||
- Use same color for same namespace
|
||||
- deps: ms@0.7.2
|
||||
* deps: etag@~1.8.0
|
||||
- Use SHA1 instead of MD5 for ETag hashing
|
||||
- Works with FIPS 140-2 OpenSSL configuration
|
||||
* deps: finalhandler@~1.0.0
|
||||
- Fix exception when `err` cannot be converted to a string
|
||||
- Fully URL-encode the pathname in the 404
|
||||
- Only include the pathname in the 404 message
|
||||
- Send complete HTML document
|
||||
- Set `Content-Security-Policy: default-src 'self'` header
|
||||
- deps: debug@2.6.1
|
||||
* deps: fresh@0.5.0
|
||||
- Fix false detection of `no-cache` request directive
|
||||
- Fix incorrect result when `If-None-Match` has both `*` and ETags
|
||||
- Fix weak `ETag` matching to match spec
|
||||
- perf: delay reading header values until needed
|
||||
- perf: enable strict mode
|
||||
- perf: hoist regular expressions
|
||||
- perf: remove duplicate conditional
|
||||
- perf: remove unnecessary boolean coercions
|
||||
- perf: skip checking modified time if ETag check failed
|
||||
- perf: skip parsing `If-None-Match` when no `ETag` header
|
||||
- perf: use `Date.parse` instead of `new Date`
|
||||
* deps: qs@6.3.1
|
||||
- Fix array parsing from skipping empty values
|
||||
- Fix compacting nested arrays
|
||||
* deps: send@0.15.0
|
||||
- Fix false detection of `no-cache` request directive
|
||||
- Fix incorrect result when `If-None-Match` has both `*` and ETags
|
||||
- Fix weak `ETag` matching to match spec
|
||||
- Remove usage of `res._headers` private field
|
||||
- Support `If-Match` and `If-Unmodified-Since` headers
|
||||
- Use `res.getHeaderNames()` when available
|
||||
- Use `res.headersSent` when available
|
||||
- deps: debug@2.6.1
|
||||
- deps: etag@~1.8.0
|
||||
- deps: fresh@0.5.0
|
||||
- deps: http-errors@~1.6.1
|
||||
* deps: serve-static@1.12.0
|
||||
- Fix false detection of `no-cache` request directive
|
||||
- Fix incorrect result when `If-None-Match` has both `*` and ETags
|
||||
- Fix weak `ETag` matching to match spec
|
||||
- Remove usage of `res._headers` private field
|
||||
- Send complete HTML document in redirect response
|
||||
- Set default CSP header in redirect response
|
||||
- Support `If-Match` and `If-Unmodified-Since` headers
|
||||
- Use `res.getHeaderNames()` when available
|
||||
- Use `res.headersSent` when available
|
||||
- deps: send@0.15.0
|
||||
* perf: add fast match path for `*` route
|
||||
* perf: improve `req.ips` performance
|
||||
|
||||
4.14.1 / 2017-01-28
|
||||
===================
|
||||
|
||||
* deps: content-disposition@0.5.2
|
||||
* deps: finalhandler@0.5.1
|
||||
- Fix exception when `err.headers` is not an object
|
||||
- deps: statuses@~1.3.1
|
||||
- perf: hoist regular expressions
|
||||
- perf: remove duplicate validation path
|
||||
* deps: proxy-addr@~1.1.3
|
||||
- deps: ipaddr.js@1.2.0
|
||||
* deps: send@0.14.2
|
||||
- deps: http-errors@~1.5.1
|
||||
- deps: ms@0.7.2
|
||||
- deps: statuses@~1.3.1
|
||||
* deps: serve-static@~1.11.2
|
||||
- deps: send@0.14.2
|
||||
* deps: type-is@~1.6.14
|
||||
- deps: mime-types@~2.1.13
|
||||
|
||||
4.14.0 / 2016-06-16
|
||||
===================
|
||||
|
||||
* Add `acceptRanges` option to `res.sendFile`/`res.sendfile`
|
||||
* Add `cacheControl` option to `res.sendFile`/`res.sendfile`
|
||||
* Add `options` argument to `req.range`
|
||||
- Includes the `combine` option
|
||||
* Encode URL in `res.location`/`res.redirect` if not already encoded
|
||||
* Fix some redirect handling in `res.sendFile`/`res.sendfile`
|
||||
* Fix Windows absolute path check using forward slashes
|
||||
* Improve error with invalid arguments to `req.get()`
|
||||
* Improve performance for `res.json`/`res.jsonp` in most cases
|
||||
* Improve `Range` header handling in `res.sendFile`/`res.sendfile`
|
||||
* deps: accepts@~1.3.3
|
||||
- Fix including type extensions in parameters in `Accept` parsing
|
||||
- Fix parsing `Accept` parameters with quoted equals
|
||||
- Fix parsing `Accept` parameters with quoted semicolons
|
||||
- Many performance improvments
|
||||
- deps: mime-types@~2.1.11
|
||||
- deps: negotiator@0.6.1
|
||||
* deps: content-type@~1.0.2
|
||||
- perf: enable strict mode
|
||||
* deps: cookie@0.3.1
|
||||
- Add `sameSite` option
|
||||
- Fix cookie `Max-Age` to never be a floating point number
|
||||
- Improve error message when `encode` is not a function
|
||||
- Improve error message when `expires` is not a `Date`
|
||||
- Throw better error for invalid argument to parse
|
||||
- Throw on invalid values provided to `serialize`
|
||||
- perf: enable strict mode
|
||||
- perf: hoist regular expression
|
||||
- perf: use for loop in parse
|
||||
- perf: use string concatination for serialization
|
||||
* deps: finalhandler@0.5.0
|
||||
- Change invalid or non-numeric status code to 500
|
||||
- Overwrite status message to match set status code
|
||||
- Prefer `err.statusCode` if `err.status` is invalid
|
||||
- Set response headers from `err.headers` object
|
||||
- Use `statuses` instead of `http` module for status messages
|
||||
* deps: proxy-addr@~1.1.2
|
||||
- Fix accepting various invalid netmasks
|
||||
- Fix IPv6-mapped IPv4 validation edge cases
|
||||
- IPv4 netmasks must be contingous
|
||||
- IPv6 addresses cannot be used as a netmask
|
||||
- deps: ipaddr.js@1.1.1
|
||||
* deps: qs@6.2.0
|
||||
- Add `decoder` option in `parse` function
|
||||
* deps: range-parser@~1.2.0
|
||||
- Add `combine` option to combine overlapping ranges
|
||||
- Fix incorrectly returning -1 when there is at least one valid range
|
||||
- perf: remove internal function
|
||||
* deps: send@0.14.1
|
||||
- Add `acceptRanges` option
|
||||
- Add `cacheControl` option
|
||||
- Attempt to combine multiple ranges into single range
|
||||
- Correctly inherit from `Stream` class
|
||||
- Fix `Content-Range` header in 416 responses when using `start`/`end` options
|
||||
- Fix `Content-Range` header missing from default 416 responses
|
||||
- Fix redirect error when `path` contains raw non-URL characters
|
||||
- Fix redirect when `path` starts with multiple forward slashes
|
||||
- Ignore non-byte `Range` headers
|
||||
- deps: http-errors@~1.5.0
|
||||
- deps: range-parser@~1.2.0
|
||||
- deps: statuses@~1.3.0
|
||||
- perf: remove argument reassignment
|
||||
* deps: serve-static@~1.11.1
|
||||
- Add `acceptRanges` option
|
||||
- Add `cacheControl` option
|
||||
- Attempt to combine multiple ranges into single range
|
||||
- Fix redirect error when `req.url` contains raw non-URL characters
|
||||
- Ignore non-byte `Range` headers
|
||||
- Use status code 301 for redirects
|
||||
- deps: send@0.14.1
|
||||
* deps: type-is@~1.6.13
|
||||
- Fix type error when given invalid type to match against
|
||||
- deps: mime-types@~2.1.11
|
||||
* deps: vary@~1.1.0
|
||||
- Only accept valid field names in the `field` argument
|
||||
* perf: use strict equality when possible
|
||||
|
||||
4.13.4 / 2016-01-21
|
||||
===================
|
||||
|
||||
|
7
node_modules/express/Readme.md
generated
vendored
7
node_modules/express/Readme.md
generated
vendored
@ -37,13 +37,16 @@ $ npm install express
|
||||
|
||||
## Docs & Community
|
||||
|
||||
* [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/expressjs/expressjs.com)]
|
||||
* [#express](https://webchat.freenode.net/?channels=express) on freenode IRC
|
||||
* [Github Organization](https://github.com/expressjs) for Official Middleware & Modules
|
||||
* Visit the [Wiki](https://github.com/expressjs/express/wiki)
|
||||
* [Google Group](https://groups.google.com/group/express-js) for discussion
|
||||
* [Gitter](https://gitter.im/expressjs/express) for support and discussion
|
||||
* [Русскоязычная документация](http://jsman.ru/express/)
|
||||
|
||||
###Security Issues
|
||||
**PROTIP** Be sure to read [Migrating from 3.x to 4.x](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) as well as [New features in 4.x](https://github.com/expressjs/express/wiki/New-features-in-4.x).
|
||||
|
||||
### Security Issues
|
||||
|
||||
If you discover a security vulnerability in Express, please see [Security Policies and Procedures](Security.md).
|
||||
|
||||
|
17
node_modules/express/lib/application.js
generated
vendored
17
node_modules/express/lib/application.js
generated
vendored
@ -28,6 +28,7 @@ var deprecate = require('depd')('express');
|
||||
var flatten = require('array-flatten');
|
||||
var merge = require('utils-merge');
|
||||
var resolve = require('path').resolve;
|
||||
var setPrototypeOf = require('setprototypeof')
|
||||
var slice = Array.prototype.slice;
|
||||
|
||||
/**
|
||||
@ -94,10 +95,10 @@ app.defaultConfiguration = function defaultConfiguration() {
|
||||
}
|
||||
|
||||
// inherit protos
|
||||
this.request.__proto__ = parent.request;
|
||||
this.response.__proto__ = parent.response;
|
||||
this.engines.__proto__ = parent.engines;
|
||||
this.settings.__proto__ = parent.settings;
|
||||
setPrototypeOf(this.request, parent.request)
|
||||
setPrototypeOf(this.response, parent.response)
|
||||
setPrototypeOf(this.engines, parent.engines)
|
||||
setPrototypeOf(this.settings, parent.settings)
|
||||
});
|
||||
|
||||
// setup locals
|
||||
@ -227,8 +228,8 @@ app.use = function use(fn) {
|
||||
router.use(path, function mounted_app(req, res, next) {
|
||||
var orig = req.app;
|
||||
fn.handle(req, res, function (err) {
|
||||
req.__proto__ = orig.request;
|
||||
res.__proto__ = orig.response;
|
||||
setPrototypeOf(req, orig.request)
|
||||
setPrototypeOf(res, orig.response)
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
@ -261,9 +262,9 @@ app.route = function route(path) {
|
||||
*
|
||||
* By default will `require()` the engine based on the
|
||||
* file extension. For example if you try to render
|
||||
* a "foo.jade" file Express will invoke the following internally:
|
||||
* a "foo.ejs" file Express will invoke the following internally:
|
||||
*
|
||||
* app.engine('jade', require('jade').__express);
|
||||
* app.engine('ejs', require('ejs').__express);
|
||||
*
|
||||
* For engines that do not provide `.__express` out of the box,
|
||||
* or if you wish to "map" a different extension to the template engine
|
||||
|
12
node_modules/express/lib/express.js
generated
vendored
12
node_modules/express/lib/express.js
generated
vendored
@ -41,8 +41,16 @@ function createApplication() {
|
||||
mixin(app, EventEmitter.prototype, false);
|
||||
mixin(app, proto, false);
|
||||
|
||||
app.request = { __proto__: req, app: app };
|
||||
app.response = { __proto__: res, app: app };
|
||||
// expose the prototype that will get set on requests
|
||||
app.request = Object.create(req, {
|
||||
app: { configurable: true, enumerable: true, writable: true, value: app }
|
||||
})
|
||||
|
||||
// expose the prototype that will get set on responses
|
||||
app.response = Object.create(res, {
|
||||
app: { configurable: true, enumerable: true, writable: true, value: app }
|
||||
})
|
||||
|
||||
app.init();
|
||||
return app;
|
||||
}
|
||||
|
78
node_modules/express/lib/request.js
generated
vendored
78
node_modules/express/lib/request.js
generated
vendored
@ -25,11 +25,17 @@ var proxyaddr = require('proxy-addr');
|
||||
|
||||
/**
|
||||
* Request prototype.
|
||||
* @public
|
||||
*/
|
||||
|
||||
var req = exports = module.exports = {
|
||||
__proto__: http.IncomingMessage.prototype
|
||||
};
|
||||
var req = Object.create(http.IncomingMessage.prototype)
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = req
|
||||
|
||||
/**
|
||||
* Return request header.
|
||||
@ -57,6 +63,14 @@ var req = exports = module.exports = {
|
||||
|
||||
req.get =
|
||||
req.header = function header(name) {
|
||||
if (!name) {
|
||||
throw new TypeError('name argument is required to req.get');
|
||||
}
|
||||
|
||||
if (typeof name !== 'string') {
|
||||
throw new TypeError('name must be a string to req.get');
|
||||
}
|
||||
|
||||
var lc = name.toLowerCase();
|
||||
|
||||
switch (lc) {
|
||||
@ -171,29 +185,34 @@ req.acceptsLanguage = deprecate.function(req.acceptsLanguages,
|
||||
'req.acceptsLanguage: Use acceptsLanguages instead');
|
||||
|
||||
/**
|
||||
* Parse Range header field,
|
||||
* capping to the given `size`.
|
||||
* Parse Range header field, capping to the given `size`.
|
||||
*
|
||||
* Unspecified ranges such as "0-" require
|
||||
* knowledge of your resource length. In
|
||||
* the case of a byte range this is of course
|
||||
* the total number of bytes. If the Range
|
||||
* header field is not given `null` is returned,
|
||||
* `-1` when unsatisfiable, `-2` when syntactically invalid.
|
||||
* Unspecified ranges such as "0-" require knowledge of your resource length. In
|
||||
* the case of a byte range this is of course the total number of bytes. If the
|
||||
* Range header field is not given `undefined` is returned, `-1` when unsatisfiable,
|
||||
* and `-2` when syntactically invalid.
|
||||
*
|
||||
* NOTE: remember that ranges are inclusive, so
|
||||
* for example "Range: users=0-3" should respond
|
||||
* with 4 users when available, not 3.
|
||||
* When ranges are returned, the array has a "type" property which is the type of
|
||||
* range that is required (most commonly, "bytes"). Each array element is an object
|
||||
* with a "start" and "end" property for the portion of the range.
|
||||
*
|
||||
* @param {Number} size
|
||||
* @return {Array}
|
||||
* The "combine" option can be set to `true` and overlapping & adjacent ranges
|
||||
* will be combined into a single range.
|
||||
*
|
||||
* NOTE: remember that ranges are inclusive, so for example "Range: users=0-3"
|
||||
* should respond with 4 users when available, not 3.
|
||||
*
|
||||
* @param {number} size
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.combine=false]
|
||||
* @return {number|array}
|
||||
* @public
|
||||
*/
|
||||
|
||||
req.range = function(size){
|
||||
req.range = function range(size, options) {
|
||||
var range = this.get('Range');
|
||||
if (!range) return;
|
||||
return parseRange(size, range);
|
||||
return parseRange(size, range, options);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -303,7 +322,7 @@ defineGetter(req, 'protocol', function protocol(){
|
||||
/**
|
||||
* Short-hand for:
|
||||
*
|
||||
* req.protocol == 'https'
|
||||
* req.protocol === 'https'
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @public
|
||||
@ -343,7 +362,12 @@ defineGetter(req, 'ip', function ip(){
|
||||
defineGetter(req, 'ips', function ips() {
|
||||
var trust = this.app.get('trust proxy fn');
|
||||
var addrs = proxyaddr.all(this, trust);
|
||||
return addrs.slice(1).reverse();
|
||||
|
||||
// reverse the order (to farthest -> closest)
|
||||
// and remove socket address
|
||||
addrs.reverse().pop()
|
||||
|
||||
return addrs
|
||||
});
|
||||
|
||||
/**
|
||||
@ -434,14 +458,18 @@ defineGetter(req, 'host', deprecate.function(function host(){
|
||||
|
||||
defineGetter(req, 'fresh', function(){
|
||||
var method = this.method;
|
||||
var s = this.res.statusCode;
|
||||
var res = this.res
|
||||
var status = res.statusCode
|
||||
|
||||
// GET or HEAD for weak freshness validation only
|
||||
if ('GET' != method && 'HEAD' != method) return false;
|
||||
if ('GET' !== method && 'HEAD' !== method) return false;
|
||||
|
||||
// 2xx or 304 as per rfc2616 14.26
|
||||
if ((s >= 200 && s < 300) || 304 == s) {
|
||||
return fresh(this.headers, (this.res._headers || {}));
|
||||
if ((status >= 200 && status < 300) || 304 === status) {
|
||||
return fresh(this.headers, {
|
||||
'etag': res.get('ETag'),
|
||||
'last-modified': res.get('Last-Modified')
|
||||
})
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -486,4 +514,4 @@ function defineGetter(obj, name, getter) {
|
||||
enumerable: true,
|
||||
get: getter
|
||||
});
|
||||
};
|
||||
}
|
||||
|
63
node_modules/express/lib/response.js
generated
vendored
63
node_modules/express/lib/response.js
generated
vendored
@ -14,17 +14,18 @@
|
||||
|
||||
var contentDisposition = require('content-disposition');
|
||||
var deprecate = require('depd')('express');
|
||||
var encodeUrl = require('encodeurl');
|
||||
var escapeHtml = require('escape-html');
|
||||
var http = require('http');
|
||||
var isAbsolute = require('./utils').isAbsolute;
|
||||
var onFinished = require('on-finished');
|
||||
var path = require('path');
|
||||
var statuses = require('statuses')
|
||||
var merge = require('utils-merge');
|
||||
var sign = require('cookie-signature').sign;
|
||||
var normalizeType = require('./utils').normalizeType;
|
||||
var normalizeTypes = require('./utils').normalizeTypes;
|
||||
var setCharset = require('./utils').setCharset;
|
||||
var statusCodes = http.STATUS_CODES;
|
||||
var cookie = require('cookie');
|
||||
var send = require('send');
|
||||
var extname = path.extname;
|
||||
@ -34,11 +35,17 @@ var vary = require('vary');
|
||||
|
||||
/**
|
||||
* Response prototype.
|
||||
* @public
|
||||
*/
|
||||
|
||||
var res = module.exports = {
|
||||
__proto__: http.ServerResponse.prototype
|
||||
};
|
||||
var res = Object.create(http.ServerResponse.prototype)
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = res
|
||||
|
||||
/**
|
||||
* Module variables.
|
||||
@ -128,7 +135,7 @@ res.send = function send(body) {
|
||||
|
||||
deprecate('res.send(status): Use res.sendStatus(status) instead');
|
||||
this.statusCode = chunk;
|
||||
chunk = statusCodes[chunk];
|
||||
chunk = statuses[chunk]
|
||||
}
|
||||
|
||||
switch (typeof chunk) {
|
||||
@ -189,7 +196,7 @@ res.send = function send(body) {
|
||||
if (req.fresh) this.statusCode = 304;
|
||||
|
||||
// strip irrelevant headers
|
||||
if (204 == this.statusCode || 304 == this.statusCode) {
|
||||
if (204 === this.statusCode || 304 === this.statusCode) {
|
||||
this.removeHeader('Content-Type');
|
||||
this.removeHeader('Content-Length');
|
||||
this.removeHeader('Transfer-Encoding');
|
||||
@ -239,7 +246,7 @@ res.json = function json(obj) {
|
||||
var app = this.app;
|
||||
var replacer = app.get('json replacer');
|
||||
var spaces = app.get('json spaces');
|
||||
var body = JSON.stringify(val, replacer, spaces);
|
||||
var body = stringify(val, replacer, spaces);
|
||||
|
||||
// content-type
|
||||
if (!this.get('Content-Type')) {
|
||||
@ -281,7 +288,7 @@ res.jsonp = function jsonp(obj) {
|
||||
var app = this.app;
|
||||
var replacer = app.get('json replacer');
|
||||
var spaces = app.get('json spaces');
|
||||
var body = JSON.stringify(val, replacer, spaces);
|
||||
var body = stringify(val, replacer, spaces);
|
||||
var callback = this.req.query[app.get('jsonp callback name')];
|
||||
|
||||
// content-type
|
||||
@ -333,7 +340,7 @@ res.jsonp = function jsonp(obj) {
|
||||
*/
|
||||
|
||||
res.sendStatus = function sendStatus(statusCode) {
|
||||
var body = statusCodes[statusCode] || String(statusCode);
|
||||
var body = statuses[statusCode] || String(statusCode)
|
||||
|
||||
this.statusCode = statusCode;
|
||||
this.type('txt');
|
||||
@ -710,9 +717,14 @@ res.header = function header(field, val) {
|
||||
: String(val);
|
||||
|
||||
// add charset to content-type
|
||||
if (field.toLowerCase() === 'content-type' && !charsetRegExp.test(value)) {
|
||||
var charset = mime.charsets.lookup(value.split(';')[0]);
|
||||
if (charset) value += '; charset=' + charset.toLowerCase();
|
||||
if (field.toLowerCase() === 'content-type') {
|
||||
if (Array.isArray(value)) {
|
||||
throw new TypeError('Content-Type cannot be set to an Array');
|
||||
}
|
||||
if (!charsetRegExp.test(value)) {
|
||||
var charset = mime.charsets.lookup(value.split(';')[0]);
|
||||
if (charset) value += '; charset=' + charset.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
this.setHeader(field, value);
|
||||
@ -740,7 +752,7 @@ res.get = function(field){
|
||||
* Clear cookie `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Object} options
|
||||
* @param {Object} [options]
|
||||
* @return {ServerResponse} for chaining
|
||||
* @public
|
||||
*/
|
||||
@ -770,7 +782,7 @@ res.clearCookie = function clearCookie(name, options) {
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String|Object} value
|
||||
* @param {Options} options
|
||||
* @param {Object} [options]
|
||||
* @return {ServerResponse} for chaining
|
||||
* @public
|
||||
*/
|
||||
@ -832,8 +844,7 @@ res.location = function location(url) {
|
||||
}
|
||||
|
||||
// set location
|
||||
this.set('Location', loc);
|
||||
return this;
|
||||
return this.set('Location', encodeUrl(loc));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -871,18 +882,17 @@ res.redirect = function redirect(url) {
|
||||
}
|
||||
|
||||
// Set location header
|
||||
this.location(address);
|
||||
address = this.get('Location');
|
||||
address = this.location(address).get('Location');
|
||||
|
||||
// Support text/{plain,html} by default
|
||||
this.format({
|
||||
text: function(){
|
||||
body = statusCodes[status] + '. Redirecting to ' + encodeURI(address);
|
||||
body = statuses[status] + '. Redirecting to ' + address
|
||||
},
|
||||
|
||||
html: function(){
|
||||
var u = escapeHtml(address);
|
||||
body = '<p>' + statusCodes[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>';
|
||||
body = '<p>' + statuses[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>'
|
||||
},
|
||||
|
||||
default: function(){
|
||||
@ -1051,3 +1061,16 @@ function sendfile(res, file, options, callback) {
|
||||
// pipe
|
||||
file.pipe(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stringify JSON, like JSON.stringify, but v8 optimized.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function stringify(value, replacer, spaces) {
|
||||
// v8 checks arguments.length for optimizing simple call
|
||||
// https://bugs.chromium.org/p/v8/issues/detail?id=4730
|
||||
return replacer || spaces
|
||||
? JSON.stringify(value, replacer, spaces)
|
||||
: JSON.stringify(value);
|
||||
}
|
||||
|
55
node_modules/express/lib/router/index.js
generated
vendored
55
node_modules/express/lib/router/index.js
generated
vendored
@ -21,6 +21,7 @@ var debug = require('debug')('express:router');
|
||||
var deprecate = require('depd')('express');
|
||||
var flatten = require('array-flatten');
|
||||
var parseUrl = require('parseurl');
|
||||
var setPrototypeOf = require('setprototypeof')
|
||||
|
||||
/**
|
||||
* Module variables.
|
||||
@ -47,7 +48,7 @@ var proto = module.exports = function(options) {
|
||||
}
|
||||
|
||||
// mixin Router class functions
|
||||
router.__proto__ = proto;
|
||||
setPrototypeOf(router, proto)
|
||||
|
||||
router.params = {};
|
||||
router._params = [];
|
||||
@ -119,7 +120,7 @@ proto.param = function param(name, fn) {
|
||||
|
||||
// ensure we end up with a
|
||||
// middleware function
|
||||
if ('function' != typeof fn) {
|
||||
if ('function' !== typeof fn) {
|
||||
throw new Error('invalid param() call for ' + name + ', got ' + fn);
|
||||
}
|
||||
|
||||
@ -137,11 +138,8 @@ proto.handle = function handle(req, res, out) {
|
||||
|
||||
debug('dispatching %s %s', req.method, req.url);
|
||||
|
||||
var search = 1 + req.url.indexOf('?');
|
||||
var pathlength = search ? search - 1 : req.url.length;
|
||||
var fqdn = req.url[0] !== '/' && 1 + req.url.substr(0, pathlength).indexOf('://');
|
||||
var protohost = fqdn ? req.url.substr(0, req.url.indexOf('/', 2 + fqdn)) : '';
|
||||
var idx = 0;
|
||||
var protohost = getProtohost(req.url) || ''
|
||||
var removed = '';
|
||||
var slashAdded = false;
|
||||
var paramcalled = {};
|
||||
@ -193,6 +191,12 @@ proto.handle = function handle(req, res, out) {
|
||||
removed = '';
|
||||
}
|
||||
|
||||
// signal to exit router
|
||||
if (layerError === 'router') {
|
||||
setImmediate(done, null)
|
||||
return
|
||||
}
|
||||
|
||||
// no more matching layers
|
||||
if (idx >= stack.length) {
|
||||
setImmediate(done, layerError);
|
||||
@ -282,18 +286,19 @@ proto.handle = function handle(req, res, out) {
|
||||
}
|
||||
|
||||
function trim_prefix(layer, layerError, layerPath, path) {
|
||||
var c = path[layerPath.length];
|
||||
if (c && '/' !== c && '.' !== c) return next(layerError);
|
||||
|
||||
// Trim off the part of the url that matches the route
|
||||
// middleware (.use stuff) needs to have the path stripped
|
||||
if (layerPath.length !== 0) {
|
||||
// Validate path breaks on a path separator
|
||||
var c = path[layerPath.length]
|
||||
if (c && c !== '/' && c !== '.') return next(layerError)
|
||||
|
||||
// Trim off the part of the url that matches the route
|
||||
// middleware (.use stuff) needs to have the path stripped
|
||||
debug('trim prefix (%s) from url %s', layerPath, req.url);
|
||||
removed = layerPath;
|
||||
req.url = protohost + req.url.substr(protohost.length + removed.length);
|
||||
|
||||
// Ensure leading slash
|
||||
if (!fqdn && req.url[0] !== '/') {
|
||||
if (!protohost && req.url[0] !== '/') {
|
||||
req.url = '/' + req.url;
|
||||
slashAdded = true;
|
||||
}
|
||||
@ -351,11 +356,6 @@ proto.process_params = function process_params(layer, called, req, res, done) {
|
||||
|
||||
paramIndex = 0;
|
||||
key = keys[i++];
|
||||
|
||||
if (!key) {
|
||||
return done();
|
||||
}
|
||||
|
||||
name = key.name;
|
||||
paramVal = req.params[name];
|
||||
paramCallbacks = params[name];
|
||||
@ -459,7 +459,7 @@ proto.use = function use(fn) {
|
||||
}
|
||||
|
||||
// add the middleware
|
||||
debug('use %s %s', path, fn.name || '<anonymous>');
|
||||
debug('use %o %s', path, fn.name || '<anonymous>')
|
||||
|
||||
var layer = new Layer(path, {
|
||||
sensitive: this.caseSensitive,
|
||||
@ -531,6 +531,23 @@ function getPathname(req) {
|
||||
}
|
||||
}
|
||||
|
||||
// Get get protocol + host for a URL
|
||||
function getProtohost(url) {
|
||||
if (typeof url !== 'string' || url.length === 0 || url[0] === '/') {
|
||||
return undefined
|
||||
}
|
||||
|
||||
var searchIndex = url.indexOf('?')
|
||||
var pathLength = searchIndex !== -1
|
||||
? searchIndex
|
||||
: url.length
|
||||
var fqdnIndex = url.substr(0, pathLength).indexOf('://')
|
||||
|
||||
return fqdnIndex !== -1
|
||||
? url.substr(0, url.indexOf('/', 3 + fqdnIndex))
|
||||
: undefined
|
||||
}
|
||||
|
||||
// get type for error message
|
||||
function gettype(obj) {
|
||||
var type = typeof obj;
|
||||
@ -609,7 +626,7 @@ function restore(fn, obj) {
|
||||
vals[i] = obj[props[i]];
|
||||
}
|
||||
|
||||
return function(err){
|
||||
return function () {
|
||||
// restore vals
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
obj[props[i]] = vals[i];
|
||||
|
10
node_modules/express/lib/router/route.js
generated
vendored
10
node_modules/express/lib/router/route.js
generated
vendored
@ -44,7 +44,7 @@ function Route(path) {
|
||||
this.path = path;
|
||||
this.stack = [];
|
||||
|
||||
debug('new %s', path);
|
||||
debug('new %o', path)
|
||||
|
||||
// route handlers for various http methods
|
||||
this.methods = {};
|
||||
@ -112,10 +112,16 @@ Route.prototype.dispatch = function dispatch(req, res, done) {
|
||||
next();
|
||||
|
||||
function next(err) {
|
||||
// signal to exit route
|
||||
if (err && err === 'route') {
|
||||
return done();
|
||||
}
|
||||
|
||||
// signal to exit router
|
||||
if (err && err === 'router') {
|
||||
return done(err)
|
||||
}
|
||||
|
||||
var layer = stack[idx++];
|
||||
if (!layer) {
|
||||
return done(err);
|
||||
@ -196,7 +202,7 @@ methods.forEach(function(method){
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
debug('%s %s', method, this.path);
|
||||
debug('%s %o', method, this.path)
|
||||
|
||||
var layer = Layer('/', {}, handle);
|
||||
layer.method = method;
|
||||
|
9
node_modules/express/lib/utils.js
generated
vendored
9
node_modules/express/lib/utils.js
generated
vendored
@ -66,9 +66,9 @@ exports.wetag = function wetag(body, encoding){
|
||||
*/
|
||||
|
||||
exports.isAbsolute = function(path){
|
||||
if ('/' == path[0]) return true;
|
||||
if (':' == path[1] && '\\' == path[2]) return true;
|
||||
if ('\\\\' == path.substring(0, 2)) return true; // Microsoft Azure absolute path
|
||||
if ('/' === path[0]) return true;
|
||||
if (':' === path[1] && ('\\' === path[2] || '/' === path[2])) return true; // Windows device path
|
||||
if ('\\\\' === path.substring(0, 2)) return true; // Microsoft Azure absolute path
|
||||
};
|
||||
|
||||
/**
|
||||
@ -142,7 +142,7 @@ function acceptParams(str, index) {
|
||||
|
||||
for (var i = 1; i < parts.length; ++i) {
|
||||
var pms = parts[i].split(/ *= */);
|
||||
if ('q' == pms[0]) {
|
||||
if ('q' === pms[0]) {
|
||||
ret.quality = parseFloat(pms[1]);
|
||||
} else {
|
||||
ret.params[pms[0]] = pms[1];
|
||||
@ -283,7 +283,6 @@ exports.setCharset = function setCharset(type, charset) {
|
||||
|
||||
function parseExtendedQueryString(str) {
|
||||
return qs.parse(str, {
|
||||
allowDots: false,
|
||||
allowPrototypes: true
|
||||
});
|
||||
}
|
||||
|
4
node_modules/express/lib/view.js
generated
vendored
4
node_modules/express/lib/view.js
generated
vendored
@ -75,7 +75,9 @@ function View(name, options) {
|
||||
|
||||
if (!opts.engines[this.ext]) {
|
||||
// load engine
|
||||
opts.engines[this.ext] = require(this.ext.substr(1)).__express;
|
||||
var mod = this.ext.substr(1)
|
||||
debug('require "%s"', mod)
|
||||
opts.engines[this.ext] = require(mod).__express
|
||||
}
|
||||
|
||||
// store loaded engine
|
||||
|
180
node_modules/express/package.json
generated
vendored
180
node_modules/express/package.json
generated
vendored
@ -1,39 +1,63 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"express@^4.13.4",
|
||||
"/Users/martin/newdev/Rinser"
|
||||
{
|
||||
"name": "express",
|
||||
"raw": "express@4.15.3",
|
||||
"rawSpec": "4.15.3",
|
||||
"scope": null,
|
||||
"spec": "4.15.3",
|
||||
"type": "version"
|
||||
},
|
||||
"/home/martind2000/dev/Rinser"
|
||||
]
|
||||
],
|
||||
"_from": "express@>=4.13.4 <5.0.0",
|
||||
"_id": "express@4.13.4",
|
||||
"_from": "express@4.15.3",
|
||||
"_id": "express@4.15.3",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/express",
|
||||
"_nodeVersion": "6.10.3",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-12-west.internal.npmjs.com",
|
||||
"tmp": "tmp/express-4.15.3.tgz_1495030658380_0.1599606357049197"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "doug@somethingdoug.com",
|
||||
"name": "dougwilson"
|
||||
},
|
||||
"_npmVersion": "1.4.28",
|
||||
"_npmVersion": "4.2.0",
|
||||
"_phantomChildren": {
|
||||
"mime-types": "2.1.11"
|
||||
"depd": "1.1.0",
|
||||
"destroy": "1.0.4",
|
||||
"encodeurl": "1.0.1",
|
||||
"escape-html": "1.0.3",
|
||||
"etag": "1.8.0",
|
||||
"forwarded": "0.1.0",
|
||||
"fresh": "0.5.0",
|
||||
"media-typer": "0.3.0",
|
||||
"mime": "1.3.4",
|
||||
"on-finished": "2.3.0",
|
||||
"parseurl": "1.3.1",
|
||||
"range-parser": "1.2.0",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"_requested": {
|
||||
"name": "express",
|
||||
"raw": "express@^4.13.4",
|
||||
"rawSpec": "^4.13.4",
|
||||
"raw": "express@4.15.3",
|
||||
"rawSpec": "4.15.3",
|
||||
"scope": null,
|
||||
"spec": ">=4.13.4 <5.0.0",
|
||||
"type": "range"
|
||||
"spec": "4.15.3",
|
||||
"type": "version"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "http://registry.npmjs.org/express/-/express-4.13.4.tgz",
|
||||
"_shasum": "3c0b76f3c77590c8345739061ec0bd3ba067ec24",
|
||||
"_resolved": "https://registry.npmjs.org/express/-/express-4.15.3.tgz",
|
||||
"_shasum": "bab65d0f03aa80c358408972fc700f916944b662",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "express@^4.13.4",
|
||||
"_where": "/Users/martin/newdev/Rinser",
|
||||
"_spec": "express@4.15.3",
|
||||
"_where": "/home/martind2000/dev/Rinser",
|
||||
"author": {
|
||||
"email": "tj@vision-media.ca",
|
||||
"name": "TJ Holowaychuk"
|
||||
@ -43,114 +67,130 @@
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Aaron Heckmann",
|
||||
"email": "aaron.heckmann+github@gmail.com"
|
||||
"email": "aaron.heckmann+github@gmail.com",
|
||||
"name": "Aaron Heckmann"
|
||||
},
|
||||
{
|
||||
"name": "Ciaran Jessup",
|
||||
"email": "ciaranj@gmail.com"
|
||||
"email": "ciaranj@gmail.com",
|
||||
"name": "Ciaran Jessup"
|
||||
},
|
||||
{
|
||||
"name": "Douglas Christopher Wilson",
|
||||
"email": "doug@somethingdoug.com"
|
||||
"email": "doug@somethingdoug.com",
|
||||
"name": "Douglas Christopher Wilson"
|
||||
},
|
||||
{
|
||||
"name": "Guillermo Rauch",
|
||||
"email": "rauchg@gmail.com"
|
||||
"email": "rauchg@gmail.com",
|
||||
"name": "Guillermo Rauch"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Ong",
|
||||
"email": "me@jongleberry.com"
|
||||
"email": "me@jongleberry.com",
|
||||
"name": "Jonathan Ong"
|
||||
},
|
||||
{
|
||||
"name": "Roman Shtylman",
|
||||
"email": "shtylman+expressjs@gmail.com"
|
||||
"email": "shtylman+expressjs@gmail.com",
|
||||
"name": "Roman Shtylman"
|
||||
},
|
||||
{
|
||||
"name": "Young Jae Sim",
|
||||
"email": "hanul@hanul.me"
|
||||
"email": "hanul@hanul.me",
|
||||
"name": "Young Jae Sim"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"accepts": "~1.2.12",
|
||||
"accepts": "~1.3.3",
|
||||
"array-flatten": "1.1.1",
|
||||
"content-disposition": "0.5.1",
|
||||
"content-type": "~1.0.1",
|
||||
"cookie": "0.1.5",
|
||||
"content-disposition": "0.5.2",
|
||||
"content-type": "~1.0.2",
|
||||
"cookie": "0.3.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "~2.2.0",
|
||||
"debug": "2.6.7",
|
||||
"depd": "~1.1.0",
|
||||
"encodeurl": "~1.0.1",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.7.0",
|
||||
"finalhandler": "0.4.1",
|
||||
"fresh": "0.3.0",
|
||||
"etag": "~1.8.0",
|
||||
"finalhandler": "~1.0.3",
|
||||
"fresh": "0.5.0",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.1",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~1.0.10",
|
||||
"qs": "4.0.0",
|
||||
"range-parser": "~1.0.3",
|
||||
"send": "0.13.1",
|
||||
"serve-static": "~1.10.2",
|
||||
"type-is": "~1.6.6",
|
||||
"proxy-addr": "~1.1.4",
|
||||
"qs": "6.4.0",
|
||||
"range-parser": "~1.2.0",
|
||||
"send": "0.15.3",
|
||||
"serve-static": "1.12.3",
|
||||
"setprototypeof": "1.0.3",
|
||||
"statuses": "~1.3.1",
|
||||
"type-is": "~1.6.15",
|
||||
"utils-merge": "1.0.0",
|
||||
"vary": "~1.0.1"
|
||||
"vary": "~1.1.1"
|
||||
},
|
||||
"description": "Fast, unopinionated, minimalist web framework",
|
||||
"devDependencies": {
|
||||
"after": "0.8.1",
|
||||
"body-parser": "~1.14.2",
|
||||
"after": "0.8.2",
|
||||
"body-parser": "1.17.1",
|
||||
"connect-redis": "~2.4.1",
|
||||
"cookie-parser": "~1.4.1",
|
||||
"cookie-parser": "~1.4.3",
|
||||
"cookie-session": "~1.2.0",
|
||||
"ejs": "2.3.4",
|
||||
"express-session": "~1.13.0",
|
||||
"istanbul": "0.4.2",
|
||||
"jade": "~1.11.0",
|
||||
"marked": "0.3.5",
|
||||
"method-override": "~2.3.5",
|
||||
"mocha": "2.3.4",
|
||||
"morgan": "~1.6.1",
|
||||
"multiparty": "~4.1.2",
|
||||
"should": "7.1.1",
|
||||
"supertest": "1.1.0",
|
||||
"vhost": "~3.0.1"
|
||||
"ejs": "2.5.6",
|
||||
"express-session": "1.15.2",
|
||||
"hbs": "4.0.1",
|
||||
"istanbul": "0.4.5",
|
||||
"marked": "0.3.6",
|
||||
"method-override": "2.3.8",
|
||||
"mocha": "3.4.1",
|
||||
"morgan": "1.8.1",
|
||||
"multiparty": "4.1.3",
|
||||
"pbkdf2-password": "1.2.1",
|
||||
"should": "11.2.1",
|
||||
"supertest": "1.2.0",
|
||||
"vhost": "~3.0.2"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "3c0b76f3c77590c8345739061ec0bd3ba067ec24",
|
||||
"tarball": "https://registry.npmjs.org/express/-/express-4.13.4.tgz"
|
||||
"shasum": "bab65d0f03aa80c358408972fc700f916944b662",
|
||||
"tarball": "https://registry.npmjs.org/express/-/express-4.15.3.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"History.md",
|
||||
"LICENSE",
|
||||
"History.md",
|
||||
"Readme.md",
|
||||
"index.js",
|
||||
"lib/"
|
||||
],
|
||||
"gitHead": "193bed2649c55c1fd362e46cd4702c773f3e7434",
|
||||
"homepage": "https://github.com/expressjs/express",
|
||||
"gitHead": "6da454c7fb37e68ed65ffe0371aa688b89f5bd6e",
|
||||
"homepage": "http://expressjs.com/",
|
||||
"keywords": [
|
||||
"api",
|
||||
"app",
|
||||
"express",
|
||||
"framework",
|
||||
"sinatra",
|
||||
"web",
|
||||
"rest",
|
||||
"restful",
|
||||
"router",
|
||||
"sinatra",
|
||||
"web"
|
||||
"app",
|
||||
"api"
|
||||
],
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "dougwilson",
|
||||
"email": "doug@somethingdoug.com"
|
||||
"email": "doug@somethingdoug.com",
|
||||
"name": "dougwilson"
|
||||
},
|
||||
{
|
||||
"email": "captain@hacksparrow.com",
|
||||
"name": "hacksparrow"
|
||||
},
|
||||
{
|
||||
"email": "jasnell@gmail.com",
|
||||
"name": "jasnell"
|
||||
},
|
||||
{
|
||||
"email": "mikeal.rogers@gmail.com",
|
||||
"name": "mikeal"
|
||||
}
|
||||
],
|
||||
"name": "express",
|
||||
@ -166,5 +206,5 @@
|
||||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
|
||||
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"
|
||||
},
|
||||
"version": "4.13.4"
|
||||
"version": "4.15.3"
|
||||
}
|
||||
|
9
node_modules/lodash/package.json
generated
vendored
9
node_modules/lodash/package.json
generated
vendored
@ -40,8 +40,13 @@
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/",
|
||||
"/cheerio",
|
||||
"/gulp-jshint"
|
||||
"/async",
|
||||
"/gulp-jshint",
|
||||
"/gulp-uglify",
|
||||
"/hipchat-notifier",
|
||||
"/mailgun-js/async",
|
||||
"/requestretry",
|
||||
"/rss-braider"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"_shasum": "78203a4d1c328ae1d86dca6460e369b57f4055ae",
|
||||
|
80
node_modules/rss-braider/.npmignore
generated
vendored
80
node_modules/rss-braider/.npmignore
generated
vendored
@ -1,79 +1 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
|
||||
|
||||
*.iml
|
||||
|
||||
/dist
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
### Node template
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directory
|
||||
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
|
||||
node_modules
|
||||
|
||||
node_modules
|
9
node_modules/rss-braider/README.md
generated
vendored
9
node_modules/rss-braider/README.md
generated
vendored
@ -1,4 +1,6 @@
|
||||
[![Build Status](https://travis-ci.org/KQED/rss-braider.svg?branch=master)](https://travis-ci.org/KQED/rss-braider)
|
||||
[![Dependencies](https://david-dm.org/rKQED/rss-braider.svg?branch=master)](https://david-dm.org/KQED/rss-braider)
|
||||
|
||||
|
||||
## Summary
|
||||
Braid/aggregate one or more RSS feeds (file or url) into a single feed (RSS or JSON output). Process resulting feed through specified plugins. Automatic deduplication
|
||||
@ -8,13 +10,16 @@ Braid/aggregate one or more RSS feeds (file or url) into a single feed (RSS or J
|
||||
npm install rss-braider
|
||||
```
|
||||
## Test
|
||||
`npm test`
|
||||
```
|
||||
npm install
|
||||
npm test
|
||||
```
|
||||
|
||||
## Examples
|
||||
```
|
||||
$ cd examples
|
||||
$ node simple.js (combines 3 sources)
|
||||
$ node plugins.js (combines 3 sources and runs a transformation plugin)
|
||||
$ node use_plugins.js (combines 3 sources and runs a transformation plugin)
|
||||
```
|
||||
### Code Example
|
||||
```js
|
||||
|
4
node_modules/rss-braider/examples/simple.js
generated
vendored
4
node_modules/rss-braider/examples/simple.js
generated
vendored
@ -33,8 +33,8 @@ var braider_options = {
|
||||
};
|
||||
var rss_braider = RssBraider.createClient(braider_options);
|
||||
|
||||
// Set logging level (debug, info, warn, err, off)
|
||||
rss_braider.logger.level('off');
|
||||
// Set logging level (debug, info, warn, err)
|
||||
rss_braider.logger.level('info');
|
||||
|
||||
rss_braider.processFeed('simple_test_feed', 'rss', function(err, data){
|
||||
if (err) {
|
||||
|
346
node_modules/rss-braider/lib/RssBraider.js
generated
vendored
346
node_modules/rss-braider/lib/RssBraider.js
generated
vendored
@ -1,206 +1,208 @@
|
||||
// Process feed-reader item into node-rss item
|
||||
var FeedParser = require('feedparser');
|
||||
var bunyan = require('bunyan');
|
||||
var _ = require('lodash');
|
||||
var async = require('async');
|
||||
var request = require('request');
|
||||
var RSS = require('rss');
|
||||
var fs = require('fs');
|
||||
var package_json = require('../package.json');
|
||||
var logger;
|
||||
// process feed-reader item into node-rss item
|
||||
var FeedParser = require('feedparser'),
|
||||
bunyan = require('bunyan'),
|
||||
_ = require('lodash'),
|
||||
async = require('async'),
|
||||
request = require('request'),
|
||||
RSS = require('rss'),
|
||||
fs = require('fs'),
|
||||
package_json = require('../package.json'),
|
||||
logger;
|
||||
|
||||
var RssBraider = function(options) {
|
||||
var RssBraider = function (options) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
options = {};
|
||||
}
|
||||
this.feeds = options.feeds || null;
|
||||
this.logger = options.logger || bunyan.createLogger({name: package_json.name});
|
||||
|
||||
if (options.log_level) {
|
||||
this.logger.level(options.log_level);
|
||||
this.logger.level(options.log_level);
|
||||
}
|
||||
|
||||
this.indent = options.indent || ' ';
|
||||
this.indent = options.indent || " ";
|
||||
this.dedupe_fields = options.dedupe_fields || []; // The fields to use to identify duplicate articles
|
||||
this.date_sort_order = options.date_sort_order || 'desc';
|
||||
this.date_sort_order = options.date_sort_order || "desc";
|
||||
|
||||
this.plugins_directories = options.plugins_directories || [];
|
||||
this.plugins = {};
|
||||
this.loadPlugins();
|
||||
};
|
||||
};
|
||||
|
||||
// Loadup self.plugins with the plugin functions
|
||||
RssBraider.prototype.loadPlugins = function() {
|
||||
// loadup self.plugins with the plugin functions
|
||||
RssBraider.prototype.loadPlugins = function () {
|
||||
var self = this;
|
||||
|
||||
if (self.plugins_directories.length < 1) {
|
||||
self.logger.debug('No plugins_directories specified. No plugins loaded.');
|
||||
self.logger.debug("No plugins_directories specified. No plugins loaded.");
|
||||
}
|
||||
self.plugins_directories.forEach(function(path) {
|
||||
// Load up each file and assign it to the plugins
|
||||
self.plugins_directories.forEach(function(path){
|
||||
// load up each file and assign it to the plugins
|
||||
var filenames = fs.readdirSync(path);
|
||||
filenames.forEach(function(filename) {
|
||||
filenames.forEach(function(filename){
|
||||
var plugin_name = filename.replace(/.js$/, '');
|
||||
if (self.plugins[plugin_name]) {
|
||||
self.logger.warn('Duplicate plugin name: ', plugin_name, 'Overwriting with newer plugin');
|
||||
self.logger.warn("Duplicate plugin name: ", plugin_name, "Overwriting with newer plugin");
|
||||
}
|
||||
self.plugins[plugin_name] = require(path + '/' + plugin_name);
|
||||
self.logger.debug('plugin registered:', plugin_name);
|
||||
});
|
||||
});
|
||||
};
|
||||
self.logger.debug("plugin registered:", plugin_name);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
RssBraider.prototype.feedExists = function(feed_name) {
|
||||
RssBraider.prototype.feedExists = function (feed_name) {
|
||||
if (this.feeds && this.feeds[feed_name]) {
|
||||
return true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Gather data from all feed sources, process each article/item through plugins,
|
||||
// trim down to desired count, dedupe and sort
|
||||
RssBraider.prototype.processFeed = function(feed_name, format, callback) {
|
||||
var self = this;
|
||||
var feed = self.feeds[feed_name];
|
||||
var feed_articles = [];
|
||||
RssBraider.prototype.processFeed = function(feed_name, format, callback)
|
||||
{
|
||||
var self = this,
|
||||
feed = self.feeds[feed_name],
|
||||
feed_articles = [];
|
||||
|
||||
if (!format) {
|
||||
format = 'rss';
|
||||
format = 'rss';
|
||||
}
|
||||
|
||||
if (!feed || !feed.sources || feed.sources.length < 1) {
|
||||
return callback('No definition for feed name: ' + feed_name);
|
||||
return callback("No definition for feed name: " + feed_name);
|
||||
}
|
||||
|
||||
// Process each feed source through Feedparser to get articles.
|
||||
// Then process each item/article through rss-braider and any plugins
|
||||
async.each(feed.sources, function(source, callback) {
|
||||
var count = source.count || feed.default_count || 10;
|
||||
var url = source.feed_url || null;
|
||||
var file_path = source.file_path || null;
|
||||
var source_articles = [];
|
||||
var count = source.count || feed.default_count || 10, // Number of articles per source
|
||||
url = source.feed_url || null,
|
||||
file_path = source.file_path || null,
|
||||
source_articles = [];
|
||||
|
||||
var feedparser = new FeedParser();
|
||||
if (url) {
|
||||
var req = request(url);
|
||||
var req = request(url);
|
||||
|
||||
req.on('error', function(error) {
|
||||
self.logger.error(error);
|
||||
req.on('error', function (error) {
|
||||
self.logger.error(error);
|
||||
});
|
||||
|
||||
req.on('response', function(res) {
|
||||
var stream = this;
|
||||
if (res.statusCode !== 200) {
|
||||
return this.emit('error', 'Bad status code for ' + url + ': ' + res.statusCode);
|
||||
}
|
||||
stream.pipe(feedparser);
|
||||
req.on('response', function (res) {
|
||||
var stream = this;
|
||||
if (res.statusCode !== 200) {
|
||||
return this.emit('error', 'Bad status code: ' + res.statusCode);
|
||||
}
|
||||
stream.pipe(feedparser);
|
||||
});
|
||||
} else if (file_path) {
|
||||
// Open file
|
||||
var filestream = fs.createReadStream(file_path);
|
||||
filestream.pipe(feedparser);
|
||||
// open file
|
||||
var filestream = fs.createReadStream(file_path);
|
||||
filestream.pipe(feedparser);
|
||||
} else {
|
||||
self.logger.error('url or file_path not defined for feed: ' + source.name);
|
||||
return callback();
|
||||
self.logger.error("url or file_path not defined for feed: " + source.name);
|
||||
return callback();
|
||||
}
|
||||
|
||||
feedparser.on('error', function(error) {
|
||||
self.logger.error('feedparser',', source.name:', source.name, ', url:', source.feed_url, error.stack);
|
||||
});
|
||||
self.logger.error("feedparser",", source.name:", source.name, ", url:", source.feed_url, error.stack);
|
||||
});
|
||||
|
||||
// Collect the articles from this source
|
||||
feedparser.on('readable', function() {
|
||||
var stream = this,
|
||||
item;
|
||||
|
||||
while (!!(item = stream.read())) {
|
||||
if (source.feed_url) {
|
||||
item.source_url = source.feed_url;
|
||||
}
|
||||
// Process Item/Article
|
||||
var article = self.processItem(item, source, feed_name);
|
||||
while ( !!(item = stream.read()) ) {
|
||||
if (source.feed_url) {
|
||||
item.source_url = source.feed_url;
|
||||
}
|
||||
// Process Item/Article
|
||||
var article = self.processItem(item, source, feed_name);
|
||||
|
||||
// Plugins may filter items and return null
|
||||
if (article) {
|
||||
source_articles.push(article);
|
||||
}
|
||||
// plugins may filter items and return null
|
||||
if (article) {
|
||||
source_articles.push(article);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
feedparser.on('end', function() {
|
||||
// De-dupe , date sort, and trim this feed's articles and push them into array
|
||||
feedparser.on("end", function(){
|
||||
// de-dupe , date sort, and trim this feed's articles and push them into array
|
||||
source_articles = self.dedupe(source_articles, self.dedupe_fields);
|
||||
source_articles = self.date_sort(source_articles);
|
||||
source_articles = source_articles.slice(0, count);
|
||||
feed_articles = feed_articles.concat(source_articles);
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(err) {
|
||||
});
|
||||
},
|
||||
function(err){
|
||||
if (err) {
|
||||
self.logger.error(err);
|
||||
return callback(err);
|
||||
self.logger.error(err);
|
||||
return callback(err);
|
||||
} else {
|
||||
// Final Dedupe step and resort
|
||||
feed_articles = self.dedupe(feed_articles, self.dedupe_fields);
|
||||
feed_articles = self.date_sort(feed_articles);
|
||||
// Final Dedupe step and resort
|
||||
feed_articles = self.dedupe(feed_articles, self.dedupe_fields);
|
||||
feed_articles = self.date_sort(feed_articles);
|
||||
|
||||
// Create new feed with these articles. Follows node-rss spec
|
||||
var options = {
|
||||
title: feed.meta.title,
|
||||
description: feed.meta.description,
|
||||
generator: feed.meta.generator || 'rss-braider',
|
||||
site_url: feed.meta.site_url || null,
|
||||
feed_url: feed.meta.feed_url || null,
|
||||
image_url: feed.meta.image_url || null,
|
||||
webMaster: feed.meta.webMaster || null,
|
||||
copyright: feed.meta.copyright || null,
|
||||
categories: feed.meta.categories || null,
|
||||
custom_namespaces: feed.custom_namespaces || [],
|
||||
no_cdata_fields: feed.no_cdata_fields
|
||||
// Create new feed with these articles. Follows node-rss spec
|
||||
var options = {
|
||||
title : feed.meta.title,
|
||||
description : feed.meta.description,
|
||||
generator : feed.meta.generator || 'rss-braider',
|
||||
site_url : feed.meta.site_url || null,
|
||||
feed_url : feed.meta.feed_url || null,
|
||||
image_url : feed.meta.image_url || null,
|
||||
webMaster : feed.meta.webMaster || null,
|
||||
copyright : feed.meta.copyright || null,
|
||||
categories : feed.meta.categories || null,
|
||||
custom_namespaces : feed.custom_namespaces || [],
|
||||
custom_elements : feed.meta.custom_elements || [],
|
||||
no_cdata_fields : feed.no_cdata_fields
|
||||
};
|
||||
|
||||
var newfeed = new RSS(options, feed_articles);
|
||||
var newfeed = new RSS(options, feed_articles);
|
||||
|
||||
var ret_string;
|
||||
switch (format.toLowerCase()) {
|
||||
case 'json':
|
||||
ret_string = JSON.stringify(newfeed);
|
||||
break;
|
||||
case 'rss':
|
||||
ret_string = newfeed.xml(self.indent);
|
||||
break;
|
||||
default:
|
||||
self.logger.error('Unknown format:', format);
|
||||
ret_string = '{}';
|
||||
}
|
||||
var ret_string;
|
||||
switch (format.toLowerCase()) {
|
||||
case 'json':
|
||||
ret_string = JSON.stringify(newfeed);
|
||||
break;
|
||||
case 'rss':
|
||||
ret_string = newfeed.xml(self.indent);
|
||||
break;
|
||||
default:
|
||||
self.logger.error("Unknown format:", format);
|
||||
ret_string = "{}";
|
||||
}
|
||||
|
||||
return callback(null, ret_string);
|
||||
return callback(null, ret_string);
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Accepts a feed-parser item and builds a node-rss itemOptions object
|
||||
RssBraider.prototype.processItem = function(item, source, feed_name) {
|
||||
RssBraider.prototype.processItem = function (item, source, feed_name) {
|
||||
var self = this;
|
||||
|
||||
if (!item || !source || !feed_name) {
|
||||
self.logger.error('processItem: missing item, source, and/or feed_name');
|
||||
return null;
|
||||
self.logger.error("processItem: missing item, source, and/or feed_name");
|
||||
return null;
|
||||
}
|
||||
// Basics
|
||||
var itemOptions = {
|
||||
title: item.title,
|
||||
description: item.summary,
|
||||
url: item.link,
|
||||
guid: item.guid,
|
||||
permalink: item.permalink,
|
||||
author: item.author,
|
||||
date: item.date,
|
||||
categories: item.categories,
|
||||
custom_elements: []
|
||||
};
|
||||
title : item.title,
|
||||
description : item.summary,
|
||||
url : item.link,
|
||||
guid : item.guid,
|
||||
permalink : item.permalink,
|
||||
author : item.author,
|
||||
date : item.date,
|
||||
categories : item.categories,
|
||||
custom_elements : []
|
||||
};
|
||||
|
||||
// Run the plugins specified by the "plugins" section of the
|
||||
// feed .js file to build out any custom elements or
|
||||
@ -208,9 +210,9 @@ RssBraider.prototype.processItem = function(item, source, feed_name) {
|
||||
var filteredItemOptions = self.runPlugins(item, itemOptions, source, feed_name);
|
||||
|
||||
return filteredItemOptions;
|
||||
};
|
||||
};
|
||||
|
||||
RssBraider.prototype.runPlugins = function(item, itemOptions, source, feed_name) {
|
||||
RssBraider.prototype.runPlugins = function (item, itemOptions, source, feed_name) {
|
||||
var self = this,
|
||||
feed = self.feeds[feed_name] || {},
|
||||
plugins_list = feed.plugins || [],
|
||||
@ -220,77 +222,77 @@ RssBraider.prototype.runPlugins = function(item, itemOptions, source, feed_name)
|
||||
// Process the item through the desired feed plugins
|
||||
// plugins_list.forEach(function(plugin_name){
|
||||
for (var i = 0; i < plugins_list.length; i++) {
|
||||
var plugin_name = plugins_list[i];
|
||||
if (self.plugins[plugin_name]) {
|
||||
filteredItemOptions = self.plugins[plugin_name](item, itemOptions, source);
|
||||
} else {
|
||||
self.logger.error('A plugin named \'' + plugin_name + '\' hasn\'t been registered');
|
||||
}
|
||||
var plugin_name = plugins_list[i];
|
||||
if (self.plugins[plugin_name]) {
|
||||
filteredItemOptions = self.plugins[plugin_name](item, itemOptions, source);
|
||||
} else {
|
||||
self.logger.error("A plugin named '" + plugin_name + "' hasn't been registered");
|
||||
}
|
||||
|
||||
// A plugin returning -1 means skip this item
|
||||
if (filteredItemOptions === -1) {
|
||||
self.logger.debug('Plugin \'' + plugin_name + '\' filtered item from feed \'' + feed.meta.title + '\'', item.guid);
|
||||
itemOptions = null;
|
||||
break;
|
||||
}
|
||||
// A plugin returning -1 means skip this item
|
||||
if (filteredItemOptions === -1) {
|
||||
self.logger.debug("Plugin '" + plugin_name + "' filtered item from feed '" + feed.meta.title + "'", item.guid);
|
||||
itemOptions = null;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check that the plugin didn't just return null or undef, which would be bad.
|
||||
if (!filteredItemOptions) {
|
||||
self.logger.debug('Plugin \'' + plugin_name + '\' failed to return itemOptions for feed:\'' + feed.meta.title + '\'', item.guid);
|
||||
filteredItemOptions = itemOptions; // Reset
|
||||
}
|
||||
// Prepare for next plugin.
|
||||
itemOptions = filteredItemOptions;
|
||||
// Check that the plugin didn't just return null or undef, which would be bad.
|
||||
if (!filteredItemOptions) {
|
||||
self.logger.debug("Plugin '" + plugin_name + "' failed to return itemOptions for feed:'" + feed.meta.title + "'", item.guid);
|
||||
filteredItemOptions = itemOptions; // Reset
|
||||
}
|
||||
// Prepare for next plugin.
|
||||
itemOptions = filteredItemOptions;
|
||||
}
|
||||
return itemOptions;
|
||||
};
|
||||
};
|
||||
|
||||
// Dedupe articles in node-rss itemOptions format
|
||||
// Accepts an array of fields to dedupe on, or does a basic uniq
|
||||
// operation on the articles array
|
||||
// TODO, make this a plugin?
|
||||
RssBraider.prototype.dedupe = function(articles_arr, fields) {
|
||||
RssBraider.prototype.dedupe = function(articles_arr, fields){
|
||||
var self = this;
|
||||
if (!fields || fields.length < 1) {
|
||||
return _.uniq(articles_arr);
|
||||
if ( !fields || fields.length < 1 ) {
|
||||
return _.uniq(articles_arr);
|
||||
} else {
|
||||
var uniques = {},
|
||||
deduped_articles = [];
|
||||
articles_arr.forEach(function(article) {
|
||||
var count = 0;
|
||||
fields.forEach(function(field) {
|
||||
if (!uniques[field]) {
|
||||
uniques[field] = [];
|
||||
}
|
||||
if (uniques[field].indexOf(article[field]) !== -1) {
|
||||
count++;
|
||||
} else {
|
||||
uniques[field].push(article[field]);
|
||||
}
|
||||
var uniques = {},
|
||||
deduped_articles = [];
|
||||
articles_arr.forEach(function(article){
|
||||
var count = 0;
|
||||
fields.forEach(function(field){
|
||||
if (!uniques[field]) {
|
||||
uniques[field] = [];
|
||||
}
|
||||
if (uniques[field].indexOf(article[field]) !== -1) {
|
||||
count++;
|
||||
} else {
|
||||
uniques[field].push(article[field]);
|
||||
}
|
||||
});
|
||||
if (count !== fields.length) {
|
||||
// It's unique
|
||||
deduped_articles.push(article);
|
||||
} else {
|
||||
// The article matched all of another article's "dedupe" fields
|
||||
// so filter it out (i.e. do nothing)
|
||||
self.logger.debug('skipping duplicate', '"' + article.title + '"', article.guid);
|
||||
}
|
||||
if (count !== fields.length) {
|
||||
// it's unique
|
||||
deduped_articles.push(article);
|
||||
} else {
|
||||
// The article matched all of another article's "dedupe" fields
|
||||
// so filter it out (i.e. do nothing)
|
||||
self.logger.debug("skipping duplicate", '"' + article.title + '"', article.guid);
|
||||
}
|
||||
});
|
||||
return deduped_articles;
|
||||
return deduped_articles;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// TODO: Could be a plugin
|
||||
// Sort articles by date
|
||||
RssBraider.prototype.date_sort = function(articles_arr) {
|
||||
var sorted_articles = _.sortBy(articles_arr, function(article) {
|
||||
return article.date.getTime();
|
||||
});
|
||||
if (this.date_sort_order === 'desc') {
|
||||
sorted_articles.reverse();
|
||||
});
|
||||
if (this.date_sort_order === "desc") {
|
||||
sorted_articles.reverse();
|
||||
}
|
||||
return sorted_articles;
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = RssBraider;
|
||||
|
75
node_modules/rss-braider/package.json
generated
vendored
75
node_modules/rss-braider/package.json
generated
vendored
@ -2,37 +2,47 @@
|
||||
"_args": [
|
||||
[
|
||||
{
|
||||
"name": null,
|
||||
"raw": "git+http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
|
||||
"rawSpec": "git+http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
|
||||
"name": "rss-braider",
|
||||
"raw": "rss-braider",
|
||||
"rawSpec": "",
|
||||
"scope": null,
|
||||
"spec": "http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
|
||||
"type": "git"
|
||||
"spec": "latest",
|
||||
"type": "tag"
|
||||
},
|
||||
"/home/martind2000/dev/Rinser"
|
||||
]
|
||||
],
|
||||
"_from": "git+http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
|
||||
"_id": "rss-braider@1.0.0",
|
||||
"_from": "rss-braider@latest",
|
||||
"_id": "rss-braider@1.2.0",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/rss-braider",
|
||||
"_nodeVersion": "6.2.1",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-18-east.internal.npmjs.com",
|
||||
"tmp": "tmp/rss-braider-1.2.0.tgz_1487633154488_0.3144866321235895"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "kgebhardt23@gmail.com",
|
||||
"name": "rv-kip"
|
||||
},
|
||||
"_npmVersion": "3.9.3",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": null,
|
||||
"raw": "git+http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
|
||||
"rawSpec": "git+http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
|
||||
"name": "rss-braider",
|
||||
"raw": "rss-braider",
|
||||
"rawSpec": "",
|
||||
"scope": null,
|
||||
"spec": "http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
|
||||
"type": "git"
|
||||
"spec": "latest",
|
||||
"type": "tag"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#DEV:/"
|
||||
"/"
|
||||
],
|
||||
"_resolved": "git+http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git#1559131d2e2d73076307667d260f0e173e64c8c3",
|
||||
"_shasum": "4ca2443627b6ffd330424d220aa10635f4f8cb8c",
|
||||
"_resolved": "https://registry.npmjs.org/rss-braider/-/rss-braider-1.2.0.tgz",
|
||||
"_shasum": "ce134542a39b643b916b95dd08a10dbfd7f1c28b",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "git+http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
|
||||
"_spec": "rss-braider",
|
||||
"_where": "/home/martind2000/dev/Rinser",
|
||||
"author": {
|
||||
"email": "kgebhardt@kqed.org",
|
||||
@ -43,20 +53,26 @@
|
||||
"url": "http://github.com/KQED/rss-braider/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^1.2.1",
|
||||
"async": "^2.1.5",
|
||||
"bunyan": "^1.4.0",
|
||||
"feedparser": "^1.1.3",
|
||||
"include-folder": "^0.9.0",
|
||||
"lodash": "^3.9.3",
|
||||
"feedparser": "^2.1.0",
|
||||
"include-folder": "^1.0.0",
|
||||
"lodash": "^4.17.4",
|
||||
"request": "^2.57.0",
|
||||
"rss": "git://github.com/rv-kip/node-rss.git#8d1420"
|
||||
"rss": "1.2.0"
|
||||
},
|
||||
"description": "Braid/aggregate/combine RSS feeds into a single RSS (or JSON) document. Optionally process through specified plugins.",
|
||||
"devDependencies": {
|
||||
"mockdate": "^1.0.3",
|
||||
"mockdate": "^2.0.1",
|
||||
"tape": "^4.0.0"
|
||||
},
|
||||
"gitHead": "1559131d2e2d73076307667d260f0e173e64c8c3",
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "ce134542a39b643b916b95dd08a10dbfd7f1c28b",
|
||||
"tarball": "https://registry.npmjs.org/rss-braider/-/rss-braider-1.2.0.tgz"
|
||||
},
|
||||
"gitHead": "898ec8743c4ab37c4bf7a8fc925356c351d7df39",
|
||||
"homepage": "https://github.com/KQED/rss-braider#readme",
|
||||
"keywords": [
|
||||
"rss",
|
||||
"braider",
|
||||
@ -77,16 +93,21 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"email": "kgebhardt23@gmail.com",
|
||||
"name": "rv-kip"
|
||||
}
|
||||
],
|
||||
"name": "rss-braider",
|
||||
"optionalDependencies": {},
|
||||
"readme": "[![Build Status](https://travis-ci.org/KQED/rss-braider.svg?branch=master)](https://travis-ci.org/KQED/rss-braider)\n\n## Summary\nBraid/aggregate one or more RSS feeds (file or url) into a single feed (RSS or JSON output). Process resulting feed through specified plugins. Automatic deduplication\n\n## Installation\n```\nnpm install rss-braider\n```\n## Test\n`npm test`\n\n## Examples\n```\n$ cd examples\n$ node simple.js (combines 3 sources)\n$ node plugins.js (combines 3 sources and runs a transformation plugin)\n```\n### Code Example\n```js\nvar RssBraider = require('rss-braider'),\n feeds = {};\n\n// Pull feeds from config files:\n// feeds.simple_test_feed = require(\"./config/feed\").feed;\n// Or define in-line\nfeeds.simple_test_feed = {\n \"feed_name\" : \"feed\",\n \"default_count\" : 1,\n \"no_cdata_fields\" : [], // Don't wrap these fields in CDATA tags\n \"meta\" : {\n \"title\": \"NPR Braided Feed\",\n \"description\": \"This is a test of two NPR\"\n },\n \"sources\" : [\n {\n \"name\" : \"NPR Headlines\",\n \"count\" : 2,\n \"feed_url\" : \"http://www.npr.org/rss/rss.php?id=1001\",\n },\n {\n \"name\" : \"NPR Sports\",\n \"count\" : 2,\n \"feed_url\" : \"http://www.npr.org/rss/rss.php?id=1055\"\n }\n ]\n};\nvar braider_options = {\n feeds : feeds,\n indent : \" \",\n date_sort_order : \"desc\", // Newest first\n log_level : \"debug\"\n};\nvar rss_braider = RssBraider.createClient(braider_options);\n\n// Override logging level (debug, info, warn, err, off)\nrss_braider.logger.level('off');\n\n// Output braided feed as rss. use 'json' for JSON output.\nrss_braider.processFeed('simple_test_feed', 'rss', function(err, data){\n if (err) {\n return console.log(err);\n }\n console.log(data);\n});\n```\n## Plugins\nPlugins provide custom manipulation and filtering of RSS items/articles. See `examples/plugins` for examples.\n\nA plugin operates by modifying the `itemOptions` object or by returning `null` which will exclude the `item` (article) from the resulting feed (See `examples/plugins/filter_out_all_articles.js`).\n\nThe `itemsOptions` object gets passed to `node-rss` to generate the RSS feeds, so read the documentation on that module and its use of custom namespaces. (https://github.com/dylang/node-rss)\n\n### Plugin Example\nThis plugin will capitalize the article title for all articles\n```js\nmodule.exports = function (item, itemOptions, source) {\n if (!item || !itemOptions) {\n return;\n }\n\n if (itemOptions.title) {\n itemOptions.title = itemOptions.title.toUpperCase();\n }\n\n return itemOptions;\n};\n```\n\nThe plugin is registered with the feed in the feed config .js file and are run in order.\n```js\nvar feed = {\n \"feed_name\" : \"feed with plugins\",\n \"default_count\" : 1,\n \"plugins\" : ['capitalize_title', 'plugin_template'],\n...\n```\n\n## Release Notes\n### 1.0.0\nChanged plugin architecture to allow filtering out of article/items by returning `-1` instead of a modified `itemsOptions` object. This is a breaking change as it will require existing plugins to return `itemsOptions` instead of modifying the reference. See `examples/plugins`.\n\n",
|
||||
"readmeFilename": "README.md",
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git"
|
||||
"url": "git+https://github.com/KQED/rss-braider.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
"version": "1.2.0"
|
||||
}
|
||||
|
17
node_modules/rss-braider/test/expected_output/dateAscOutput.xml
generated
vendored
17
node_modules/rss-braider/test/expected_output/dateAscOutput.xml
generated
vendored
@ -1,15 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:ev="http://purl.org/rss/2.0/modules/event/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:ev="http://purl.org/rss/2.0/modules/event/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
<channel>
|
||||
<title><![CDATA[Test File Feed]]></title>
|
||||
<description>This feed comes from a file</description>
|
||||
<description><![CDATA[This feed comes from a file]]></description>
|
||||
<link>http://github.com/dylang/node-rss</link>
|
||||
<generator>rss-braider</generator>
|
||||
<lastBuildDate>Wed, 31 Dec 2014 00:00:01 GMT</lastBuildDate>
|
||||
<item>
|
||||
<title><![CDATA[Rent Hike For Dance Mission Theater Has Artists Worried About Uncertain Future]]></title>
|
||||
<description><p>Stepping out of BART at 24th and Mission at most hours of the day, one is likely to hear the pulse of African drums, hip-hop or salsa emanating from the second-floor studios of Dance Brigade's Dance Mission Theater. But that music may not continue forever.</p>
|
||||
<p>The performance space and dance school <a href="http://ww2.kqed.org/news/2014/12/20/dance-mission-theater-rent-increase-worries-artists/" target="_self" id="rssmi_more"> ...read more</a></description>
|
||||
<description><![CDATA[<p>Stepping out of BART at 24th and Mission at most hours of the day, one is likely to hear the pulse of African drums, hip-hop or salsa emanating from the second-floor studios of Dance Brigade's Dance Mission Theater. But that music may not continue forever.</p>
|
||||
<p>The performance space and dance school <a href="http://ww2.kqed.org/news/2014/12/20/dance-mission-theater-rent-increase-worries-artists/" target="_self" id="rssmi_more"> ...read more</a>]]></description>
|
||||
<link>http://ww2.kqed.org/news/2014/12/20/dance-mission-theater-rent-increase-worries-artists/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/2014/12/20/rent-hike-for-dance-mission-theater-has-artists-worried-about-uncertain-future/</guid>
|
||||
<dc:creator><![CDATA[KQED Arts]]></dc:creator>
|
||||
@ -27,7 +26,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[Bob Miller: Teasing Science Lessons from Everyday Phenomena]]></title>
|
||||
<description>Until February 5, 2015, you can visit the main branch of the San Francisco Public Library and be momentarily transported through space and time to the early days of the Exploratorium via the life and work of Bob Miller, who died in 2007.</description>
|
||||
<description><![CDATA[Until February 5, 2015, you can visit the main branch of the San Francisco Public Library and be momentarily transported through space and time to the early days of the Exploratorium via the life and work of Bob Miller, who died in 2007.]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/20/bob-miller-teasing-science-lessons-from-everyday-phenomena/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10220517</guid>
|
||||
<dc:creator><![CDATA[Sarah Hotchkiss]]></dc:creator>
|
||||
@ -55,7 +54,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[Light Art Brings Holiday Glow to Darkest Nights]]></title>
|
||||
<description>In the dark of winter, San Franciscans with an urge to celebrate the light can visit a new wealth of illuminated art installations. This video tour offers a preview of some of the more dazzling works.</description>
|
||||
<description><![CDATA[In the dark of winter, San Franciscans with an urge to celebrate the light can visit a new wealth of illuminated art installations. This video tour offers a preview of some of the more dazzling works.]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/21/on-darkest-nights-illuminated-art-brings-holiday-glow/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10231062</guid>
|
||||
<dc:creator><![CDATA[KQED Arts]]></dc:creator>
|
||||
@ -72,7 +71,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[93 ‘Til Infinity: Watch Bay Area Musicians Remix Classic ’90s Hip-Hop]]></title>
|
||||
<description>One night back in November, the YBCA took a trip to 1993 to celebrate a groundbreaking year for hip hop.</description>
|
||||
<description><![CDATA[One night back in November, the YBCA took a trip to 1993 to celebrate a groundbreaking year for hip hop.]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/22/93-til-infinity-watch-bay-area-musicians-remix-classic-90s-hip-hop/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10230592</guid>
|
||||
<dc:creator><![CDATA[Kevin L. Jones]]></dc:creator>
|
||||
@ -91,7 +90,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[Protest Icons: Not Just for Show]]></title>
|
||||
<description>Hands up, umbrellas out, hoodies on, fists raised -- the icons of protest have long played a significant role in movements of social change and revolution. Some of the most potent protest icons of 2014 appeared in just the last four months of the year.</description>
|
||||
<description><![CDATA[Hands up, umbrellas out, hoodies on, fists raised -- the icons of protest have long played a significant role in movements of social change and revolution. Some of the most potent protest icons of 2014 appeared in just the last four months of the year.]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/23/protest-icons-not-just-for-show/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10189953</guid>
|
||||
<dc:creator><![CDATA[Michele Carlson]]></dc:creator>
|
||||
|
15
node_modules/rss-braider/test/expected_output/dateDescOutput.xml
generated
vendored
15
node_modules/rss-braider/test/expected_output/dateDescOutput.xml
generated
vendored
@ -1,14 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:ev="http://purl.org/rss/2.0/modules/event/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:ev="http://purl.org/rss/2.0/modules/event/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
<channel>
|
||||
<title><![CDATA[Test File Feed]]></title>
|
||||
<description>This feed comes from a file</description>
|
||||
<description><![CDATA[This feed comes from a file]]></description>
|
||||
<link>http://github.com/dylang/node-rss</link>
|
||||
<generator>rss-braider</generator>
|
||||
<lastBuildDate>Wed, 31 Dec 2014 00:00:01 GMT</lastBuildDate>
|
||||
<item>
|
||||
<title><![CDATA[Top 10 Movie Moments of 2014]]></title>
|
||||
<description>A handful of scenes resonate from a mediocre year for film.</description>
|
||||
<description><![CDATA[A handful of scenes resonate from a mediocre year for film.]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/26/top-10-movie-moments-of-2014/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10222283</guid>
|
||||
<dc:creator><![CDATA[Michael Fox]]></dc:creator>
|
||||
@ -56,7 +55,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[Radio Show: Rockin’ Roots to Radical Rauschenberg]]></title>
|
||||
<description>Cy Musiker and David Wiegand share their picks for great events around the Bay Area this week.</description>
|
||||
<description><![CDATA[Cy Musiker and David Wiegand share their picks for great events around the Bay Area this week.]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/25/radio-show-rockin-roots-to-radical-rauschenberg/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10238611</guid>
|
||||
<dc:creator><![CDATA[The Do List]]></dc:creator>
|
||||
@ -98,7 +97,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[Watch a Hip Hop Orchestra Perform Wu-Tang Clan’s “C.R.E.A.M”]]></title>
|
||||
<description>Above: Ensemble Mik Nawooj (EMN), led by music director, composer/pianist JooWan Kim, reinterprets Wu-Tang Clan’s &#8220;C.R.E.A.M.&#8221; at YBCA&#8217;s Clas/Sick Hip Hop: 1993 Edition. Ensemble Mik Nawooj (EMN) is the brainchild of composer/pianist JooWan Kim, who introduces western-European classical techniques into hip-hop, rock, and pop. The group&#8217;s lineup includes traditional Pierrot ensemble instrumentation (flute, clarinet, violin, cello and piano) with [&#8230;]</description>
|
||||
<description><![CDATA[Above: Ensemble Mik Nawooj (EMN), led by music director, composer/pianist JooWan Kim, reinterprets Wu-Tang Clan’s “C.R.E.A.M.” at YBCA’s Clas/Sick Hip Hop: 1993 Edition. Ensemble Mik Nawooj (EMN) is the brainchild of composer/pianist JooWan Kim, who introduces western-European classical techniques into hip-hop, rock, and pop. The group’s lineup includes traditional Pierrot ensemble instrumentation (flute, clarinet, violin, cello and piano) with […]]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/24/a-hip-hop-orchestra-does-wu-tang-clans-c-r-e-a-m/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10238600</guid>
|
||||
<dc:creator><![CDATA[Siouxsie Oki]]></dc:creator>
|
||||
@ -118,7 +117,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[Watch a Hip-Hop Funk Big Band Pay Homage to Saafir’s “Light Sleeper”]]></title>
|
||||
<description>Above: Kev Choice Ensemble reinterprets Saafir&#8217;s &#8220;Light Sleeper&#8221; at YBCA&#8217;s Clas/Sick Hip Hop: 1993 Edition. Oakland-based artist Kev Choice is a pianist, MC, producer, bandleader, sideman, music historian and urban griot dedicated to cultural expression. Through his band Kev Choice Ensemble, he produces and performs his own material, including original jazz and classical compositions as well as classical, [&#8230;]</description>
|
||||
<description><![CDATA[Above: Kev Choice Ensemble reinterprets Saafir’s “Light Sleeper” at YBCA’s Clas/Sick Hip Hop: 1993 Edition. Oakland-based artist Kev Choice is a pianist, MC, producer, bandleader, sideman, music historian and urban griot dedicated to cultural expression. Through his band Kev Choice Ensemble, he produces and performs his own material, including original jazz and classical compositions as well as classical, […]]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/24/a-jazz-hip-hop-funk-big-band-pays-homage-to-saafirs-light-sleeper/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10238610</guid>
|
||||
<dc:creator><![CDATA[Siouxsie Oki]]></dc:creator>
|
||||
@ -139,7 +138,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[Jason McHenry and His Quest for One Million Paintings]]></title>
|
||||
<description>Though the original intent was to make as much art as possible, the project somehow morphed into a goal of producing a seemingly preposterous number of paintings; now the mission of the <em>One Thousand Thousand</em> project is to amass that amount with the help of friends.</description>
|
||||
<description><![CDATA[Though the original intent was to make as much art as possible, the project somehow morphed into a goal of producing a seemingly preposterous number of paintings; now the mission of the <em>One Thousand Thousand</em> project is to amass that amount with the help of friends.]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/24/jason-mchenry-and-his-quest-to-amass-one-million-paintings/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10218934</guid>
|
||||
<dc:creator><![CDATA[Brian Eder]]></dc:creator>
|
||||
|
3
node_modules/rss-braider/test/expected_output/emptyFeed.xml
generated
vendored
3
node_modules/rss-braider/test/expected_output/emptyFeed.xml
generated
vendored
@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
|
||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
|
||||
<channel>
|
||||
<title><![CDATA[A Feed with no elements]]></title>
|
||||
<description><![CDATA[This feed will have no elements as a result of the filter_all_articles plugin. Used for unit tests.]]></description>
|
||||
|
3
node_modules/rss-braider/test/expected_output/fileFeedBadPlugin.xml
generated
vendored
3
node_modules/rss-braider/test/expected_output/fileFeedBadPlugin.xml
generated
vendored
@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
|
||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
|
||||
<channel>
|
||||
<title><![CDATA[A Feed with no elements]]></title>
|
||||
<description><![CDATA[This feed will have no elements as a result of the filter_all_articles plugin. Used for unit tests.]]></description>
|
||||
|
7
node_modules/rss-braider/test/expected_output/fileFeedOutput.xml
generated
vendored
7
node_modules/rss-braider/test/expected_output/fileFeedOutput.xml
generated
vendored
@ -1,14 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:ev="http://purl.org/rss/2.0/modules/event/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:ev="http://purl.org/rss/2.0/modules/event/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
<channel>
|
||||
<title><![CDATA[Test File Feed]]></title>
|
||||
<description>This feed comes from a file</description>
|
||||
<description><![CDATA[This feed comes from a file]]></description>
|
||||
<link>http://github.com/dylang/node-rss</link>
|
||||
<generator>rss-braider</generator>
|
||||
<lastBuildDate>Wed, 31 Dec 2014 00:00:01 GMT</lastBuildDate>
|
||||
<item>
|
||||
<title><![CDATA[Top 10 Movie Moments of 2014]]></title>
|
||||
<description>A handful of scenes resonate from a mediocre year for film.</description>
|
||||
<description><![CDATA[A handful of scenes resonate from a mediocre year for film.]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/26/top-10-movie-moments-of-2014/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10222283</guid>
|
||||
<dc:creator><![CDATA[Michael Fox]]></dc:creator>
|
||||
|
7
node_modules/rss-braider/test/expected_output/fileFeedOutputPlugins.xml
generated
vendored
7
node_modules/rss-braider/test/expected_output/fileFeedOutputPlugins.xml
generated
vendored
@ -1,14 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:ev="http://purl.org/rss/2.0/modules/event/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:ev="http://purl.org/rss/2.0/modules/event/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
<channel>
|
||||
<title><![CDATA[Test File Feed]]></title>
|
||||
<description>This feed comes from a file</description>
|
||||
<description><![CDATA[This feed comes from a file]]></description>
|
||||
<link>http://github.com/dylang/node-rss</link>
|
||||
<generator>rss-braider</generator>
|
||||
<lastBuildDate>Wed, 31 Dec 2014 00:00:01 GMT</lastBuildDate>
|
||||
<item>
|
||||
<title><![CDATA[Top 10 Movie Moments of 2014]]></title>
|
||||
<description>A handful of scenes resonate from a mediocre year for film.</description>
|
||||
<description><![CDATA[A handful of scenes resonate from a mediocre year for film.]]></description>
|
||||
<link>http://ww2.kqed.org/arts/2014/12/26/top-10-movie-moments-of-2014/</link>
|
||||
<guid isPermaLink="false">http://ww2.kqed.org/arts/?p=10222283</guid>
|
||||
<dc:creator><![CDATA[Michael Fox]]></dc:creator>
|
||||
|
1
node_modules/rss-braider/test/index.js
generated
vendored
1
node_modules/rss-braider/test/index.js
generated
vendored
@ -23,7 +23,6 @@ test('generate feed. No plugins', function(t) {
|
||||
}
|
||||
// console.log(data);
|
||||
t.equal(data, expectedOutput.fileFeedOutput);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
46
package.json
46
package.json
@ -2,43 +2,43 @@
|
||||
"name": "Rinser",
|
||||
"version": "0.1.1",
|
||||
"devDependencies": {
|
||||
"cheerio": "^0.20.0",
|
||||
"cheerio": "^0.22.0",
|
||||
"del": "^2.2.0",
|
||||
"ejs": "^2.3.3",
|
||||
"ejs": "^2.5.6",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "^3.1.0",
|
||||
"gulp-cache": "^0.4.2",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-autoprefixer": "^4.0.0",
|
||||
"gulp-cache": "^0.4.6",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-cssnano": "^2.1.1",
|
||||
"gulp-html-replace": "^1.5.5",
|
||||
"gulp-htmlmin": "^1.3.0",
|
||||
"gulp-inject": "^3.0.0",
|
||||
"gulp-jshint": "^2.0.0",
|
||||
"gulp-html-replace": "^1.6.2",
|
||||
"gulp-htmlmin": "^3.0.0",
|
||||
"gulp-inject": "^4.2.0",
|
||||
"gulp-jshint": "^2.0.4",
|
||||
"gulp-livereload": "^3.8.1",
|
||||
"gulp-notify": "^2.2.0",
|
||||
"gulp-notify": "^3.0.0",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-uglify": "^1.5.3",
|
||||
"jshint": "^2.9.1",
|
||||
"jsonfile": "^2.4.0",
|
||||
"gulp-uglify": "^3.0.0",
|
||||
"jshint": "^2.9.5",
|
||||
"jsonfile": "^3.0.1",
|
||||
"lodash": "^4.17.4",
|
||||
"log4js": "^0.6.38",
|
||||
"rss-braider": "git+http://gitlab.silvrtree.co.uk/martind2000/rss-braider.git",
|
||||
"log4js": "^2.2.0",
|
||||
"stopwords-en": "^0.3.0",
|
||||
"striptags": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"body-parser": "^1.14.2",
|
||||
"body-parser": "^1.17.2",
|
||||
"cookie-parser": "*",
|
||||
"ejs": "*",
|
||||
"errorhandler": "*",
|
||||
"express": "^4.13.4",
|
||||
"express-session": "*",
|
||||
"errorhandler": "^1.5.0",
|
||||
"express": "^4.15.3",
|
||||
"express-session": "^1.15.3",
|
||||
"htmlparser": "^1.7.7",
|
||||
"jsonfile": "^2.4.0",
|
||||
"lodash": "^4.16.6",
|
||||
"method-override": "*",
|
||||
"morgan": "*",
|
||||
"request": "*",
|
||||
"yargs": "^6.3.0"
|
||||
"method-override": "^2.3.9",
|
||||
"morgan": "^1.8.2",
|
||||
"request": "^2.81.0",
|
||||
"rss-braider": "^1.2.0",
|
||||
"yargs": "^8.0.2"
|
||||
}
|
||||
}
|
||||
|
1
test/BAEBF3BDF82B8FEF.rss
Normal file
1
test/BAEBF3BDF82B8FEF.rss
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user