Commit 26aef736 authored by dangdoan's avatar dangdoan

Merge branch 'develop' into 'test-meger'

# Conflicts:
#   .gitlab-ci.yml
#   package.json
parents bea55101 b755de72
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: maximegris # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: maximegris # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
{
"version": "0.2.0",
"configurations": [
{
"args": [
"task"
],
"name": "Gulp task",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
{
"name": "Debug Typescript",
"type": "node",
......
......@@ -69,6 +69,9 @@ curl -X POST -H 'Content-Type: application/json' -d '{"email":"foo@bar.com","pwd
npm run build
```
## Express Validator
https://github.com/validatorjs/validator.js#sanitizers
## Lint your code before you commit!
In a collaborative project, it's always a pain when you have to work on files not correctly formatted.
......
......@@ -80,7 +80,7 @@ gulp.task(GENERATE_DOC, gulp.series(CLEAN_DOC, function () {
return gulp.src(TS_SRC_GLOB)
.pipe(typedoc({
out: "docs",
target: "es5",
target: "es6",
name: "Express + Sequelize",
module: "commonjs",
readme: "readme.md",
......
{
"name": "typescript-express-sequelize",
"version": "2.1.0",
"description": "Sample project with Express + Sequelize + Typescript",
"homepage": "https://github.com/maximegris/typescript-express-sequelize",
"name": "typescript-express-postgresql-sequelize",
"version": "1.0.0",
"description": "A sample project with Express + Sequelize + Typescript + Postgresql",
"homepage": "",
"author": {
"name": "Maxime GRIS",
"email": "maxime.gris@gmail.com"
"name": "Author",
"email": "email@yourdomain.com"
},
"main": "build/src/server.js",
"keywords": [
......@@ -17,7 +17,7 @@
"scripts": {
"build": "gulp build",
"doc": "gulp generate:doc",
"start": "cross-env NODE_ENV=development gulp watch",
"start": "cross-env NODE_ENV=development gulp watch ",
"start:prod": "cross-env NODE_ENV=production gulp watch",
"run:test": "cross-env NODE_ENV=test gulp test",
"tslint": "gulp tslint",
......@@ -37,10 +37,14 @@
"cross-env": "7.0.0",
"express": "^4.17.1",
"express-boom": "3.0.0",
"express-validator": "^6.9.2",
"kafka-node": "^5.0.0",
"morgan": "1.9.1",
"pg": "^8.5.1",
"pg-hstore": "^2.3.3",
"sequelize": "^6.5.0",
"swagger-jsdoc": "^6.0.7",
"swagger-ui-express": "^4.1.4",
"uuid": "3.4.0",
"winston": "3.2.1"
},
......@@ -62,7 +66,7 @@
"lint-staged": "10.0.7",
"remap-istanbul": "0.13.0",
"rimraf": "3.0.2",
"sequelize-cli": "5.5.1",
"sequelize-cli": "^5.5.1",
"tslint": "6.0.0",
"typedoc": "0.16.10",
"typescript": "3.8.2",
......
{
"development": {
"username": "postgres",
"password": "chinguyen",
"database": "node_sequelize",
"host": "127.0.0.1",
"port": 5432,
"dialect": "postgres"
}
}
\ No newline at end of file
import * as LanguagesDao from './languages'
import * as AppUserDao from './appusers'
import * as StudentDao from './students'
// For kafka only
// import * as ConsumerDao from '../kafka/consumerMessage'
// import * as ProducerDao from '../kafka/messageProducer'
export { LanguagesDao }
export { AppUserDao }
export { StudentDao }
// For kafka only
// export { ConsumerDao }
// export { ProducerDao }
import * as uuid from 'uuid'
import { AppUser } from './../sqlz/models/appuser'
import { AppUsers } from './../sqlz/models/appuser'
import { Language } from '../sqlz/models/language'
export function create(appUser: any): Promise<any> {
return Language.findOne({
where: { name: 'fr' }
})
.then(language => {
return AppUser
.create({
id: uuid.v1(),
email: appUser.email,
pwd: appUser.pwd,
languageId: language.get('id')
})
export function createUserDao(appUsers: any): Promise<any> {
return AppUsers
.create({
id: uuid.v1(),
email: appUsers.email,
pwd: appUsers.pwd
})
}
export function findAll(): Promise<any> {
return AppUser
return AppUsers
.findAll({ include: [{ all: true }] })
}
export function login(appUser: any): Promise<any> {
return AppUser
return AppUsers
.findOne({
where: {
email: appUser.email,
pwd: appUser.pwd
},
include: [Language]
// include: [Language]
})
}
import * as uuid from 'uuid'
import { Students } from './../sqlz/models/students'
import { where, Op } from 'sequelize/types'
import { Request, Response } from 'express'
export function create(students: any): Promise<any> {
return Students.create({
id: uuid.v1(),
code: students.code,
firstname: students.firstname,
lastname: students.lastname,
email: students.email,
sdt: students.sdt
})
}
export function findAll(): Promise<any> {
return Students.findAll()
}
export function findStudentPagination(page: any, pagesize: any): Promise<any> {
return Students.findAndCountAll({
offset: (page - 1) * pagesize,
limit: pagesize
//offset: 1,
//limit: 2
})
}
export function deleteUser(code: any): Promise<any> {
return Students.destroy({
where: { code }
})
}
export function updateUser(code: any, students: any): Promise<any> {
return Students.findOne({
where: { code }
}).then(function(student) {
if (student) {
student.update({
firstname: students.firstname,
lastname: students.lastname,
email: students.email,
sdt: students.sdt
})
}
})
}
import * as LanguageController from './languages/_index'
import * as AppUserController from './appusers/_index'
import * as StudentsController from './students/_index'
// For kafka only
// import * as ConsumerController from './consumer/_index'
// import * as ProducerController from './producer/_index'
export { LanguageController, AppUserController }
export { LanguageController, AppUserController, StudentsController }
import { Request, Response } from 'express'
import { AppUserDao } from '../../dao/_index'
import { body, validationResult } from 'express-validator'
export function create(req: Request, res: Response) {
req.checkBody('pwd', 'Password is required').notEmpty()
req.checkBody('email', 'Email is required').notEmpty()
req.checkBody('email', 'A valid email is required').isEmail()
req.getValidationResult()
.then(function(result) {
if (result.isEmpty()) {
return AppUserDao.create(req.body)
.then(appuser => res.status(201).send(appuser))
.catch(error => res.boom.badRequest(error))
} else {
res.boom.badRequest('Validation errors', result.mapped())
}
})
const createUserValidationRules = [
body('pwd', 'Password is required').notEmpty(),
body('email', 'Email is required').notEmpty(),
body('email', 'A valid email is required').isEmail()
]
const loginValidationRules = [
body('pwd', 'Password is required').notEmpty(),
body('email', 'Email is required').notEmpty(),
body('email', 'A valid email is required').isEmail()
]
export function getValidationRules(method) {
switch (method) {
case 'CreateUser': {
return createUserValidationRules
}
case 'Login': {
return loginValidationRules
}
}
}
export function createUser(req: Request, res: Response) {
let errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
return AppUserDao.createUserDao(req.body).then(user => res.json(user))
}
export function login(req: Request, res: Response) {
let errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
req.checkBody('pwd', 'Password is required').notEmpty()
req.checkBody('email', 'Email is required').notEmpty()
req.checkBody('email', 'A valid email is required').isEmail()
req.getValidationResult()
.then(function(result) {
if (result.isEmpty()) {
return AppUserDao.login(req.body)
} else {
res.boom.badRequest('Validation errors', result.mapped())
}
})
.then(appuser => res.status(200).send(appuser))
.catch(error => res.boom.badRequest(error))
return AppUserDao.login(req.body).then(user => res.json(user))
}
import * as StudentsGet from './students.get'
import * as StudentsPost from './students.post'
import * as StudentsDelete from './students.delete'
import * as StudentsPut from './students.put'
export { StudentsGet, StudentsPost, StudentsDelete, StudentsPut }
\ No newline at end of file
import { Request, Response } from 'express'
import { StudentDao } from '../../dao/_index'
export function deleteUser(req: Request, res: Response) {
return StudentDao.deleteUser(req.params.code).then(res.status(200).json({success: true, message: 'delete success'}))
}
import { Request, Response } from 'express'
import { StudentDao } from '../../dao/_index'
export function getAllUsers(req: Request, res: Response) {
return StudentDao
.findAll()
.then(students => res.status(200).send(students))
.catch(error => res.boom.badRequest(error))
}
export function getUserBasePagination(req: Request, res: Response) {
return StudentDao.findStudentPagination(req.query.page, req.query.pagesize)
.then(students => res.status(200).send(students.rows))
}
import { Request, Response } from 'express'
import { StudentDao } from '../../dao/_index'
export function Add(req: Request, res: Response) {
return StudentDao
.create(req.body)
.then(students => res.status(200).send(students))
.catch(error => res.boom.badRequest(error))
}
import { Request, Response } from 'express'
import { StudentDao } from '../../dao/_index'
export function updateUser(req: Request, res: Response) {
return StudentDao.updateUser(req.params.code, req.body).then(res.status(200).json({success: true, message: 'update successful'}))
}
\ No newline at end of file
File added
......@@ -2,6 +2,7 @@ import * as winston from 'winston'
import { Express, Request, Response } from 'express'
import * as LanguagesRoutes from './languages'
import * as AppUserRoutes from './appusers'
import * as StudentsRoutes from './students'
export function initRoutes(app: Express) {
winston.log('info', '--> Initialisations des routes')
......@@ -12,6 +13,7 @@ export function initRoutes(app: Express) {
LanguagesRoutes.routes(app)
AppUserRoutes.routes(app)
StudentsRoutes.routes(app)
app.all('*', (req: Request, res: Response) => res.boom.notFound())
}
......@@ -2,9 +2,16 @@ import { Express } from 'express'
import { AppUserController } from '../endpoints/_index'
export function routes(app: Express) {
app.get('/api/appUsers', AppUserController.AppUserGet.list)
app.post('/api/appUsers', AppUserController.AppUserPost.create)
app.post('/api/appUsers/login', AppUserController.AppUserPost.login)
/**
* @swagger
* /api/users:
* get:
* description: Get all users
* responses:
* '200':
* description: A successful response
*/
app.get('/api/users', AppUserController.AppUserGet.list)
app.post('/api/user', AppUserController.AppUserPost.getValidationRules('CreateUser'), AppUserController.AppUserPost.createUser)
app.post('/api/user/login', AppUserController.AppUserPost.getValidationRules('Login'), AppUserController.AppUserPost.login)
}
import { Express } from 'express'
import { StudentsController } from '../endpoints/_index'
export function routes(app: Express) {
app.get('/api/students/all', StudentsController.StudentsGet.getAllUsers)
app.get('/api/students/paging*', StudentsController.StudentsGet.getUserBasePagination )
app.post('/api/addStudent', StudentsController.StudentsPost.Add)
app.delete('/api/deleteStudent/:code', StudentsController.StudentsDelete.deleteUser)
app.put('/api/updateStudent/:code',StudentsController.StudentsPut.updateUser)
}
\ No newline at end of file
......@@ -6,6 +6,9 @@ import * as cors from 'cors'
import { json, urlencoded } from 'body-parser'
import { Express } from 'express'
import * as routes from './routes/_index'
import * as specs from './swagger'
import * as swaggerUi from 'swagger-ui-express'
const PORT: number = 3000
......@@ -14,22 +17,23 @@ const PORT: number = 3000
* Can be used for basic configurations, for instance starting up the server or registering middleware.
*/
export class Server {
private app: Express
constructor() {
this.app = express()
// Express middleware
this.app.use(cors({
optionsSuccessStatus: 200
}))
this.app.use(urlencoded({
extended: true
}))
this.app.use(cors({ optionsSuccessStatus: 200 }))
this.app.use(urlencoded({ extended: true }))
this.app.use(json())
this.app.use(boom())
this.app.use(morgan('combined'))
if (process.env["EnvironmentName"] == "development") {
this.app.use('/swagger', swaggerUi.serve, swaggerUi.setup(specs.default));
}
this.app.listen(PORT, () => {
winston.log('info', '--> Server successfully started at port %d', PORT)
})
......
{
"development": {
"username": "postgres",
"password": "chinguyen",
"database": "node_sequelize",
"host": "127.0.0.1",
"port": 5432,
"password": "meu@sds12@!#gh",
"database": "chinguyen_nodejs-practice",
"host": "27.74.255.96",
"port": 5430,
"dialect": "postgres"
}
}
\ No newline at end of file
'use strict';
module.exports = {
up: async(queryInterface, Sequelize) => {
await queryInterface.createTable('Students', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV1
},
code: {
type: Sequelize.STRING
},
firstname: {
type: Sequelize.STRING
},
lastname: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
sdt: {
type: Sequelize.STRING
},
createdAt: {
allowNull: true,
type: Sequelize.DATE
},
updatedAt: {
allowNull: true,
type: Sequelize.DATE
}
});
},
down: async(queryInterface, Sequelize) => {
await queryInterface.dropTable('Students');
}
};
\ No newline at end of file
......@@ -2,26 +2,23 @@ import { Model, STRING, UUID, Deferrable } from 'sequelize'
import sequelize from './_index'
import { Language } from './language'
export class AppUser extends Model {
export class AppUsers extends Model {
}
export class AppUserModel {
export class AppUsersModel {
id: string
name: string
email: string
pwd: string
createdAt: Date
updatedAt: Date
}
AppUser.init(
AppUsers.init(
{
email: STRING(50),
pwd: STRING(50)
email: STRING,
pwd: STRING
},
{ sequelize, modelName: 'AppUser' }
{ sequelize, modelName: 'AppUsers' },
)
AppUser.belongsTo(Language, {
foreignKey: 'languageId'
})
import { Model, STRING, UUID } from 'sequelize'
import sequelize from './_index'
import { AppUser } from './appuser'
import { AppUsers } from './appuser'
export class Language extends Model {
}
......
import { Model, STRING, UUID, Deferrable, NUMBER, DATE, INTEGER, BIGINT } from 'sequelize'
import sequelize from './_index'
export class Students extends Model {
}
export class StudentsModel {
id: string
code: string
firstname: string
lastname: string
email: string
sdt: string
createdAt: Date
updatedAt: Date
}
Students.init({
code: STRING,
firstname: STRING,
lastname: STRING,
email: STRING,
sdt: STRING
}, {
sequelize,
modelName: 'Students',
})
\ No newline at end of file
import * as swaggerJsdoc from 'swagger-jsdoc'
const options = {
apis: ['**/*.ts'],
explorer: true,
swaggerDefinition: {
info: {
swagger: '2.0',
title: "Sample project APIs doc",
description: "Your project description here",
contact: {
name: "Author name"
},
version: '1.0.0'
}
}
};
const specs = swaggerJsdoc(options);
export default specs;
......@@ -5,6 +5,8 @@
"module": "commonjs",
"declaration": false,
"noImplicitAny": false,
"resolveJsonModule": true,
"skipLibCheck": true,
"removeComments": true,
"noLib": false,
"emitDecoratorMetadata": true,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment