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 🙏

© 2025 – Pkg Stats / Ryan Hefner

egg-xc-base

v1.2.8

Published

a base framework with egg.js

Readme

egg-xc-base

base framework of our egg

QuickStart

egg-bin init 项目名 --type-simple

将package.json egg对象下面 里面增加一行:
egg: {
  framework:'egg-xc-base'
}
然后使用yarn add egg-xc-base初始化项目

初次初始化yarn dev 脚手架会自动生成一些配置目录和文件


然后使用
$yarn init-config 
指令初始化项目配置文件

config/plugin.js

module.exports = {
    mysql : {
      enable: false,
      package: 'egg-mysql'
  },
    xcSSO :{
      enable:false,
      package :'egg-xc-sso'
    }
};

mysql插件默认是关闭状态
xcSSO鉴权默认是关闭状态

config/config.default.js

  config.xcSSO = {//统一认证服务配置
    //客户端ID 必配
    clientId : '',
  
    //客户端秘钥 必配
    clientSecret : '',
  
    //上下文根 选配默认 /
    prefix:config.static && config.static.prefix ? config.static.prefix : '/',
  
    //回调IP端口 必配 eg: http://127.0.0.1:${config.cluster.listen.port} 备注:此处IP为服务端生成环境IP地址或者域名
    callbackIpPort:`http://127.0.0.1:${config.cluster.listen.port}`,
  
    //回调路径 选配默认 /sso/callback 最终拼接规则`${config.xcSSO.callbackIpPort}${config.xcSSO.prefix}/sso/callback`
    callbackURL: `/sso/callback`,
  
    //统一身份认证服务器IP端口 必配 eg:http://192.168.137.1:5001
    authIpPort:`http://192.168.137.1:5001`,
  
    //登录URL 选配 默认/sso/login 最终拼接规则`${config.xcSSO.callbackIpPort}${config.xcSSO.prefix}/sso/login`
    loginURL : `/sso/login`,
  
    //登出URL 选配默认 /sso/logout 最终拼接规则`${config.xcSSO.callbackIpPort}${config.xcSSO.prefix}/sso/logout`
    logoutURL : `/sso/logout`,
  
    //登录成功后回调地址 选配默认 /index.html 最终拼接规则`${config.xcSSO.callbackIpPort}${config.xcSSO.prefix}/index.html`
    successRedirect : `/index.html`,
  }
  config.checkLogin = {//登录拦截白名单
    whiteList : [
      `${config.static.prefix}${config.xcSSO.callbackURL}`,
      `${config.static.prefix}${config.xcSSO.loginURL}`,
      `${config.static.prefix}${config.xcSSO.successRedirect}`,
    ]
  }


config.xcSSO: 鉴权模块的一些配置项
config.checkLogin:  框架依赖的egg-xc-sso 中间件会抓取每一个http请求(public下静态资源除外),这里可以配置白名单。脚手架默认将鉴权的对应路径加入配置

