diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 464dd17..b7fde48 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,7 @@ { "recommendations": [ "eg2.tslint", + "ms-azuretools.vscode-cosmosdb", "streetsidesoftware.code-spell-checker" ] } \ No newline at end of file diff --git a/README.md b/README.md index 691115e..77eefb7 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ mongod ``` - Build and run the project ``` +npm run build npm start ``` Navigate to `http://localhost:3000` @@ -73,6 +74,7 @@ The full folder structure of this app is explained below: | .env.example | API keys, tokens, passwords, database URI. Clone this, but don't check it in to public repos. | | .travis.yml | Used to configure Travis CI build | | .copyStaticAssets.ts | Build script that copies images, fonts, and JS libs to the dist folder | +| jest.config.js | Used to configure Jest | | package.json | File that contains npm dependencies as well as [build scripts](#what-if-a-library-isnt-on-definitelytyped) | | tsconfig.json | Config settings for compiling server code written in TypeScript | | tsconfig.tests.json | Config settings for compiling tests written in TypeScript | @@ -317,24 +319,26 @@ npm install -D jest ts-jest `jest` is the testing framework itself, and `ts-jest` is just a simple function to make running TypeScript tests a little easier. ### Configure Jest -Jest's configuration lives in `package.json`, so let's open it up and add the following code: -```json -"jest": { - "globals": { - "__TS_CONFIG__": "tsconfig.json" - }, - "moduleFileExtensions": [ - "ts", - "js" - ], - "transform": { - "^.+\\.(ts)$": "./node_modules/ts-jest/preprocessor.js" - }, - "testMatch": [ - "**/test/**/*.test.(ts|js)" - ], - "testEnvironment": "node" - }, +Jest's configuration lives in `jest.config.js`, so let's open it up and add the following code: +```js +module.exports = { + globals: { + 'ts-jest': { + tsConfigFile: 'tsconfig.json' + } + }, + moduleFileExtensions: [ + 'ts', + 'js' + ], + transform: { + '^.+\\.(ts|tsx)$': './node_modules/ts-jest/preprocessor.js' + }, + testMatch: [ + '**/test/**/*.test.(ts|js)' + ], + testEnvironment: 'node' +}; ``` Basically we are telling Jest that we want it to consume all files that match the pattern `"**/test/**/*.test.(ts|js)"` (all `.test.ts`/`.test.js` files in the `test` folder), but we want to preprocess the `.ts` files first. This preprocess step is very flexible, but in our case, we just want to compile our TypeScript to JavaScript using our `tsconfig.json`. diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..6ea5c4a --- /dev/null +++ b/jest.config.js @@ -0,0 +1,18 @@ +module.exports = { + globals: { + 'ts-jest': { + tsConfigFile: 'tsconfig.json' + } + }, + moduleFileExtensions: [ + 'ts', + 'js' + ], + transform: { + '^.+\\.(ts|tsx)$': './node_modules/ts-jest/preprocessor.js' + }, + testMatch: [ + '**/test/**/*.test.(ts|js)' + ], + testEnvironment: 'node' +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 52bc1dd..da1da33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,12 @@ "integrity": "sha1-TN2WtJKTs5MhIuS34pVD415rrlg=", "dev": true }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==", + "dev": true + }, "@types/body-parser": { "version": "1.16.7", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.7.tgz", @@ -3310,9 +3316,9 @@ } }, "hooks-fixed": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.0.tgz", - "integrity": "sha1-oB2JTVKsf2WZu7H2PfycQR33DLo=" + "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": "2.5.0", @@ -5079,6 +5085,11 @@ } } }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -5352,18 +5363,19 @@ } }, "mongoose": { - "version": "4.12.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.12.4.tgz", - "integrity": "sha512-3QTbQ/+wRe8Lr1IGTBAu2gyx+7VgvnCGmY2N1HSW8nsvfMGO0QW9iNDzZT3ceEY2Wctlt28wNavHivcLDO76bQ==", + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.13.7.tgz", + "integrity": "sha512-3VPcGQWaTzT/OVK+TpE9dGpNHBnEqFX2RmbFr1XvbsKmxPsL9kaRBSHqaQ8QEMd6CUeOYMRdH1pKRrlnCenRsg==", "requires": { "async": "2.1.4", "bson": "1.0.4", - "hooks-fixed": "2.0.0", + "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.2", + "mquery": "2.3.3", "ms": "2.0.0", "muri": "1.3.0", "regexp-clone": "0.0.1", @@ -5403,16 +5415,21 @@ "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY=" }, "mquery": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.2.tgz", - "integrity": "sha512-KXWMypZSvhCuqRtza+HMQZdYw7PfFBjBTFvP31NNAq0OX0/NTIgpcDpkWQ2uTxk6vGQtwQ2elhwhs+ZvCA8OaA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.3.tgz", + "integrity": "sha512-NC8L14kn+qxJbbJ1gbcEMDxF0sC3sv+1cbRReXXwVvowcwY1y9KoVZFq0ebwARibsadu8lx8nWGvm3V0Pf0ZWQ==", "requires": { - "bluebird": "3.5.1", + "bluebird": "3.5.0", "debug": "2.6.9", "regexp-clone": "0.0.1", "sliced": "0.0.5" }, "dependencies": { + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + }, "sliced": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", diff --git a/package.json b/package.json index 4bef1c7..e3e6403 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,11 @@ "author": "Bowden Kelly", "license": "MIT", "scripts": { - "start": "npm run build && npm run watch", + "start": "npm run serve", "build": "npm run build-sass && npm run build-ts && npm run tslint && npm run copy-static-assets", - "serve": "nodemon dist/server.js", - "watch": "concurrently -k -p \"[{name}]\" -n \"Sass,TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-sass\" \"npm run watch-ts\" \"npm run serve\"", + "serve": "node dist/server.js", + "watch-node": "nodemon dist/server.js", + "watch": "concurrently -k -p \"[{name}]\" -n \"Sass,TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-sass\" \"npm run watch-ts\" \"npm run watch-node\"", "test": "jest --forceExit", "build-ts": "tsc", "watch-ts": "tsc -w", @@ -24,27 +25,10 @@ "serve-debug": "nodemon --inspect dist/server.js", "watch-debug": "concurrently -k -p \"[{name}]\" -n \"Sass,TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-sass\" \"npm run watch-ts\" \"npm run serve-debug\"" }, - "jest": { - "globals": { - "ts-jest": { - "tsConfigFile": "tsconfig.json" - } - }, - "moduleFileExtensions": [ - "ts", - "js" - ], - "transform": { - "^.+\\.(ts|tsx)$": "./node_modules/ts-jest/preprocessor.js" - }, - "testMatch": [ - "**/test/**/*.test.(ts|js)" - ], - "testEnvironment": "node" - }, "dependencies": { "async": "^2.5.0", "bcrypt-nodejs": "^0.0.3", + "bluebird": "^3.5.1", "body-parser": "^1.18.2", "compression": "^1.7.1", "connect-mongo": "^1.3.2", @@ -57,7 +41,7 @@ "fbgraph": "^1.4.1", "lodash": "^4.17.4", "lusca": "^1.5.2", - "mongoose": "^4.12.4", + "mongoose": "^4.13.7", "morgan": "^1.9.0", "nodemailer": "^2.7.2", "passport": "^0.4.0", @@ -69,6 +53,7 @@ "devDependencies": { "@types/async": "^2.0.40", "@types/bcrypt-nodejs": "0.0.30", + "@types/bluebird": "^3.5.18", "@types/body-parser": "^1.16.2", "@types/compression": "0.0.33", "@types/connect-mongo": "0.0.34", diff --git a/src/app.ts b/src/app.ts index a27c241..8f2150a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,6 +1,3 @@ -/** - * Module dependencies. - */ import * as express from "express"; import * as compression from "compression"; // compresses requests import * as session from "express-session"; @@ -13,50 +10,38 @@ import * as flash from "express-flash"; import * as path from "path"; import * as mongoose from "mongoose"; import * as passport from "passport"; -import expressValidator = require("express-validator"); +import * as expressValidator from "express-validator"; +import * as bluebird from "bluebird"; const MongoStore = mongo(session); -/** - * Load environment variables from .env file, where API keys and passwords are configured. - */ +// Load environment variables from .env file, where API keys and passwords are configured dotenv.config({ path: ".env.example" }); - -/** - * Controllers (route handlers). - */ +// Controllers (route handlers) import * as homeController from "./controllers/home"; import * as userController from "./controllers/user"; import * as apiController from "./controllers/api"; import * as contactController from "./controllers/contact"; -/** - * API keys and Passport configuration. - */ + +// API keys and Passport configuration import * as passportConfig from "./config/passport"; -/** - * Create Express server. - */ +// Create Express server const app = express(); -/** - * Connect to MongoDB. - */ -// mongoose.Promise = global.Promise; -mongoose.connect(process.env.MONGODB_URI || process.env.MONGOLAB_URI); - -mongoose.connection.on("error", () => { - console.log("MongoDB connection error. Please make sure MongoDB is running."); - process.exit(); +// Connect to MongoDB +const mongoUrl = process.env.MONGOLAB_URI; +(mongoose).Promise = bluebird; +mongoose.connect(mongoUrl, {useMongoClient: true}).then( + () => { /** ready to use. The `mongoose.connect()` promise resolves to undefined. */ }, +).catch(err => { + console.log("MongoDB connection error. Please make sure MongoDB is running. " + err); + // process.exit(); }); - - -/** - * Express configuration. - */ +// Express configuration app.set("port", process.env.PORT || 3000); app.set("views", path.join(__dirname, "../views")); app.set("view engine", "pug"); @@ -70,7 +55,7 @@ app.use(session({ saveUninitialized: true, secret: process.env.SESSION_SECRET, store: new MongoStore({ - url: process.env.MONGODB_URI || process.env.MONGOLAB_URI, + url: mongoUrl, autoReconnect: true }) })); @@ -86,13 +71,13 @@ app.use((req, res, next) => { app.use((req, res, next) => { // After successful login, redirect back to the intended page if (!req.user && - req.path !== "/login" && - req.path !== "/signup" && - !req.path.match(/^\/auth/) && - !req.path.match(/\./)) { + req.path !== "/login" && + req.path !== "/signup" && + !req.path.match(/^\/auth/) && + !req.path.match(/\./)) { req.session.returnTo = req.path; } else if (req.user && - req.path == "/account") { + req.path == "/account") { req.session.returnTo = req.path; } next(); diff --git a/views/partials/footer.pug b/views/partials/footer.pug index f238b47..9a135dc 100644 --- a/views/partials/footer.pug +++ b/views/partials/footer.pug @@ -1,5 +1,5 @@ footer .container.text-center - p.pull-left © 2016 Company, Inc. All Rights Reserved + p.pull-left © 2018 Company, Inc. All Rights Reserved iframe.pull-right(src="https://ghbtns.com/github-btn.html?user=Microsoft&repo=TypeScript-Node-Starter&type=star&count=true" frameborder="0" scrolling="0" width="90px" height="20px" style="margin-top:15px") \ No newline at end of file