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

lowcode-controller

v1.0.8

Published

a low-code controller util, you can use json write your controller code

Downloads

1

Readme

lowcode-controller

lowcode-controller是一个可以用json来配置化的生成对应的controller逻辑的工具,它允许配置化的生成分页查询、查询单条、查询列表、新增、更新、删除逻辑,能够覆盖大部分crud场景 你也可以通过class的方法重写和定义自己的逻辑处理 它也提供了各个阶段的生命周期,你可以在对应的生命周期定义自己的逻辑

安装

npm install --save lowcode-controller

基本使用

//in your controller  /controller/cats.js
const { LowCodeController } = require('lowcode-controller')
const cats_model = require('../model/cat_model')
const path = require('path')

LowCodeController.setGlobalDBPath(path.join(__dirname, '../db/mysql')) // 设置数据库文件
LowCodeController.setUserNameField('username') // 可以设置用户名的字段key
LowCodeController.setCustomResField('code', 'msg', 'data') // 允许自定义返回的字段key,默认是 { errno: 0, errmsg: 'success', data: null }

class CatsController extends LowCodeController {
    constructor(model, config, db, extraOptions) {
        super(model, config, null, extraOptions)
    }

    async sayHello(ctx) {
        ctx.body = { errno: 0, message: 'hello world', data: 'hello world' }
    }
}

const Cats = new CatsController(
    cats_model,
    {
        pageQuery: {
            query: {
                cat_name: {
                    like: true,
                    value: 'cat_name',
                },
                age: {
                    type: 'constant',
                    value: 2,
                },
            },
            extraOptions: {
                order: [['cat_name', 'DESC']],
                attributes: ['cat_name', 'age', 'job'],
            },
            beforeQueryHook: async function (ctx) {
                console.log('before query hook')
                return null
            },
        },
        getList: {
            extraOptions: {
                order: [['cat_name', 'DESC']],
                attributes: ['cat_name', 'age', 'job'],
            },
            afterQueryHook: async function (ctx, sourceResults) {
                sourceResults.forEach(item => {
                    item.desc = 'cute cat'
                })
                return sourceResults
            },
        },
        create: {
            validate: {
                cat_name: {
                    name: 'cat name',
                    rule: 'required',
                },
            },
            constantCreate: {
                age: 2,
            },
            enableBatch: true,
        },
        update: {
            pick: ['job'],
            query: {
                job: 'student',
            },
            afterUpdateHook: async function (ctx, t, updateItem) {
                if (updateItem.job === 'rollback') {
                    throw new Error('roll back')
                }
            },
        },
    },
    null,
    {
        creatorField: 'creator',
        updatorField: 'updator',
    }
)

module.exports = Cats
//router.js

//you can choose the routing module you like
const router = require('koa-router')()
const Cat = require('./controller/cats')

router.get('/public/cats/hello', Cat.sayHello)
router.get('/api/cats', Cat.pageQuery)
router.post('/api/cats', Cat.create)
router.get('/api/cats/list', Cat.getList)
router.get('/api/cats/:id', Cat.getSingle)
router.put('/api/cats', Cat.update)
router.put('/api/cats/:id', Cat.update)
router.delete('/api/cats/:id', Cat.delete)

module.exports = router
//app.js
const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const router = require('./router')

const app = new Koa()

app.use(async (ctx, next) => {
    ctx.username = 'admin'
    await next()
})
//lowcode-controller need ctx.query and ctx.request.body
app.use(bodyParser())

//you can choose the routing module you like
app.use(router.routes()).use(router.allowedMethods())

const server = app.listen(3000, function () {
    console.log('server is listen on 3000')
})

方法

构造函数

| 参数名 | 二级参数 | 说明 | | ------------ | ------------ | ----------------------- | | model | | 数据库model | | config | 参考二级参数 | 各个方法的配置 | | | pageQuery | | | | create | | | | update | | | | getSingle | | | | getList | | | | delete | | | db | | mysql sequelize实例 | | extraOptions | 参考二级参数 | | | | creatorField | String 创建人字段 | | | updatorField | String 创建人字段 | | | defaultQuery | Object 默认查询条件 | | | updateDelete | Object 逻辑删除更新字段 |

静态方法

setGlobalDBPath

| 参数名 | 说明 | | ------ | ------------------------------ | | dbPath | 设置全局db sequelize实例的路径 |

setUserNameField

| 参数名 | 说明 | | ------ | -------------------------------------------------- | | field | 设置从ctx里取出的用户唯一表示字段,支持xxx.xxx形式 |

setCustomResField

| 参数名 | 说明 | | ------ | ----------------- | | code | code对应的字段key | | msg | msg对应的字段key | | data | data对应的字段key |

实例方法

所有路由类实例方法参数都是ctx

pageQuery

对应到构造函数中的config.pageQuery,配置项说明如下

| 参数名 | 类型 | 说明 | | --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | query | Object | 查询条件,具体字段见后面的说明 | | beforeQueryHook | function|async function(query, extraOptions, ctx) | 在执行数据库查询之前执行,函数里return将会阻断后续执行 | | afterQueryHook | function|async function(sourceResults, query, extraOptions, ctx) | 在执行数据库查询之后执行,函数里return的值将会作为最后的接口data的返回结果 sourceResults是从数据库查出来的数据 | | filter | function | 查询数据库后,将结果放到filter函数执行过滤操作 | | extraOptions | Object | 额外设置,会透传给sequelize执行 |

create

| 参数名 | 类型 | 说明 | | ---------------- | ------------------------------------------------------ | ------------------------------------------------------------ | | validate | Object | 参数验证配置 | | beforeInsertHook | function|async function(createItem, ctx) | 在执行数据库插入之前执行,createItem为插入数据库的实体对象 | | afterInsertHook | function|async function(insertItem, transaction, ctx) | 在执行数据库插入之后执行,insertItem为插入数据库的实体对象, transaction是sequelize事务标志 | | constantCreate | Object | 用该对象的字段覆盖插入的字段值 | | extraOptions | Object | 额外设置,会透传给sequelize执行 | | pickCreate | Object | 举例{age: 'newAge'} 从createItem中的newAge值覆盖到createItem中的age字段上 | | enbaleBatch | Boolean | 默认false,开启后,支持传数组,进行批量插入 |

update

| 参数名 | 类型 | 说明 | | ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | query | Object | 查询条件,具体字段见后面的说明 | | beforeUpdateHook | function|async function(updateItem, item, ctx) | 在执行数据库更新之前执行,updateItem为传参的更新内容,item为数据库查询的更新内容 | | afterUpdateHook | function|async function(updateItem, item, raw, transaction, ctx) | 在执行数据库更新之后执行,updateItem为传参的更新内容,item为数据库查询的更新内容,raw为数据库update返回值,t为事务标志 | | filter | function | 查询数据库后,将结果放到filter函数执行过滤操作 | | extraOptions | Object | 额外设置,会透传给sequelize执行 | | validate | Object | 参数验证配置 | | itemBlock | Object | 配置更新对象的字段,不符合预期直接返回错误,比如{age: { value: 12, message: 'wrong age' }} | | pick | Array | 从传参里提取哪些字段进行更新 |

getSingle

| 参数名 | 类型 | 说明 | | --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | query | Object | 查询条件,具体字段见后面的说明 | | beforeQueryHook | function|async function(query, extraOptions, ctx) | 在执行数据库查询之前执行,函数里return将会阻断后续执行 | | afterQueryHook | function|async function(sourceResults, query, extraOptions, ctx) | 在执行数据库查询之后执行,函数里return的值将会作为最后的接口data的返回结果 sourceResults是从数据库查出来的数据 | | filter | function | 查询数据库后,将结果放到filter函数执行过滤操作 | | extraOptions | Object | 额外设置,会透传给sequelize执行 |

getList

| 参数名 | 类型 | 说明 | | --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | query | Object | 查询条件,具体字段见后面的说明 | | beforeQueryHook | function|async function( query, extraOptions, ctx) | 在执行数据库查询之前执行,函数里return将会阻断后续执行 | | afterQueryHook | function|async function(sourceResults, query, extraOptions, ctx) | 在执行数据库查询之后执行,函数里return的值将会作为最后的接口data的返回结果 sourceResults是从数据库查出来的数据 | | filter | function | 查询数据库后,将结果放到filter函数执行过滤操作 | | extraOptions | Object | 额外设置,会透传给sequelize执行 |

delete

| 参数名 | 类型 | 说明 | | ---------------- | ------------------------------------------------------------ | ------------------------------------------------------ | | query | Object | 查询条件,具体字段见后面的说明 | | beforeDeleteHook | function|async function(query, extraOptions, ctx) | 在执行数据库查询之前执行,函数里return将会阻断后续执行 | | afterDeleteHook | function|async function(query, extraOptions, transaction, ctx) | 在执行数据库查询之后执行,t为事务标志 | | extraOptions | Object | 额外设置,会透传给sequelize执行 | | physicDelete | Boolean | 是否进行物理删除,true是,false否,默认false |

query

{
  //比如请求传过来的cat_name为haha,就模糊查询数据库里cat_name为haha的内容
  'cat_name': {  //查询字段名cat_name
    'like': true,  //是否模糊查询
    'value': 'cat_name',  //从请求参数里取cat_name字段作为查询条件值
    'require': true //请求参数里的cat_name字段必须有值   
  },
   //查询数据库中age为2的内容 
   'age': {
     'type': 'constant', //查询的value为一个常量
     'value': 2 //常量值为2
   },
   //查询数据库字段cat_job里包含了请求传过来的job的内容  
   'cat_job': { //数据库字段为cat_job
     'value': 'job', //从请求参数里取job字段作为查询条件值
     'json': true //数据库cat_job是一个json类型,启用JSON_CONTAINS进行查询
   },
   //查询数据库字段creator的值为ctx里的username的内容  
   'creator': {
     'type': 'constant',
     'ctxField': 'username'  
   }, 
   //查询数据库字段birthday,大于等于请求参数里的startTime,小于等于endTime的字段  
   'birthday': {
     'type': 'varTime', //时间字段查询
     'value': ['startTime', 'endTime'] //从请求参数里取数组第一个字段为开始时间值,第二个为结束时间值
   } 
  //以上条件没加特殊操作符,默认都是and
  
  //以下查询条件都是or
  '$or': {
    //从请求参数里取为color的字段比如['black', 'white'],然后查询数据库字段color为这两种颜色之一的内容
    'color': {
      'type': 'varArray', //表面查询条件是一个数组
      'value': 'color'  
    },
    //查询数据库字段height不等于30的内容
    'height': {
      'type': 'constant',//查询的value为一个常量
      'operator': '$ne',   
      'value': 30 //常量值不等于30
    },
    //查询数据库字段weight为50或者100的内容  
    'weight': {
      'type': 'constant',
      'operator': '$in',   
      'value': [50, 100]
    },
    //查询数据库字段birthday小于等于2000-10-11的内容
    'birthday': {
      'type': 'constant',
      'operator': '$time', //时间字段查询 
      'value': [null, '2000-10-11'] //数组第一项为空无开始时间,第二项作为结束时间
    } 
  }
  //以上条件总的为查询(cat_name、age、cat_job creator birthday) and (or (color height weight birthday))
}