@oneline/core

一个快速开发web系统的框架. 我们使用的是typescript来完成开发.

Usage no npm install needed!

<script type="module">
  import onelineCore from 'https://cdn.skypack.dev/@oneline/core';
</script>

README

oneline-core

一个快速开发web系统的框架. 我们使用的是typescript来完成开发.

目前框架源码与实际项目还在分离中, 目前使用的版本, 有问题或者建议,欢迎大家在issues中提。

install

   npm install @oneline/core;
   //or
   yarn add @oneline/core;

也可以通过@oneline/cli 来快速创建基于@oneline/core的项目结构.


  npm install @oneline/cli -g;
  
  //然后来创建项目
  oneline -c oneline-demo //online-demo为示例名称,大家可以自行修改

快速指南

视频教程地址: http://v.qq.com/vplus/962b27e96a60d6a4d198c58fb86eb4dc?page=cover

1.首先我们创建一个control: index.ts 目前我们默认是application/json的响应数据.

  import {Get, HttpResult} from '@oneline/core';
  
  class Index {

    @Get("/index", "首页")
    public index() {
      return HttpResult.ok({message: '返回成功', data: []})
    }

  }

2.创建项目启动入口: app.ts

  import {start} from '@oneline/core';
  import './index';


  start(3000);

3.启动

  node app.js

接口说明

start

 const app = start(port: number, options: WayOptions, filters: HttpFilter[], callback: Function);

我们还可以通过Start类来启动项目:

  const startServer = new Start();
  startServer.start(3000, ()=>{
    console.log("启动项目在端口: 3000")
  })

详细的Start的声明如下:

 class Start {
  addEngine(type: string, engine:(temp: string, context:any) => Promise<string>|string):Start;
  setHandlebarsEngine(engine:any):Start;
  setEjsEngine(engine:any):Start;
  setEngineOptions(options:any):Start;
  setView(path: string):Start;
  setDefaultEngine(engineName: string):Start;
  setErrorJsonFormat(isJson: boolean):Start;
  configCors(cors: WayCrosOptions):Start;
  configStatic(prefix: string, path: string):Start;
  configLog(showed: boolean):Start;
  configUploadSize(size: number):Start;  
  configDb(config: WayDBOptions):Start;
  addFilter(filter: HttpFilter):Start;
  start(port: number, host:string, callback: Function):FastifyInstance;
  start(port: number, hostCallback:string|Function, callback?: any):FastifyInstance;
}

app 为fastify实例对象. 可以根据fastify功能,增加相关功能

WayOptions

这个类型包含: db, cors, static 字段.

db是数据库配置对象. 数据库字段包含:

{
  host: string;
  port: number;
  username: string;
  password: string;
  database: string;
}

host: 服务器地址

port: 数据库端口

username: 用户名

password: 密码

database: 数据库名称

数据库目前只支持mongodb.

cors 跨域配置. 主要字段如下:

{
  origin?: string|string[]|Boolean|Function;
  methods?: string|string[];
  allowedHeaders?: string|string[];
  exposedHeaders?: string|string[];
  preflight?:Boolean,
  credentials?: Boolean
}

字段都是可选. 每个字段的作用可查看MDN文档

static: 配置静态文件路径. 配置静态文件读取的路径及请求前缀.

{prefix: string, path: string}

prefix 为请求前缀, 默认为static. 这里不需要加入斜杆(/)作为起始.

path 为静态文件的目录.

HttpFilter

abstract class HttpFilter {
  abstract chain(app:FastifyInstance, request: FastifyRequest<IncomingMessage>, response: FastifyReply<ServerResponse>, key?: String, bean?: ComponentBean):Promise<{success: boolean, message: string, break?:boolean, code?:string}>;
}

HttpFilter为过滤器, 它是一个抽象类, 需要实现这个类. 这里可以根据自己的需求来加入系统的过滤器.

callback 为一个回调函数. 启动完成后,会执行该函数.

请求注解功能

@Action

  Action(options: ComponentActionOptions)

ComponentActionOptions 类型主要有以下字段:

  path: string; //View中的请求路径 必要
  method: any; // 请求方法 必要
  paramtypes?: Array<any>; //参数类型数据
  paramNames?: Array<string>;//参数名称
  params?: object;
  actionName?: string;
  marker?:boolean;
  response?: HttpResponseHeader;

以下是Action的简便方法.

@Get

  Get(path: string | ComponentActionOptions, actionName?: string, marker:boolean = false)

path :当为string时, 这个为路由路径. 如果是ComponentActionOptions对象时, 同上.

actionName: 函数的功能说明.

marker: true 作为编组的标记, 否则是函数功能

@Post

同上