鉴权逻辑


  1.框架默认使用OAuth2.0进行鉴权操作
    OAuth 2.0 规定了四种获得令牌的流程。
    1.1授权码(authorization-code)
    1.2隐藏式(implicit)
    1.3密码式(password):
    1.4客户端凭证(client credentials)

    本框架主要对1.1 1.3 1.4进行了封装,开发者无需关注具体是怎么和鉴权服务进行交互的,框架会自动帮你将登录接口、登出接口、刷新token业务全部自动搞定。

   2.本框鉴权一般 配合xc-oauth(基于oauth2-server进行改进优化过的工程),项目进行使用使用。亦可对框架进行扩展,集成GitHub,推特,微信等第三方Oauth Server。

   3.获取用户
     凡是通过鉴权的接口可通过
     ctx.state.user 获取用户信息
        "id": 3,
        "username": "test01",
        "phone": "13666778899",
        "email": "[email protected]",
        "create_at": "1608521057872",
        "update_at": "1608521057872",
        "last_sign_in_at": "1609411919009"
    愉快的使用就可以了

  4.前端登录 、登出
    4.1登录
     config.xcSSO.loginURL 配置里的URL让前端直接调用即可 GET、DELETE、POST、PUT请求都可以
    4.2
     config.xcSSO.logoutURL 配置里的URL让前端直接调用即可 GET、DELETE、POST、PUT请求都可以
  
  5.客户端登录、登出、刷新token
    直接使用xc-oauth提供的用户、密码鉴权模式即可。
    然后所有业务请求Header中加入Authorization = Bearer accessToken 即可
    框架会自动适配,来源于客户端的Header还是浏览器的Cookie

  6.登出来源客户端、浏览器识别
    框架会自动判别请求来源进行登出、浏览器无需加入任何header、客户端加入Authorization = Bearer accessToken 即可
  
  7.开给第三方的API,鉴权认证
    让他们参考xc-oauth 提供的客户端凭证 鉴权方式即可,他们所有的请求header里面加入Authorization = Bearer accessToken 即可
    上述业务逻辑与自研应用一致

  8.第三方单点登录
    让他们参考xc-oauth 提供的授权码 鉴权方式即可,框架和xc-oauth自动完成单点登录

框架相对于xc.base

 1.去掉了egg-xc-auth插件,使用更完善的 egg-xc-sso进行鉴权
 2.脚手架自动生成的代码,上下文根采用 config.default中配置的,包括./init/.init.json , router.js , controller.js
 3.脚手架自动生成的代码去掉冗余注释,apidoc看起来更清爽了
 4.plugin默认禁用了mysql插件、xc-SSO插件,初始化项目的时候更加友好,不报错且不用加额外配置
 5.命名规范了下,方便debug的时候查找了,再也不用拉到node_module最底下查找了

命令行工具

1. 生成模块

指令:yarn api-init 模块 模块名称 [表名称] [数据库]

1.模块
2.模块名称
3.[表名称]可选 如果不传,初始化空的controller.js和service.js
4.[数据库]可选 默认db1

eg: yarn api-init room 房间 jg_room db1

2. 生成模块下的上下文

指令:yarn api-ctx 模块 上下文根 [表名称] [数据库]

1.模块
2.上下文根
3.[表名称]可选 如果不传,初始化空的controller.js和service.js
4.[数据库]可选 默认db1

eg: yarn api-init room 房间 jg_room db1

3. 生成api

指令:yarn api 模块 上下文根 方法名

1.模块
2.上下文根
3.方法名

eg: yarn api room room getByBimId

1) 在 api/模块/.init/.init.json中,ctxs下面的上下文根对象的apis (eg: [/api/room/.init/.init.json].ctxs.room.apis )数组添加
 {
  "fun": "getByBimId",
  "method": "DELETE",
  "url": "/bimc/v1.0.0/room/getByBimId/:bim_id",
  "name": "根据bimid查询房间"
 }

2) 运行指令

4. 生成api/ apidoc文档

默认在app/public/doc/api/下生成静态资源

指令:yarn doc-api

5. 生成app/ apidoc文档

默认在app/public/doc/app/下生成静态资源

指令:yarn doc-app

6. 生成config/config.default.js 及 config/plugin.js 模板文件(可选)

注:该命令会覆盖当前 config/config.default.js 及 config/plugin.js
建议用于项目初始化

指令:yarn init-config



