-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
293 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
{ | ||
"presets": ["es2015", "stage-0"], | ||
"plugins": [ | ||
"transform-runtime" | ||
"transform-runtime", | ||
"transform-flow-strip-types" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
[include] | ||
|
||
[libs] | ||
api/decls/ | ||
decls/ | ||
|
||
[options] | ||
module.system=haste | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
### get started | ||
|
||
```bash | ||
git init | ||
npm init | ||
``` | ||
|
||
### install babel (presets and plugins) | ||
|
||
```bash | ||
cnpm i -D babel-core babel-loader babel-polyfill babel-preset-es2015 babel-preset-stage-0 | ||
cnpm i -D babel-plugin-transform-flow-strip-types babel-plugin-transform-runtime | ||
``` | ||
|
||
your `.babelrc` should look like: | ||
|
||
```json | ||
{ | ||
"presets": ["es2015", "stage-0"], | ||
"plugins": [ | ||
"transform-runtime", | ||
"transform-flow-strip-types" | ||
] | ||
} | ||
``` | ||
|
||
### plan to use koa2 for http service, sequelize for ORM, jwt for authenticate, and we do test-driven develop. | ||
|
||
```bash | ||
cnpm install koa@latest koa-body@next koa-router@next --save | ||
cnpm install boom jsonwebtoken --save | ||
cnpm install sequelize --save | ||
cnpm install chai sqlite3 sequelize-fixtures superagent --save-dev | ||
``` | ||
|
||
### setup mysql & sqlite3 | ||
|
||
```bash | ||
mysql> create database ilabs; | ||
mysql> grant all on ilabs.* to ''@'localhost'; | ||
``` | ||
|
||
_(setup fixtures.yml for test)_ | ||
|
||
### [#1] first router | ||
### first orm model |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
|
||
declare type Parameters = { | ||
[key: string]: string | ||
} | ||
|
||
declare type Filter = (key: string) => boolean | ||
|
||
declare type Model = { | ||
name: string, | ||
attributes: {[key: string]: any}, | ||
options: { | ||
setterMethods?: {[key: string]: any} | ||
}, | ||
associations: { | ||
[key: string]: any | ||
}, | ||
readbodyFilter?: Filter, | ||
findAll: Function, | ||
create: Function, | ||
bulkCreate: Function, | ||
sequelize: { | ||
transaction: Function, | ||
Utils: { inflection: { [key: string]: Function }} | ||
} | ||
} | ||
|
||
declare type Order = [string, 'ASC'|'DESC'][] | ||
|
||
declare type Attributes = Model | string[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// @flow | ||
|
||
import Sequelize from 'sequelize' | ||
const env = process.env.NODE_ENV | ||
|
||
let _instance: ?Sequelize = null | ||
|
||
export default class Database { | ||
static getInstance() { | ||
if (!_instance) { | ||
if (env === 'test') { | ||
_instance = new Sequelize({ | ||
dialect: 'sqlite', | ||
storage: ':memory:', | ||
logging: false | ||
}) | ||
console.log('db - use in memory sqlite3') | ||
} else { | ||
_instance = new Sequelize(process.env.MYSQL_DB, process.env.MYSQL_USERNAME, process.env.MYSQL_PASSWORD, { | ||
host: process.env.MYSQL_HOST, | ||
dialect: 'mysql', | ||
pool: { | ||
max: 5, | ||
min: 0, | ||
idle: 10000 | ||
} | ||
}) | ||
} | ||
} | ||
return _instance | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
//@flow | ||
|
||
import Boom from 'boom' | ||
|
||
export default () => { | ||
return async (ctx: any, next: Function) => { | ||
try { | ||
await next() | ||
} catch(error) { | ||
let boom | ||
if (error.errors) { | ||
const err = error.errors[0] | ||
if (err.type == 'unique violation') { | ||
boom = Boom.conflict(err.message, err) | ||
} else if (err.type == 'Validation error') { | ||
boom = Boom.expectationFailed(err.message, err) | ||
} else { | ||
boom = Boom.badData(err.message, err) | ||
} | ||
} else if (error.name == 'UnauthorizedError') { | ||
boom = Boom.unauthorized(error.message.trim()) | ||
} else { | ||
boom = Boom.wrap(error) | ||
} | ||
if (boom.output.statusCode == 500) { | ||
console.trace(error) | ||
} | ||
ctx.status = boom.output.statusCode | ||
ctx.body = boom.output.payload | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
//@flow | ||
|
||
export {default as errors} from './errors' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
//@flow | ||
|
||
import Sequelize from 'sequelize' | ||
import crypto from 'crypto' | ||
import jwt from 'jsonwebtoken' | ||
import Boom from 'boom' | ||
import Database from '../database' | ||
|
||
const Person = Database.getInstance().define('person', { | ||
first_name: { | ||
type: Sequelize.STRING, | ||
allowNull: false | ||
}, | ||
last_name: { | ||
type: Sequelize.STRING, | ||
allowNull: false | ||
}, | ||
email: { | ||
type: Sequelize.STRING, | ||
validate: { | ||
isEmail: true, | ||
notEmpty: true | ||
}, | ||
allowNull: false, | ||
unique: true | ||
}, | ||
salt: { | ||
type: Sequelize.STRING(64), | ||
allowNull: false | ||
}, | ||
hash: { | ||
type: Sequelize.STRING(64), | ||
allowNull: false | ||
} | ||
}, | ||
{ | ||
underscored: true, | ||
defaultScope: { | ||
attributes: { exclude: ['salt', 'hash'] } | ||
}, | ||
setterMethods: { | ||
password: function(password: string) { | ||
if (!password || password.length < 6) { | ||
throw Boom.expectationFailed('password should have at least 6 characters') | ||
} | ||
const buf = crypto.randomBytes(32) | ||
const salt = buf.toString('hex') | ||
this.setDataValue('salt', salt) | ||
this.setDataValue('hash', Person.hash(password, salt)) | ||
} | ||
}, | ||
classMethods: { | ||
hash(password: string, salt: string): string { | ||
return crypto.pbkdf2Sync(password, salt, 10000, 32, 'sha512').toString('hex') | ||
} | ||
}, | ||
|
||
instanceMethods: { | ||
toSafeJSON() { | ||
const json = this.toJSON() | ||
delete json.salt | ||
delete json.hash | ||
return json | ||
}, | ||
matchPassword(password: string): boolean { | ||
return this.hash === Person.hash(password, this.salt) | ||
}, | ||
generateToken(): string { | ||
return jwt.sign({ | ||
id: this.id | ||
}, process.env.AUTH_SECRET) | ||
} | ||
} | ||
}) | ||
|
||
export default Person |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import fixtures from 'sequelize-fixtures' | ||
import Database from '../src/database' | ||
|
||
beforeEach('db - fill with fixtures', async () => { | ||
await Database.getInstance().sync({ force: true }) | ||
await fixtures.loadFile(`${__dirname}/fixtures.yml`, Database.getInstance().models, { log: () => {} }) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
fixtures: | ||
- model: person | ||
data: | ||
id: 1 | ||
email: shengning@gmail.com | ||
first_name: ning | ||
last_name: sheng | ||
salt: 99c751ab86303aefa9c2accd1118e90c4142ed629a600649ddcab8e693a971df | ||
hash: edba21231351b18635c7469269cb35177ece5dcdefb759c73a5b1fbfcf08477d | ||
- model: person | ||
data: | ||
id: 2 | ||
email: shengning+1@gmail.com | ||
first_name: ning | ||
last_name: sheng | ||
salt: 99c751ab86303aefa9c2accd1118e90c4142ed629a600649ddcab8e693a971df | ||
hash: edba21231351b18635c7469269cb35177ece5dcdefb759c73a5b1fbfcf08477d |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters