npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

koa-decorator-resolver

v1.3.1

Published

Depend resolve koa decorator

Downloads

28

Readme

koa-decorator-resolver :zap:

这是一个可以在koa框架中使用装饰器的解决方案

license:MIT version:1.3.x


// 测试基于以下版本,取自2022/8/2最新版本
{
  "dependencies": {
    "@types/jest": "^27.4.1",
    "@types/request": "^2.48.8",
    "chalk": "^2.4.1",
    "console-writer": "^1.0.0-beta.1.1",
    "crypto-js": "^4.1.1",
    "exceljs": "^4.3.0",
    "fs-extra": "^10.0.0",
    "jest": "^27.5.1",
    "jest-fast-config": "^1.0.3",
    "jest-html-reporter": "^3.4.2",
    "koa": "^2.13.4",
    "koa-body": "^5.0.0",
    "koa-bodyparser": "^4.3.0",
    "koa-decorator-resolver": "^1.2.5",
    "koa-router": "^12.0.0",
    "koa-send": "^5.0.1",
    "koa-websocket": "^7.0.0",
    "lodash": "^4.17.21",
    "moment": "^2.23.0",
    "mysql2": "^2.3.3",
    "request": "^2.88.2",
    "require-all": "^3.0.0",
    "sequelize": "^6.21.3",
    "sqlite": "^4.0.23",
    "sqlite3": "^5.0.11",
    "ts-jest": "^27.1.4",
    "ts-node": "^10.9.1",
    "tsconfig-paths": "^4.0.0",
    "typescript": "^4.7.4",
    "uuid": "^8.3.2",
    "xlsx": "^0.17.4"
  },
  "devDependencies": {
    "@types/node": "^10.17.44",
    "chai": "^4.3.4",
    "copy": "^0.3.2",
    "dotenv": "^10.0.0",
    "dotenv-cli": "^6.0.0",
    "mocha": "^9.1.3",
    "nodemon": "^2.0.15",
    "npm-run-all": "^4.1.5",
    "nyc": "^15.1.0",
    "ts-mocha": "^8.0.0"
  }
}

安装

# 安装依赖
npm install koa-decorator-resolve 

数据库支持

# 如果要用到mysql数据库,则需要安装驱动,如下:
npm install [email protected]

# 如果要用到postgres数据库,则需要安装驱动,如下:
npm install [email protected] [email protected]

# 如果要用到sqlite数据库,则需要安装驱动,如下:
npm install [email protected] [email protected]

完全依赖于Sequelize对数据库的支持,详细参照:https://www.sequelize.com.cn/

默认请求

不需要定义restful,单纯的通过定义类和函数的方式自动解析成restful请求,请求的Url格式是“类名/函数名”,默认解析成的是Post,如果想要解析成Get或其他请求可以通过自定义插件的方式生成相应装饰器来解决。

使用方法

  • 文件: index.ts
// 这是koa工程的入口文件
import * as Koa from 'koa';
import * as Router from 'koa-router';
import { routeBinder } from 'koa-decorator-resolve';
import * as serviceModules from './serviceModules';
const router = new Router();
// 把模块注册在路由上
routeBinder(router,serviceModules);
app.use(router.routes());
app.listen(8080, () => {
    console.log('server start on 8080');
});
  • 文件: serviceModules.ts
// 这是注册在路由上的模块列表
export class serviceModule1 {
    func1(data){
        return {name:data.name + ' func1',msg:'success'}
    }
    func2(data){
        return {name:data.name + ' func2',msg:'success'}
    }
}
export class serviceModule2 {
    func3(data){
        return {name:data.name + ' func3',msg:'success'}
    }
}
  • 在前端发送几个请求
    // 通过“类名/函数”就可以发送出去
    axios.post('/serviceModule1/func1',{name:'m1f1'}).then(res=>{
        console.log(res); // 结果 : {name:'m1f1 func1',msg'success'}
    })
    axios.post('/serviceModule2/func3',{name:'m2f3'}).then(res=>{
        console.log(res); // 结果 : {name:'m2f3 func3',msg'success'}
    })

定义插件

自定义装饰器,用来扩展一些功能

1. 定义装饰器和插件函数
  • 文件: plugins.ts
// 这个文件用于配置和注册插件
import {injectorBuilder,Injector,ModuleFuncArgsType} from 'koa-decorator-resolve';
// 定义装饰器
type Option = {value:string}
// Transfer是装饰器名
export const Transfer: Injector<Option> = injectorBuilder('Transfer');
// 配置装饰器
export const config = {
    Transfer: { // Transfer是装饰器名,一定要与injectorBuilder里参数中的名字一致
        method: 'get', // 被装饰的方法反射的restful类型,默认是post,如果一个方法有多个装饰插件,则以第一个为主
        before: { // 被装饰方法执行前,所执行的钩子方法
            plugin: (ctx: any, option?: Option) => {
                return {'transfer-before':option.value};
            },
            replaceProps: true, // 是否把钩子方法的返回值替换给被装饰方法的第一个参数
        },
        after: { //  被装饰方法执行结束后,所执行的钩子方法
            plugin: (res: any, ctx: any, option?: Option) => {
                return {'transfer-after':res}
            },
            replaceProps: true, // 是否把钩子方法的返回值替换给请求返回值的body
        },
        intercept: (func: (...args: ModuleFuncArgsType) => any, args: ModuleFuncArgsType, option?: Option) => {
            // 拦截器钩子,如果多个装饰器定义了拦截器钩子,只生效第一个
            return func(...args)
        }
    }
}
2. 注册插件
  • 文件: index.ts