##API
###BaseController
```js
//简化helper获取方式由this.ctx.helper 简化为this.helper
get helper()

// 错误统一处理 status 为200 http返回 
//  {
//   code: 500,
//   message: err.message,
//  }
error(err)

//content为错误内容可为object status为200 http返回
// {
//   code: 500,
//   message: err.message,
//   content
// }
errorContent(err, content)

// 成功统一处理 如果data为null则统一处理为执行失败错误
// {
//   code: 0,
//   message: 'success',
//   content: data,
// }
success(data)

//统一成功和失败错误处理
//如果asycnfunction 抛出错误则执行失败处理
async result(asyncFunction)

//统一处理 http参数验证及错误处理
//info验证泛型,body为验证目标对象
//body如果为undefined 默认验证request.body
//如果验证成功返回 true
//如果验证失败返回 false 并统一按照errorContent处理错误
validate(info, body)

DbController DbService

DbController 继承自BaseController

//获取helper里面的数据库对象 简化db的获取为this.db
get db()

//直接执行sql语句 框架统一处理错误,无错误抛出
async doQuery(_sql)

//直接用db1执行sql 如果查不到就返回null,查到直接返回对象
async doQueryObj(_sql)

//直接执行sql语句 有错误抛出
async doQueryError(_sql)

//执行事务
async tran(asyncFunction)

//事务回调里面直接执行sql语句
async doQueryConn(conn,_sql)

//事务回调里面直接执行sql语句 如果查不到就返回null,查到直接返回对象
async doQueryConnObj(conn,_sql)

//多数据源执行sql语句
async doMQuery(dbId,_sql)

//多数据源执行事务
async tranM(dbId,asyncFunction)

//统一防sql注入处理,sql语句里面的参数用this.to()包裹
 to(params)

helper

  //数据库操作相关 已集成到DbService和DbController 如果需要自行实现见源码
  helper.db

  //时间操作相关
  helper.time
  // 获取当前时间格式 YYYY-MM-DD HH:mm:ss.SSS
  helper.time.getCurrentTime()

report中间件 reportEnd中间件

统一为http请求加上唯一requestId 追加到 httpQuery 统一打印 http请求入参 统一打印 http执行耗时及结束标志

config

// mysql 数据库配置
const mysqlCon = {
  clients: {
    // clientId, 获取client实例,需要通过 app.mysql.get('clientId') 获取
    db1: {
      // 数据库名默认
      database: 'xc_main',
    },
    db2: {
      // 数据库名
      database: 'xc_app',
    },
    // ...
  },
  // 所有数据库配置的默认值
  default: {
    // host
    host: '',
    // 端口号
    port: '',
    // 用户名
    user: '',
    // 密码
    password: '',
  },

  // 是否加载到 app 上,默认开启
  app: true,
  // 是否加载到 agent 上,默认关闭
  agent: false,
};

Example

BaseController

'use strict';
const Controller = require('xc.base').BaseController;

class TemplateController extends Controller {
  async create() {
    if (!this.validate({
      name: { type: 'string' },
      userid: { type: 'string' },
    })) return;
    const { ctx, service } = this;
    //注意 result 里面没有 await
    await this.result(service.template.create(ctx.request.body));
  }

  async list() {
    await this.success(await this.service.template.list());
  }
}
module.exports = TemplateController;

DbService

'use strict';
const Service = require('xc.base').DbService;
class TemplateService extends Service {
  async create(info) {
    return await this.doQueryError(
      `insert into xc_p_template(name,createtime,updatetime,createuser,updateuser) values(
          ${this.to(info.name)},${this.to(this.helper.time.getCurrentTime())},${this.to(this.helper.time.getCurrentTime())}
        ,${this.to(info.userid)},${this.to(info.userid)})`
    );
  }
  async list() {
    return await this.doQuery('select * from xc_p_template');
  }
  async getSowingsTran(dateTime) {
    return await this.tran( async conn => {
      const _sql1 = `update xc_config_sowing set title = ${this.to(dateTime)} where id = 39`;
      await this.doQueryConn(conn, this_sql1);
      const _sql2 = 'select * from xc_config_sowing where id = 39';
      const result = await this.doQueryConn(conn, _sql2);
      this.logger.info(`dateTime=${dateTime}`);
      this.logger.info(`result=${JSON.stringify(result)}`);
      return result;
    });
  }
}
module.exports = TemplateService;

config

//覆盖写出字段名 保留未写出字段
exports.mysql = {
    clients: {
      db1: {
        database: 'aaa',
      },
    },
  };