- Typescript
- with express
- Redis support
- Database support with Sequelize
- Database migration with Sequelize
- MVC architecture
- Multi language support with i18next
- CSRF protection
- SCSS compailer
- Server Side Render with EJS
- Logging support with winston
- Rate limitter
- Session and Authorization
- Fully customizable
- Customizable Error Pages
- Simple build and start
- Auto refresh on changes (.ts, .ejs and public folder)
- On (S)CSS change page updated without page refresh
k start <app-name>
For more information k
you could access default express app with
import app from 'src/k/app'
src/web/router.ts
contains variable named DefaultRouter
- DefaultRouter
express.Router()
!required
Could used for all routes and entegrate other routes
export const DefaultRouter = express.Router()
.use(CsrfProtection) // Csrf Protection
.use('/', RateLimiterMiddleware, SiteRouter) // Simple Router Usage
If you want to separate the route files, you can keep them in
src/web/routers
folder with .router.ts extension
Separate Router Example
// src/web/routers/site.router.ts
export const SiteRouter = router
.use(SetLayoutMiddleware('./layouts/site'))
.use(SiteController.getLayout())
.get('/', SiteController.getIndex)
Create With k
k generate router <router-name>
Controllers will stored in src/controllers
with .controller.ts extension
Create With k
k generate controller <router-name>
Example
Do not forget import definition
//Definition
export default {
someController(req,res){
res.send('Hello World')
}
}
//Usage
DefaultRouter
.get('/',<file-name>.someController)
//Definition
export const SiteController = {
someController(req,res){
res.send('Hello World')
}
}
//Usage
DefaultRouter
.get('/',SiteController.someController)
//Definition
export const someController = (req,res) => {
res.send('Hello World')
}
//Usage
DefaultRouter
.get('/',someController)
Right know only ejs supported
Views will stored in src/views
with .ejs extension
We have four folder
- Layouts
- Pages
- Partials
- Errors
Build do not include views and other ejs files do not delete src folder on production
For layout support express-ejs-layouts
Express-ejs-layouts options
Name | Default | Description |
---|---|---|
extractMetas |
true |
Details |
extractStyles |
true |
Details |
extractScripts |
true |
Details |
Layout options
Name | Default | Description |
---|---|---|
body |
null |
Used for print page html |
meta |
null |
Used for print extractMetas value |
style |
null |
Used for print extractStyles value |
script |
null |
Used for print extractScripts value |
Default Layout is null
You Can Set Layout for Router with
.use(SetLayoutMiddleware('./layouts/site')) // 'site' is name of .ejs file
Layout Example
<!DOCTYPE html>
<html>
<head>
<%- meta %>
<%- style %>
</head>
<body>
<%- body %>
</body>
<%- script %>
</html>
Stored in src/views/errors
Right now only available for 404
and 500
http codes
Default pages stored in
src/k/views/pages
Do not change this files
Root folder for page ejs files.
Subfolders recomended for clean code.
In ejs u can include ejs files like
<%- include('../somepartial.ejs') %>
if partial in partials folder u can include like
<%- partial('somepartial') %>
Models will stored in src/models
with .model.ts extension
For more details sequelize-typescript
Example
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import bcrypt from "bcrypt";
// Example User
// User.create({
// name:"Admin",
// email:"tahsincesur1@gmail.com",
// password:"123123123",
// status:1
// })
@Table({
modelName: 'User',
tableName: 'users',
paranoid: true,
})
export default class User extends Model {
@Column({
type: DataType.STRING,
allowNull: false
})
name: string
@Column({
type: DataType.STRING,
allowNull: false
})
email: string
@Column({
type: DataType.STRING,
allowNull: false
})
password: string
@Column({
type: DataType.TINYINT,
allowNull: false,
defaultValue: 1
})
status: string
async validPassword(password: string): Promise<boolean> {
try {
return await bcrypt.compare(password, this.password);
} catch (error) {
return false
}
}
}
User.beforeCreate((user:User, options) => {
return bcrypt.hash(user.password, 10)
.then(hash => {
user.password = hash;
})
.catch(err => {
throw new Error();
});
})
WARNING if you do not know what to do, do not touch
src/k/models
You can get
and set
session properties like
req.session.example = 'example'
Session stored in Redis
, Database
or Memory
Priority is
Redis > Database > Memory
**Memory not recomended for production
There is two ENV file .env
and .env.dev
.
yarn run serve
-> development.env
,
yarn start
-> production.env
if you want to change these settings or file names you can edit package.json scripts
Track request with RateLimiterMiddleware
middleware.
Add points per tracked request and store it in redis
or session
.
Priority
Redis > Session
Name | Default | Description |
---|---|---|
Duration | 1 | Stored For 1 second |
Point | 10 | Max request count in duration |
Changeable in .env file
RATE_LIMITTER_DURATION
andRATE_LIMITTER_POINT
Using winston-typescript for logging
Logs will stored in .log file or in DB if available in .env
Priority
DB > .log
.log file location is <root>/log/output/combined.log
Error logs stored in error.log file to
Usage Example
import { Logger } from "src/k/logger";
Logger.info("Info log")
Logger.error("Error log")
Logger.warn("Warn log")
In Development, Logs not gonna stored in DB or .log file, only print to console
Inside of a ejs file you can use i18n
like <%- t('key') %>
.
If you need to use i18n in your ts file you can use i18n
function like req.i18n.t('key')
.
You can access more detailed documantation i18n and i18n-express-middleware
import { Login } from 'src/k/authGuard'
Login(req: express.Request, authName:string="user", auth:object={} ):Promise<void>
Paramater | Description | Default |
---|---|---|
req | express.Request | |
authName | identifier for multiple login | "user" |
auth | identifier values ex:user id | {} |
stores session variables under req.session.auth[authName]
import { Logout } from 'src/k/authGuard'
Logout(req: express.Request, authName: string = 'user'): Promise<void>
Paramater | Description | Default |
---|---|---|
req | express.Request | |
authName | identifier for multiple login | "user" |
clear session variables under req.session.auth[authName]
Redirect unauthentication to target path
Paramater | Description | Default |
---|---|---|
redirect | target path for redirection | |
authName | identifier for multiple login | "user" |
import { AuthGuard } from 'src/k/authGuard'
express.Router()
.get('/user',AuthGuard('/','user'),UserController.getIndex)
.get('/admin',AuthGuard('/','admin'),AdminController.getIndex)
Redirect authentication to target path
Paramater | Description | Default |
---|---|---|
redirect | target path for redirection | |
authName | identifier for multiple login | "user" |
import { RedirectOnAuth } from 'src/k/authGuard'
express.Router()
.get('/login',RedirectOnAuth('/user','user'),SiteController.getLogin)
For more detail express-validator
example
import { validate } from 'src/k/validator';
import { check } from 'express-validator';
export const SiteRouter = router
.post('/signin',validate([
check('email')
.notEmpty().withMessage('e-mail can not empty')
.isString().withMessage('check your e-mail')
.isEmail().withMessage('check your e-mail'),
check('password')
.notEmpty().withMessage('password can not empty')
]),SiteController.postSignin)
You can use
ng serve
for development but you may encounter some problems mostly about url
- have fun ?
- cypress test or karma
Tested on Ubuntu 20.04 and Windows 10