@OPTIONS

同上

@Delete

同上

参数注解

@Param

参数匹配映射. 这里包含了, 请求链接参数和实体类内容. 都可以用Param来映射到函数参数中.

  //请求: http://api.weixin.qq.com/sns/login?type=wechat
  public login(@Param('type') type: string) {
    console.log(type); // 输出wechat
  }

  //或者
  public login(@Param('type') loginType: string) {
    console.log(loginType); //输出wechat
  }

@Body({rule: object, query: object})

实体类映射. 主要用于实体类的在插入到数据库之前,做限制规则.

rule 为校验规则的对象. 主要是post请求中的实体数据.

query 为请求链接中的参数.

验证实体类

regx: 正则表达式. regx的优先级最高, 如果regx设置, 则email, required等默认的格式验证, 则被忽略.

readonly: 只读设定. 默认自动生成. 也可以指定value:(():any)来自己实现.

required: 不能为空验证. 如果需要检测是否在数据库存在, 加入connect: {dao: Dao, method: string, key: string}

email: 邮箱验证

unique: 唯一验证. 需要对比数据库的数据情况. {dao: Dao, method: string, key: string, self: boolean}. 如果self为true, 则代表更新状态.则不需要与自己作对比.

例子


 class SignUser {
   uid: string = "";
   username: string  = "";
   password: string = "";
   createTime: number = Date.now();
   from: string = "";
 }

 const SignRule = {
   signup: {
     uid: {
       label: "用户ID",
       rules: [
         {readonly: true}
       ]
     },
     username: {
       label: "用户名",
       type: String,
       rules: [
         {required: true, message: '请输入用户名'}
       ]
     },
     password: {
       label: "密码",
       type: String,
       rules: [
         {regx: /\w{6, 8}/, message: "密码必须是6~8个字符"}
       ]
     },

     from: {
       label: '来自',
       type: String,
       rules: [
         {required:true}
       ]
     }
   }
 }

 // 设置from, 来自url中. http://localhost:3000/signup?platform=app
 class SignMarker {

   @Post("/signup", "注册")
   signup(@Body({rule: SignRule.signup, query: {platform: 'from'}}) user: SignUser) {
     return HttpResult.ok({message: '注册成功'});
   }

 }

如果不满足条件, 则会报错! 不会执行函数体, 不会返回注册成功.

属性注解

@Property

属性注解用于自动注入对象, 不用自己手动创建对象.

   class Test {
     public todo() {
       console.log("todo...")
     }
   }

   class TestIndex {
      @Property() test: Test;
      public index() {
         this.test.todo();
      }

   }

mongo数据库操作

数据库操作, 我们需要在启动的时候, 配置数据库的链接

  star(3000, {
    db: {
      host: '127.0.0.1',
      port: 3690,
      database: 'oneline',
      username: 'root'
      password: '123456'
    }
  })

在操作方面, 我们内置了一个service层和数据库(Dao)操作层.

service

DefaultService<T> 这是一个抽象类, 实现了接口Service<T>. 我们也可以实现Service<T>接口, 和继承DefaultService<T>使用现有的操作数据库的方法.

dao

DefaultDao<T> 这是一个抽象类, 实现了接口Dao<T>. 我们也可以实现Dao<T>接口, 和继承DefaultDao<T>使用现有的操作数据库的方法.

例子

  
  public class User {
    uid: string = "";
    uname: string = "";
    upass: string = "";
    createTime: number = Date.now();
  }


  public class UserDao extends DefaultDao<User> {
    table: string = "ol-user";
  }


  public class UserService extends DefaultService<User> {
    @Property() dao: UserDao<User>;
  }


  public class UserAction {
    @Property() service: UserService;

    @Post("/user/signup")
    public async signup(@Body() user:User) {
      await this.service.save(user);
      return HttResult.ok({message: "注册成功"});
    }
  }


模板渲染

Type, HtmlType

Type, HtmlType是用来指定函数响应什么样的格式数据给用户。其实目前主要是用来后端渲染界面。默认是Json数据格式的返回。

  function Type(type: string, temp: string, engine:string):void;
  function HtmlType(temp: string, engine?: string):void;

Type的参数type为content-type的值, temp 为渲染的界面文件名, engine为渲染引擎的名称, 默认有handlebars, ejs. 但是必须由开发者调用Start类的方法: setHandlebarsEngine, setEjsEngine来引入引擎模块。如果要自定义引擎, 请调用Start方法: addEngine

HtmlType是基于Type的默认了type为text/html

例如:

  class TemplateAction {

    @Get("/index")
    @HtmlType("index.html") //默认为handlebars
    public index() {
      return {title: 'home'}
    }
  }