From 521b6b389de6f82e6fe1f937b51471816bb83413 Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Wed, 18 Oct 2017 19:19:15 -0700
Subject: [PATCH 01/15] initial commit
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index 7513987..cdd9ddc 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,4 @@
# assignment_thoreddit
A social news web application for Viking thunder Gods
+
+By Tyler Ketron.
From 6bf733e9eabcc111555800d7ee2d80cd729a51f1 Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Sun, 22 Oct 2017 21:16:14 -0700
Subject: [PATCH 02/15] initialized app
---
.gitignore | 1 +
app.js | 117 +++++++++++++++++++++++++++
config/mongo.json | 13 +++
models/index.js | 14 ++++
mongo.js | 10 +++
package.json | 32 ++++++++
views/layouts/application.handlebars | 1 +
views/shared/_nav.handlebars | 0
8 files changed, 188 insertions(+)
create mode 100644 .gitignore
create mode 100644 app.js
create mode 100644 config/mongo.json
create mode 100644 models/index.js
create mode 100644 mongo.js
create mode 100644 package.json
create mode 100644 views/layouts/application.handlebars
create mode 100644 views/shared/_nav.handlebars
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c2658d7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules/
diff --git a/app.js b/app.js
new file mode 100644
index 0000000..1ec8e84
--- /dev/null
+++ b/app.js
@@ -0,0 +1,117 @@
+var express = require('express');
+var app = express();
+
+// ----------------------------------------
+// Body Parser
+// ----------------------------------------
+var bodyParser = require('body-parser');
+app.use(bodyParser.urlencoded({ extended: true }));
+
+// ----------------------------------------
+// Sessions/Cookies
+// ----------------------------------------
+var cookieSession = require('cookie-session');
+
+app.use(
+ cookieSession({
+ name: 'session',
+ keys: ['asdf1234567890qwer']
+ })
+);
+
+app.use((req, res, next) => {
+ res.locals.session = req.session;
+ res.locals.currentUser = req.session.currentUser;
+ next();
+});
+
+// ----------------------------------------
+// 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
+// ----------------------------------------
+var morgan = require('morgan');
+var morganToolkit = require('morgan-toolkit')(morgan);
+
+app.use(morganToolkit());
+
+// ----------------------------------------
+// Mongoose
+// ----------------------------------------
+const mongoose = require('mongoose');
+app.use((req, res, next) => {
+ if (mongoose.connection.readyState) {
+ next();
+ } else {
+ require('./mongo')().then(() => next());
+ }
+});
+
+// ----------------------------------------
+// Routes
+// ----------------------------------------
+// var sessionsRouter = require('./routers/sessions')(app);
+// app.use('/', sessionsRouter);
+//
+// var usersRouter = require('./routers/users');
+// app.use('/users', usersRouter);
+//
+// var ratablesRouter = require('./routers/ratables');
+// app.use('/ratables', ratablesRouter);
+app.use((req, res, next) => {
+ res.render('layouts/application');
+});
+
+// ----------------------------------------
+// Template Engine
+// ----------------------------------------
+var expressHandlebars = require('express-handlebars');
+
+var hbs = expressHandlebars.create({
+ partialsDir: 'views/',
+ defaultLayout: 'application'
+});
+
+app.engine('handlebars', hbs.engine);
+app.set('view engine', 'handlebars');
+
+// ----------------------------------------
+// Server
+// ----------------------------------------
+var port = process.env.PORT || process.argv[2] || 3000;
+var host = 'localhost';
+
+var args;
+process.env.NODE_ENV === 'production' ? (args = [port]) : (args = [port, host]);
+
+args.push(() => {
+ console.log(`Listening: http://${host}:${port}`);
+});
+
+app.listen.apply(app, args);
+
+module.exports = app;
diff --git a/config/mongo.json b/config/mongo.json
new file mode 100644
index 0000000..36c68bc
--- /dev/null
+++ b/config/mongo.json
@@ -0,0 +1,13 @@
+{
+ "development": {
+ "database": "thoreddit_development",
+ "host": "localhost"
+ },
+ "test": {
+ "database": "thoreddit_test",
+ "host": "localhost"
+ },
+ "production": {
+ "use_env_variable": "MONGODB_URI"
+ }
+}
diff --git a/models/index.js b/models/index.js
new file mode 100644
index 0000000..e7902f5
--- /dev/null
+++ b/models/index.js
@@ -0,0 +1,14 @@
+var mongoose = require('mongoose');
+var bluebird = require('bluebird');
+
+// Set bluebird as the promise
+// library for mongoose
+mongoose.Promise = bluebird;
+
+var models = {};
+
+// Load models and attach to models here
+// models.User = require('./user');
+//... more models
+
+module.exports = models;
diff --git a/mongo.js b/mongo.js
new file mode 100644
index 0000000..79e118f
--- /dev/null
+++ b/mongo.js
@@ -0,0 +1,10 @@
+var mongoose = require('mongoose');
+var env = process.env.NODE_ENV || 'development';
+var config = require('./config/mongo')[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.json b/package.json
new file mode 100644
index 0000000..8e67b60
--- /dev/null
+++ b/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "assignment_thoreddit",
+ "version": "1.0.0",
+ "description": "A social news web application for Viking thunder Gods",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/tketron/assignment_thoreddit.git"
+ },
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/tketron/assignment_thoreddit/issues"
+ },
+ "homepage": "https://github.com/tketron/assignment_thoreddit#readme",
+ "dependencies": {
+ "bluebird": "^3.5.1",
+ "body-parser": "^1.18.2",
+ "cookie-session": "^2.0.0-beta.3",
+ "express": "^4.16.2",
+ "express-handlebars": "^3.0.0",
+ "express-method-override-get-post-support": "0.0.7",
+ "method-override": "^2.3.10",
+ "mongoose": "^4.12.3",
+ "mongooseeder": "^2.0.5",
+ "morgan": "^1.9.0",
+ "morgan-toolkit": "^1.0.2"
+ }
+}
diff --git a/views/layouts/application.handlebars b/views/layouts/application.handlebars
new file mode 100644
index 0000000..b0e02bd
--- /dev/null
+++ b/views/layouts/application.handlebars
@@ -0,0 +1 @@
+Hello, Thoreddit!
diff --git a/views/shared/_nav.handlebars b/views/shared/_nav.handlebars
new file mode 100644
index 0000000..e69de29
From ce7bc981f4c383558996bc921273e060fa075634 Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Sat, 28 Oct 2017 10:58:58 -0700
Subject: [PATCH 03/15] implemented session functionality
---
app.js | 16 +++----
models/index.js | 1 +
models/user.js | 37 ++++++++++++++++
repl.js | 24 ++++++++++
routers/sessions.js | 65 ++++++++++++++++++++++++++++
routers/users.js | 29 +++++++++++++
views/layouts/application.handlebars | 36 ++++++++++++++-
views/sessions/new.handlebars | 18 ++++++++
views/shared/_nav.handlebars | 32 ++++++++++++++
views/users/index.handlebars | 59 +++++++++++++++++++++++++
views/users/show.handlebars | 47 ++++++++++++++++++++
11 files changed, 355 insertions(+), 9 deletions(-)
create mode 100644 models/user.js
create mode 100644 repl.js
create mode 100644 routers/sessions.js
create mode 100644 routers/users.js
create mode 100644 views/sessions/new.handlebars
create mode 100644 views/users/index.handlebars
create mode 100644 views/users/show.handlebars
diff --git a/app.js b/app.js
index 1ec8e84..d005d41 100644
--- a/app.js
+++ b/app.js
@@ -74,17 +74,17 @@ app.use((req, res, next) => {
// ----------------------------------------
// Routes
// ----------------------------------------
-// var sessionsRouter = require('./routers/sessions')(app);
-// app.use('/', sessionsRouter);
-//
-// var usersRouter = require('./routers/users');
-// app.use('/users', usersRouter);
+var sessionsRouter = require('./routers/sessions')(app);
+app.use('/', sessionsRouter);
+
+var usersRouter = require('./routers/users');
+app.use('/users', usersRouter);
//
// var ratablesRouter = require('./routers/ratables');
// app.use('/ratables', ratablesRouter);
-app.use((req, res, next) => {
- res.render('layouts/application');
-});
+// app.use((req, res, next) => {
+// res.render('body');
+// });
// ----------------------------------------
// Template Engine
diff --git a/models/index.js b/models/index.js
index e7902f5..75eaad3 100644
--- a/models/index.js
+++ b/models/index.js
@@ -10,5 +10,6 @@ var models = {};
// Load models and attach to models here
// models.User = require('./user');
//... more models
+models.User = require('./user');
module.exports = models;
diff --git a/models/user.js b/models/user.js
new file mode 100644
index 0000000..5dcdac9
--- /dev/null
+++ b/models/user.js
@@ -0,0 +1,37 @@
+const mongoose = require('mongoose');
+var Schema = mongoose.Schema;
+
+var UserSchema = new Schema(
+ {
+ fname: String,
+ lname: String,
+ username: String,
+ email: String
+ },
+ {
+ timestamps: true
+ }
+);
+
+UserSchema.methods.name = function() {
+ return `${this.fname} ${this.lname}`;
+};
+
+UserSchema.statics.findByFirstName = function(fname) {
+ return User.find({ fname: fname });
+};
+
+UserSchema.virtual('fullname').set(function(name) {
+ console.log('Setting the name of the user');
+ name = name.toString();
+ var splat = name.split(' ');
+ var fname = splat[0] || this.fname;
+ var lname = splat[1] || this.lname;
+ this.fname = fname;
+ this.lname = lname;
+ return this.name();
+});
+
+var User = mongoose.model('User', UserSchema);
+
+module.exports = User;
diff --git a/repl.js b/repl.js
new file mode 100644
index 0000000..9b8d15b
--- /dev/null
+++ b/repl.js
@@ -0,0 +1,24 @@
+const mongoose = require('mongoose');
+var repl = require('repl').start({});
+var models = require('./models');
+
+
+require('./mongo')().then(() => {
+ repl.context.models = models;
+
+
+ Object.keys(models).forEach((modelName) => {
+ repl.context[modelName] = mongoose.model(modelName);
+ });
+
+
+ repl.context.lg = (data) => console.log(data);
+});
+
+
+
+
+
+
+
+
diff --git a/routers/sessions.js b/routers/sessions.js
new file mode 100644
index 0000000..5fb5613
--- /dev/null
+++ b/routers/sessions.js
@@ -0,0 +1,65 @@
+var url = require('url');
+var express = require('express');
+var router = express.Router();
+const mongoose = require('mongoose');
+var models = require('./../models');
+var User = mongoose.model('User');
+
+module.exports = app => {
+ // Auth
+ app.use((req, res, next) => {
+ var reqUrl = url.parse(req.url);
+ if (
+ !req.session.currentUser &&
+ !['/', '/login', '/sessions'].includes(reqUrl.pathname)
+ ) {
+ res.redirect('/login');
+ } else {
+ next();
+ }
+ });
+
+ // New
+ var onNew = (req, res) => {
+ if (req.session.currentUser) {
+ res.redirect('/users');
+ } else {
+ res.render('sessions/new');
+ }
+ };
+ router.get('/', onNew);
+ router.get('/login', onNew);
+
+ // Create
+ router.post('/sessions', (req, res) => {
+ User.findOne({
+ username: req.body.username,
+ email: req.body.email
+ })
+ .then(user => {
+ if (user) {
+ req.session.currentUser = {
+ username: user.username,
+ email: user.email,
+ id: user.id,
+ _id: user._id
+ };
+ res.redirect('/users');
+ } else {
+ //user not in database
+ res.redirect('/login');
+ }
+ })
+ .catch(e => res.status(500).send(e.stack));
+ });
+
+ // Destroy
+ var onDestroy = (req, res) => {
+ req.session.currentUser = null;
+ res.redirect('/login');
+ };
+ router.get('/logout', onDestroy);
+ router.delete('/logout', onDestroy);
+
+ return router;
+};
diff --git a/routers/users.js b/routers/users.js
new file mode 100644
index 0000000..1132b31
--- /dev/null
+++ b/routers/users.js
@@ -0,0 +1,29 @@
+var express = require('express');
+var router = express.Router();
+const mongoose = require('mongoose');
+var models = require('./../models');
+var User = mongoose.model('User');
+
+// ----------------------------------------
+// Index
+// ----------------------------------------
+router.get('/', (req, res) => {
+ User.find()
+ .then(users => {
+ res.render('users/index', { users });
+ })
+ .catch(e => res.status(500).send(e.stack));
+});
+
+// ----------------------------------------
+// Show
+// ----------------------------------------
+router.get('/:id', (req, res) => {
+ User.findById(req.params.id)
+ .then(user => {
+ res.render('users/show', { user });
+ })
+ .catch(e => res.status(500).send(e.stack));
+});
+
+module.exports = router;
diff --git a/views/layouts/application.handlebars b/views/layouts/application.handlebars
index b0e02bd..69a0dfc 100644
--- a/views/layouts/application.handlebars
+++ b/views/layouts/application.handlebars
@@ -1 +1,35 @@
-Hello, Thoreddit!
+
+
+
+
+
+
+
+ Hello, Thoreddit!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{> shared/_nav }}
+
+ {{{ body }}}
+
+
+
+
diff --git a/views/sessions/new.handlebars b/views/sessions/new.handlebars
new file mode 100644
index 0000000..b49302b
--- /dev/null
+++ b/views/sessions/new.handlebars
@@ -0,0 +1,18 @@
+
+
+
+
diff --git a/views/shared/_nav.handlebars b/views/shared/_nav.handlebars
index e69de29..0069090 100644
--- a/views/shared/_nav.handlebars
+++ b/views/shared/_nav.handlebars
@@ -0,0 +1,32 @@
+
diff --git a/views/users/index.handlebars b/views/users/index.handlebars
new file mode 100644
index 0000000..204235f
--- /dev/null
+++ b/views/users/index.handlebars
@@ -0,0 +1,59 @@
+
+
+
+
+
+{{#if users.length }}
+
+{{else }}
+ No users
+{{/if }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/views/users/show.handlebars b/views/users/show.handlebars
new file mode 100644
index 0000000..38fa4bd
--- /dev/null
+++ b/views/users/show.handlebars
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+ Key |
+ Value |
+
+
+
+
+ First Name |
+ {{ user.fname }} |
+
+
+ Last Name |
+ {{ user.lname }} |
+
+
+ Username |
+ {{ user.username }} |
+
+
+ Email |
+ {{ user.email }} |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 6d781f27589494db53640b7dac6decc879e22531 Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Wed, 1 Nov 2017 19:23:05 -0700
Subject: [PATCH 04/15] added Post model and index view
---
app.js | 9 ++--
models/index.js | 1 +
models/post.js | 21 ++++++++
routers/posts.js | 30 ++++++++++++
seeds/index.js | 94 ++++++++++++++++++++++++++++++++++++
views/posts/index.handlebars | 40 +++++++++++++++
views/posts/show.handlebars | 0
views/shared/_nav.handlebars | 2 +-
8 files changed, 190 insertions(+), 7 deletions(-)
create mode 100644 models/post.js
create mode 100644 routers/posts.js
create mode 100644 seeds/index.js
create mode 100644 views/posts/index.handlebars
create mode 100644 views/posts/show.handlebars
diff --git a/app.js b/app.js
index d005d41..5ca3065 100644
--- a/app.js
+++ b/app.js
@@ -79,12 +79,9 @@ app.use('/', sessionsRouter);
var usersRouter = require('./routers/users');
app.use('/users', usersRouter);
-//
-// var ratablesRouter = require('./routers/ratables');
-// app.use('/ratables', ratablesRouter);
-// app.use((req, res, next) => {
-// res.render('body');
-// });
+
+var postsRouter = require('./routers/posts');
+app.use('/posts', postsRouter);
// ----------------------------------------
// Template Engine
diff --git a/models/index.js b/models/index.js
index 75eaad3..994f4a3 100644
--- a/models/index.js
+++ b/models/index.js
@@ -11,5 +11,6 @@ var models = {};
// models.User = require('./user');
//... more models
models.User = require('./user');
+models.Post = require('./post');
module.exports = models;
diff --git a/models/post.js b/models/post.js
new file mode 100644
index 0000000..f0da077
--- /dev/null
+++ b/models/post.js
@@ -0,0 +1,21 @@
+const mongoose = require('mongoose');
+var Schema = mongoose.Schema;
+
+var PostSchema = new Schema(
+ {
+ title: String,
+ body: String,
+ author: {
+ type: Schema.Types.ObjectId,
+ ref: 'User'
+ }
+ },
+ {
+ timestamps: true,
+ discriminatorKey: 'kind'
+ }
+);
+
+var Post = mongoose.model('Post', PostSchema);
+
+module.exports = Post;
diff --git a/routers/posts.js b/routers/posts.js
new file mode 100644
index 0000000..b60d84b
--- /dev/null
+++ b/routers/posts.js
@@ -0,0 +1,30 @@
+var express = require('express');
+var router = express.Router();
+const mongoose = require('mongoose');
+var models = require('./../models');
+var Post = mongoose.model('Post');
+
+// ----------------------------------------
+// Index
+// ----------------------------------------
+router.get('/', (req, res) => {
+ Post.find()
+ .populate('author')
+ .then(posts => {
+ res.render('posts/index', { posts });
+ })
+ .catch(e => res.status(500).send(e.stack));
+});
+
+// ----------------------------------------
+// Show
+// ----------------------------------------
+router.get('/:id', (req, res) => {
+ Post.findById(req.params.id)
+ .then(post => {
+ res.render('posts/show', { post });
+ })
+ .catch(e => res.status(500).send(e.stack));
+});
+
+module.exports = router;
diff --git a/seeds/index.js b/seeds/index.js
new file mode 100644
index 0000000..0b0b68d
--- /dev/null
+++ b/seeds/index.js
@@ -0,0 +1,94 @@
+const mongoose = require('mongoose');
+const models = require('./../models');
+var env = process.env.NODE_ENV || 'development';
+var config = require('./../config/mongo')[env];
+const mongooseeder = require('mongooseeder');
+
+const { User, Post } = models;
+
+const MULTIPLIER = 5;
+
+function randomRating() {
+ return Math.floor(Math.random() * 6);
+}
+
+const seeds = () => {
+ // ----------------------------------------
+ // Create Users
+ // ----------------------------------------
+ console.log('Creating Users');
+ var users = [];
+ for (let i = 0; i < MULTIPLIER * 2; i++) {
+ var user = new User({
+ fname: 'Foo',
+ lname: 'Bar',
+ username: `foobar${i}`,
+ email: `foobar${i}@gmail.com`
+ });
+ users.push(user);
+ }
+
+ // ----------------------------------------
+ // Posts
+ // ----------------------------------------
+ console.log('Creating Posts');
+ var posts = [];
+ for (let i = 0; i < MULTIPLIER * 1; i++) {
+ var post = new Post({
+ title: 'A Post',
+ body: 'This is an example post on Thoreddit',
+ author: users[i]
+ });
+ posts.push(post);
+ }
+ // // ----------------------------------------
+ // // Ratings
+ // // ----------------------------------------
+ // console.log('Creating Ratings');
+ // var ratings = [];
+ // for (let i = 0; i < MULTIPLIER * 1000; i++) {
+ // var hotel = hotels[i % hotels.length];
+ // var motel = motels[i % motels.length];
+ // var user = users[1];
+ // var hotelRating = new Rating({
+ // ratable: hotel,
+ // user: user,
+ // value: randomRating()
+ // });
+ // var motelRating = new Rating({
+ // ratable: motel,
+ // user: user,
+ // value: randomRating()
+ // });
+ // hotel.ratings.push(hotelRating);
+ // motel.ratings.push(motelRating);
+ // ratings.push(hotelRating);
+ // ratings.push(motelRating);
+ // }
+
+ // ----------------------------------------
+ // Finish
+ // ----------------------------------------
+ console.log('Saving...');
+ var promises = [];
+ [users, posts].forEach(collection => {
+ collection.forEach(model => {
+ promises.push(model.save());
+ });
+ });
+ return Promise.all(promises);
+};
+
+// Always use the MongoDB URL to allow
+// easy connection in all environments
+const mongodbUrl = process.env.NODE_ENV === 'production'
+ ? process.env[config.use_env_variable]
+ : `mongodb://${config.host}/${config.database}`;
+
+mongooseeder.seed({
+ mongodbUrl: mongodbUrl,
+ seeds: seeds,
+ clean: true,
+ models: models,
+ mongoose: mongoose
+});
diff --git a/views/posts/index.handlebars b/views/posts/index.handlebars
new file mode 100644
index 0000000..fc980cf
--- /dev/null
+++ b/views/posts/index.handlebars
@@ -0,0 +1,40 @@
+
+
+
+
+
+{{#if posts.length }}
+
+{{else }}
+ No posts
+{{/if }}
diff --git a/views/posts/show.handlebars b/views/posts/show.handlebars
new file mode 100644
index 0000000..e69de29
diff --git a/views/shared/_nav.handlebars b/views/shared/_nav.handlebars
index 0069090..fbbebb6 100644
--- a/views/shared/_nav.handlebars
+++ b/views/shared/_nav.handlebars
@@ -20,7 +20,7 @@
Menu
Logout
From c8f3ae882b81d953e0dee5f105994679d04121a6 Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Thu, 2 Nov 2017 20:06:52 -0700
Subject: [PATCH 05/15] created post show view
---
models/comment.js | 24 ++++++++++++++++++++++++
models/index.js | 2 ++
models/votable.js | 0
routers/posts.js | 1 +
seeds/index.js | 9 ++++++++-
views/posts/show.handlebars | 7 +++++++
6 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 models/comment.js
create mode 100644 models/votable.js
diff --git a/models/comment.js b/models/comment.js
new file mode 100644
index 0000000..181e7ce
--- /dev/null
+++ b/models/comment.js
@@ -0,0 +1,24 @@
+const mongoose = require('mongoose');
+var Schema = mongoose.Schema;
+
+var CommentSchema = new Schema(
+ {
+ body: String,
+ author: {
+ type: Schema.Types.ObjectId,
+ ref: 'User'
+ },
+ parent: {
+ type: Schema.Types.ObjectId,
+ ref: 'Votable'
+ }
+ },
+ {
+ timestamps: true,
+ discriminatorKey: 'kind'
+ }
+);
+
+var Comment = mongoose.model('Comment', CommentSchema);
+
+module.exports = Comment;
diff --git a/models/index.js b/models/index.js
index 994f4a3..d1a6a71 100644
--- a/models/index.js
+++ b/models/index.js
@@ -11,6 +11,8 @@ var models = {};
// models.User = require('./user');
//... more models
models.User = require('./user');
+models.Votable = require('./votable');
models.Post = require('./post');
+models.Comment = require('./comment');
module.exports = models;
diff --git a/models/votable.js b/models/votable.js
new file mode 100644
index 0000000..e69de29
diff --git a/routers/posts.js b/routers/posts.js
index b60d84b..d91d19b 100644
--- a/routers/posts.js
+++ b/routers/posts.js
@@ -21,6 +21,7 @@ router.get('/', (req, res) => {
// ----------------------------------------
router.get('/:id', (req, res) => {
Post.findById(req.params.id)
+ .populate('author')
.then(post => {
res.render('posts/show', { post });
})
diff --git a/seeds/index.js b/seeds/index.js
index 0b0b68d..7bd8b85 100644
--- a/seeds/index.js
+++ b/seeds/index.js
@@ -18,6 +18,13 @@ const seeds = () => {
// ----------------------------------------
console.log('Creating Users');
var users = [];
+ var user = new User({
+ fname: 'Tyler',
+ lname: 'Ketron',
+ username: 'tketron',
+ email: 'tketron@gmail.com'
+ });
+ users.push(user);
for (let i = 0; i < MULTIPLIER * 2; i++) {
var user = new User({
fname: 'Foo',
@@ -37,7 +44,7 @@ const seeds = () => {
var post = new Post({
title: 'A Post',
body: 'This is an example post on Thoreddit',
- author: users[i]
+ author: users[Math.floor(Math.random() * users.length)]
});
posts.push(post);
}
diff --git a/views/posts/show.handlebars b/views/posts/show.handlebars
index e69de29..ad29711 100644
--- a/views/posts/show.handlebars
+++ b/views/posts/show.handlebars
@@ -0,0 +1,7 @@
+
From f69c7fa3dff630b4714adf897bd6c9f1fb6df7f3 Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Mon, 6 Nov 2017 21:53:24 -0800
Subject: [PATCH 06/15] refactored posts view page
---
app.js | 8 ++++++-
models/votable.js | 16 ++++++++++++++
routers/posts.js | 12 +++++++++-
seeds/index.js | 24 +++++++++++++++-----
views/posts/index.handlebars | 43 ++++++++++++------------------------
views/posts/show.handlebars | 14 ++++++++++++
6 files changed, 81 insertions(+), 36 deletions(-)
diff --git a/app.js b/app.js
index 5ca3065..c02a634 100644
--- a/app.js
+++ b/app.js
@@ -90,7 +90,13 @@ var expressHandlebars = require('express-handlebars');
var hbs = expressHandlebars.create({
partialsDir: 'views/',
- defaultLayout: 'application'
+ defaultLayout: 'application',
+ helpers: {
+ trimPostBody: function(bodyText) {
+ var trimmedBody = bodyText.substring(0, 50) + `...`;
+ return trimmedBody;
+ }
+ }
});
app.engine('handlebars', hbs.engine);
diff --git a/models/votable.js b/models/votable.js
index e69de29..a53adde 100644
--- a/models/votable.js
+++ b/models/votable.js
@@ -0,0 +1,16 @@
+const mongoose = require('mongoose');
+var Schema = mongoose.Schema;
+
+var VotableSchema = new Schema(
+ {
+ score: Number
+ },
+ {
+ timestamps: true,
+ discriminatorKey: 'kind'
+ }
+);
+
+var Votable = mongoose.model('Votable', VotableSchema);
+
+module.exports = Votable;
diff --git a/routers/posts.js b/routers/posts.js
index d91d19b..fa6f6b1 100644
--- a/routers/posts.js
+++ b/routers/posts.js
@@ -3,6 +3,8 @@ var router = express.Router();
const mongoose = require('mongoose');
var models = require('./../models');
var Post = mongoose.model('Post');
+var Comment = mongoose.model('Comment');
+var ObjectId = require('mongoose').Types.ObjectId;
// ----------------------------------------
// Index
@@ -23,7 +25,15 @@ router.get('/:id', (req, res) => {
Post.findById(req.params.id)
.populate('author')
.then(post => {
- res.render('posts/show', { post });
+ console.log('Post: ' + post);
+ Comment.find({
+ parent: new ObjectId(post._id)
+ })
+ .populate('author')
+ .then(comments => {
+ console.log('Comments: ' + comments);
+ res.render('posts/show', { post, comments });
+ });
})
.catch(e => res.status(500).send(e.stack));
});
diff --git a/seeds/index.js b/seeds/index.js
index 7bd8b85..c182354 100644
--- a/seeds/index.js
+++ b/seeds/index.js
@@ -4,7 +4,7 @@ var env = process.env.NODE_ENV || 'development';
var config = require('./../config/mongo')[env];
const mongooseeder = require('mongooseeder');
-const { User, Post } = models;
+const { User, Votable, Post, Comment } = models;
const MULTIPLIER = 5;
@@ -27,8 +27,8 @@ const seeds = () => {
users.push(user);
for (let i = 0; i < MULTIPLIER * 2; i++) {
var user = new User({
- fname: 'Foo',
- lname: 'Bar',
+ fname: `Foo${i}`,
+ lname: `Bar${i}`,
username: `foobar${i}`,
email: `foobar${i}@gmail.com`
});
@@ -44,10 +44,24 @@ const seeds = () => {
var post = new Post({
title: 'A Post',
body: 'This is an example post on Thoreddit',
- author: users[Math.floor(Math.random() * users.length)]
+ author: users[Math.floor(Math.random() * users.length)],
+ score: Math.floor(Math.random() * 100)
});
posts.push(post);
}
+ // ----------------------------------------
+ // Comments
+ // ----------------------------------------
+ console.log('Creating Comments');
+ var comments = [];
+ for (let i = 0; i < MULTIPLIER * 5; i++) {
+ var comment = new Comment({
+ body: 'This is an example comment.',
+ author: users[Math.floor(Math.random() * users.length)],
+ parent: posts[Math.floor(Math.random() * posts.length)]
+ });
+ comments.push(comment);
+ }
// // ----------------------------------------
// // Ratings
// // ----------------------------------------
@@ -78,7 +92,7 @@ const seeds = () => {
// ----------------------------------------
console.log('Saving...');
var promises = [];
- [users, posts].forEach(collection => {
+ [users, posts, comments].forEach(collection => {
collection.forEach(model => {
promises.push(model.save());
});
diff --git a/views/posts/index.handlebars b/views/posts/index.handlebars
index fc980cf..72530d5 100644
--- a/views/posts/index.handlebars
+++ b/views/posts/index.handlebars
@@ -6,35 +6,20 @@
-{{#if posts.length }}
-
+{{#if posts.length}}
+
+ {{#each posts as |post|}}
+ -
+
+
+
+ {{{trimPostBody post.body}}}
+
+
+
+
+ {{/each}}
+
{{else }}
No posts
{{/if }}
diff --git a/views/posts/show.handlebars b/views/posts/show.handlebars
index ad29711..b7c9a64 100644
--- a/views/posts/show.handlebars
+++ b/views/posts/show.handlebars
@@ -4,4 +4,18 @@
{{ post.body }}
+
+ Score: {{ post.score }}
+
+
+{{#each comments as |comment| }}
+
+
+ {{comment.author.fname }} {{comment.author.lname}} said:
+
+
+ {{comment.body}}
+
+
+{{/each }}
From 9549c1bfc32073f81a06309d3cd827ffd402492f Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Mon, 6 Nov 2017 22:13:49 -0800
Subject: [PATCH 07/15] allowed post and comment models to inherit score from
votable model
---
models/comment.js | 4 +++-
models/post.js | 4 +++-
seeds/index.js | 3 ++-
views/posts/show.handlebars | 3 +++
4 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/models/comment.js b/models/comment.js
index 181e7ce..6f73ca8 100644
--- a/models/comment.js
+++ b/models/comment.js
@@ -1,5 +1,6 @@
const mongoose = require('mongoose');
var Schema = mongoose.Schema;
+var Votable = require('./votable');
var CommentSchema = new Schema(
{
@@ -19,6 +20,7 @@ var CommentSchema = new Schema(
}
);
-var Comment = mongoose.model('Comment', CommentSchema);
+// var Comment = mongoose.model('Comment', CommentSchema);
+var Comment = Votable.discriminator('Comment', CommentSchema);
module.exports = Comment;
diff --git a/models/post.js b/models/post.js
index f0da077..693298e 100644
--- a/models/post.js
+++ b/models/post.js
@@ -1,5 +1,6 @@
const mongoose = require('mongoose');
var Schema = mongoose.Schema;
+var Votable = require('./votable');
var PostSchema = new Schema(
{
@@ -16,6 +17,7 @@ var PostSchema = new Schema(
}
);
-var Post = mongoose.model('Post', PostSchema);
+// var Post = mongoose.model('Post', PostSchema);
+var Post = Votable.discriminator('Post', PostSchema);
module.exports = Post;
diff --git a/seeds/index.js b/seeds/index.js
index c182354..ac6ad88 100644
--- a/seeds/index.js
+++ b/seeds/index.js
@@ -58,7 +58,8 @@ const seeds = () => {
var comment = new Comment({
body: 'This is an example comment.',
author: users[Math.floor(Math.random() * users.length)],
- parent: posts[Math.floor(Math.random() * posts.length)]
+ parent: posts[Math.floor(Math.random() * posts.length)],
+ score: Math.floor(Math.random() * 100)
});
comments.push(comment);
}
diff --git a/views/posts/show.handlebars b/views/posts/show.handlebars
index b7c9a64..ba997fb 100644
--- a/views/posts/show.handlebars
+++ b/views/posts/show.handlebars
@@ -17,5 +17,8 @@
{{comment.body}}
+
+ Score: {{comment.score}}
+
{{/each }}
From 088b7cb88a9b4001d4763e5757ef5f48f8a74d8a Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Tue, 7 Nov 2017 20:50:45 -0800
Subject: [PATCH 08/15] refactored post and comment view
---
routers/posts.js | 2 +-
views/posts/show.handlebars | 18 ++++++++++++++----
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/routers/posts.js b/routers/posts.js
index fa6f6b1..1533a65 100644
--- a/routers/posts.js
+++ b/routers/posts.js
@@ -25,11 +25,11 @@ router.get('/:id', (req, res) => {
Post.findById(req.params.id)
.populate('author')
.then(post => {
- console.log('Post: ' + post);
Comment.find({
parent: new ObjectId(post._id)
})
.populate('author')
+ .sort({ score: -1 })
.then(comments => {
console.log('Comments: ' + comments);
res.render('posts/show', { post, comments });
diff --git a/views/posts/show.handlebars b/views/posts/show.handlebars
index ba997fb..c9edf89 100644
--- a/views/posts/show.handlebars
+++ b/views/posts/show.handlebars
@@ -9,16 +9,26 @@
+
+
{{#each comments as |comment| }}
-
+
+
+
{{comment.author.fname }} {{comment.author.lname}} said:
{{comment.body}}
-
- Score: {{comment.score}}
-
+
+
{{/each }}
+
+
+
From 019ed7ccb2d993cf8cae0feaf1181be100b70fcc Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Mon, 13 Nov 2017 23:22:24 -0800
Subject: [PATCH 09/15] added ability to query child comments from the database
---
models/childcomment.js | 30 ++++++++++++++++++++++++++++++
models/comment.js | 8 +++++++-
models/index.js | 1 +
routers/posts.js | 11 +++++++++--
seeds/index.js | 15 +++++++++++++--
views/posts/show.handlebars | 7 +++++++
6 files changed, 67 insertions(+), 5 deletions(-)
create mode 100644 models/childcomment.js
diff --git a/models/childcomment.js b/models/childcomment.js
new file mode 100644
index 0000000..c9b93ff
--- /dev/null
+++ b/models/childcomment.js
@@ -0,0 +1,30 @@
+const mongoose = require('mongoose');
+var Schema = mongoose.Schema;
+var Votable = require('./votable');
+
+var ChildCommentSchema = new Schema(
+ {
+ body: String,
+ author: {
+ type: Schema.Types.ObjectId,
+ ref: 'User'
+ },
+ parent: {
+ type: Schema.Types.ObjectId,
+ ref: 'Votable'
+ },
+ parent_post: {
+ type: Schema.Types.ObjectId,
+ ref: 'Post'
+ }
+ },
+ {
+ timestamps: true,
+ discriminatorKey: 'kind'
+ }
+);
+
+// var Comment = mongoose.model('Comment', CommentSchema);
+var ChildComment = Votable.discriminator('ChildComment', ChildCommentSchema);
+
+module.exports = ChildComment;
diff --git a/models/comment.js b/models/comment.js
index 6f73ca8..6d09a18 100644
--- a/models/comment.js
+++ b/models/comment.js
@@ -12,7 +12,13 @@ var CommentSchema = new Schema(
parent: {
type: Schema.Types.ObjectId,
ref: 'Votable'
- }
+ },
+ children: [
+ {
+ type: Schema.Types.ObjectId,
+ ref: 'ChildComment'
+ }
+ ]
},
{
timestamps: true,
diff --git a/models/index.js b/models/index.js
index d1a6a71..8e324e9 100644
--- a/models/index.js
+++ b/models/index.js
@@ -14,5 +14,6 @@ models.User = require('./user');
models.Votable = require('./votable');
models.Post = require('./post');
models.Comment = require('./comment');
+models.ChildComment = require('./childcomment');
module.exports = models;
diff --git a/routers/posts.js b/routers/posts.js
index 1533a65..e16715e 100644
--- a/routers/posts.js
+++ b/routers/posts.js
@@ -4,6 +4,7 @@ const mongoose = require('mongoose');
var models = require('./../models');
var Post = mongoose.model('Post');
var Comment = mongoose.model('Comment');
+var ChildComment = mongoose.model('ChildComment');
var ObjectId = require('mongoose').Types.ObjectId;
// ----------------------------------------
@@ -21,7 +22,7 @@ router.get('/', (req, res) => {
// ----------------------------------------
// Show
// ----------------------------------------
-router.get('/:id', (req, res) => {
+router.get('/:id', (req, res, next) => {
Post.findById(req.params.id)
.populate('author')
.then(post => {
@@ -30,7 +31,13 @@ router.get('/:id', (req, res) => {
})
.populate('author')
.sort({ score: -1 })
- .then(comments => {
+ .then(async comments => {
+ for (let comment of comments) {
+ const childComments = await ChildComment.find({
+ parent: comment._id
+ }).populate('author');
+ comment.children = childComments;
+ }
console.log('Comments: ' + comments);
res.render('posts/show', { post, comments });
});
diff --git a/seeds/index.js b/seeds/index.js
index ac6ad88..2260c1f 100644
--- a/seeds/index.js
+++ b/seeds/index.js
@@ -4,7 +4,7 @@ var env = process.env.NODE_ENV || 'development';
var config = require('./../config/mongo')[env];
const mongooseeder = require('mongooseeder');
-const { User, Votable, Post, Comment } = models;
+const { User, Votable, Post, Comment, ChildComment } = models;
const MULTIPLIER = 5;
@@ -54,6 +54,7 @@ const seeds = () => {
// ----------------------------------------
console.log('Creating Comments');
var comments = [];
+ var childComments = [];
for (let i = 0; i < MULTIPLIER * 5; i++) {
var comment = new Comment({
body: 'This is an example comment.',
@@ -61,8 +62,18 @@ const seeds = () => {
parent: posts[Math.floor(Math.random() * posts.length)],
score: Math.floor(Math.random() * 100)
});
+ var childComment = new ChildComment({
+ body: 'This is a child comment.',
+ author: users[Math.floor(Math.random() * users.length)],
+ parent: comment,
+ parent_post: comment.parent,
+ score: Math.floor(Math.random() * 100)
+ });
+ comment.children.push(comment);
+ childComments.push(childComment);
comments.push(comment);
}
+
// // ----------------------------------------
// // Ratings
// // ----------------------------------------
@@ -93,7 +104,7 @@ const seeds = () => {
// ----------------------------------------
console.log('Saving...');
var promises = [];
- [users, posts, comments].forEach(collection => {
+ [users, posts, comments, childComments].forEach(collection => {
collection.forEach(model => {
promises.push(model.save());
});
diff --git a/views/posts/show.handlebars b/views/posts/show.handlebars
index c9edf89..708ddb2 100644
--- a/views/posts/show.handlebars
+++ b/views/posts/show.handlebars
@@ -7,6 +7,7 @@
Score: {{ post.score }}
+ Comment
@@ -21,6 +22,7 @@
{{comment.body}}
+
Comment
Upvote
@@ -28,6 +30,11 @@
Score: {{comment.score}}
+
+{{#each comment.children as |child| }}
+{{child.author.fname}} {{child.author.lname}}
+{{/each}}
+
{{/each }}
From a7cbd82aad149dee845dac1af16868e26db44474 Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Mon, 13 Nov 2017 23:24:13 -0800
Subject: [PATCH 10/15] updated post view with child comments
---
views/posts/show.handlebars | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/views/posts/show.handlebars b/views/posts/show.handlebars
index 708ddb2..7b0605d 100644
--- a/views/posts/show.handlebars
+++ b/views/posts/show.handlebars
@@ -32,7 +32,22 @@
{{#each comment.children as |child| }}
-{{child.author.fname}} {{child.author.lname}}
+
+
+
+
+ {{child.author.fname }} {{child.author.lname}} said:
+
+
+ {{child.body}}
+
+
+
+
{{/each}}
{{/each }}
From 867c2650e670941c58f122010c859945f493b75e Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Thu, 16 Nov 2017 18:02:38 -0800
Subject: [PATCH 11/15] new comment routes enabled
---
models/childcomment.js | 4 ----
models/votable.js | 6 +++++-
routers/posts.js | 36 +++++++++++++++++++++++++++++++++--
seeds/index.js | 2 ++
views/comments/new.handlebars | 15 +++++++++++++++
views/posts/show.handlebars | 4 ++--
6 files changed, 58 insertions(+), 9 deletions(-)
create mode 100644 views/comments/new.handlebars
diff --git a/models/childcomment.js b/models/childcomment.js
index c9b93ff..b30fa1a 100644
--- a/models/childcomment.js
+++ b/models/childcomment.js
@@ -12,10 +12,6 @@ var ChildCommentSchema = new Schema(
parent: {
type: Schema.Types.ObjectId,
ref: 'Votable'
- },
- parent_post: {
- type: Schema.Types.ObjectId,
- ref: 'Post'
}
},
{
diff --git a/models/votable.js b/models/votable.js
index a53adde..5e40baf 100644
--- a/models/votable.js
+++ b/models/votable.js
@@ -3,7 +3,11 @@ var Schema = mongoose.Schema;
var VotableSchema = new Schema(
{
- score: Number
+ score: Number,
+ parent_post: {
+ type: Schema.Types.ObjectId,
+ ref: 'Post'
+ }
},
{
timestamps: true,
diff --git a/routers/posts.js b/routers/posts.js
index e16715e..ea86d98 100644
--- a/routers/posts.js
+++ b/routers/posts.js
@@ -22,7 +22,7 @@ router.get('/', (req, res) => {
// ----------------------------------------
// Show
// ----------------------------------------
-router.get('/:id', (req, res, next) => {
+router.get('/:id', (req, res) => {
Post.findById(req.params.id)
.populate('author')
.then(post => {
@@ -30,12 +30,15 @@ router.get('/:id', (req, res, next) => {
parent: new ObjectId(post._id)
})
.populate('author')
+ .populate('parent')
.sort({ score: -1 })
.then(async comments => {
for (let comment of comments) {
const childComments = await ChildComment.find({
parent: comment._id
- }).populate('author');
+ })
+ .populate('author')
+ .populate('comment');
comment.children = childComments;
}
console.log('Comments: ' + comments);
@@ -45,4 +48,33 @@ router.get('/:id', (req, res, next) => {
.catch(e => res.status(500).send(e.stack));
});
+// ----------------------------------------
+// Show
+// ----------------------------------------
+router.get('/:id/comment', (req, res) => {
+ var parentType = 'Post';
+ Post.findById(req.params.id).populate('parent_post').then(parent => {
+ console.log('Parent post: ' + parent.id);
+ // parent.parent_post.id = parent.id;
+ res.render('comments/new', { parentType, parent });
+ });
+});
+
+router.get('/:id/comment/:commentID', (req, res) => {
+ var parentType = 'Comment';
+ Comment.findById(req.params.commentID)
+ .populate('parent_post')
+ .then(parent => {
+ console.log('Parent id: ' + parent.parent_post.id);
+ res.render('comments/new', { parentType, parent });
+ });
+});
+
+router.post('/:id', (req, res) => {
+ //save comment to db
+
+ //redirect to post page
+ res.render('posts/show');
+});
+
module.exports = router;
diff --git a/seeds/index.js b/seeds/index.js
index 2260c1f..887472e 100644
--- a/seeds/index.js
+++ b/seeds/index.js
@@ -47,6 +47,7 @@ const seeds = () => {
author: users[Math.floor(Math.random() * users.length)],
score: Math.floor(Math.random() * 100)
});
+ post.parent_post = post;
posts.push(post);
}
// ----------------------------------------
@@ -62,6 +63,7 @@ const seeds = () => {
parent: posts[Math.floor(Math.random() * posts.length)],
score: Math.floor(Math.random() * 100)
});
+ comment.parent_post = comment.parent;
var childComment = new ChildComment({
body: 'This is a child comment.',
author: users[Math.floor(Math.random() * users.length)],
diff --git a/views/comments/new.handlebars b/views/comments/new.handlebars
new file mode 100644
index 0000000..81b8c0e
--- /dev/null
+++ b/views/comments/new.handlebars
@@ -0,0 +1,15 @@
+New Comment
+
+Commenting on a {{parentType}}
+
+
+ Original Message: {{parent.body}}
+
+
+
diff --git a/views/posts/show.handlebars b/views/posts/show.handlebars
index 7b0605d..46379b2 100644
--- a/views/posts/show.handlebars
+++ b/views/posts/show.handlebars
@@ -7,7 +7,7 @@
Score: {{ post.score }}
- Comment
+ Comment
Upvote
From 170850ba1056a9c2d6dbb011a8da996e1f56b84a Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Sun, 19 Nov 2017 23:25:14 -0800
Subject: [PATCH 12/15] implemented saving new comments to db
---
routers/posts.js | 55 +++++++++++++++++-
routers/posts_alternate.js | 106 ++++++++++++++++++++++++++++++++++
views/comments/new.handlebars | 7 ++-
3 files changed, 162 insertions(+), 6 deletions(-)
create mode 100644 routers/posts_alternate.js
diff --git a/routers/posts.js b/routers/posts.js
index ea86d98..dc6170b 100644
--- a/routers/posts.js
+++ b/routers/posts.js
@@ -4,6 +4,8 @@ const mongoose = require('mongoose');
var models = require('./../models');
var Post = mongoose.model('Post');
var Comment = mongoose.model('Comment');
+var User = mongoose.model('User');
+var Votable = mongoose.model('Votable');
var ChildComment = mongoose.model('ChildComment');
var ObjectId = require('mongoose').Types.ObjectId;
@@ -38,7 +40,8 @@ router.get('/:id', (req, res) => {
parent: comment._id
})
.populate('author')
- .populate('comment');
+ .populate('parent')
+ .sort({ score: -1 });
comment.children = childComments;
}
console.log('Comments: ' + comments);
@@ -70,11 +73,57 @@ router.get('/:id/comment/:commentID', (req, res) => {
});
});
-router.post('/:id', (req, res) => {
+router.post('/:id', async (req, res) => {
//save comment to db
+ const parentComment = await Votable.findById(req.params.id)
+ .populate('author')
+ .populate('parent_post');
+
+ console.log('Parent Comment' + parentComment);
+
+ var commentText = req.body.comment;
+ console.log('Comment Text: ' + req.body.comment);
+
+ const user = await User.find({
+ username: req.session.currentUser.username
+ });
+ console.log('Current User: ' + user);
+ // console.log('User: ' + req.session.currentUser.username);
+
+ //parent is votable ObjectId
+ //parent_post is votable parent_post
+ //author is from session
+ //make comment or childcomment depending on level
+ var comment;
+ if (parentComment.id === parentComment.parent_post.id) {
+ comment = new Comment({
+ body: req.body.comment,
+ author: new ObjectId(user.id),
+ parent: new ObjectId(parentComment.id),
+ score: 50,
+ parent_post: parentComment.parent_post
+ });
+ } else {
+ comment = new ChildComment({
+ body: req.body.comment,
+ author: new ObjectId(user.id),
+ parent: new ObjectId(parentComment.id),
+ score: 50,
+ parent_post: parentComment.parent_post
+ });
+ }
+
+ // comment.parent_post = comment.parentComment.parent_post;
//redirect to post page
- res.render('posts/show');
+ comment
+ .save()
+ .then(comment => {
+ res.redirect(`${comment.parent_post.id}`);
+ })
+ .catch(e => res.status(500).send(e.stack));
+ // res.render('posts/show');
+ // res.redirect(`posts/${comment.parent_post.id}`);
});
module.exports = router;
diff --git a/routers/posts_alternate.js b/routers/posts_alternate.js
new file mode 100644
index 0000000..3d1bf1a
--- /dev/null
+++ b/routers/posts_alternate.js
@@ -0,0 +1,106 @@
+var express = require('express');
+var router = express.Router();
+const mongoose = require('mongoose');
+var models = require('./../models');
+var Post = mongoose.model('Post');
+var Comment = mongoose.model('Comment');
+var Votable = mongoose.model('Votable');
+var ChildComment = mongoose.model('ChildComment');
+var ObjectId = require('mongoose').Types.ObjectId;
+
+// ----------------------------------------
+// Index
+// ----------------------------------------
+module.exports = app => {
+ router.get('/', (req, res) => {
+ Post.find()
+ .populate('author')
+ .then(posts => {
+ res.render('posts/index', { posts });
+ })
+ .catch(e => res.status(500).send(e.stack));
+ });
+
+ // ----------------------------------------
+ // Show
+ // ----------------------------------------
+ router.get('/:id', (req, res) => {
+ Post.findById(req.params.id)
+ .populate('author')
+ .then(post => {
+ Comment.find({
+ parent: new ObjectId(post._id)
+ })
+ .populate('author')
+ .populate('parent')
+ .sort({ score: -1 })
+ .then(async comments => {
+ for (let comment of comments) {
+ const childComments = await ChildComment.find({
+ parent: comment._id
+ })
+ .populate('author')
+ .populate('comment')
+ .sort({ score: -1 });
+ comment.children = childComments;
+ }
+ console.log('Comments: ' + comments);
+ res.render('posts/show', { post, comments });
+ });
+ })
+ .catch(e => res.status(500).send(e.stack));
+ });
+
+ // ----------------------------------------
+ // Show
+ // ----------------------------------------
+ router.get('/:id/comment', (req, res) => {
+ var parentType = 'Post';
+ Post.findById(req.params.id).populate('parent_post').then(parent => {
+ console.log('Parent post: ' + parent.id);
+ // parent.parent_post.id = parent.id;
+ res.render('comments/new', { parentType, parent });
+ });
+ });
+
+ router.get('/:id/comment/:commentID', (req, res) => {
+ var parentType = 'Comment';
+ Comment.findById(req.params.commentID)
+ .populate('parent_post')
+ .then(parent => {
+ console.log('Parent id: ' + parent.parent_post.id);
+ res.render('comments/new', { parentType, parent });
+ });
+ });
+
+ router.post('/:id', (req, res) => {
+ //save comment to db
+ var parentComment = Votable.findById(req.params.id)
+ .populate('author')
+ .populate('parent_post')
+ .then(parent => {
+ console.log(parent);
+ });
+
+ var commentText = req.body.comment;
+ console.log('Comment Text: ' + req.body.comment);
+
+ console.log('User: ' + req.session.currentUser);
+
+ //parent is votable ObjectId
+ //parent_post is votable parent_post
+ //author is from session
+
+ // var comment = new Comment({
+ // body: req.body.comment_text,
+ // author: users[Math.floor(Math.random() * users.length)],
+ // parent: posts[Math.floor(Math.random() * posts.length)],
+ // score: 5
+ // });
+ // comment.parent_post = comment.parent;
+ //redirect to post page
+ res.render('posts/show');
+ });
+
+ return router;
+};
diff --git a/views/comments/new.handlebars b/views/comments/new.handlebars
index 81b8c0e..0c1fe41 100644
--- a/views/comments/new.handlebars
+++ b/views/comments/new.handlebars
@@ -6,10 +6,11 @@
Original Message: {{parent.body}}
-
From b98d9d160a7cb05ed1b1b5b7b13221a99e2aad3e Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Mon, 20 Nov 2017 17:44:25 -0800
Subject: [PATCH 13/15] implemented upvote/downvote functions
---
models/votable.js | 51 ++++++++++++++++++++++++++++++++++++-
routers/posts.js | 38 +++++++++++++--------------
views/posts/show.handlebars | 8 +++---
3 files changed, 73 insertions(+), 24 deletions(-)
diff --git a/models/votable.js b/models/votable.js
index 5e40baf..23c63e1 100644
--- a/models/votable.js
+++ b/models/votable.js
@@ -7,7 +7,9 @@ var VotableSchema = new Schema(
parent_post: {
type: Schema.Types.ObjectId,
ref: 'Post'
- }
+ },
+ hasUpvoted: [String],
+ hasDownvoted: [String]
},
{
timestamps: true,
@@ -15,6 +17,53 @@ var VotableSchema = new Schema(
}
);
+VotableSchema.methods.upvote = function(username) {
+ console.log('Upvoted: ' + this.hasUpvoted);
+ if (this.hasUpvoted.includes(username)) {
+ console.log('already upvoted');
+ this.score = this.score - 1;
+ remove(this.hasUpvoted, username);
+ this.save();
+ } else if (this.hasDownvoted.includes(username)) {
+ console.log('already downvoted');
+ this.score = this.score + 2;
+ remove(this.hasDownvoted, username);
+ this.hasUpvoted.push(username);
+ this.save();
+ } else {
+ this.hasUpvoted.push(username);
+ this.score = this.score + 1;
+ this.save();
+ }
+};
+
+VotableSchema.methods.downvote = function(username) {
+ if (this.hasDownvoted.includes(username)) {
+ console.log('already downvoted');
+ this.score = this.score + 1;
+ remove(this.hasDownvoted, username);
+ this.save();
+ } else if (this.hasUpvoted.includes(username)) {
+ console.log('already upvoted');
+ this.score = this.score - 2;
+ remove(this.hasUpvoted, username);
+ this.hasDownvoted.push(username);
+ this.save();
+ } else {
+ this.hasDownvoted.push(username);
+ this.score = this.score - 1;
+ this.save();
+ }
+};
+
+function remove(array, element) {
+ const index = array.indexOf(element);
+
+ if (index !== -1) {
+ array.splice(index, 1);
+ }
+}
+
var Votable = mongoose.model('Votable', VotableSchema);
module.exports = Votable;
diff --git a/routers/posts.js b/routers/posts.js
index dc6170b..2a53a5b 100644
--- a/routers/posts.js
+++ b/routers/posts.js
@@ -44,7 +44,6 @@ router.get('/:id', (req, res) => {
.sort({ score: -1 });
comment.children = childComments;
}
- console.log('Comments: ' + comments);
res.render('posts/show', { post, comments });
});
})
@@ -74,32 +73,20 @@ router.get('/:id/comment/:commentID', (req, res) => {
});
router.post('/:id', async (req, res) => {
- //save comment to db
const parentComment = await Votable.findById(req.params.id)
.populate('author')
.populate('parent_post');
- console.log('Parent Comment' + parentComment);
-
- var commentText = req.body.comment;
- console.log('Comment Text: ' + req.body.comment);
-
const user = await User.find({
username: req.session.currentUser.username
});
- console.log('Current User: ' + user);
- // console.log('User: ' + req.session.currentUser.username);
-
- //parent is votable ObjectId
- //parent_post is votable parent_post
- //author is from session
//make comment or childcomment depending on level
var comment;
if (parentComment.id === parentComment.parent_post.id) {
comment = new Comment({
body: req.body.comment,
- author: new ObjectId(user.id),
+ author: user,
parent: new ObjectId(parentComment.id),
score: 50,
parent_post: parentComment.parent_post
@@ -107,23 +94,36 @@ router.post('/:id', async (req, res) => {
} else {
comment = new ChildComment({
body: req.body.comment,
- author: new ObjectId(user.id),
+ author: user,
parent: new ObjectId(parentComment.id),
score: 50,
parent_post: parentComment.parent_post
});
}
- // comment.parent_post = comment.parentComment.parent_post;
- //redirect to post page
comment
.save()
.then(comment => {
res.redirect(`${comment.parent_post.id}`);
})
.catch(e => res.status(500).send(e.stack));
- // res.render('posts/show');
- // res.redirect(`posts/${comment.parent_post.id}`);
+});
+
+router.get('/upvote/:id', async (req, res) => {
+ // const user = await User.find({
+ // username: req.session.currentUser.username
+ // });
+ // console.log('User: ' + user);
+ const votableTarget = await Votable.findById(req.params.id);
+
+ votableTarget.upvote(req.session.currentUser.username);
+ res.redirect('back');
+});
+
+router.get('/downvote/:id', async (req, res) => {
+ const votableTarget = await Votable.findById(req.params.id);
+ votableTarget.downvote(req.session.currentUser.username);
+ res.redirect('back');
});
module.exports = router;
diff --git a/views/posts/show.handlebars b/views/posts/show.handlebars
index 46379b2..cdcdcd3 100644
--- a/views/posts/show.handlebars
+++ b/views/posts/show.handlebars
@@ -25,8 +25,8 @@
Comment
@@ -43,8 +43,8 @@
From ef0e30c5b8890d1a90a17d313257592321c3fbd6 Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Mon, 20 Nov 2017 17:54:03 -0800
Subject: [PATCH 14/15] bug fixes
---
models/votable.js | 5 -----
routers/posts.js | 9 +++------
2 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/models/votable.js b/models/votable.js
index 23c63e1..e11ebf2 100644
--- a/models/votable.js
+++ b/models/votable.js
@@ -18,14 +18,11 @@ var VotableSchema = new Schema(
);
VotableSchema.methods.upvote = function(username) {
- console.log('Upvoted: ' + this.hasUpvoted);
if (this.hasUpvoted.includes(username)) {
- console.log('already upvoted');
this.score = this.score - 1;
remove(this.hasUpvoted, username);
this.save();
} else if (this.hasDownvoted.includes(username)) {
- console.log('already downvoted');
this.score = this.score + 2;
remove(this.hasDownvoted, username);
this.hasUpvoted.push(username);
@@ -39,12 +36,10 @@ VotableSchema.methods.upvote = function(username) {
VotableSchema.methods.downvote = function(username) {
if (this.hasDownvoted.includes(username)) {
- console.log('already downvoted');
this.score = this.score + 1;
remove(this.hasDownvoted, username);
this.save();
} else if (this.hasUpvoted.includes(username)) {
- console.log('already upvoted');
this.score = this.score - 2;
remove(this.hasUpvoted, username);
this.hasDownvoted.push(username);
diff --git a/routers/posts.js b/routers/posts.js
index 2a53a5b..e0fe549 100644
--- a/routers/posts.js
+++ b/routers/posts.js
@@ -80,13 +80,14 @@ router.post('/:id', async (req, res) => {
const user = await User.find({
username: req.session.currentUser.username
});
+ console.log('commenting user: ' + user);
//make comment or childcomment depending on level
var comment;
if (parentComment.id === parentComment.parent_post.id) {
comment = new Comment({
body: req.body.comment,
- author: user,
+ author: new ObjectId(user.id),
parent: new ObjectId(parentComment.id),
score: 50,
parent_post: parentComment.parent_post
@@ -94,7 +95,7 @@ router.post('/:id', async (req, res) => {
} else {
comment = new ChildComment({
body: req.body.comment,
- author: user,
+ author: new ObjectId(user.id),
parent: new ObjectId(parentComment.id),
score: 50,
parent_post: parentComment.parent_post
@@ -110,10 +111,6 @@ router.post('/:id', async (req, res) => {
});
router.get('/upvote/:id', async (req, res) => {
- // const user = await User.find({
- // username: req.session.currentUser.username
- // });
- // console.log('User: ' + user);
const votableTarget = await Votable.findById(req.params.id);
votableTarget.upvote(req.session.currentUser.username);
From 404eb2c2ba3747c448151e1aef4dc66070a5d36e Mon Sep 17 00:00:00 2001
From: Tyler Ketron
Date: Wed, 29 Nov 2017 20:15:21 -0800
Subject: [PATCH 15/15] completed refactored model code
---
models/childcomment.js | 8 +-
models/comment.js | 8 +-
models/post.js | 2 +-
package-lock.json | 1251 ++++++++++++++++++++++++++++++++++++++++
package.json | 2 +-
routers/posts.js | 16 +-
seeds/index.js | 5 +-
7 files changed, 1275 insertions(+), 17 deletions(-)
create mode 100644 package-lock.json
diff --git a/models/childcomment.js b/models/childcomment.js
index b30fa1a..ccd5673 100644
--- a/models/childcomment.js
+++ b/models/childcomment.js
@@ -5,13 +5,13 @@ var Votable = require('./votable');
var ChildCommentSchema = new Schema(
{
body: String,
- author: {
- type: Schema.Types.ObjectId,
- ref: 'User'
- },
parent: {
type: Schema.Types.ObjectId,
ref: 'Votable'
+ },
+ author: {
+ type: Schema.Types.ObjectId,
+ red: 'User'
}
},
{
diff --git a/models/comment.js b/models/comment.js
index 6d09a18..4ce0682 100644
--- a/models/comment.js
+++ b/models/comment.js
@@ -5,14 +5,14 @@ var Votable = require('./votable');
var CommentSchema = new Schema(
{
body: String,
- author: {
- type: Schema.Types.ObjectId,
- ref: 'User'
- },
parent: {
type: Schema.Types.ObjectId,
ref: 'Votable'
},
+ author: {
+ type: Schema.Types.ObjectId,
+ red: 'User'
+ },
children: [
{
type: Schema.Types.ObjectId,
diff --git a/models/post.js b/models/post.js
index 693298e..ac056f2 100644
--- a/models/post.js
+++ b/models/post.js
@@ -8,7 +8,7 @@ var PostSchema = new Schema(
body: String,
author: {
type: Schema.Types.ObjectId,
- ref: 'User'
+ red: 'User'
}
},
{
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..f71ec67
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1251 @@
+{
+ "name": "assignment_thoreddit",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "accepts": {
+ "version": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+ "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
+ "requires": {
+ "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+ "negotiator": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz"
+ }
+ },
+ "align-text": {
+ "version": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+ "requires": {
+ "kind-of": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "longest": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "repeat-string": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz"
+ }
+ },
+ "amdefine": {
+ "version": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
+ },
+ "ansi-regex": {
+ "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha1-wVm41b4PnlpvNG2rlPFs4CIWG4g=",
+ "requires": {
+ "color-convert": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz"
+ }
+ },
+ "any-promise": {
+ "version": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+ },
+ "array-flatten": {
+ "version": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "asap": {
+ "version": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ },
+ "async": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz",
+ "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=",
+ "requires": {
+ "lodash": "4.17.4"
+ }
+ },
+ "balanced-match": {
+ "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "basic-auth": {
+ "version": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
+ "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
+ "requires": {
+ "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"
+ }
+ },
+ "bluebird": {
+ "version": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+ "integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk="
+ },
+ "body-parser": {
+ "version": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+ "requires": {
+ "bytes": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "content-type": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "qs": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "raw-body": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz"
+ }
+ },
+ "brace-expansion": {
+ "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "requires": {
+ "balanced-match": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "concat-map": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ }
+ },
+ "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="
+ },
+ "builtin-modules": {
+ "version": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
+ },
+ "bytes": {
+ "version": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ },
+ "camelcase": {
+ "version": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "optional": true
+ },
+ "center-align": {
+ "version": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+ "optional": true,
+ "requires": {
+ "align-text": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "lazy-cache": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz"
+ }
+ },
+ "chalk": {
+ "version": "https://registry.npmjs.org/chalk/-/chalk-2.2.0.tgz",
+ "integrity": "sha1-R3s78vm4/Vyp5Cl0fjf3JO568kA=",
+ "requires": {
+ "ansi-styles": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz"
+ }
+ },
+ "cli-highlight": {
+ "version": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-1.1.4.tgz",
+ "integrity": "sha1-5FWQwU+xjhOGXjiZ6CTFWSzCKSY=",
+ "requires": {
+ "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "he": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+ "highlight.js": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz",
+ "mz": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "yargs": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "chalk": {
+ "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "has-ansi": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
+ }
+ },
+ "cliui": {
+ "version": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "requires": {
+ "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "wrap-ansi": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz"
+ }
+ },
+ "supports-color": {
+ "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ },
+ "window-size": {
+ "version": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
+ "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU="
+ },
+ "yargs": {
+ "version": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
+ "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
+ "requires": {
+ "cliui": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "decamelize": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "get-caller-file": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+ "lodash.assign": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+ "os-locale": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "read-pkg-up": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "require-directory": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "require-main-filename": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "set-blocking": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "which-module": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "window-size": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
+ "y18n": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "yargs-parser": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz"
+ }
+ }
+ }
+ },
+ "cliui": {
+ "version": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+ "optional": true,
+ "requires": {
+ "center-align": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "right-align": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "wordwrap": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+ "optional": true
+ }
+ }
+ },
+ "code-point-at": {
+ "version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "color-convert": {
+ "version": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
+ "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
+ "requires": {
+ "color-name": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
+ }
+ },
+ "color-name": {
+ "version": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "concat-map": {
+ "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "content-disposition": {
+ "version": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
+ },
+ "content-type": {
+ "version": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js="
+ },
+ "cookie": {
+ "version": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+ },
+ "cookie-session": {
+ "version": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.0.0-beta.3.tgz",
+ "integrity": "sha1-TkRr2fhb1+J9PiJvTpmvEgEaQ4Y=",
+ "requires": {
+ "cookies": "https://registry.npmjs.org/cookies/-/cookies-0.7.1.tgz",
+ "debug": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "on-headers": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
+ "requires": {
+ "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
+ }
+ }
+ }
+ },
+ "cookie-signature": {
+ "version": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "cookies": {
+ "version": "https://registry.npmjs.org/cookies/-/cookies-0.7.1.tgz",
+ "integrity": "sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=",
+ "requires": {
+ "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "keygrip": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.2.tgz"
+ }
+ },
+ "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="
+ },
+ "debug": {
+ "version": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+ "requires": {
+ "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
+ }
+ },
+ "decamelize": {
+ "version": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
+ "define-properties": {
+ "version": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
+ "requires": {
+ "foreach": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "object-keys": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz"
+ }
+ },
+ "depd": {
+ "version": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
+ },
+ "destroy": {
+ "version": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "ee-first": {
+ "version": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "encodeurl": {
+ "version": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+ "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
+ },
+ "error-ex": {
+ "version": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+ "requires": {
+ "is-arrayish": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
+ }
+ },
+ "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": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "escape-string-regexp": {
+ "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "etag": {
+ "version": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "express": {
+ "version": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
+ "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
+ "requires": {
+ "accepts": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+ "array-flatten": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "body-parser": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "content-disposition": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "content-type": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "cookie": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "cookie-signature": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+ "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "etag": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "finalhandler": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "fresh": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "merge-descriptors": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "methods": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "path-to-regexp": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "proxy-addr": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
+ "qs": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "range-parser": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "send": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
+ "serve-static": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
+ "setprototypeof": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
+ "utils-merge": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "vary": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
+ }
+ },
+ "express-handlebars": {
+ "version": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-3.0.0.tgz",
+ "integrity": "sha1-gKBwu4GbCeSvLKbQeA91zgXnXC8=",
+ "requires": {
+ "glob": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "handlebars": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz",
+ "object.assign": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz",
+ "promise": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz"
+ }
+ },
+ "express-method-override-get-post-support": {
+ "version": "https://registry.npmjs.org/express-method-override-get-post-support/-/express-method-override-get-post-support-0.0.7.tgz",
+ "integrity": "sha1-Dec3RwS7OvvV6mMsSlARYiTTBIA="
+ },
+ "finalhandler": {
+ "version": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
+ "requires": {
+ "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+ "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "unpipe": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
+ }
+ },
+ "find-up": {
+ "version": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "requires": {
+ "path-exists": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "pinkie-promise": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"
+ }
+ },
+ "foreach": {
+ "version": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
+ },
+ "forwarded": {
+ "version": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "fresh": {
+ "version": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "function-bind": {
+ "version": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0="
+ },
+ "get-caller-file": {
+ "version": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+ "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U="
+ },
+ "glob": {
+ "version": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+ "requires": {
+ "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
+ }
+ },
+ "graceful-fs": {
+ "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "handlebars": {
+ "version": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz",
+ "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=",
+ "requires": {
+ "async": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "optimist": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "source-map": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "uglify-js": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz"
+ },
+ "dependencies": {
+ "async": {
+ "version": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ }
+ }
+ },
+ "has-ansi": {
+ "version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "requires": {
+ "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"
+ }
+ },
+ "has-flag": {
+ "version": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
+ },
+ "he": {
+ "version": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0="
+ },
+ "highlight.js": {
+ "version": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz",
+ "integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4="
+ },
+ "hooks-fixed": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.2.tgz",
+ "integrity": "sha512-YurCM4gQSetcrhwEtpQHhQ4M7Zo7poNGqY4kQGeBS6eZtOcT3tnNs01ThFa0jYBByAiYt1MjMjP/YApG0EnAvQ=="
+ },
+ "hosted-git-info": {
+ "version": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+ "integrity": "sha1-bWDjSzq7yDEwYsO3mO+NkBoHrzw="
+ },
+ "http-errors": {
+ "version": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "requires": {
+ "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "setprototypeof": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz"
+ },
+ "dependencies": {
+ "setprototypeof": {
+ "version": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
+ }
+ }
+ },
+ "iconv-lite": {
+ "version": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs="
+ },
+ "inflight": {
+ "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ },
+ "inherits": {
+ "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "invert-kv": {
+ "version": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
+ },
+ "ipaddr.js": {
+ "version": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
+ "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
+ },
+ "is-arrayish": {
+ "version": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+ },
+ "is-buffer": {
+ "version": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
+ },
+ "is-builtin-module": {
+ "version": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+ "requires": {
+ "builtin-modules": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz"
+ }
+ },
+ "is-utf8": {
+ "version": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "kareem": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.5.0.tgz",
+ "integrity": "sha1-4+QQHZ3P3imXadr0tNtk2JXRdEg="
+ },
+ "keygrip": {
+ "version": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.2.tgz",
+ "integrity": "sha1-rTKXxVcGneqLz+ek+kkbdcXd65E="
+ },
+ "kind-of": {
+ "version": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz"
+ }
+ },
+ "lazy-cache": {
+ "version": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+ "optional": true
+ },
+ "lcid": {
+ "version": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "requires": {
+ "invert-kv": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz"
+ }
+ },
+ "load-json-file": {
+ "version": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "requires": {
+ "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "parse-json": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "pify": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "pinkie-promise": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "strip-bom": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz"
+ }
+ },
+ "lodash": {
+ "version": "4.17.4",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
+ },
+ "lodash.assign": {
+ "version": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc="
+ },
+ "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": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
+ },
+ "media-typer": {
+ "version": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "method-override": {
+ "version": "https://registry.npmjs.org/method-override/-/method-override-2.3.10.tgz",
+ "integrity": "sha1-49r41d7hDdLc59SuiNYrvud0drQ=",
+ "requires": {
+ "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "methods": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "vary": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
+ }
+ },
+ "methods": {
+ "version": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "mime": {
+ "version": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY="
+ },
+ "mime-db": {
+ "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+ "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
+ },
+ "mime-types": {
+ "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+ "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+ "requires": {
+ "mime-db": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz"
+ }
+ },
+ "minimatch": {
+ "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+ "requires": {
+ "brace-expansion": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz"
+ }
+ },
+ "minimist": {
+ "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
+ },
+ "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"
+ }
+ },
+ "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.5",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.13.5.tgz",
+ "integrity": "sha512-xcQ2Igh7hZwrxeBSh1eTW0dC0leQfcj2YA/VfOj/2nBqa5Iab3I8W3ivvs228Jw5qQqtvId1rnXW/QEHEVBNMw==",
+ "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": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "muri": "1.3.0",
+ "regexp-clone": "0.0.1",
+ "sliced": "1.0.1"
+ }
+ },
+ "mongooseeder": {
+ "version": "https://registry.npmjs.org/mongooseeder/-/mongooseeder-2.0.5.tgz",
+ "integrity": "sha1-f5CRavENvKyEsmkhmIfU4vJjt/4="
+ },
+ "morgan": {
+ "version": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
+ "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
+ "requires": {
+ "basic-auth": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
+ "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "on-headers": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz"
+ }
+ },
+ "morgan-toolkit": {
+ "version": "https://registry.npmjs.org/morgan-toolkit/-/morgan-toolkit-1.0.2.tgz",
+ "integrity": "sha1-wTJMWvojtkhJtMEjZa9CthkxD+w=",
+ "requires": {
+ "chalk": "https://registry.npmjs.org/chalk/-/chalk-2.2.0.tgz",
+ "cli-highlight": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-1.1.4.tgz"
+ }
+ },
+ "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": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "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": "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": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha1-lQCAV6Vsr63CvGPd5/n/aVWUjjI=",
+ "requires": {
+ "any-promise": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "thenify-all": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz"
+ }
+ },
+ "negotiator": {
+ "version": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ },
+ "normalize-package-data": {
+ "version": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=",
+ "requires": {
+ "hosted-git-info": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+ "is-builtin-module": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "semver": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+ "validate-npm-package-license": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz"
+ }
+ },
+ "number-is-nan": {
+ "version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+ },
+ "object-assign": {
+ "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "object-keys": {
+ "version": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
+ "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0="
+ },
+ "object.assign": {
+ "version": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz",
+ "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=",
+ "requires": {
+ "define-properties": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+ "function-bind": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "object-keys": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz"
+ }
+ },
+ "on-finished": {
+ "version": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
+ }
+ },
+ "on-headers": {
+ "version": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
+ },
+ "once": {
+ "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ },
+ "optimist": {
+ "version": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "requires": {
+ "minimist": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "wordwrap": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz"
+ }
+ },
+ "os-locale": {
+ "version": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "requires": {
+ "lcid": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz"
+ }
+ },
+ "parse-json": {
+ "version": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "requires": {
+ "error-ex": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz"
+ }
+ },
+ "parseurl": {
+ "version": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+ },
+ "path-exists": {
+ "version": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "requires": {
+ "pinkie-promise": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"
+ }
+ },
+ "path-is-absolute": {
+ "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-to-regexp": {
+ "version": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "path-type": {
+ "version": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "requires": {
+ "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "pify": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "pinkie-promise": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"
+ }
+ },
+ "pify": {
+ "version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ },
+ "pinkie": {
+ "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+ },
+ "pinkie-promise": {
+ "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "requires": {
+ "pinkie": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz"
+ }
+ },
+ "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": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=",
+ "requires": {
+ "asap": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz"
+ }
+ },
+ "proxy-addr": {
+ "version": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
+ "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
+ "requires": {
+ "forwarded": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "ipaddr.js": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz"
+ }
+ },
+ "qs": {
+ "version": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg="
+ },
+ "range-parser": {
+ "version": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
+ },
+ "raw-body": {
+ "version": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+ "requires": {
+ "bytes": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "unpipe": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
+ }
+ },
+ "read-pkg": {
+ "version": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "requires": {
+ "load-json-file": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "normalize-package-data": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "path-type": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz"
+ }
+ },
+ "read-pkg-up": {
+ "version": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "requires": {
+ "find-up": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "read-pkg": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz"
+ }
+ },
+ "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": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "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": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
+ },
+ "require-directory": {
+ "version": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+ },
+ "require-main-filename": {
+ "version": "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": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz"
+ }
+ },
+ "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": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+ "optional": true,
+ "requires": {
+ "align-text": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz"
+ }
+ },
+ "safe-buffer": {
+ "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM="
+ },
+ "semver": {
+ "version": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+ "integrity": "sha1-4FnAnYVx8FQII3M0M1BdOi8AsY4="
+ },
+ "send": {
+ "version": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
+ "integrity": "sha1-pw4coh0TgsEdDZ9iMd6ygQgNerM=",
+ "requires": {
+ "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "destroy": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+ "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "etag": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "fresh": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "mime": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "range-parser": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz"
+ }
+ },
+ "serve-static": {
+ "version": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
+ "integrity": "sha1-TFfVNASnYdjy58HooYpH2/J4pxk=",
+ "requires": {
+ "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+ "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "send": "https://registry.npmjs.org/send/-/send-0.16.1.tgz"
+ }
+ },
+ "set-blocking": {
+ "version": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+ },
+ "setprototypeof": {
+ "version": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY="
+ },
+ "sliced": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
+ "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
+ },
+ "source-map": {
+ "version": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "requires": {
+ "amdefine": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz"
+ }
+ },
+ "spdx-correct": {
+ "version": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+ "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+ "requires": {
+ "spdx-license-ids": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz"
+ }
+ },
+ "spdx-expression-parse": {
+ "version": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+ "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw="
+ },
+ "spdx-license-ids": {
+ "version": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+ "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc="
+ },
+ "statuses": {
+ "version": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
+ },
+ "string-width": {
+ "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
+ }
+ },
+ "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": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"
+ }
+ },
+ "strip-ansi": {
+ "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"
+ }
+ },
+ "strip-bom": {
+ "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "requires": {
+ "is-utf8": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz"
+ }
+ },
+ "supports-color": {
+ "version": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "requires": {
+ "has-flag": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz"
+ }
+ },
+ "thenify": {
+ "version": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
+ "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=",
+ "requires": {
+ "any-promise": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz"
+ }
+ },
+ "thenify-all": {
+ "version": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
+ "requires": {
+ "thenify": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz"
+ }
+ },
+ "type-is": {
+ "version": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
+ "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
+ "requires": {
+ "media-typer": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz"
+ }
+ },
+ "uglify-js": {
+ "version": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+ "optional": true,
+ "requires": {
+ "source-map": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "uglify-to-browserify": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "yargs": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "optional": true
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "optional": true
+ },
+ "unpipe": {
+ "version": "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": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "validate-npm-package-license": {
+ "version": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+ "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+ "requires": {
+ "spdx-correct": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+ "spdx-expression-parse": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz"
+ }
+ },
+ "vary": {
+ "version": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "which-module": {
+ "version": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
+ },
+ "window-size": {
+ "version": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+ "optional": true
+ },
+ "wordwrap": {
+ "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
+ },
+ "wrap-ansi": {
+ "version": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "requires": {
+ "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
+ }
+ },
+ "wrappy": {
+ "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "y18n": {
+ "version": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+ },
+ "yargs": {
+ "version": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+ "optional": true,
+ "requires": {
+ "camelcase": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "cliui": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "decamelize": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "window-size": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz"
+ }
+ },
+ "yargs-parser": {
+ "version": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
+ "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
+ "requires": {
+ "camelcase": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "lodash.assign": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 8e67b60..47f6d69 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
"express-handlebars": "^3.0.0",
"express-method-override-get-post-support": "0.0.7",
"method-override": "^2.3.10",
- "mongoose": "^4.12.3",
+ "mongoose": "^4.13.5",
"mongooseeder": "^2.0.5",
"morgan": "^1.9.0",
"morgan-toolkit": "^1.0.2"
diff --git a/routers/posts.js b/routers/posts.js
index e0fe549..4e52a84 100644
--- a/routers/posts.js
+++ b/routers/posts.js
@@ -2,9 +2,9 @@ var express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
var models = require('./../models');
+var User = mongoose.model('User');
var Post = mongoose.model('Post');
var Comment = mongoose.model('Comment');
-var User = mongoose.model('User');
var Votable = mongoose.model('Votable');
var ChildComment = mongoose.model('ChildComment');
var ObjectId = require('mongoose').Types.ObjectId;
@@ -16,6 +16,7 @@ router.get('/', (req, res) => {
Post.find()
.populate('author')
.then(posts => {
+ console.log('Posts: ' + posts);
res.render('posts/index', { posts });
})
.catch(e => res.status(500).send(e.stack));
@@ -37,13 +38,14 @@ router.get('/:id', (req, res) => {
.then(async comments => {
for (let comment of comments) {
const childComments = await ChildComment.find({
- parent: comment._id
+ parent: new ObjectId(comment._id)
})
.populate('author')
.populate('parent')
.sort({ score: -1 });
comment.children = childComments;
}
+ console.log('Post: ' + post);
res.render('posts/show', { post, comments });
});
})
@@ -77,17 +79,18 @@ router.post('/:id', async (req, res) => {
.populate('author')
.populate('parent_post');
- const user = await User.find({
+ const currentUser = await User.find({
username: req.session.currentUser.username
});
- console.log('commenting user: ' + user);
+ console.log('commenting user: ' + currentUser);
//make comment or childcomment depending on level
var comment;
if (parentComment.id === parentComment.parent_post.id) {
+ console.log('user: ' + currentUser);
comment = new Comment({
body: req.body.comment,
- author: new ObjectId(user.id),
+ author: new ObjectId(currentUser.id),
parent: new ObjectId(parentComment.id),
score: 50,
parent_post: parentComment.parent_post
@@ -95,7 +98,7 @@ router.post('/:id', async (req, res) => {
} else {
comment = new ChildComment({
body: req.body.comment,
- author: new ObjectId(user.id),
+ author: ObjectId(currentUser._id),
parent: new ObjectId(parentComment.id),
score: 50,
parent_post: parentComment.parent_post
@@ -105,6 +108,7 @@ router.post('/:id', async (req, res) => {
comment
.save()
.then(comment => {
+ console.log('newly created comment: ' + comment);
res.redirect(`${comment.parent_post.id}`);
})
.catch(e => res.status(500).send(e.stack));
diff --git a/seeds/index.js b/seeds/index.js
index 887472e..4ca08d0 100644
--- a/seeds/index.js
+++ b/seeds/index.js
@@ -3,6 +3,7 @@ const models = require('./../models');
var env = process.env.NODE_ENV || 'development';
var config = require('./../config/mongo')[env];
const mongooseeder = require('mongooseeder');
+var ObjectId = require('mongoose').Schema.Types.ObjectId;
const { User, Votable, Post, Comment, ChildComment } = models;
@@ -44,9 +45,11 @@ const seeds = () => {
var post = new Post({
title: 'A Post',
body: 'This is an example post on Thoreddit',
- author: users[Math.floor(Math.random() * users.length)],
+ author: users[0],
+ // author: users[Math.floor(Math.random() * users.length)],
score: Math.floor(Math.random() * 100)
});
+ console.log(typeof post.author);
post.parent_post = post;
posts.push(post);
}