zeanium-node
Advanced tools
Comparing version 0.4.29 to 0.5.0
{ | ||
"name": "zeanium-node", | ||
"version": "0.4.29", | ||
"version": "0.5.0", | ||
"description": "Zeanium for Node.js, simple http server and custome your business.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -1,2 +0,202 @@ | ||
# Zeanium-Node | ||
正在翻译中... | ||
# zeanium-node | ||
[English Document](https://github.com/yangyxu/Zeanium-Node/blob/master/README.md) | ||
## 介绍 | ||
zeanium-node是基于[zeanium](https://github.com/yangyxu/zeanium), 是专门为nodejs开发的后端框架,提供了基础的`cache`、`cli`、`database`、`io`、`net`、`parser`、`session`、`template`. 基本的OOP使用语法请访问https://github.com/yangyxu/zeanium. | ||
## 基础模块列表 | ||
- `cache`:有`数据库缓存`、`内存缓存`、`redis缓存`等三种cache的实现. | ||
- `cli`: 提供一系列基于zn命令行工具如`zn run`. | ||
- `database`: 提供不同数据库标准访问接口, 本框架已经提供基于mysql的实现方案, 也实现sql语句拼接及生成、mysql基于事件队列的事务机制、常见基础model实现及API操作. | ||
- `net`: 网络模块提供http、socket、web socket三种网络服务的实现接口,. | ||
zeanium-node http模块是基于MVC框架. | ||
```bash | ||
$ npm install zeanium-node -g | ||
``` | ||
Node.js >= 5.0.0 required. | ||
## 功能 | ||
- Http server base | ||
- Plugin customization | ||
- Dynamic development & deployment | ||
>This is very important feature, developer don't need restart http server when develop mode or release mode. If you do any change for project, the system will auto reload the newly code. | ||
- Using event queue to solve asynchronous | ||
- Support promise | ||
- Support middleware | ||
- Support SQL transaction | ||
- Support some Class(Model, Controller) inherit. | ||
- Customize model(M)&view(V)&controller(C) | ||
- Customize http handler router | ||
## Docs & Community | ||
- [Website && Documentations](https://www.zeanium.com) | ||
- [plugins](https://github.com/search?q=topic%3Azeanium-node-plugin&type=Repositories) | ||
## Getting Started | ||
```js | ||
//define database model | ||
zn.define(function () { | ||
//common data model | ||
var model = zn.db.common.model; | ||
//zn.Model is define. | ||
return zn.Model("zn_rights_user", { | ||
mixins: [ | ||
model.Base | ||
], | ||
//define property | ||
properties: { | ||
name: { | ||
value: null, //field data value | ||
type: ['varchar', 100], //field data type | ||
default: '' //field default value | ||
}, | ||
pwd: { | ||
value: null, | ||
type: ['varchar', 100], | ||
default: '' | ||
}, | ||
email: { | ||
value: null, | ||
type: ['varchar', 50], | ||
default: '' | ||
}, | ||
phone: { | ||
value: null, | ||
type: ['varchar', 20], | ||
default: '' | ||
}, | ||
address: { | ||
value: null, | ||
type: ['varchar', 250], | ||
default: '' | ||
}, | ||
avatarImg: { | ||
value: null, | ||
type: ['varchar', 100], | ||
default: '' | ||
}, | ||
lastLoginTime: { | ||
value: null, | ||
type: ['datetime'], | ||
format: "date_format({},'%Y-%c-%d %h:%i:%s')", | ||
default: null | ||
} | ||
} | ||
}); | ||
}) | ||
``` | ||
```js | ||
//define user controller | ||
zn.define(function () { | ||
//define controller name | ||
return zn.Controller('user',{ | ||
methods: { | ||
init: function (args){ | ||
//init | ||
this._action = this.action('zn_rights_user'); | ||
}, | ||
//define login action | ||
login: { | ||
method: 'GET/POST', //action method | ||
argv: { //action argv | ||
username: null, | ||
password: null | ||
}, | ||
value: function (request, response, chain){ | ||
this._action.selectOne(request.getValue()).then(function (user){ | ||
if(user){ | ||
request.session.user = user; | ||
response.success(user); | ||
} else { | ||
response.error('Username or password is incorrect.'); | ||
} | ||
}, function (error){ | ||
response.error(error.message); | ||
}); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
``` | ||
```js | ||
//define user Action | ||
zn.define(function () { | ||
return zn.Action({ | ||
methods: { | ||
getLoginInfo: function (userId){ | ||
} | ||
} | ||
}); | ||
}); | ||
``` | ||
## Try it | ||
```sh | ||
npm install zeanium-node -g | ||
git clone https://github.com/yangyxu/zeanium-node-demo.git | ||
cd zeanium-node-demo | ||
zn run config:zn.workspace.config.js | ||
``` | ||
The terminal will show the message for http server. | ||
## Create Workspace | ||
```sh | ||
zn create workspace workspace_demo | ||
``` | ||
## Create Application | ||
```sh | ||
zn create app app_demo | ||
``` | ||
## Install dependencies | ||
```sh | ||
npm install | ||
``` | ||
## Start Application | ||
```sh | ||
zn run config:xxx.config.js | ||
``` | ||
If you start server you will see the detail on console: | ||
```text | ||
2016-08-17 21:12:44.043 [INFO] [ Begin ] Scanning Path:../www/ | ||
2016-08-17 21:12:44.051 [INFO] Loading Application: ../www/__zn__ | ||
2016-08-17 21:12:44.059 [INFO] Register Project(Application): __zn__ | ||
2016-08-17 21:12:44.060 [INFO] [ End ] Scanning Path(Application:1):../www/ | ||
2016-08-17 21:12:44.060 [INFO] [ Begin ] Scanning Path:../bin/ | ||
2016-08-17 21:12:44.063 [INFO] [ End ] Scanning Path(Application:0):../bin/ | ||
2016-08-17 21:12:44.066 [INFO] http://0.0.0.0:8080 | ||
2016-08-17 21:12:44.068 [INFO] http://127.0.0.1:8080 | ||
2016-08-17 21:12:44.069 [INFO] You can press [ control + c ] to stop current zeanium server. | ||
``` | ||
## Documentation | ||
[http://www.zeanium.com](http://www.zeanium.com) | ||
## License | ||
[MIT](https://github.com/yangyxu/Zeanium-Node/blob/master/LICENSE) |
@@ -37,5 +37,4 @@ /** | ||
return { | ||
host: '0.0.0.0', | ||
host: this._argv.host || '0.0.0.0', | ||
port: this._argv.port || 8080, | ||
catalog: '/', | ||
onLoaded: function (){ | ||
@@ -42,0 +41,0 @@ zn.info('You can press [ control + c ] to stop current zeanium server.'); |
@@ -42,12 +42,14 @@ /** | ||
ApplicationController._methods_.forEach(function (method, index){ | ||
_member = ApplicationController.member(method); | ||
if(_member.meta.router!==null){ | ||
_router = _member.meta.router || _member.name; | ||
_router = node_path.normalize(zn.SLASH + (_self._deploy||'') + zn.SLASH + _key + zn.SLASH + _router); | ||
_self._routers[_router] = { | ||
controller: _controller, | ||
action: method, | ||
handler: _member, | ||
appContext: _self | ||
}; | ||
if(method!=='init'){ | ||
_member = ApplicationController.member(method); | ||
if(_member.meta.router!==null){ | ||
_router = _member.meta.router || _member.name; | ||
_router = node_path.normalize(zn.SLASH + (_self._deploy||'') + zn.SLASH + _key + zn.SLASH + _router); | ||
_self._routers[_router] = { | ||
controller: _controller, | ||
action: method, | ||
handler: _member, | ||
appContext: _self | ||
}; | ||
} | ||
} | ||
@@ -111,13 +113,15 @@ }); | ||
controller._methods_.forEach(function (method, index){ | ||
_member = controller.member(method); | ||
if(_member.meta.router!==null){ | ||
_router = _member.meta.router || _member.name; | ||
_router = node_path.normalize(zn.SLASH + (_config.deploy||'') + zn.SLASH + _key + zn.SLASH + _router); | ||
_routers[_router] = { | ||
controller: _controller, | ||
action: method, | ||
handler: _member, | ||
appContext: _self, | ||
validate: (_member.meta.validate !== undefined) ? _member.meta.validate : _validate | ||
}; | ||
if(method!="init"){ | ||
_member = controller.member(method); | ||
if(_member.meta.router!==null){ | ||
_router = _member.meta.router || _member.name; | ||
_router = node_path.normalize(zn.SLASH + (_config.deploy||'') + zn.SLASH + _key + zn.SLASH + _router); | ||
_routers[_router] = { | ||
controller: _controller, | ||
action: method, | ||
handler: _member, | ||
appContext: _self, | ||
validate: (_member.meta.validate !== undefined) ? _member.meta.validate : _validate | ||
}; | ||
} | ||
} | ||
@@ -124,0 +128,0 @@ }); |
@@ -60,8 +60,11 @@ zn.define([ | ||
return { | ||
host: '127.0.0.1', | ||
host: '0.0.0.0', | ||
port: 8888, | ||
catalog: '/webapps/', | ||
catalog: '/znapps/', | ||
watchCwd: '/src/', | ||
modules: null, | ||
timeout: 12000, | ||
mode: 'debug', //release, debug, view, | ||
reDeployDelay: 3000, | ||
CORS: true, | ||
mode: 'release', //release, debug, view, | ||
indexs: ['index.html', 'index.htm', 'default.html', 'default.htm'], | ||
@@ -90,5 +93,8 @@ session: { | ||
mapping: function (url, context, handler){ | ||
var _routers = context._routers, | ||
var _routers = context.getRouters(), | ||
_chain = new RequestHandlerChain(), | ||
_handler = null; | ||
console.log('Routers: ', Object.keys(_routers)); | ||
for(var key in _routers) { | ||
@@ -95,0 +101,0 @@ _handler = zn.extend({}, _routers[key]); |
zn.define(function () { | ||
return zn.Controller('server', { | ||
return zn.Controller('$', { | ||
methods: { | ||
init: function (serverContext){ | ||
this._serverContext = serverContext; | ||
}, | ||
redeploy: { | ||
method: 'GET/POST', | ||
value: function (request, response, chain){ | ||
this._serverContext.__delayDeploy(); | ||
response.success('redeploy success'); | ||
} | ||
}, | ||
apps: { | ||
method: 'GET/POST', | ||
value: function (request, response, chain){ | ||
response.success(Object.keys(this._serverContext._apps)); | ||
} | ||
} | ||
} | ||
@@ -7,0 +22,0 @@ }); |
@@ -20,2 +20,3 @@ /** | ||
var _app = _context._apps[_project]; | ||
if(!_app){ | ||
@@ -34,2 +35,3 @@ return response.writeURL(request.url), false; | ||
} | ||
return response.writePath(_app._config.root + zn.SLASH + _paths.join(zn.SLASH)), false; | ||
@@ -36,0 +38,0 @@ }, |
@@ -13,3 +13,6 @@ /** | ||
_chain = request.chain; | ||
response.upon('finish', ()=>this.__onRequestFinish(request, response)); | ||
response.upon('finish', function(){ | ||
this.__onRequestFinish(request, response); | ||
}.bind(this)); | ||
if(_chain && _chain.size>0){ | ||
@@ -16,0 +19,0 @@ response.applicationContext = _chain.applicationContext; |
@@ -14,2 +14,4 @@ /** | ||
var _package = require("../../../package.json"); | ||
return zn.Class('HttpServer', { | ||
@@ -50,2 +52,3 @@ statics: { | ||
if('OPTIONS' == request.method){ | ||
var _name = _package.name + '@' + _package.version; | ||
response.writeHead(200, { | ||
@@ -57,7 +60,7 @@ 'Access-Control-Allow-Origin': request.headers.origin, | ||
'Access-Control-Max-Age': '3600',//一个小时时间 | ||
'X-Powered-By': 'zeanium-node@1.2.0', | ||
'X-Powered-By': _name, | ||
'Content-Type': 'text/html;charset=utf-8', | ||
'Trailer': 'Content-MD5' | ||
}); | ||
response.write('<a href="https://github.com/yangyxu/Zeanium-Node">zeanium-node@1.2.0</a>'); | ||
response.write('<a href="https://github.com/yangyxu/Zeanium-Node">'+_name+'</a>'); | ||
response.addTrailers({'Content-MD5': zn.uuid()}); | ||
@@ -64,0 +67,0 @@ response.end(); |
@@ -11,4 +11,5 @@ /** | ||
'./RequestAcceptor', | ||
'./controller/HttpServerController', | ||
'../../session/MemorySessionManager' | ||
], function (chokidar, fs, os, path, Scanner, RequestAcceptor, MemorySessionManager) { | ||
], function (chokidar, fs, os, node_path, Scanner, RequestAcceptor, HttpServerController, MemorySessionManager) { | ||
@@ -38,2 +39,8 @@ var CONFIG = { | ||
init: function (args){ | ||
var _main = '', | ||
_modules = args.config.modules; | ||
if(_modules && _modules[0]){ | ||
_main = _modules[0]; | ||
} | ||
args.config.watchCwd = node_path.normalize(args.config.catalog + _main + args.config.watchCwd); | ||
var _config = args.config; | ||
@@ -57,5 +64,34 @@ this.sets(args); | ||
this.__scanWebPath(); | ||
this._baseRouters = this.__registerHttpServerController(); | ||
}, | ||
getRouters: function (){ | ||
return zn.extend(this._baseRouters, this._routers); | ||
}, | ||
__registerHttpServerController: function (){ | ||
var _key = HttpServerController.getMeta('controller') || ''; | ||
var _controller = new HttpServerController(this); | ||
var _member, | ||
_router, | ||
_routers = {}, | ||
_self = this; | ||
HttpServerController._methods_.forEach(function (method, index){ | ||
if(method!=='init'){ | ||
_member = HttpServerController.member(method); | ||
if(_member.meta.router!==null){ | ||
_router = _member.meta.router || _member.name; | ||
_router = node_path.normalize(zn.SLASH + _key + zn.SLASH + _router); | ||
_routers[_router] = { | ||
controller: _controller, | ||
action: method, | ||
handler: _member, | ||
appContext: _self | ||
}; | ||
} | ||
} | ||
}); | ||
return _routers; | ||
}, | ||
accept: function (serverRequest, serverResponse){ | ||
serverRequest.url = path.normalize(serverRequest.url); | ||
serverRequest.url = node_path.normalize(serverRequest.url); | ||
this._requestAcceptor.accept(serverRequest, serverResponse); | ||
@@ -66,2 +102,5 @@ }, | ||
}, | ||
registerRouters: function (routers){ | ||
return zn.extend(this._routers, routers), this; | ||
}, | ||
registerApplication: function (app){ | ||
@@ -86,6 +125,6 @@ if(!app){ return } | ||
_webPath = this._webPath; | ||
if(fs.existsSync(_webPath + CONFIG.APP)){ | ||
this._scanner.scanApplication(_webPath, '', function (app){ | ||
this.registerApplication(app); | ||
}.bind(this)).then(function (){ | ||
this.__onLoaded(_webPath); | ||
@@ -140,3 +179,3 @@ }.bind(this)); | ||
zn.debug(event + ': ' + _path); | ||
this._deployDelay = 3000; | ||
this._deployDelay = this._config.reDeployDelay || 3000; | ||
this.__doFileChange(_path); | ||
@@ -154,3 +193,3 @@ } | ||
this._changedFiles = []; | ||
this.__scanWebPath(true); | ||
return this.__scanWebPath(true); | ||
}, | ||
@@ -157,0 +196,0 @@ __doFileChange: function (path){ |
@@ -28,2 +28,3 @@ /** | ||
} | ||
var _url = node_url.parse(serverRequest.url, true).pathname, | ||
@@ -40,4 +41,4 @@ _handlerManager = null, | ||
_chain = _handlerManager.match(_url); | ||
//zn.info('Do [' + key + '] request handler : ' + _match); | ||
if(_chain){ | ||
zn.debug('[' + key + ']: ' + _url); | ||
return _handlerManager.accept(serverRequest, serverResponse, _chain); | ||
@@ -44,0 +45,0 @@ } |
@@ -9,3 +9,3 @@ /** | ||
'node:path' | ||
], function (html, mime, fs, path) { | ||
], function (html, mime, fs, node_path) { | ||
@@ -23,2 +23,3 @@ var CONTENT_TYPE = { | ||
var _htmlRender = new html.Render(); | ||
var _package = require("../../../package.json"); | ||
@@ -80,3 +81,3 @@ return zn.Class({ | ||
'Access-Control-Max-Age': '3600',//一个小时时间 | ||
'X-Powered-By': 'zeanium-node@1.2.0', | ||
'X-Powered-By': _package.name + '@' + _package.version, | ||
'Content-Type': 'application/json;charset=utf-8' | ||
@@ -88,4 +89,8 @@ }; | ||
'Content-Type': _self.__getContentType() | ||
}, _crossSetting); | ||
}); | ||
if(this._context._config.CORS){ | ||
_args = zn.overwrite(_args, _crossSetting); | ||
} | ||
if(_session){ | ||
@@ -147,3 +152,3 @@ if(_session.hasItem()){ | ||
writePath: function (_path, _encoding){ | ||
_path = path.normalize(_path).split('?')[0]; | ||
_path = node_path.normalize(_path).split('?')[0]; | ||
if(fs.existsSync(_path)){ | ||
@@ -163,3 +168,8 @@ fs.readFile(_path, _encoding, function(err, content){ | ||
} else { | ||
this.doIndex(); | ||
zn.error("Can't Open Path: ", _path); | ||
this.viewModel('_error', { | ||
code: 404, | ||
msg: '未找到资源文件: ', | ||
detail: '' | ||
}, true); | ||
} | ||
@@ -170,3 +180,3 @@ }, | ||
}, | ||
doIndex: function (){ | ||
doIndex: function (path){ | ||
var _basePath = this.__fixBasePath(); | ||
@@ -182,32 +192,39 @@ _mode = null, | ||
} | ||
_basePath = path.normalize(_basePath); | ||
_basePath = node_path.normalize(_basePath); | ||
if(!_mode){ | ||
_mode = this._context._config.mode; | ||
} | ||
if(_mode=='catalog'){ | ||
this.doCatalog(_basePath); | ||
} else { | ||
zn.each(this._context._config.indexs || [], function (index){ | ||
if(fs.existsSync(_basePath + index)){ | ||
_path = _basePath + index; | ||
return false; | ||
//release, debug, view, catalog | ||
switch (_mode) { | ||
case 'release': | ||
zn.each(this._context._config.indexs || [], function (index){ | ||
if(fs.existsSync(_basePath + index)){ | ||
_path = _basePath + index; | ||
return false; | ||
} | ||
}); | ||
if(_path){ | ||
this.writePath(_path); | ||
} else { | ||
if(!this._context._config.debug){ | ||
_basePath = this._request.url; | ||
} | ||
this.viewModel('_error', { | ||
code: 404, | ||
msg: '未找到资源文件: ' + _basePath, | ||
detail: '' | ||
}, true); | ||
} | ||
}); | ||
if(_path){ | ||
this.writePath(_path); | ||
} else { | ||
if(!this._context._config.debug){ | ||
_basePath = this._request.url; | ||
} | ||
this.viewModel('_error', { | ||
code: 404, | ||
msg: '未找到资源文件: ' + _basePath, | ||
detail: '' | ||
}, true); | ||
} | ||
break; | ||
case 'debug': | ||
this.success('正在完善中...'); | ||
break; | ||
case 'view': | ||
case 'catalog': | ||
this.doCatalog(_basePath); | ||
break; | ||
} | ||
}, | ||
doCatalog: function (src){ | ||
var _baseURL = path.normalize(this.request._pathname + zn.SLASH); | ||
var _baseURL = node_path.normalize(this.request._pathname + zn.SLASH); | ||
var _dirPath = src || this.__fixBasePath(); | ||
@@ -235,6 +252,6 @@ if(!fs.statSync(_dirPath).isDirectory()){ | ||
files = files.map(function(file){ | ||
if(fs.statSync(path.join(src, file)).isDirectory()){ | ||
file = path.basename(file) + zn.SLASH; | ||
if(fs.statSync(node_path.join(src, file)).isDirectory()){ | ||
file = node_path.basename(file) + zn.SLASH; | ||
}else{ | ||
file = path.basename(file); | ||
file = node_path.basename(file); | ||
} | ||
@@ -288,3 +305,3 @@ return { | ||
} | ||
_serverRequest.url = path.normalize(url); | ||
_serverRequest.url = node_path.normalize(url); | ||
this._context.accept(_serverRequest, _serverResponse); | ||
@@ -341,3 +358,3 @@ }, | ||
__getServerVersion: function (){ | ||
return 'Zeanium-Server V1.0.0'; | ||
return _package.name + ' V' + _package.version; | ||
}, | ||
@@ -344,0 +361,0 @@ __fixBasePath: function (){ |
@@ -23,2 +23,4 @@ /** | ||
_self = this, | ||
_config = this._context._config, | ||
_modules = _config.modules, | ||
_apps = []; | ||
@@ -30,4 +32,15 @@ zn.info('[ Begin ] Scanning Path:' + path); | ||
files.forEach(function(file){ | ||
if((_modules && _modules.indexOf(file)!=-1) || !_modules){ | ||
_queue.push(function (task){ | ||
_self.scanApplication.call(_self, path, file, function (appContext){ | ||
task.done(appContext); | ||
}); | ||
}, _self); | ||
} | ||
}); | ||
_config.node_modules && _config.node_modules.forEach(function (name, index){ | ||
var _paths = require.resolve(name).split(name); | ||
_queue.push(function (task){ | ||
this.scanApplication.call(this, path, file, function (appContext){ | ||
_self.scanApplication.call(_self, _paths[0], name, function (appContext){ | ||
task.done(appContext); | ||
@@ -37,2 +50,3 @@ }); | ||
}); | ||
_queue.every(function (appContext){ | ||
@@ -52,5 +66,7 @@ if(appContext){ | ||
var _defer = zn.async.defer(), | ||
_queue = zn.queue(), | ||
_apps = [], | ||
_self = this, | ||
_appPath = path + file, | ||
_appContext = null; | ||
_appContext = null, | ||
_serverContext = this._context, | ||
@@ -85,11 +101,35 @@ _configPath = _appPath + zn.SLASH + CONFIG.APP; | ||
_appContext = new ApplicationContext(zn.overwrite(appConfig, { deploy: _deploy }), _serverContext); | ||
_self.scanPackage(_appPath, appConfig.models, appConfig.controllers, _appContext, function (applicationContext){ | ||
if(appConfig.plugin){ | ||
_self.scanPlugin(appConfig.root + appConfig.plugin, applicationContext, callback); | ||
} else { | ||
callback && callback(applicationContext); | ||
_queue.push(function (task){ | ||
_self.scanPackage(_appPath, appConfig.models, appConfig.controllers, _appContext, function (applicationContext){ | ||
if(appConfig.plugin){ | ||
_self.scanPlugin(appConfig.root + appConfig.plugin, applicationContext, callback); | ||
} else { | ||
callback && callback(applicationContext); | ||
} | ||
}).then(function (applicationContext){ | ||
task.done(applicationContext); | ||
}); | ||
}, _self); | ||
/** ---- load node ---- **/ | ||
appConfig.node_modules && appConfig.node_modules.forEach(function (name, index){ | ||
var _paths = require.resolve(name).split(name); | ||
_queue.push(function (task){ | ||
_self.scanApplication.call(_self, _paths[0], name, function (appContext){ | ||
callback && callback(appContext); | ||
task.done(appContext); | ||
}); | ||
}, _self); | ||
}); | ||
_queue.every(function (appContext){ | ||
if(appContext){ | ||
_apps.push(appContext); | ||
} | ||
}).then(function (applicationContext){ | ||
_defer.resolve(applicationContext); | ||
}); | ||
}).finally(function(){ | ||
_defer.resolve(_apps); | ||
}).start(); | ||
/**** ---- ---- ***/ | ||
}); | ||
@@ -96,0 +136,0 @@ |
@@ -5,10 +5,2 @@ zn.define([ | ||
'./APIController' | ||
], function (DefaultController, ErrorController, APIController) { | ||
return { | ||
DefaultController: DefaultController, | ||
ErrorController: ErrorController, | ||
APIController: APIController | ||
} | ||
}); | ||
]); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
313658
6527
6