// the entry of project
import * as Koa from 'koa';
import * as Router from 'koa-router';
import {routeBinder} from 'koa-decorator-resolve';
import * as serviceModules from './serviceModules';
import {config} from './plugins'; // 上一步定义的插件配置
const router = new Router();
// 通过注册路由方法的第三个参数注册插件
routeBinder(router,serviceModules,config);
app.use(router.routes());
app.listen(8080, () => {
    console.log('server start on 8080');
});
3. 使用装饰器
  • 文件: serviceModules.ts
// the restful modules
import {Transfer} from './plugins';
export class serviceModule {
    // 用定义的装饰器直接注解方法
    @Transfer({value:123})
    func(data){
        // 根据上面的逻辑,data的值 : {'transfer-before':123}
        return 456
    }
    // 根据上面的逻辑,请求response的值 : {'transfer-after':456}
}

使用数据库

通过装饰器注入数据库实例

配置数据库

创建数据库连接实例

首先要创建数据库连接

  • 文件: initTables.ts
// 引入sequelize的类型
import { STRING, INTEGER, BIGINT, DATE, TIME, DATEONLY, BOOLEAN, FLOAT, DOUBLE } from 'sequelize';
// 引入定义函数
import {defineTables} from 'koa-decorator-resolve';
// 以下是表模型的构造器
export const tablesStructure = {
    ACCESS:[{
        id: {
          type: BIGINT,
          primaryKey: true,
        },
        user_name: STRING(20),
        role: STRING(4),
        access: INTEGER,
        begin_date: DATE,
        end_date: DATE,
    }, {version: true}],
    USER:[{
        user_id: {
          type: BIGINT,
          primaryKey: true,
        },
        user_name: STRING(20),
        password: STRING(20)
    }, {version: true}],
}
// 表与表的关系模型可以定义在这里,基于sequelize的关系模型定义方式
export const relationCallback = (tables) => {
    tables.ACCESS.hasOne(tables.USER);
    // ...
}
export const {
    Database, // 装饰器
    connect // 连接函数(下面参数useAlwaysConnection=true的场合需要在入口手动调用这个函数来创建连接)
} = new defineTables(tablesStructure, relationCallback, {
    // 使用长连接,短连接是每次执行方法的时候连接一次,执行完释放连接
    useAlwaysConnection: false, // 默认false
    // // 是否使用基础配置文件(基础配置方式请查看文档最后的说明)
    // useBaseConfig: false, // 默认true
    // 直接传入sequelize参数, 数组内为实例化sequelize的参数,详细参数用法,请参照sequelize库
    sequelizeArgs: [
      "default_db",
      "root",
      "root",
      {
        host: "localhost",
        port: 3306,
        dialect: "mysql",
      },
    ]
});
调用Sequelize数据库关系模型库

装饰器注入DB实例

// the restful modules
import {OrmSequelize} from 'koa-decorator-resolve';
import {Database,tablesStructure} from './initTables';
export class serviceModule extends OrmSequelize<typeof tablesStructure> {
    @Database({
        tables: ['ACCESS','USER'],
        relation: (tables) => {
            // 配合tables用于动态表关联
        }
    })
    async func(data){
        return await this.db.tables.ACCESS.findAll() // 通过表模型直接操作数据库,参照Sequelize
    }
}
开启事务

事务中,成功commit,异常rollback

// the restful modules
import {OrmSequelize} from 'koa-decorator-resolve';
import {Database,tablesStructure} from './initTables';
export class serviceModule extends OrmSequelize<typeof tablesStructure> {
    @Sqlite({
        useTransaction:true // 开启事务
    })
    async func(data){
        return await this.db.tables.ACCESS.findAll()
    }
}

文件配置数据库

通过配置文件配置数据库

  1. useBaseConfig = true 使用基本配置
import {defineTables} from 'koa-decorator-resover';
export const {Database,connect} = new defineTables(tablesStructure, relationCallback, {
    // 是否使用基础配置文件
    useBaseConfig: true, // 默认true
    // 注意: sequelizeArgs参数不能添加,否则会优先于sequelizeArgs对数据库的配置
});
# 在工程根目录下的.env文件中配置当前连接到哪个数据库,每个数据库有单独的配置文件,短连接的时候支持热替换(服务运行当中替换数据库)
[base] -- .env
     | -- db.mysql.js
     | -- db.postgres.js

