fix #58 add TypeScript to delos!
parent
8dcdfb03dc
commit
90314eba58
@ -1,6 +1,7 @@
|
|||||||
|
/dist
|
||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules
|
node_modules
|
||||||
bower_components
|
bower_components
|
||||||
coverage
|
coverage
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
tmp
|
tmp
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
// local or development or production
|
|
||||||
module.exports =
|
|
||||||
(process.env.NODE_ENV === 'local' && require('./config.local')) ||
|
|
||||||
(process.env.NODE_ENV === 'development' && require('./config.dev')) ||
|
|
||||||
require('./config.prod')
|
|
@ -0,0 +1,9 @@
|
|||||||
|
import { IConfigOptions } from "../types";
|
||||||
|
|
||||||
|
// local or development or production
|
||||||
|
let configObj:IConfigOptions =
|
||||||
|
(process.env.NODE_ENV === 'local' && require('./config.local')).default ||
|
||||||
|
(process.env.NODE_ENV === 'development' && require('./config.dev')).default ||
|
||||||
|
require('./config.prod').default
|
||||||
|
|
||||||
|
export default configObj
|
@ -1,12 +1,6 @@
|
|||||||
// process.env.NODE_ENV = 'production'
|
import * as cluster from 'cluster'
|
||||||
|
import * as path from 'path'
|
||||||
|
|
||||||
// http://gitlab.alibaba-inc.com/thx/rap2-dolores/commit/2fd70fdcaa9d179e9cf95e530e37f31f8488f432
|
|
||||||
// https://nodejs.org/api/cluster.html
|
|
||||||
// https://github.com/node-modules/graceful/blob/master/example/express_with_cluster/dispatch.js
|
|
||||||
// http://gitlab.alibaba-inc.com/mm/fb/blob/master/dispatch.js
|
|
||||||
|
|
||||||
let cluster = require('cluster')
|
|
||||||
let path = require('path')
|
|
||||||
let now = () => new Date().toISOString().replace(/T/, ' ').replace(/Z/, '')
|
let now = () => new Date().toISOString().replace(/T/, ' ').replace(/Z/, '')
|
||||||
|
|
||||||
cluster.setupMaster({
|
cluster.setupMaster({
|
@ -1,5 +1,5 @@
|
|||||||
const Sequelize = require('sequelize')
|
const Sequelize = require('sequelize')
|
||||||
module.exports = {
|
export let Helper = {
|
||||||
id: { type: Sequelize.BIGINT(11).UNSIGNED, primaryKey: true, allowNull: false, autoIncrement: true, comment: '唯一标识' },
|
id: { type: Sequelize.BIGINT(11).UNSIGNED, primaryKey: true, allowNull: false, autoIncrement: true, comment: '唯一标识' },
|
||||||
include: [],
|
include: [],
|
||||||
exclude: {
|
exclude: {
|
@ -0,0 +1,11 @@
|
|||||||
|
import { User } from '.';
|
||||||
|
|
||||||
|
export { QueryInclude } from './queryInclude'
|
||||||
|
export { Interface } from './interface'
|
||||||
|
export { Logger } from './logger'
|
||||||
|
export { Module } from './module'
|
||||||
|
export { Notification } from './notification'
|
||||||
|
export { Organization } from './organization'
|
||||||
|
export { Property } from './property'
|
||||||
|
export { Repository } from './repository'
|
||||||
|
export { User } from './user'
|
@ -1,16 +0,0 @@
|
|||||||
const Sequelize = require('sequelize')
|
|
||||||
const sequelize = require('./sequelize')
|
|
||||||
const { id } = require('./helper')
|
|
||||||
const methods = ['GET', 'POST', 'PUT', 'DELETE']
|
|
||||||
module.exports = sequelize.define('interface', {
|
|
||||||
id,
|
|
||||||
name: { type: Sequelize.STRING(256), allowNull: false, comment: '接口名称' },
|
|
||||||
url: { type: Sequelize.STRING(256), allowNull: false, comment: '接口地址' },
|
|
||||||
method: { type: Sequelize.ENUM(...methods), allowNull: false, comment: '接口类型' },
|
|
||||||
description: { type: Sequelize.TEXT, allowNull: true, comment: '接口描述' },
|
|
||||||
// DONE 2.2 支持接口排序
|
|
||||||
priority: { type: Sequelize.BIGINT(11).UNSIGNED, allowNull: false, defaultValue: 1, comment: '接口优先级' }
|
|
||||||
}, {
|
|
||||||
paranoid: true,
|
|
||||||
comment: '接口'
|
|
||||||
})
|
|
@ -0,0 +1,70 @@
|
|||||||
|
import { Sequelize, Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default, BelongsTo, ForeignKey } from 'sequelize-typescript'
|
||||||
|
import { User, Module, Repository, Property } from './index';
|
||||||
|
|
||||||
|
enum methods { GET= 'GET', POST= 'POST', PUT= 'PUT', DELETE= 'DELETE' }
|
||||||
|
|
||||||
|
@Table({ paranoid: true, freezeTableName: false, timestamps: true })
|
||||||
|
export class Interface extends Model<Interface> {
|
||||||
|
|
||||||
|
public static METHODS= methods
|
||||||
|
|
||||||
|
public request?:object
|
||||||
|
public response?:object
|
||||||
|
|
||||||
|
@AutoIncrement
|
||||||
|
@PrimaryKey
|
||||||
|
@Column
|
||||||
|
id: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column(DataType.STRING(256))
|
||||||
|
name: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column(DataType.STRING(256))
|
||||||
|
url: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column({ type: DataType.ENUM(methods.GET, methods.POST, methods.PUT, methods.DELETE), comment: 'API method' })
|
||||||
|
method: string
|
||||||
|
|
||||||
|
@Column(DataType.TEXT)
|
||||||
|
description
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Default(1)
|
||||||
|
@Column({ type: DataType.BIGINT(11).UNSIGNED, comment: 'Priority used for ordering' })
|
||||||
|
priority: number
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
creatorId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
lockerId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Module)
|
||||||
|
@Column
|
||||||
|
moduleId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Repository)
|
||||||
|
@Column
|
||||||
|
repositoryId: number
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'creatorId')
|
||||||
|
creator: User
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'lockerId')
|
||||||
|
locker: User
|
||||||
|
|
||||||
|
@BelongsTo(() => Module, 'moduleId')
|
||||||
|
module: Module
|
||||||
|
|
||||||
|
@BelongsTo(() => Repository, 'repositoryId')
|
||||||
|
repository: Repository
|
||||||
|
|
||||||
|
@HasMany(() => Property, 'interfaceId')
|
||||||
|
properties: Property[]
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
import { Sequelize, Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default, BelongsTo, ForeignKey } from 'sequelize-typescript'
|
||||||
|
import { User, Repository, Organization, Module, Interface } from './index'
|
||||||
|
|
||||||
|
enum types {
|
||||||
|
CREATE = 'create', UPDATE = 'update', DELETE = 'delete',
|
||||||
|
LOCK = 'lock', UNLOCK = 'unlock', JOIN = 'join', EXIT = 'exit'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table({ paranoid: true, freezeTableName: false, timestamps: true })
|
||||||
|
export class Logger extends Model<Logger> {
|
||||||
|
public static TYPES = types
|
||||||
|
|
||||||
|
@AutoIncrement
|
||||||
|
@PrimaryKey
|
||||||
|
@Column
|
||||||
|
id: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column({
|
||||||
|
type: DataType.ENUM(types.CREATE, types.UPDATE, types.DELETE, types.LOCK, types.UNLOCK, types.JOIN, types.EXIT),
|
||||||
|
comment: 'operation type'
|
||||||
|
})
|
||||||
|
type: string
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column(DataType.BIGINT(11).UNSIGNED)
|
||||||
|
creatorId: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column(DataType.BIGINT(11).UNSIGNED)
|
||||||
|
userId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Organization)
|
||||||
|
@Column(DataType.BIGINT(11).UNSIGNED)
|
||||||
|
organizationId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Repository)
|
||||||
|
@Column(DataType.BIGINT(11).UNSIGNED)
|
||||||
|
repositoryId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Module)
|
||||||
|
@Column(DataType.BIGINT(11).UNSIGNED)
|
||||||
|
moduleId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Interface)
|
||||||
|
@Column(DataType.BIGINT(11).UNSIGNED)
|
||||||
|
interfaceId: number
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'creatorId')
|
||||||
|
creator: User
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'userId')
|
||||||
|
user: User
|
||||||
|
|
||||||
|
@BelongsTo(() => Repository, 'repositoryId')
|
||||||
|
repository: Repository
|
||||||
|
|
||||||
|
@BelongsTo(() => Organization, 'organizationId')
|
||||||
|
organization: Organization
|
||||||
|
|
||||||
|
@BelongsTo(() => Module, 'moduleId')
|
||||||
|
module: Module
|
||||||
|
|
||||||
|
@BelongsTo(() => Interface, 'interfaceId')
|
||||||
|
interface: Interface
|
||||||
|
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
const Sequelize = require('sequelize')
|
|
||||||
const sequelize = require('./sequelize')
|
|
||||||
const { id } = require('./helper')
|
|
||||||
module.exports = sequelize.define('module', {
|
|
||||||
id,
|
|
||||||
name: { type: Sequelize.STRING(256), allowNull: false, comment: '模块名称' },
|
|
||||||
description: { type: Sequelize.TEXT, comment: '模块描述' },
|
|
||||||
priority: { type: Sequelize.BIGINT(11).UNSIGNED, allowNull: false, defaultValue: 1, comment: '接口优先级' }
|
|
||||||
}, {
|
|
||||||
paranoid: true,
|
|
||||||
comment: '模块'
|
|
||||||
})
|
|
@ -0,0 +1,42 @@
|
|||||||
|
import { Sequelize, Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default, BelongsTo, ForeignKey } from 'sequelize-typescript'
|
||||||
|
import {User, Repository, Interface} from './index'
|
||||||
|
|
||||||
|
@Table({ paranoid: true, freezeTableName: false, timestamps: true })
|
||||||
|
export class Module extends Model<Module> {
|
||||||
|
|
||||||
|
@AutoIncrement
|
||||||
|
@PrimaryKey
|
||||||
|
@Column
|
||||||
|
id: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column(DataType.STRING(256))
|
||||||
|
name: string
|
||||||
|
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column(DataType.TEXT)
|
||||||
|
description: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Default(1)
|
||||||
|
@Column(DataType.BIGINT(11).UNSIGNED)
|
||||||
|
priority: number
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
creatorId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Repository)
|
||||||
|
@Column
|
||||||
|
repositoryId: number
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'creatorId')
|
||||||
|
creator: User
|
||||||
|
|
||||||
|
@BelongsTo(() => Repository, 'repositoryId')
|
||||||
|
repository: Repository
|
||||||
|
|
||||||
|
@HasMany(() => Interface, 'moduleId')
|
||||||
|
interfaces: Interface[]
|
||||||
|
}
|
@ -1,16 +0,0 @@
|
|||||||
const Sequelize = require('sequelize')
|
|
||||||
const sequelize = require('./sequelize')
|
|
||||||
const { id } = require('./helper')
|
|
||||||
module.exports = sequelize.define('notification', {
|
|
||||||
id,
|
|
||||||
fromId: { type: Sequelize.BIGINT(11), allowNull: true, comment: '发送者' },
|
|
||||||
toId: { type: Sequelize.BIGINT(11), allowNull: false, comment: '接受者' },
|
|
||||||
type: { type: Sequelize.STRING(128), allowNull: false, comment: '消息类型' },
|
|
||||||
param1: { type: Sequelize.STRING(128), allowNull: true, comment: '参数1' },
|
|
||||||
param2: { type: Sequelize.STRING(128), allowNull: true, comment: '参数2' },
|
|
||||||
param3: { type: Sequelize.STRING(128), allowNull: true, comment: '参数3' },
|
|
||||||
readed: { type: Sequelize.BOOLEAN, allowNull: false, defautValue: false, comment: '是否已读' }
|
|
||||||
}, {
|
|
||||||
paranoid: true,
|
|
||||||
comment: '消息'
|
|
||||||
})
|
|
@ -0,0 +1,35 @@
|
|||||||
|
import { Sequelize, Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default } from 'sequelize-typescript'
|
||||||
|
|
||||||
|
@Table({ paranoid: true, freezeTableName: false, timestamps: true })
|
||||||
|
export class Notification extends Model<Notification> {
|
||||||
|
|
||||||
|
@AutoIncrement
|
||||||
|
@PrimaryKey
|
||||||
|
@Column
|
||||||
|
id: number
|
||||||
|
|
||||||
|
@Column({ type: DataType.BIGINT(11).UNSIGNED, comment: 'sender' })
|
||||||
|
fromId: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column({ type: DataType.BIGINT(11).UNSIGNED, comment: 'receiver' })
|
||||||
|
toId: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column({ type: DataType.STRING(128), comment: 'msg type' })
|
||||||
|
type: string
|
||||||
|
|
||||||
|
@Column(DataType.STRING(128))
|
||||||
|
param1: string
|
||||||
|
|
||||||
|
@Column(DataType.STRING(128))
|
||||||
|
param2: string
|
||||||
|
|
||||||
|
@Column(DataType.STRING(128))
|
||||||
|
param3: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Default(false)
|
||||||
|
@Column
|
||||||
|
readed: boolean
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
const Sequelize = require('sequelize')
|
|
||||||
const sequelize = require('./sequelize')
|
|
||||||
const { id } = require('./helper')
|
|
||||||
module.exports = sequelize.define('organization', {
|
|
||||||
id,
|
|
||||||
name: { type: Sequelize.STRING(256), allowNull: false, comment: '团队名称' },
|
|
||||||
description: { type: Sequelize.TEXT, allowNull: true, comment: '团队描述' },
|
|
||||||
logo: { type: Sequelize.STRING(256), allowNull: true, comment: '团队标志' },
|
|
||||||
visibility: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true, comment: '是否公开' }
|
|
||||||
}, {
|
|
||||||
paranoid: true,
|
|
||||||
comment: '团队'
|
|
||||||
})
|
|
@ -0,0 +1,46 @@
|
|||||||
|
import { Sequelize, Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default, BelongsTo, BelongsToMany, ForeignKey } from 'sequelize-typescript'
|
||||||
|
import { User, Repository } from './index'
|
||||||
|
|
||||||
|
@Table({ paranoid: true, freezeTableName: false, timestamps: true })
|
||||||
|
export class Organization extends Model<Organization> {
|
||||||
|
|
||||||
|
@AutoIncrement
|
||||||
|
@PrimaryKey
|
||||||
|
@Column
|
||||||
|
id: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column(DataType.STRING(256))
|
||||||
|
name: string
|
||||||
|
|
||||||
|
@Column(DataType.TEXT)
|
||||||
|
description: string
|
||||||
|
|
||||||
|
@Column(DataType.STRING(256))
|
||||||
|
logo: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Default(true)
|
||||||
|
@Column({ comment: 'true:public, false:private' })
|
||||||
|
visibility: boolean
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
creatorId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
ownerId: number
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'creatorId')
|
||||||
|
creator: User
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'ownerId')
|
||||||
|
owner: User
|
||||||
|
|
||||||
|
@BelongsToMany(() => User, 'organizations_members', 'organizationId', 'userId')
|
||||||
|
members: User[]
|
||||||
|
|
||||||
|
@HasMany(() => Repository, 'organizationId')
|
||||||
|
repositories: Repository[]
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
const Sequelize = require('sequelize')
|
|
||||||
const sequelize = require('./sequelize')
|
|
||||||
const { id } = require('./helper')
|
|
||||||
const SCOPES = ['request', 'response']
|
|
||||||
const TYPES = ['String', 'Number', 'Boolean', 'Object', 'Array', 'Function', 'RegExp']
|
|
||||||
module.exports = sequelize.define('property', {
|
|
||||||
id,
|
|
||||||
scope: { type: Sequelize.ENUM(...SCOPES), allowNull: false, defaultValue: 'response', comment: '属性归属' },
|
|
||||||
name: { type: Sequelize.STRING(256), allowNull: false, comment: '属性名称' },
|
|
||||||
type: { type: Sequelize.ENUM(...TYPES), allowNull: false, comment: '属性值类型' },
|
|
||||||
rule: { type: Sequelize.STRING(128), allowNull: true, comment: '属性值生成规则' },
|
|
||||||
value: { type: Sequelize.TEXT, allowNull: true, comment: '属性值' },
|
|
||||||
description: { type: Sequelize.TEXT, allowNull: true, comment: '属性描述' },
|
|
||||||
parentId: { type: Sequelize.BIGINT(11), allowNull: false, defaultValue: -1, comment: '父属性' },
|
|
||||||
priority: { type: Sequelize.BIGINT(11).UNSIGNED, allowNull: false, defaultValue: 1, comment: '接口优先级' }
|
|
||||||
}, {
|
|
||||||
paranoid: true,
|
|
||||||
comment: '属性'
|
|
||||||
})
|
|
@ -0,0 +1,86 @@
|
|||||||
|
import { Sequelize, Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default, BelongsTo, ForeignKey } from 'sequelize-TYPEScript'
|
||||||
|
import { User, Interface, Module, Repository } from './index'
|
||||||
|
|
||||||
|
enum SCOPES { REQUEST = 'request', RESPONSE = 'response' }
|
||||||
|
enum TYPES { STRING = 'String', NUMBER = 'Number', BOOLEAN = 'Boolean', OBJECT = 'Object', ARRAY = 'Array', FUNCTION = 'Function', REGEXP = 'RegExp' }
|
||||||
|
|
||||||
|
@Table({ paranoid: true, freezeTableName: false, timestamps: true })
|
||||||
|
export class Property extends Model<Property> {
|
||||||
|
public static TYPES = TYPES
|
||||||
|
public static SCOPES = SCOPES
|
||||||
|
|
||||||
|
@AutoIncrement
|
||||||
|
@PrimaryKey
|
||||||
|
@Column
|
||||||
|
id: number
|
||||||
|
|
||||||
|
static attributes: any;
|
||||||
|
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Default(SCOPES.RESPONSE)
|
||||||
|
@Column({
|
||||||
|
type: DataType.ENUM(SCOPES.REQUEST, SCOPES.RESPONSE),
|
||||||
|
comment: 'property owner'
|
||||||
|
})
|
||||||
|
scope: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column({
|
||||||
|
type: DataType.ENUM(TYPES.STRING, TYPES.NUMBER, TYPES.BOOLEAN, TYPES.OBJECT, TYPES.ARRAY, TYPES.FUNCTION, TYPES.REGEXP),
|
||||||
|
comment: 'property type'
|
||||||
|
})
|
||||||
|
type: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column(DataType.STRING(256))
|
||||||
|
name: string
|
||||||
|
|
||||||
|
@Column({ type: DataType.STRING(128), comment: 'property generation rules' })
|
||||||
|
rule: string
|
||||||
|
|
||||||
|
@Column({ type: DataType.TEXT, comment: 'value of this property'})
|
||||||
|
value: string
|
||||||
|
|
||||||
|
@Column(DataType.TEXT)
|
||||||
|
description: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Default(-1)
|
||||||
|
@Column({ type: DataType.BIGINT(11), comment: 'parent property ID' })
|
||||||
|
parentId: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Default(1)
|
||||||
|
@Column(DataType.BIGINT(11).UNSIGNED)
|
||||||
|
priority: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Interface)
|
||||||
|
@Column
|
||||||
|
interfaceId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
creatorId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Module)
|
||||||
|
@Column
|
||||||
|
moduleId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Repository)
|
||||||
|
@Column
|
||||||
|
repositoryId: number
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'creatorId')
|
||||||
|
creator: User
|
||||||
|
|
||||||
|
@BelongsTo(() => Interface, 'interfaceId')
|
||||||
|
interface: Interface
|
||||||
|
|
||||||
|
@BelongsTo(() => Module, 'moduleId')
|
||||||
|
module: Module
|
||||||
|
|
||||||
|
@BelongsTo(() => Repository, 'repositoryId')
|
||||||
|
repository: Repository
|
||||||
|
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
const Sequelize = require('sequelize')
|
|
||||||
const sequelize = require('./sequelize')
|
|
||||||
const { id } = require('./helper')
|
|
||||||
module.exports = sequelize.define('repository', {
|
|
||||||
id,
|
|
||||||
name: { type: Sequelize.STRING(256), allowNull: false, comment: '仓库名称' },
|
|
||||||
description: { type: Sequelize.TEXT, allowNull: true, comment: '仓库描述' },
|
|
||||||
logo: { type: Sequelize.STRING(256), allowNull: true, comment: '仓库标志' },
|
|
||||||
visibility: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true, comment: '是否公开' }
|
|
||||||
}, {
|
|
||||||
paranoid: true,
|
|
||||||
comment: '仓库'
|
|
||||||
})
|
|
@ -0,0 +1,67 @@
|
|||||||
|
import { Sequelize, Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default, BelongsTo, BelongsToMany, ForeignKey } from 'sequelize-typescript'
|
||||||
|
import { User, Organization, Module, Interface } from './index'
|
||||||
|
|
||||||
|
@Table({ paranoid: true, freezeTableName: false, timestamps: true })
|
||||||
|
export class Repository extends Model<Repository> {
|
||||||
|
|
||||||
|
@AutoIncrement
|
||||||
|
@PrimaryKey
|
||||||
|
@Column
|
||||||
|
id: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column(DataType.STRING(256))
|
||||||
|
name: string
|
||||||
|
|
||||||
|
@Column(DataType.TEXT)
|
||||||
|
description: string
|
||||||
|
|
||||||
|
@Column(DataType.STRING(256))
|
||||||
|
logo: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Default(true)
|
||||||
|
@Column({ comment: 'true:public, false:private' })
|
||||||
|
visibility: boolean
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
ownerId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => Organization)
|
||||||
|
@Column
|
||||||
|
organizationId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
creatorId: number
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
lockerId: number
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'creatorId')
|
||||||
|
creator: User
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'ownerId')
|
||||||
|
owner: User
|
||||||
|
|
||||||
|
@BelongsTo(() => Organization, 'organizationId')
|
||||||
|
organization: Organization
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'lockerId')
|
||||||
|
locker: User
|
||||||
|
|
||||||
|
@BelongsToMany(() => User, 'repositories_members', 'repositoryId', 'userId')
|
||||||
|
members: User[]
|
||||||
|
|
||||||
|
@HasMany(() => Module, 'repositoryId')
|
||||||
|
modules: Module[]
|
||||||
|
|
||||||
|
@HasMany(() => Module, 'repositoryId')
|
||||||
|
interfaces: Interface[]
|
||||||
|
|
||||||
|
@BelongsToMany(() => Repository, 'repositories_collaborators', 'repositoryId', 'collaboratorId')
|
||||||
|
collaborators: Repository[]
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
import { Sequelize } from 'sequelize-typescript'
|
||||||
|
import { Interface, Logger, Module, Notification, Organization, Property, User, Repository } from './index'
|
||||||
|
import config from '../config'
|
||||||
|
|
||||||
|
const chalk = require('chalk')
|
||||||
|
const now = () => new Date().toISOString().replace(/T/, ' ').replace(/Z/, '')
|
||||||
|
const logging = process.env.NODE_ENV === 'development'
|
||||||
|
? (sql) => {
|
||||||
|
sql = sql.replace('Executing (default): ', '')
|
||||||
|
console.log(`${chalk.bold('SQL')} ${now()} ${chalk.gray(sql)}`)
|
||||||
|
}
|
||||||
|
: console.log
|
||||||
|
|
||||||
|
const sequelize = new Sequelize({
|
||||||
|
database: config.db.database,
|
||||||
|
dialect: config.db.dialect,
|
||||||
|
username: config.db.username,
|
||||||
|
password: config.db.password,
|
||||||
|
host: config.db.host,
|
||||||
|
port: config.db.port,
|
||||||
|
pool: config.db.pool,
|
||||||
|
logging: config.db.logging ? logging : false
|
||||||
|
})
|
||||||
|
|
||||||
|
sequelize.addModels([Interface, Logger, Module, Notification, Organization, Property, Repository, User])
|
||||||
|
sequelize.authenticate()
|
||||||
|
.then((/* err */) => {
|
||||||
|
|
||||||
|
// initialize hooks
|
||||||
|
Organization.hook('afterCreate', async(instance, options) => {
|
||||||
|
await Logger.create({
|
||||||
|
userId: instance.creatorId,
|
||||||
|
type: 'create',
|
||||||
|
organizationId: instance.id
|
||||||
|
})
|
||||||
|
})
|
||||||
|
console.log('----------------------------------------')
|
||||||
|
console.log('DATABASE √')
|
||||||
|
console.log(' HOST %s', config.db.host)
|
||||||
|
console.log(' PORT %s', config.db.port)
|
||||||
|
console.log(' DATABASE %s', config.db.database)
|
||||||
|
console.log('----------------------------------------')
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('Unable to connect to the database:', err)
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = sequelize
|
@ -0,0 +1,36 @@
|
|||||||
|
import { Sequelize, Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default, Unique, ForeignKey, BelongsToMany } from 'sequelize-typescript'
|
||||||
|
import { Organization, Repository } from './index'
|
||||||
|
|
||||||
|
@Table({ paranoid: true, freezeTableName: false, timestamps: true })
|
||||||
|
export class User extends Model<User> {
|
||||||
|
|
||||||
|
@AutoIncrement
|
||||||
|
@PrimaryKey
|
||||||
|
@Column
|
||||||
|
id: number
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column(DataType.STRING(32))
|
||||||
|
fullname: string
|
||||||
|
|
||||||
|
@Column(DataType.STRING(32))
|
||||||
|
password: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Unique
|
||||||
|
@Column(DataType.STRING(128))
|
||||||
|
email: string
|
||||||
|
|
||||||
|
@HasMany(() => Organization, 'ownerId')
|
||||||
|
ownedOrganizations: Organization[]
|
||||||
|
|
||||||
|
@BelongsToMany(() => Organization, 'organizations_members', 'organizationId', 'userId')
|
||||||
|
joinedOrganizations: Organization[]
|
||||||
|
|
||||||
|
@HasMany(() => Repository, 'ownerId')
|
||||||
|
ownedRepositories: Repository[]
|
||||||
|
|
||||||
|
@BelongsToMany(() => Repository, 'repositories_members', 'userId', 'repositoryId')
|
||||||
|
joinedRepositories: Repository[]
|
||||||
|
|
||||||
|
}
|
@ -1,173 +0,0 @@
|
|||||||
const vm = require('vm')
|
|
||||||
const _ = require('underscore')
|
|
||||||
const Mock = require('mockjs')
|
|
||||||
const { RE_KEY } = require('mockjs/src/mock/constant')
|
|
||||||
|
|
||||||
const Tree = {}
|
|
||||||
|
|
||||||
Tree.ArrayToTree = (list) => {
|
|
||||||
let result = {
|
|
||||||
name: 'root',
|
|
||||||
children: [],
|
|
||||||
depth: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
let mapped = {}
|
|
||||||
list.forEach(item => { mapped[item.id] = item })
|
|
||||||
|
|
||||||
function _parseChildren (parentId, children, depth) {
|
|
||||||
for (let id in mapped) {
|
|
||||||
let item = mapped[id]
|
|
||||||
if (typeof parentId === 'function' ? parentId(item.parentId) : item.parentId === parentId) {
|
|
||||||
children.push(item)
|
|
||||||
item.depth = depth + 1
|
|
||||||
item.children = _parseChildren(item.id, [], item.depth)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return children
|
|
||||||
}
|
|
||||||
|
|
||||||
_parseChildren(
|
|
||||||
(parentId) => {
|
|
||||||
// 忽略 parentId 为 0 的根属性(历史遗留),现为 -1
|
|
||||||
if (parentId === -1) return true
|
|
||||||
},
|
|
||||||
result.children,
|
|
||||||
result.depth
|
|
||||||
)
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO 2.x 和前端重复了
|
|
||||||
Tree.TreeToTemplate = (tree) => {
|
|
||||||
function parse (item, result) {
|
|
||||||
let rule = item.rule ? ('|' + item.rule) : ''
|
|
||||||
let value = item.value
|
|
||||||
switch (item.type) {
|
|
||||||
case 'String':
|
|
||||||
result[item.name + rule] = item.value
|
|
||||||
break
|
|
||||||
case 'Number':
|
|
||||||
if (value === '') value = 1
|
|
||||||
let parsed = parseFloat(value)
|
|
||||||
if (!isNaN(parsed)) value = parsed
|
|
||||||
result[item.name + rule] = value
|
|
||||||
break
|
|
||||||
case 'Boolean':
|
|
||||||
if (value === 'true') value = true
|
|
||||||
if (value === 'false') value = false
|
|
||||||
if (value === '0') value = false
|
|
||||||
value = !!value
|
|
||||||
result[item.name + rule] = value
|
|
||||||
break
|
|
||||||
case 'Function':
|
|
||||||
case 'RegExp':
|
|
||||||
try {
|
|
||||||
result[item.name + rule] = eval('(' + item.value + ')') // eslint-disable-line no-eval
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(`TreeToTemplate ${e.message}: ${item.type} { ${item.name}${rule}: ${item.value} }`) // TODO 2.2 怎么消除异常值?
|
|
||||||
result[item.name + rule] = item.value
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'Object':
|
|
||||||
if (item.value) {
|
|
||||||
try {
|
|
||||||
result[item.name + rule] = eval(`(${item.value})`) // eslint-disable-line no-eval
|
|
||||||
} catch (e) {
|
|
||||||
result[item.name + rule] = item.value
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result[item.name + rule] = {}
|
|
||||||
item.children.forEach((child) => {
|
|
||||||
parse(child, result[item.name + rule])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'Array':
|
|
||||||
if (item.value) {
|
|
||||||
try {
|
|
||||||
result[item.name + rule] = eval(`(${item.value})`) // eslint-disable-line no-eval
|
|
||||||
} catch (e) {
|
|
||||||
result[item.name + rule] = item.value
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result[item.name + rule] = item.children.length ? [{}] : []
|
|
||||||
item.children.forEach((child) => {
|
|
||||||
parse(child, result[item.name + rule][0])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let result = {}
|
|
||||||
tree.children.forEach((child) => {
|
|
||||||
parse(child, result)
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
Tree.TemplateToData = (template) => {
|
|
||||||
// 数据模板 template 中可能含有攻击代码,例如死循环,所以在沙箱中生成最终数据
|
|
||||||
// https://nodejs.org/dist/latest-v7.x/docs/api/vm.html
|
|
||||||
const sandbox = { Mock, template, data: {} }
|
|
||||||
const script = new vm.Script('data = Mock.mock(template)')
|
|
||||||
const context = new vm.createContext(sandbox) // eslint-disable-line new-cap
|
|
||||||
try {
|
|
||||||
script.runInContext(context, { timeout: 1000 }) // 每次 Mock.mock() 最多执行 1s
|
|
||||||
// DONE 2.1 __root__
|
|
||||||
let data = sandbox.data
|
|
||||||
let keys = Object.keys(data)
|
|
||||||
if (keys.length === 1 && keys[0] === '__root__') data = data.__root__
|
|
||||||
return data
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err)
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Tree.ArrayToTreeToTemplate = (list) => {
|
|
||||||
let tree = Tree.ArrayToTree(list)
|
|
||||||
let template = Tree.TreeToTemplate(tree)
|
|
||||||
return template
|
|
||||||
}
|
|
||||||
|
|
||||||
Tree.ArrayToTreeToTemplateToData = (list, extra) => {
|
|
||||||
let tree = Tree.ArrayToTree(list)
|
|
||||||
let template = Tree.TreeToTemplate(tree)
|
|
||||||
let data
|
|
||||||
|
|
||||||
if (extra) {
|
|
||||||
// DONE 2.2 支持引用请求参数
|
|
||||||
let keys = Object.keys(template).map(item => item.replace(RE_KEY, '$1'))
|
|
||||||
let extraKeys = _.difference(Object.keys(extra), keys)
|
|
||||||
let scopedData = Tree.TemplateToData(
|
|
||||||
Object.assign({}, _.pick(extra, extraKeys), template)
|
|
||||||
)
|
|
||||||
data = _.pick(scopedData, keys)
|
|
||||||
} else {
|
|
||||||
data = Tree.TemplateToData(template)
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
Tree.ArrayToTreeToTemplateToJSONSchema = (list) => {
|
|
||||||
let tree = Tree.ArrayToTree(list)
|
|
||||||
let template = Tree.TreeToTemplate(tree)
|
|
||||||
let schema = Mock.toJSONSchema(template)
|
|
||||||
return schema
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO 2.2 执行 JSON.stringify() 序列化时会丢失正则和函数。需要转为字符串或者函数。
|
|
||||||
// X Function.protytype.toJSON = Function.protytype.toString
|
|
||||||
// X RegExp.protytype.toJSON = RegExp.protytype.toString
|
|
||||||
Tree.stringifyWithFunctonAndRegExp = (json) => {
|
|
||||||
return JSON.stringify(json, (k, v) => {
|
|
||||||
if (typeof v === 'function') return v.toString()
|
|
||||||
if (v !== undefined && v !== null && v.exec) return v.toString()
|
|
||||||
else return v
|
|
||||||
}, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Tree
|
|
@ -0,0 +1,174 @@
|
|||||||
|
const vm = require('vm')
|
||||||
|
const _ = require('underscore')
|
||||||
|
const Mock = require('mockjs')
|
||||||
|
const { RE_KEY } = require('mockjs/src/mock/constant')
|
||||||
|
|
||||||
|
|
||||||
|
export default class Tree {
|
||||||
|
|
||||||
|
public static ArrayToTree (list) {
|
||||||
|
let result = {
|
||||||
|
name: 'root',
|
||||||
|
children: [],
|
||||||
|
depth: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
let mapped = {}
|
||||||
|
list.forEach(item => { mapped[item.id] = item })
|
||||||
|
|
||||||
|
function _parseChildren (parentId, children, depth) {
|
||||||
|
for (let id in mapped) {
|
||||||
|
let item = mapped[id]
|
||||||
|
if (typeof parentId === 'function' ? parentId(item.parentId) : item.parentId === parentId) {
|
||||||
|
children.push(item)
|
||||||
|
item.depth = depth + 1
|
||||||
|
item.children = _parseChildren(item.id, [], item.depth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return children
|
||||||
|
}
|
||||||
|
|
||||||
|
_parseChildren(
|
||||||
|
(parentId) => {
|
||||||
|
// 忽略 parentId 为 0 的根属性(历史遗留),现为 -1
|
||||||
|
if (parentId === -1) return true
|
||||||
|
},
|
||||||
|
result.children,
|
||||||
|
result.depth
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 2.x 和前端重复了
|
||||||
|
public static TreeToTemplate (tree) {
|
||||||
|
function parse (item, result) {
|
||||||
|
let rule = item.rule ? ('|' + item.rule) : ''
|
||||||
|
let value = item.value
|
||||||
|
switch (item.type) {
|
||||||
|
case 'String':
|
||||||
|
result[item.name + rule] = item.value
|
||||||
|
break
|
||||||
|
case 'Number':
|
||||||
|
if (value === '') value = 1
|
||||||
|
let parsed = parseFloat(value)
|
||||||
|
if (!isNaN(parsed)) value = parsed
|
||||||
|
result[item.name + rule] = value
|
||||||
|
break
|
||||||
|
case 'Boolean':
|
||||||
|
if (value === 'true') value = true
|
||||||
|
if (value === 'false') value = false
|
||||||
|
if (value === '0') value = false
|
||||||
|
value = !!value
|
||||||
|
result[item.name + rule] = value
|
||||||
|
break
|
||||||
|
case 'Function':
|
||||||
|
case 'RegExp':
|
||||||
|
try {
|
||||||
|
result[item.name + rule] = eval('(' + item.value + ')') // eslint-disable-line no-eval
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`TreeToTemplate ${e.message}: ${item.type} { ${item.name}${rule}: ${item.value} }`) // TODO 2.2 怎么消除异常值?
|
||||||
|
result[item.name + rule] = item.value
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'Object':
|
||||||
|
if (item.value) {
|
||||||
|
try {
|
||||||
|
result[item.name + rule] = eval(`(${item.value})`) // eslint-disable-line no-eval
|
||||||
|
} catch (e) {
|
||||||
|
result[item.name + rule] = item.value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result[item.name + rule] = {}
|
||||||
|
item.children.forEach((child) => {
|
||||||
|
parse(child, result[item.name + rule])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'Array':
|
||||||
|
if (item.value) {
|
||||||
|
try {
|
||||||
|
result[item.name + rule] = eval(`(${item.value})`) // eslint-disable-line no-eval
|
||||||
|
} catch (e) {
|
||||||
|
result[item.name + rule] = item.value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result[item.name + rule] = item.children.length ? [{}] : []
|
||||||
|
item.children.forEach((child) => {
|
||||||
|
parse(child, result[item.name + rule][0])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let result = {}
|
||||||
|
tree.children.forEach((child) => {
|
||||||
|
parse(child, result)
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TemplateToData (template) {
|
||||||
|
// 数据模板 template 中可能含有攻击代码,例如死循环,所以在沙箱中生成最终数据
|
||||||
|
// https://nodejs.org/dist/latest-v7.x/docs/api/vm.html
|
||||||
|
const sandbox = { Mock, template, data: {} }
|
||||||
|
const script = new vm.Script('data = Mock.mock(template)')
|
||||||
|
const context = new vm.createContext(sandbox) // eslint-disable-line new-cap
|
||||||
|
try {
|
||||||
|
script.runInContext(context, { timeout: 1000 }) // 每次 Mock.mock() 最多执行 1s
|
||||||
|
// DONE 2.1 __root__
|
||||||
|
let data:any = sandbox.data
|
||||||
|
let keys = Object.keys(data)
|
||||||
|
if (keys.length === 1 && keys[0] === '__root__') data = data.__root__
|
||||||
|
return data
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayToTreeToTemplate(list) {
|
||||||
|
let tree = Tree.ArrayToTree(list)
|
||||||
|
let template = Tree.TreeToTemplate(tree)
|
||||||
|
return template
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayToTreeToTemplateToData(list, extra?:any) {
|
||||||
|
let tree = Tree.ArrayToTree(list)
|
||||||
|
let template = Tree.TreeToTemplate(tree)
|
||||||
|
let data
|
||||||
|
|
||||||
|
if (extra) {
|
||||||
|
// DONE 2.2 支持引用请求参数
|
||||||
|
let keys = Object.keys(template).map(item => item.replace(RE_KEY, '$1'))
|
||||||
|
let extraKeys = _.difference(Object.keys(extra), keys)
|
||||||
|
let scopedData = Tree.TemplateToData(
|
||||||
|
Object.assign({}, _.pick(extra, extraKeys), template)
|
||||||
|
)
|
||||||
|
data = _.pick(scopedData, keys)
|
||||||
|
} else {
|
||||||
|
data = Tree.TemplateToData(template)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayToTreeToTemplateToJSONSchema(list) {
|
||||||
|
let tree = Tree.ArrayToTree(list)
|
||||||
|
let template = Tree.TreeToTemplate(tree)
|
||||||
|
let schema = Mock.toJSONSchema(template)
|
||||||
|
return schema
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 2.2 执行 JSON.stringify() 序列化时会丢失正则和函数。需要转为字符串或者函数。
|
||||||
|
// X Function.protytype.toJSON = Function.protytype.toString
|
||||||
|
// X RegExp.protytype.toJSON = RegExp.protytype.toString
|
||||||
|
public static stringifyWithFunctonAndRegExp(json) {
|
||||||
|
return JSON.stringify(json, (k, v) => {
|
||||||
|
if (typeof v === 'function') return v.toString()
|
||||||
|
if (v !== undefined && v !== null && v.exec) return v.toString()
|
||||||
|
else return v
|
||||||
|
}, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
let pathToRegexp = require('path-to-regexp')
|
|
||||||
|
|
||||||
const pkg = {}
|
|
||||||
|
|
||||||
pkg.getRelative = url => {
|
|
||||||
if (!url || typeof url !== 'string') return null
|
|
||||||
url = url.toLowerCase()
|
|
||||||
const prefixes = ['https://', 'http://']
|
|
||||||
for (let item of prefixes) {
|
|
||||||
if (url.indexOf(item) > -1) {
|
|
||||||
url = url.substring(item.length)
|
|
||||||
if (url.indexOf('/') > -1) {
|
|
||||||
url = url.substring(url.indexOf('/'))
|
|
||||||
} else {
|
|
||||||
url = '/'
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (url.indexOf('?') > -1) {
|
|
||||||
url = url.substring(0, url.indexOf('?'))
|
|
||||||
}
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
|
|
||||||
pkg.urlMatchesPattern = (url, pattern) => {
|
|
||||||
url = pkg.getRelative(url)
|
|
||||||
pattern = pkg.getRelative(pattern)
|
|
||||||
let re = pathToRegexp(pattern)
|
|
||||||
return re.test(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = pkg
|
|
@ -0,0 +1,33 @@
|
|||||||
|
let pathToRegexp = require('path-to-regexp')
|
||||||
|
|
||||||
|
export default class pkg {
|
||||||
|
|
||||||
|
public static getRelative = url => {
|
||||||
|
if (!url || typeof url !== 'string') return null
|
||||||
|
url = url.toLowerCase()
|
||||||
|
const prefixes = ['https://', 'http://']
|
||||||
|
for (let item of prefixes) {
|
||||||
|
if (url.indexOf(item) > -1) {
|
||||||
|
url = url.substring(item.length)
|
||||||
|
if (url.indexOf('/') > -1) {
|
||||||
|
url = url.substring(url.indexOf('/'))
|
||||||
|
} else {
|
||||||
|
url = '/'
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (url.indexOf('?') > -1) {
|
||||||
|
url = url.substring(0, url.indexOf('?'))
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
public static urlMatchesPattern = (url, pattern) => {
|
||||||
|
url = pkg.getRelative(url)
|
||||||
|
pattern = pkg.getRelative(pattern)
|
||||||
|
let re = pathToRegexp(pattern)
|
||||||
|
return re.test(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
import { PoolOptions } from "sequelize";
|
||||||
|
import { ISequelizeConfig } from "sequelize-typescript";
|
||||||
|
|
||||||
|
declare interface IConfigOptions {
|
||||||
|
version: string,
|
||||||
|
serve: {
|
||||||
|
port: number
|
||||||
|
},
|
||||||
|
keys: string[],
|
||||||
|
session: {
|
||||||
|
key: string
|
||||||
|
},
|
||||||
|
keycenter?: string | boolean,
|
||||||
|
db: ISequelizeConfig
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"target": "es6",
|
||||||
|
"removeComments": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"watch": false,
|
||||||
|
"baseUrl": "./src",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"paths": {
|
||||||
|
"*": [
|
||||||
|
"node_modules/*",
|
||||||
|
"src/types/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
|
||||||
|
{
|
||||||
|
"rules": {
|
||||||
|
"no-eval": true,
|
||||||
|
"forin": true,
|
||||||
|
"no-any": true,
|
||||||
|
"no-arg": true,
|
||||||
|
"no-bitwise": true,
|
||||||
|
"no-conditional-assignment": true,
|
||||||
|
"no-duplicate-variable": true,
|
||||||
|
"no-empty": true,
|
||||||
|
"no-for-in-array": false,
|
||||||
|
"no-invalid-this": true,
|
||||||
|
"no-string-literal": true,
|
||||||
|
"no-string-throw": true,
|
||||||
|
"no-unsafe-finally": true,
|
||||||
|
"no-unused-expression": true,
|
||||||
|
"no-use-before-declare": true,
|
||||||
|
"radix": true,
|
||||||
|
"switch-default": true,
|
||||||
|
"triple-equals": [true, "allow-null-check"],
|
||||||
|
|
||||||
|
"adjacent-overload-signatures": true,
|
||||||
|
"array-type": [true, "array"],
|
||||||
|
"arrow-parens": false,
|
||||||
|
"callable-types": true,
|
||||||
|
"class-name": true,
|
||||||
|
"comment-format": [true, "check-space", "check-uppercase"],
|
||||||
|
"interface-name": [true, "always-prefix"],
|
||||||
|
"jsdoc-format": true,
|
||||||
|
"max-classes-per-file": [true, 3],
|
||||||
|
"max-file-line-count": [true, 500],
|
||||||
|
"max-line-length": [true, 140],
|
||||||
|
"member-access": true,
|
||||||
|
"member-ordering": [true, { "order": "fields-first" }],
|
||||||
|
"new-parens": true,
|
||||||
|
"no-construct": true,
|
||||||
|
"no-default-export": true,
|
||||||
|
"no-inferrable-types": false,
|
||||||
|
"no-null-keyword": false,
|
||||||
|
"no-parameter-properties": true,
|
||||||
|
"no-require-imports": true,
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
"no-var-keyword": true,
|
||||||
|
"no-var-requires": true,
|
||||||
|
"object-literal-sort-keys": false,
|
||||||
|
"one-variable-per-declaration": [true, "ignore-for-loop"],
|
||||||
|
"only-arrow-functions": false,
|
||||||
|
"ordered-imports": [true, "case-insensitive"],
|
||||||
|
"prefer-const": false,
|
||||||
|
"prefer-for-of": true,
|
||||||
|
"typedef": [true, "call-signature", "parameter", "property-declaration", "variable-declaration", "member-variable-declaration"],
|
||||||
|
"unified-signatures": true,
|
||||||
|
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"],
|
||||||
|
|
||||||
|
"align": [true, "parameters", "statements"],
|
||||||
|
"curly": true,
|
||||||
|
"eofline": true,
|
||||||
|
"import-spacing": true,
|
||||||
|
"indent": [true, "spaces"],
|
||||||
|
"linebreak-style": true,
|
||||||
|
"no-consecutive-blank-lines": true,
|
||||||
|
"no-trailing-whitespace": true,
|
||||||
|
"object-literal-key-quotes": [true, "as-needed"],
|
||||||
|
"one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"],
|
||||||
|
"quotemark": [true, "single"],
|
||||||
|
"semicolon": [true, "always"],
|
||||||
|
"trailing-comma": [true, {"singleline": "never", "multiline": "always"}],
|
||||||
|
"typedef-whitespace": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"call-signature": "nospace",
|
||||||
|
"index-signature": "nospace",
|
||||||
|
"parameter": "nospace",
|
||||||
|
"property-declaration": "nospace",
|
||||||
|
"variable-declaration": "nospace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"call-signature": "onespace",
|
||||||
|
"index-signature": "onespace",
|
||||||
|
"parameter": "onespace",
|
||||||
|
"property-declaration": "onespace",
|
||||||
|
"variable-declaration": "onespace"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"],
|
||||||
|
|
||||||
|
"ban": false,
|
||||||
|
"cyclomatic-complexity": false,
|
||||||
|
"file-header": false,
|
||||||
|
"import-blacklist": false,
|
||||||
|
"interface-over-type-literal": false,
|
||||||
|
"no-angle-bracket-type-assertion": false,
|
||||||
|
"no-empty-interface": false,
|
||||||
|
"no-inferred-empty-object-type": false,
|
||||||
|
"no-internal-module": false,
|
||||||
|
"no-magic-numbers": false,
|
||||||
|
"no-mergeable-namespace": false,
|
||||||
|
"no-namespace": false,
|
||||||
|
"no-reference": true,
|
||||||
|
"object-literal-shorthand": false,
|
||||||
|
"space-before-function-paren": false
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue