From 61889e88c6e71abded059e5b683c618cafed676b Mon Sep 17 00:00:00 2001 From: Jeff Dederick Date: Fri, 15 Dec 2017 11:50:39 -0500 Subject: [PATCH 01/11] initial commit --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4bf1f55..5858db0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # assignment_mad_lib_api Serving up the madness with a Mad Lib API! + +Jeffrey Dederick + +Edwin Yung From e92c6735471e960609ada18ac00aaeb241b01407 Mon Sep 17 00:00:00 2001 From: EdwinYung Date: Fri, 15 Dec 2017 12:23:19 -0500 Subject: [PATCH 02/11] finished login, register, and show user --- .gitignore | 14 + README.md | 2 + app.js | 272 +++ config/.keep | 1 + config/mongoose.json | 13 + helpers/application_helper.js | 19 + helpers/bootstrap_helper.js | 13 + helpers/flash_helper.js | 14 + helpers/index.js | 9 + helpers/lodash_helper.js | 19 + helpers/math_helper.js | 14 + helpers/utils_helper.js | 93 + lib/.keep | 0 models/.keep | 0 models/index.js | 19 + models/user.js | 73 + mongo.js | 11 + package-lock.json | 2500 +++++++++++++++++++++++ package.json | 56 + public/assets/stylesheets/css/style.css | 0 public/favicon.ico | Bin 0 -> 318 bytes repl.js | 39 + routers/.keep | 0 routers/users.js | 74 + views/errors/500.handlebars | 14 + views/layouts/application.handlebars | 36 + views/sessions/new.handlebars | 17 + views/shared/.keep | 0 views/shared/_flash.handlebars | 11 + views/shared/_nav.handlebars | 39 + views/users/new.handlebars | 30 + views/users/show.handlebars | 31 + views/welcome/index.handlebars | 1 + 33 files changed, 3434 insertions(+) create mode 100644 .gitignore create mode 100644 app.js create mode 100644 config/.keep create mode 100644 config/mongoose.json create mode 100644 helpers/application_helper.js create mode 100644 helpers/bootstrap_helper.js create mode 100644 helpers/flash_helper.js create mode 100644 helpers/index.js create mode 100644 helpers/lodash_helper.js create mode 100644 helpers/math_helper.js create mode 100644 helpers/utils_helper.js create mode 100644 lib/.keep create mode 100644 models/.keep create mode 100644 models/index.js create mode 100644 models/user.js create mode 100644 mongo.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/assets/stylesheets/css/style.css create mode 100644 public/favicon.ico create mode 100644 repl.js create mode 100644 routers/.keep create mode 100644 routers/users.js create mode 100644 views/errors/500.handlebars create mode 100644 views/layouts/application.handlebars create mode 100644 views/sessions/new.handlebars create mode 100644 views/shared/.keep create mode 100644 views/shared/_flash.handlebars create mode 100644 views/shared/_nav.handlebars create mode 100644 views/users/new.handlebars create mode 100644 views/users/show.handlebars create mode 100644 views/welcome/index.handlebars diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5627a2a --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# ---------------------------------------- +# NPM +# ---------------------------------------- + +node_modules/ +npm-debug.log + + +# ---------------------------------------- +# ENV +# ---------------------------------------- +.env + + diff --git a/README.md b/README.md index 4bf1f55..8e16e1c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # assignment_mad_lib_api Serving up the madness with a Mad Lib API! + +--save request repl bcrypt bluebird body-parser cli-highlight cookie-session express express-flash-messages cookie-parser express-handlebars express-method-override-get-post-support faker furious_spinoff jasmine load-helpers lodash md5 method-override mongoose mongoose-unique-validator mongooseeder morgan morgan-toolkit passport passport-http-bearer passport-local qs uuid voca dotenv diff --git a/app.js b/app.js new file mode 100644 index 0000000..fde33e6 --- /dev/null +++ b/app.js @@ -0,0 +1,272 @@ +const express = require('express'); +const app = express(); + + +// ---------------------------------------- +// App Variables +// ---------------------------------------- +app.locals.appName = 'Mad Libs'; + + +// ---------------------------------------- +// ENV +// ---------------------------------------- +if (process.env.NODE_ENV !== 'production') { + require('dotenv').config(); +} + + +// ---------------------------------------- +// Body Parser +// ---------------------------------------- +const bodyParser = require('body-parser'); +app.use(bodyParser.urlencoded({ extended: true })); + + +// ---------------------------------------- +// Sessions/Cookies +// ---------------------------------------- +const cookieParser = require('cookie-parser'); +const cookieSession = require('cookie-session'); + +app.use(cookieParser()); +app.use(cookieSession({ + name: 'session', + keys: [ + process.env.SESSION_SECRET || 'secret' + ] +})); + +app.use((req, res, next) => { + res.locals.session = req.session; + next(); +}); + + +// ---------------------------------------- +// Flash Messages +// ---------------------------------------- +const flash = require('express-flash-messages'); +app.use(flash()); + + +// ---------------------------------------- +// Method Override +// ---------------------------------------- +const methodOverride = require('method-override'); +const getPostSupport = require('express-method-override-get-post-support'); + +app.use(methodOverride( + getPostSupport.callback, + getPostSupport.options // { methods: ['POST', 'GET'] } +)); + + +// ---------------------------------------- +// Referrer +// ---------------------------------------- +app.use((req, res, next) => { + req.session.backUrl = req.header('Referer') || '/'; + next(); +}); + + +// ---------------------------------------- +// Public +// ---------------------------------------- +app.use(express.static(`${__dirname}/public`)); + + +// ---------------------------------------- +// Logging +// ---------------------------------------- +const morgan = require('morgan'); +const morganToolkit = require('morgan-toolkit')(morgan, { + req: ['cookies'/*, 'signedCookies' */] +}); + +app.use(morganToolkit()); + + +// ---------------------------------------- +// Mongoose +// ---------------------------------------- +const mongoose = require('mongoose'); +app.use((req, res, next) => { + if (mongoose.connection.readyState) { + next(); + } else { + require('./mongo')().then(() => next()); + } +}); + +// ---------------------------------------- +// Sessions +// ---------------------------------------- +// Require passport, strategies and User model +const passport = require('passport'); +const LocalStrategy = require('passport-local').Strategy; +const BearerStrategy = require('passport-http-bearer').Strategy; +const User = require('./models').User; + +// Initialize passport +app.use(passport.initialize()); +app.use(passport.session()); + +// Create local strategy +const localStrategy = new LocalStrategy({ + + // Set username field to email + // to match form + usernameField: 'email' +}, (email, password, done) => { + + // Find user by email + User.findOne({ email: email }) + .then(user => { + + // The user is valid if the password is valid + const isValid = user.validatePassword(password); + + // If the user is valid pass the user + // to the done callback + // Else pass false + return done(null, isValid ? user : false); + }) + .catch(e => done(null, false)); +}); + +// Create the token bearer strategy +const bearerStrategy = new BearerStrategy((token, done) => { + + // Find the user by token + User.findOne({ token: token }) + .then(user => { + + // Pass the user if found else false + return done(null, user || false); + }) + .catch(e => done(null, false)); +}); + +// Use the strategy middlewares +passport.use(localStrategy); +passport.use(bearerStrategy); + +// Serialize and deserialize the user +// with the user ID +passport.serializeUser((user, done) => done(null, user.id)); +passport.deserializeUser((id, done) => { + + // Find the user in the database + User.findById(id) + .then(user => done(null, user)) + .catch(e => done(null, false)); +}); + +// ---------------------------------------- +// Session Helper Middlewares +// ---------------------------------------- + +// Set up middleware to allow/disallow login/logout +const loggedInOnly = (req, res, next) => { + return req.user ? next() : res.redirect('/login'); +}; + +const loggedOutOnly = (req, res, next) => { + return !req.user ? next() : res.redirect('/'); +}; + +// Show login only if logged out +app.get('/login', loggedOutOnly, (req, res) => { + res.render('sessions/new'); +}); + +// Allow logout via GET and DELETE +const onLogout = (req, res) => { + + // Passport convenience method to logout + req.logout(); + + // Ensure always redirecting as GET + req.method = 'GET'; + res.redirect('/login'); +}; + +app.get('/logout', loggedInOnly, onLogout); + +app.delete('/logout', loggedInOnly, onLogout); + +// Create session with passport +app.post('/sessions', passport.authenticate('local', { + successRedirect: '/', + failureRedirect: '/login', + failureFlash: true +})); + +// ---------------------------------------- +// Routes +// ---------------------------------------- + +const usersRouter = require('./routers/users')({ + loggedInOnly, + loggedOutOnly +}); +app.use('/', usersRouter); + + + +// ---------------------------------------- +// Template Engine +// ---------------------------------------- +const expressHandlebars = require('express-handlebars'); +const helpers = require('./helpers'); + +const hbs = expressHandlebars.create({ + helpers: helpers, + partialsDir: 'views/', + defaultLayout: 'application' +}); + +app.engine('handlebars', hbs.engine); +app.set('view engine', 'handlebars'); + + +// ---------------------------------------- +// Server +// ---------------------------------------- +const port = process.env.PORT || + process.argv[2] || + 3000; +const host = 'localhost'; + +let args; +process.env.NODE_ENV === 'production' ? + args = [port] : + args = [port, host]; + +args.push(() => { + console.log(`Listening: http://${ host }:${ port }\n`); +}); + +if (require.main === module) { + app.listen.apply(app, args); +} + + +// ---------------------------------------- +// Error Handling +// ---------------------------------------- +app.use((err, req, res, next) => { + if (res.headersSent) { + return next(err); + } + + if (err.stack) { + err = err.stack; + } + res.status(500).render('errors/500', { error: err }); +}); + + +module.exports = app; diff --git a/config/.keep b/config/.keep new file mode 100644 index 0000000..4f07f1c --- /dev/null +++ b/config/.keep @@ -0,0 +1 @@ +.keep \ No newline at end of file diff --git a/config/mongoose.json b/config/mongoose.json new file mode 100644 index 0000000..ed152ee --- /dev/null +++ b/config/mongoose.json @@ -0,0 +1,13 @@ +{ + "development": { + "database": "assignment_mad_lib_api_development", + "host": "localhost" + }, + "test": { + "database": "assignment_mad_lib_api_test", + "host": "localhost" + }, + "production": { + "use_env_variable": "MONGO_URL" + } +} diff --git a/helpers/application_helper.js b/helpers/application_helper.js new file mode 100644 index 0000000..6ab3bcf --- /dev/null +++ b/helpers/application_helper.js @@ -0,0 +1,19 @@ +const ApplicationHelper = {}; + + +ApplicationHelper.rootPath = () => '/'; +ApplicationHelper.CSSID = (...args) => { + let n = args.length; + let options = args[n - 1]; + let viewPath = options.data.exphbs.view; + let id = viewPath.split('/').join('-'); + return id; +}; + + +module.exports = ApplicationHelper; + + + + + diff --git a/helpers/bootstrap_helper.js b/helpers/bootstrap_helper.js new file mode 100644 index 0000000..7e1b39f --- /dev/null +++ b/helpers/bootstrap_helper.js @@ -0,0 +1,13 @@ +const BootstrapHelper = {}; + + +BootstrapHelper.glyphicon = type => { + return `` +}; + + + +module.exports = BootstrapHelper; diff --git a/helpers/flash_helper.js b/helpers/flash_helper.js new file mode 100644 index 0000000..a025dd0 --- /dev/null +++ b/helpers/flash_helper.js @@ -0,0 +1,14 @@ +const FlashHelper = {}; + + +FlashHelper.bootstrapAlertClassFor = key => { + return { + "error": "danger", + "alert": "danger", + "notice": "info" + }[key] || key; +}; + + +module.exports = FlashHelper; + diff --git a/helpers/index.js b/helpers/index.js new file mode 100644 index 0000000..aeb43ff --- /dev/null +++ b/helpers/index.js @@ -0,0 +1,9 @@ +const LoadHelpers = require('load-helpers'); +const helperLoader = new LoadHelpers(); +const helpers = helperLoader.load('helpers/*_helper.js').cache; + +module.exports = helpers; + + + + diff --git a/helpers/lodash_helper.js b/helpers/lodash_helper.js new file mode 100644 index 0000000..18364fd --- /dev/null +++ b/helpers/lodash_helper.js @@ -0,0 +1,19 @@ +const _ = require('lodash'); + + +const LodashHelper = {}; + + +LodashHelper.isEmpty = _.isEmpty; +LodashHelper.size = _.size; + + + +module.exports = LodashHelper; + + + + + + + diff --git a/helpers/math_helper.js b/helpers/math_helper.js new file mode 100644 index 0000000..aa61dab --- /dev/null +++ b/helpers/math_helper.js @@ -0,0 +1,14 @@ + +const MathHelper = {}; + + +MathHelper.add = (a, b) => a + b; +MathHelper.sub = (a, b) => a - b; +MathHelper.div = (a, b) => a / b; +MathHelper.mult = (a, b) => a * b; + + + +module.exports = MathHelper; + + diff --git a/helpers/utils_helper.js b/helpers/utils_helper.js new file mode 100644 index 0000000..db99ae3 --- /dev/null +++ b/helpers/utils_helper.js @@ -0,0 +1,93 @@ + + + +const UtilsHelper = {}; + + +UtilsHelper.concat = (...args) => args.slice(0, -1).join(''); + + +UtilsHelper.join = (str, ...args) => args.slice(0, -1).join(str); + + +UtilsHelper.debug = obj => `
${ JSON.stringify(obj, null, 2) }
`; + + +UtilsHelper.json = obj => JSON.stringify(obj, null, 2); + + +UtilsHelper.eq = (a, b) => a == b; + + +UtilsHelper.eql = (a, b) => a === b; + + +UtilsHelper.gt = (a, b) => a > b; + + +UtilsHelper.gte = (a, b) => a >= b; + + +UtilsHelper.lt = (a, b) => a < b; + + +UtilsHelper.lte = (a, b) => a <= b; + + +UtilsHelper.times = function(n, options) { + if (typeof n === 'object') { + options = n; + } + + let start; + let stop; + let step; + let direction; + + if (options.hash && Object.keys(options.hash).length) { + start = options.hash.start; + stop = options.hash.stop; + step = options.hash.step; + direction = options.hash.direction; + step = step || 1; + direction = direction || 1; + } else { + start = 0; + stop = n - 1; + step = 1; + direction = 1; + } + + if (options.hash.start && + options.hash.stop) { + start = options.hash.start; + stop = options.hash.stop; + } + + let output = ''; + + for (let i = start; i <= stop; i += (step * direction)) { + output += options.fn(this, { + data: { index: i }, + blockParams: [i] + }); + } + + return output; +}; + + + +module.exports = UtilsHelper; + + + + + + + + + + + + diff --git a/lib/.keep b/lib/.keep new file mode 100644 index 0000000..e69de29 diff --git a/models/.keep b/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/models/index.js b/models/index.js new file mode 100644 index 0000000..c65a53a --- /dev/null +++ b/models/index.js @@ -0,0 +1,19 @@ +const mongoose = require('mongoose'); +const bluebird = require('bluebird'); + +mongoose.Promise = bluebird; + +// Enable logging if not testing +(process.env.NODE_ENV === 'test') || + mongoose.set('debug', true); + + +const models = {}; + + +models.User = require('./user'); + + + + +module.exports = models; diff --git a/models/user.js b/models/user.js new file mode 100644 index 0000000..b989851 --- /dev/null +++ b/models/user.js @@ -0,0 +1,73 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; +const uniqueValidator = require('mongoose-unique-validator'); +const bcrypt = require('bcrypt'); +const md5 = require('md5'); +const uuid = require('uuid/v4'); + + +const UserSchema = new Schema({ + fname: { + type: String, + required: true + }, + lname:{ + type: String, + required: true + }, + email: { + type: String, + required: true, + unique: true + }, + hashedPassword: { + type: String, + required: true + }, + token: { + type: String, + unique: true + } +}, { + timestamps: true +}); + + +UserSchema.plugin(uniqueValidator); + + +UserSchema.virtual('password').set(function(value) { + this._password = value; + this.hashedPassword = bcrypt.hashSync(value, 8); +}); + + +UserSchema.virtual('password').get(function() { + return this.hashedPassword; +}); + + +UserSchema.path('hashedPassword').validate(function(val) { + if (this._password.length < 8) { + this.invalidate('password', 'Password must be at least 8 characters'); + } +}); + + +UserSchema.methods.validatePassword = function(password) { + return bcrypt.compareSync(password, this.hashedPassword); +}; + +//Create token before save +UserSchema.pre('save', function(next) { + this.token = md5(`${ this.email }${ uuid() }`); + next(); +}); + + +const User = mongoose.model('User', UserSchema); + + + + +module.exports = User; diff --git a/mongo.js b/mongo.js new file mode 100644 index 0000000..f818ee3 --- /dev/null +++ b/mongo.js @@ -0,0 +1,11 @@ +var mongoose = require('mongoose'); +var env = process.env.NODE_ENV || 'development'; +var config = require('./config/mongoose')[env]; + + +module.exports = () => { + var envUrl = process.env[config.use_env_variable]; + var localUrl = `mongodb://${ config.host }/${ config.database }`; + var mongoUrl = envUrl ? envUrl : localUrl; + return mongoose.connect(mongoUrl); +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a1b0b66 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2500 @@ +{ + "name": "assignment_mad_lib_api", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/node": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.1.tgz", + "integrity": "sha512-SrmAO+NhnsuG/6TychSl2VdxBZiw/d6V+8j+DFo8O3PwFi+QeYXWHhAw+b170aSc6zYab6/PjEWRZHIDN9mNUw==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", + "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", + "requires": { + "mime-types": "2.1.17", + "negotiator": "0.6.1" + } + }, + "ajv": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz", + "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=", + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "requires": { + "color-convert": "1.9.1" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "apparatus": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/apparatus/-/apparatus-0.0.9.tgz", + "integrity": "sha1-N9zSWDStC2UQdllikduCPusZCL0=", + "requires": { + "sylvester": "0.0.21" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.3" + } + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "articles": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/articles/-/articles-0.2.1.tgz", + "integrity": "sha1-wOEBAxuDPb0L3HegrgZQLYIaRSA=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "async-array-reduce": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/async-array-reduce/-/async-array-reduce-0.2.1.tgz", + "integrity": "sha1-yL4BCitc0A3qlsgRFgNGk9/dgtE=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "basic-auth": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz", + "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "bcrypt": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-1.0.3.tgz", + "integrity": "sha512-pRyDdo73C8Nim3jwFJ7DWe3TZCgwDfWZ6nHS5LSdU77kWbj1frruvdndP02AOavtD4y8v6Fp2dolbHgp4SDrfg==", + "requires": { + "nan": "2.6.2", + "node-pre-gyp": "0.6.36" + } + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "2.0.3" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.1", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.15" + } + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "requires": { + "hoek": "4.2.0" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "bson": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz", + "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw=" + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + }, + "chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" + }, + "cli-highlight": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-1.2.3.tgz", + "integrity": "sha512-cmc4Y2kJuEpT2KZd9pgWWskpDMMfJu2roIcY1Ya/aIItufF5FKsV/NtA6vvdhSUllR8KJfvQDNmIcskU+MKLDg==", + "requires": { + "chalk": "2.3.0", + "highlight.js": "9.12.0", + "mz": "2.7.0", + "parse5": "3.0.3", + "yargs": "10.0.3" + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6" + } + }, + "cookie-session": { + "version": "2.0.0-beta.3", + "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.0.0-beta.3.tgz", + "integrity": "sha512-zyqm5tA0z9yMEB/xyP7lnRnqp8eLR2e0dap+9+rBwVigla9yPKn8XTL1jJymog8xjfrowqW2o5LUjixQChkqrw==", + "requires": { + "cookies": "0.7.1", + "debug": "3.1.0", + "on-headers": "1.0.1", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "cookies": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.1.tgz", + "integrity": "sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=", + "requires": { + "depd": "1.1.1", + "keygrip": "1.0.2" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dotenv": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" + }, + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "requires": { + "os-homedir": "1.0.2" + } + }, + "express": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "requires": { + "accepts": "1.3.4", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "1.1.1", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "finalhandler": "1.1.0", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "2.0.2", + "qs": "6.5.1", + "range-parser": "1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.1", + "serve-static": "1.13.1", + "setprototypeof": "1.1.0", + "statuses": "1.3.1", + "type-is": "1.6.15", + "utils-merge": "1.0.1", + "vary": "1.1.2" + }, + "dependencies": { + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + } + } + }, + "express-flash-messages": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/express-flash-messages/-/express-flash-messages-0.1.1.tgz", + "integrity": "sha1-QCDOUXjDuzZjlN6QZiILwnBb1vI=" + }, + "express-handlebars": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-3.0.0.tgz", + "integrity": "sha1-gKBwu4GbCeSvLKbQeA91zgXnXC8=", + "requires": { + "glob": "6.0.4", + "graceful-fs": "4.1.11", + "handlebars": "4.0.11", + "object.assign": "4.0.4", + "promise": "7.3.1" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "express-method-override-get-post-support": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/express-method-override-get-post-support/-/express-method-override-get-post-support-1.0.0.tgz", + "integrity": "sha512-uBS1tJsdoRgTa3ujiJRXC1z6haAdSccZs1tH0a4NTpm9dm598xgM/C7rg+x3qPf14GLQf90h6ltsQ4x68zkt/Q==" + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "0.1.1" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "faker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", + "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=" + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" + }, + "dependencies": { + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + } + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "2.0.0" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "furious_spinoff": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/furious_spinoff/-/furious_spinoff-1.0.4.tgz", + "integrity": "sha1-psEbXlL6IjZfEhXTbyq2e5y3e1w=", + "requires": { + "faker": "4.1.0" + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "requires": { + "global-prefix": "0.1.5", + "is-windows": "0.2.0" + } + }, + "global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "requires": { + "homedir-polyfill": "1.0.1", + "ini": "1.3.5", + "is-windows": "0.2.0", + "which": "1.3.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "handlebars": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "5.5.1", + "har-schema": "2.0.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "has-glob": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-0.1.1.tgz", + "integrity": "sha1-omHEwqbGZ+DHe3AKfyl8Oe86pYk=", + "requires": { + "is-glob": "2.0.1" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + } + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" + } + }, + "highlight.js": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz", + "integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=" + }, + "hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "1.0.0" + } + }, + "hooks-fixed": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.2.tgz", + "integrity": "sha512-YurCM4gQSetcrhwEtpQHhQ4M7Zo7poNGqY4kQGeBS6eZtOcT3tnNs01ThFa0jYBByAiYt1MjMjP/YApG0EnAvQ==" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "ipaddr.js": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", + "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "2.1.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-valid-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", + "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=" + }, + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", + "requires": { + "exit": "0.1.2", + "glob": "7.1.2", + "jasmine-core": "2.8.0" + } + }, + "jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kareem": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.5.0.tgz", + "integrity": "sha1-4+QQHZ3P3imXadr0tNtk2JXRdEg=" + }, + "keygrip": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.2.tgz", + "integrity": "sha1-rTKXxVcGneqLz+ek+kkbdcXd65E=" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.6" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "optional": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "1.0.0" + } + }, + "load-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/load-helpers/-/load-helpers-1.0.1.tgz", + "integrity": "sha1-ZoEbwF/PBwSO9w9lRzC0Ip5qrLM=", + "requires": { + "component-emitter": "1.2.1", + "extend-shallow": "2.0.1", + "is-glob": "3.1.0", + "is-valid-glob": "0.3.0", + "kind-of": "3.2.2", + "matched": "0.4.4", + "resolve-dir": "0.1.1", + "set-value": "0.4.3" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "matched": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/matched/-/matched-0.4.4.tgz", + "integrity": "sha1-Vte36xgDPwz5vFLrIJD6x9weifo=", + "requires": { + "arr-union": "3.1.0", + "async-array-reduce": "0.2.1", + "extend-shallow": "2.0.1", + "fs-exists-sync": "0.1.0", + "glob": "7.1.2", + "has-glob": "0.1.1", + "is-valid-glob": "0.3.0", + "lazy-cache": "2.0.2", + "resolve-dir": "0.1.1" + }, + "dependencies": { + "lazy-cache": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", + "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", + "requires": { + "set-getter": "0.1.0" + } + } + } + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "1.1.6" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "1.1.0" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "method-override": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.10.tgz", + "integrity": "sha1-49r41d7hDdLc59SuiNYrvud0drQ=", + "requires": { + "debug": "2.6.9", + "methods": "1.1.2", + "parseurl": "1.3.2", + "vary": "1.1.2" + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "minipass": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.1.tgz", + "integrity": "sha512-u1aUllxPJUI07cOqzR7reGmQxmCqlH88uIIsf6XZFEWgw7gXKpJdR+5R9Y3KEDmWYkdIz9wXZs3C0jOPxejk/Q==", + "requires": { + "yallist": "3.0.2" + }, + "dependencies": { + "yallist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + } + } + }, + "minizlib": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.0.4.tgz", + "integrity": "sha512-sN4U9tIJtBRwKbwgFh9qJfrPIQ/GGTRr1MGqkgOeMTLy8/lM0FcWU//FqlnZ3Vb7gJ+Mxh3FOg1EklibdajbaQ==", + "requires": { + "minipass": "2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mongodb": { + "version": "2.2.33", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.33.tgz", + "integrity": "sha1-tTfEcdNKZlG0jzb9vyl1A0Dgi1A=", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.17", + "readable-stream": "2.2.7" + }, + "dependencies": { + "readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + } + } + }, + "mongodb-core": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.17.tgz", + "integrity": "sha1-pBizN6FKFJkPtRC5I97mqBMXPfg=", + "requires": { + "bson": "1.0.4", + "require_optional": "1.0.1" + } + }, + "mongoose": { + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.13.7.tgz", + "integrity": "sha512-3VPcGQWaTzT/OVK+TpE9dGpNHBnEqFX2RmbFr1XvbsKmxPsL9kaRBSHqaQ8QEMd6CUeOYMRdH1pKRrlnCenRsg==", + "requires": { + "async": "2.1.4", + "bson": "1.0.4", + "hooks-fixed": "2.0.2", + "kareem": "1.5.0", + "lodash.get": "4.4.2", + "mongodb": "2.2.33", + "mpath": "0.3.0", + "mpromise": "0.5.5", + "mquery": "2.3.3", + "ms": "2.0.0", + "muri": "1.3.0", + "regexp-clone": "0.0.1", + "sliced": "1.0.1" + }, + "dependencies": { + "async": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz", + "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=", + "requires": { + "lodash": "4.17.4" + } + } + } + }, + "mongoose-unique-validator": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/mongoose-unique-validator/-/mongoose-unique-validator-1.0.6.tgz", + "integrity": "sha512-hJf1eiWPw9O5ed7HUtFHtHhqnWDpm42Q5iC3xs6p99kr1qrVMq8WR2x+yobx6rY5F26Ki2NqGvJTe8v/Fax0kw==", + "requires": { + "lodash.foreach": "4.5.0", + "lodash.get": "4.4.2" + } + }, + "mongooseeder": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/mongooseeder/-/mongooseeder-2.0.6.tgz", + "integrity": "sha512-pfOCHcor9JUgbsY1awb5w9mG1MmyO7sECjgd9esv70LJC5/zTANmZd3GXWWucdIC6GR+qIqdzjMxWKXq4/eVYA==" + }, + "morgan": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", + "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=", + "requires": { + "basic-auth": "2.0.0", + "debug": "2.6.9", + "depd": "1.1.1", + "on-finished": "2.3.0", + "on-headers": "1.0.1" + } + }, + "morgan-toolkit": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/morgan-toolkit/-/morgan-toolkit-1.0.2.tgz", + "integrity": "sha512-tFhfamRSNrnGlaVfY384lFyeHZl8Y4IwSt2219+6YEuVeEJKVBlAQHT/NSAF5hlHrloI0G578zRy0Hxv4Iv10Q==", + "requires": { + "chalk": "2.3.0", + "cli-highlight": "1.2.3" + } + }, + "mpath": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.3.0.tgz", + "integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q=" + }, + "mpromise": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz", + "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY=" + }, + "mquery": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.3.tgz", + "integrity": "sha512-NC8L14kn+qxJbbJ1gbcEMDxF0sC3sv+1cbRReXXwVvowcwY1y9KoVZFq0ebwARibsadu8lx8nWGvm3V0Pf0ZWQ==", + "requires": { + "bluebird": "3.5.0", + "debug": "2.6.9", + "regexp-clone": "0.0.1", + "sliced": "0.0.5" + }, + "dependencies": { + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + }, + "sliced": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", + "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "muri": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/muri/-/muri-1.3.0.tgz", + "integrity": "sha512-FiaFwKl864onHFFUV/a2szAl7X0fxVlSKNdhTf+BM8i8goEgYut8u5P9MqQqIYwvaMxjzVESsoEm/2kfkFH1rg==" + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "requires": { + "any-promise": "1.3.0", + "object-assign": "4.1.1", + "thenify-all": "1.6.0" + } + }, + "nan": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", + "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=" + }, + "natural": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/natural/-/natural-0.1.29.tgz", + "integrity": "sha1-WaN6bNhtVekEtlbTudpD/S3J4Eo=", + "requires": { + "apparatus": "0.0.9", + "sylvester": "0.0.21", + "underscore": "1.8.3" + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "node-pre-gyp": { + "version": "0.6.36", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz", + "integrity": "sha1-22BBEst04NR3VU6bUFsXq936t4Y=", + "requires": { + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.2", + "rc": "1.2.2", + "request": "2.83.0", + "rimraf": "2.6.2", + "semver": "5.4.1", + "tar": "2.2.1", + "tar-pack": "3.4.1" + } + }, + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "requires": { + "abbrev": "1.1.1", + "osenv": "0.1.4" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "2.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" + }, + "object.assign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz", + "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=", + "requires": { + "define-properties": "1.1.2", + "function-bind": "1.1.1", + "object-keys": "1.0.11" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=" + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "1.1.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "requires": { + "@types/node": "8.5.1" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "passport": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", + "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", + "requires": { + "passport-strategy": "1.0.0", + "pause": "0.0.1" + } + }, + "passport-http-bearer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/passport-http-bearer/-/passport-http-bearer-1.0.1.tgz", + "integrity": "sha1-FHRp6jZp4qhMYWfvmdu3fh8AmKg=", + "requires": { + "passport-strategy": "1.0.0" + } + }, + "passport-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", + "requires": { + "passport-strategy": "1.0.0" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "prng-well1024a": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prng-well1024a/-/prng-well1024a-1.0.1.tgz", + "integrity": "sha1-Bejtkj5OorP3ivXulPBWtNXPqyQ=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "2.0.6" + } + }, + "proxy-addr": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", + "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.5.2" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "randy": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/randy/-/randy-1.5.1.tgz", + "integrity": "sha1-59wIag7Li+99ZzVmQs0qM/liRlw=", + "requires": { + "prng-well1024a": "1.0.1" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", + "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "regexp-clone": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", + "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "request": { + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "2.0.0", + "semver": "5.4.1" + } + }, + "resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "requires": { + "expand-tilde": "1.2.2", + "global-modules": "0.2.3" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "optional": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "send": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", + "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "requires": { + "debug": "2.6.9", + "depd": "1.1.1", + "destroy": "1.0.4", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" + }, + "dependencies": { + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + } + } + }, + "sentencer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/sentencer/-/sentencer-0.1.5.tgz", + "integrity": "sha1-HDURWBoAsiNhJ/+yH94X9PSGWeI=", + "requires": { + "articles": "0.2.1", + "lodash": "2.4.2", + "natural": "0.1.29", + "randy": "1.5.1" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=" + } + } + }, + "serve-static": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "requires": { + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.16.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-getter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", + "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", + "requires": { + "to-object-path": "0.3.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "requires": { + "hoek": "4.2.0" + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": "1.0.1" + } + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "requires": { + "has-flag": "2.0.0" + } + }, + "sylvester": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/sylvester/-/sylvester-0.0.21.tgz", + "integrity": "sha1-KYexzivS84sNzio0OIiEv6RADqc=" + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz", + "integrity": "sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg==", + "requires": { + "debug": "2.6.9", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.3.3", + "rimraf": "2.6.2", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "thenify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", + "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "requires": { + "any-promise": "1.3.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "requires": { + "thenify": "3.3.0" + } + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "3.2.2" + } + }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.17" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "optional": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "optional": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "optional": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "optional": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "voca": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/voca/-/voca-1.3.1.tgz", + "integrity": "sha512-wnWynM+Q3Zvoa+AOdQMrKfNNOhshXP1YJHUZta5iUthSrQ3Jjhsyr7s1rzEWw0PkqUDDjCEqdwCz4fHC4jnoow==" + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "requires": { + "string-width": "1.0.2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "optional": true + }, + "wordnet-db": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/wordnet-db/-/wordnet-db-3.1.6.tgz", + "integrity": "sha1-75kaOOmGq5HhsDai+ZF5jBNiD5g=", + "requires": { + "tar": "3.2.1" + }, + "dependencies": { + "tar": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-3.2.1.tgz", + "integrity": "sha512-ZSzds1E0IqutvMU8HxjMaU8eB7urw2fGwTq88ukDOVuUIh0656l7/P7LiVPxhO5kS4flcRJQk8USG+cghQbTUQ==", + "requires": { + "chownr": "1.0.1", + "minipass": "2.2.1", + "minizlib": "1.0.4", + "mkdirp": "0.5.1", + "yallist": "3.0.2" + } + }, + "yallist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + } + } + }, + "wordpos": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wordpos/-/wordpos-1.1.5.tgz", + "integrity": "sha1-FzXIjAhGbwUpc1jij3JUEiQMzvc=", + "requires": { + "commander": "2.12.2", + "underscore": "1.8.3", + "wordnet-db": "3.1.6" + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.0.3.tgz", + "integrity": "sha512-DqBpQ8NAUX4GyPP/ijDGHsJya4tYqLQrjPr95HNsr1YwL3+daCfvBwg7+gIC6IdJhR2kATh3hb61vjzMWEtjdw==", + "requires": { + "cliui": "3.2.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "8.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.0.0.tgz", + "integrity": "sha1-IdR2Mw5agieaS4gTRb8GYQLiGcY=", + "requires": { + "camelcase": "4.1.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..0dbf3f9 --- /dev/null +++ b/package.json @@ -0,0 +1,56 @@ +{ + "name": "assignment_mad_lib_api", + "version": "1.0.0", + "description": "Serving up the madness with a Mad Lib API!", + "main": "app.js", + "directories": { + "lib": "lib" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/edwinyung/assignment_mad_lib_api.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/edwinyung/assignment_mad_lib_api/issues" + }, + "homepage": "https://github.com/edwinyung/assignment_mad_lib_api#readme", + "dependencies": { + "bcrypt": "^1.0.3", + "bluebird": "^3.5.1", + "body-parser": "^1.18.2", + "cli-highlight": "^1.2.3", + "cookie-parser": "^1.4.3", + "cookie-session": "^2.0.0-beta.3", + "dotenv": "^4.0.0", + "express": "^4.16.2", + "express-flash-messages": "^0.1.1", + "express-handlebars": "^3.0.0", + "express-method-override-get-post-support": "^1.0.0", + "faker": "^4.1.0", + "furious_spinoff": "^1.0.4", + "jasmine": "^2.8.0", + "load-helpers": "^1.0.1", + "lodash": "^4.17.4", + "md5": "^2.2.1", + "method-override": "^2.3.10", + "mongoose": "^4.13.7", + "mongoose-unique-validator": "^1.0.6", + "mongooseeder": "^2.0.6", + "morgan": "^1.9.0", + "morgan-toolkit": "^1.0.2", + "passport": "^0.4.0", + "passport-http-bearer": "^1.0.1", + "passport-local": "^1.0.0", + "qs": "^6.5.1", + "request": "^2.83.0", + "sentencer": "^0.1.5", + "uuid": "^3.1.0", + "voca": "^1.3.1", + "wordpos": "^1.1.5" + } +} diff --git a/public/assets/stylesheets/css/style.css b/public/assets/stylesheets/css/style.css new file mode 100644 index 0000000..e69de29 diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..16456511652dc03aea35abada151e76a6b98711c GIT binary patch literal 318 zcmbV{F%H5o3`Jk0?u4at$DX3sVgLz--m5o(8$dS(1nvKBqY8-$N467xfBOfLPR?1e zqD@c(tvt&cx$Cw|#3dLjHudH9Pu|PK)85z^gRLk`sxX|aPJ)zG5xnmIk-zaWCqCmD iQ80ViJMQ4|gxd>-H=H^+Ug2 { + + // ---------------------------------------- + // Models/Helpers + // ---------------------------------------- + repl.context.models = models; + repl.context.helpers = helpers; + + + // ---------------------------------------- + // Mongoose + // ---------------------------------------- + Object.keys(models).forEach((key) => { + repl.context[key] = mongoose.model(key); + }); + + + // ---------------------------------------- + // Libs + // ---------------------------------------- + repl.context.faker = faker; + repl.context.md5 = md5; + repl.context.uuid = uuid; + + + // ---------------------------------------- + // Logging + // ---------------------------------------- + repl.context.lg = console.log; +}); diff --git a/routers/.keep b/routers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/routers/users.js b/routers/users.js new file mode 100644 index 0000000..e895c62 --- /dev/null +++ b/routers/users.js @@ -0,0 +1,74 @@ +// routers/users.js + +const express = require('express'); +const router = express.Router(); +const mongoose = require('mongoose'); +const models = require('./../models'); +const User = mongoose.model('User'); +const helpers = require('./../helpers'); +const h = helpers.registered; + + +module.exports = (middlewares) => { + + // Extract middlewares + const { + loggedInOnly, + loggedOutOnly + } = middlewares; + + // ---------------------------------------- + // Show + // ---------------------------------------- + const onShow = (req, res) => { + res.render('users/show', { currentUser: req.user }); + }; + + // Showing a user only if logged in + router.get('/', loggedInOnly, onShow); + router.get('/user', loggedInOnly, onShow); + + + // ---------------------------------------- + // New + // ---------------------------------------- + + // Allow user registration only if logged out + router.get('/user/new', loggedOutOnly, (req, res) => { + res.render('users/new'); + }); + + + // ---------------------------------------- + // Create + // ---------------------------------------- + + // Allow user creation only if logged out + router.post('/users', loggedOutOnly, (req, res, next) => { + let userParams = { + fname: req.body.user.fname, + lname: req.body.user.lname, + email: req.body.user.email, + password: req.body.user.password + }; + + User.create(userParams) + .then((user) => { + req.flash('success', 'User created! You may now login.'); + res.redirect('/login'); + }) + .catch((e) => { + if (e.errors) { + Object.keys(e.errors).forEach((key) => { + req.flash('error', `${ e.errors[key].message }`); + res.redirect(req.session.backUrl); + }); + } else { + next(e); + } + }); + }); + + + return router; +}; diff --git a/views/errors/500.handlebars b/views/errors/500.handlebars new file mode 100644 index 0000000..c968333 --- /dev/null +++ b/views/errors/500.handlebars @@ -0,0 +1,14 @@ + +
+ +
+
{{ error }}
+
+ + + + + + diff --git a/views/layouts/application.handlebars b/views/layouts/application.handlebars new file mode 100644 index 0000000..1e8caba --- /dev/null +++ b/views/layouts/application.handlebars @@ -0,0 +1,36 @@ + + + + + + + + {{ appName }} + {{#if title }} + | {{ title }} + {{/if }} + + + + + + + + + + + + + + + + + + + {{> shared/_nav }} + {{> shared/_flash }} +
+ {{{ body }}} +
+ + diff --git a/views/sessions/new.handlebars b/views/sessions/new.handlebars new file mode 100644 index 0000000..a127e0d --- /dev/null +++ b/views/sessions/new.handlebars @@ -0,0 +1,17 @@ + + +
+
+ + +
+
+ + +
+
+ +
+
diff --git a/views/shared/.keep b/views/shared/.keep new file mode 100644 index 0000000..e69de29 diff --git a/views/shared/_flash.handlebars b/views/shared/_flash.handlebars new file mode 100644 index 0000000..c162a6a --- /dev/null +++ b/views/shared/_flash.handlebars @@ -0,0 +1,11 @@ + +{{#each getMessages as |messages key| }} + {{#each messages as |message| }} + + {{/each }} +{{/each }} diff --git a/views/shared/_nav.handlebars b/views/shared/_nav.handlebars new file mode 100644 index 0000000..55e3c13 --- /dev/null +++ b/views/shared/_nav.handlebars @@ -0,0 +1,39 @@ + + + diff --git a/views/users/new.handlebars b/views/users/new.handlebars new file mode 100644 index 0000000..d07affc --- /dev/null +++ b/views/users/new.handlebars @@ -0,0 +1,30 @@ + + + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
diff --git a/views/users/show.handlebars b/views/users/show.handlebars new file mode 100644 index 0000000..8eb95bb --- /dev/null +++ b/views/users/show.handlebars @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyValue
First Name{{ currentUser.fname }}
Last Name{{ currentUser.lname }}
Email{{ currentUser.email }}
API Token{{ currentUser.token }}
diff --git a/views/welcome/index.handlebars b/views/welcome/index.handlebars new file mode 100644 index 0000000..7ab6572 --- /dev/null +++ b/views/welcome/index.handlebars @@ -0,0 +1 @@ +

Hello Express!

\ No newline at end of file From 075714fb8e5eafb172fa5b4edcc2581d82b4398e Mon Sep 17 00:00:00 2001 From: Jeff Dederick Date: Fri, 15 Dec 2017 13:37:29 -0500 Subject: [PATCH 03/11] jasmine tests initialized --- app.js | 186 ++++++++++++++-------------- models/user.js | 2 +- package-lock.json | 233 +----------------------------------- package.json | 9 +- routers/index.js | 20 ++++ seeds/clean.js | 26 ++++ spec/app_spec.js | 69 +++++++++++ spec/helpers/spec_helper.js | 22 ++++ spec/support/jasmine.json | 11 ++ 9 files changed, 247 insertions(+), 331 deletions(-) create mode 100644 routers/index.js create mode 100644 seeds/clean.js create mode 100644 spec/app_spec.js create mode 100644 spec/helpers/spec_helper.js create mode 100644 spec/support/jasmine.json diff --git a/app.js b/app.js index fde33e6..00a5bcd 100644 --- a/app.js +++ b/app.js @@ -1,102 +1,94 @@ -const express = require('express'); +const express = require("express"); const app = express(); - // ---------------------------------------- // App Variables // ---------------------------------------- -app.locals.appName = 'Mad Libs'; - +app.locals.appName = "Mad Libs"; // ---------------------------------------- // ENV // ---------------------------------------- -if (process.env.NODE_ENV !== 'production') { - require('dotenv').config(); +if (process.env.NODE_ENV !== "production") { + require("dotenv").config(); } - // ---------------------------------------- // Body Parser // ---------------------------------------- -const bodyParser = require('body-parser'); +const bodyParser = require("body-parser"); app.use(bodyParser.urlencoded({ extended: true })); - // ---------------------------------------- // Sessions/Cookies // ---------------------------------------- -const cookieParser = require('cookie-parser'); -const cookieSession = require('cookie-session'); +const cookieParser = require("cookie-parser"); +const cookieSession = require("cookie-session"); app.use(cookieParser()); -app.use(cookieSession({ - name: 'session', - keys: [ - process.env.SESSION_SECRET || 'secret' - ] -})); +app.use( + cookieSession({ + name: "session", + keys: [process.env.SESSION_SECRET || "secret"] + }) +); app.use((req, res, next) => { res.locals.session = req.session; next(); }); - // ---------------------------------------- // Flash Messages // ---------------------------------------- -const flash = require('express-flash-messages'); +const flash = require("express-flash-messages"); app.use(flash()); - // ---------------------------------------- // Method Override // ---------------------------------------- -const methodOverride = require('method-override'); -const getPostSupport = require('express-method-override-get-post-support'); - -app.use(methodOverride( - getPostSupport.callback, - getPostSupport.options // { methods: ['POST', 'GET'] } -)); +const methodOverride = require("method-override"); +const getPostSupport = require("express-method-override-get-post-support"); +app.use( + methodOverride( + getPostSupport.callback, + getPostSupport.options // { methods: ['POST', 'GET'] } + ) +); // ---------------------------------------- // Referrer // ---------------------------------------- app.use((req, res, next) => { - req.session.backUrl = req.header('Referer') || '/'; + req.session.backUrl = req.header("Referer") || "/"; next(); }); - // ---------------------------------------- // Public // ---------------------------------------- app.use(express.static(`${__dirname}/public`)); - // ---------------------------------------- // Logging // ---------------------------------------- -const morgan = require('morgan'); -const morganToolkit = require('morgan-toolkit')(morgan, { - req: ['cookies'/*, 'signedCookies' */] +const morgan = require("morgan"); +const morganToolkit = require("morgan-toolkit")(morgan, { + req: ["cookies" /*, 'signedCookies' */] }); app.use(morganToolkit()); - // ---------------------------------------- // Mongoose // ---------------------------------------- -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); app.use((req, res, next) => { if (mongoose.connection.readyState) { next(); } else { - require('./mongo')().then(() => next()); + require("./mongo")().then(() => next()); } }); @@ -104,45 +96,43 @@ app.use((req, res, next) => { // Sessions // ---------------------------------------- // Require passport, strategies and User model -const passport = require('passport'); -const LocalStrategy = require('passport-local').Strategy; -const BearerStrategy = require('passport-http-bearer').Strategy; -const User = require('./models').User; +const passport = require("passport"); +const LocalStrategy = require("passport-local").Strategy; +const BearerStrategy = require("passport-http-bearer").Strategy; +const User = require("./models").User; // Initialize passport app.use(passport.initialize()); app.use(passport.session()); // Create local strategy -const localStrategy = new LocalStrategy({ - - // Set username field to email - // to match form - usernameField: 'email' -}, (email, password, done) => { - - // Find user by email - User.findOne({ email: email }) - .then(user => { - - // The user is valid if the password is valid - const isValid = user.validatePassword(password); - - // If the user is valid pass the user - // to the done callback - // Else pass false - return done(null, isValid ? user : false); - }) - .catch(e => done(null, false)); -}); +const localStrategy = new LocalStrategy( + { + // Set username field to email + // to match form + usernameField: "email" + }, + (email, password, done) => { + // Find user by email + User.findOne({ email: email }) + .then(user => { + // The user is valid if the password is valid + const isValid = user.validatePassword(password); + + // If the user is valid pass the user + // to the done callback + // Else pass false + return done(null, isValid ? user : false); + }) + .catch(e => done(null, false)); + } +); // Create the token bearer strategy const bearerStrategy = new BearerStrategy((token, done) => { - // Find the user by token User.findOne({ token: token }) .then(user => { - // Pass the user if found else false return done(null, user || false); }) @@ -157,7 +147,6 @@ passport.use(bearerStrategy); // with the user ID passport.serializeUser((user, done) => done(null, user.id)); passport.deserializeUser((id, done) => { - // Find the user in the database User.findById(id) .then(user => done(null, user)) @@ -170,89 +159,91 @@ passport.deserializeUser((id, done) => { // Set up middleware to allow/disallow login/logout const loggedInOnly = (req, res, next) => { - return req.user ? next() : res.redirect('/login'); + return req.user ? next() : res.redirect("/login"); }; const loggedOutOnly = (req, res, next) => { - return !req.user ? next() : res.redirect('/'); + return !req.user ? next() : res.redirect("/"); }; // Show login only if logged out -app.get('/login', loggedOutOnly, (req, res) => { - res.render('sessions/new'); +app.get("/login", loggedOutOnly, (req, res) => { + res.render("sessions/new"); }); // Allow logout via GET and DELETE const onLogout = (req, res) => { - // Passport convenience method to logout req.logout(); // Ensure always redirecting as GET - req.method = 'GET'; - res.redirect('/login'); + req.method = "GET"; + res.redirect("/login"); }; -app.get('/logout', loggedInOnly, onLogout); +app.get("/logout", loggedInOnly, onLogout); -app.delete('/logout', loggedInOnly, onLogout); +app.delete("/logout", loggedInOnly, onLogout); // Create session with passport -app.post('/sessions', passport.authenticate('local', { - successRedirect: '/', - failureRedirect: '/login', - failureFlash: true -})); +app.post( + "/sessions", + passport.authenticate("local", { + successRedirect: "/", + failureRedirect: "/login", + failureFlash: true + }) +); // ---------------------------------------- // Routes // ---------------------------------------- -const usersRouter = require('./routers/users')({ +const usersRouter = require("./routers/users")({ loggedInOnly, loggedOutOnly }); -app.use('/', usersRouter); - +app.use("/", usersRouter); +const furiousSpinoff = require("./routers/index"); +app.use("/api/v1", furiousSpinoff); // ---------------------------------------- // Template Engine // ---------------------------------------- -const expressHandlebars = require('express-handlebars'); -const helpers = require('./helpers'); +const expressHandlebars = require("express-handlebars"); +const helpers = require("./helpers"); const hbs = expressHandlebars.create({ helpers: helpers, - partialsDir: 'views/', - defaultLayout: 'application' + partialsDir: "views/", + defaultLayout: "application" }); -app.engine('handlebars', hbs.engine); -app.set('view engine', 'handlebars'); - +app.engine("handlebars", hbs.engine); +app.set("view engine", "handlebars"); // ---------------------------------------- // Server // ---------------------------------------- -const port = process.env.PORT || - process.argv[2] || - 3000; -const host = 'localhost'; +const port = process.env.PORT || process.argv[2] || 3000; +const host = "localhost"; let args; -process.env.NODE_ENV === 'production' ? - args = [port] : - args = [port, host]; +process.env.NODE_ENV === "production" ? (args = [port]) : (args = [port, host]); args.push(() => { - console.log(`Listening: http://${ host }:${ port }\n`); + console.log(`Listening: http://${host}:${port}\n`); }); if (require.main === module) { app.listen.apply(app, args); } +// Disable logging in test mode +if (process.env.NODE_ENV !== "test") { + app.use(morgan("tiny")); +} // ---------------------------------------- // Error Handling @@ -265,8 +256,7 @@ app.use((err, req, res, next) => { if (err.stack) { err = err.stack; } - res.status(500).render('errors/500', { error: err }); + res.status(500).render("errors/500", { error: err }); }); - module.exports = app; diff --git a/models/user.js b/models/user.js index b989851..d10b569 100644 --- a/models/user.js +++ b/models/user.js @@ -1,7 +1,7 @@ const mongoose = require('mongoose'); const Schema = mongoose.Schema; const uniqueValidator = require('mongoose-unique-validator'); -const bcrypt = require('bcrypt'); +const bcrypt = require('bcryptjs'); const md5 = require('md5'); const uuid = require('uuid/v4'); diff --git a/package-lock.json b/package-lock.json index a1b0b66..eb476bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.1.tgz", "integrity": "sha512-SrmAO+NhnsuG/6TychSl2VdxBZiw/d6V+8j+DFo8O3PwFi+QeYXWHhAw+b170aSc6zYab6/PjEWRZHIDN9mNUw==" }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, "accepts": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", @@ -75,20 +70,6 @@ "sylvester": "0.0.21" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.3" - } - }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", @@ -157,15 +138,6 @@ "safe-buffer": "5.1.1" } }, - "bcrypt": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-1.0.3.tgz", - "integrity": "sha512-pRyDdo73C8Nim3jwFJ7DWe3TZCgwDfWZ6nHS5LSdU77kWbj1frruvdndP02AOavtD4y8v6Fp2dolbHgp4SDrfg==", - "requires": { - "nan": "2.6.2", - "node-pre-gyp": "0.6.36" - } - }, "bcrypt-pbkdf": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", @@ -175,13 +147,10 @@ "tweetnacl": "0.14.5" } }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "2.0.3" - } + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" }, "bluebird": { "version": "3.5.1", @@ -345,11 +314,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -468,11 +432,6 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, - "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" - }, "define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", @@ -487,11 +446,6 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, "depd": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", @@ -760,27 +714,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.2" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", - "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -794,21 +727,6 @@ "faker": "4.1.0" } }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", @@ -918,11 +836,6 @@ } } }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, "hawk": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", @@ -1513,11 +1426,6 @@ "thenify-all": "1.6.0" } }, - "nan": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", - "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=" - }, "natural": { "version": "0.1.29", "resolved": "https://registry.npmjs.org/natural/-/natural-0.1.29.tgz", @@ -1533,31 +1441,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, - "node-pre-gyp": { - "version": "0.6.36", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz", - "integrity": "sha1-22BBEst04NR3VU6bUFsXq936t4Y=", - "requires": { - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.2", - "rc": "1.2.2", - "request": "2.83.0", - "rimraf": "2.6.2", - "semver": "5.4.1", - "tar": "2.2.1", - "tar-pack": "3.4.1" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.4" - } - }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -1566,17 +1449,6 @@ "path-key": "2.0.1" } }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -1652,20 +1524,6 @@ "mem": "1.1.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", - "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -1828,38 +1686,6 @@ "unpipe": "1.0.0" } }, - "rc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", - "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, "regexp-clone": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", @@ -1941,14 +1767,6 @@ "align-text": "0.1.4" } }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "requires": { - "glob": "7.1.2" - } - }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -2139,11 +1957,6 @@ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, "supports-color": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", @@ -2157,31 +1970,6 @@ "resolved": "https://registry.npmjs.org/sylvester/-/sylvester-0.0.21.tgz", "integrity": "sha1-KYexzivS84sNzio0OIiEv6RADqc=" }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz", - "integrity": "sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg==", - "requires": { - "debug": "2.6.9", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.3.3", - "rimraf": "2.6.2", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, "thenify": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", @@ -2297,11 +2085,6 @@ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "optional": true }, - "uid-number": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", - "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" - }, "underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", @@ -2360,14 +2143,6 @@ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, - "wide-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", - "requires": { - "string-width": "1.0.2" - } - }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", diff --git a/package.json b/package.json index 0dbf3f9..c3b0127 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,11 @@ "lib": "lib" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, + "test": "npm run whichnodemon && nodemon --exec npm run jasmine || npm run jasmine", + "start": "npm run whichnodemon && nodemon app.js || node app.js", + "whichnodemon": "which nodemon > /dev/null", + "jasmine": "./node_modules/jasmine/bin/jasmine.js" +}, "repository": { "type": "git", "url": "git+https://github.com/edwinyung/assignment_mad_lib_api.git" @@ -20,7 +23,7 @@ }, "homepage": "https://github.com/edwinyung/assignment_mad_lib_api#readme", "dependencies": { - "bcrypt": "^1.0.3", + "bcryptjs": "^2.4.3", "bluebird": "^3.5.1", "body-parser": "^1.18.2", "cli-highlight": "^1.2.3", diff --git a/routers/index.js b/routers/index.js new file mode 100644 index 0000000..4c21845 --- /dev/null +++ b/routers/index.js @@ -0,0 +1,20 @@ +const express = require("express"); +const router = express.Router(); +const helpers = require("./../helpers"); +const h = helpers.registered; +const furiousSpinoff = require("furious_spinoff"); + +// ---------------------------------------- +// Index +// ---------------------------------------- +router.get("/furious_spinoffs", (req, res, next) => { + const count = +req.query.count || 10; + const titles = []; + for (let i = 0; i < count; i++) { + titles.push(furiousSpinoff()); + } + res.status(200).json(titles); +}); + +module.exports = router; + diff --git a/seeds/clean.js b/seeds/clean.js new file mode 100644 index 0000000..9dd4863 --- /dev/null +++ b/seeds/clean.js @@ -0,0 +1,26 @@ +const mongoose = require('mongoose'); + + +module.exports = () => { + + // Get all collections + let collections = mongoose + .connection + .collections; + + // Get collection names + let collectionKeys = Object.keys(collections); + + // Store promises + let promises = []; + + // For each collection + collectionKeys.forEach((key) => { + + // Remove all documents + const promise = collections[key].remove(); + promises.push(promise); + }); + + return Promise.all(promises); +}; diff --git a/spec/app_spec.js b/spec/app_spec.js new file mode 100644 index 0000000..7979d4b --- /dev/null +++ b/spec/app_spec.js @@ -0,0 +1,69 @@ +const app = require("../app"); +const request = require("request"); +const mongoose = require("mongoose"); +const User = mongoose.model("User"); +const qs = require("qs"); + +describe("App", () => { + const baseUrl = "http://localhost:8888"; + const apiUrl = baseUrl + "/api/v1/"; + let server; + + let user; + + const apiUrlFor = (type, params) => { + params = params ? `&${qs.stringify(params)}` : ""; + return `${apiUrl}${type}?access_token=${user.token}${params}`; + }; + const j = str => JSON.parse(str); + + beforeAll(done => { + server = app.listen(8888, () => { + done(); + }); + }); + + beforeEach(done => { + User.create({ + fname: "Foo", + lname: "Bar", + email: "foobar@gmail", + password: "password" + }).then(result => { + user = result; + done(); + }); + }); + + afterAll(done => { + server.close(); + server = null; + done(); + }); + + // ---------------------------------------- + // App + // ---------------------------------------- + it("renders the home page", done => { + request.get(baseUrl, (err, res, body) => { + expect(res.statusCode).toBe(200); + expect(body).toMatch(/api/i); + done(); + }); + }); + + // ---------------------------------------- + // Furious Spinoffs API + // ---------------------------------------- + it("returns an array with the given number of titles", done => { + request.get( + apiUrlFor("furious_spinoffs", { count: 10 }), + (err, res, body) => { + console.log(body); + let result = j(body); + expect(result.length).toEqual(10); + done(); + } + ); + }); +}); diff --git a/spec/helpers/spec_helper.js b/spec/helpers/spec_helper.js new file mode 100644 index 0000000..62a07f6 --- /dev/null +++ b/spec/helpers/spec_helper.js @@ -0,0 +1,22 @@ +// Set test environment +process.env.NODE_ENV = 'test'; + +const mongoose = require('mongoose'); + +// Set test environment +process.env.NODE_ENV = 'test'; + +beforeAll((done) => { + if (mongoose.connection.readyState) { + done(); + } else { + require('./../../mongo')() + .then(() => done()); + } +}); + +afterEach((done) => { + require('./../../seeds/clean')() + .then(() => done()) + .catch((e) => console.error(e.stack)); +}); diff --git a/spec/support/jasmine.json b/spec/support/jasmine.json new file mode 100644 index 0000000..3ea3166 --- /dev/null +++ b/spec/support/jasmine.json @@ -0,0 +1,11 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "**/*[sS]pec.js" + ], + "helpers": [ + "helpers/**/*.js" + ], + "stopSpecOnExpectationFailure": false, + "random": false +} From 5bb269222bed07c8ec26b38306ddf7822506a2ae Mon Sep 17 00:00:00 2001 From: EdwinYung Date: Fri, 15 Dec 2017 13:38:55 -0500 Subject: [PATCH 04/11] initial --- models/user.js | 2 +- package-lock.json | 233 +--------------------------------------------- package.json | 2 +- 3 files changed, 6 insertions(+), 231 deletions(-) diff --git a/models/user.js b/models/user.js index b989851..d10b569 100644 --- a/models/user.js +++ b/models/user.js @@ -1,7 +1,7 @@ const mongoose = require('mongoose'); const Schema = mongoose.Schema; const uniqueValidator = require('mongoose-unique-validator'); -const bcrypt = require('bcrypt'); +const bcrypt = require('bcryptjs'); const md5 = require('md5'); const uuid = require('uuid/v4'); diff --git a/package-lock.json b/package-lock.json index a1b0b66..eb476bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.1.tgz", "integrity": "sha512-SrmAO+NhnsuG/6TychSl2VdxBZiw/d6V+8j+DFo8O3PwFi+QeYXWHhAw+b170aSc6zYab6/PjEWRZHIDN9mNUw==" }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, "accepts": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", @@ -75,20 +70,6 @@ "sylvester": "0.0.21" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.3" - } - }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", @@ -157,15 +138,6 @@ "safe-buffer": "5.1.1" } }, - "bcrypt": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-1.0.3.tgz", - "integrity": "sha512-pRyDdo73C8Nim3jwFJ7DWe3TZCgwDfWZ6nHS5LSdU77kWbj1frruvdndP02AOavtD4y8v6Fp2dolbHgp4SDrfg==", - "requires": { - "nan": "2.6.2", - "node-pre-gyp": "0.6.36" - } - }, "bcrypt-pbkdf": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", @@ -175,13 +147,10 @@ "tweetnacl": "0.14.5" } }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "2.0.3" - } + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" }, "bluebird": { "version": "3.5.1", @@ -345,11 +314,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -468,11 +432,6 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, - "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" - }, "define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", @@ -487,11 +446,6 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, "depd": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", @@ -760,27 +714,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.2" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", - "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -794,21 +727,6 @@ "faker": "4.1.0" } }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", @@ -918,11 +836,6 @@ } } }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, "hawk": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", @@ -1513,11 +1426,6 @@ "thenify-all": "1.6.0" } }, - "nan": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", - "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=" - }, "natural": { "version": "0.1.29", "resolved": "https://registry.npmjs.org/natural/-/natural-0.1.29.tgz", @@ -1533,31 +1441,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, - "node-pre-gyp": { - "version": "0.6.36", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz", - "integrity": "sha1-22BBEst04NR3VU6bUFsXq936t4Y=", - "requires": { - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.2", - "rc": "1.2.2", - "request": "2.83.0", - "rimraf": "2.6.2", - "semver": "5.4.1", - "tar": "2.2.1", - "tar-pack": "3.4.1" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.4" - } - }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -1566,17 +1449,6 @@ "path-key": "2.0.1" } }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -1652,20 +1524,6 @@ "mem": "1.1.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", - "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -1828,38 +1686,6 @@ "unpipe": "1.0.0" } }, - "rc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", - "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, "regexp-clone": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", @@ -1941,14 +1767,6 @@ "align-text": "0.1.4" } }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "requires": { - "glob": "7.1.2" - } - }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -2139,11 +1957,6 @@ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, "supports-color": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", @@ -2157,31 +1970,6 @@ "resolved": "https://registry.npmjs.org/sylvester/-/sylvester-0.0.21.tgz", "integrity": "sha1-KYexzivS84sNzio0OIiEv6RADqc=" }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz", - "integrity": "sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg==", - "requires": { - "debug": "2.6.9", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.3.3", - "rimraf": "2.6.2", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, "thenify": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", @@ -2297,11 +2085,6 @@ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "optional": true }, - "uid-number": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", - "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" - }, "underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", @@ -2360,14 +2143,6 @@ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, - "wide-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", - "requires": { - "string-width": "1.0.2" - } - }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", diff --git a/package.json b/package.json index 0dbf3f9..2899574 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "homepage": "https://github.com/edwinyung/assignment_mad_lib_api#readme", "dependencies": { - "bcrypt": "^1.0.3", + "bcryptjs": "^2.4.3", "bluebird": "^3.5.1", "body-parser": "^1.18.2", "cli-highlight": "^1.2.3", From 7b79978dedde80ad01e473440146ce351c38bc02 Mon Sep 17 00:00:00 2001 From: EdwinYung Date: Fri, 15 Dec 2017 14:00:31 -0500 Subject: [PATCH 05/11] finished basic WordPos test --- package.json | 2 +- spec/app_spec.js | 68 +++++++++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index c3b0127..2ce518d 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "start": "npm run whichnodemon && nodemon app.js || node app.js", "whichnodemon": "which nodemon > /dev/null", "jasmine": "./node_modules/jasmine/bin/jasmine.js" -}, + }, "repository": { "type": "git", "url": "git+https://github.com/edwinyung/assignment_mad_lib_api.git" diff --git a/spec/app_spec.js b/spec/app_spec.js index 7979d4b..c13ed30 100644 --- a/spec/app_spec.js +++ b/spec/app_spec.js @@ -1,18 +1,20 @@ -const app = require("../app"); -const request = require("request"); -const mongoose = require("mongoose"); -const User = mongoose.model("User"); -const qs = require("qs"); +const app = require('../app'); +const request = require('request'); +const mongoose = require('mongoose'); +const User = mongoose.model('User'); +const qs = require('qs'); +var WordPOS = require('wordpos'), + wordpos = new WordPOS(); -describe("App", () => { - const baseUrl = "http://localhost:8888"; - const apiUrl = baseUrl + "/api/v1/"; +describe('App', () => { + const baseUrl = 'http://localhost:8888'; + const apiUrl = baseUrl + '/api/v1/'; let server; let user; const apiUrlFor = (type, params) => { - params = params ? `&${qs.stringify(params)}` : ""; + params = params ? `&${qs.stringify(params)}` : ''; return `${apiUrl}${type}?access_token=${user.token}${params}`; }; const j = str => JSON.parse(str); @@ -25,10 +27,10 @@ describe("App", () => { beforeEach(done => { User.create({ - fname: "Foo", - lname: "Bar", - email: "foobar@gmail", - password: "password" + fname: 'Foo', + lname: 'Bar', + email: 'foobar@gmail', + password: 'password' }).then(result => { user = result; done(); @@ -44,7 +46,7 @@ describe("App", () => { // ---------------------------------------- // App // ---------------------------------------- - it("renders the home page", done => { + it('renders the home page', done => { request.get(baseUrl, (err, res, body) => { expect(res.statusCode).toBe(200); expect(body).toMatch(/api/i); @@ -54,16 +56,34 @@ describe("App", () => { // ---------------------------------------- // Furious Spinoffs API + // // ---------------------------------------- + // it("returns an array with the given number of titles", done => { + // request.get( + // apiUrlFor("furious_spinoffs", { count: 10 }), + // (err, res, body) => { + // console.log(body); + // let result = j(body); + // expect(result.length).toEqual(10); + // done(); + // } + // ); + // }); + + // 1. user (after login) submit sentence in clear text (in a textarea or something) + // 2. call to BE and analyze the sentence and extract nouns/adverbs/adjectives/etc. (via wordpos and the APIs around that) + // 3. replace every noun/adverb/verb/etc. with templates (eg: {{ noun}}) that sentencer knows + // 4. let sentencer return the newly formed sentence + // ---------------------------------------- + // WordPOS API // ---------------------------------------- - it("returns an array with the given number of titles", done => { - request.get( - apiUrlFor("furious_spinoffs", { count: 10 }), - (err, res, body) => { - console.log(body); - let result = j(body); - expect(result.length).toEqual(10); - done(); - } - ); + it('extract nouns/adverbs/adjectives/etc', async done => { + let testStr = 'The angry bear chased the frightened little squirrel.'; + let wordPosObj = await wordpos.getPOS(testStr, console.log); + expect(wordPosObj.nouns).toEqual(['bear', 'chased', 'little', 'squirrel']); + expect(wordPosObj.verbs).toEqual(['bear']); + expect(wordPosObj.adjectives).toEqual(['angry', 'frightened', 'little']); + expect(wordPosObj.adverbs).toEqual(['little']); + expect(wordPosObj.rest).toEqual(['The', '']); + done(); }); }); From f237763207ba3f03d930992072725435f37084ec Mon Sep 17 00:00:00 2001 From: Jeff Dederick Date: Fri, 15 Dec 2017 16:37:33 -0500 Subject: [PATCH 06/11] setting replace methods --- app.js | 7 +++++-- routers/story.js | 17 +++++++++++++++++ views/users/show.handlebars | 11 +++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 routers/story.js diff --git a/app.js b/app.js index 00a5bcd..a421d71 100644 --- a/app.js +++ b/app.js @@ -205,8 +205,11 @@ const usersRouter = require("./routers/users")({ }); app.use("/", usersRouter); -const furiousSpinoff = require("./routers/index"); -app.use("/api/v1", furiousSpinoff); +// const furiousSpinoff = require("./routers/index"); +// app.use("/api/v1", furiousSpinoff); + +const story = require("./routers/story"); +app.use("/story", story); // ---------------------------------------- // Template Engine diff --git a/routers/story.js b/routers/story.js new file mode 100644 index 0000000..d7666b9 --- /dev/null +++ b/routers/story.js @@ -0,0 +1,17 @@ +const express = require("express"); +const router = express.Router(); +const helpers = require("./../helpers"); +const h = helpers.registered; +var WordPOS = require("wordpos"), + wordpos = new WordPOS(); +// ---------------------------------------- +// Story +// ---------------------------------------- +router.post("/", async (req, res, next) => { + let story = req.body.sentence; + let words = await wordpos.getPOS(story, console.log); + let templated = story.replace(); + res.status(200).json(result); +}); + +module.exports = router; diff --git a/views/users/show.handlebars b/views/users/show.handlebars index 8eb95bb..aafefa8 100644 --- a/views/users/show.handlebars +++ b/views/users/show.handlebars @@ -29,3 +29,14 @@ + +
+
+ + +
+ +
+ +
+
From 56efb730bb16850ab9b02df0c866c2809d428745 Mon Sep 17 00:00:00 2001 From: EdwinYung Date: Fri, 15 Dec 2017 17:02:03 -0500 Subject: [PATCH 07/11] working on replace --- routers/story.js | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/routers/story.js b/routers/story.js index d7666b9..05cd3cf 100644 --- a/routers/story.js +++ b/routers/story.js @@ -1,16 +1,41 @@ -const express = require("express"); +const express = require('express'); const router = express.Router(); -const helpers = require("./../helpers"); +const helpers = require('./../helpers'); const h = helpers.registered; -var WordPOS = require("wordpos"), +var WordPOS = require('wordpos'), wordpos = new WordPOS(); +var Sentencer = require('sentencer'); + +// Sentencer.configure({ +// actions: { +// number: function() { +// return Math.floor( Math.random() * 10 ) + 1; +// } +// } +// }); + // ---------------------------------------- // Story // ---------------------------------------- -router.post("/", async (req, res, next) => { +router.post('/', async (req, res, next) => { let story = req.body.sentence; let words = await wordpos.getPOS(story, console.log); - let templated = story.replace(); + let templated = await function(words) { + let temp = story; + for (let key in words) { + if (key !== 'rest') { + words[key].forEach(element => { + temp.replace(element, `{{ ${key} }}`); + }); + } + } + return temp; + }; + let result = templated(words); + //let templated = story.replace(); + console.log('======================='); + console.log(result); + console.log('======================='); res.status(200).json(result); }); From 53d92344aeb13774195bb698a4ebff64e7a14670 Mon Sep 17 00:00:00 2001 From: EdwinYung Date: Fri, 15 Dec 2017 17:31:29 -0500 Subject: [PATCH 08/11] algo works --- routers/story.js | 72 +++++++++++++++++++++++++++++++++++++++--------- spec/app_spec.js | 13 +++++++++ 2 files changed, 72 insertions(+), 13 deletions(-) diff --git a/routers/story.js b/routers/story.js index 05cd3cf..cd42d00 100644 --- a/routers/story.js +++ b/routers/story.js @@ -6,13 +6,59 @@ var WordPOS = require('wordpos'), wordpos = new WordPOS(); var Sentencer = require('sentencer'); -// Sentencer.configure({ -// actions: { -// number: function() { -// return Math.floor( Math.random() * 10 ) + 1; -// } -// } -// }); +let randomVerbs = [ + 'unite', + 'help', + 'whip', + 'introduce', + 'protect', + 'cross', + 'subtract', + 'scream', + 'rain', + 'pedal', + 'object', + 'charge', + 'practise', + 'load', + 'hope', + 'claim', + 'attend', + 'destroy', + 'trace', + 'pass', + 'type', + 'bruise', + 'remember', + 'snow', + 'wobble', + 'whistle', + 'seal', + 'step', + 'joke', + 'phone', + 'nail', + 'replace', + 'guide', + 'melt', + 'record', + 'smoke', + 'print', + 'admit', + 'add', + 'screw' +]; + +Sentencer.configure({ + actions: { + adjectives: function() { + return Sentencer.make('{{ adjective }}'); + }, + verbs: function() { + return randomVerbs[Math.floor(Math.random(randomVerbs.length - 1))]; + } + } +}); // ---------------------------------------- // Story @@ -20,23 +66,23 @@ var Sentencer = require('sentencer'); router.post('/', async (req, res, next) => { let story = req.body.sentence; let words = await wordpos.getPOS(story, console.log); - let templated = await function(words) { + let templated = async function(words) { let temp = story; for (let key in words) { if (key !== 'rest') { words[key].forEach(element => { - temp.replace(element, `{{ ${key} }}`); + temp = temp.replace(element, `{{ ${key} }}`); }); } } return temp; }; - let result = templated(words); - //let templated = story.replace(); + let result = await templated(words); + let finalResult = await Sentencer.make(result); console.log('======================='); - console.log(result); + console.log(finalResult); console.log('======================='); - res.status(200).json(result); + res.status(200).json(finalResult); }); module.exports = router; diff --git a/spec/app_spec.js b/spec/app_spec.js index c13ed30..17c4c1e 100644 --- a/spec/app_spec.js +++ b/spec/app_spec.js @@ -86,4 +86,17 @@ describe('App', () => { expect(wordPosObj.rest).toEqual(['The', '']); done(); }); + + it('return madlibbed paragraph', async done => { + // request.get( + // apiUrlFor("furious_spinoffs", { count: 10 }), + // (err, res, body) => { + // console.log(body); + // let result = j(body); + // expect(result.length).toEqual(10); + // done(); + // } + // ); + } + }); From a7963e9c536dbb3ab6366f368a077447d5266406 Mon Sep 17 00:00:00 2001 From: Jeff Dederick Date: Fri, 15 Dec 2017 17:51:09 -0500 Subject: [PATCH 09/11] debugging api --- app.js | 2 +- routers/story.js | 115 +++++++++++++++++++++--------------- views/users/show.handlebars | 2 +- 3 files changed, 68 insertions(+), 51 deletions(-) diff --git a/app.js b/app.js index a421d71..6ed59df 100644 --- a/app.js +++ b/app.js @@ -209,7 +209,7 @@ app.use("/", usersRouter); // app.use("/api/v1", furiousSpinoff); const story = require("./routers/story"); -app.use("/story", story); +app.use("/api/v1", story); // ---------------------------------------- // Template Engine diff --git a/routers/story.js b/routers/story.js index cd42d00..4880bec 100644 --- a/routers/story.js +++ b/routers/story.js @@ -1,58 +1,59 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); -const helpers = require('./../helpers'); +const helpers = require("./../helpers"); const h = helpers.registered; -var WordPOS = require('wordpos'), +var WordPOS = require("wordpos"), wordpos = new WordPOS(); -var Sentencer = require('sentencer'); +var Sentencer = require("sentencer"); +const passport = require("passport"); let randomVerbs = [ - 'unite', - 'help', - 'whip', - 'introduce', - 'protect', - 'cross', - 'subtract', - 'scream', - 'rain', - 'pedal', - 'object', - 'charge', - 'practise', - 'load', - 'hope', - 'claim', - 'attend', - 'destroy', - 'trace', - 'pass', - 'type', - 'bruise', - 'remember', - 'snow', - 'wobble', - 'whistle', - 'seal', - 'step', - 'joke', - 'phone', - 'nail', - 'replace', - 'guide', - 'melt', - 'record', - 'smoke', - 'print', - 'admit', - 'add', - 'screw' + "unite", + "help", + "whip", + "introduce", + "protect", + "cross", + "subtract", + "scream", + "rain", + "pedal", + "object", + "charge", + "practise", + "load", + "hope", + "claim", + "attend", + "destroy", + "trace", + "pass", + "type", + "bruise", + "remember", + "snow", + "wobble", + "whistle", + "seal", + "step", + "joke", + "phone", + "nail", + "replace", + "guide", + "melt", + "record", + "smoke", + "print", + "admit", + "add", + "screw" ]; Sentencer.configure({ actions: { adjectives: function() { - return Sentencer.make('{{ adjective }}'); + return Sentencer.make("{{ adjective }}"); }, verbs: function() { return randomVerbs[Math.floor(Math.random(randomVerbs.length - 1))]; @@ -63,13 +64,15 @@ Sentencer.configure({ // ---------------------------------------- // Story // ---------------------------------------- -router.post('/', async (req, res, next) => { +router.post("/story", async (req, res, next) => { + passport.authenticate("bearer", { session: false }); + let story = req.body.sentence; let words = await wordpos.getPOS(story, console.log); let templated = async function(words) { let temp = story; for (let key in words) { - if (key !== 'rest') { + if (key !== "rest") { words[key].forEach(element => { temp = temp.replace(element, `{{ ${key} }}`); }); @@ -79,10 +82,24 @@ router.post('/', async (req, res, next) => { }; let result = await templated(words); let finalResult = await Sentencer.make(result); - console.log('======================='); + console.log("======================="); console.log(finalResult); - console.log('======================='); + console.log("======================="); res.status(200).json(finalResult); }); +router.get( + "/story", + + // Register the passport bearer strategy middleware + // we this router's only route + passport.authenticate("bearer", { session: false }), + + // Callback for the route + // serves the data from the API + (req, res, next) => { + res.status(200).json(randomVerbs); + } +); + module.exports = router; diff --git a/views/users/show.handlebars b/views/users/show.handlebars index aafefa8..1d71ce6 100644 --- a/views/users/show.handlebars +++ b/views/users/show.handlebars @@ -30,7 +30,7 @@ -
+
From 83f743d662d5de1e20637959307bc2fe060c8f9e Mon Sep 17 00:00:00 2001 From: EdwinYung Date: Fri, 15 Dec 2017 18:51:33 -0500 Subject: [PATCH 10/11] editing login --- app.js | 103 +++++++++++++++--------------- curl | 1 + routers/story.js | 112 ++++++++++++++++----------------- spec/app_spec.js | 23 ++++--- views/sessions/new.handlebars | 10 ++- views/welcome/index.handlebars | 1 - 6 files changed, 127 insertions(+), 123 deletions(-) create mode 100644 curl delete mode 100644 views/welcome/index.handlebars diff --git a/app.js b/app.js index 6ed59df..cf34613 100644 --- a/app.js +++ b/app.js @@ -1,35 +1,35 @@ -const express = require("express"); +const express = require('express'); const app = express(); // ---------------------------------------- // App Variables // ---------------------------------------- -app.locals.appName = "Mad Libs"; +app.locals.appName = 'Mad Libs'; // ---------------------------------------- // ENV // ---------------------------------------- -if (process.env.NODE_ENV !== "production") { - require("dotenv").config(); +if (process.env.NODE_ENV !== 'production') { + require('dotenv').config(); } // ---------------------------------------- // Body Parser // ---------------------------------------- -const bodyParser = require("body-parser"); +const bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: true })); // ---------------------------------------- // Sessions/Cookies // ---------------------------------------- -const cookieParser = require("cookie-parser"); -const cookieSession = require("cookie-session"); +const cookieParser = require('cookie-parser'); +const cookieSession = require('cookie-session'); app.use(cookieParser()); app.use( cookieSession({ - name: "session", - keys: [process.env.SESSION_SECRET || "secret"] + name: 'session', + keys: [process.env.SESSION_SECRET || 'secret'] }) ); @@ -41,14 +41,14 @@ app.use((req, res, next) => { // ---------------------------------------- // Flash Messages // ---------------------------------------- -const flash = require("express-flash-messages"); +const flash = require('express-flash-messages'); app.use(flash()); // ---------------------------------------- // Method Override // ---------------------------------------- -const methodOverride = require("method-override"); -const getPostSupport = require("express-method-override-get-post-support"); +const methodOverride = require('method-override'); +const getPostSupport = require('express-method-override-get-post-support'); app.use( methodOverride( @@ -61,7 +61,7 @@ app.use( // Referrer // ---------------------------------------- app.use((req, res, next) => { - req.session.backUrl = req.header("Referer") || "/"; + req.session.backUrl = req.header('Referer') || '/'; next(); }); @@ -73,9 +73,9 @@ app.use(express.static(`${__dirname}/public`)); // ---------------------------------------- // Logging // ---------------------------------------- -const morgan = require("morgan"); -const morganToolkit = require("morgan-toolkit")(morgan, { - req: ["cookies" /*, 'signedCookies' */] +const morgan = require('morgan'); +const morganToolkit = require('morgan-toolkit')(morgan, { + req: ['cookies' /*, 'signedCookies' */] }); app.use(morganToolkit()); @@ -83,12 +83,12 @@ app.use(morganToolkit()); // ---------------------------------------- // Mongoose // ---------------------------------------- -const mongoose = require("mongoose"); +const mongoose = require('mongoose'); app.use((req, res, next) => { if (mongoose.connection.readyState) { next(); } else { - require("./mongo")().then(() => next()); + require('./mongo')().then(() => next()); } }); @@ -96,10 +96,10 @@ app.use((req, res, next) => { // Sessions // ---------------------------------------- // Require passport, strategies and User model -const passport = require("passport"); -const LocalStrategy = require("passport-local").Strategy; -const BearerStrategy = require("passport-http-bearer").Strategy; -const User = require("./models").User; +const passport = require('passport'); +const LocalStrategy = require('passport-local').Strategy; +const BearerStrategy = require('passport-http-bearer').Strategy; +const User = require('./models').User; // Initialize passport app.use(passport.initialize()); @@ -110,7 +110,7 @@ const localStrategy = new LocalStrategy( { // Set username field to email // to match form - usernameField: "email" + usernameField: 'email' }, (email, password, done) => { // Find user by email @@ -159,16 +159,16 @@ passport.deserializeUser((id, done) => { // Set up middleware to allow/disallow login/logout const loggedInOnly = (req, res, next) => { - return req.user ? next() : res.redirect("/login"); + return req.user ? next() : res.redirect('/login'); }; const loggedOutOnly = (req, res, next) => { - return !req.user ? next() : res.redirect("/"); + return !req.user ? next() : res.redirect('/'); }; // Show login only if logged out -app.get("/login", loggedOutOnly, (req, res) => { - res.render("sessions/new"); +app.get('/login', loggedOutOnly, (req, res) => { + res.render('sessions/new'); }); // Allow logout via GET and DELETE @@ -177,20 +177,20 @@ const onLogout = (req, res) => { req.logout(); // Ensure always redirecting as GET - req.method = "GET"; - res.redirect("/login"); + req.method = 'GET'; + res.redirect('/login'); }; -app.get("/logout", loggedInOnly, onLogout); +app.get('/logout', loggedInOnly, onLogout); -app.delete("/logout", loggedInOnly, onLogout); +app.delete('/logout', loggedInOnly, onLogout); // Create session with passport app.post( - "/sessions", - passport.authenticate("local", { - successRedirect: "/", - failureRedirect: "/login", + '/sessions', + passport.authenticate('local', { + successRedirect: '/', + failureRedirect: '/login', failureFlash: true }) ); @@ -199,41 +199,38 @@ app.post( // Routes // ---------------------------------------- -const usersRouter = require("./routers/users")({ +const usersRouter = require('./routers/users')({ loggedInOnly, loggedOutOnly }); -app.use("/", usersRouter); +app.use('/', usersRouter); -// const furiousSpinoff = require("./routers/index"); -// app.use("/api/v1", furiousSpinoff); - -const story = require("./routers/story"); -app.use("/api/v1", story); +const story = require('./routers/story'); +app.use('/api/v1', story); // ---------------------------------------- // Template Engine // ---------------------------------------- -const expressHandlebars = require("express-handlebars"); -const helpers = require("./helpers"); +const expressHandlebars = require('express-handlebars'); +const helpers = require('./helpers'); const hbs = expressHandlebars.create({ helpers: helpers, - partialsDir: "views/", - defaultLayout: "application" + partialsDir: 'views/', + defaultLayout: 'application' }); -app.engine("handlebars", hbs.engine); -app.set("view engine", "handlebars"); +app.engine('handlebars', hbs.engine); +app.set('view engine', 'handlebars'); // ---------------------------------------- // Server // ---------------------------------------- const port = process.env.PORT || process.argv[2] || 3000; -const host = "localhost"; +const host = 'localhost'; let args; -process.env.NODE_ENV === "production" ? (args = [port]) : (args = [port, host]); +process.env.NODE_ENV === 'production' ? (args = [port]) : (args = [port, host]); args.push(() => { console.log(`Listening: http://${host}:${port}\n`); @@ -244,8 +241,8 @@ if (require.main === module) { } // Disable logging in test mode -if (process.env.NODE_ENV !== "test") { - app.use(morgan("tiny")); +if (process.env.NODE_ENV !== 'test') { + app.use(morgan('tiny')); } // ---------------------------------------- @@ -259,7 +256,7 @@ app.use((err, req, res, next) => { if (err.stack) { err = err.stack; } - res.status(500).render("errors/500", { error: err }); + res.status(500).render('errors/500', { error: err }); }); module.exports = app; diff --git a/curl b/curl new file mode 100644 index 0000000..f384c8b --- /dev/null +++ b/curl @@ -0,0 +1 @@ +curl -H "Authorization: Bearer 4185bb480d198be788edef9cd33057ef" -H "Content-Type: application/json" -d '{"sentence": "This is a sentence"}' http://localhost:3000/api/v1/story diff --git a/routers/story.js b/routers/story.js index 4880bec..5b95ec8 100644 --- a/routers/story.js +++ b/routers/story.js @@ -1,62 +1,63 @@ -const express = require("express"); +const express = require('express'); const router = express.Router(); -const helpers = require("./../helpers"); +const helpers = require('./../helpers'); const h = helpers.registered; -var WordPOS = require("wordpos"), +var WordPOS = require('wordpos'), wordpos = new WordPOS(); -var Sentencer = require("sentencer"); -const passport = require("passport"); +var Sentencer = require('sentencer'); +const passport = require('passport'); -let randomVerbs = [ - "unite", - "help", - "whip", - "introduce", - "protect", - "cross", - "subtract", - "scream", - "rain", - "pedal", - "object", - "charge", - "practise", - "load", - "hope", - "claim", - "attend", - "destroy", - "trace", - "pass", - "type", - "bruise", - "remember", - "snow", - "wobble", - "whistle", - "seal", - "step", - "joke", - "phone", - "nail", - "replace", - "guide", - "melt", - "record", - "smoke", - "print", - "admit", - "add", - "screw" +var randomVerbs = [ + 'unite', + 'help', + 'whip', + 'introduce', + 'protect', + 'cross', + 'subtract', + 'scream', + 'rain', + 'pedal', + 'object', + 'charge', + 'practise', + 'load', + 'hope', + 'claim', + 'attend', + 'destroy', + 'trace', + 'pass', + 'type', + 'bruise', + 'remember', + 'snow', + 'wobble', + 'whistle', + 'seal', + 'step', + 'joke', + 'phone', + 'nail', + 'replace', + 'guide', + 'melt', + 'record', + 'smoke', + 'print', + 'admit', + 'add', + 'screw' ]; Sentencer.configure({ actions: { adjectives: function() { - return Sentencer.make("{{ adjective }}"); + return Sentencer.make('{{ adjective }}'); }, verbs: function() { - return randomVerbs[Math.floor(Math.random(randomVerbs.length - 1))]; + randomNum = Math.floor(Math.random() * randomVerbs.length); + return randomVerbs[randomNum]; } } }); @@ -64,15 +65,14 @@ Sentencer.configure({ // ---------------------------------------- // Story // ---------------------------------------- -router.post("/story", async (req, res, next) => { - passport.authenticate("bearer", { session: false }); - +router.post('/story', async (req, res, next) => { + passport.authenticate('bearer', { session: false }); let story = req.body.sentence; let words = await wordpos.getPOS(story, console.log); let templated = async function(words) { let temp = story; for (let key in words) { - if (key !== "rest") { + if (key !== 'rest') { words[key].forEach(element => { temp = temp.replace(element, `{{ ${key} }}`); }); @@ -82,18 +82,18 @@ router.post("/story", async (req, res, next) => { }; let result = await templated(words); let finalResult = await Sentencer.make(result); - console.log("======================="); + console.log('======================='); console.log(finalResult); - console.log("======================="); + console.log('======================='); res.status(200).json(finalResult); }); router.get( - "/story", + '/story', // Register the passport bearer strategy middleware // we this router's only route - passport.authenticate("bearer", { session: false }), + passport.authenticate('bearer', { session: false }), // Callback for the route // serves the data from the API diff --git a/spec/app_spec.js b/spec/app_spec.js index 17c4c1e..b60ee4f 100644 --- a/spec/app_spec.js +++ b/spec/app_spec.js @@ -87,16 +87,15 @@ describe('App', () => { done(); }); - it('return madlibbed paragraph', async done => { - // request.get( - // apiUrlFor("furious_spinoffs", { count: 10 }), - // (err, res, body) => { - // console.log(body); - // let result = j(body); - // expect(result.length).toEqual(10); - // done(); - // } - // ); - } - + // it('return madlibbed paragraph', async done => { + // // request.get( + // // apiUrlFor("furious_spinoffs", { count: 10 }), + // // (err, res, body) => { + // // console.log(body); + // // let result = j(body); + // // expect(result.length).toEqual(10); + // // done(); + // // } + // // ); + // } }); diff --git a/views/sessions/new.handlebars b/views/sessions/new.handlebars index a127e0d..a7f8de4 100644 --- a/views/sessions/new.handlebars +++ b/views/sessions/new.handlebars @@ -12,6 +12,14 @@
- +
+ + diff --git a/views/welcome/index.handlebars b/views/welcome/index.handlebars deleted file mode 100644 index 7ab6572..0000000 --- a/views/welcome/index.handlebars +++ /dev/null @@ -1 +0,0 @@ -

Hello Express!

\ No newline at end of file From bcb1db307085fdc2720cdf60972b74167c323134 Mon Sep 17 00:00:00 2001 From: EdwinYung Date: Fri, 15 Dec 2017 19:29:51 -0500 Subject: [PATCH 11/11] just have to do the router.get with the :id --- app.js | 2 +- curl | 4 +- routers/story.js | 71 +++++++++++++++++++---------------- views/sessions/new.handlebars | 10 +---- 4 files changed, 44 insertions(+), 43 deletions(-) diff --git a/app.js b/app.js index cf34613..83e6e0a 100644 --- a/app.js +++ b/app.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== 'production') { // Body Parser // ---------------------------------------- const bodyParser = require('body-parser'); -app.use(bodyParser.urlencoded({ extended: true })); +app.use(bodyParser.json()); // ---------------------------------------- // Sessions/Cookies diff --git a/curl b/curl index f384c8b..cb58a42 100644 --- a/curl +++ b/curl @@ -1 +1,3 @@ -curl -H "Authorization: Bearer 4185bb480d198be788edef9cd33057ef" -H "Content-Type: application/json" -d '{"sentence": "This is a sentence"}' http://localhost:3000/api/v1/story +curl -H "Authorization: Bearer 4185bb480d198be788edef9cd33057ef" -H "Content-Type: application/json" -d '{"sentence": "I like New York City and I love running and swimming"}' http://localhost:3000/api/v1/story + +curl -H "Content-Type: application/json" -d '{"sentence": "I like New York City and I love running and swimming"}' http://localhost:3000/api/v1/story?access_token=4185bb480d198be788edef9cd33057ef diff --git a/routers/story.js b/routers/story.js index 5b95ec8..a32a759 100644 --- a/routers/story.js +++ b/routers/story.js @@ -65,41 +65,48 @@ Sentencer.configure({ // ---------------------------------------- // Story // ---------------------------------------- -router.post('/story', async (req, res, next) => { - passport.authenticate('bearer', { session: false }); - let story = req.body.sentence; - let words = await wordpos.getPOS(story, console.log); - let templated = async function(words) { - let temp = story; - for (let key in words) { - if (key !== 'rest') { - words[key].forEach(element => { - temp = temp.replace(element, `{{ ${key} }}`); - }); - } - } - return temp; - }; - let result = await templated(words); - let finalResult = await Sentencer.make(result); - console.log('======================='); - console.log(finalResult); - console.log('======================='); - res.status(200).json(finalResult); -}); - -router.get( +router.post( '/story', - - // Register the passport bearer strategy middleware - // we this router's only route passport.authenticate('bearer', { session: false }), - - // Callback for the route - // serves the data from the API - (req, res, next) => { - res.status(200).json(randomVerbs); + async (req, res, next) => { + let story = req.body.sentence; + let words = await wordpos.getPOS(story, console.log); + let templated = async function(words) { + let temp = story; + for (let key in words) { + if (key !== 'rest') { + words[key].forEach(element => { + temp = temp.replace(element, `{{ ${key} }}`); + }); + } + } + return temp; + }; + let result = await templated(words); + let finalResult = await Sentencer.make(result); + console.log('======================='); + console.log(finalResult); + console.log('======================='); + res.status(200).json(finalResult); } ); +//curl -H "Content-Type: application/json" -d '{"sentence": "I like New York City and I love running and swimming"}' http://localhost:3000/api/v1/story?access_token=4185bb480d198be788edef9cd33057ef + +// router.get( +// '/story', +// +// // Register the passport bearer strategy middleware +// // we this router's only route +// passport.authenticate('bearer', { session: false }), +// +// // Callback for the route +// // serves the data from the API +// (req, res, next) => { +// res.status(200).json(randomVerbs); +// } +// ); + +// ); + module.exports = router; diff --git a/views/sessions/new.handlebars b/views/sessions/new.handlebars index a7f8de4..b98074e 100644 --- a/views/sessions/new.handlebars +++ b/views/sessions/new.handlebars @@ -12,14 +12,6 @@
- +
- -