Showing preview only (274K chars total). Download the full file or copy to clipboard to get everything.
Repository: calidion/vig
Branch: master
Commit: 72ce12c69c20
Files: 355
Total size: 179.6 KB
Directory structure:
gitextract_1tm1fzl_/
├── .editorconfig
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── demo/
│ ├── chapter-1/
│ │ ├── README.md
│ │ ├── index.js
│ │ └── package.json
│ ├── chapter-2/
│ │ ├── README.md
│ │ ├── all.js
│ │ ├── get-set.js
│ │ ├── index.js
│ │ └── package.json
│ ├── chapter-3/
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── query.js
│ ├── chapter-4/
│ │ ├── README.md
│ │ ├── alias.js
│ │ ├── email.js
│ │ ├── enum.js
│ │ ├── index.js
│ │ ├── length.js
│ │ ├── package.json
│ │ └── password.js
│ ├── chapter-5/
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── phone.js
│ │ └── regex.js
│ └── chapter-6/
│ ├── README.md
│ ├── config/
│ │ └── waterline/
│ │ ├── adapter.js
│ │ ├── connections.js
│ │ ├── databases/
│ │ │ ├── mongodb.js
│ │ │ └── mysql.js
│ │ └── index.js
│ ├── config.js
│ ├── handlers/
│ │ └── user/
│ │ ├── add.js
│ │ └── index.js
│ ├── index.js
│ ├── models/
│ │ └── User.js
│ └── package.json
├── docs/
│ ├── README.md
│ ├── Session.md
│ ├── progress.md
│ └── use.md
├── package.json
├── ppt/
│ └── intro.md
├── src/
│ ├── Components/
│ │ ├── HTTP.ts
│ │ ├── VBase.ts
│ │ ├── VConfig.ts
│ │ ├── VError.ts
│ │ ├── VEvent.ts
│ │ ├── VHTTPBase.ts
│ │ ├── VMiddleware.ts
│ │ ├── VModel.ts
│ │ ├── VRouter.ts
│ │ ├── VWebSocket.ts
│ │ └── index.ts
│ ├── DefinitionParsers/
│ │ ├── VFallbackDefinition.ts
│ │ └── VPolicyDefinition.ts
│ ├── MiddlewareParsers/
│ │ ├── VBody.ts
│ │ ├── VCondition.ts
│ │ ├── VFallback.ts
│ │ ├── VFile.ts
│ │ ├── VLimitation.ts
│ │ ├── VPager.ts
│ │ ├── VPolicy.ts
│ │ ├── VSession.ts
│ │ ├── VValidator.ts
│ │ └── index.ts
│ ├── Templates/
│ │ ├── Filter.ts
│ │ └── VTemplate.ts
│ ├── VDefinition.ts
│ ├── VEvent.ts
│ ├── VHandler.ts
│ ├── VService.ts
│ ├── VWSServer.ts
│ └── index.ts
├── test/
│ ├── Components/
│ │ ├── VBase.test.ts
│ │ ├── VCondition.test.ts
│ │ ├── VConfig.test.ts
│ │ ├── VError.test.ts
│ │ ├── VFallback.test.ts
│ │ ├── VHTTPBase.test.ts
│ │ ├── VMiddleware.test.ts
│ │ ├── VPager.test.ts
│ │ ├── VPolicy.test.ts
│ │ ├── VRouter.test.ts
│ │ └── VValidator.test.ts
│ ├── VEvent.test.ts
│ ├── VFailureDefinition.test.ts
│ ├── VFile.test.ts
│ ├── VHandler.test.ts
│ ├── VModel.prepare.test.ts
│ ├── VService.test.ts
│ ├── VSession.test.ts
│ ├── VTemplate.test.ts
│ ├── bodies.test.ts
│ ├── config.test.ts
│ ├── data/
│ │ ├── component/
│ │ │ ├── conditions/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.ts
│ │ │ │ └── put.js
│ │ │ ├── configs/
│ │ │ │ └── test.js
│ │ │ ├── errors/
│ │ │ │ ├── dir/
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── no
│ │ │ │ └── vig.js
│ │ │ ├── events/
│ │ │ │ ├── hello.ts
│ │ │ │ └── send.ts
│ │ │ ├── fallbacks/
│ │ │ │ ├── condition.js
│ │ │ │ ├── fuck.js
│ │ │ │ ├── policy.js
│ │ │ │ └── validation.js
│ │ │ ├── handlers
│ │ │ ├── middlewares/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ ├── models/
│ │ │ │ ├── Pet.js
│ │ │ │ └── User.js
│ │ │ ├── pagers/
│ │ │ │ ├── get.ts
│ │ │ │ └── post.ts
│ │ │ ├── policies/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ ├── routers/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ └── validators/
│ │ │ ├── delete.js
│ │ │ ├── get.js
│ │ │ ├── options.js
│ │ │ ├── post.js
│ │ │ └── put.js
│ │ ├── component.bodies/
│ │ │ ├── asyncs/
│ │ │ │ ├── get.ts
│ │ │ │ └── post.ts
│ │ │ ├── bodies/
│ │ │ │ ├── get.ts
│ │ │ │ └── post.ts
│ │ │ ├── routers/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ └── sessions/
│ │ │ ├── get.ts
│ │ │ └── put.ts
│ │ ├── component.inheritance/
│ │ │ ├── configs/
│ │ │ │ └── upload.ts
│ │ │ ├── handlers/
│ │ │ │ └── send/
│ │ │ │ └── handlers/
│ │ │ │ ├── one/
│ │ │ │ │ ├── configs/
│ │ │ │ │ │ └── one.ts
│ │ │ │ │ ├── routers/
│ │ │ │ │ │ └── get.ts
│ │ │ │ │ └── urls.ts
│ │ │ │ └── third/
│ │ │ │ ├── configs/
│ │ │ │ │ └── third.ts
│ │ │ │ ├── routers/
│ │ │ │ │ └── get.ts
│ │ │ │ └── urls.ts
│ │ │ ├── middlewares/
│ │ │ │ ├── configs/
│ │ │ │ │ └── mad.ts
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ └── routers/
│ │ │ ├── fuck.js
│ │ │ ├── get.ts
│ │ │ ├── post.ts
│ │ │ └── put.js
│ │ ├── component.middleware/
│ │ │ ├── configs/
│ │ │ │ └── upload.ts
│ │ │ ├── middlewares/
│ │ │ │ ├── delete.ts
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ └── routers/
│ │ │ ├── fuck.js
│ │ │ ├── get.ts
│ │ │ ├── post.ts
│ │ │ └── put.js
│ │ ├── component.middleware.all/
│ │ │ ├── middlewares/
│ │ │ │ ├── all.ts
│ │ │ │ └── fuck.js
│ │ │ └── routers/
│ │ │ ├── all.js
│ │ │ └── fuck.js
│ │ ├── component.models/
│ │ │ ├── conditions/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.ts
│ │ │ │ └── put.js
│ │ │ ├── configs/
│ │ │ │ └── test.js
│ │ │ ├── errors/
│ │ │ │ ├── dir/
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── no
│ │ │ │ └── vig.js
│ │ │ ├── events/
│ │ │ │ ├── hello.ts
│ │ │ │ └── send.ts
│ │ │ ├── fallbacks/
│ │ │ │ ├── condition.js
│ │ │ │ ├── fuck.js
│ │ │ │ ├── policy.js
│ │ │ │ └── validation.js
│ │ │ ├── middlewares/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ ├── models/
│ │ │ │ ├── Pet.js
│ │ │ │ └── User.js
│ │ │ ├── pagers/
│ │ │ │ ├── get.ts
│ │ │ │ └── post.ts
│ │ │ ├── policies/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ ├── routers/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.ts
│ │ │ │ └── put.js
│ │ │ └── validators/
│ │ │ ├── delete.js
│ │ │ ├── get.js
│ │ │ ├── options.js
│ │ │ ├── post.js
│ │ │ └── put.js
│ │ ├── component.nomethod/
│ │ │ └── routers/
│ │ │ └── all.js
│ │ ├── component.policies/
│ │ │ ├── definitions/
│ │ │ │ ├── fallbacks/
│ │ │ │ │ └── ok.ts
│ │ │ │ └── policies/
│ │ │ │ ├── fail.ts
│ │ │ │ ├── ok.ts
│ │ │ │ └── test.ts
│ │ │ ├── fallbacks/
│ │ │ │ └── policy.js
│ │ │ ├── policies/
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ └── routers/
│ │ │ ├── get.js
│ │ │ ├── post.js
│ │ │ └── put.js
│ │ ├── component.sessions/
│ │ │ ├── routers/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.ts
│ │ │ │ └── put.js
│ │ │ ├── sessions/
│ │ │ │ └── all.ts
│ │ │ └── urls.ts
│ │ ├── component.templates/
│ │ │ ├── configs/
│ │ │ │ └── test.ts
│ │ │ ├── handlers/
│ │ │ │ ├── a.ts
│ │ │ │ └── send/
│ │ │ │ ├── handlers/
│ │ │ │ │ └── send/
│ │ │ │ │ ├── handlers/
│ │ │ │ │ │ └── send/
│ │ │ │ │ │ ├── routers/
│ │ │ │ │ │ │ └── get.ts
│ │ │ │ │ │ └── urls.ts
│ │ │ │ │ ├── routers/
│ │ │ │ │ │ └── get.ts
│ │ │ │ │ └── urls.ts
│ │ │ │ ├── prefix.ts
│ │ │ │ ├── routers/
│ │ │ │ │ └── get.ts
│ │ │ │ ├── templates/
│ │ │ │ │ └── views/
│ │ │ │ │ └── h2.html
│ │ │ │ └── urls.ts
│ │ │ ├── middlewares/
│ │ │ │ ├── fuck.ts
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.ts
│ │ │ │ └── put.ts
│ │ │ ├── pagers/
│ │ │ │ ├── get.ts
│ │ │ │ └── post.ts
│ │ │ ├── policies/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.ts
│ │ │ │ └── put.js
│ │ │ ├── routers/
│ │ │ │ ├── delete.ts
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ ├── templates/
│ │ │ │ ├── filters/
│ │ │ │ │ └── name.js
│ │ │ │ └── views/
│ │ │ │ └── layout.html
│ │ │ └── urls.ts
│ │ ├── component.urls/
│ │ │ ├── conditions/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.ts
│ │ │ │ └── put.js
│ │ │ ├── configs/
│ │ │ │ └── test.js
│ │ │ ├── errors/
│ │ │ │ ├── dir/
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── no
│ │ │ │ └── vig.js
│ │ │ ├── events/
│ │ │ │ ├── hello.ts
│ │ │ │ └── send.ts
│ │ │ ├── fallbacks/
│ │ │ │ ├── condition.js
│ │ │ │ ├── fuck.js
│ │ │ │ ├── policy.js
│ │ │ │ └── validation.js
│ │ │ ├── handlers/
│ │ │ │ ├── a.ts
│ │ │ │ └── send/
│ │ │ │ ├── handlers/
│ │ │ │ │ └── send/
│ │ │ │ │ ├── handlers/
│ │ │ │ │ │ └── send/
│ │ │ │ │ │ ├── routers/
│ │ │ │ │ │ │ └── get.ts
│ │ │ │ │ │ └── urls.ts
│ │ │ │ │ ├── routers/
│ │ │ │ │ │ └── get.ts
│ │ │ │ │ └── urls.ts
│ │ │ │ ├── routers/
│ │ │ │ │ └── get.ts
│ │ │ │ └── urls.ts
│ │ │ ├── middlewares/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ ├── models/
│ │ │ │ ├── Pet.js
│ │ │ │ └── User.js
│ │ │ ├── pagers/
│ │ │ │ ├── get.ts
│ │ │ │ └── post.ts
│ │ │ ├── policies/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ ├── prefix.ts
│ │ │ ├── routers/
│ │ │ │ ├── delete.ts
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.js
│ │ │ │ ├── post.js
│ │ │ │ └── put.js
│ │ │ ├── templates/
│ │ │ │ ├── filters/
│ │ │ │ │ └── name.ts
│ │ │ │ └── views/
│ │ │ │ └── layout.html
│ │ │ ├── urls.ts
│ │ │ └── validators/
│ │ │ ├── delete.js
│ │ │ ├── get.js
│ │ │ ├── options.js
│ │ │ ├── post.js
│ │ │ └── put.js
│ │ ├── component.websockets/
│ │ │ ├── configs/
│ │ │ │ ├── session.ts
│ │ │ │ └── upload.ts
│ │ │ ├── routers/
│ │ │ │ ├── fuck.js
│ │ │ │ ├── get.ts
│ │ │ │ ├── post.ts
│ │ │ │ └── put.js
│ │ │ ├── sessions/
│ │ │ │ └── all.ts
│ │ │ └── websockets/
│ │ │ ├── broadcast.ts
│ │ │ ├── enter.ts
│ │ │ ├── false.ts
│ │ │ ├── get.ts
│ │ │ ├── leave.ts
│ │ │ ├── post.ts
│ │ │ ├── put.ts
│ │ │ └── user.ts
│ │ ├── configs/
│ │ │ └── test.js
│ │ ├── errors/
│ │ │ ├── dir/
│ │ │ │ └── .gitkeep
│ │ │ ├── no
│ │ │ └── vig.js
│ │ ├── errorsHandlers.ts
│ │ ├── eventsHandlers.ts
│ │ ├── fallbacks/
│ │ │ ├── ok.js
│ │ │ └── test.js
│ │ ├── fixtures/
│ │ │ ├── events.js
│ │ │ └── events.once.js
│ │ ├── models/
│ │ │ ├── Pet.js
│ │ │ └── User.js
│ │ ├── nomethodHandlers.ts
│ │ ├── nourlsHandlers.ts
│ │ ├── policies/
│ │ │ ├── ok.ts
│ │ │ └── test.ts
│ │ ├── policiesHandler.ts
│ │ ├── prefixHandlers.ts
│ │ ├── routersHandler.ts
│ │ ├── uploader/
│ │ │ ├── a.txt
│ │ │ └── b.txt
│ │ ├── uploadersHandlers.ts
│ │ └── validationsHandlers.ts
│ ├── error.test.ts
│ ├── handlers.test.ts
│ ├── index.test.ts
│ ├── inheritance.test.ts
│ ├── middlewares.test.ts
│ ├── nomethod.test.ts
│ ├── pager.test.ts
│ ├── policies.test.ts
│ ├── prefix.test.ts
│ ├── typings.d.test.ts
│ └── validations.test.ts
├── tsconfig.json
└── tslint.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
================================================
FILE: .gitignore
================================================
coverage/
node_modules/
npm-debug.log
.nyc_output
.tmp
.vscode
lib
uploaded
package-lock.json
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- '13'
- '12'
- '11'
- '10'
- '9'
- '8'
script:
- npm run build # build
- npm run coverage # run mocha unit tests with coverage
after_script:
- 'cat coverage/lcov.info | ./node_modules/.bin/coveralls' # sends the coverage report to coveralls
================================================
FILE: LICENSE
================================================
Copyright 2016 calidion <caldiion@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# (this project is deprecated in favor of the new fast, simple, async web framework for nodejs: [aex](https://github.com/calidion/aex/))
# vig
[![NPM version][npm-image]][npm-url]
[![Downloads][downloads-image]][npm-url]
[![Downloads][downloads-image-month]][npm-url]
[![Build Status][travis-image]][travis-url]
[![Dependency Status][daviddm-image]][daviddm-url]
[![Coverage percentage][coveralls-image]][coveralls-url]
[![Backers][backers-image]](#backers)
[![Sponsors][sponsors-image]](#sponsors)
## 简介
一个受sailsjs启发的新Web框架,但是追求小而美,而又敏捷,灵活,高效。以完成MVC的C端为重点,插件化的Web框架。
## 交流QQ群
423652352
## 导航
[[缘起](https://github.com/calidion/vig/wiki)] [[教程](https://github.com/calidion/vig/wiki/%E6%95%99%E7%A8%8B)]
## 示例
国内: [https://t1bao.com/](https://t1bao.com/)
国外: [https://forum.webfullstack.me/](https://forum.webfullstack.me/)
## vig与其它框架单机性能测试对照
详细见文章:
[ 一个支持async的超高性能的基于node.js的Web业务框架](https://t1bao.com/thread/visit/11)

> vig是一个Web业务框架,本身并不想处理Web协议层面的事情。
> 但是因为协议与上层的业务是紧密关联的,所以未来可能会参与到协议层框架的开发上去。
> 原因很简单,虽然vig相对于express的折损只有1%多点。
> 但是如果基于koa的也只折损1%,那么vig的性能就会大大的提高。
## 关于vig
是一个专注于Web业务逻辑的组件化框架,主要关心:
1. 精减Web业务处理的代码
2. 简化常规Web业务的处理
3. 加速项目的开发
4. 是一个简化Web业务处理的Web框架
5. 将Web的业务逻辑标准化,可重用化是vig的主要目标
目标是:
1. 模块化(Modular)
2. 可插件化(Pluggable)
3. 可重入化(Reenterable)
4. 可集成化(Integratable)
## 功能列表
1. 组件化,所的功能都是组件级的
2. 简化的路由机制
3. 简洁,而强大的数据输入校检
4. 方便的权限验证功能
5. 框架内的事件机制
6. 实用的VIG API规范支持
7. 简单的文件上传机制
8. 简单的模型定义方式(基于waterline)
9. 统一的错误处理机制(基于Errorable)
10. 组件配置支持与全局配置支持
11. 模板支持
## 快速上手
1、创建一个test.ts文件(推荐使用TS)
```sh
vi test.ts
```
2、添加如下代码
```js
import { VHandler } from "vig";
let app = require('express')();
const handler = new VHandler();
handler.set({
prefix: '/demo',
urls: ['/', '/hello'],
routers: {
get: async (req, res, scope) => {
res.send('Hello world!');
}
}
});
handler.attach(app);
app.listen(10000, function () {
console.log('server running on http://localhost:10000');
});
```
3、安装包
```sh
yarn install
```
4、测试
```
npm test
```
## 关于async/await支持的几点说明
vig对async/await的支持依赖于用户的开发环境本身,与vig框架无关。
但是开发者需要注意的是:
1. async/await无法实现对事件的支持,所以回调函数与async/await是不同的。
2. 回调函数不会消失,async/await也无法适用于所有的场景
所以在使用vig框架时需要注意事件与IO回调的区别。
下面再将事件与常规的IO调用的差别说明一下。
1. IO的调用本身也是事件。
2. IO调用本身也是可以不定期的,比如网络IO。
3. 对于时间与任务明确的IO调用,推荐async/awati,比如数据库访问,文件访问等。
4. 对于不明确的事件应该使用回调,比如有些网络IO,一些硬件的IO事件,如键盘事件,鼠标事件等。
5. async/await无法取代回调函数
## 安装
```sh
$ npm install --save vig
$ yarn add vig
# 推荐使用1.0版本
$ npm install --save vig@next
$ yarn add vig@next
```
## 版本说明
Semver不但引起了版本爆炸,也让版本失去了意义。
所以vig采用 · [Effective Versioning](https://github.com/calidion/effective-versioning) · 的版本管理方式。
1. 尽量保持小版本的一致性,但是不保证小版本升级一定是接口不变的
2. 不推荐动不动升级,只有你当前的版本不能满足你的需要时再升级
## 使用yarn取代npm作为包管理软件
由于semver的错误,npm5之后软件的版本已经固定下来,不再执行semver里自动升级的方式。
对于非npm5的用户来说,仍存在严重的包版自动升级风险,因此vig推荐所有人使用yarn来解决你的版本不一致的问题。
## 项目地址
https://github.com/calidion/vig
## Contributors
This project exists thanks to all the people who contribute.
<a href="https://github.com/calidion/vig/graphs/contributors"><img src="https://opencollective.com/vig/contributors.svg?width=890&button=false" /></a>
## Backers
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/vig#backer)]
<a href="https://opencollective.com/vig#backers" target="_blank"><img src="https://opencollective.com/vig/backers.svg?width=890"></a>
## Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/vig#sponsor)]
<a href="https://opencollective.com/vig/sponsor/0/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/vig/sponsor/1/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/vig/sponsor/2/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/vig/sponsor/3/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/vig/sponsor/4/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/vig/sponsor/5/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/vig/sponsor/6/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/vig/sponsor/7/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/vig/sponsor/8/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/vig/sponsor/9/website" target="_blank"><img src="https://opencollective.com/vig/sponsor/9/avatar.svg"></a>
## License
Apache-2.0 © [calidion](https://github.com/calidion)
[downloads-image]: http://img.shields.io/npm/dt/vig.svg
[downloads-image-month]: http://img.shields.io/npm/dm/vig.svg
[npm-image]: https://img.shields.io/npm/v/vig.svg
[npm-url]: https://npmjs.org/package/vig
[travis-image]: https://travis-ci.org/calidion/vig.svg?branch=master
[travis-url]: https://travis-ci.org/calidion/vig
[daviddm-image]: https://david-dm.org/calidion/vig.svg?theme=shields.io
[daviddm-url]: https://david-dm.org/calidion/vig
[coveralls-image]: https://coveralls.io/repos/calidion/vig/badge.svg
[coveralls-url]: https://coveralls.io/r/calidion/vig
[backers-image]: https://opencollective.com/vig/backers/badge.svg
[sponsors-image]: https://opencollective.com/vig/sponsors/badge.svg
================================================
FILE: demo/chapter-1/README.md
================================================
# 最简服务器创建与URL机制讲解
vig框架的目标是快速的完成Web业务的开发,同时提升模块化水平。
目标听起来很完美,如果无法付之行动,那么就是没有意义的。
所以在这个系列文章中,我们将会陆续介绍vig框架的使用。
这一节我们介绍如何使用vig做一个最简单的hello world服务器。
## 基础步骤
要完成一个最基本的vig服务器,只需要完成以下三步:
1、引入基础服务器
目前vig只测试了express的代码,所以只能支持express的基础服务器,
因为需要引入一个express服务器
2、初始化vig系统
3、添加一个handler服务器
## 代码示例
所以完成后的代码就是这样的:
```node
var app = require('express')();
var vig = require('vig');
vig.init(app);
vig.addHandler(app, {
urls: ['/'],
routers: {
get: function (req, res) {
res.send('Hello world!');
}
}
});
app.listen(10000, function () {
console.log('server running on http://localhost:1000');
});
```
## 运行效果
然后
```
node index.js
```
运行一下:

启动成功。
然后通过浏览器打开,效果如下:

我们得到了hello world!输出。
是不是很简单呢?
## url别名
如果你注意的话,会发现handler里使用的是urls.
原因很简单,vig是支持URL别名机制的。
所以你可以填写多个URL地址而得到同样的处理。
比如我在urls上添加一个新的地址:
```
urls: ['/', '/hello'],
```
这时再访问浏览器,一样可以得到相同的返回结果。
效果如下图,注意地址栏上多出来的'/hello'。

## url前缀
vig框架提供了简单的前缀机制。
只要在handler里添加prefix字段,就可以实现前缀机制了。这对于项目不同的版本的维护可以带来很大的便利性。
```node
var app = require('express')();
var vig = require('vig');
vig.init(app);
vig.addHandler(app, {
prefix: '/demo',
urls: ['/'],
routers: {
get: function (req, res) {
res.send('Hello world!');
}
}
});
app.listen(10000, function () {
console.log('server running on http://localhost:1000');
});
```
然后分别访问几个地址的结果如下:




prefix后,所有的url都加上了/demo前缀,之前的URL地址就失效了。
以上就是vig的简单的使用教程,是不是很简单呢?
欢迎留言告诉我你的问题.
================================================
FILE: demo/chapter-1/index.js
================================================
var app = require('express')();
var vig = require('vig');
vig.init(app);
vig.addHandler(app, {
prefix: '/demo',
urls: ['/', '/hello'],
routers: {
get: function (req, res) {
res.send('Hello world!');
}
}
});
app.listen(10000, function () {
console.log('server running on http://localhost:1000');
});
================================================
FILE: demo/chapter-1/package.json
================================================
{
"name": "demo",
"version": "1.0.0",
"description": "vig框架的目标是快速的完成Web业务的开发,同时提升模块化水平。目标听起来很完美,如果无法付之行动,那么就是没有意义的。 所以在这个系列文章中,我们将会陆续介绍vig框架的使用。 这一节我们介绍如何使用vig做一个最简单的hello world服务器。",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
================================================
FILE: demo/chapter-2/README.md
================================================
# vig对HTTP方法的支持与提供的几种处理机制介绍
上一讲我们讲到了vig的url机制里的:
1. 别名机制
2. 前缀机制
这一讲我们来讲解vig的:
1. 增强机制
2. 增强机制的HTTP处理方式
3. vig api的规范以及提供的http方法
vig框架最首要的目标是减少开发过程中的重复劳动,提升开发者的生产率。
让开发者可以不被常规的web业务所分心,集中精力将业务功能快速,安全的开发出来。
所以vig框架最大的核心功能就是这些用于减少开发量的增强功能。
所以我们下面一起来看一下增加功能都有那些,以及这些增强如何处理不同的http请求方法。
## 增强机制(enhancements)
1. routers
2. validations
3. policies
4. failures
5. conditions
这些增强是vig得以加速开发的根本所在,也是vig的最核心功能。
以后的章节,我们将会详细的介绍每个模块的用法。
现在我们简单的介绍一下:
1. routers 是对HTTP方法的路由与处理,是所有处理的核心。
2. validations 是对路由上的数据进行校验,如果错误则会中断处理,并返回错误信息。如果正确则会直接提取校验数据,而忽略其它的数据。
3. policies 是对路由用户权限的一种检验,只有通过权限校验的用户才有权访问。
下面我们介绍他们对各种http方法的统一处理格式。
## http方法的处理机制
所有的vig增强都是针对http方法处理的。
基本格式如下:
```
enhancements : {
method: [function | object]
}
```
1. enhancements就是上面列举的几个增强的名字。比如我们上一节使用的routers.
未来如果我们的vig进一步的扩展,可能会有更多的增强关键字。而你只需要在关键字属性上添加你的处理就可以了。
2. method就是express支持的所有HTTP方法,不合法的HTTP方法会被自动的忽略,所以在编写时要注意方法写正确,并且是以字母小写的形式书写。
3. method同时支持all方法,all方法表示接受所有的HTTP请求,一般不建议使用。
所以如果我们要对routers的get与set都进行处理,我们的处理函数就会是这样的。
vs code 编辑器上的效果:
;
原始代码:
```node
// get-set.js
module.exports = {
prefix: '/get-set',
urls: ['/'],
routers: {
get: function (req, res) {
res.send('get');
},
post: function (req, res) {
res.send('post');
}
}
};
```
如果我们要对所有的方法进行处理,我们的处理函数就会是这样的。
vs code 编辑器上的效果:
;
原始代码:
```node
// all.js
module.exports = {
prefix: '/all',
urls: ['/'],
routers: {
all: function (req, res) {
res.send('all');
}
}
};
```
我们给上面的处理加上了前缀,所以就可以一起将他们放到vig框架里了。
因此我们的框架代码就是这样的。
vs code 编辑器上的效果:
;
原始代码:
```node
var app = require('express')();
var vig = require('vig');
var all = require('./all');
var gs = require('./get-set');
vig.init(app);
vig.addHandler(app, all);
vig.addHandler(app, gs);
app.listen(10000, function () {
console.log('server running on http://localhost:10000');
});
```
这里大家可以看到,我们的addHandler加载的是一个包。
所以基于这一点,我们是不是就可以很方便的去组成我们的处理函数了呢?
下面我们运行一下主函数:
```
node index.js
```
然后得到:
;
运行成功。
然后我们分别查看几个URL上的返回结果。由于这次我们的结果需要POST请求的支持,所以我使用POSTMAN来测试。
效果如下:
1. get

2. post

3. all

是不是很简单呢?
通过这个示例,我们可以看出来,vig倾向于在同一个URL上一起处理所有的逻辑,并将他们归类到一起处理。
所以其它的增强也跟routers是一样的遵循这个基本的使用原则。所以只要理解了rourters的使用,就理解了整个vig增强体系。
vig 框架除了增强了Web业务的处理,也对API的设计有自己的理解。因些我们制定有vig api规范(原名egg api),因为egg的npm包被占用,所以egg框架改名为vig。
## 基于vig api规范(原egg api),对HTTP方法与URL使用的一些建议
1. 如果你的API是返回的业务数据,只使用HTTP的GET/POST。GET用于获取、查询数据,POST用于提交,删除,修改数据。
2. 不建议使用其它的HTTP方法,除非一定需要
3. 对于API来说,应尊重URL用于定位的理念,即URL上尽量只保留名词,将方法使用query形式提交.即user/1?action=edit.
未来的版本里,vig将会添加这一支持.让资源/业务定位的理念在框架上有更好的实现。
4. vig api本身并不是完全支持RESTful api的理念的,vig api更加支持业务实际,但是RESTful api里很多先进的理念会被vig api继承下来。
## 相关资源的地址
vig api(即egg api,未来将会改名成vig api)规范地址:
[https://github.com/calidion/egg](https://github.com/calidion/egg)
vig 框架地址:
[https://github.com/calidion/vig](https://github.com/calidion/vig)
这样vig框架的C(Controller)端的基本核心机制就已经介绍完了,是不是很简单呢?
下一节,我们将会介绍如何对数据进行校验,以及如何使用校验后的数据。
如果你有对框架或者文章的疑问或者建议,欢迎到github上提问或者留言。也可以关注公共账号:frontend-guru并留言。
================================================
FILE: demo/chapter-2/all.js
================================================
module.exports = {
prefix: '/all',
urls: ['/'],
routers: {
all: function (req, res) {
res.send('all');
}
}
};
================================================
FILE: demo/chapter-2/get-set.js
================================================
module.exports = {
prefix: '/get-set',
urls: ['/'],
routers: {
get: function (req, res) {
res.send('get');
},
post: function (req, res) {
res.send('post');
}
}
};
================================================
FILE: demo/chapter-2/index.js
================================================
var app = require('express')();
var vig = require('vig');
var all = require('./all');
var gs = require('./get-set');
vig.init(app);
vig.addHandler(app, all);
vig.addHandler(app, gs);
app.listen(10000, function () {
console.log('server running on http://localhost:10000');
});
================================================
FILE: demo/chapter-2/package.json
================================================
{
"name": "chapter-2",
"version": "1.0.0",
"description": "上一讲我们讲到了vig的url机制里的: 1、别名机制 2、前缀机制",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
================================================
FILE: demo/chapter-3/README.md
================================================
# 通过vig实现对输入数据的校验与提取
通常输入数据的校验对于程序的安全性来讲是非常重要的,但是检验数据通常又会变成非常无聊、重复、浪费时间的事情。
所以vig框架希望能将开发者从这部分工作中解脱出来。
因此提供了validations和conditions来协助用户更加有效,方便,灵活的对数据进行校验。
本篇文章主要介绍validations的使用。
# validation机制——vig的Web业务增强功能之一
vig的validation支持是通过validations字段来实现的。而validations属于我们上一篇介绍的几个基本增强,所以用法跟routers一样。
但是validations支持object验证,以及提取,所以会比routers要复杂一些。
# 基本的validation用法。
validation可以支持的数据输入类型有三类:
1、query,即<code>?</code>号后的内容,比如<code>?a=1&b=1</code>里的a和b.
2、params,即URL的Pattern所对应的内容,比如<code>/user/:id</code>里的id
3、body, 即post所提供的内容,比如post数据里的<code>a=1&b=1</code>里的a和b
> 暂时不支持文件的校验
## 校验query
query可以出现在post,也可以出现在get的请求里。
我们先看看出现在get里的情况,
vs code 编辑器上的效果:
;
原始代码:
```
module.exports = {
prefix: '/query',
urls: ['/'],
routers: {
all: function (req, res) {
var extracted = req.extracted;
res.send(extracted.query.id);
}
},
validations: {
get: {
query: {
id: {
type: 'int'
}
}
}
}
};
```
我们基于以上代码发起请求:
分别得到如下的结果:
1. 没有带任何参数时

2. 带上非指定字段时:

3. 带上正确字段与正确的数值时:

4. 带上正确字段与错误的数值时:

## 疑问1:没有传入id时,竟然也到达了get处理
这里在没有通过验证ID的情况下,也可以通过,但是有没有办法让query的验证必须传入后才能通过到达get处理呢?
答案是:有的。
在vig里只要在validations添加上
```
required: ['query'],
```
就可以要求query必须传入了。同样的,还可以添加上
```
required: ['query', 'params', 'body'],
```
要求所有的输入都必须有,且通过校验。
添加required后,我们的验证代码变成这样:

我们再查看<code>/query</code>不带参数的结果如下:

这时我们发现query已经返回403,内容是<code>Access Denied</code>了。
## 疑问2,如果出错了,想手动添加不同的处理,应该如何处理呢?
在vig框架里的处理也是很简单的那就是使用failures增强。
所以我们下面看一下如何手动的处理出错信息。
我们在handler里添加failures处理,代码如下:

这里我们重新启动服务器,再访问一个错误链接。
我们得到了下面的结果:

这时返回的不再是Access Denied!这个默认返回了。
这样你就可以根据需要自行处理错误结果了。
这里要注意的是:
1. 在failures上添加错误处理时,字段名是单数的。
即
validations => validation
policies => policy
conditions => condition
2. 处理必须是函数,参数分别是err, req, res, next
err是表示失败的原因或者信息的
req: 表示http请求
res: 表示http发送
next: 是回调函数。如果res.send发送结束后,通常不必回调。
# 小结
今天我们以query为例子简单的介绍了vig里如何简单的处理输入校验以及处理校验错误的方法。
下面几节,我们将深入的学习vig能校验的重要字段类型,以及补充对params,body进行校验的例子。
另:如果你对nodejs开发或者开源项目感兴趣,也欢迎加入我们的QQ开发群:
nodejs全栈开发群: 423652352
nodejs开源项目交流群: 312685910
也可以关注我们的公共帐号: frontend-guru
进行咨询与了解。
================================================
FILE: demo/chapter-3/index.js
================================================
var app = require('express')();
var vig = require('vig');
var query = require('./query');
vig.init(app);
vig.addHandler(app, query);
app.listen(10000, function () {
console.log('server running on http://localhost:10000');
});
================================================
FILE: demo/chapter-3/package.json
================================================
{
"name": "chapter-3",
"version": "1.0.0",
"description": "通常输入数据的校验对于程序的安全性来讲是非常重要的,但是检验数据通常又会变成非常无聊、重复、浪费时间的事情。 所以vig框架希望能将开发者从这部分工作中解脱出来。 因此提供了validations和conditions来协助用户更加有效,方便,灵活的对数据进行校验。 本篇文章主要介绍conditions的使用。",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.14.0",
"vig": "^0.7.2"
}
}
================================================
FILE: demo/chapter-3/query.js
================================================
module.exports = {
prefix: '/query',
urls: ['/'],
routers: {
all: function (req, res) {
var extracted = req.extracted;
if (extracted && extracted.query) {
res.send(extracted.query.id);
} else {
res.send('ok');
}
}
},
validations: {
get: {
required: ['query'],
query: {
id: {
type: 'int'
}
}
}
},
failures: {
validation: function (err, req, res, next) {
res.send('id validation falied!');
}
}
};
================================================
FILE: demo/chapter-4/README.md
================================================
# 通过vig实现对输入数据的校验详解
上一讲我们讲到了数据校验的基本规则与提取方法,但是我们只讲到了int类型的校验。
这一讲我们再详细的讲解vig更加强大的校验机制。
# vig校验的类型与类型外的特殊方法讲解
除了校验类型之外,我们通常还会有一些附属的校验要求。这一节我们主要介绍几个常用的校验类型与特殊方法。
## 对字符串限定长度
表达形式:
```
max: {
type: 'string',
maxLength: 5,
minLength: 2,
required: true
}
```
对于如下的代码:

我们的执行结果是这样的:

第一种情况是长度超过返回错误,
第二种情况是正确的返回结果.
第三种情况是长度过短返回的错误。
## 密码确认或者字符匹配
在输入校验过程中,我们经常碰到的是两次密码需要的匹配情况,vig里配置密码与确定密码变的非常容易。
只需要在字段里添加<code>matches</code>字符,找到要对应的字段名即可。
表达形式如下:
```
password: {
type: 'string',
maxLength: 5,
minLength: 2,
required: true
},
confirm: {
matches: 'password'
}
```
对于如下的代码:

我们的执行结果是这样的:

第一种情况是正确的返回结果。
第二,三种情况都是匹配错误的情况。
## 别名提取(alias)
有时候输入输出接口的命名与你的系统命令并不一致,这时你可以通过别名的方式将数据名修改成你想要的。
表达形式如下:
```
alias: {
type: 'email',
alias: 'mem'
}
```
对于如下的代码:

我们的执行结果是这样的:

将email提取成了mem。
## enum类型
enum类型用于校验类型受限的字符串。
表达形式如下:
```
enum: {
type: 'enum',
enums: ['A', 'B', 'C']
}
```
对于如下的代码:

我们的执行结果是这样的:

只要不是['A', 'B', 'C']中的值,校验就都会失败。
# 小结
这一节课,我们主要讲解了web校验中非常实用的功能与基本的类型,是不是感觉一下子提取与校验数据一下子特别的没有负担了呢?
下一节,我们将继续讲解常用并且特殊的类型与方法以及常用的类型用法。
另:如果你对nodejs开发或者开源项目感兴趣,也欢迎加入我们的QQ开发群:
nodejs全栈开发群: 423652352
nodejs开源项目交流群: 312685910
也可以关注我们的公共帐号: frontend-guru
进行咨询与了解。
================================================
FILE: demo/chapter-4/alias.js
================================================
module.exports = {
prefix: '/alias',
urls: ['/'],
routers: {
all: function (req, res) {
var extracted = req.extracted;
if (extracted && extracted.query) {
res.send(JSON.stringify(extracted.query) + '\n');
} else {
res.send('ok');
}
}
},
validations: {
get: {
required: ['query'],
query: {
email: {
type: 'email',
alias: 'mem'
}
}
}
},
failures: {
validation: function (err, req, res, next) {
res.send(JSON.stringify(err) + '\n');
}
}
};
================================================
FILE: demo/chapter-4/email.js
================================================
module.exports = {
prefix: '/email',
urls: ['/'],
routers: {
all: function (req, res) {
var extracted = req.extracted;
if (extracted && extracted.query) {
res.send(extracted.query.email + '\n');
} else {
res.send('ok');
}
}
},
validations: {
get: {
required: ['query'],
query: {
email: {
type: 'email'
}
}
}
},
failures: {
validation: function (err, req, res, next) {
res.send(JSON.stringify(err) + '\n');
}
}
};
================================================
FILE: demo/chapter-4/enum.js
================================================
module.exports = {
prefix: '/enum',
urls: ['/'],
routers: {
all: function (req, res) {
var extracted = req.extracted;
if (extracted && extracted.query) {
res.send(JSON.stringify(extracted.query) + '\n');
} else {
res.send('ok');
}
}
},
validations: {
get: {
required: ['query'],
query: {
enum: {
type: 'enum',
enums: ['A', 'B', 'C']
}
}
}
},
failures: {
validation: function (err, req, res, next) {
res.send(JSON.stringify(err) + '\n');
}
}
};
================================================
FILE: demo/chapter-4/index.js
================================================
var app = require('express')();
var vig = require('vig');
var email = require('./email');
var length = require('./length');
var password = require('./password');
var alias = require('./alias');
var enum1 = require('./enum');
vig.init(app);
vig.addHandler(app, email);
vig.addHandler(app, length);
vig.addHandler(app, password);
vig.addHandler(app, alias);
vig.addHandler(app, enum1);
app.listen(10000, function () {
console.log('server running on http://localhost:10000');
});
================================================
FILE: demo/chapter-4/length.js
================================================
module.exports = {
prefix: '/length',
urls: ['/'],
routers: {
all: function (req, res) {
var extracted = req.extracted;
if (extracted && extracted.query) {
res.send(extracted.query.length + '\n');
} else {
res.send('ok');
}
}
},
validations: {
get: {
required: ['query'],
query: {
length : {
type: 'string',
maxLength: 5,
minLength: 3,
required: true
}
}
}
},
failures: {
validation: function (err, req, res, next) {
res.send(JSON.stringify(err) + '\n');
}
}
};
================================================
FILE: demo/chapter-4/package.json
================================================
{
"name": "chapter-4",
"version": "1.0.0",
"description": "上一讲我们讲到了数据校验的基本规则与提取方法,但是我们只讲到了int类型的校验。 这一讲我们再详细的讲解vig可以校验那些主要的数据类型。",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.14.0",
"vig": "^0.7.3"
}
}
================================================
FILE: demo/chapter-4/password.js
================================================
module.exports = {
prefix: '/password',
urls: ['/'],
routers: {
all: function (req, res) {
var extracted = req.extracted;
if (extracted && extracted.query) {
res.send(JSON.stringify(extracted.query) + '\n');
} else {
res.send('ok');
}
}
},
validations: {
get: {
required: ['query'],
query: {
password : {
type: 'string',
required: true
},
confirm: {
matches: 'password'
}
}
}
},
failures: {
validation: function (err, req, res, next) {
res.send(JSON.stringify(err) + '\n');
}
}
};
================================================
FILE: demo/chapter-5/README.md
================================================
# 通过vig实现对输入数据的校验详解(二)
上一讲我们讲到了几个重要的类型与检测方法,这一讲,我们继续介绍常用用的数据类型的校验。
## 对移动电话号码的检验
表达形式:
```
phone: {
type: 'phone'
}
```
对于如下的代码:

我们的执行结果是这样的:
输入正确的手机号:

输入错误的手机号:

## 自定义正则表达式
虽然vig默认提供了很多类型的检测能力,但是这些类型仍可能无法满足您的需求,所以vig也支持正则表达式的校验,让您可以完全自己控制所有的输入参数。
表达形式:
```
fieldname : {
type: 'regex',
regex: /xxx/
}
```
对于如下的代码:

我们的执行结果是这样的:
输入正确的字符串:

输入错误的字符串:



# 小结
这一节课,我们已经将vig里的重要的校验方式已经讲完了,通过以上的校验技巧将可以帮助你校验除文件外的所有的输入数据。
下一节,我们将讲解如何在vig里使用数据库,如何编写模型,以及如何使用模型输入数据。
如果你对vig框架的源码感兴趣,可以直接访问:
https://github.com/calidion/vig
查看。
另:如果你对nodejs开发或者开源项目感兴趣,也欢迎加入我们的QQ开发群:
nodejs全栈开发群: 423652352
nodejs开源项目交流群: 312685910
也可以关注我们的公共帐号: frontend-guru
进行咨询与了解。
================================================
FILE: demo/chapter-5/index.js
================================================
var app = require('express')();
var vig = require('vig');
var phone = require('./phone');
var regex = require('./regex');
vig.init(app);
vig.addHandler(app, phone);
vig.addHandler(app, regex);
app.listen(10000, function () {
console.log('server running on http://localhost:10000');
});
================================================
FILE: demo/chapter-5/package.json
================================================
{
"name": "chapter-5",
"version": "1.0.0",
"description": "上一讲我们讲到了几个重要的类型与检测方法,这一讲,我们继续介绍常用用的数据类型的校验。",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.14.0",
"vig": "^0.7.4"
}
}
================================================
FILE: demo/chapter-5/phone.js
================================================
module.exports = {
prefix: '/phone',
urls: ['/'],
routers: {
all: function (req, res) {
var extracted = req.extracted;
if (extracted && extracted.query) {
res.send(extracted.query.phone + '\n');
} else {
res.send('ok');
}
}
},
validations: {
get: {
required: ['query'],
query: {
phone: {
type: 'phone'
}
}
}
},
failures: {
validation: function (err, req, res, next) {
res.send('phone validation falied!\n');
}
}
};
================================================
FILE: demo/chapter-5/regex.js
================================================
module.exports = {
prefix: '/regex',
urls: ['/'],
routers: {
all: function (req, res) {
var extracted = req.extracted;
if (extracted && extracted.query) {
res.send(extracted.query.regex + '\n');
} else {
res.send('ok');
}
}
},
validations: {
get: {
required: ['query'],
query: {
regex: {
type: 'regex',
regex: /[a-z]{3}/,
required: true
}
}
}
},
failures: {
validation: function (err, req, res, next) {
res.send('regex validation falied!\n');
}
}
};
================================================
FILE: demo/chapter-6/README.md
================================================
# 通过vig实现对数据库的操作
上面几讲我们讲了vig对输入数据的校验,这一讲我们来讲一下vig对数据库操作的支持。
目前vig是基于waterline这个orm库来实现对数据库的操作的。
原因是他足够简单易用,方便书写,代码清晰。
waterline是sailsjs的默认ORM,而vig是受sailsjs启发的一个框架。
我们下面一起来看一下使用waterline定义数据库简单在那里。
# 定义数据模型
下面的代码是放在User.js里的代码,他定义了一个User的模型:

```js
module.exports = {
connection: 'default', // 指定连接配置
identity: 'user', // 指定的唯一标识
schema: true,
tableName: 'user', // 指定的表名
attributes: {
username: {
type: 'string',
required: true,
unique: true
},
password: {
type: 'string',
required: true
}
}
};
```
# 初始化
vig里面提供了models对象来初始化模型。
1. vig.models.addDir
通过vig.models.addDir来添加模型的路径。
由于waterline限制的原因,目前vig的模型路径暂时是唯一的。
2. vig.models.init
通过vig.models.init可以初始化模型的数据库配置并启动waterline。

```js
var path = require('path');
var dir = path.resolve(__dirname, './models/');
// 添加路径
vig.models.addDir(dir);
// 初始化配置
vig.models.init(config, {
connection: 'default' // 配置连接为默认(default)连接
}, function (error, models) {
// 这里的models就是初始化完成后的所有的模型
// 名字与文件对应。推荐的模型文件名是大写的模式,如: User, Student,Tag等。
});
```
# 在Handler里调用
在初始化调用完成后,每个Handler里的req.models就可以调用包含你定义的模型了。
在这里就是User模型。代码如下:

```js
User.create({
username: username,
password: password
}).then(function(created) {
res.send(created);
});
```
这样对我们的模型的基本调用就完成了。
# 访问效果
由于我们的教程都是有具体的样例的,所以我们可以看一下样例返回的结果。
我们访问的地址是:http://localhost:10000/add,
结果如下:
```json
{
"username":"username1484234334529",
"password":"password1484234334529",
"createdAt":"2017-01-12T15:18:54.532Z",
"updatedAt":"2017-01-12T15:18:54.532Z",
"id":"58779e5e81aceb251b204408"
}
```

# 小结
waterline是目前vig默认支持的ORM,未来可能还会有新的不同的ORM可以加入。
但是waterline确实是一个不错的ORM,从示例的代码可以看出来他是非常简单可配置的。
值得一试,vig将会优先推荐最精简,最实用的ORM。
================================================
FILE: demo/chapter-6/config/waterline/adapter.js
================================================
var mongoAdapter = require('sails-mongo');
var mysqlAdapter = require('sails-mysql');
module.exports = {
mongo: mongoAdapter,
mysql: mysqlAdapter
};
================================================
FILE: demo/chapter-6/config/waterline/connections.js
================================================
// database connections
var mysql = require('./databases/mysql');
var mongodb = require('./databases/mongodb');
// 这里的adapter的值,就是adapter.js里面的字段名
mysql.adapter = 'mysql';
mongodb.adapter = 'mongodb';
module.exports = {
default: mysql,
mysql: mysql,
mongodb: mongodb
};
================================================
FILE: demo/chapter-6/config/waterline/databases/mongodb.js
================================================
module.exports = {
url: process.env.FORIM_MONGO_DB_URI || 'mongodb://127.0.0.1:27017/vig'
};
================================================
FILE: demo/chapter-6/config/waterline/databases/mysql.js
================================================
module.exports = {
host: process.env.FORIM_MYSQL_DB_HOST || '127.0.0.1',
user: process.env.FORIM_MYSQL_DB_USER || 'vig',
password: process.env.FORIM_MYSQL_DB_PASSWORD || 'vig',
database: process.env.FORIM_MYSQL_DB_NAME || 'vig',
prefix: process.env.FORIM_MYSQL_DB_PREFIX || ''
};
================================================
FILE: demo/chapter-6/config/waterline/index.js
================================================
var adapter = require('./adapter');
var connections = require('./connections');
module.exports = {
adapters: adapter,
connections: connections,
defaults: {
migrate: 'alter'
}
};
================================================
FILE: demo/chapter-6/config.js
================================================
var mysqlConf = {
adapter: 'mysql',
};
var mongoConf = {
adapter: 'mongo',
url: process.env.FORIM_MONGO_DB_URI || 'mongodb://127.0.0.1:27017/forim'
};
var mongoAdapter = require('sails-mongo');
var mysqlAdapter = require('sails-mysql');
var mongo = require
module.exports = {
adapters: {
mongo: mongoAdapter,
mysql: mysqlAdapter
},
connections: {
default: mongoConf,
mongo: mongoConf,
mysql: mysqlConf
},
defaults: {
migrate: 'alter'
}
};
================================================
FILE: demo/chapter-6/handlers/user/add.js
================================================
module.exports = {
urls: ['/add'],
routers: {
get: function (req, res) {
var username = "username" + new Date().getTime();
var password = "password" + new Date().getTime();
var User = req.models.User;
User.create({
username: username,
password: password
}).then(function(created) {
res.send(created);
});
}
}
};
================================================
FILE: demo/chapter-6/handlers/user/index.js
================================================
var requires = ['add'];
var modules = [];
for (var i = 0; i < requires.length; i++) {
modules = modules.concat(require('./' + requires[i]));
}
console.log('inside user');
module.exports = modules;
================================================
FILE: demo/chapter-6/index.js
================================================
var app = require('express')();
var vig = require('vig');
var user = require('./handlers/user');
var config = require('./config');
var path = require('path');
var dir = path.resolve(__dirname, './models/');
vig.models.addDir(dir);
vig.models.init(config, {
connection: 'default'
}, function (error, models) {
if (error) {
console.error('数据库出错,请检查你的配置!');
console.error(error, config.connections);
throw error;
}
vig.init(app);
vig.addHandlers(app, user);
app.listen(10000, function () {
console.log('server running on http://localhost:10000');
});
});
================================================
FILE: demo/chapter-6/models/User.js
================================================
module.exports = {
connection: 'default', // 指定连接配置
identity: 'user', // 指定的唯一标识
schema: true,
tableName: 'user', // 指定的表名
attributes: {
username: {
type: 'string',
required: true,
unique: true
},
password: {
type: 'string',
required: true
}
}
};
================================================
FILE: demo/chapter-6/package.json
================================================
{
"name": "chapter-6",
"version": "1.0.0",
"description": "上面几讲我们讲了vig对数据的操作,这一讲我们来讲一下vig对数据库操作的支持。 目前vig是基于waterline这个orm库来实现对数据库的操作的。 原因是他足够简单易用,方便书写,代码清晰。",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"sails-mongo": "^0.12.2",
"sails-mysql": "^0.11.5",
"vig": "^0.7.4"
}
}
================================================
FILE: docs/README.md
================================================
# VIG 文档
[Session和Cookie的配置](./Session.md)
================================================
FILE: docs/Session.md
================================================
VIG的Session与express的Session是一样的。
唯一的不同就是VIG支持不同的页面使用不同的Session配置,而在express下面这种配置不同是无法实现的。
下面我们介绍如何在VIG中配置Session。
### Session的配置位置
如果是直接通过VHandler设计的话,那么位置在`configs.session.middleware`;
也就是当你使用VHandler进行目录配置时,目录是`/configs/session.ts`
这时session.ts的内容示例如下:
```
import * as session from "express-session";
export = {
middleware: session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
cookie: { secure: true }
})
};
```
这里的session就是express的session。可以随便的根本需要修改。
如果是直接通过VHandler的set函数进行设置的话,代码是这样的。
```
import * as session from "express-session";
import { VHandler } from "vig";
const vhandler = new VHandler();
vhandler.set({
configs: {
session: {
middleware: session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
cookie: { secure: true }
})
}
}
});
vhandler.attach(app);
```
这样Session的配置就完成,配置好之后就可以根据需要在适当的地方使用了。
### Session使用
session的使用可以根本HTTP的方便来编写。
比如我们要对get使用session.
#### 文件
那么配置路径是`sessions.get`;
如果是`sessions/get.ts`文件。
这时`get.ts`的内容示例如下:
```
export = {
session: true
};
```
这样,当每次get请求发起时,系统都会启动session机制获得相关的session信息了。
其它方法的使用情况与这个是完全一样的。只需要修改一下文件名比如`post.ts`
如果要让所有的HTTP方法都使用Session,只需要提供`all.ts`即可。里面的内容跟`get.ts`中一样。
#### 变量
如果是直接通过VHandler的set函数进行设置的话,代码是这样的。
```
import * as session from "express-session";
import { VHandler } from "vig";
const vhandler = new VHandler();
vhandler.set({
sessions: {
get: {
session: true
},
post: {
session: true
}
}
});
vhandler.attach(app);
```
### Cookies
如果你只需要Cookies,但是不需要Session.
你可以这样写。
```
import * as session from "express-session";
import { VHandler } from "vig";
const vhandler = new VHandler();
vhandler.set({
sessions: {
get: {
cookies: true
}
}
});
vhandler.attach(app);
```
================================================
FILE: docs/progress.md
================================================
# Web基本的业务模型内容与vig的完成目标与进度
对于现在常见的Web模型,他通常包括如下的内容:
1. 请求与返回(Request & Response)
[由基础Web框架提供]
2. 前端与后端(Frontend & Backend)
[vig只关心后端,将会提供传统的HTML模板能力与API提供能力,其它的前端功能不会再提供]
3. 数据库抽象与业务逻辑的连接(Database Design & Business Logic analystics)
[vig不提供直接的M层支持, 但是基于waterline,提供了优秀的ORM机制]
4. 安全策略与权限管理(Security & Privileges)
[已经完成]
5. 共享用户与单点登录(User Sharing & Autchenication)
6. 配置动态化与自动化( Configuration & Automation)
7. 标准化接口(API Standardization)
[基于errorable-express提供标准输出API]
8. 模块化与独立化,可分布式化(Modulization,Indepency, Distribution)
9. 错误返回(Error Response)
[已经完成]
10. 文件上传与云传输(Cloud File Distribution)
[已经完成]
11. 数据输入的过滤与校验(Input Data Filtering and Validation)
[已经完成]
12. 将控制器、模型、业务、库、路由更方便的进行标准化。
13. HTML页面模板
[由第三方提供,vig只提供接入方法]
14. 接入socket.io,提供WebSocket的能力
所以我们在设计这个框架时,将会着重关注以上的几点。
并努力的将这些核心内容接口化,标准化,从而方便迁移与升级。
# vig框架的原型
vig 框架的原型已经在forim框架有所体现。
但是vig未来会加强forim里的原型代码的模块化并且会适时的更新到forim上去验证。
forim项目地址:
https://github.com/calidion/forim/
原型代码地址:
https://github.com/calidion/forim/tree/master/lib/v2
# vig的现有组成
## 基础web框架
目前会以express的接口为标准,未来如果有可能会进行标准化。
所以测试框架会优先选择express,
由于vig的目标是基础框架无关的关注Web业务逻辑的框架,
所以只要是基于express接口标准的框架都可以轻松的与vig配合使用。
express项目地址:
http://expressjs.com/
## ORM模型
ORM模型
优先选择waterline
项目地址:
https://github.com/balderdashy/waterline
## 错误标准
会使用errorable的错误规范
项目地址:
https://github.com/calidion/errorable
## api标准
目前称为egg api,不会考虑restful api,
因为vig是偏向Web业务的框架,所以使用偏向于业务的egg api,而不是偏向资源的RESTful API。
未来egg api会修改为 vig api
项目地址:
https://github.com/calidion/egg
## 云存储
采用file cloud uploader
项目地址:
https://github.com/calidion/file-cloud-uploader
## 数据校验
可以一次性方便的对输入数据进行检验。
采用集成node-form-validator的方式进行
https://github.com/calidion/node-form-validator
## 参考框架
sailsjs
项目地址:
http://sailsjs.org/
================================================
FILE: docs/use.md
================================================
### 生成错误
```js
// errors.js
var common = require('errorable-common');
var errorable = require('errorable');
var Generator = errorable.Generator;
var errors = new Generator(common, 'zh-CN').errors;
module.exports = errors;
```
### 设定路由及处理函数
```js
// handlers.js
module.exports = [{
prefix: '/prefix', // 最后不能接'/'
urls: ['/', '/:id', '/user/:id'], // 必须以'/'开头
/**
* 路由处理定义,只要熟悉nodejs的req, res都知道如何处理了
*/
// @方式一
routers: {
get: function (req, res) {
res.errorize(res.errors.Success);
},
post: function (req, res) {
res.restify(res.errors.Failure);
}
},
// @方式二
routers: {
all: function (req, res) {
res.errorize(res.errors.Success);
}
},
/**
* 策略定义,成功调用next(true),失败调用next(false);
*/
policies: {
get: function (req, res, next) {
next(true);
},
post: function (req, res, next) {
next(true);
}
},
/**
* 检验条件定义,如果需要校验调用next(true),如果不需要校验调用next(false);
*/
conditions: {
get: function (req, res, next) {
next(true);
}
},
/**
* 失败统一处理机制
*/
failures: {
validation: function(error, req, res) {
// res.status(403).send('Access Denied');
},
condition: function(error, req, res) {
// res.status(403).send('Access Denied');
},
policy: function(error, req, res) {
}
},
/**
* 检验规则,即可添加函数自己编写,可以直接对query, params, body进行规则编写.
* 一个handler只能有一种数据格式,暂时不支持文件检验
*/
validations: {
get: function (req, res, next) {
next(true);
},
post: {
required: ['query'], // 指定必须有内容,并且必须匹配的属性,
// 默认validations的属性并不是强制必须传输的
query: {
username: {
type: 'string',
required: true,
maxLength: 30,
minLength: 2
},
password: {
type: 'string',
required: true,
minLength: 6,
maxLength: 30
}
},
params: {
id: {
type: 'int',
required: true
}
},
body: {
value: {
type: 'int',
required: true
}
}
}
},
/**
* 事件定义,无URL无关,可以在任何一个Handler里定义
*/
events: {
names: ['@event1', '@event2', 'bad'],
handlers: {
'@event1': function (next) {
next('@event1');
},
'@event2': function (next) {
next('@event2');
}
}
},
}];
```
### 调用vig框架
```js
var vig = require('vig');
vig.init(app, errors);
vig.addHandlers(app, handlers);
```
## 基于waterline的ORM技术
### 添加orm目录
vig的models放在指定的目录,需要手动转入目录告诉vig,然后调用vig.models.addDir添加。
代码如下:
```js
var path = require('path');
var dir = path.resolve(__dirname, './models/');
vig.models.addDir(dir);
```
### 编写一个model
详细使用请查看waterline的文档。
```js
// User.js
module.exports = {
identity: 'user', // 需要唯一
attributes: { // 所有的字段
firstName: 'string',
lastName: 'string',
}
};
```
### 初始化orm,必须在指定dir之后才能生效
```js
var config = {
adapters: {
memory: sailsMemoryAdapter
},
connections: {
default: {
adapter: 'memory'
}
}
};
var options = {
connection: 'default'
};
vig.models.init(config, options,
function (error, models) {
if (error) {
throw error;
}
// models.User.find()
});
```
上面的`models`就是定义的全部ORM模型。
这时你可以通过`models.User`来访问他。
`User`是去掉了`.js`的文件名。
这样你的orm功能就可以使用了。
详细的模型的使用方法参考[waterline](https://github.com/balderdashy/waterline-docs)
### 文件上传与云上传
文件上传使用的是skipper。
文件的云上传使用的是file-cloud-uploader。
使用req.file调用skipper。
使用req.cloud调用的是file-cloud-uploader。
比如提交一个字段名为txt的文件,代码如下:
```js
app.post('/file/upload', function (req, res) {
req.cloud('txt', {
type: 'disk',
config: {
dir: path.resolve(__dirname, './uploaded/'),
base: 'http://localhost'
}
}).then(function (files) {
res.send(String(files.length));
});
});
```
1. req.cloud(filedName, options)
2. req.cloud返回文件数组的Promise
3. 通过
```js
var file = files[i];
var ulr = file.url;
```
来获取文件访问信息。
================================================
FILE: package.json
================================================
{
"name": "vig",
"version": "1.0.0-rc-2",
"description": "a component based web framework, focus on web basic logics",
"license": "MIT",
"repository": "calidion/vig",
"author": {
"name": "calidion",
"email": "caldiion@gmail.com",
"url": ""
},
"files": [
"lib"
],
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"keywords": [
"nodejs",
"express",
"vig"
],
"scripts": {
"clean": "rimraf lib",
"lint": "tslint --force --format verbose \"src/**/*.ts\"",
"prebuild": "rimraf node_modules && yarn install",
"build": "npm run clean && npm run lint && echo Using TypeScript && tsc --version && tsc --pretty",
"test": "npm run build && nyc --reporter=text --reporter=html --reporter=lcov mocha --bail --compilers ts:ts-node/register --recursive 'test/**/*.test.ts'",
"coverage": "nyc --include='src/**/*.ts' --reporter=text --reporter=html --reporter=lcov mocha --bail --compilers ts:ts-node/register --recursive 'test/**/*.test.ts'",
"watch": "npm run build -- --watch",
"watch:test": "npm run test -- --watch",
"postinstall": "opencollective-postinstall"
},
"dependencies": {
"async": "^3.1.0",
"body-parser": "^1.18.1",
"cookie-parser": "^1.4.3",
"errorable": "^0.4.0",
"errorable-common": "^0.1.0",
"errorable-express": "0.0.4",
"file-cloud-uploader": "^0.0.6",
"lodash": "^4.17.15",
"node-form-validator": "^1.5.2",
"nunjucks": "^3.0.1",
"skipper": "^0.8.2",
"waterline": "^0.11.11",
"ws": "^7.2.0"
},
"devDependencies": {
"@types/chai": "^4.0.4",
"@types/mocha": "^2.2.43",
"@types/node": "^8.0.28",
"chai": "^4.1.2",
"codecov": "^3.7.1",
"connect": "^3.6.4",
"coveralls": "^2.13.1",
"errorable-common": "^0.1.0",
"express": "^4.15.4",
"express-session": "^1.15.5",
"mocha": "^3.5.3",
"nyc": "^11.2.1",
"opencollective": "^1.0.3",
"opencollective-postinstall": "^2.0.2",
"restify": "^6.0.1",
"rimraf": "^2.6.2",
"sails-memory": "^0.10.7",
"supertest": "^3.0.0",
"ts-node": "^3.3.0",
"tslint": "^5.7.0",
"typescript": "^2.5.2",
"yarn": "^1.21.0"
},
"engines": {
"node": ">=4.0.0"
},
"nyc": {
"include": [
"src/**/*.ts"
],
"exclude": [
"lib"
],
"extension": [
".ts"
],
"require": [
"ts-node/register"
],
"reporter": [],
"all": true
},
"collective": {
"type": "opencollective",
"url": "https://opencollective.com/vig"
}
}
================================================
FILE: ppt/intro.md
================================================
`vig`
===
## 不一样的框架
##### by [calidion](https://github.com/calidion)
----
vig是什么?
===
1. 一个新的框架
2. 简单,轻量,高速
3. 基于Web业务本身
4. 关注Web业务的细节
5. 非传统MVC框架
1) 无具体的Controller
2) Model和View可选
6. 基于Node.js
---
为什么要开发vig
===
1. 目前似乎没有纯做Web业务的框架
2. 减少重复的处理Web常规业务的代码
3. 找出更多的常规Web业务场景
4. 减少开发时间
5. 对传统MVC框架的不满
---
vig 1.0 包含那些新的内容?
===
1. 固定了很多中间件功能及位置,减少类似于express.use这样的中间件的选择
2. 将常用的Web业务固定化.比如对于post,默认支持form表单解析;比如默认的文件上传功能等。
3. 纠正koa中间件中错误方式,实现无回调函数的async/await中间件,以及回归中间件的线性本质
4. 提供了组件部分属性可承继的功能,从而实现了层次化组织HTTP请求的能力
---
vig 1.0 包含那些新的内容?(二)
===
5. 默认除事件(event)外,所有的调用函数都是支持async/await异步调用的
6. 支持WebSocket,并提供了自动的Session功能。让游戏,聊天室的编写更加的方便。
7. 为几乎所有中间件与请求添加了scope对象,让系统可以更加方便的获取系统的配置与设置,而无需要引用相对的文件。
8. 模板的分布式组合
---
如何理解vig?
===
可以将vig理解为express++
1. 几乎兼容所有的express中间件
2. 支持与express协同开发
3. 增强了async/await
4. 增强了web逻辑的处理能力
---
vig对web的看法
===
vig将web看成是一条直线。在这个直线上有很多处理点。而vig做的事情就是将这些点提出来,并且将这些点细化。所以我们可以将这个模型称之为web请求直线,简称***Web直线***。
也就是说vig是基于HTTP的请求直线来开发的框架。
它的起点是req请求到达服务器,终点是处理完成后通过res发送出去。
---
## web直线
1. 最简单的表示
```
req => process => res
```
2. 更加详细,但是并不全面的表示
```
req => middlewares(parser, authorization,
security / policy, conditional entrance,
valiator)
=> router => product logic => output => res
```
3. process的内容是可大可小的,vig将优先做好最核心最常用的部分
---
## vig关注的点
***Web直线***上除`产品逻辑(product logic)`外所有Web技术问题。
也就是说vig要完全区分开`web逻辑(web logic)`与`产品逻辑(product logic)`。
同时要为编写`产品逻辑`提供很好的技术基础。
---
## 深化与突破MVC
vig对mvc有如下的看法:
1. mvc是一个简单的模型,现实场景远比MVC复杂
2. 认为mvc三者都是可选的,并不需要完备
3. 同时mvc三者都是可拆解的,并且vig主要是拆解了C
4. 认为MVC是递归的,所以C里仍可以包括有完整的MVC体系
基于以上的几点看法,才会了vig对MVC的突破。
---
## 消除回调地狱,全面async/await化
在0.8发布时,vig并没有马上提供async/await化的支持。
一方面是时间不允分,也有与旧代码兼容的原因。
0.9版本开始,vig就全面转向了async/await。
所有的中间件,路由都通过async/await来实现异步。
1.0版本开始,vig提供了scope,让系统的变量与中间件都可以很好的通过scope来被访问,同时scope提供了依赖注入的能力。
---
## 版本升级
在vig的版本管理上,vig否定了semver的理想主义原则。
采用了[effective versioning](https://github.com/calidion/effective-versioning)的态度。即:
1. 不鼓励升级
2. 不做自动升级
3. 小版本,表示错误修正或者小调整,建议努力保持兼容,但不做兼容保证
4. 大版本表示架构的变动或者属性的大规模升级,但是仍可以保持兼容性
> Effective Versioning完全否定了大小版本基于兼容性的特点。
---
## 包管理
由于Semver的理论的错误,导致了npm在处理包上存在重大错误。
经常会导致包不稳定,并且包作者无法控制。
因此谷歌等多家公司联合起来推出了yarn这个包管理工具,试图将包的依赖固定,从而保证包的稳定性,从而可以在产生环境下保证代码的迁移不变性。
因此vig推荐使用yarn包管理工具来管理vig项目。
npm5对这类问题进行了修复,但是考虑到不同node使用的npm版本可能不同,所以直接使用yarn更加的简单,不容易混淆。
---
## URL为中心的框架,面向微服务的架构
### 传统MVC框架的问题
#### Controller的控制粒度过大取
login(get) 获取登录页面与login(post)进行登录操作通常混在一起编写。对于get我们并不需要数据检验,但是对于post我们是需要数据检验的。而写在一起代码就显得混乱。
#### 模块化能力差
将GET/POST事件放在一个方法处理,不方便业务逻辑的分离,模板化水平低
#### 耦合度高
将GET/POST事件进行了耦合,代码的独立性降低,耦合度增加。
---
## URL为中心的框架,面向微服务的架构
### vig的解决方案
与传统的MVC框架不同,vig里的代码的组织是基于URL的,或者说是基于业务/逻辑单元的。
在vig里,处理是基于URL来组织起来的。通过URL将业务分割成独立的单元。
所以/user/login对应不同的HTTP方法,处理是完全分开的。
所以每个请求的代码都很短,并且处理的方式完全不同,get方法时不会加载中间件,会非常快。post时会自动加载form处理,加载validator进行验证,所以可以完美的解决传统MVC框架存在的问题。
除了解决传统MVC框架的问题外,vig还有很多其它的可能性。
---
## 明确的中间件排序
由于我们之前讲到了Web直线,而在直线上的任何两个点都是有方向性的。因些我们的很多中间件其实也是有序列。
所以vig的工作就是找到这些顺序,并且按正确的方式排列出来。
一个简单的例子就是,你必须将post过来的body解析后,你才能对body的数据进行校验。
所以body parser 一定在validator之前。
但是在写vig时,你就不需要考虑他们的顺序,因为vig都帮你处理好了。
---
## scope建立处理与系统的桥梁
通常,我们获取系统的配置,请求过来的数据,检验的结果等数据都是需要自己手动写的。
但是在vig里,scope会很好的帮助你完成这些工作。
scope会提供上级以及当前的处理URL程序的所有配置信息,经过校验的数据,分页的信息等。
系统的模型类的信息。
scope是路由(Router)处理中最核心的对象。
scope对象是一种***弱水共享***(即弱水三行, 我只取一瓢)。
本身scope里有很多内容,但是router处理里,只需要取出相应的需要的内容进行处理即可。
---
## scope获取系统内容
const {models, errors,configs} = scope
即可获得系统定义的模型与错误信息
models: 整个系统的模型
errors: 整个系统的错误与当前组件错误的整合结果
configs: 整个系统的配置与当前组件的配置的整合结果
---
## 支持npm包级别模块化
前面讲到vig是按处理逻辑来划分模块的,这样的好处是能将模块直接打包成npm包。
然后在使用到的时候直接包含进来,非常有利于团队的协作开发与集成测试。
---
## API错误的统一处理
vig基于errable提供了统一的API错误机制。
1. 基于errorable
2. 包括基本的错误代码
3. 方便的自定义机制
---
## 层次化的模板管理
---
# 高效
1. 基础执行高效
“Hello World"程序的效率约等于基础框架
2. 单个请求高效,灵活
单个请求所经过的路由
3. 整体上高效
---
## 分布+组装的模板
## 适合的场景
1. Web网站快速开发
2. 实时应用,如游戏与聊天室,股票行情等
3. 网站与实时应用在用户上具高度一致性的项目
## vig的调试
1. 支持debug模块,但尚不完善
2. `DEBUG=vig:*` 即可开启调试模式
<!-- footer: This is a footer -->
================================================
FILE: src/Components/HTTP.ts
================================================
export class HTTP {
public static methods = [
"all",
"checkout",
"copy",
"delete",
"get",
"head",
"lock",
"merge",
"mkactivity",
"mkcol",
"move",
"m-search",
"notify",
"options",
"patch",
"post",
"purge",
"put",
"report",
"search",
"subscribe",
"trace",
"unlock",
"unsubscribe"
];
}
================================================
FILE: src/Components/VBase.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import * as fs from "fs";
import * as path from "path";
import { promisify } from "bluebird";
/**
* Base class for all Components
*/
export abstract class VBase {
// Default path where components can read definitions from
protected defaultPath = ""
// Component base directory
protected basePath = ""
// Stored data from specified directory.
protected data: any = {};
// files loaded
protected files: string[] = [];
// data types:
// named: named by filename
// nameless: merged by object
protected nameless = false;
// Filter enabled to ignore files whose names are not in array filters.
protected filterEnabled = false;
// Names should be filtered.
protected filters: string[] = [];
// Alloed extensions
protected allowedExt = [".js", ".ts", ".json"];
constructor(basePath: string) {
this.basePath = basePath;
}
public toAsync(cb, self) {
const pcb = promisify(cb);
return async (...args) => {
await pcb.apply(self, args);
}
}
public toMethods() {
const json = {
methods: []
};
for (const key of Object.keys(this.data)) {
json.methods.push(key);
json[key] = this.data[key];
}
return json;
}
public get() {
return this.data;
}
public set(data) {
if (!data) {
return;
}
this.data = data;
}
public getFiles() {
return this.files;
}
public reset() {
this.data = {};
this.files = [];
}
public addFile(file: string = "") {
if (fs.existsSync(file)) {
this.files.push(file);
}
}
public getFile(file: string): object {
if (fs.existsSync(file)) {
const json = require(file);
return json;
}
return null;
}
public extends(name: string, json: object, data: any = {}) {
if (this.nameless) {
data = Object.assign(this.data, json);
} else {
data[name] = json;
}
return data;
}
public generate(data = {}) {
this.files.forEach((file) => {
const json = require(file);
const name = path.basename(file, path.extname(file))
data = this.extends(name, json, data);
});
return data;
}
// public filter() {
// if (!this.filterEnabled) {
// return;
// }
// this.files = this.files.map((file) => {
// return this._filter(file);
// });
// }
public loadOn() {
this.set(this.load());
}
public parseDir(dir = "") {
if (fs.existsSync(dir)) {
return dir;
}
return false;
}
public parseFile(dir, file) {
const absPath = path.resolve(dir, file);
const stat = fs.statSync(absPath);
// ignore directories
if (stat && stat.isDirectory()) {
return false;
}
// read from valid extensions only
if (this.allowedExt.indexOf(path.extname(file)) === -1) {
return false;
}
if (this.filterEnabled && !this._filter(absPath)) {
return false;
}
const loaded = require(absPath);
if (!this.isType(loaded)) {
return false;
}
return { path: absPath, loaded };
}
public dirReader(dir, iterator) {
dir = this.parseDir(dir);
if (dir) {
const files = fs.readdirSync(dir);
files.forEach((file) => {
return iterator(dir, file);
});
this.files = this.files.filter((value, index, self) => {
return self.indexOf(value) === index;
});
}
return dir;
}
// public addDir(dir) {
// this.dirReader(dir, (realDir, file) => {
// const parsed = this.parseFile(realDir, file);
// if (!parsed) {
// return;
// }
// // this.files.push(parsed.path);
// });
// }
public load(dir: any = "", data = {}) {
if (!dir) {
dir = path.resolve(this.basePath, this.defaultPath);
}
if (this.dirReader(dir, (realDir, file) => {
const parsed = this.parseFile(realDir, file);
if (!parsed) {
return;
}
this.files.push(parsed.path);
const name = path.basename(parsed.path, path.extname(parsed.path))
data = this.extends(name, parsed.loaded, data);
})) {
return data;
}
}
protected _filter(file: string) {
const name = path.basename(file, path.extname(file))
if (this.filters.indexOf(name) !== -1) {
return file
}
return null;
}
// Define types able to be parsed
protected abstract isType(item: any): boolean;
}
================================================
FILE: src/Components/VConfig.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VBase } from "./VBase";
export class VConfig extends VBase {
constructor(path) {
super(path)
this.defaultPath = "configs";
}
public isType(item: any): boolean {
return item instanceof Object;
}
public parse(scope) {
if (Object.keys(this.data).length) {
scope.configs = this.data;
}
}
}
================================================
FILE: src/Components/VError.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { Generator } from "errorable";
import { VBase } from "./VBase";
import * as errorize from "errorable-express";
import * as common from "errorable-common";
import * as _ from "lodash";
export class VError extends VBase {
protected locale = "zh-CN"
private cache = null;
constructor(basePath = "", locale = "zh-CN") {
super(basePath)
this.nameless = true;
this.locale = locale;
this.defaultPath = "errors";
}
public isType(item: any): boolean {
return item instanceof Object;
}
public set(data) {
super.set(data);
this.cache = null;
}
public parse(scope) {
if (!this.cache) {
this.cache = this.generate(this.locale, false);
}
scope.errors = this.cache;
}
public generate(locale: string = "zh-CN", filesOnly = true): object {
let errors = super.generate();
if (!filesOnly) {
errors = _.merge(errors, this.data);
}
errors = _.merge(errors, common);
const generator = new Generator(errors, locale);
return generator.errors;
}
}
================================================
FILE: src/Components/VEvent.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VBase } from "./VBase";
export class VEventReader extends VBase {
constructor(basePath) {
super(basePath)
this.defaultPath = "events";
}
public isType(item: any): boolean {
return item instanceof Object;
}
public async run(key, args) {
const handler = this.data[key];
if (handler instanceof Function) {
await handler.apply(this, args);
}
}
}
================================================
FILE: src/Components/VHTTPBase.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VBase } from "./VBase";
import { HTTP } from "./HTTP";
import * as debug from "debug";
const print = debug("vig:httpbase");
export class VHTTPBase extends VBase {
protected failurable = false;
protected failureHandler: () => void;
constructor(path) {
super(path);
this.filterEnabled = true;
this.filters = HTTP.methods;
}
public isType(item: any): boolean {
return item instanceof Function || item instanceof Array;
}
public check(req) {
const method = req.method.toLowerCase();
return this.data[method] || this.data.all;
}
public checkEx(req, scope) {
const method = req.method.toLowerCase();
const handler = this.data[method] || this.data.all;
if (handler instanceof Function) {
return handler;
}
if (handler instanceof Array) {
return handler;
}
if (typeof handler !== "string") {
return false;
}
return this.getDefinition(handler, this.defaultPath, scope);
}
public getDefinition(handler, name, scope) {
const definitions = scope.definitions;
const namedHandler = definitions[name];
if (!namedHandler) {
return false;
}
const result = namedHandler[handler];
if (!result) {
return false;
}
if (result instanceof Function) {
return result;
}
return false;
}
public setFailureHandler(handler) {
this.failureHandler = handler;
}
public extend(method, handler) {
if (!(handler instanceof Function)) {
return false;
}
if (this.filters.indexOf(method) === -1) {
return false;
}
this.data[method] = handler;
return true;
}
public getFallback(req, scope) {
const handler: any = this.failureHandler;
if (handler instanceof Function) {
return handler;
}
if (typeof handler !== "string") {
return false;
}
return this.getDefinition(handler, "fallbacks", scope);
}
public async process(req, res, scope): Promise<boolean> {
const handler = this.checkEx(req, scope);
if (handler instanceof Function) {
const processed: boolean = await this._onProcess(handler, req, res, scope);
return processed;
}
if (handler instanceof Array) {
for (const f of handler) {
const processed: boolean = await this._onProcess(f, req, res, scope);
if (!processed) {
return false;
}
}
}
return true;
}
public async onPassed(req, res, scope, info, cb) {
if (cb instanceof Function) {
return await cb(info, req, res, scope);
} else {
return this.onAuthorFailed(info, req, res, scope);
}
}
public onAuthorFailed(message, req, res, scope): boolean {
print(message)
print(req.body);
print(req.params);
print(req.query);
res.status(403).end("Access Denied!");
return false;
}
protected async _onProcess(func, req, res, scope): Promise<boolean> {
const passed = await func(req, res, scope);
if (!this.failurable || passed) {
return true;
}
const falback = this.getFallback(req, scope);
if (falback instanceof Function) {
falback(true, req, res, scope);
} else {
this.onAuthorFailed(true, req, res, scope);
}
return false;
}
}
================================================
FILE: src/Components/VMiddleware.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VHTTPBase } from "./VHTTPBase";
/**
* Middleware class
* Handles:
* 1. parser => parsing all input data
* 2. authenticator => authenticating all the requests
* 3. validator => validator all input data
* 4. pager => extracting pagination info
*/
export class VMiddleware extends VHTTPBase {
constructor(path = "") {
super(path)
this.defaultPath = "middlewares";
}
public async process(req, res, scope): Promise<boolean> {
const handler = this.checkEx(req, scope);
if (handler instanceof Function) {
const processed: boolean = await handler(req, res, scope);
return processed;
}
if (handler instanceof Array) {
for (const f of handler) {
const processed: boolean = await f(req, res, scope);
if (processed === false) {
return false;
}
}
}
return true;
}
}
================================================
FILE: src/Components/VModel.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VBase } from "./VBase";
import * as Waterline from "waterline";
import { promisify } from "bluebird";
export class VModel extends VBase {
public static async fetch(config, options) {
if (VModel.initialized) {
return VModel.models;
}
return await VModel.prepare(config, options);
}
public static async prepare(config, options) {
const waterline = new Waterline();
const data: any = VModel.data;
for (const key in data) {
if (typeof key === "string") {
const model = data[key];
for (const k in options) {
if (typeof k === "string") {
model[k] = options[k];
}
}
const connection = Waterline.Collection.extend(model);
waterline.loadCollection(connection);
}
}
const initialize = promisify(waterline.initialize);
const ontology = await initialize.call(waterline, config);
const results = {};
for (const key of Object.keys(data)) {
results[key] = ontology.collections[data[key].identity];
}
VModel.initialized = true;
VModel.models = results;
return results;
}
protected static initialized = false;
protected static data = {};
protected static models = {};
constructor(basePath = "") {
super(basePath)
this.defaultPath = "models";
}
public parse(scope) {
if (VModel.initialized) {
scope.models = VModel.models;
}
}
public isType(item: any): boolean {
return item.attributes instanceof Object;
}
public loadOn(data = null) {
if (!data) {
this.set(this.load());
data = this.data;
}
VModel.data = Object.assign(VModel.data, data);
}
}
================================================
FILE: src/Components/VRouter.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VHTTPBase } from "./VHTTPBase";
export class VRouter extends VHTTPBase {
constructor(path = "") {
super(path);
this.defaultPath = "routers";
}
public async run(req, res, scope): Promise<any> {
const handler = this.checkEx(req, scope);
if (handler) {
return await this._run(handler, req, res, scope);
}
return false;
}
protected async _run(func, req, res, scope): Promise<any> {
return await func(req, res, scope);
}
}
================================================
FILE: src/Components/VWebSocket.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VBase } from "./VBase";
import { VWSServer } from "../VWSServer";
export class VWebSocket extends VBase {
constructor(path) {
super(path)
this.defaultPath = "websockets";
}
public isType(item: any): boolean {
return item instanceof Function;
}
public async run(event, message, ws, req, scope) {
const eh = this.get();
const handler = eh[event];
await handler(ws, req, scope, message);
}
}
================================================
FILE: src/Components/index.ts
================================================
export * from "./HTTP";
export * from "./VBase";
export * from "./VConfig";
export * from "./VEvent";
export * from "./VError";
export * from "./VMiddleware";
export * from "./VRouter";
export * from "./VModel";
export * from "./VWebSocket";
================================================
FILE: src/DefinitionParsers/VFallbackDefinition.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VBase } from "../Components/VBase";
export class VFallbackDefinition extends VBase {
constructor(path) {
super(path)
this.defaultPath = "fallbacks";
}
public isType(item: any): boolean {
return item instanceof Object;
}
}
================================================
FILE: src/DefinitionParsers/VPolicyDefinition.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VBase } from "../Components/VBase";
export class VPolicyDefinition extends VBase {
constructor(path) {
super(path)
this.defaultPath = "policies";
}
public isType(item: any): boolean {
return item instanceof Object;
}
}
================================================
FILE: src/MiddlewareParsers/VBody.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VHTTPBase } from "../Components/VHTTPBase";
import { promisify } from "bluebird";
import * as parser from "body-parser";
import * as skipper from "skipper";
export class VBody extends VHTTPBase {
constructor(path) {
super(path);
this.defaultPath = "bodies";
}
public isType(item: any): boolean {
return item instanceof Object;
}
public file(req) {
return async (name) => {
const cb = promisify(req.file(name).upload);
return await cb.call(req.file(name));
}
}
public async parse(req, res): Promise<boolean> {
let data = this.check(req);
if (!data) {
const method = req.method.toLowerCase();
// Enable form for post request
if (method === "post") {
data = {
form: true
};
} else {
return false;
}
}
for (const k of Object.keys(data)) {
let cb = data[k];
if (!cb) {
continue;
}
if (!(cb instanceof Function)) {
switch (k) {
case "formdata":
case "form":
cb = parser.urlencoded({ extended: false });
cb = this.toAsync(cb, cb)
break;
case "xml":
cb = parser.raw({ type: "*/xml" });
cb = this.toAsync(cb, cb)
break;
case "json":
cb = parser.json();
cb = this.toAsync(cb, cb)
break;
case "file":
cb = skipper();
req.storage = this.file(req);
cb = this.toAsync(cb, cb)
break;
default:
continue;
}
}
await cb(req, res);
}
return true;
}
}
================================================
FILE: src/MiddlewareParsers/VCondition.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VHTTPBase } from "../Components/VHTTPBase";
export class VCondition extends VHTTPBase {
constructor(path) {
super(path)
this.failurable = true;
this.defaultPath = "conditions";
}
}
================================================
FILE: src/MiddlewareParsers/VFallback.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VHTTPBase } from "../Components/VHTTPBase";
export class VFallback extends VHTTPBase {
constructor(path) {
super(path)
this.defaultPath = "fallbacks";
this.filters = ["condition", "validation", "policy", "validator"]
}
public isType(item: any): boolean {
return item instanceof Function
|| typeof item === "string";
}
}
================================================
FILE: src/MiddlewareParsers/VFile.ts
================================================
import * as uploader from "file-cloud-uploader";
import * as async from "async";
import * as skipper from "skipper";
export class VFile {
protected name
protected options
public cloud(req) {
return (name, options) => {
return new Promise((resolve, reject) => {
req.file(name).upload((err, files) => {
this._isError(err, resolve, () => {
const cloudFiles = [];
async.each(files, (file, cb) => {
uploader(options.type,
file.fd,
options.config,
(data) => {
cloudFiles.push(data);
cb();
});
}, (err1) => {
this._isError(err1, reject, () => {
resolve(cloudFiles);
});
});
})
});
});
};
}
public attach(app) {
app.use(skipper());
app.use(this.use());
}
public use() {
return (req, res, next) => {
req.cloud = this.cloud(req);
next();
}
}
public _isError(err, reject, cb = null) {
if (err) {
return reject(err);
}
if (cb instanceof Function) {
cb();
}
}
}
================================================
FILE: src/MiddlewareParsers/VLimitation.ts
================================================
================================================
FILE: src/MiddlewareParsers/VPager.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
/**
* @class VPager
* VPager is a parser for pagination info, after parsing, the sharing info inside {VHandler}
* will be provided with a pager attribute, containing attributes:
* 1. @param page current requesting page number
* 2. @param limit max items per page
*
* so every request hander inside routers can accession this with
* {si.pager.page} or {si.pager.limit}
*/
import { VHTTPBase } from "../Components/VHTTPBase";
export class VPager extends VHTTPBase {
constructor(path) {
super(path)
this.defaultPath = "pagers";
}
public isType(item: any): boolean {
return typeof item === "boolean";
}
public toNumber(value) {
value = parseInt(value, 10);
if (isNaN(value)) {
value = 1;
}
if (value < 1) {
value = 1;
}
return value;
}
public async parse(req, res, scope): Promise<boolean> {
const handler = this.check(req);
if (!handler) {
scope.query = req.query;
delete scope.query.page;
delete scope.query.limit;
return false;
}
const query = req.query;
query.page = this.toNumber(query.page);
query.limit = this.toNumber(query.limit);
scope.query = query;
return true;
}
}
================================================
FILE: src/MiddlewareParsers/VPolicy.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VHTTPBase } from "../Components/VHTTPBase";
export class VPolicy extends VHTTPBase {
constructor(path = "") {
super(path)
this.failurable = true;
this.defaultPath = "policies";
}
public isType(item: any): boolean {
return super.isType(item)
|| typeof item === "string";
}
}
================================================
FILE: src/MiddlewareParsers/VSession.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VHTTPBase } from "../Components/VHTTPBase";
import { promisify } from "bluebird";
import * as parser from "cookie-parser";
import * as skipper from "skipper";
import * as _ from "lodash";
import * as debug from "debug";
const print = debug("vig:session");
export class VSession extends VHTTPBase {
constructor(path) {
super(path);
this.defaultPath = "sessions";
}
public isType(item: any): boolean {
return item instanceof Object;
}
public async parse(req, res, scope): Promise<boolean> {
const data = this.check(req);
if (!data) {
return false;
}
for (const k of Object.keys(data)) {
let cb = data[k];
if (!cb) {
continue;
}
if (!(cb instanceof Function)) {
switch (k) {
case "cookie":
case "cookies":
cb = parser();
cb = this.toAsync(cb, cb)
break;
case "session":
cb = _.get(scope, ["configs", "session", "middleware"]);
if (!cb) {
print("Session Middleware Not Found!");
print(`Please make sure your session.ts/js file is placed inside configs folder, ` +
`and with an expressjs compatible session middleware inside this configuration file.`
);
return false;
}
cb = this.toAsync(cb, cb)
break;
default:
continue;
}
}
await cb(req, res);
}
return true;
}
}
================================================
FILE: src/MiddlewareParsers/VValidator.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import { VHTTPBase } from "../Components/VHTTPBase";
import * as validator from "node-form-validator";
export class VValidator extends VHTTPBase {
private paramKeys = ["required", "params", "query", "body"]
constructor(path = "") {
super(path)
this.failurable = true;
this.defaultPath = "validators";
}
public isType(item: any): boolean {
if (item instanceof Object) {
for (const k in item) {
if (typeof k === "string") {
if (this.paramKeys.indexOf(k) === -1) {
return false;
}
if (k === "required") {
if (!(item[k] instanceof Array)) {
return false;
}
}
}
}
}
return item instanceof Object || item instanceof Function;
}
public async process(req, res, scope = null): Promise<boolean> {
const handler = this.check(req);
if (handler instanceof Function) {
return await this._onProcess(handler, req, res, scope);
}
if (handler && handler instanceof Object) {
const processed: boolean = await this.processObject(handler, req, res, scope);
return processed;
}
return true;
}
public async processObject(handler, req, res, scope): Promise<boolean> {
scope.extracted = {};
req.extracted = {};
const keys = ["query", "params", "body"];
const fallback = this.getFallback(req, scope);
for (const key of keys) {
// continue when no validation specified
if (!handler[key]) {
continue;
}
// when no data provided
req[key] = req[key] || {};
if (Object.keys(req[key]).length <= 0) {
// return error when data is required
if (!(handler.required instanceof Array)) {
continue;
}
if (handler.required.indexOf(key) === -1) {
continue;
}
return await this.onPassed(req, res, scope, new Error(key + " is required"), fallback);
}
const result = validator.validate(req[key], handler[key]);
// return error info when validation failed
if (!result || result.code !== 0) {
return await this.onPassed(req, res, scope, result, fallback);
}
// saved validated data
scope.extracted[key] = result.data;
req.extracted[key] = result.data;
}
if (Object.keys(scope.extracted).length <= 0) {
delete scope.extracted;
delete req.extracted;
}
return true;
}
}
================================================
FILE: src/MiddlewareParsers/index.ts
================================================
export * from "./VCondition";
export * from "./VValidator";
export * from "./VPolicy";
export * from "./VFallback";
export * from "./VFile";
export * from "./VPager";
export * from "./VBody";
export * from "./VSession";
================================================
FILE: src/Templates/Filter.ts
================================================
import { VBase } from "../Components/VBase";
export class Filter extends VBase {
constructor(path) {
super(path);
this.defaultPath = "filters";
}
public isType(item: any): boolean {
return item instanceof Function;
}
}
================================================
FILE: src/Templates/VTemplate.ts
================================================
/**
* Copyright(c) 2016 calidion <calidion@gmail.com>
* Apache 2.0 Licensed
*/
import * as nunjucks from "nunjucks";
import * as path from "path";
import * as fs from "fs";
import * as _ from "lodash";
import * as debug from "debug";
const print = debug("VTemplate");
import { VBase } from "../Components/VBase";
import { Filter } from "./Filter";
export class VTemplate extends VBase {
protected initialized: boolean = false;
protected tFilter: Filter;
protected views = [];
protected parent: VTemplate;
protected env;
constructor(dir) {
super(dir);
this.defaultPath = "templates";
const resolvedPath = path.resolve(dir, "./templates");
this.views.push(path.resolve(resolvedPath, "./views"));
this.tFilter = new Filter(resolvedPath);
}
public isType(item: any): boolean {
return true;
}
public getEnv() {
if (this.initialized) {
return this.env;
}
const views = this.getViews();
const loader = new nunjucks.FileSystemLoader(views, {
watch: true
});
const env = new nunjucks.Environment(loader, {
autoescape: false
});
const filters = this.getFilters();
for (const key of Object.keys(filters)) {
env.addFilter(key, filters[key]);
}
this.env = env;
this.initialized = true;
return env;
}
public render(data, template, ext) {
return this.getEnv().render(template + "." + ext, data);
}
public setParent(p: VTemplate) {
this.parent = p;
this.initialized = false;
}
public getFilters() {
this.tFilter.loadOn();
const filters = this.tFilter.get();
if (!this.parent) {
return filters;
}
const parent = this.parent.getFilters();
return _.merge(parent, filters);
}
public getViews() {
if (!this.parent) {
return this.views;
}
const views = this.parent.getViews();
return views.concat(this.views);
}
}
================================================
FILE: src/VDefinition.ts
================================================
import { resolve } from "path";
import { VFallbackDefinition as VFallback } from "./DefinitionParsers/VFallbackDefinition";
import { VPolicyDefinition as VPolicy } from "./DefinitionParsers/VPolicyDefinition";
export class VDefinition {
public fallback: VFallback;
public policy: VPolicy;
constructor(path: string) {
const base = resolve(path);
const definitionDir = resolve(base, "./definitions");
this.fallback = new VFallback(definitionDir);
this.policy = new VPolicy(definitionDir);
this.fallback.loadOn();
this.policy.loadOn();
}
public parse(scope) {
const definitions: any = {
};
const fallbacks = this.fallback.get();
const policies = this.policy.get();
if (Object.keys(fallbacks).length > 0) {
definitions.fallbacks = fallbacks;
}
if (Object.keys(policies).length > 0) {
definitions.policies = policies;
}
if (Object.keys(definitions).length > 0) {
scope.definitions = definitions;
}
}
public set(data) {
if (data.fallbacks) {
this.fallback.set(data.fallbacks);
}
if (data.policies) {
this.policy.set(data.policies);
}
}
};
================================================
FILE: src/VEvent.ts
================================================
import * as EventEmitter from "events";
export class VEvent {
public static getInstance() {
if (!VEvent.instance) {
VEvent.instance = new VEvent();
}
return VEvent.instance;
}
protected static emitter: EventEmitter = new EventEmitter();
protected static listeners = {};
protected static onceListeners = {};
protected static instance;
protected static VIG_EVENT = "__vig_event";
private constructor() {
VEvent.emitter.on(VEvent.VIG_EVENT, async (...args) => {
await this._onEvent(...args[0]);
});
}
/**
* Add an Event Object, which may contain many events and handlers.
* @param {Object} events - Having to keys:
* 1. {Array} names: events to be listened.
* 2. {Object} handlers: key-value pairs, with events and corresponding handlers;
* @param {Boolean} isOnce - once or not
*/
public add(events, isOnce = true) {
const once = isOnce ? "once" : "on";
if (!events) {
return;
}
if (!events.names) {
return;
}
if (!events.handlers) {
return;
}
for (const name of events.names) {
const handler = events.handlers[name];
if (handler) {
if (isOnce) {
this._on(name, handler, VEvent.onceListeners);
} else {
this._on(name, handler, VEvent.listeners);
}
}
// VEvent.emitter[once](name, handler);
}
}
/**
* Send an event to its listeners
*/
public send(...args) {
VEvent.emitter.emit(VEvent.VIG_EVENT, args);
// VEvent.emitter.emit.apply(VEvent.emitter, args);
}
/**
* Add an event handler.
* @param {String} event - Event to be listened.
* @param {Function} handler - Function to handler the event.
*/
public on(event, handler) {
this._on(event, handler, VEvent.listeners);
}
/**
* Add an event handler for one time handling.
* @param {String} event - Event to be listened.
* @param {Function} handler - Function to handler the event.
*/
public once(event, handler) {
this._on(event, handler, VEvent.onceListeners);
}
private _on(event, handler, listeners) {
if (!handler) {
return;
}
let handlers = listeners[event];
if (!handlers) {
handlers = [];
}
if (handlers.indexOf(handler) !== -1) {
return;
}
if (handler instanceof Function) {
handlers.push(handler);
listeners[event] = handlers;
}
}
private async _processEvent(handlers, params) {
if (handlers instanceof Array) {
for (const handler of handlers) {
await handler.apply(handler, params);
}
}
}
private async _onEvent(...args) {
const event = args[0];
const params = args.splice(1);
const handlers = VEvent.listeners[event];
const onceHandlers = VEvent.onceListeners[event];
VEvent.onceListeners[event] = null;
await this._processEvent(handlers, params);
await this._processEvent(onceHandlers, params);
}
}
================================================
FILE: src/VHandler.ts
================================================
import * as fs from "fs";
import * as fsPath from "path";
import * as async from "async";
import * as _ from "lodash";
import { VEvent } from "./VEvent";
import { VDefinition } from "./VDefinition";
import { HTTP, VBase, VConfig, VError, VModel, VMiddleware, VRouter, VEventReader, VWebSocket } from "./Components";
import { VFallback, VCondition, VPolicy, VValidator, VPager, VBody, VSession } from "./MiddlewareParsers";
import { VTemplate } from "./Templates/VTemplate";
import { VWSServer } from "./VWSServer";
import { promisify } from "bluebird";
import * as debug from "debug";
import * as url from "url";
const print = debug("vig:vhandler");
export class VHandler {
public urls: string[] = [];
public prefix = "";
public config: VConfig;
public condition: VCondition;
public error: VError;
public body: VBody;
public event: VEventReader;
// Expressjs Traditional Middlewares
public middleware: VMiddleware;
public model: VModel;
public policy: VPolicy;
public session: VSession;
public router: VRouter;
public validator: VValidator;
public fallback: VFallback;
// VWebSocket
public websocket: VWebSocket;
// Pagination Parser
public pager: VPager;
public template: VTemplate;
public definition: VDefinition;
protected path: string;
private parent: VHandler = null;
private children: VHandler[] = [];
private eventHandler: VEvent = VEvent.getInstance();
// Current Scope
private scope: object = {};
private unmuted: any = {
};
constructor(urls: string[] = null, path: string = "", prefix = "") {
this.urls = urls || [];
path = path || "";
this.path = path;
this.prefix = prefix;
if (!urls || !urls.length) {
this.requireFile("urls");
}
if (!prefix) {
this.requireFile("prefix");
}
this.config = new VConfig(path);
this.pager = new VPager(path);
this.event = new VEventReader(path);
this.condition = new VCondition(path);
this.error = new VError(path);
this.body = new VBody(path);
this.model = new VModel(path);
this.session = new VSession(path);
this.middleware = new VMiddleware(path);
this.policy = new VPolicy(path);
this.router = new VRouter(path);
this.validator = new VValidator(path);
this.fallback = new VFallback(path);
this.template = new VTemplate(path);
this.websocket = new VWebSocket(path);
this.definition = new VDefinition(path);
const data = [
"pager",
"config",
"condition",
"error",
"body",
"model",
"session",
"event",
"middleware",
"policy",
"event",
"router",
"validator",
"websocket",
"fallback"];
for (const key of data) {
this[key].loadOn();
}
this.updateFallbacks();
this.loadStaticScope();
this.initChildren();
}
public requireFile(name: string) {
const allowedExt = [".js", ".ts", ".json"];
for (const ext of allowedExt) {
const dir = fsPath.resolve(this.path, "./" + name);
const resolve = dir + ext;
if (fs.existsSync(resolve)) {
const data = require(resolve);
if (data) {
this[name] = data;
break;
}
}
}
}
public setUrls(urls: string[]) {
this.urls = urls;
}
public setParent(p: VHandler) {
this.parent = p;
this.template.setParent(p.template);
const parent = this.parent.getScope();
const clone = _.merge({}, parent);
const scope = _.merge({}, this.scope);
this.scope = _.merge(clone, scope);
for (const child of this.children) {
child.setParent(this);
}
}
public setPrefix(prefix) {
this.prefix = prefix;
}
public update(k: string, v) {
if (this[k]) {
this[k].set(v);
}
}
public extend(method, cb) {
return this.router.extend(method, cb);
}
public set(config) {
const keys = {
condition: "conditions",
middleware: "middlewares",
router: "routers",
error: "errors",
config: "configs",
event: "events",
body: "bodies",
model: "models",
session: "sessions",
pager: "pagers",
definition: "definitions",
policy: "policies",
websocket: "websockets",
validator: "validations",
fallback: "failures"
};
if (config.urls) {
this.urls = config.urls;
}
if (config.prefix) {
this.prefix = config.prefix;
}
for (const key of Object.keys(keys)) {
if (config[keys[key]]) {
this[key].set(config[keys[key]]);
} else {
this[key].set({});
}
}
this.updateFallbacks();
this.loadStaticScope();
this.children = [];
}
public getScope() {
return this.scope;
}
public updateFallbacks() {
const keys = {
validation: "validator"
};
const fallbacks = this.fallback.get();
const items = Object.keys(fallbacks);
for (const key of items) {
const keyOne = this[keys[key]] || this[key];
if (keyOne) {
keyOne.setFailureHandler(fallbacks[key]);
}
}
}
public attach(app) {
const prefix = this.prefix || "";
let urls = [];
if (this.urls instanceof Array) {
urls = this.urls;
}
for (const item of urls) {
let urlTemp = prefix + item;
urlTemp = urlTemp.replace(/\/+/g, "/");
app.all(urlTemp, (req, res) => {
this.run(req, res).catch((e) => print(e));
});
}
for (const child of this.children) {
child.attach(app);
}
}
public loadStaticScope() {
this.config.parse(this.scope);
this.error.parse(this.scope);
this.definition.parse(this.scope);
this.eventPrepare();
this.websocketPrepare();
// Accelerate speed by ignoring unnecessary processes
this.processMuted();
}
public eventPrepare() {
const events = this.event.get();
for (const key in events) {
if (key && events[key]) {
this.eventHandler.on(key, ((iK) => {
return async (...args) => {
args = [this.scope].concat(args);
await this.event.run(iK, args);
}
})(key));
}
}
}
public websocketPrepare() {
const wss = VWSServer.getInstance();
const websocketHandlers = this.websocket.get();
for (const key of Object.keys(websocketHandlers)) {
wss.addEventListener(key, this);
}
}
public getFixedScope() {
const scope: any = {
debug,
time: {
start: new Date()
}
};
for (const key of Object.keys(this.scope)) {
scope[key] = this.scope[key];
}
this.model.parse(scope);
scope.template = this.template;
return scope;
}
public checkMutable(module) {
return Object.keys(this[module].get()).length > 0;
}
public processMuted() {
const mutables = ["body", "session", "condition", "policy", "middleware", "condition", "validator", "pager"];
for (const key of mutables) {
this.unmuted[key] = this.checkMutable(key);
}
}
public async run(req, res) {
// Scoped Data
const scope: any = this.getFixedScope();
scope.event = this.eventHandler;
try {
// Parsers and processors
// TODO: enable server protector here, using condition instead now.
// Input Data prepare
if (req.method === "POST" || this.unmuted.body) {
await this.body.parse(req, res);
}
if (this.unmuted.session) {
await this.session.parse(req, res, scope);
}
// Utilities
res.vRender = (data, template, ext = "html") => {
// Add user session to current User
if (req.session && req.session.user) {
data.currentUser = req.session.user;
}
// Add configs to template defaultly
data.config = scope.configs;
res.send(this.template.render(data, template, ext));
};
res.errorize = res.restify = function errorize(error, data) {
if (!error) {
return res.json(scope.errors.UnknownError.restify());
}
if (error.restify && error.restify instanceof Function) {
error = error.restify();
}
if (!data) {
return res.json(
_.extend(error)
);
}
return res.json(
_.extend(error, { data })
);
};
// Middlewares
// Exit when middleware return false
if (this.unmuted.middleware && await this.middleware.process(req, res, scope) === false) {
return;
}
if (this.unmuted.condition && !await this.condition.process(req, res, scope)) {
return;
}
if (this.unmuted.validator && !await this.validator.process(req, res, scope)) {
return;
}
if (this.unmuted.pager) {
await this.pager.parse(req, res, scope);
}
if (this.unmuted.policy && !await this.policy.process(req, res, scope)) {
return;
}
// Final request process
const result = await this.router.run(req, res, scope);
if (false === result) {
return this.notFound("Not Found!", req, res);
}
} catch (e) {
print(e);
}
}
public notFound(error, req, res) {
res.status(404).send("Not Found!");
}
// Web sockets
public async wsEvent(event, message, ws, req) {
const cookies = req.headers.cookie;
const store = _.get(this.scope, ["configs", "session", "store"]);
if (this.unmuted.session && cookies && store) {
let id = cookies.split("=");
id = id[1];
id = decodeURIComponent(id);
id = id.split(".")[0].split(":")[1];
const getSession = promisify(store.get);
const session = await getSession.call(store, id);
req.session = session;
}
await this.websocket.run(event, message, ws, req, this.scope);
}
// Deprecated
public toJSON() {
const json: any = {};
json.prefix = this.prefix;
json.urls = this.urls;
json.routers = this.router.toMethods();
json.middlewares = this.middleware.get();
json.policies = this.policy.toMethods();
json.validations = this.validator.get();
json.conditions = this.condition.get();
json.failures = this.fallback.get();
return json;
}
private initChildren() {
const subDir = "handlers"
const resolve = fsPath.resolve(this.path, subDir);
if (!fs.existsSync(resolve)) {
return;
}
const stat = fs.statSync(resolve);
// ignore directories
if (!stat || !stat.isDirectory()) {
return false;
}
this.loadDirectory(resolve);
}
private loadDirectory(dir: string) {
const files = fs.readdirSync(dir);
files.forEach((file) => {
const absPath = fsPath.resolve(dir, file);
const stat = fs.statSync(absPath);
let handler;
// ignore directories
if (stat && stat.isDirectory()) {
handler = new VHandler(null, absPath);
} else {
const data = require(absPath);
handler = new VHandler();
handler.set(data);
}
this.children.push(handler);
handler.setParent(this);
});
}
}
================================================
FILE: src/VService.ts
================================================
import { VWSServer } from "./VWSServer";
import * as http from "http";
import * as debug from "debug";
const print = debug("vig:service");
/**
* VService is A Service can be a standard alone server or as a part of a server
*/
export class VService {
protected options;
constructor(options: any = {}) {
options.ip = options.ip || "127.0.0.1";
options.port = options.port || 8080;
this.options = options;
}
public defaultRun() {
const { port, ip } = this.options;
print("Server Successfully Running On " + ip + ":" + port);
}
public start(app, cb) {
const server = http.createServer(app);
const vwss = VWSServer.getInstance();
vwss.start(server);
server.listen(this.options.port, this.options.ip, () => {
this.defaultRun();
if (cb instanceof Function) {
cb(server, this.options, vwss);
}
});
}
}
================================================
FILE: src/VWSServer.ts
================================================
import * as WebSocket from "ws";
import { VHandler } from "./VHandler";
import { Server } from "http";
import * as debug from "debug";
const print = debug("vig:vwss");
export class VWSServer {
public static ENTER = "enter";
public static LEAVE = "leave";
public static getInstance(): VWSServer {
if (VWSServer.instance) {
return VWSServer.instance;
}
VWSServer.instance = new VWSServer();
return VWSServer.instance;
}
private static instance;
public server;
public eventsAndListeners: object = {};
private constructor() {
}
public addEventListener(event: string, handler: VHandler) {
let handlers = this.eventsAndListeners[event];
if (!(handlers instanceof Array)) {
handlers = [];
}
if (handlers.indexOf(handler) === -1) {
handlers.push(handler);
}
this.eventsAndListeners[event] = handlers;
}
public broadcast(data, filter) {
const wss = this.server;
wss.clients.forEach(async (client) => {
if (filter && !filter(client)) {
return;
}
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
}
public async onEvent(event, ws, req) {
const enterListeners = this.eventsAndListeners[event];
for (const handler of enterListeners) {
await handler.wsEvent(event, null, ws, req);
}
}
public async onEnter(ws, req) {
await this.onEvent(VWSServer.ENTER, ws, req);
}
public async onLeave(ws, req) {
await this.onEvent(VWSServer.LEAVE, ws, req);
}
public onEvents(ws, req) {
ws.on("message", async (data) => {
try {
const json = JSON.parse(data);
const event = json.event;
const message = json.message;
const eventListeners = this.eventsAndListeners[event];
if (!eventListeners) {
return;
}
for (const handler of eventListeners) {
await handler.wsEvent(event, message, ws, req);
}
} catch (e) {
print(e);
return;
}
});
}
public start(server: Server) {
const wss = new WebSocket.Server({ server });
this.server = wss;
wss.on("connection", async (ws, req) => {
await this.onEnter(ws, req);
this.onEvents(ws, req);
ws.on("close", async () => {
await this.onLeave(ws, req);
})
});
}
}
================================================
FILE: src/index.ts
================================================
export * from "./VService";
export * from "./VHandler";
export * from "./VEvent";
export * from "./Components";
export * from "./MiddlewareParsers/";
================================================
FILE: test/Components/VBase.test.ts
================================================
import 'mocha';
import { VBase } from '../../src/Components/VBase';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
class NewBase extends VBase {
public isType(): boolean {
return true;
}
}
const base = new NewBase(__dirname);
describe('VBase', () => {
it('should new VBase', () => {
assert(base);
});
it('should reset', () => {
base.reset();
assert(Object.keys(base.get()).length === 0);
assert(base.getFiles().length === 0);
});
it('should add file', () => {
base.addFile();
var file = path.resolve(__dirname, '../data/errors/vig.js');
base.addFile(file);
assert(base.getFiles().length === 1);
var file1 = path.resolve(__dirname, '../data/errors/vig1.js');
base.addFile(file1);
assert(base.getFiles().length === 1);
})
it('should extends base', () => {
var file = path.resolve(__dirname, '../data/errors/vig.js');
var json = require(file);
var data = base.extends('', json);
assert(Object.keys(data).length > 0);
})
it('should get File bases', () => {
var file = path.resolve(__dirname, '../data/errors/vig.js');
var json: any = base.getFile(file);
assert(Object.keys(json['Vig']).length !== 0);
var file1 = path.resolve(__dirname, '../data/errors/vig1.js');
var json1 = base.getFile(file1);
assert(json1 === null);
})
it('should generate bases', () => {
var a = {};
var bases100 = base.generate(a);
var bases = base.generate();
assert(Object.keys(bases).length !== 0);
var bases1 = base.extends('', {
ABC: {
base: {
messages: {
'zh-CN': 'ABC测试错误!',
'en-US': 'ABC Test base!'
}
}
}
}, base);
assert.notDeepEqual(bases, bases1);
})
it('should load wrong dir', () => {
base.parseDir();
assert(!base.load('sdfsfdsdf'));
assert(!base.load('sdfsfdsdf', {aaa: 1}));
})
});
================================================
FILE: test/Components/VCondition.test.ts
================================================
import "mocha";
import { VCondition } from "../../src/MiddlewareParsers/VCondition";
import * as assert from "assert";
import * as path from "path";
import * as fs from "fs";
const router = new VCondition("");
var componentPath = path.resolve(__dirname, "../data/component/");
var objPath = path.resolve(__dirname, "../data/component/conditions");
describe("VCondition", () => {
it("should new VCondition", () => {
assert(router);
});
it("should load", () => {
var data: any = router.load(objPath);
assert(data && data.get && data.post);
})
it("should load", () => {
let r = new VCondition(componentPath);
var data: any = r.load();
assert(data && data.get && data.post && !data.fuck);
})
it("should new undefined", () => {
let r = new VCondition(undefined);
})
});
================================================
FILE: test/Components/VConfig.test.ts
================================================
import 'mocha';
import { VConfig } from '../../src/Components/VConfig';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
var componentPath = path.resolve(__dirname, '../data/');
var objPath = path.resolve(__dirname, '../data/configs');
const config = new VConfig("");
describe('VConfig', () => {
it('should new VConfig', () => {
assert(config);
});
it('should load', () => {
var data: any = config.load(objPath);
assert(data && data.test && data.test.a === '1');
})
it('should load', () => {
var route = new VConfig(componentPath);
var data: any = route.load();
assert(data && data.test && data.test.a === '1');
})
});
================================================
FILE: test/Components/VError.test.ts
================================================
// import 'mocha';
// import * as assert from 'assert';
// import * as path from 'path';
// import * as fs from 'fs';
// import * as express from 'express';
// import * as request from 'supertest';
// import * as common from 'errorable-common';
// import * as errorize from 'errorable-express';
// import { VHandler, VService, VError } from '../../src/';
// var service = new VService();
// var app = express();
// var errors;
// describe('VError', () => {
// before(function () {
// app = express();
// let handler = new VHandler();
// handler.set(require( '../data/errorsHandlers'));
// handler.attach(app);
// });
// it('should get /errors', function (done) {
// request(app)
// .get('/errors')
// .expect(200)
// .end(function (err, res) {
// assert(!err);
// assert.deepEqual(res.body, errors.Success.restify());
// done();
// });
// });
// it('should put /errors', function (done) {
// request(app)
// .put('/errors')
// .expect(200)
// .end(function (err, res) {
// assert(!err);
// assert.deepEqual(res.body, errors.VigTestError.restify());
// done();
// });
// });
// it('should generate errors', () => {
// assert(errors && errors.VigTestError);
// })
// it('should load', () => {
// var error = new VError(path.resolve(__dirname, '../data/'));
// var data: any = error.load();
// assert(data);
// var errors: any = error.generate();
// assert(errors && errors.VigTestError);
// errors = error.generate('', false);
// assert(errors && errors.VigTestError);
// error.filter();
// error.addDir(path.resolve(__dirname, '../data/'));
// })
// it('should merge', () => {
// var error = new VError(path.resolve(__dirname, '../data/'));
// var data: any = error.merge({
// Send: {
// Me: {
// messages: {
// 'zh-CN': 'Vig测试错误!',
// 'en-US': 'Vig Test Error!'
// }
// }
// }
// });
// var errors: any = error.generate('', false);
// assert(errors && errors.SendMe);
// })
// it('should merge errors', (done) => {
// var error = new VError(path.resolve(__dirname, '../data/'));
// var data: any = error.merge({
// Send: {
// Me: {
// messages: {
// 'zh-CN': 'Vig测试错误!',
// 'en-US': 'Vig Test Error!'
// }
// }
// }
// });
// error.attach(app);
// var errors: any = error.generate('', false);
// app.all('/merged/errors', function (req, res) {
// res.errorize(res.errors.SendMe);
// });
// request(app)
// .get('/merged/errors')
// .expect(200)
// .end(function (err, res) {
// assert(!err);
// assert.deepEqual(res.body, errors.SendMe.restify());
// done();
// });
// })
// });
================================================
FILE: test/Components/VFallback.test.ts
================================================
import 'mocha';
import { VFallback } from '../../src/MiddlewareParsers/VFallback';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
const router = new VFallback("");
var componentPath = path.resolve(__dirname, '../data/component');
var objPath = path.resolve(__dirname, '../data/component/fallbacks');
describe('VFallback', () => {
it('should new VFallback', () => {
assert(router);
});
it('should load', () => {
var data: any = router.load(objPath);
assert(data && data.condition
&& data.validation
&& data.policy);
})
it('should load', () => {
var router = new VFallback(componentPath);
var data: any = router.load();
assert(data && data.condition
&& data.validation
&& data.policy);
})
});
================================================
FILE: test/Components/VHTTPBase.test.ts
================================================
import 'mocha';
import { VHTTPBase } from '../../src/Components/VHTTPBase';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
const base = new VHTTPBase(__dirname);
class VHTTP extends VHTTPBase {
constructor(path = "") {
super(path);
this.defaultPath = "a";
}
public isType(item: any): boolean {
return item instanceof Function || typeof item === "string";
}
}
const v = new VHTTP();
describe('VHTTPBase', () => {
it('should new VHTTPBase', () => {
assert(base);
});
it('should check', () => {
base.set({
get: true
});
assert(base.check({
method: 'get'
}));
base.set({
get: false
});
assert(!base.check({
method: 'get'
}));
})
it('should process', () => {
base.set({
get: true
});
assert(base.check({
method: 'get'
}));
base.set({
get: false
});
assert(!base.check({
method: 'get'
}));
})
it('should getFallback with no callbacks', () => {
base.setFailureHandler('get');
var handler = base.getFallback({
}, {definitions: {}});
var handler1 = base.getFallback({
}, { definitions: { fallbacks: {} } });
var handler2 = base.getFallback({
}, { definitions: { fallbacks: { get: 'oosodssd' } } });
})
it('should checkEx', () => {
v.setFailureHandler('get');
v.set({
get: 'get'
});
v.checkEx({
method: 'get'
}, { definitions: { fallbacks: { get: 'oosodssd' } } });
v.checkEx({
method: 'get',
a: {
}
}, { definitions: { fallbacks: { get: 'oosodssd' } } });
v.checkEx({
method: 'get',
a: {
get: 'sodff'
}
}, { definitions: { fallbacks: { get: 'oosodssd' } } });
new VHTTPBase("");
new VHTTPBase("sosos");
})
});
================================================
FILE: test/Components/VMiddleware.test.ts
================================================
import 'mocha';
import { VMiddleware } from '../../src/Components/VMiddleware';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
const router = new VMiddleware();
var componentPath = path.resolve(__dirname, '../data/component/');
var objPath = path.resolve(__dirname, '../data/component/conditions');
describe('VMiddleware', () => {
it('should new VMiddleware', () => {
assert(router);
});
it('should load', () => {
var data: any = router.load(objPath);
assert(data && data.get && data.post);
})
it('should load', () => {
var router = new VMiddleware(componentPath);
var data: any = router.load();
assert(data && data.get && data.post && !data.fuck);
})
});
================================================
FILE: test/Components/VPager.test.ts
================================================
import 'mocha';
import { VPager } from '../../src/MiddlewareParsers/VPager';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
const pager = new VPager("");
var componentPath = path.resolve(__dirname, '../data/component/');
var objPath = path.resolve(__dirname, '../data/component/pagers');
describe('VPolicy', () => {
it('should new VPolicy', () => {
assert(pager);
});
it('should load', () => {
var data: any = pager.load(objPath);
assert(data && data.get && !data.post);
})
it('should load', () => {
var pager1 = new VPager(componentPath);
var data: any = pager1.load();
assert(data && data.get && !data.post && !data.fuck);
})
});
================================================
FILE: test/Components/VPolicy.test.ts
================================================
import 'mocha';
import { VPolicy } from '../../src/MiddlewareParsers/VPolicy';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
const router = new VPolicy();
var componentPath = path.resolve(__dirname, '../data/component/');
var objPath = path.resolve(__dirname, '../data/component/policies');
describe('VPolicy', () => {
it('should new VPolicy', () => {
assert(router);
});
it('should load', () => {
var data: any = router.load(objPath);
assert(data && data.get && data.post);
})
it('should load', () => {
var router = new VPolicy(componentPath);
var data: any = router.load();
assert(data && data.get && data.post && !data.fuck);
})
});
================================================
FILE: test/Components/VRouter.test.ts
================================================
import 'mocha';
import { VRouter } from '../../src/Components/VRouter';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
const router = new VRouter();
var componentPath = path.resolve(__dirname, '../data/component');
var objPath = path.resolve(__dirname, '../data/component/routers');
describe('VRouter', () => {
it('should new VRouter', () => {
assert(router);
});
it('should load', () => {
var data: any = router.load(objPath);
assert(data && data.get && data.post);
})
it('should load', () => {
var router = new VRouter(componentPath);
var data: any = router.load();
assert(data && data.get && data.post && !data.fuck);
// router.filter();
})
});
================================================
FILE: test/Components/VValidator.test.ts
================================================
import 'mocha';
import { VValidator } from '../../src/MiddlewareParsers/VValidator';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
var componentPath = path.resolve(__dirname, '../data/component/');
var objPath = path.resolve(__dirname, '../data/component/validators');
const config = new VValidator();
describe('VValidator', () => {
it('should new VValidator', () => {
assert(config);
});
it('should load', () => {
var data: any = config.load(objPath);
assert(data && data.get && data.post && data.put);
})
it('should load', () => {
var route = new VValidator(componentPath);
var data: any = route.load();
assert(data && data.get && data.post && data.put);
})
});
================================================
FILE: test/VEvent.test.ts
================================================
import 'mocha';
import { VEvent } from '../src';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
const config = require('./data/fixtures/events');
const event = VEvent.getInstance();
event.add(config);
const once = require('./data/fixtures/events.once');
event.add(once, false);
event.add(null, false);
event.add({}, false);
event.add({ names: [] }, false);
event.add({
names: [], handlers: {
}
}, false);
describe('VEvent', () => {
it('should new VEvent', () => {
assert(event);
});
it('should handle /events', function (done) {
event.send('@event1', function (data) {
assert(data === '@event1');
done();
});
});
it('should handle /events again', function (done) {
var visited = false;
event.send('@event1', function (data) {
visited = true;
});
setTimeout(() => {
assert(!visited);
done();
}, 30);
});
it('should handle event', function (done) {
event.send('@eventonce1', function (data) {
assert(data === '@eventonce1');
done();
});
});
it('should handle event again', function (done) {
event.send('@eventonce1', function (data) {
assert(data === '@eventonce1');
done();
});
});
it('should not handle nonefuc', function (done) {
let notEntered = true;
event.on('nonefuc', 'hello');
event.send('nonefuc', function (data) {
notEntered = false;
});
setTimeout(() => {
assert(notEntered);
done();
}, 500)
});
it('should get /events', function (done) {
event.send('@event2', function (data) {
assert(data === '@event2');
done();
});
});
it('should enable on events', function (done) {
var passed = false;
event.on('hello', function (data) {
assert(data === 'world');
if (passed === false) {
passed = true;
event.send('hello', 'world');
} else {
done();
}
});
event.send('hello', 'world');
});
it('should enable once events', function (done) {
var res;
event.once('hello1', function (data) {
assert(data === 'world');
event.send('hello1', 'world');
done();
});
event.send('hello1', 'world');
});
it('should fill the gap', function () {
var res;
event.once('hello12323');
function aaa() {
};
event.once('more', aaa);
event.once('more', aaa);
event.on('more', aaa);
event.on('more', aaa);
});
});
================================================
FILE: test/VFailureDefinition.test.ts
================================================
"use strict";
var assert = require("assert");
var request = require("supertest");
var express = require("express");
var session = require("express-session");
var cookies;
var path = require("path");
import { VHandler, VService, VPolicy } from "../src";
var vhandler = new VHandler();
var app = express();
describe("vig #policies", function () {
before(function () {
app.use(session({
name: "vig",
secret: "secret oososos",
resave: false,
saveUninitialized: true,
cookie: {
secure: false
}
}));
vhandler.set({
urls: ['/failure'],
definitions: {
fallbacks: {
ok: function (error, req, res) {
res.status(200).send('ok');
},
test: function (error, req, res) {
res.status(404).send('test');
}
}
},
routers: {
get: function (req, res) {
res.send('get');
},
post: function (req, res) {
res.send('post');
}
},
policies: {
methods: ['get'],
get: async (req, res, scope) => {
return (false);
}
},
validations: {
post: async (req, res, scope) => {
return (false);
}
},
failures: {
policy: 'ok',
validation: 'test'
}
});
vhandler.attach(app);
});
it("should have fallbacks", function (done) {
var passed = false;
app.use((req, res, next) => {
passed = true;
assert(req.fallbacks);
next();
});
request(app)
.get("/")
.end(function (err, res) {
assert(passed);
done();
});
});
it("should provent failure", function (done) {
request(app)
.get("/failure")
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.text === "ok");
done();
});
});
it("should post /prevent all", function (done) {
request(app)
.post("/failure")
.expect(404)
.end(function (err, res) {
assert(!err);
assert(res.text === "test");
done();
});
});
})
================================================
FILE: test/VFile.test.ts
================================================
import 'mocha';
import { VFile } from '../src';
import * as express from 'express';
import * as request from 'supertest';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
const file = new VFile();
var app;
describe('VFile', () => {
before(function () {
app = express();
file.attach(app);
app.post('/file/upload', function (req, res) {
req.cloud('txt', {
type: 'disk',
config: {
dir: path.resolve(__dirname, './data/uploaded/'),
base: 'http://localhost'
}
}).then(function (files) {
res.send(String(files.length));
});
});
});
it('should upload files', function (done) {
request(app).post('/file/upload')
.attach('txt', path.resolve(__dirname, './data/uploader/a.txt'))
.attach('txt', path.resolve(__dirname, './data/uploader/b.txt'))
.end(function (err, res) {
assert(!err);
assert(res.text === '2');
done();
});
});
it('should upload files', function (done) {
request(app).post('/file/upload')
.attach('txt', path.resolve(__dirname, './data/uploader/a.txt'))
.end(function (err, res) {
assert(!err);
assert(res.text === '1');
done();
});
});
it('should test onError', function (done) {
file._isError(true, function (err) {
assert(err);
done();
});
});
it('should test onError', function () {
file._isError(false, function (err) {
});
});
});
================================================
FILE: test/VHandler.test.ts
================================================
import 'mocha';
import { VHandler, VRouter, VEvent} from '../src';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
// import * as vig from '../lib/';
import * as express from 'express';
const app = express();
import * as request from 'supertest';
const router = new VRouter("");
const router1 = new VRouter(null);
var componentPath = path.resolve(__dirname, './data/component/');
var componentPathNoFailure = path.resolve(__dirname, './data/component.nofailure/');
var componentPathUrls = path.resolve(__dirname, './data/component.urls/');
describe('VHandler', () => {
it('should new VHandler 1', () => {
const handler = new VHandler(null, __dirname);
var json = handler.toJSON();
assert(json);
});
it('should new VHandler 2', () => {
var passed = false;
const handler = new VHandler(['/abc'], null);
var json = handler.toJSON();
assert(json);
});
it('should new VHandler 3', () => {
const handler = new VHandler(['/abc'], 'null');
var json = handler.toJSON();
assert(json);
});
it('should new VHandler 4', (done) => {
const handler = new VHandler(
[
'/xxx'
],
componentPath,
'/send');
var json = handler.toJSON();
assert(json.failures);
assert(json.failures.condition);
assert(json.failures.policy);
assert(json.failures.validation);
handler.attach(app);
request(app).get('/send/xxx').
expect(200, function (err, res) {
assert(res.text === 'get');
done()
});
});
it('should new VHandler 5', (done) => {
const handler = new VHandler(
[
'/xxx'
],
componentPath,
'/send');
var json = handler.toJSON();
assert(json);
handler.attach(app);
request(app).put('/send/xxx').
expect(404, function (err, res) {
assert(!err);
assert(res.text === 'Not Found!');
done()
});
});
it('should new VHandler urls', (done) => {
const handler = new VHandler(undefined,
componentPathUrls);
var json = handler.toJSON();
assert(json);
handler.attach(app);
request(app).get('/prefix/urls').
expect(200, function (err, res) {
assert(!err);
assert(res.text === 'get');
done()
});
});
it('should new VHandler sendurl', (done) => {
const handler = new VHandler(undefined,
componentPathUrls);
handler.attach(app);
request(app).get('/sendurl').
expect(200, function (err, res) {
assert(!err);
assert(res.text === 'get');
done()
});
});
it('should new VHandler urls', (done) => {
request(app).delete('/prefix/urls').
expect(200, function (err, res) {
assert(!err);
assert(res.text.indexOf("Hello, VIG, Good Morning") !== -1);
done()
});
});
it('should new VHandler sendurl', (done) => {
// const handler = new VHandler(undefined,
// componentPathUrls);
// handler.attach(app);
request(app).get('/sendurl1').
expect(200, function (err, res) {
assert(!err);
assert(res.text === 'get');
done()
});
});
it('should new VHandler sendurl', (done) => {
const handler = new VHandler(undefined,
componentPathUrls);
handler.attach(app);
request(app).get('/a/urls').
expect(200, function (err, res) {
assert(!err);
assert(res.text === 'get');
done()
});
});
it('should new VHandler 6', (done) => {
let visited = false;
let handler = new VHandler(
[
'/xxx'
],
componentPath,
'/send');
handler.setUrls(['/send/xxx111'])
handler.setPrefix('/prefix');
handler.update('rouaaater', {
});
handler.update('router', {
put: function (req, res) {
visited = true;
res.send('put');
}
});
handler.attach(app);
request(app).put('/prefix/send/xxx111').
end(function (err, res) {
assert(!err);
assert(visited);
assert(res.text === 'put');
done()
});
});
it('should extend VHandler', (done) => {
let visited = false;
let handler = new VHandler();
handler.setUrls(['/send/xxx222'])
handler.setPrefix('/prefix');
handler.extend('sooo', () => {
});
handler.extend('post', null);
handler.extend('post', null);
handler.extend('get', function (req, res) {
visited = true;
res.send('get');
});
handler.attach(app);
request(app).get('/prefix/send/xxx222').
end(function (err, res) {
assert(!err);
assert(visited);
assert(res.text === 'get');
done()
});
});
it('should errorize none errorable', (done) => {
let visited = false;
let handler = new VHandler();
handler.setUrls(['/send/xxx2333'])
handler.setPrefix('/prefix');
handler.extend('sooo', () => {
});
handler.extend('post', null);
handler.extend('post', null);
handler.extend('get', function (req, res) {
visited = true;
res.errorize({}, { ok: 1 })
});
handler.attach(app);
request(app).get('/prefix/send/xxx2333').
end(function (err, res) {
assert(!err);
assert(visited);
assert(res.body.data.ok === 1);
done()
});
});
it('should extend VHandler after attach', (done) => {
let visited = false;
let visited1 = false;
let handler = new VHandler();
handler.setUrls(['/send/resend'])
handler.setPrefix('/prefix');
handler.extend('sooo', () => {
});
handler.extend('post', null);
handler.extend('post', null);
handler.extend('get', function (req, res) {
visited = true;
res.send('get');
});
handler.attach(app);
handler.extend('get', function (req, res) {
visited1 = true;
res.send('get1');
});
request(app).get('/prefix/send/resend').
end(function (err, res) {
assert(!err);
assert(visited1);
assert(res.text === 'get1');
done()
});
});
it('should extend VHandler after attach', () => {
let visited = false;
let visited1 = false;
let handler = new VHandler();
handler.urls = null;
handler.attach(app);
});
it('should extend VHandler after attach', () => {
let visited = false;
let visited1 = false;
let handler = new VHandler();
handler.run(null, null);
});
it('should handler errors', (done) => {
let visited = false;
let visited1 = false;
let handler = new VHandler();
handler.set({
urls: ['/errors'],
routers: {
get: async (req, res, scope) => {
res.errorize(scope.errors.Success);
}
}
});
handler.attach(app);
request(app).get("/errors").end((error, res) => {
assert(res.body.code === 0);
done();
});
});
it('should handler errors', (done) => {
let visited = false;
let visited1 = false;
let handler = new VHandler();
handler.set({
urls: ['/errors1'],
routers: {
get: async (req, res, scope) => {
res.errorize(scope.errors.Success, { hello: 'world1' });
}
}
});
handler.attach(app);
request(app).get("/errors1").end((error, res) => {
assert(res.body.code === 0);
assert(res.body.data.hello === "world1");
done();
});
});
it('should handler errors', (done) => {
let visited = false;
let visited1 = false;
let handler = new VHandler();
handler.set({
urls: ['/errors2'],
routers: {
get: async (req, res, scope) => {
res.errorize();
}
}
});
handler.attach(app);
request(app).get("/errors2").end((error, res) => {
assert(res.body.name === "UnknownError");
done();
});
});
it('should set handler without urls', () => {
let handler = new VHandler();
handler.set({
routers: {
get: async (req, res, scope) => {
res.errorize();
}
}
});
});
it('should handler errors', (done) => {
let visited = false;
let visited1 = false;
let handler = new VHandler();
handler.set({
urls: ['/errors2'],
routers: {
get: async (req, res, scope) => {
assert(scope.event);
assert(scope.event === VEvent.getInstance());
res.errorize();
}
}
});
handler.attach(app);
request(app).get("/errors2").end((error, res) => {
assert(res.body.name === "UnknownError");
done();
});
});
});
================================================
FILE: test/VModel.prepare.test.ts
================================================
import 'mocha';
import { VModel, VHandler } from '../src';
var assert = require('assert');
var path = require('path');
var sailsMemoryAdapter = require('sails-memory');
var request = require('supertest');
var express = require('express');
var app;
var componentPath = path.resolve(__dirname, './data/component.models/');
const model = new VModel(componentPath);
let models;
describe('VModel', function () {
before(function () {
app = express();
});
it('should init models', async () => {
models = await VModel.fetch({
adapters: {
memory: sailsMemoryAdapter
},
connections: {
default: {
adapter: 'memory'
}
}
},
{
connection: 'default'
});
assert(models);
assert(models.User);
assert(models.Pet);
});
it('should get models again', async () => {
models = await VModel.fetch({
adapters: {
memory: sailsMemoryAdapter
},
connections: {
default: {
adapter: 'memory'
}
}
},
{
connection: 'default'
});
assert(models);
assert(models.User);
assert(models.Pet);
});
it("should get models", (done) => {
let app1 = express();
let handler = new VHandler(['/models'], componentPath);
handler.attach(app1);
request(app1)
.post('/models')
.expect(200)
.end(async (err, res) => {
assert(!err);
assert(res.text === 'post');
done();
});
});
});
================================================
FILE: test/VService.test.ts
================================================
import 'mocha';
import { VHandler, VService } from '../src';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
import * as express from 'express';
import * as http from "supertest";
import * as WebSocket from "ws";
import * as session from "express-session";
import { expect } from "chai";
const componentPath = path.resolve(__dirname, './data/component.websockets/');
let app, handler, service, cookies;
let server, options, wsUrl, wsserver;
// let req = request.defaults({ jar: true })
describe('VService', () => {
before(function (done) {
app = express();
handler = new VHandler(null, componentPath);
handler.attach(app);
const h1 = new VHandler();
h1.set(
{
urls: ['/session1'],
sessions: {
all: { session: true }
},
routers: {
get: function (req, res) {
res.json(req.session.user);
},
post: function (req, res) {
req.session.user = {
id: 100
};
res.send('post');
}
}
});
h1.attach(app);
h1.setParent(handler);
service = new VService();
service.start(app, (s, o, ws) => {
server = s;
options = o;
wsserver = ws;
wsUrl = `ws://${options.ip}:${options.port}`;
done();
});
});
after(function (done) {
app = express();
service = new VService({});
service.start(app);
setTimeout(() => done(), 300);
});
it("should open a web socket", (done) => {
const ws = new WebSocket(wsUrl);
ws.on("message", (data) => {
assert("hello" === data);
ws.close();
done();
});
})
it("should send message", (done) => {
const ws = new WebSocket(wsUrl);
ws.on("open", () => {
ws.send("abcd");
ws.send(JSON.stringify({
event: 'put',
message: {
text: 'text'
}
}));
ws.send(JSON.stringify({
event: 'post',
message: 'message'
}));
ws.on("message", (data) => {
if ("hello" === data) {
return;
}
data = JSON.parse(data);
expect(data.event).to.be.eq("post");
expect(data.message).to.be.eq("echo message");
ws.close();
done();
});
});
})
it("should broadcast message", (done) => {
const ws = new WebSocket(wsUrl);
const ws1 = new WebSocket(wsUrl);
let count = 0;
const f = (data) => {
if ("hello" === data) {
return;
}
expect(data).to.be.eq("message");
count++;
if (count > 1) {
ws.close();
ws1.close();
done();
}
}
ws.on("open", () => {
});
ws.on("message", f);
ws1.on("message", f);
ws1.on("open", () => {
ws1.send(JSON.stringify({
event: 'get',
message: 'message'
}));
});
})
it("should broadcast message with filter", (done) => {
const ws = new WebSocket(wsUrl);
const ws1 = new WebSocket(wsUrl);
let count = 0;
const f = (data) => {
if ("hello" === data) {
return;
}
expect(data).to.be.eq("message");
count++;
if (count > 1) {
ws.close();
ws1.close();
done();
}
}
ws.on("open", () => {
ws.send(JSON.stringify({
event: 'false',
message: 'message'
}));
});
ws.on("message", f);
ws1.on("message", f);
ws1.on("open", () => {
ws1.send(JSON.stringify({
event: 'broadcast',
message: 'message'
}));
});
})
it("should post", (done) => {
const req = http(app).post("/session1");
req.expect(200).end((err, res) => {
assert(!err);
assert(res.text === "post");
var re = new RegExp('; path=/; httponly', 'gi');
cookies = res.headers['set-cookie']
.map(function (r) {
return r.replace(re, '');
}).join("; ");
done();
});
});
it("should get", (done) => {
const req = http(app).get("/session1");
req.cookies = cookies;
req.expect(200).end((err, res) => {
assert(!err);
assert(res.body.id === 100);
done();
});
});
it("should should get session info", (done) => {
const ws = new WebSocket(wsUrl,
[],
{
'headers': {
'Cookie': cookies
}
});
ws.on("open", () => {
ws.send(JSON.stringify({
event: 'user',
message: ""
}));
ws.on("message", (data) => {
if ("hello" === data) {
return;
}
data = JSON.parse(String(data));
expect(data.id).to.be.eq(100);
ws.close();
done();
});
});
})
it("should should get session info again", (done) => {
const ws = new WebSocket(wsUrl,
[],
{
'headers': {
'Cookie': cookies
}
});
ws.on("open", () => {
ws.send(JSON.stringify({
event: 'user',
message: ""
}));
ws.on("message", (data) => {
if ("hello" === data) {
return;
}
data = JSON.parse(String(data));
expect(data.id).to.be.eq(100);
ws.close();
done();
});
});
})
it("should shut down", (done) => {
server.close();
done();
})
it("should add event to wsserver", (done) => {
wsserver.addEventListener('aaa', app);
wsserver.addEventListener('aaa', app);
done();
})
});
================================================
FILE: test/VSession.test.ts
================================================
import 'mocha';
import { VHandler, VRouter } from '../src';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
// import * as vig from '../lib/';
import * as express from 'express';
const app = express();
import * as request from 'supertest';
var componentPathUrls = path.resolve(__dirname, './data/component.sessions/');
let handler = new VHandler(null, componentPathUrls);
handler.attach(app);
describe('VSession', () => {
it('should not get', (done) => {
request(app).get('/sessions').
expect(200, function (err, res) {
console.log(err, res.text);
done();
});
});
});
================================================
FILE: test/VTemplate.test.ts
================================================
import 'mocha';
import { VHandler, VRouter } from '../src';
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
// import * as vig from '../lib/';
import * as express from 'express';
const app = express();
import * as request from 'supertest';
var componentPathUrls = path.resolve(__dirname, './data/component.templates/');
let handler = new VHandler(null, componentPathUrls);
handler.attach(app);
describe('VTemplate', () => {
it('should invoke hirarchically', (done) => {
request(app).get('/h2').
expect(200, function (err, res) {
assert(!err);
assert(res.text.indexOf("color: black;") !== -1);
assert(res.text.indexOf("Hello, VIG, Good Morning") !== -1);
done();
});
});
it('should invoke hirarchically again', (done) => {
assert(handler.template.isType(""));
request(app).get('/h2').
expect(200, function (err, res) {
assert(!err);
assert(res.text.indexOf("color: black;") !== -1);
assert(res.text.indexOf("Hello, VIG, Good Morning") !== -1);
done();
});
});
it('should request arrayed middlewares', (done) => {
assert(handler.template.isType(""));
request(app).get('/h1').
expect(200, function (err, res) {
assert(!err);
assert(res.text === "get");
done();
});
});
it('should request arrayed middlewares with failure', (done) => {
assert(handler.template.isType(""));
request(app).post('/h1').
expect(403, function (err, res) {
assert(!err);
assert(res.text === "Access Denied!");
done();
});
});
});
================================================
FILE: test/bodies.test.ts
================================================
var assert = require("assert");
var request = require("supertest");
var express = require("express");
var path = require("path");
import { promisify } from "bluebird";
import { VHandler, VService, VEvent } from "../src";
import * as fs from "fs";
var app = express();
var componentPath = path.resolve(__dirname, "./data/component.bodies/");
describe("vig #body", function () {
it("should get body1", function (done) {
var handler = new VHandler();
handler.set({
urls: ["/body1"],
bodies: {
post: {
form: true
}
},
routers: {
post: async (req, res) => {
res.send(req.body);
}
}
});
handler.attach(app);
request(app)
.post("/body1")
.type("form")
.send({
key: "value",
key1: "value1"
})
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.body.key === "value");
assert(res.body.key1 === "value1");
done();
});
});
it("should get body1", function (done) {
var handler = new VHandler();
handler.set({
urls: ["/body110"],
bodies: {
post: {
form: true
}
},
routers: {
get: async (req, res) => {
res.send(req.body);
}
}
});
handler.attach(app);
request(app)
.get("/body110")
.expect(200)
.end(function (err, res) {
assert(!err);
done();
});
});
it("should get body2", function (done) {
var handler = new VHandler();
handler.set({
urls: ["/body2"],
bodies: {
post: {
formdata: true
}
},
routers: {
post: async (req, res) => {
res.send(req.body);
}
}
});
handler.attach(app);
request(app)
.post("/body2")
.type("form")
.send({
key: "value",
key1: "value1"
})
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.body.key === "value");
assert(res.body.key1 === "value1");
done();
});
});
it("should get body3", function (done) {
var handler = new VHandler();
handler.set({
urls: ["/body3"],
bodies: {
post: {
json: true
}
},
routers: {
post: async (req, res) => {
res.send(req.body);
}
}
});
handler.attach(app);
request(app)
.post("/body3")
.type("json")
.send(JSON.stringify({
key: "value",
key1: "value1"
}))
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.body.key === "value");
assert(res.body.key1 === "value1");
done();
});
});
it("should get body4", function (done) {
var handler = new VHandler();
handler.set({
urls: ["/body4"],
bodies: {
post: {
xml: true,
lot: true,
good: null,
send: async (req, res, scope) => {
}
}
},
routers: {
post: async (req, res) => {
res.send(String(req.body));
}
}
});
handler.attach(app);
request(app)
.post("/body4")
.type("raw")
.set("Content-Type", "text/xml")
.set("Accept", "text/xml")
.send("<?xml version=\"1.0\" encoding=\"utf-8\" ?><key>value</key><key1>value1</key1>")
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.text === "<?xml version=\"1.0\" encoding=\"utf-8\" ?><key>value</key><key1>value1</key1>");
done();
});
});
it("should get body5", function (done) {
var handler = new VHandler();
handler.set({
urls: ["/body5"],
bodies: {
post: {
xml: true,
lot: true,
good: null,
send: async (req, res, scope) => {
}
}
},
routers: {
post: async (req, res) => {
res.send(String(req.body));
}
}
});
handler.attach(app);
request(app)
.post("/body5")
.type("raw")
.set("Content-Type", "application/xml")
.set("Accept", "application/xml")
.send("<?xml version=\"1.0\" encoding=\"utf-8\" ?><key>value</key><key1>value1</key1>")
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.text === "<?xml version=\"1.0\" encoding=\"utf-8\" ?><key>value</key><key1>value1</key1>");
done();
});
});
it("should get body51", function (done) {
var handler = new VHandler();
handler.set({
urls: ["/body511"],
routers: {
post: async (req, res) => {
res.json(req.body);
}
}
});
handler.attach(app);
request(app)
.post("/body511")
.type("form")
.send({
key: "value",
key1: "value1"
})
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.body.key === "value");
assert(res.body.key1 === "value1");
done();
});
});
it("should post /body6", function (done) {
const app1 = express();
var handler = new VHandler(
["/body6"],
componentPath,
"/"
);
handler.attach(app1);
request(app1)
.post("/body6")
.type("form")
.set('Cookie', ['myApp-token=12345667', 'myApp-other=blah'])
.send({
key: "value",
key1: "value1"
})
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.body.key === "value");
assert(res.body.key1 === "value1");
done();
});
});
it("should post /file", function (done) {
var handler = new VHandler();
handler.set({
urls: ["/file"],
asyncs: {
post: [async () => {
}, async () => {
}]
},
bodies: {
post: {
file: true,
lot: true,
good: null,
send: async (req, res, scope) => {
}
}
},
routers: {
post: async (req, res) => {
const files = await req.storage("txt");
const file = files[0];
const content = fs.readFileSync(file.fd);
res.send(String(content));
}
}
});
handler.attach(app);
request(app)
.post("/file")
.attach("txt", path.resolve(__dirname, "./data/uploader/a.txt"))
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.text === "hello world!")
done();
});
});
});
================================================
FILE: test/config.test.ts
================================================
var assert = require('assert');
var request = require('supertest');
var express = require('express');
var path = require('path');
import { VHandler, VService, VEvent } from '../src';
var app = express();
describe('vig #configs', function () {
before(function () {
var handler = new VHandler();
handler.set({
urls: ['/configs'],
configs: {
limitation: {
page: 100
}
},
routers: {
get: async (req, res, scope) => {
const { configs } = scope;
assert(configs.limitation.page === 100);
res.send('get');
},
post: async (req, res, scope) => {
const { configs } = scope;
assert(configs.limitation.page === 100);
res.send('post');
}
}
});
handler.attach(app);
});
it('should get configs', function (done) {
request(app)
.get('/configs')
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.text === 'get');
done();
});
});
it('should post configs', function (done) {
request(app)
.post('/configs')
.expect(200)
.end(function (err, res) {
assert(!err);
assert(res.text === 'post');
done();
});
});
});
================================================
FILE: test/data/component/conditions/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/conditions/get.ts
================================================
export = async (req, res, scope) => {
return(false);
};
================================================
FILE: test/data/component/conditions/post.ts
================================================
export = async (req, res, scope) => {
return(true);
};
================================================
FILE: test/data/component/conditions/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component/configs/test.js
================================================
module.exports = {
a: '1'
};
================================================
FILE: test/data/component/errors/dir/.gitkeep
================================================
================================================
FILE: test/data/component/errors/no
================================================
================================================
FILE: test/data/component/errors/vig.js
================================================
module.exports = {
Vig: {
Test: {
Error: {
messages: {
'zh-CN': 'Vig测试错误!',
'en-US': 'Vig Test Error!'
}
}
}
}
};
================================================
FILE: test/data/component/events/hello.ts
================================================
export = async(scope, cb) => {
const {errors} = scope;
cb('hello', errors);
}
================================================
FILE: test/data/component/events/send.ts
================================================
export = 'aaa';
================================================
FILE: test/data/component/fallbacks/condition.js
================================================
module.exports = function (error, req, res) {
res.status(403).send('Access Denied Due to Failure to conditions');
};
================================================
FILE: test/data/component/fallbacks/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/fallbacks/policy.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/fallbacks/validation.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/handlers
================================================
================================================
FILE: test/data/component/middlewares/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/middlewares/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/middlewares/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component/middlewares/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component/models/Pet.js
================================================
module.exports = {
identity: 'pet',
attributes: {
breed: 'string',
type: 'string',
name: 'string',
// Add a reference to User
owner: {
model: 'user'
}
}
};
================================================
FILE: test/data/component/models/User.js
================================================
module.exports = {
identity: 'user',
attributes: {
firstName: 'string',
lastName: 'string',
// Add a reference to Pets
pets: {
collection: 'pet',
via: 'owner'
}
}
};
================================================
FILE: test/data/component/pagers/get.ts
================================================
export = true;
================================================
FILE: test/data/component/pagers/post.ts
================================================
export = false;
================================================
FILE: test/data/component/policies/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/policies/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/policies/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component/policies/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/routers/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component/routers/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component/routers/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component/validators/delete.js
================================================
module.exports = {
required: [],
cc : {
},
bb: {
},
aa: {
}
};
================================================
FILE: test/data/component/validators/get.js
================================================
module.exports = {};
================================================
FILE: test/data/component/validators/options.js
================================================
module.exports = {
required: {}
};
================================================
FILE: test/data/component/validators/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component/validators/put.js
================================================
module.exports = {
required: [],
body : {
},
params: {
},
query: {
}
};
================================================
FILE: test/data/component.bodies/asyncs/get.ts
================================================
export = async (req, res, scope) => {
scope.asyncs = {
get: true
};
}
================================================
FILE: test/data/component.bodies/asyncs/post.ts
================================================
export = [async()=> {
}, async() => {
}];
================================================
FILE: test/data/component.bodies/bodies/get.ts
================================================
export = {
formdata: true
};
================================================
FILE: test/data/component.bodies/bodies/post.ts
================================================
export = {
formdata: true
};
================================================
FILE: test/data/component.bodies/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.bodies/routers/get.ts
================================================
var assert = require("assert");
export = async (req, res, scope) => {
assert(req.cookies);
assert(scope.asyncs.get);
res.send('get');
};
================================================
FILE: test/data/component.bodies/routers/post.js
================================================
var assert = require("assert");
module.exports = function (req, res) {
assert(!req.cookies);
res.send(req.body);
};
================================================
FILE: test/data/component.bodies/routers/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.bodies/sessions/get.ts
================================================
export = {
cookie: true
}
================================================
FILE: test/data/component.bodies/sessions/put.ts
================================================
export = {
cookie: true
}
================================================
FILE: test/data/component.inheritance/configs/upload.ts
================================================
export = {
file: 1
}
================================================
FILE: test/data/component.inheritance/handlers/send/handlers/one/configs/one.ts
================================================
export = {
one: true
};
================================================
FILE: test/data/component.inheritance/handlers/send/handlers/one/routers/get.ts
================================================
export = async (req, res, scope) => {
console.log('inside one get');
res.json(scope.configs);
}
================================================
FILE: test/data/component.inheritance/handlers/send/handlers/one/urls.ts
================================================
export = ["/one"];
================================================
FILE: test/data/component.inheritance/handlers/send/handlers/third/configs/third.ts
================================================
export = {
third: true
};
================================================
FILE: test/data/component.inheritance/handlers/send/handlers/third/routers/get.ts
================================================
export = async (req, res, scope) => {
console.log('inside get');
res.json(scope.configs);
}
================================================
FILE: test/data/component.inheritance/handlers/send/handlers/third/urls.ts
================================================
export = ["/configs"];
================================================
FILE: test/data/component.inheritance/middlewares/configs/mad.ts
================================================
export = {
mad: true
};
================================================
FILE: test/data/component.inheritance/middlewares/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.inheritance/middlewares/get.ts
================================================
export = async (req, res, scope) => {
req.mid = 'mid';
};
================================================
FILE: test/data/component.inheritance/middlewares/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.inheritance/middlewares/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.inheritance/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.inheritance/routers/get.ts
================================================
var assert = require("assert");
export = async (req, res, scope) => {
const {configs} = scope;
assert(configs.upload.file === 1);
res.send(req.mid);
};
================================================
FILE: test/data/component.inheritance/routers/post.ts
================================================
var assert = require("assert");
export = async (req, res, scope) => {
const {configs} = scope;
assert(configs.upload.file === 1);
res.send('post');
};
================================================
FILE: test/data/component.inheritance/routers/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.middleware/configs/upload.ts
================================================
export = {
file: 1
}
================================================
FILE: test/data/component.middleware/middlewares/delete.ts
================================================
module.exports = function (req, res) {
return false;
};
================================================
FILE: test/data/component.middleware/middlewares/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.middleware/middlewares/get.ts
================================================
export = async (req, res, scope) => {
req.mid = 'mid';
};
================================================
FILE: test/data/component.middleware/middlewares/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.middleware/middlewares/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.middleware/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.middleware/routers/get.ts
================================================
var assert = require("assert");
export = async (req, res, scope) => {
const {configs} = scope;
assert(configs.upload.file === 1);
res.send(req.mid);
};
================================================
FILE: test/data/component.middleware/routers/post.ts
================================================
var assert = require("assert");
export = async (req, res, scope) => {
const {configs} = scope;
assert(configs.upload.file === 1);
res.send('post');
};
================================================
FILE: test/data/component.middleware/routers/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.middleware.all/middlewares/all.ts
================================================
export = async (req, res, scope) => {
req.mid = 'all';
};
================================================
FILE: test/data/component.middleware.all/middlewares/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.middleware.all/routers/all.js
================================================
module.exports = function (req, res) {
res.send(req.mid);
};
================================================
FILE: test/data/component.middleware.all/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/conditions/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/conditions/get.ts
================================================
export = async (req, res, scope) => {
return false;
};
================================================
FILE: test/data/component.models/conditions/post.ts
================================================
export = async (req, res, scope) => {
return true;
};
================================================
FILE: test/data/component.models/conditions/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.models/configs/test.js
================================================
module.exports = {
a: '1'
};
================================================
FILE: test/data/component.models/errors/dir/.gitkeep
================================================
================================================
FILE: test/data/component.models/errors/no
================================================
================================================
FILE: test/data/component.models/errors/vig.js
================================================
module.exports = {
Vig: {
Test: {
Error: {
messages: {
'zh-CN': 'Vig测试错误!',
'en-US': 'Vig Test Error!'
}
}
}
}
};
================================================
FILE: test/data/component.models/events/hello.ts
================================================
export = async(scope, cb) => {
const {errors} = scope;
cb('hello', errors);
}
================================================
FILE: test/data/component.models/events/send.ts
================================================
export = 'aaa';
================================================
FILE: test/data/component.models/fallbacks/condition.js
================================================
module.exports = function (error, req, res) {
res.status(403).send('Access Denied Due to Failure to conditions');
};
================================================
FILE: test/data/component.models/fallbacks/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/fallbacks/policy.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/fallbacks/validation.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/middlewares/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/middlewares/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/middlewares/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.models/middlewares/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.models/models/Pet.js
================================================
module.exports = {
identity: 'pet',
attributes: {
breed: 'string',
type: 'string',
name: 'string',
// Add a reference to User
owner: {
model: 'user'
}
}
};
================================================
FILE: test/data/component.models/models/User.js
================================================
module.exports = {
identity: 'user',
attributes: {
firstName: 'string',
lastName: 'string',
// Add a reference to Pets
pets: {
collection: 'pet',
via: 'owner'
}
}
};
================================================
FILE: test/data/component.models/pagers/get.ts
================================================
export = true;
================================================
FILE: test/data/component.models/pagers/post.ts
================================================
export = false;
================================================
FILE: test/data/component.models/policies/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/policies/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/policies/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.models/policies/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.models/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.models/routers/get.ts
================================================
import * as assert from "assert";
export = async (req, res, scope) => {
const { User, Pet } = scope.models;
assert(User);
assert(Pet);
res.send('get');
};
================================================
FILE: test/data/component.models/routers/post.ts
================================================
import * as assert from "assert";
module.exports = async (req, res, scope) => {
const { User, Pet } = scope.models;
assert(User);
assert(Pet);
res.send('post');
};
================================================
FILE: test/data/component.models/routers/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.models/validators/delete.js
================================================
module.exports = {
required: [],
cc : {
},
bb: {
},
aa: {
}
};
================================================
FILE: test/data/component.models/validators/get.js
================================================
module.exports = {};
================================================
FILE: test/data/component.models/validators/options.js
================================================
module.exports = {
required: {}
};
================================================
FILE: test/data/component.models/validators/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.models/validators/put.js
================================================
module.exports = {
required: [],
body : {
},
params: {
},
query: {
}
};
================================================
FILE: test/data/component.nomethod/routers/all.js
================================================
module.exports = function (req, res) {
var id = req.params.id;
res.send('nomethod' + id);
};
================================================
FILE: test/data/component.policies/definitions/fallbacks/ok.ts
================================================
export = async (err, req, res, scope) => {
res.status(403).send('Fail back!');
}
================================================
FILE: test/data/component.policies/definitions/policies/fail.ts
================================================
export = async (req, res, scope) => {
return(false);
}
================================================
FILE: test/data/component.policies/definitions/policies/ok.ts
================================================
export = async (req, res, scope) => {
res.status(200).send('ok');
}
================================================
FILE: test/data/component.policies/definitions/policies/test.ts
================================================
export = async (req, res, scope) => {
res.status(404).send('test');
}
================================================
FILE: test/data/component.policies/fallbacks/policy.js
================================================
module.exports = "ok";
================================================
FILE: test/data/component.policies/policies/get.js
================================================
module.exports = 'ok';
================================================
FILE: test/data/component.policies/policies/post.js
================================================
module.exports = 'test';
================================================
FILE: test/data/component.policies/policies/put.js
================================================
module.exports = 'fail';
================================================
FILE: test/data/component.policies/routers/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.policies/routers/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.policies/routers/put.js
================================================
================================================
FILE: test/data/component.sessions/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.sessions/routers/get.ts
================================================
var assert = require("assert");
export = async (req, res, scope) => {
const {configs} = scope;
res.send('get');
};
================================================
FILE: test/data/component.sessions/routers/post.ts
================================================
var assert = require("assert");
export = async (req, res, scope) => {
const {configs} = scope;
assert(configs.upload.file === 1);
res.send('post');
};
================================================
FILE: test/data/component.sessions/routers/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.sessions/sessions/all.ts
================================================
export = { session: true };
================================================
FILE: test/data/component.sessions/urls.ts
================================================
export = ['/sessions']
================================================
FILE: test/data/component.templates/configs/test.ts
================================================
export = {
hello: "world"
};
================================================
FILE: test/data/component.templates/handlers/a.ts
================================================
import * as assert from "assert";
export = {
urls: ['/urls'],
prefix: '/a',
configs: {
b: 1,
test: {
b: 1
}
},
routers: {
get: async(req, res, scope) => {
assert(scope.configs.test.a === '1');
assert(scope.configs.test.b === 1);
assert(scope.configs.b === 1);
res.send('get');
}
}
}
================================================
FILE: test/data/component.templates/handlers/send/handlers/send/handlers/send/routers/get.ts
================================================
import * as assert from "assert";
export = async (req, res, scope) => {
assert(scope.configs.test.a);
res.send('get');
};
================================================
FILE: test/data/component.templates/handlers/send/handlers/send/handlers/send/urls.ts
================================================
export = ['/send3', '/sendurl3'];
================================================
FILE: test/data/component.templates/handlers/send/handlers/send/routers/get.ts
================================================
import * as assert from "assert";
export = async (req, res, scope) => {
assert(scope.configs.test.a);
res.send('get');
};
================================================
FILE: test/data/component.templates/handlers/send/handlers/send/urls.ts
================================================
export = ['/send1', '/sendurl1'];
================================================
FILE: test/data/component.templates/handlers/send/prefix.ts
================================================
export = "";
================================================
FILE: test/data/component.templates/handlers/send/routers/get.ts
================================================
export = async (req, res, scope) => {
req.session = {
user: 1
};
res.vRender({ username: "VIG" }, "h2");
};
================================================
FILE: test/data/component.templates/handlers/send/templates/views/h2.html
================================================
{% extends "layout.html" %} {% block header %}
<style>
h1 {
color: black;
}
</style>
{% endblock %}
================================================
FILE: test/data/component.templates/handlers/send/urls.ts
================================================
export = ['/h2'];
================================================
FILE: test/data/component.templates/middlewares/fuck.ts
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.templates/middlewares/get.ts
================================================
module.exports = [async (req, res, scope) => {
scope.mid1 = true;
}, async (req, res, scope) => {
scope.mid2 = true;
}, async (req, res, scope) => {
scope.mid3 = true;
}];
================================================
FILE: test/data/component.templates/middlewares/post.ts
================================================
module.exports = [async (req, res, scope) => {
scope.mid1 = true;
}];
================================================
FILE: test/data/component.templates/middlewares/put.ts
================================================
module.exports = {};
================================================
FILE: test/data/component.templates/pagers/get.ts
================================================
export = true;
================================================
FILE: test/data/component.templates/pagers/post.ts
================================================
export = false;
================================================
FILE: test/data/component.templates/policies/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.templates/policies/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.templates/policies/post.ts
================================================
module.exports = [async (req, res, scope) => {
scope.mid1 = true;
}];
================================================
FILE: test/data/component.templates/policies/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.templates/routers/delete.ts
================================================
export = async (req, res, scope) => {
req.session = {
user: 1
};
res.vRender({ username: "VIG" }, "layout");
};
================================================
FILE: test/data/component.templates/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.templates/routers/get.js
================================================
var assert = require("assert");
module.exports = function (req, res, scope) {
assert(scope.mid1);
assert(scope.mid2);
assert(scope.mid3);
req.session = {
user: 1
};
res.send('get');
};
================================================
FILE: test/data/component.templates/routers/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.templates/routers/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.templates/templates/filters/name.js
================================================
module.exports = function(name) {
return name + ", Good Morning";
};
================================================
FILE: test/data/component.templates/templates/views/layout.html
================================================
<!DOCTYPE html>
<html>
{% block header%} {% endblock %}
<body>
{% block main %} Hello, {{ username | name }} {% endblock %}
{% if currentUser %}
user = {{currentUser}}
{% endif %}
{{ config.test.hello }}
</body>
</html>
================================================
FILE: test/data/component.templates/urls.ts
================================================
export = ['/h1']
================================================
FILE: test/data/component.urls/conditions/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/conditions/get.ts
================================================
import * as assert from 'assert';
export = async (req, res, scope) => {
assert(scope.configs.test.a === "1");
assert(scope.configs.test.b === "2");
return false;
};
================================================
FILE: test/data/component.urls/conditions/post.ts
================================================
export = async (req, res, scope) => {
return true;
};
================================================
FILE: test/data/component.urls/conditions/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.urls/configs/test.js
================================================
module.exports = {
a: '1',
b: '2'
};
================================================
FILE: test/data/component.urls/errors/dir/.gitkeep
================================================
================================================
FILE: test/data/component.urls/errors/no
================================================
================================================
FILE: test/data/component.urls/errors/vig.js
================================================
module.exports = {
Vig: {
Test: {
Error: {
messages: {
'zh-CN': 'Vig测试错误!',
'en-US': 'Vig Test Error!'
}
}
}
}
};
================================================
FILE: test/data/component.urls/events/hello.ts
================================================
export = async(scope, cb) => {
const {errors} = scope;
cb('hello', errors);
}
================================================
FILE: test/data/component.urls/events/send.ts
================================================
export = 'aaa';
================================================
FILE: test/data/component.urls/fallbacks/condition.js
================================================
module.exports = function (error, req, res) {
res.status(403).send('Access Denied Due to Failure to conditions');
};
================================================
FILE: test/data/component.urls/fallbacks/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/fallbacks/policy.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/fallbacks/validation.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/handlers/a.ts
================================================
import * as assert from "assert";
export = {
urls: ['/urls'],
prefix: '/a',
configs: {
b: 1,
test: {
b: 1
}
},
routers: {
get: async(req, res, scope) => {
assert(scope.configs.test.a === '1');
assert(scope.configs.test.b === 1);
assert(scope.configs.b === 1);
res.send('get');
}
}
}
================================================
FILE: test/data/component.urls/handlers/send/handlers/send/handlers/send/routers/get.ts
================================================
import * as assert from "assert";
export = async (req, res, scope) => {
assert(scope.configs.test.a);
res.send('get');
};
================================================
FILE: test/data/component.urls/handlers/send/handlers/send/handlers/send/urls.ts
================================================
export = ['/send3', '/sendurl3'];
================================================
FILE: test/data/component.urls/handlers/send/handlers/send/routers/get.ts
================================================
import * as assert from "assert";
export = async (req, res, scope) => {
assert(scope.configs.test.a);
res.send('get');
};
================================================
FILE: test/data/component.urls/handlers/send/handlers/send/urls.ts
================================================
export = ['/send1', '/sendurl1'];
================================================
FILE: test/data/component.urls/handlers/send/routers/get.ts
================================================
import * as assert from "assert";
export = async (req, res, scope) => {
assert(scope.configs.test.a);
res.send('get');
};
================================================
FILE: test/data/component.urls/handlers/send/urls.ts
================================================
export = ['/send', '/sendurl'];
================================================
FILE: test/data/component.urls/middlewares/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/middlewares/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/middlewares/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.urls/middlewares/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.urls/models/Pet.js
================================================
module.exports = {
identity: 'pet',
attributes: {
breed: 'string',
type: 'string',
name: 'string',
// Add a reference to User
owner: {
model: 'user'
}
}
};
================================================
FILE: test/data/component.urls/models/User.js
================================================
module.exports = {
identity: 'user',
attributes: {
firstName: 'string',
lastName: 'string',
// Add a reference to Pets
pets: {
collection: 'pet',
via: 'owner'
}
}
};
================================================
FILE: test/data/component.urls/pagers/get.ts
================================================
export = true;
================================================
FILE: test/data/component.urls/pagers/post.ts
================================================
export = false;
================================================
FILE: test/data/component.urls/policies/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/policies/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/policies/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.urls/policies/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.urls/prefix.ts
================================================
export = "/prefix";
================================================
FILE: test/data/component.urls/routers/delete.ts
================================================
export = async (req, res, scope) => {
res.vRender({ username: "VIG" }, "layout", 'html');
};
================================================
FILE: test/data/component.urls/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/routers/get.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.urls/routers/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.urls/routers/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.urls/templates/filters/name.ts
================================================
export = (name) => {
return name + ", Good Morning";
}
================================================
FILE: test/data/component.urls/templates/views/layout.html
================================================
<!DOCTYPE html>
<html>
{% block header%} {% endblock %}
<body>
{% block main %} Hello, {{ username | name }} {% endblock %}
</body>
</html>
================================================
FILE: test/data/component.urls/urls.ts
================================================
export = ['/urls']
================================================
FILE: test/data/component.urls/validators/delete.js
================================================
module.exports = {
required: [],
cc : {
},
bb: {
},
aa: {
}
};
================================================
FILE: test/data/component.urls/validators/get.js
================================================
module.exports = {};
================================================
FILE: test/data/component.urls/validators/options.js
================================================
module.exports = {
required: {}
};
================================================
FILE: test/data/component.urls/validators/post.js
================================================
module.exports = function (req, res) {
res.send('post');
};
================================================
FILE: test/data/component.urls/validators/put.js
================================================
module.exports = {
required: [],
body : {
},
params: {
},
query: {
}
};
================================================
FILE: test/data/component.websockets/configs/session.ts
================================================
import * as session from "express-session";
const MemoryStore = session.MemoryStore;
const store = new MemoryStore();
const options = {
store: store,
secret: 'keyboard cat',
resave: false,
saveUninitialized: false,
cookie: { secure: false }
};
export = {
store: store,
options: options,
middleware: session(options)
};
================================================
FILE: test/data/component.websockets/configs/upload.ts
================================================
export = {
file: 1
}
================================================
FILE: test/data/component.websockets/routers/fuck.js
================================================
module.exports = function (req, res) {
res.send('get');
};
================================================
FILE: test/data/component.websockets/routers/get.ts
================================================
var assert = require("assert");
export = async (req, res, scope) => {
const {configs} = scope;
assert(configs.upload.file === 1);
res.send(req.mid);
};
================================================
FILE: test/data/component.websockets/routers/post.ts
================================================
var assert = require("assert");
export = async (req, res, scope) => {
const {configs} = scope;
assert(configs.upload.file === 1);
res.send('post');
};
================================================
FILE: test/data/component.websockets/routers/put.js
================================================
module.exports = {};
================================================
FILE: test/data/component.websockets/sessions/all.ts
================================================
export = { session: true };
================================================
FILE: test/data/component.websockets/websockets/broadcast.ts
================================================
import {VWSServer} from "../../../../src/VWSServer";
export = async (message, ws, scope) => {
const vws = VWSServer.getInstance()
vws.broadcast("message", () => {
return true
});
};
================================================
FILE: test/data/component.websockets/websockets/enter.ts
================================================
export = async (ws, req, scope) => {
ws.send("hello");
};
================================================
FILE: test/data/component.websockets/websockets/false.ts
================================================
import {VWSServer} from "../../../../src/VWSServer";
export = async () => {
const vws = VWSServer.getInstance()
vws.broadcast("message", () => {
return false
});
};
================================================
FILE: test/data/component.websockets/websockets/get.ts
================================================
import {VWSServer} from "../../../../src/VWSServer";
export = async () => {
const vws = VWSServer.getInstance()
vws.broadcast("message", null);
};
================================================
FILE: test/data/component.websockets/websockets/leave.ts
================================================
export = async (ws, req, scope) => {
console.log("leave");
};
================================================
FILE: test/data/component.websockets/websockets/post.ts
================================================
export = async (ws, req, scope, message) => {
ws.send(JSON.stringify({
event: "post",
message: "echo " + message
}));
};
================================================
FILE: test/data/component.websockets/websockets/put.ts
================================================
export = {};
================================================
FILE: test/data/component.websockets/websockets/user.ts
================================================
export = async (ws, req, scope) => {
console.log("inside user socket info");
console.log(req.session.user);
ws.send(JSON.stringify(req.session.user));
};
================================================
FILE: test/data/configs/test.js
================================================
module.exports = {
a: '1'
};
================================================
FILE: test/data/errors/dir/.gitkeep
================================================
================================================
FILE: test/data/errors/no
================================================
================================================
FILE: test/data/errors/vig.js
================================================
module.exports = {
Vig: {
Test: {
Error: {
messages: {
'zh-CN': 'Vig测试错误!',
'en-US': 'Vig Test Error!'
}
}
}
}
};
================================================
FILE: test/data/errorsHandlers.ts
================================================
export = [{
urls: ['/errors'],
routers: {
get: function (req, res) {
res.errorize(res.errors.Success);
},
post: function (req, res) {
res.restify(res.errors.Failure);
},
put: function (req, res) {
res.restify(res.errors.VigTestError);
}
}
}];
================================================
FILE: test/data/eventsHandlers.ts
================================================
export = {
names: ['@event1', '@event2', 'bad'],
handlers: {
'@event1': function (next) {
next('@event1');
},
'@event2': function (next) {
next('@event2');
}
}
};
================================================
FILE: test/data/fallbacks/ok.js
================================================
module.exports = function(error, req, res) {
res.status(200).send('ok');
}
================================================
FILE: test/data/fallbacks/test.js
================================================
module.exports = function(error, req, res) {
res.status(404).send('test');
}
================================================
FILE: test/data/fixtures/events.js
================================================
module.exports = {
names: ['@event1', '@ev
gitextract_1tm1fzl_/ ├── .editorconfig ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── demo/ │ ├── chapter-1/ │ │ ├── README.md │ │ ├── index.js │ │ └── package.json │ ├── chapter-2/ │ │ ├── README.md │ │ ├── all.js │ │ ├── get-set.js │ │ ├── index.js │ │ └── package.json │ ├── chapter-3/ │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ └── query.js │ ├── chapter-4/ │ │ ├── README.md │ │ ├── alias.js │ │ ├── email.js │ │ ├── enum.js │ │ ├── index.js │ │ ├── length.js │ │ ├── package.json │ │ └── password.js │ ├── chapter-5/ │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ ├── phone.js │ │ └── regex.js │ └── chapter-6/ │ ├── README.md │ ├── config/ │ │ └── waterline/ │ │ ├── adapter.js │ │ ├── connections.js │ │ ├── databases/ │ │ │ ├── mongodb.js │ │ │ └── mysql.js │ │ └── index.js │ ├── config.js │ ├── handlers/ │ │ └── user/ │ │ ├── add.js │ │ └── index.js │ ├── index.js │ ├── models/ │ │ └── User.js │ └── package.json ├── docs/ │ ├── README.md │ ├── Session.md │ ├── progress.md │ └── use.md ├── package.json ├── ppt/ │ └── intro.md ├── src/ │ ├── Components/ │ │ ├── HTTP.ts │ │ ├── VBase.ts │ │ ├── VConfig.ts │ │ ├── VError.ts │ │ ├── VEvent.ts │ │ ├── VHTTPBase.ts │ │ ├── VMiddleware.ts │ │ ├── VModel.ts │ │ ├── VRouter.ts │ │ ├── VWebSocket.ts │ │ └── index.ts │ ├── DefinitionParsers/ │ │ ├── VFallbackDefinition.ts │ │ └── VPolicyDefinition.ts │ ├── MiddlewareParsers/ │ │ ├── VBody.ts │ │ ├── VCondition.ts │ │ ├── VFallback.ts │ │ ├── VFile.ts │ │ ├── VLimitation.ts │ │ ├── VPager.ts │ │ ├── VPolicy.ts │ │ ├── VSession.ts │ │ ├── VValidator.ts │ │ └── index.ts │ ├── Templates/ │ │ ├── Filter.ts │ │ └── VTemplate.ts │ ├── VDefinition.ts │ ├── VEvent.ts │ ├── VHandler.ts │ ├── VService.ts │ ├── VWSServer.ts │ └── index.ts ├── test/ │ ├── Components/ │ │ ├── VBase.test.ts │ │ ├── VCondition.test.ts │ │ ├── VConfig.test.ts │ │ ├── VError.test.ts │ │ ├── VFallback.test.ts │ │ ├── VHTTPBase.test.ts │ │ ├── VMiddleware.test.ts │ │ ├── VPager.test.ts │ │ ├── VPolicy.test.ts │ │ ├── VRouter.test.ts │ │ └── VValidator.test.ts │ ├── VEvent.test.ts │ ├── VFailureDefinition.test.ts │ ├── VFile.test.ts │ ├── VHandler.test.ts │ ├── VModel.prepare.test.ts │ ├── VService.test.ts │ ├── VSession.test.ts │ ├── VTemplate.test.ts │ ├── bodies.test.ts │ ├── config.test.ts │ ├── data/ │ │ ├── component/ │ │ │ ├── conditions/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.ts │ │ │ │ ├── post.ts │ │ │ │ └── put.js │ │ │ ├── configs/ │ │ │ │ └── test.js │ │ │ ├── errors/ │ │ │ │ ├── dir/ │ │ │ │ │ └── .gitkeep │ │ │ │ ├── no │ │ │ │ └── vig.js │ │ │ ├── events/ │ │ │ │ ├── hello.ts │ │ │ │ └── send.ts │ │ │ ├── fallbacks/ │ │ │ │ ├── condition.js │ │ │ │ ├── fuck.js │ │ │ │ ├── policy.js │ │ │ │ └── validation.js │ │ │ ├── handlers │ │ │ ├── middlewares/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ ├── models/ │ │ │ │ ├── Pet.js │ │ │ │ └── User.js │ │ │ ├── pagers/ │ │ │ │ ├── get.ts │ │ │ │ └── post.ts │ │ │ ├── policies/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ ├── routers/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ └── validators/ │ │ │ ├── delete.js │ │ │ ├── get.js │ │ │ ├── options.js │ │ │ ├── post.js │ │ │ └── put.js │ │ ├── component.bodies/ │ │ │ ├── asyncs/ │ │ │ │ ├── get.ts │ │ │ │ └── post.ts │ │ │ ├── bodies/ │ │ │ │ ├── get.ts │ │ │ │ └── post.ts │ │ │ ├── routers/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.ts │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ └── sessions/ │ │ │ ├── get.ts │ │ │ └── put.ts │ │ ├── component.inheritance/ │ │ │ ├── configs/ │ │ │ │ └── upload.ts │ │ │ ├── handlers/ │ │ │ │ └── send/ │ │ │ │ └── handlers/ │ │ │ │ ├── one/ │ │ │ │ │ ├── configs/ │ │ │ │ │ │ └── one.ts │ │ │ │ │ ├── routers/ │ │ │ │ │ │ └── get.ts │ │ │ │ │ └── urls.ts │ │ │ │ └── third/ │ │ │ │ ├── configs/ │ │ │ │ │ └── third.ts │ │ │ │ ├── routers/ │ │ │ │ │ └── get.ts │ │ │ │ └── urls.ts │ │ │ ├── middlewares/ │ │ │ │ ├── configs/ │ │ │ │ │ └── mad.ts │ │ │ │ ├── fuck.js │ │ │ │ ├── get.ts │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ └── routers/ │ │ │ ├── fuck.js │ │ │ ├── get.ts │ │ │ ├── post.ts │ │ │ └── put.js │ │ ├── component.middleware/ │ │ │ ├── configs/ │ │ │ │ └── upload.ts │ │ │ ├── middlewares/ │ │ │ │ ├── delete.ts │ │ │ │ ├── fuck.js │ │ │ │ ├── get.ts │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ └── routers/ │ │ │ ├── fuck.js │ │ │ ├── get.ts │ │ │ ├── post.ts │ │ │ └── put.js │ │ ├── component.middleware.all/ │ │ │ ├── middlewares/ │ │ │ │ ├── all.ts │ │ │ │ └── fuck.js │ │ │ └── routers/ │ │ │ ├── all.js │ │ │ └── fuck.js │ │ ├── component.models/ │ │ │ ├── conditions/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.ts │ │ │ │ ├── post.ts │ │ │ │ └── put.js │ │ │ ├── configs/ │ │ │ │ └── test.js │ │ │ ├── errors/ │ │ │ │ ├── dir/ │ │ │ │ │ └── .gitkeep │ │ │ │ ├── no │ │ │ │ └── vig.js │ │ │ ├── events/ │ │ │ │ ├── hello.ts │ │ │ │ └── send.ts │ │ │ ├── fallbacks/ │ │ │ │ ├── condition.js │ │ │ │ ├── fuck.js │ │ │ │ ├── policy.js │ │ │ │ └── validation.js │ │ │ ├── middlewares/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ ├── models/ │ │ │ │ ├── Pet.js │ │ │ │ └── User.js │ │ │ ├── pagers/ │ │ │ │ ├── get.ts │ │ │ │ └── post.ts │ │ │ ├── policies/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ ├── routers/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.ts │ │ │ │ ├── post.ts │ │ │ │ └── put.js │ │ │ └── validators/ │ │ │ ├── delete.js │ │ │ ├── get.js │ │ │ ├── options.js │ │ │ ├── post.js │ │ │ └── put.js │ │ ├── component.nomethod/ │ │ │ └── routers/ │ │ │ └── all.js │ │ ├── component.policies/ │ │ │ ├── definitions/ │ │ │ │ ├── fallbacks/ │ │ │ │ │ └── ok.ts │ │ │ │ └── policies/ │ │ │ │ ├── fail.ts │ │ │ │ ├── ok.ts │ │ │ │ └── test.ts │ │ │ ├── fallbacks/ │ │ │ │ └── policy.js │ │ │ ├── policies/ │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ └── routers/ │ │ │ ├── get.js │ │ │ ├── post.js │ │ │ └── put.js │ │ ├── component.sessions/ │ │ │ ├── routers/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.ts │ │ │ │ ├── post.ts │ │ │ │ └── put.js │ │ │ ├── sessions/ │ │ │ │ └── all.ts │ │ │ └── urls.ts │ │ ├── component.templates/ │ │ │ ├── configs/ │ │ │ │ └── test.ts │ │ │ ├── handlers/ │ │ │ │ ├── a.ts │ │ │ │ └── send/ │ │ │ │ ├── handlers/ │ │ │ │ │ └── send/ │ │ │ │ │ ├── handlers/ │ │ │ │ │ │ └── send/ │ │ │ │ │ │ ├── routers/ │ │ │ │ │ │ │ └── get.ts │ │ │ │ │ │ └── urls.ts │ │ │ │ │ ├── routers/ │ │ │ │ │ │ └── get.ts │ │ │ │ │ └── urls.ts │ │ │ │ ├── prefix.ts │ │ │ │ ├── routers/ │ │ │ │ │ └── get.ts │ │ │ │ ├── templates/ │ │ │ │ │ └── views/ │ │ │ │ │ └── h2.html │ │ │ │ └── urls.ts │ │ │ ├── middlewares/ │ │ │ │ ├── fuck.ts │ │ │ │ ├── get.ts │ │ │ │ ├── post.ts │ │ │ │ └── put.ts │ │ │ ├── pagers/ │ │ │ │ ├── get.ts │ │ │ │ └── post.ts │ │ │ ├── policies/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.ts │ │ │ │ └── put.js │ │ │ ├── routers/ │ │ │ │ ├── delete.ts │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ ├── templates/ │ │ │ │ ├── filters/ │ │ │ │ │ └── name.js │ │ │ │ └── views/ │ │ │ │ └── layout.html │ │ │ └── urls.ts │ │ ├── component.urls/ │ │ │ ├── conditions/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.ts │ │ │ │ ├── post.ts │ │ │ │ └── put.js │ │ │ ├── configs/ │ │ │ │ └── test.js │ │ │ ├── errors/ │ │ │ │ ├── dir/ │ │ │ │ │ └── .gitkeep │ │ │ │ ├── no │ │ │ │ └── vig.js │ │ │ ├── events/ │ │ │ │ ├── hello.ts │ │ │ │ └── send.ts │ │ │ ├── fallbacks/ │ │ │ │ ├── condition.js │ │ │ │ ├── fuck.js │ │ │ │ ├── policy.js │ │ │ │ └── validation.js │ │ │ ├── handlers/ │ │ │ │ ├── a.ts │ │ │ │ └── send/ │ │ │ │ ├── handlers/ │ │ │ │ │ └── send/ │ │ │ │ │ ├── handlers/ │ │ │ │ │ │ └── send/ │ │ │ │ │ │ ├── routers/ │ │ │ │ │ │ │ └── get.ts │ │ │ │ │ │ └── urls.ts │ │ │ │ │ ├── routers/ │ │ │ │ │ │ └── get.ts │ │ │ │ │ └── urls.ts │ │ │ │ ├── routers/ │ │ │ │ │ └── get.ts │ │ │ │ └── urls.ts │ │ │ ├── middlewares/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ ├── models/ │ │ │ │ ├── Pet.js │ │ │ │ └── User.js │ │ │ ├── pagers/ │ │ │ │ ├── get.ts │ │ │ │ └── post.ts │ │ │ ├── policies/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ ├── prefix.ts │ │ │ ├── routers/ │ │ │ │ ├── delete.ts │ │ │ │ ├── fuck.js │ │ │ │ ├── get.js │ │ │ │ ├── post.js │ │ │ │ └── put.js │ │ │ ├── templates/ │ │ │ │ ├── filters/ │ │ │ │ │ └── name.ts │ │ │ │ └── views/ │ │ │ │ └── layout.html │ │ │ ├── urls.ts │ │ │ └── validators/ │ │ │ ├── delete.js │ │ │ ├── get.js │ │ │ ├── options.js │ │ │ ├── post.js │ │ │ └── put.js │ │ ├── component.websockets/ │ │ │ ├── configs/ │ │ │ │ ├── session.ts │ │ │ │ └── upload.ts │ │ │ ├── routers/ │ │ │ │ ├── fuck.js │ │ │ │ ├── get.ts │ │ │ │ ├── post.ts │ │ │ │ └── put.js │ │ │ ├── sessions/ │ │ │ │ └── all.ts │ │ │ └── websockets/ │ │ │ ├── broadcast.ts │ │ │ ├── enter.ts │ │ │ ├── false.ts │ │ │ ├── get.ts │ │ │ ├── leave.ts │ │ │ ├── post.ts │ │ │ ├── put.ts │ │ │ └── user.ts │ │ ├── configs/ │ │ │ └── test.js │ │ ├── errors/ │ │ │ ├── dir/ │ │ │ │ └── .gitkeep │ │ │ ├── no │ │ │ └── vig.js │ │ ├── errorsHandlers.ts │ │ ├── eventsHandlers.ts │ │ ├── fallbacks/ │ │ │ ├── ok.js │ │ │ └── test.js │ │ ├── fixtures/ │ │ │ ├── events.js │ │ │ └── events.once.js │ │ ├── models/ │ │ │ ├── Pet.js │ │ │ └── User.js │ │ ├── nomethodHandlers.ts │ │ ├── nourlsHandlers.ts │ │ ├── policies/ │ │ │ ├── ok.ts │ │ │ └── test.ts │ │ ├── policiesHandler.ts │ │ ├── prefixHandlers.ts │ │ ├── routersHandler.ts │ │ ├── uploader/ │ │ │ ├── a.txt │ │ │ └── b.txt │ │ ├── uploadersHandlers.ts │ │ └── validationsHandlers.ts │ ├── error.test.ts │ ├── handlers.test.ts │ ├── index.test.ts │ ├── inheritance.test.ts │ ├── middlewares.test.ts │ ├── nomethod.test.ts │ ├── pager.test.ts │ ├── policies.test.ts │ ├── prefix.test.ts │ ├── typings.d.test.ts │ └── validations.test.ts ├── tsconfig.json └── tslint.json
SYMBOL INDEX (170 symbols across 30 files)
FILE: src/Components/HTTP.ts
class HTTP (line 1) | class HTTP {
FILE: src/Components/VBase.ts
method constructor (line 43) | constructor(basePath: string) {
method toAsync (line 47) | public toAsync(cb, self) {
method toMethods (line 54) | public toMethods() {
method get (line 65) | public get() {
method set (line 69) | public set(data) {
method getFiles (line 76) | public getFiles() {
method reset (line 80) | public reset() {
method addFile (line 85) | public addFile(file: string = "") {
method getFile (line 91) | public getFile(file: string): object {
method extends (line 99) | public extends(name: string, json: object, data: any = {}) {
method generate (line 108) | public generate(data = {}) {
method loadOn (line 126) | public loadOn() {
method parseDir (line 130) | public parseDir(dir = "") {
method parseFile (line 137) | public parseFile(dir, file) {
method dirReader (line 158) | public dirReader(dir, iterator) {
method load (line 182) | public load(dir: any = "", data = {}) {
method _filter (line 199) | protected _filter(file: string) {
FILE: src/Components/VConfig.ts
class VConfig (line 8) | class VConfig extends VBase {
method constructor (line 9) | constructor(path) {
method isType (line 13) | public isType(item: any): boolean {
method parse (line 17) | public parse(scope) {
FILE: src/Components/VError.ts
class VError (line 12) | class VError extends VBase {
method constructor (line 17) | constructor(basePath = "", locale = "zh-CN") {
method isType (line 24) | public isType(item: any): boolean {
method set (line 28) | public set(data) {
method parse (line 33) | public parse(scope) {
method generate (line 40) | public generate(locale: string = "zh-CN", filesOnly = true): object {
FILE: src/Components/VEvent.ts
class VEventReader (line 8) | class VEventReader extends VBase {
method constructor (line 10) | constructor(basePath) {
method isType (line 15) | public isType(item: any): boolean {
method run (line 19) | public async run(key, args) {
FILE: src/Components/VHTTPBase.ts
class VHTTPBase (line 12) | class VHTTPBase extends VBase {
method constructor (line 15) | constructor(path) {
method isType (line 21) | public isType(item: any): boolean {
method check (line 25) | public check(req) {
method checkEx (line 30) | public checkEx(req, scope) {
method getDefinition (line 47) | public getDefinition(handler, name, scope) {
method setFailureHandler (line 65) | public setFailureHandler(handler) {
method extend (line 69) | public extend(method, handler) {
method getFallback (line 80) | public getFallback(req, scope) {
method process (line 91) | public async process(req, res, scope): Promise<boolean> {
method onPassed (line 108) | public async onPassed(req, res, scope, info, cb) {
method onAuthorFailed (line 116) | public onAuthorFailed(message, req, res, scope): boolean {
method _onProcess (line 125) | protected async _onProcess(func, req, res, scope): Promise<boolean> {
FILE: src/Components/VMiddleware.ts
class VMiddleware (line 16) | class VMiddleware extends VHTTPBase {
method constructor (line 17) | constructor(path = "") {
method process (line 22) | public async process(req, res, scope): Promise<boolean> {
FILE: src/Components/VModel.ts
class VModel (line 10) | class VModel extends VBase {
method fetch (line 11) | public static async fetch(config, options) {
method prepare (line 18) | public static async prepare(config, options) {
method constructor (line 49) | constructor(basePath = "") {
method parse (line 54) | public parse(scope) {
method isType (line 60) | public isType(item: any): boolean {
method loadOn (line 64) | public loadOn(data = null) {
FILE: src/Components/VRouter.ts
class VRouter (line 7) | class VRouter extends VHTTPBase {
method constructor (line 8) | constructor(path = "") {
method run (line 13) | public async run(req, res, scope): Promise<any> {
method _run (line 21) | protected async _run(func, req, res, scope): Promise<any> {
FILE: src/Components/VWebSocket.ts
class VWebSocket (line 9) | class VWebSocket extends VBase {
method constructor (line 10) | constructor(path) {
method isType (line 15) | public isType(item: any): boolean {
method run (line 19) | public async run(event, message, ws, req, scope) {
FILE: src/DefinitionParsers/VFallbackDefinition.ts
class VFallbackDefinition (line 7) | class VFallbackDefinition extends VBase {
method constructor (line 8) | constructor(path) {
method isType (line 12) | public isType(item: any): boolean {
FILE: src/DefinitionParsers/VPolicyDefinition.ts
class VPolicyDefinition (line 8) | class VPolicyDefinition extends VBase {
method constructor (line 9) | constructor(path) {
method isType (line 13) | public isType(item: any): boolean {
FILE: src/MiddlewareParsers/VBody.ts
class VBody (line 10) | class VBody extends VHTTPBase {
method constructor (line 11) | constructor(path) {
method isType (line 16) | public isType(item: any): boolean {
method file (line 20) | public file(req) {
method parse (line 27) | public async parse(req, res): Promise<boolean> {
FILE: src/MiddlewareParsers/VCondition.ts
class VCondition (line 7) | class VCondition extends VHTTPBase {
method constructor (line 8) | constructor(path) {
FILE: src/MiddlewareParsers/VFallback.ts
class VFallback (line 7) | class VFallback extends VHTTPBase {
method constructor (line 8) | constructor(path) {
method isType (line 13) | public isType(item: any): boolean {
FILE: src/MiddlewareParsers/VFile.ts
class VFile (line 5) | class VFile {
method cloud (line 8) | public cloud(req) {
method attach (line 32) | public attach(app) {
method use (line 36) | public use() {
method _isError (line 42) | public _isError(err, reject, cb = null) {
FILE: src/MiddlewareParsers/VPager.ts
class VPager (line 19) | class VPager extends VHTTPBase {
method constructor (line 20) | constructor(path) {
method isType (line 24) | public isType(item: any): boolean {
method toNumber (line 28) | public toNumber(value) {
method parse (line 39) | public async parse(req, res, scope): Promise<boolean> {
FILE: src/MiddlewareParsers/VPolicy.ts
class VPolicy (line 7) | class VPolicy extends VHTTPBase {
method constructor (line 8) | constructor(path = "") {
method isType (line 13) | public isType(item: any): boolean {
FILE: src/MiddlewareParsers/VSession.ts
class VSession (line 15) | class VSession extends VHTTPBase {
method constructor (line 16) | constructor(path) {
method isType (line 21) | public isType(item: any): boolean {
method parse (line 25) | public async parse(req, res, scope): Promise<boolean> {
FILE: src/MiddlewareParsers/VValidator.ts
class VValidator (line 9) | class VValidator extends VHTTPBase {
method constructor (line 12) | constructor(path = "") {
method isType (line 18) | public isType(item: any): boolean {
method process (line 36) | public async process(req, res, scope = null): Promise<boolean> {
method processObject (line 48) | public async processObject(handler, req, res, scope): Promise<boolean> {
FILE: src/Templates/Filter.ts
class Filter (line 2) | class Filter extends VBase {
method constructor (line 3) | constructor(path) {
method isType (line 7) | public isType(item: any): boolean {
FILE: src/Templates/VTemplate.ts
class VTemplate (line 18) | class VTemplate extends VBase {
method constructor (line 25) | constructor(dir) {
method isType (line 33) | public isType(item: any): boolean {
method getEnv (line 37) | public getEnv() {
method render (line 57) | public render(data, template, ext) {
method setParent (line 61) | public setParent(p: VTemplate) {
method getFilters (line 66) | public getFilters() {
method getViews (line 76) | public getViews() {
FILE: src/VDefinition.ts
class VDefinition (line 5) | class VDefinition {
method constructor (line 8) | constructor(path: string) {
method parse (line 17) | public parse(scope) {
method set (line 33) | public set(data) {
FILE: src/VEvent.ts
class VEvent (line 2) | class VEvent {
method getInstance (line 3) | public static getInstance() {
method constructor (line 19) | private constructor() {
method add (line 32) | public add(events, isOnce = true) {
method send (line 59) | public send(...args) {
method on (line 69) | public on(event, handler) {
method once (line 78) | public once(event, handler) {
method _on (line 82) | private _on(event, handler, listeners) {
method _processEvent (line 101) | private async _processEvent(handlers, params) {
method _onEvent (line 109) | private async _onEvent(...args) {
FILE: src/VHandler.ts
class VHandler (line 22) | class VHandler {
method constructor (line 68) | constructor(urls: string[] = null, path: string = "", prefix = "") {
method requireFile (line 124) | public requireFile(name: string) {
method setUrls (line 139) | public setUrls(urls: string[]) {
method setParent (line 143) | public setParent(p: VHandler) {
method setPrefix (line 155) | public setPrefix(prefix) {
method update (line 159) | public update(k: string, v) {
method extend (line 165) | public extend(method, cb) {
method set (line 169) | public set(config) {
method getScope (line 205) | public getScope() {
method updateFallbacks (line 209) | public updateFallbacks() {
method attach (line 223) | public attach(app) {
method loadStaticScope (line 241) | public loadStaticScope() {
method eventPrepare (line 252) | public eventPrepare() {
method websocketPrepare (line 266) | public websocketPrepare() {
method getFixedScope (line 274) | public getFixedScope() {
method checkMutable (line 292) | public checkMutable(module) {
method processMuted (line 296) | public processMuted() {
method run (line 303) | public async run(req, res) {
method notFound (line 376) | public notFound(error, req, res) {
method wsEvent (line 381) | public async wsEvent(event, message, ws, req) {
method toJSON (line 399) | public toJSON() {
method initChildren (line 412) | private initChildren() {
method loadDirectory (line 426) | private loadDirectory(dir: string) {
FILE: src/VService.ts
class VService (line 11) | class VService {
method constructor (line 13) | constructor(options: any = {}) {
method defaultRun (line 19) | public defaultRun() {
method start (line 24) | public start(app, cb) {
FILE: src/VWSServer.ts
class VWSServer (line 8) | class VWSServer {
method getInstance (line 13) | public static getInstance(): VWSServer {
method constructor (line 26) | private constructor() {
method addEventListener (line 28) | public addEventListener(event: string, handler: VHandler) {
method broadcast (line 39) | public broadcast(data, filter) {
method onEvent (line 51) | public async onEvent(event, ws, req) {
method onEnter (line 58) | public async onEnter(ws, req) {
method onLeave (line 62) | public async onLeave(ws, req) {
method onEvents (line 66) | public onEvents(ws, req) {
method start (line 86) | public start(server: Server) {
FILE: test/Components/VBase.test.ts
class NewBase (line 8) | class NewBase extends VBase {
method isType (line 9) | public isType(): boolean {
FILE: test/Components/VHTTPBase.test.ts
class VHTTP (line 10) | class VHTTP extends VHTTPBase {
method constructor (line 11) | constructor(path = "") {
method isType (line 15) | public isType(item: any): boolean {
FILE: test/VEvent.test.ts
function aaa (line 108) | function aaa() {
Condensed preview — 355 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (236K chars).
[
{
"path": ".editorconfig",
"chars": 171,
"preview": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newli"
},
{
"path": ".gitignore",
"chars": 94,
"preview": "coverage/\nnode_modules/\nnpm-debug.log\n.nyc_output\n.tmp\n.vscode\nlib\nuploaded\npackage-lock.json\n"
},
{
"path": ".travis.yml",
"chars": 289,
"preview": "language: node_js\nnode_js:\n - '13'\n - '12'\n - '11'\n - '10'\n - '9'\n - '8'\nscript:\n - npm run build # build\n - np"
},
{
"path": "LICENSE",
"chars": 567,
"preview": "Copyright 2016 calidion <caldiion@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may no"
},
{
"path": "README.md",
"chars": 5841,
"preview": "# (this project is deprecated in favor of the new fast, simple, async web framework for nodejs: [aex](https://github.com"
},
{
"path": "demo/chapter-1/README.md",
"chars": 1587,
"preview": "# 最简服务器创建与URL机制讲解\n\nvig框架的目标是快速的完成Web业务的开发,同时提升模块化水平。\n\n目标听起来很完美,如果无法付之行动,那么就是没有意义的。\n\n所以在这个系列文章中,我们将会陆续介绍vig框架的使用。\n\n这一节我们介"
},
{
"path": "demo/chapter-1/index.js",
"chars": 324,
"preview": "var app = require('express')();\nvar vig = require('vig');\nvig.init(app);\nvig.addHandler(app, {\n prefix: '/demo',\n urls"
},
{
"path": "demo/chapter-1/package.json",
"chars": 327,
"preview": "{\n \"name\": \"demo\",\n \"version\": \"1.0.0\",\n \"description\": \"vig框架的目标是快速的完成Web业务的开发,同时提升模块化水平。目标听起来很完美,如果无法付之行动,那么就是没有意义的"
},
{
"path": "demo/chapter-2/README.md",
"chars": 3124,
"preview": "# vig对HTTP方法的支持与提供的几种处理机制介绍\n\n上一讲我们讲到了vig的url机制里的:\n\n1. 别名机制\n2. 前缀机制\n\n这一讲我们来讲解vig的:\n\n1. 增强机制\n2. 增强机制的HTTP处理方式\n3. vig api的规"
},
{
"path": "demo/chapter-2/all.js",
"chars": 132,
"preview": "module.exports = {\n prefix: '/all',\n urls: ['/'],\n routers: {\n all: function (req, res) {\n res.send('all');\n "
},
{
"path": "demo/chapter-2/get-set.js",
"chars": 199,
"preview": "module.exports = {\n prefix: '/get-set',\n urls: ['/'],\n routers: {\n get: function (req, res) {\n res.send('get'"
},
{
"path": "demo/chapter-2/index.js",
"chars": 279,
"preview": "var app = require('express')();\nvar vig = require('vig');\nvar all = require('./all');\nvar gs = require('./get-set');\nvig"
},
{
"path": "demo/chapter-2/package.json",
"chars": 239,
"preview": "{\n \"name\": \"chapter-2\",\n \"version\": \"1.0.0\",\n \"description\": \"上一讲我们讲到了vig的url机制里的: 1、别名机制 2、前缀机制\",\n \"main\": \"index.j"
},
{
"path": "demo/chapter-3/README.md",
"chars": 2312,
"preview": "# 通过vig实现对输入数据的校验与提取\n\n通常输入数据的校验对于程序的安全性来讲是非常重要的,但是检验数据通常又会变成非常无聊、重复、浪费时间的事情。\n所以vig框架希望能将开发者从这部分工作中解脱出来。\n因此提供了validations"
},
{
"path": "demo/chapter-3/index.js",
"chars": 229,
"preview": "var app = require('express')();\nvar vig = require('vig');\nvar query = require('./query');\nvig.init(app);\nvig.addHandler("
},
{
"path": "demo/chapter-3/package.json",
"chars": 432,
"preview": "{\n \"name\": \"chapter-3\",\n \"version\": \"1.0.0\",\n \"description\": \"通常输入数据的校验对于程序的安全性来讲是非常重要的,但是检验数据通常又会变成非常无聊、重复、浪费时间的事情。 "
},
{
"path": "demo/chapter-3/query.js",
"chars": 525,
"preview": "module.exports = {\n prefix: '/query',\n urls: ['/'],\n routers: {\n all: function (req, res) {\n var extracted = "
},
{
"path": "demo/chapter-4/README.md",
"chars": 1384,
"preview": "# 通过vig实现对输入数据的校验详解\n\n上一讲我们讲到了数据校验的基本规则与提取方法,但是我们只讲到了int类型的校验。\n这一讲我们再详细的讲解vig更加强大的校验机制。\n\n# vig校验的类型与类型外的特殊方法讲解\n\n除了校验类型之外,"
},
{
"path": "demo/chapter-4/alias.js",
"chars": 577,
"preview": "module.exports = {\n prefix: '/alias',\n urls: ['/'],\n routers: {\n all: function (req, res) {\n var extracted = "
},
{
"path": "demo/chapter-4/email.js",
"chars": 543,
"preview": "module.exports = {\n prefix: '/email',\n urls: ['/'],\n routers: {\n all: function (req, res) {\n var extracted = "
},
{
"path": "demo/chapter-4/enum.js",
"chars": 584,
"preview": "module.exports = {\n prefix: '/enum',\n urls: ['/'],\n routers: {\n all: function (req, res) {\n var extracted = r"
},
{
"path": "demo/chapter-4/index.js",
"chars": 480,
"preview": "var app = require('express')();\nvar vig = require('vig');\nvar email = require('./email');\nvar length = require('./length"
},
{
"path": "demo/chapter-4/length.js",
"chars": 622,
"preview": "module.exports = {\n prefix: '/length',\n urls: ['/'],\n routers: {\n all: function (req, res) {\n var extracted ="
},
{
"path": "demo/chapter-4/package.json",
"chars": 345,
"preview": "{\n \"name\": \"chapter-4\",\n \"version\": \"1.0.0\",\n \"description\": \"上一讲我们讲到了数据校验的基本规则与提取方法,但是我们只讲到了int类型的校验。 这一讲我们再详细的讲解vig"
},
{
"path": "demo/chapter-4/password.js",
"chars": 647,
"preview": "module.exports = {\n prefix: '/password',\n urls: ['/'],\n routers: {\n all: function (req, res) {\n var extracted"
},
{
"path": "demo/chapter-5/README.md",
"chars": 844,
"preview": "# 通过vig实现对输入数据的校验详解(二)\n\n上一讲我们讲到了几个重要的类型与检测方法,这一讲,我们继续介绍常用用的数据类型的校验。\n\n\n## 对移动电话号码的检验\n\n\n表达形式:\n\n```\nphone: {\n type: 'phone"
},
{
"path": "demo/chapter-5/index.js",
"chars": 289,
"preview": "var app = require('express')();\nvar vig = require('vig');\nvar phone = require('./phone');\nvar regex = require('./regex')"
},
{
"path": "demo/chapter-5/package.json",
"chars": 319,
"preview": "{\n \"name\": \"chapter-5\",\n \"version\": \"1.0.0\",\n \"description\": \"上一讲我们讲到了几个重要的类型与检测方法,这一讲,我们继续介绍常用用的数据类型的校验。\",\n \"main\":"
},
{
"path": "demo/chapter-5/phone.js",
"chars": 545,
"preview": "module.exports = {\n prefix: '/phone',\n urls: ['/'],\n routers: {\n all: function (req, res) {\n var extracted = "
},
{
"path": "demo/chapter-5/regex.js",
"chars": 600,
"preview": "module.exports = {\n prefix: '/regex',\n urls: ['/'],\n routers: {\n all: function (req, res) {\n var extracted = "
},
{
"path": "demo/chapter-6/README.md",
"chars": 1900,
"preview": "# 通过vig实现对数据库的操作\n\n上面几讲我们讲了vig对输入数据的校验,这一讲我们来讲一下vig对数据库操作的支持。\n目前vig是基于waterline这个orm库来实现对数据库的操作的。\n原因是他足够简单易用,方便书写,代码清晰。\nw"
},
{
"path": "demo/chapter-6/config/waterline/adapter.js",
"chars": 153,
"preview": "var mongoAdapter = require('sails-mongo');\nvar mysqlAdapter = require('sails-mysql');\nmodule.exports = {\n mongo: mongoA"
},
{
"path": "demo/chapter-6/config/waterline/connections.js",
"chars": 280,
"preview": "\n// database connections\nvar mysql = require('./databases/mysql');\nvar mongodb = require('./databases/mongodb');\n\n\n// 这里"
},
{
"path": "demo/chapter-6/config/waterline/databases/mongodb.js",
"chars": 95,
"preview": "module.exports = {\n url: process.env.FORIM_MONGO_DB_URI || 'mongodb://127.0.0.1:27017/vig'\n};\n"
},
{
"path": "demo/chapter-6/config/waterline/databases/mysql.js",
"chars": 290,
"preview": "module.exports = {\n host: process.env.FORIM_MYSQL_DB_HOST || '127.0.0.1',\n user: process.env.FORIM_MYSQL_DB_USER || 'v"
},
{
"path": "demo/chapter-6/config/waterline/index.js",
"chars": 191,
"preview": "var adapter = require('./adapter');\nvar connections = require('./connections');\n\nmodule.exports = {\n adapters: adapter,"
},
{
"path": "demo/chapter-6/config.js",
"chars": 482,
"preview": "var mysqlConf = {\n adapter: 'mysql',\n};\nvar mongoConf = {\n adapter: 'mongo',\n url: process.env.FORIM_MONGO_DB_URI || "
},
{
"path": "demo/chapter-6/handlers/user/add.js",
"chars": 386,
"preview": "module.exports = {\n urls: ['/add'],\n routers: {\n get: function (req, res) {\n var username = \"username\" + new D"
},
{
"path": "demo/chapter-6/handlers/user/index.js",
"chars": 202,
"preview": "\nvar requires = ['add'];\nvar modules = [];\nfor (var i = 0; i < requires.length; i++) {\n modules = modules.concat(requir"
},
{
"path": "demo/chapter-6/index.js",
"chars": 585,
"preview": "var app = require('express')();\nvar vig = require('vig');\nvar user = require('./handlers/user');\nvar config = require('."
},
{
"path": "demo/chapter-6/models/User.js",
"chars": 327,
"preview": "module.exports = {\n connection: 'default', // 指定连接配置\n identity: 'user', // 指定的唯一标识\n schema: true, \n "
},
{
"path": "demo/chapter-6/package.json",
"chars": 408,
"preview": "{\n \"name\": \"chapter-6\",\n \"version\": \"1.0.0\",\n \"description\": \"上面几讲我们讲了vig对数据的操作,这一讲我们来讲一下vig对数据库操作的支持。 目前vig是基于waterl"
},
{
"path": "docs/README.md",
"chars": 47,
"preview": "# VIG 文档\r\n\r\n[Session和Cookie的配置](./Session.md)\r\n"
},
{
"path": "docs/Session.md",
"chars": 1831,
"preview": "VIG的Session与express的Session是一样的。\n唯一的不同就是VIG支持不同的页面使用不同的Session配置,而在express下面这种配置不同是无法实现的。\n下面我们介绍如何在VIG中配置Session。\n\n### S"
},
{
"path": "docs/progress.md",
"chars": 1786,
"preview": "# Web基本的业务模型内容与vig的完成目标与进度\n\n对于现在常见的Web模型,他通常包括如下的内容:\n\n1. 请求与返回(Request & Response) \n[由基础Web框架提供] \n2. 前端与后端(Frontend & "
},
{
"path": "docs/use.md",
"chars": 4019,
"preview": "\n### 生成错误\n\n```js\n// errors.js\nvar common = require('errorable-common');\nvar errorable = require('errorable');\nvar Genera"
},
{
"path": "package.json",
"chars": 2551,
"preview": "{\n \"name\": \"vig\",\n \"version\": \"1.0.0-rc-2\",\n \"description\": \"a component based web framework, focus on web basic logi"
},
{
"path": "ppt/intro.md",
"chars": 3994,
"preview": "`vig`\n===\n\n## 不一样的框架\n\n##### by [calidion](https://github.com/calidion)\n\n----\n\nvig是什么?\n===\n1. 一个新的框架\n2. 简单,轻量,高速\n3. 基于"
},
{
"path": "src/Components/HTTP.ts",
"chars": 383,
"preview": "export class HTTP {\n public static methods = [\n \"all\",\n \"checkout\",\n \"copy\",\n \"delete\",\n \"get\",\n \"hea"
},
{
"path": "src/Components/VBase.ts",
"chars": 4479,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\nimport * as fs from \"fs\";\nimport * as"
},
{
"path": "src/Components/VConfig.ts",
"chars": 418,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\nimport { VBase } from \"./VBase\";\n\nexp"
},
{
"path": "src/Components/VError.ts",
"chars": 1123,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\nimport { Generator } from \"errorable\""
},
{
"path": "src/Components/VEvent.ts",
"chars": 480,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\nimport { VBase } from \"./VBase\";\n\nexp"
},
{
"path": "src/Components/VHTTPBase.ts",
"chars": 3339,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\nimport { VBase } from \"./VBase\";\n\nimpo"
},
{
"path": "src/Components/VMiddleware.ts",
"chars": 953,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\nimport { VHTTPBase } from \"./VHTTPBase"
},
{
"path": "src/Components/VModel.ts",
"chars": 1762,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\nimport { VBase } from \"./VBase\";\nimpo"
},
{
"path": "src/Components/VRouter.ts",
"chars": 558,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\nimport { VHTTPBase } from \"./VHTTPBase"
},
{
"path": "src/Components/VWebSocket.ts",
"chars": 520,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\nimport { VBase } from \"./VBase\";\nimpo"
},
{
"path": "src/Components/index.ts",
"chars": 242,
"preview": "export * from \"./HTTP\";\nexport * from \"./VBase\";\nexport * from \"./VConfig\";\nexport * from \"./VEvent\";\nexport * from \"./V"
},
{
"path": "src/DefinitionParsers/VFallbackDefinition.ts",
"chars": 334,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\nimport { VBase } from \"../Components/V"
},
{
"path": "src/DefinitionParsers/VPolicyDefinition.ts",
"chars": 332,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\nimport { VBase } from \"../Components/"
},
{
"path": "src/MiddlewareParsers/VBody.ts",
"chars": 1751,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\nimport { VHTTPBase } from \"../Componen"
},
{
"path": "src/MiddlewareParsers/VCondition.ts",
"chars": 289,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\nimport { VHTTPBase } from \"../Componen"
},
{
"path": "src/MiddlewareParsers/VFallback.ts",
"chars": 442,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\nimport { VHTTPBase } from \"../Componen"
},
{
"path": "src/MiddlewareParsers/VFile.ts",
"chars": 1188,
"preview": "import * as uploader from \"file-cloud-uploader\";\nimport * as async from \"async\";\nimport * as skipper from \"skipper\";\n\nex"
},
{
"path": "src/MiddlewareParsers/VLimitation.ts",
"chars": 0,
"preview": ""
},
{
"path": "src/MiddlewareParsers/VPager.ts",
"chars": 1290,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\n/**\n * @class VPager\n * VPager is a p"
},
{
"path": "src/MiddlewareParsers/VPolicy.ts",
"chars": 394,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\nimport { VHTTPBase } from \"../Componen"
},
{
"path": "src/MiddlewareParsers/VSession.ts",
"chars": 1591,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\nimport { VHTTPBase } from \"../Componen"
},
{
"path": "src/MiddlewareParsers/VValidator.ts",
"chars": 2529,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\nimport { VHTTPBase } from \"../Compone"
},
{
"path": "src/MiddlewareParsers/index.ts",
"chars": 220,
"preview": "export * from \"./VCondition\";\nexport * from \"./VValidator\";\nexport * from \"./VPolicy\";\nexport * from \"./VFallback\";\nexpo"
},
{
"path": "src/Templates/Filter.ts",
"chars": 239,
"preview": "import { VBase } from \"../Components/VBase\";\nexport class Filter extends VBase {\n constructor(path) {\n super(path);\n"
},
{
"path": "src/Templates/VTemplate.ts",
"chars": 1909,
"preview": "/**\n * Copyright(c) 2016 calidion <calidion@gmail.com>\n * Apache 2.0 Licensed\n */\n\nimport * as nunjucks from \"nunjucks\";"
},
{
"path": "src/VDefinition.ts",
"chars": 1164,
"preview": "import { resolve } from \"path\";\nimport { VFallbackDefinition as VFallback } from \"./DefinitionParsers/VFallbackDefinitio"
},
{
"path": "src/VEvent.ts",
"chars": 3016,
"preview": "import * as EventEmitter from \"events\";\nexport class VEvent {\n public static getInstance() {\n if (!VEvent.instance) "
},
{
"path": "src/VHandler.ts",
"chars": 12857,
"preview": "import * as fs from \"fs\";\nimport * as fsPath from \"path\";\nimport * as async from \"async\";\nimport * as _ from \"lodash\";\ni"
},
{
"path": "src/VService.ts",
"chars": 881,
"preview": "import { VWSServer } from \"./VWSServer\";\nimport * as http from \"http\";\nimport * as debug from \"debug\";\n\nconst print = de"
},
{
"path": "src/VWSServer.ts",
"chars": 2352,
"preview": "import * as WebSocket from \"ws\";\nimport { VHandler } from \"./VHandler\";\nimport { Server } from \"http\";\nimport * as debug"
},
{
"path": "src/index.ts",
"chars": 150,
"preview": "export * from \"./VService\";\nexport * from \"./VHandler\";\nexport * from \"./VEvent\";\nexport * from \"./Components\";\nexport *"
},
{
"path": "test/Components/VBase.test.ts",
"chars": 1952,
"preview": "import 'mocha';\nimport { VBase } from '../../src/Components/VBase';\n\nimport * as assert from 'assert';\nimport * as path "
},
{
"path": "test/Components/VCondition.test.ts",
"chars": 814,
"preview": "import \"mocha\";\nimport { VCondition } from \"../../src/MiddlewareParsers/VCondition\";\n\nimport * as assert from \"assert\";\n"
},
{
"path": "test/Components/VConfig.test.ts",
"chars": 700,
"preview": "import 'mocha';\nimport { VConfig } from '../../src/Components/VConfig';\n\nimport * as assert from 'assert';\nimport * as p"
},
{
"path": "test/Components/VError.test.ts",
"chars": 2935,
"preview": "// import 'mocha';\n\n// import * as assert from 'assert';\n// import * as path from 'path';\n// import * as fs from 'fs';\n\n"
},
{
"path": "test/Components/VFallback.test.ts",
"chars": 798,
"preview": "import 'mocha';\nimport { VFallback } from '../../src/MiddlewareParsers/VFallback';\n\nimport * as assert from 'assert';\nim"
},
{
"path": "test/Components/VHTTPBase.test.ts",
"chars": 1837,
"preview": "import 'mocha';\nimport { VHTTPBase } from '../../src/Components/VHTTPBase';\n\nimport * as assert from 'assert';\nimport * "
},
{
"path": "test/Components/VMiddleware.test.ts",
"chars": 739,
"preview": "import 'mocha';\nimport { VMiddleware } from '../../src/Components/VMiddleware';\n\nimport * as assert from 'assert';\nimpor"
},
{
"path": "test/Components/VPager.test.ts",
"chars": 715,
"preview": "import 'mocha';\nimport { VPager } from '../../src/MiddlewareParsers/VPager';\n\nimport * as assert from 'assert';\nimport *"
},
{
"path": "test/Components/VPolicy.test.ts",
"chars": 720,
"preview": "import 'mocha';\nimport { VPolicy } from '../../src/MiddlewareParsers/VPolicy';\n\nimport * as assert from 'assert';\nimport"
},
{
"path": "test/Components/VRouter.test.ts",
"chars": 735,
"preview": "import 'mocha';\nimport { VRouter } from '../../src/Components/VRouter';\n\nimport * as assert from 'assert';\nimport * as p"
},
{
"path": "test/Components/VValidator.test.ts",
"chars": 748,
"preview": "import 'mocha';\nimport { VValidator } from '../../src/MiddlewareParsers/VValidator';\n\nimport * as assert from 'assert';\n"
},
{
"path": "test/VEvent.test.ts",
"chars": 2488,
"preview": "import 'mocha';\nimport { VEvent } from '../src';\n\nimport * as assert from 'assert';\nimport * as path from 'path';\nimport"
},
{
"path": "test/VFailureDefinition.test.ts",
"chars": 2153,
"preview": "\"use strict\";\nvar assert = require(\"assert\");\nvar request = require(\"supertest\");\nvar express = require(\"express\");\nvar "
},
{
"path": "test/VFile.test.ts",
"chars": 1521,
"preview": "import 'mocha';\nimport { VFile } from '../src';\n\nimport * as express from 'express';\nimport * as request from 'supertest"
},
{
"path": "test/VHandler.test.ts",
"chars": 8614,
"preview": "import 'mocha';\nimport { VHandler, VRouter, VEvent} from '../src';\n\nimport * as assert from 'assert';\nimport * as path f"
},
{
"path": "test/VModel.prepare.test.ts",
"chars": 1514,
"preview": "import 'mocha';\nimport { VModel, VHandler } from '../src';\nvar assert = require('assert');\nvar path = require('path');\nv"
},
{
"path": "test/VService.test.ts",
"chars": 5502,
"preview": "import 'mocha';\n\nimport { VHandler, VService } from '../src';\n\nimport * as assert from 'assert';\nimport * as path from '"
},
{
"path": "test/VSession.test.ts",
"chars": 649,
"preview": "import 'mocha';\nimport { VHandler, VRouter } from '../src';\n\nimport * as assert from 'assert';\nimport * as path from 'pa"
},
{
"path": "test/VTemplate.test.ts",
"chars": 1654,
"preview": "import 'mocha';\nimport { VHandler, VRouter } from '../src';\n\nimport * as assert from 'assert';\nimport * as path from 'pa"
},
{
"path": "test/bodies.test.ts",
"chars": 6649,
"preview": "var assert = require(\"assert\");\nvar request = require(\"supertest\");\nvar express = require(\"express\");\nvar path = require"
},
{
"path": "test/config.test.ts",
"chars": 1286,
"preview": "var assert = require('assert');\nvar request = require('supertest');\nvar express = require('express');\nvar path = require"
},
{
"path": "test/data/component/conditions/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/conditions/get.ts",
"chars": 57,
"preview": "export = async (req, res, scope) => {\n return(false);\n};"
},
{
"path": "test/data/component/conditions/post.ts",
"chars": 56,
"preview": "export = async (req, res, scope) => {\n return(true);\n};"
},
{
"path": "test/data/component/conditions/put.js",
"chars": 20,
"preview": "module.exports = {};"
},
{
"path": "test/data/component/configs/test.js",
"chars": 31,
"preview": "module.exports = {\n a: '1'\n};\n"
},
{
"path": "test/data/component/errors/dir/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "test/data/component/errors/no",
"chars": 0,
"preview": ""
},
{
"path": "test/data/component/errors/vig.js",
"chars": 174,
"preview": "module.exports = {\n Vig: {\n Test: {\n Error: {\n messages: {\n 'zh-CN': 'Vig测试错误!',\n 'en-"
},
{
"path": "test/data/component/events/hello.ts",
"chars": 81,
"preview": "export = async(scope, cb) => {\n const {errors} = scope;\n cb('hello', errors);\n}"
},
{
"path": "test/data/component/events/send.ts",
"chars": 15,
"preview": "export = 'aaa';"
},
{
"path": "test/data/component/fallbacks/condition.js",
"chars": 122,
"preview": "module.exports = function (error, req, res) {\n res.status(403).send('Access Denied Due to Failure to conditions');\n"
},
{
"path": "test/data/component/fallbacks/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/fallbacks/policy.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/fallbacks/validation.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/handlers",
"chars": 0,
"preview": ""
},
{
"path": "test/data/component/middlewares/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/middlewares/get.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/middlewares/post.js",
"chars": 62,
"preview": "module.exports = function (req, res) {\n res.send('post');\n};\n"
},
{
"path": "test/data/component/middlewares/put.js",
"chars": 20,
"preview": "module.exports = {};"
},
{
"path": "test/data/component/models/Pet.js",
"chars": 193,
"preview": "module.exports = {\n identity: 'pet',\n attributes: {\n breed: 'string',\n type: 'string',\n name: 'string',\n\n "
},
{
"path": "test/data/component/models/User.js",
"chars": 205,
"preview": "module.exports = {\n identity: 'user',\n attributes: {\n firstName: 'string',\n lastName: 'string',\n\n // Add a re"
},
{
"path": "test/data/component/pagers/get.ts",
"chars": 15,
"preview": "export = true;\n"
},
{
"path": "test/data/component/pagers/post.ts",
"chars": 16,
"preview": "export = false;\n"
},
{
"path": "test/data/component/policies/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/policies/get.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/policies/post.js",
"chars": 62,
"preview": "module.exports = function (req, res) {\n res.send('post');\n};\n"
},
{
"path": "test/data/component/policies/put.js",
"chars": 20,
"preview": "module.exports = {};"
},
{
"path": "test/data/component/routers/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/routers/get.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component/routers/post.js",
"chars": 62,
"preview": "module.exports = function (req, res) {\n res.send('post');\n};\n"
},
{
"path": "test/data/component/routers/put.js",
"chars": 20,
"preview": "module.exports = {};"
},
{
"path": "test/data/component/validators/delete.js",
"chars": 84,
"preview": "module.exports = {\n required: [],\n cc : {\n\n },\n bb: {\n\n },\n aa: {\n \n }\n};\n"
},
{
"path": "test/data/component/validators/get.js",
"chars": 21,
"preview": "module.exports = {};\n"
},
{
"path": "test/data/component/validators/options.js",
"chars": 37,
"preview": "module.exports = {\n required: {}\n};\n"
},
{
"path": "test/data/component/validators/post.js",
"chars": 62,
"preview": "module.exports = function (req, res) {\n res.send('post');\n};\n"
},
{
"path": "test/data/component/validators/put.js",
"chars": 93,
"preview": "module.exports = {\n required: [],\n body : {\n\n },\n params: {\n\n },\n query: {\n \n }\n};\n"
},
{
"path": "test/data/component.bodies/asyncs/get.ts",
"chars": 77,
"preview": "export = async (req, res, scope) => {\n scope.asyncs = {\n get: true\n };\n}"
},
{
"path": "test/data/component.bodies/asyncs/post.ts",
"chars": 41,
"preview": "export = [async()=> {\n}, async() => {\n}];"
},
{
"path": "test/data/component.bodies/bodies/get.ts",
"chars": 31,
"preview": "export = {\n formdata: true\n};\n"
},
{
"path": "test/data/component.bodies/bodies/post.ts",
"chars": 31,
"preview": "export = {\n formdata: true\n};\n"
},
{
"path": "test/data/component.bodies/routers/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.bodies/routers/get.ts",
"chars": 143,
"preview": "var assert = require(\"assert\");\nexport = async (req, res, scope) => {\n assert(req.cookies);\n assert(scope.asyncs.get);"
},
{
"path": "test/data/component.bodies/routers/post.js",
"chars": 120,
"preview": "var assert = require(\"assert\");\nmodule.exports = function (req, res) {\n assert(!req.cookies);\n res.send(req.body);\n};\n"
},
{
"path": "test/data/component.bodies/routers/put.js",
"chars": 20,
"preview": "module.exports = {};"
},
{
"path": "test/data/component.bodies/sessions/get.ts",
"chars": 27,
"preview": "export = {\n cookie: true\n}"
},
{
"path": "test/data/component.bodies/sessions/put.ts",
"chars": 27,
"preview": "export = {\n cookie: true\n}"
},
{
"path": "test/data/component.inheritance/configs/upload.ts",
"chars": 22,
"preview": "export = {\n file: 1\n}"
},
{
"path": "test/data/component.inheritance/handlers/send/handlers/one/configs/one.ts",
"chars": 26,
"preview": "export = {\n one: true\n};\n"
},
{
"path": "test/data/component.inheritance/handlers/send/handlers/one/routers/get.ts",
"chars": 99,
"preview": "export = async (req, res, scope) => {\n console.log('inside one get');\n res.json(scope.configs);\n}"
},
{
"path": "test/data/component.inheritance/handlers/send/handlers/one/urls.ts",
"chars": 18,
"preview": "export = [\"/one\"];"
},
{
"path": "test/data/component.inheritance/handlers/send/handlers/third/configs/third.ts",
"chars": 28,
"preview": "export = {\n third: true\n};\n"
},
{
"path": "test/data/component.inheritance/handlers/send/handlers/third/routers/get.ts",
"chars": 95,
"preview": "export = async (req, res, scope) => {\n console.log('inside get');\n res.json(scope.configs);\n}"
},
{
"path": "test/data/component.inheritance/handlers/send/handlers/third/urls.ts",
"chars": 22,
"preview": "export = [\"/configs\"];"
},
{
"path": "test/data/component.inheritance/middlewares/configs/mad.ts",
"chars": 26,
"preview": "export = {\n mad: true\n};\n"
},
{
"path": "test/data/component.inheritance/middlewares/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.inheritance/middlewares/get.ts",
"chars": 60,
"preview": "export = async (req, res, scope) => {\n req.mid = 'mid';\n};\n"
},
{
"path": "test/data/component.inheritance/middlewares/post.js",
"chars": 62,
"preview": "module.exports = function (req, res) {\n res.send('post');\n};\n"
},
{
"path": "test/data/component.inheritance/middlewares/put.js",
"chars": 21,
"preview": "module.exports = {};\n"
},
{
"path": "test/data/component.inheritance/routers/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.inheritance/routers/get.ts",
"chars": 159,
"preview": "var assert = require(\"assert\");\n\nexport = async (req, res, scope) => {\n const {configs} = scope;\n assert(configs.uploa"
},
{
"path": "test/data/component.inheritance/routers/post.ts",
"chars": 158,
"preview": "var assert = require(\"assert\");\n\nexport = async (req, res, scope) => {\n const {configs} = scope;\n assert(configs.uploa"
},
{
"path": "test/data/component.inheritance/routers/put.js",
"chars": 21,
"preview": "module.exports = {};\n"
},
{
"path": "test/data/component.middleware/configs/upload.ts",
"chars": 22,
"preview": "export = {\n file: 1\n}"
},
{
"path": "test/data/component.middleware/middlewares/delete.ts",
"chars": 58,
"preview": "module.exports = function (req, res) {\n return false;\n};\n"
},
{
"path": "test/data/component.middleware/middlewares/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.middleware/middlewares/get.ts",
"chars": 60,
"preview": "export = async (req, res, scope) => {\n req.mid = 'mid';\n};\n"
},
{
"path": "test/data/component.middleware/middlewares/post.js",
"chars": 62,
"preview": "module.exports = function (req, res) {\n res.send('post');\n};\n"
},
{
"path": "test/data/component.middleware/middlewares/put.js",
"chars": 21,
"preview": "module.exports = {};\n"
},
{
"path": "test/data/component.middleware/routers/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.middleware/routers/get.ts",
"chars": 159,
"preview": "var assert = require(\"assert\");\n\nexport = async (req, res, scope) => {\n const {configs} = scope;\n assert(configs.uploa"
},
{
"path": "test/data/component.middleware/routers/post.ts",
"chars": 158,
"preview": "var assert = require(\"assert\");\n\nexport = async (req, res, scope) => {\n const {configs} = scope;\n assert(configs.uploa"
},
{
"path": "test/data/component.middleware/routers/put.js",
"chars": 21,
"preview": "module.exports = {};\n"
},
{
"path": "test/data/component.middleware.all/middlewares/all.ts",
"chars": 60,
"preview": "export = async (req, res, scope) => {\n req.mid = 'all';\n};\n"
},
{
"path": "test/data/component.middleware.all/middlewares/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.middleware.all/routers/all.js",
"chars": 63,
"preview": "module.exports = function (req, res) {\n res.send(req.mid);\n};\n"
},
{
"path": "test/data/component.middleware.all/routers/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.models/conditions/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.models/conditions/get.ts",
"chars": 56,
"preview": "export = async (req, res, scope) => {\n return false;\n};"
},
{
"path": "test/data/component.models/conditions/post.ts",
"chars": 55,
"preview": "export = async (req, res, scope) => {\n return true;\n};"
},
{
"path": "test/data/component.models/conditions/put.js",
"chars": 20,
"preview": "module.exports = {};"
},
{
"path": "test/data/component.models/configs/test.js",
"chars": 31,
"preview": "module.exports = {\n a: '1'\n};\n"
},
{
"path": "test/data/component.models/errors/dir/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "test/data/component.models/errors/no",
"chars": 0,
"preview": ""
},
{
"path": "test/data/component.models/errors/vig.js",
"chars": 174,
"preview": "module.exports = {\n Vig: {\n Test: {\n Error: {\n messages: {\n 'zh-CN': 'Vig测试错误!',\n 'en-"
},
{
"path": "test/data/component.models/events/hello.ts",
"chars": 81,
"preview": "export = async(scope, cb) => {\n const {errors} = scope;\n cb('hello', errors);\n}"
},
{
"path": "test/data/component.models/events/send.ts",
"chars": 15,
"preview": "export = 'aaa';"
},
{
"path": "test/data/component.models/fallbacks/condition.js",
"chars": 122,
"preview": "module.exports = function (error, req, res) {\n res.status(403).send('Access Denied Due to Failure to conditions');\n"
},
{
"path": "test/data/component.models/fallbacks/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.models/fallbacks/policy.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.models/fallbacks/validation.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.models/middlewares/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.models/middlewares/get.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.models/middlewares/post.js",
"chars": 62,
"preview": "module.exports = function (req, res) {\n res.send('post');\n};\n"
},
{
"path": "test/data/component.models/middlewares/put.js",
"chars": 20,
"preview": "module.exports = {};"
},
{
"path": "test/data/component.models/models/Pet.js",
"chars": 193,
"preview": "module.exports = {\n identity: 'pet',\n attributes: {\n breed: 'string',\n type: 'string',\n name: 'string',\n\n "
},
{
"path": "test/data/component.models/models/User.js",
"chars": 205,
"preview": "module.exports = {\n identity: 'user',\n attributes: {\n firstName: 'string',\n lastName: 'string',\n\n // Add a re"
},
{
"path": "test/data/component.models/pagers/get.ts",
"chars": 15,
"preview": "export = true;\n"
},
{
"path": "test/data/component.models/pagers/post.ts",
"chars": 16,
"preview": "export = false;\n"
},
{
"path": "test/data/component.models/policies/fuck.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
},
{
"path": "test/data/component.models/policies/get.js",
"chars": 61,
"preview": "module.exports = function (req, res) {\n res.send('get');\n};\n"
}
]
// ... and 155 more files (download for full content)
About this extraction
This page contains the full source code of the calidion/vig GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 355 files (179.6 KB), approximately 63.5k tokens, and a symbol index with 170 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.