mirror of
https://github.com/microsoft/TypeScript-Node-Starter.git
synced 2025-11-08 20:27:37 +00:00
Merge branch 'master' into feat/ts-node
This commit is contained in:
1
.vscode/extensions.json
vendored
1
.vscode/extensions.json
vendored
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"eg2.tslint",
|
||||
"ms-azuretools.vscode-cosmosdb",
|
||||
"streetsidesoftware.code-spell-checker"
|
||||
]
|
||||
}
|
||||
40
README.md
40
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`.
|
||||
|
||||
18
jest.config.js
Normal file
18
jest.config.js
Normal file
@@ -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'
|
||||
};
|
||||
41
package-lock.json
generated
41
package-lock.json
generated
@@ -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",
|
||||
|
||||
29
package.json
29
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",
|
||||
|
||||
59
src/app.ts
59
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;
|
||||
(<any>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();
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user