# 以下是.env文件的格式
--------------------------------
| # 此时加载根目录下的db.mysql.js, 如果DB_DRIVER=postgres则会加载根目录下的db.postgres.js文件
| # DB_DRIVER=mysql
--------------------------------
// db.mysql.js 和 db.postgres.js的配置方法
module.exports = {
    database: 'test_db',
    username: 'test_user',
    password: 'test_pw',
    host: 'localhost',
    port: 2001,
    pool: { // 池化参数同样参照sequelize
        max: 5,
        min: 0,
        acquire: 30000,
        idle: 10000,
    };
}
// db.sqlite.js文件的配置方法
module.exports = {
    path: '/etc/test.db',
    pool: { // 池化参数同样参照sequelize
        max: 5,
        min: 0,
        acquire: 30000,
        idle: 10000,
    };
}

注意:基本配置只支持mysql、postgres、sqlite

  1. useBaseConfig = false 使用标准配置
import {defineTables} from 'koa-decorator-resover';
export const {Database,connect} = new defineTables(tablesStructure, relationCallback, {
    // 是否使用基础配置文件
    useBaseConfig: false, // 默认true
    // 注意: sequelizeArgs参数不能添加,否则会优先于sequelizeArgs对数据库的配置
});
# 在工程根目录下只需要配置db.config.js文件
[base] -- db.config.js
// 默认标准配置,完全sequelize参数,不需要.env
module.exports = {
  driver: "mysql",
  options: {
    mysql: [
      "default_db",
      "root",
      "root",
      {
        host: "localhost",
        port: 3306,
        dialect: "mysql",
      },
    ],
    postgres: [
      "default_db",
      "postgres",
      "password",
      {
        host: "localhost",
        port: 2345,
        dialect: "postgres",
      },
    ],
    sqlite: [
      {
        dialect: "sqlite",
        storage: require("path").resolve("dbfile", "sqlite.db"),
      },
    ],
  },
};

注意:标准配置参数完全准寻sequelize参数,详细参照sequelize即可


方法、参数一览

[F]方法、[D]装饰器、[C]类、[I]接口、[T]类型

  • service.binder
    • [F]routeBinder - 路由绑定方法
    • [F]restfulBinder - 传统restful绑定方法(仅支持Get/Post装饰器,即将弃用)
  • service.injector
    • [F]servInjector - 服务注入器,注入插件,生成controller函数和method类别
  • decorator.builder
    • [F]injectorBuilder - 函数装饰器构建器
    • [F]classInjectorBuilder - 类装饰器构建器
    • [F]propsInjectorBuilder - 参数装饰器构建器
  • decorator.factory
    • [F]injectBind - 装饰器参数对象绑定
    • [F]injectRemove - 装饰器参数对象解除绑定
  • decorator.restful
    • [D]Get - 传统restful装饰器(配合restfulBinder使用,即将启用)
    • [D]Post - 传统restful装饰器(配合restfulBinder使用,即将启用)
  • database.baseDefined (orm共通)
    • [C]DefineDatabase - 定义数据库入口类
    • [I]OrmBaseLoader - 加载器类接口
    • [I]OrmBaseLoaderConstructor - 加载器实例化接口
  • database.configurator(orm共通)
    • [F]standardTransfor - 连接参数标准转换器
    • [I]Transfor - 连接参数转换器接口
    • [I]StandardConfigType - 配置文件内容格式接口类型
    • [F]loadConfig - 参数读取方法
  • database.loader.sequelize.loader
    • [C]OrmLoader - sequelize加载器类
    • [T]Combine - 类型继承
    • [T]CombineAny - 类型继承,元素转换成any类型
    • [T]CombineColumnModel - 继承Model并注入column字段的类型
    • [T]TablesModelType - TablesStructure推断表结构
    • [T]DefineModel - 简化sequelize.define方法
    • [T]TablesStructureProps - 表结构callback中的参数
    • [T]TablesStructure - 表结构定义
    • [T]Relation - 关系函数
    • [T]DatabaseOptions - Database装饰器参数
    • [T]GlobalOptions - 全局参数,defineTables的第三个参数类型
    • [T]DB - 注入的db的类型,通过this.db.获取
    • [I]OrmSequelize - 用于Service模块db对象注入的继承类,实现this.db.tables.???自动提示,并能提示字段
    • [I]OrmInterface - 模块接口
    • [T]RewriteModelCtor - 解析重写Model方法类型
    • [T]RewriteModelProps - 重写Model方法的类型
    • [T]RewriteModelKeys - 重写Model方法名称的list
    • [T]BaseConfigType - 配置文件内容格式接口类型
  • database.loader.sequelize.binder
    • [F]defineTables - 构建表实例入口方法
      • [F]connect - 主动连接函数
      • [D]Database - DB注入装饰器
    • [F]baseTransfor - sequelize用的连接参数转换器
  • type
    • [T]PluginConfig - 装饰器插件配置结构

    • [T]Injector - 装饰器类型声明

    • [T]ModuleFuncType - 模块函数类型

    • [T]ModuleFuncArgsType - 模块函数参数

    • [T]MethodType - restful的method