├── .gitignore ├── README.md ├── bin ├── .gitkeeper ├── km.js ├── link.js ├── moa.js ├── moad.js ├── moag.js ├── moan-after.sh ├── moan-exist.sh ├── moan.js └── moas.js ├── cp.sh ├── doc ├── moa.jpg └── private_npm.md ├── index.js ├── lib ├── .gitkeeper ├── controller.js ├── model.js ├── route.js ├── route_api.js └── view.js ├── package.json ├── test.js ├── test └── .gitkeeper └── tpl ├── controllers └── controller.js ├── models └── movie.js ├── routes ├── api │ ├── index.js │ └── movie.js ├── index.js ├── movies.js └── users.js └── views └── movies ├── edit.jade ├── index.jade ├── movie.jade ├── new.jade └── show.jade /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules* 2 | *.log 3 | public/upload/* 4 | public/html/* 5 | npm-debug.log 6 | tmp/** 7 | out/**/* 8 | app 9 | new_project 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Moajs 2 | 3 | Moajs is a open-source web framework based expressjs、mongoose、bluebird、mocha that’s optimized 4 | for programmer happiness and sustainable productivity. It lets you 5 | write beautiful code by favoring convention over configuration. 6 | 7 | [![gitter][gitter-image]][gitter-url] 8 | [![NPM version][npm-image]][npm-url] 9 | 10 | * Modular && Plugable 11 | * Scaffold 12 | * Model-View-Controller (MVC) pattern 13 | * Restful Api 14 | * Auto mount routes 15 | * Mongoosedao for data access 16 | * Gulp as task management 17 | * Live reload 18 | * Runtime Server 19 | 20 | 21 | ![](doc/moa.jpg) 22 | 23 | > "Lost, like the Moa is lost" - Maori proverb 24 | 25 | ## Requirement 26 | 27 | - nodejs v0.10 + 28 | - nvm v0.25 + 29 | - gulp v3.90 + 30 | 31 | ## Install 32 | 33 | [sudo] npm install -g moajs 34 | 35 | ## Usage 36 | 37 | ### help 38 | 39 | ➜ moajs git:(master) moa 40 | Moajs HELP: 41 | 42 | moan: 【创建新项目】 moan new_project_name 43 | moag: 【创建脚手架】 moag user name:string password:string uid:object 44 | moad: 【移除脚手架】 moad user 45 | moas: 【启动服务器】 moas 46 | 47 | Have a good day! Moaer 48 | 49 | ### new a project in cli 50 | 51 | moan new_project 52 | 53 | or force update with moa-seed latest version 54 | 55 | moan new_project -f 56 | 57 | ### create scaffold user 58 | 59 | moag user name:string password:object 60 | 61 | 62 | mongoose支持的data type基本如下: 63 | 64 | - String -> string 65 | - Number-> number 66 | - Date -> date 67 | - Boolean -> boolean 68 | - Buffer -> buffer 69 | - ObjectId -> object 70 | - Mixed -> mixed 71 | - Array -> array 72 | 73 | ### destroy scaffold user,this will move user to `~/.moajs/xxxx` 74 | 75 | moad user 76 | 77 | ### moas 78 | 79 | moas = moa server, runtime for test plugin 80 | 81 | 解决单个插件模块测试问题 82 | 83 | 使用`nmm init`初始化moa插件,然后使用moag来生成代码,并编写里面的功能。如果需要测试插件功能,可以使用moas来模拟moa运行时环境。 84 | 85 | 86 | ``` 87 | cd wms-plugin-warehouse 88 | moalink 89 | moas 90 | ``` 91 | 92 | 如果使用自定义端口,可以这样 93 | 94 | ``` 95 | export PORT=3009 && moas 96 | ``` 97 | 98 | ## Test 99 | 100 | npm run moag 101 | npm run moad 102 | npm run moan 103 | 104 | ## Components 105 | 106 | - [x] Scaffold 107 | - [x] Restful 108 | - 7 methods for render view 109 | - 5 methods for render api 110 | - [x] MongooseDao 111 | - [x] Middlewares 112 | - session 113 | - token-based api 114 | - [x] Task(gulp-based) 115 | - [x] Plugin(implement)(支持public模块和private模块) 116 | - [ ] Test 117 | - [ ] Migration 118 | - [ ] Deployments 119 | - [ ] Docs(http://github.com/andy0323/api-test) 120 | - [ ] refact api to router.api('get', middlewares, $.api.update) 在考虑要不要做 121 | 122 | ## FAQ 123 | 124 | ### moa官方模块 125 | 126 | https://github.com/moa-modules/ 127 | 128 | 目前只有2个插件 129 | 130 | - moa-plugin-user 131 | - moa-plugin-wechat 132 | 133 | 如果你开发了moa插件,开源的,请邮件或者issue通知我 shiren1118@126.com 134 | 135 | ### npm私有模块在服务器安装不上? 136 | 137 | 私有模块的好处是必须是模块拥有者才能下载,npmjs上是7美元/月,可以无限量的上传。私有模块无法被其他源copy,所以要保证源是`registry=https://registry.npmjs.org/`或者 138 | `nrm use npmjs`. 139 | 140 | 1) 更新npm版本,必须在2.11以上 141 | 142 | npm install -g npm 143 | 144 | 2) 用户登录,注意是该模块的拥有者 145 | 146 | npm login 147 | 148 | 3) 检查~/.npmrc,是否存在_authToken,如无,请更新npm版本去 149 | 150 | ``` 151 | [deploy@iZ251uvtr2bZ moajs]$ cat ~/.npmrc 152 | registry=https://registry.npmjs.org/ 153 | //registry.npmjs.org/:_authToken=fc83b39-7bfa-47b7-9f8c-ed91652613 154 | ``` 155 | 156 | 4) 安装你的私有插件吧,下面这句是安装不上的,就是给大家看看 157 | 158 | npm install @i5ting/wms-plugin-warehouse 159 | 160 | 161 | ## Contributing 162 | 163 | 1. Fork it 164 | 2. Create your feature branch (`git checkout -b my-new-feature`) 165 | 3. Commit your changes (`git commit -am 'Add some feature'`) 166 | 4. Push to the branch (`git push origin my-new-feature`) 167 | 5. Create new Pull Request 168 | 169 | ## History 170 | 171 | - v1.0.21 add nmm plugin 172 | - v1.0.17 add api generator 173 | - v1.0.16 add controller api export 174 | - v1.0.4 add exd to destroy it 175 | - v1.0.2 rename index to / 176 | - v1.0.0 init 177 | 178 | 179 | ## Welcome fork and feedback 180 | 181 | - write by `i5ting` shiren1118@126.com 182 | 183 | 如有建议或意见,请在issue提问或邮件 184 | 185 | ## License 186 | 187 | this repo is released under the [MIT 188 | License](http://www.opensource.org/licenses/MIT). 189 | 190 | 191 | [npm-image]: https://img.shields.io/npm/v/moajs.svg?style=flat-square 192 | [npm-url]: https://npmjs.org/package/moajs 193 | [gitter-image]: https://badges.gitter.im/Join%20Chat.svg 194 | [gitter-url]: https://gitter.im/i5ting/moajs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge -------------------------------------------------------------------------------- /bin/.gitkeeper: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moajs/moa/16f7570974f3d99d01212943faf46f200b1423e2/bin/.gitkeeper -------------------------------------------------------------------------------- /bin/km.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var child_process = require('child_process'); 4 | 5 | var argv = process.argv; 6 | argv.shift(); 7 | 8 | var file_path = __dirname; 9 | var current_path = process.cwd(); 10 | 11 | var server_port = 3000; 12 | var pre = ''; 13 | 14 | for(var i in argv){ 15 | var _argv = argv[i]; 16 | if(_argv == '-s' || first_arg == '--sudo'){ 17 | pre = 'sudo '; 18 | } 19 | } 20 | 21 | if ( argv.length > 1 ) { 22 | // console.log(argv) 23 | var first_arg = argv[1]; 24 | if ( first_arg == '-h' || first_arg == '--help' ) { 25 | return console.log('Usages: km'); 26 | } 27 | } 28 | 29 | var script = pre + " ps -ef|grep moas|awk '{print $2}'|xargs kill -9"; 30 | 31 | // execFile: executes a file with the specified arguments 32 | child_process.exec(script, 33 | function (error, stdout, stderr) { 34 | if (error !== null) { 35 | console.log('km exec error: ' + error); 36 | }else{ 37 | console.log("km exeute sucess!") 38 | } 39 | }); -------------------------------------------------------------------------------- /bin/link.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var current_path = process.cwd(); 4 | // console.log(__dirname) 5 | 6 | var dirw = require('dirw'); 7 | 8 | var dest_path = 'node_modules'; 9 | 10 | function main(){ 11 | var root = __dirname.split('/') 12 | root.pop(); 13 | 14 | var root_path = root.join('/') 15 | 16 | dirw.dir(root_path + '/node_modules', function(dir, dir_name){ 17 | // if(dir_name == 'bin' || dir_name == '.bin'){ 18 | // return; 19 | // } 20 | 21 | _create_symlink(dir, dir_name) 22 | }); 23 | } 24 | 25 | function _create_symlink(dir, dir_name) { 26 | var link = require('fs-symlink') 27 | 28 | link(dir, dest_path + '/' + dir_name, 'junction').then(function () { 29 | console.log('copy modudle ' + dir_name + ' finished'); 30 | }) 31 | } 32 | 33 | main(); -------------------------------------------------------------------------------- /bin/moa.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('shelljs/global'); 3 | 4 | var program = require('commander'); 5 | 6 | var version = require('../package.json').version 7 | program 8 | .version(version) 9 | .parse(process.argv); 10 | // 11 | // console.log('you ordered a pizza with:'); 12 | // if (program.peppers) console.log(' - peppers'); 13 | // if (program.pineapple) console.log(' - pineapple'); 14 | // if (program.bbqSauce) console.log(' - bbq'); 15 | // console.log(' - %s cheese', program.cheese); 16 | 17 | echo('Moajs HELP:'); 18 | echo(''); 19 | echo('moan: 【创建新项目】 moan new_project_name'); 20 | echo('moag: 【创建脚手架】 moag user name:string password:string uid:object'); 21 | echo('moad: 【移除脚手架】 moad user'); 22 | echo('moas: 【启动服务器】 moas'); 23 | echo(''); 24 | echo('Have a good day! Moaer'); 25 | -------------------------------------------------------------------------------- /bin/moad.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var child_process = require('child_process'); 4 | 5 | var argv = process.argv; 6 | argv.shift(); 7 | 8 | // var file_path = __dirname; 9 | var current_path = process.cwd(); 10 | 11 | var model = { 12 | base_path : current_path + '/app', 13 | entity:'entity', 14 | attr:{} 15 | } 16 | 17 | if(argv.length < 1){ 18 | return console.log('Usages: moad user'); 19 | } 20 | 21 | model.entity = argv[1]; 22 | 23 | // main 24 | var Generator = require('../index'); 25 | var g = new Generator(model,{}); 26 | 27 | g.destroy(); 28 | 29 | 30 | -------------------------------------------------------------------------------- /bin/moag.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var child_process = require('child_process'); 4 | 5 | var argv = process.argv; 6 | argv.shift(); 7 | 8 | // var file_path = __dirname; 9 | var current_path = process.cwd(); 10 | 11 | var model = { 12 | base_path : current_path + '/app', 13 | entity:'entity', 14 | attr:{} 15 | } 16 | 17 | if(argv.length < 2){ 18 | return console.log('Usages: exg user name:string password:string'); 19 | } 20 | 21 | model.entity = argv[1]; 22 | 23 | argv.shift(); 24 | 25 | for(var i in argv){ 26 | var _attr = argv[i]; 27 | 28 | if(argv[i].match(/:/g)){ 29 | console.log('it is a attr'); 30 | var _attr_arr = argv[i].split(':'); 31 | var k = _attr_arr[0]; 32 | var v = _attr_arr[1]; 33 | model.attr[k] = v 34 | } 35 | } 36 | 37 | // main 38 | var Generator = require('../index'); 39 | var g = new Generator(model,{}); 40 | 41 | g.all(); -------------------------------------------------------------------------------- /bin/moan-after.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | cd ~/.moa && moalink && cp ~/.moa/config/mongodb.example.js ~/.moa/config/mongodb.js 4 | 5 | echo 'moan finish!' -------------------------------------------------------------------------------- /bin/moan-exist.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | project_name=$1 4 | 5 | cp -r ~/.moa $project_name 6 | cd $project_name && npm install --save moa-plugin-user 7 | 8 | 9 | echo 'moan finish!' -------------------------------------------------------------------------------- /bin/moan.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('shelljs/global'); 3 | 4 | var child_process = require('child_process'); 5 | var fs = require('fs'); 6 | 7 | var argv = process.argv; 8 | argv.shift(); 9 | 10 | if(argv.length < 1){ 11 | return console.log('Usages: exn project_name'); 12 | } 13 | 14 | var file_path = __dirname; 15 | var current_path = process.cwd(); 16 | var project_name = argv[1]; 17 | var home_dir = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; 18 | 19 | 20 | if (!which('git')) { 21 | echo('Sorry, this script requires git'); 22 | exit(1); 23 | } 24 | var cache_dir = home_dir + '/.moa'; 25 | var folder_exists = fs.existsSync(cache_dir); 26 | // console.log(home_dir + ' - ' + folder_exists); 27 | 28 | for(var i in argv){ 29 | var _argv = argv[i]; 30 | if(_argv == '-f' || _argv == '--force'){ 31 | // rm('-rf', home_dir + '/.moa'); 32 | folder_exists = false; 33 | } 34 | } 35 | // TODO: refact with promise 36 | setTimeout(function(){ 37 | 38 | if(!folder_exists){ 39 | console.log('start clone moa-seed to ~/.moa'); 40 | var clone = 'rm -rf ~/.moa && git clone --depth=1 https://github.com/moajs/moa-seed.git ' + '/' +cache_dir + ' && cd ~/.moa && moalink && cp config/mongodb.example.js config/mongodb.js '; 41 | // Run external tool synchronously 42 | if (exec(clone).code !== 0) { 43 | echo('Error: Git clone failed'); 44 | exit(1); 45 | }else{ 46 | child_process.execFile(file_path + '/moan-after.sh', [], {cwd:current_path},function (error,stdout,stderr) { 47 | if (error !== null) { 48 | console.log('start moan-after.sh here exec error: ' + error); 49 | }else{ 50 | echo('Success: moan clone finished!'); 51 | } 52 | }); 53 | 54 | } 55 | }else{ 56 | console.log(cache_dir + ' is already exist, if you want update force,please use -f option'); 57 | } 58 | 59 | child_process.execFile(file_path + '/moan-exist.sh', [project_name], {cwd:current_path},function (error,stdout,stderr) { 60 | if (error !== null) { 61 | console.log('start moan-a.sh here exec error: ' + error); 62 | }else{ 63 | // console.log('start mongo here success!') 64 | 65 | echo(''); 66 | echo('Congratulations! moan finished!'); 67 | echo(''); 68 | 69 | echo('step 0: 【修改配置】 cp config/default.example.json to config/default.json'); 70 | echo('step 1: 【启动服务器】 npm start'); 71 | echo('step 2: 【创建脚手架】 moag user name:string password:string uid:object'); 72 | echo('step 3: 【如果需要,移除已有脚手架】 moad user'); 73 | echo('Have a good day! Moaer'); 74 | } 75 | }); 76 | }, 200); -------------------------------------------------------------------------------- /bin/moas.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('shelljs/global'); 3 | 4 | var fs = require('fs') 5 | var child_process = require('child_process'); 6 | 7 | var argv = process.argv; 8 | argv.shift(); 9 | 10 | var file_path = __dirname; 11 | var files = __dirname.split('/'); 12 | files.pop(); 13 | file_path = files.join('/') 14 | 15 | var current_path = process.cwd(); 16 | console.log(current_path); 17 | var home_dir = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; 18 | 19 | if(argv.length < 1){ 20 | return console.log('Usages: exn project_name'); 21 | } 22 | 23 | if (!which('git')) { 24 | echo('Sorry, this script requires git'); 25 | exit(1); 26 | } 27 | 28 | var files = [ 29 | 'config', 30 | 'app/views/layouts', 31 | 'app/views/error.jade', 32 | 'app/middlewares/check_api_token.js' 33 | ]; 34 | 35 | link(); 36 | // unlink(); 37 | 38 | setTimeout(function(){ 39 | process.chdir( current_path ); 40 | var server = file_path + "/node_modules/.bin/nodemon"; 41 | var clone = server + ' ~/.moa/bin/www' 42 | 43 | // console.log('[SERVER START] ' + clone) 44 | // Run external tool synchronously 45 | if (exec(clone).code !== 0) { 46 | echo('Error: Moa server start failed'); 47 | exit(1); 48 | }else{ 49 | echo('Success: Moa server start finished!'); 50 | } 51 | }, 200); 52 | 53 | echo(''); 54 | echo('Congratulations! moan finished!'); 55 | echo(''); 56 | 57 | echo('step 0: 【修改配置】 cp config/default.example.json to config/default.json'); 58 | echo('step 1: 【启动服务器】 npm start'); 59 | echo('step 2: 【创建脚手架】 moag user name:string password:string uid:object'); 60 | echo('step 3: 【如果需要,移除已有脚手架】 moad user'); 61 | echo('Have a good day! Moaer'); 62 | 63 | process.stdin.resume();//so the program will not close instantly 64 | 65 | function exitHandler(options, err) { 66 | unlink(); 67 | } 68 | process.on( 'exit', function() { 69 | console.log( "\nGracefully shutting down from exit" ); 70 | // some other closing procedures go here 71 | process.exit( ); 72 | }) 73 | 74 | process.on( 'SIGINT', function() { 75 | console.log( "\nGracefully shutting down from SIGINT (Ctrl-C)" ); 76 | // some other closing procedures go here 77 | process.exit( ); 78 | }) 79 | 80 | process.on( 'SIGINT', function() { 81 | console.log( "\nGracefully shutting down from SIGINT (Ctrl-C)" ); 82 | // some other closing procedures go here 83 | process.exit( ); 84 | }) 85 | 86 | function link(){ 87 | files.forEach(function(file){ 88 | var src = home_dir + '/.moa/' + file; 89 | var dest = current_path + '/' + file; 90 | fs.appendFileSync('.gitignore',dest+'\n'); 91 | console.log(src + ' - ' + dest); 92 | _create_symlink(src, file) ; 93 | }); 94 | } 95 | 96 | function unlink(){ 97 | console.log('unlink...'); 98 | files.forEach(function(file){ 99 | var src = home_dir + '/.moa/' + file; 100 | var dest = current_path + '/' + file; 101 | 102 | fs.unlinkSync(dest); 103 | }); 104 | } 105 | 106 | function _create_symlink(dir, dir_name) { 107 | var link = require('fs-symlink') 108 | 109 | console.log(dir + ' - ' + dir_name); 110 | link(dir, current_path + '/' + dir_name, 'junction').then(function () { 111 | console.log('copy modudle ' + dir_name + ' finished'); 112 | }) 113 | } 114 | -------------------------------------------------------------------------------- /cp.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | 4 | cp -f out/app/controllers/users_controller.js ../express-g-demo/app/controllers/ 5 | cp -f out/app/models/user.js ../express-g-demo/app/models/ 6 | cp -f out/app/routes/users.js ../express-g-demo/app/routes/ 7 | cp -rf out/app/views/users ../express-g-demo/app/views/ -------------------------------------------------------------------------------- /doc/moa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moajs/moa/16f7570974f3d99d01212943faf46f200b1423e2/doc/moa.jpg -------------------------------------------------------------------------------- /doc/private_npm.md: -------------------------------------------------------------------------------- 1 | # 你一定要知道的private npm 2 | 3 | 私有模块的好处是必须是模块拥有者才能下载, 4 | 5 | ## Why? 6 | 7 | 以后js大一统,npm就不再只是nodejs package manager的,而是js package manager 8 | 9 | 首先看一下npm的好处 10 | 11 | - 易于使用,下载,开发,发布,测试等 12 | - 管理模块依赖 13 | - 模块化,易于拆分 14 | - npm提供足够多的hook,可以定制很多功能 15 | - 安装版本,可随意指定,可以干坏事儿的 16 | 17 | 私有npm的好处 18 | 19 | - 继承了所有npm的好处 20 | - 只有模块拥有者才可以下载,具有私密性 21 | 22 | 目前情况 23 | 24 | - nodejs世界里都是npm,一统江湖 25 | - 前端js世界,正在向npm靠拢,npm的种种好处,只比bower强,不弱。 26 | 27 | 举个例子,眼下最火的reactjs的组件,推荐就是webpack打包,然后发布都npm上。目前做的比较好的是ant.design,它的tab组件里的package.json 28 | 29 | https://github.com/react-component/tabs/blob/master/package.json 30 | 31 | 我们再看一下它的用法 32 | 33 | ``` 34 | var Tabs = require('rc-tabs'); 35 | var TabPane = Tabs.TabPane; 36 | 37 | var callback = function(key){ 38 | 39 | } 40 | 41 | React.render( 42 | ( 43 | 44 | first 45 | second 46 | third 47 | 48 | ), 49 | document.getElementById('t2')); 50 | ``` 51 | 52 | 一样的require,一样的调用,是不是感觉很亲切啊? 53 | 54 | ## Moajs的插件机制:它可以做的更多 55 | 56 | 核心代码如下 57 | 58 | ``` 59 | "scripts": { 60 | "start": "npm publish .", 61 | "test": "echo \"Error: no test specified\" && exit 1", 62 | "postinstall": "node ./node_modules/nmm-link/link.bin.js" 63 | }, 64 | "dependencies": { 65 | "nmm-link": "^1.0.2" 66 | }, 67 | ``` 68 | 69 | 说明: 70 | 71 | - postinstall是npm的hook,当安装完成之后的回调,这里只想nmm-link里的一个脚本 72 | - nmm-link是一个生产软连接的工具 73 | 74 | 其实整个插件机制异常简单 75 | 76 | - 通过npm安装后的回调postinstall来执行脚本 77 | - 根据当前npm目录信息来创建对应的逻辑处理,比如这里的创建link 78 | 79 | 是不是很简单? 80 | 81 | 更多参见:https://docs.npmjs.com/misc/scripts 82 | 83 | npm supports the "scripts" property of the package.json script, for the following scripts: 84 | 85 | - prepublish: Run BEFORE the package is published. (Also run on local npm install without any arguments.) 86 | - publish, postpublish: Run AFTER the package is published. 87 | - preinstall: Run BEFORE the package is installed 88 | - install, postinstall: Run AFTER the package is installed. 89 | - preuninstall, uninstall: Run BEFORE the package is uninstalled. 90 | - postuninstall: Run AFTER the package is uninstalled. 91 | - preversion, version: Run BEFORE bump the package version. 92 | - postversion: Run AFTER bump the package version. 93 | - pretest, test, posttest: Run by the npm test command. 94 | - prestop, stop, poststop: Run by the npm stop command. 95 | - prestart, start, poststart: Run by the npm start command. 96 | - prerestart, restart, postrestart: Run by the npm restart command. Note: npm restart will run the stop and start scripts if no restart script is provided. 97 | 98 | 这么多hook,是不是想干啥都够? 99 | 100 | 扯了这么多,我的目的是讲npm的好处,其实这就衍生出私有npm的重要性,很多时候,公司的东西不能开发,就算是一个插件,开发出来也不合适,于是大家都行要私有的npm,于是这帮货就想了个办法,给npm增加scope功能,即所谓的private npm。 101 | 102 | ## 自建npm源的技术选项 103 | 104 | 实现private npm有2种办法 105 | 106 | - 自建 107 | - 付费购买 108 | 109 | 110 | 我参照的是 111 | 112 | https://github.com/cnpm/cnpmjs.org/wiki/Deploy-a-private-npm-registry-in-5-minutes 113 | 114 | 目前没有成功,有成功的可以分享一下 115 | 116 | 搭建私有仓库的可选方案 117 | 118 | - https://github.com/npm/npm-registry-couchapp 119 | - https://github.com/cnpm/cnpmjs.org 120 | 121 | 上面2种方式,一个推荐couchdb,一个推荐mysql,总是每个1G内存,甭想玩,而且同步能否限制还不好说。 122 | 123 | ## 付费方案 124 | 125 | npmjs上是7美元/月,可以无限量的上传。私有模块无法被其他源copy,所以要保证源是`registry=https://registry.npmjs.org/`或者`nrm use npmjs`. 126 | 127 | 破财省得麻烦,也算值得了 128 | 129 | ## npm私有模块在服务器安装不上? 130 | 131 | 1) 更新npm版本,必须在2.11以上 132 | 133 | npm install -g npm 134 | 135 | 2) 用户登录,注意是该模块的拥有者 136 | 137 | npm login 138 | 139 | 3) 检查~/.npmrc,是否存在_authToken,如无,请更新npm版本去 140 | 141 | ``` 142 | [deploy@iZ251uvtr2bZ moajs]$ cat ~/.npmrc 143 | registry=https://registry.npmjs.org/ 144 | //registry.npmjs.org/:_authToken=fc83b39-7bfa-47b7-9f8c-ed91652613 145 | ``` 146 | 147 | 4) 安装你的私有插件吧,下面这句是安装不上的,就是给大家看看 148 | 149 | npm install @i5ting/wms-plugin-warehouse 150 | 151 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('shelljs/global'); 2 | 3 | var util = require("util"); 4 | var mkdirp = require('mkdirp'); 5 | var Inflector = require('inflected'); 6 | var tpl = require('tpl_apply'); 7 | 8 | // util.inherits(MyStream, events.EventEmitter); 9 | 10 | // var file_path = __dirname; 11 | // var current_path = process.cwd(); 12 | function getUserHome() { 13 | return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME']; 14 | } 15 | 16 | var cache_path = getUserHome() + '/.express-g/'; 17 | 18 | mkdirp(cache_path, function (err) { 19 | if (err) console.error(err) 20 | else console.log('pow! create cache_path') 21 | }); 22 | 23 | var _default_options = function (base_path){ 24 | return { 25 | controller_path : base_path + '/controllers', 26 | model_path : base_path + '/models', 27 | view_path : base_path + '/views', 28 | route_path : base_path + '/routes' 29 | } 30 | } 31 | 32 | function _cp(des, src) { 33 | if (!des) { 34 | des = {}; 35 | } 36 | if (src) { 37 | for (var i in src) { 38 | des[i] = src[i]; 39 | } 40 | } 41 | return des; 42 | } 43 | 44 | function g (obj, opts) { 45 | this.model = obj; 46 | 47 | this.root_path = __dirname; 48 | this.base_path = obj.base_path; 49 | 50 | this.option = _default_options(this.base_path); 51 | 52 | _cp(this.option, opts); 53 | _cp(this, this.option); 54 | 55 | _mkdir(this); 56 | } 57 | 58 | function _mkdir(t){ 59 | mkdirp(t.controller_path, function (err) { 60 | if (err) console.error(err) 61 | else console.log('pow! create controller_path') 62 | }); 63 | 64 | mkdirp(t.model_path, function (err) { 65 | if (err) console.error(err) 66 | else console.log('pow! create model_path') 67 | }); 68 | 69 | mkdirp(t.view_path, function (err) { 70 | if (err) console.error(err) 71 | else console.log('pow! create view_path') 72 | }); 73 | 74 | mkdirp(t.route_path, function (err) { 75 | if (err) console.error(err) 76 | else console.log('pow! create route_path') 77 | }); 78 | 79 | mkdirp(t.route_path + '/api', function (err) { 80 | if (err) console.error(err) 81 | else console.log('pow! create route_api_path') 82 | }); 83 | } 84 | 85 | g.prototype.c = function () { 86 | require('./lib/controller')(this) 87 | } 88 | 89 | g.prototype.m = function () { 90 | require('./lib/model')(this) 91 | } 92 | 93 | g.prototype.v = function () { 94 | require('./lib/view')(this) 95 | } 96 | 97 | g.prototype.r = function () { 98 | require('./lib/route')(this) 99 | } 100 | 101 | g.prototype.r_api = function () { 102 | require('./lib/route_api')(this) 103 | } 104 | 105 | g.prototype.all = function () { 106 | this.c(); 107 | this.m(); 108 | this.v(); 109 | this.r(); 110 | this.r_api(); 111 | } 112 | 113 | g.prototype.destroy = function () { 114 | var entity = this.model.entity; 115 | var cache_path = getUserHome() +'/.express-g/' + Date.now(); 116 | 117 | mkdirp(cache_path, function (err) { 118 | if (err) console.error(err) 119 | else console.log('pow! create controller_path') 120 | }); 121 | 122 | var c = this.controller_path +'/'+ Inflector.pluralize(entity) + "_controller.js"; 123 | var m = this.model_path +'/'+ entity + ".js"; 124 | var v = this.view_path +'/'+ Inflector.pluralize(entity) + "/"; 125 | var r = this.route_path +'/'+ Inflector.pluralize(entity) + ".js"; 126 | var a = this.route_path +'/api/'+ Inflector.pluralize(entity) + ".js"; 127 | 128 | [c,m,v,r,a].forEach(function(file){ 129 | mv('-f', file, cache_path + '/'); 130 | }); 131 | } 132 | 133 | module.exports = g; -------------------------------------------------------------------------------- /lib/.gitkeeper: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moajs/moa/16f7570974f3d99d01212943faf46f200b1423e2/lib/.gitkeeper -------------------------------------------------------------------------------- /lib/controller.js: -------------------------------------------------------------------------------- 1 | var Inflector = require('inflected'); 2 | var tpl = require('tpl_apply'); 3 | var moment = require('moment'); 4 | 5 | // movies_controller 6 | function g(o) { 7 | this.created_at = moment().format('MMMM Do YYYY, h:mm:ss a'); 8 | this.entity = Inflector.camelize(o.model.entity); 9 | this.attrs = JSON.stringify(o.model.attr); 10 | // console.log(o); 11 | this.model = o.model.entity; 12 | this.models = Inflector.pluralize(o.model.entity); 13 | this.out_file_name = o.controller_path +'/'+ Inflector.pluralize(o.model.entity) + "_controller.js"; 14 | this.source_file = o.root_path + '/tpl/controllers/controller.js' 15 | 16 | // console.log(this); 17 | 18 | var source = this.source_file; 19 | var dest = this.out_file_name; 20 | 21 | var keypair = []; 22 | for(var k in o.model.attr){ 23 | keypair.push( k + ": req.body." + k ); 24 | } 25 | this.keypair = '{'+ keypair.join(',') + '}' 26 | 27 | tpl.tpl_apply(source, this, dest); 28 | } 29 | 30 | module.exports = g; -------------------------------------------------------------------------------- /lib/model.js: -------------------------------------------------------------------------------- 1 | var Inflector = require('inflected'); 2 | var tpl = require('tpl_apply'); 3 | var moment = require('moment'); 4 | 5 | // movies_controller 6 | function g(o) { 7 | this.created_at = moment().format('MMMM Do YYYY, h:mm:ss a'); 8 | this.entity = Inflector.camelize(o.model.entity); 9 | this.attrs = JSON.stringify(o.model.attr); 10 | // console.log(o); 11 | this.model = o.model.entity; 12 | this.models = Inflector.pluralize(o.model.entity); 13 | this.out_file_name = o.model_path +'/'+ o.model.entity + ".js"; 14 | this.source_file = o.root_path + '/tpl/models/movie.js' 15 | 16 | // console.log(this); 17 | 18 | var source = this.source_file; 19 | var dest = this.out_file_name 20 | 21 | this.mongoose_attrs = get_mongoose_type_attrs(o.model.attr); 22 | 23 | tpl.tpl_apply(source, this, dest); 24 | } 25 | // name:string 26 | function get_mongoose_type_attrs(attrs){ 27 | var _attrs = attrs 28 | for(var k in attrs){ 29 | var _new_type = _decode_mongoose_type(attrs[k]); 30 | 31 | _attrs[k] = _new_type; 32 | } 33 | 34 | console.log('_attrs = ' + _attrs) 35 | console.dir( _attrs) 36 | 37 | return JSON.stringify(_attrs) 38 | } 39 | /** 40 | • String -> string 41 | • Number-> number 42 | • Date -> date 43 | • Boolean -> boolean 44 | • Buffer -> buffer 45 | • ObjectId -> object 46 | • Mixed -> mixed 47 | • Array -> array 48 | */ 49 | function _decode_mongoose_type(type){ 50 | var _t = type.toLowerCase(); 51 | 52 | if(_t == 'object' || _t == 'objectid' || _t == 'objectId'){ 53 | _t = 'objectId'; 54 | } 55 | 56 | return Inflector.camelize(_t); 57 | } 58 | 59 | module.exports = g; -------------------------------------------------------------------------------- /lib/route.js: -------------------------------------------------------------------------------- 1 | var Inflector = require('inflected'); 2 | var tpl = require('tpl_apply'); 3 | var moment = require('moment'); 4 | 5 | // movies_controller 6 | function g(o) { 7 | this.created_at = moment().format('MMMM Do YYYY, h:mm:ss a'); 8 | this.entity = Inflector.camelize(o.model.entity); 9 | this.attrs = JSON.stringify(o.model.attr); 10 | // console.log(o); 11 | this.model = o.model.entity; 12 | this.models = Inflector.pluralize(o.model.entity); 13 | this.out_file_name = o.route_path +'/'+ this.models + ".js"; 14 | this.source_file = o.root_path + '/tpl/routes/movies.js' 15 | 16 | // console.log(this); 17 | 18 | var source = this.source_file; 19 | var dest = this.out_file_name; 20 | 21 | tpl.tpl_apply(source, this, dest); 22 | } 23 | 24 | module.exports = g; -------------------------------------------------------------------------------- /lib/route_api.js: -------------------------------------------------------------------------------- 1 | var Inflector = require('inflected'); 2 | var tpl = require('tpl_apply'); 3 | var moment = require('moment'); 4 | 5 | // movies_controller 6 | function g(o) { 7 | this.created_at = moment().format('MMMM Do YYYY, h:mm:ss a'); 8 | this.entity = Inflector.camelize(o.model.entity); 9 | this.attrs = JSON.stringify(o.model.attr); 10 | // console.log(o); 11 | this.model = o.model.entity; 12 | this.models = Inflector.pluralize(o.model.entity); 13 | this.out_file_name = o.route_path +'/api/'+ this.models + ".js"; 14 | this.source_file = o.root_path + '/tpl/routes/api/movie.js' 15 | 16 | // console.log(this); 17 | 18 | var source = this.source_file; 19 | var dest = this.out_file_name; 20 | 21 | tpl.tpl_apply(source, this, dest); 22 | } 23 | 24 | module.exports = g; -------------------------------------------------------------------------------- /lib/view.js: -------------------------------------------------------------------------------- 1 | var Inflector = require('inflected'); 2 | var tpl = require('tpl_apply'); 3 | var fs = require('fs'); 4 | var moment = require('moment'); 5 | 6 | // movies_controller 7 | function g(o) { 8 | this.created_at = moment().format('MMMM Do YYYY, h:mm:ss a'); 9 | this.entity = Inflector.camelize(o.model.entity); 10 | this.attrs = JSON.stringify(o.model.attr); 11 | this.model = o.model.entity; 12 | this.models = Inflector.pluralize(o.model.entity); 13 | this.out_file_name = o.view_path +'/'; 14 | this.source_file = o.root_path + '/tpl/views/' 15 | 16 | var keys = []; 17 | var keypair = []; 18 | var model_dot_attrs = []; 19 | 20 | for(var k in o.model.attr){ 21 | keypair.push( k + ": req.body." + k ); 22 | keys.push("'" + k + "'"); 23 | model_dot_attrs.push("'" + this.model + '.' + k + "'"); 24 | } 25 | 26 | this.keypair = '{'+ keypair.join(',') + '}'; 27 | this.keys = keys; 28 | this.model_dot_attrs = model_dot_attrs; 29 | 30 | var e = this.models; 31 | var e1 = this.model; 32 | 33 | var views = ['edit','index', 'movie' ,'new','show'] 34 | 35 | var out_file_name = this.out_file_name + '' + e ; 36 | // 37 | console.log(this.out_file_name) 38 | 39 | var is_exist = fs.existsSync(out_file_name); 40 | if(is_exist == true) { 41 | 42 | fs.readdirSync(out_file_name).forEach(function(file){ 43 | fs.unlinkSync(out_file_name + '/' + file); 44 | }); 45 | fs.rmdirSync(out_file_name); 46 | } 47 | 48 | var mkdirp = require('mkdirp'); 49 | 50 | mkdirp(out_file_name, function (err) { 51 | if (err) console.error(err) 52 | else console.log('pow! create view_path') 53 | }); 54 | 55 | var t = this; 56 | views.forEach(function(i){ 57 | var source = this.source_file + '' + 'movies/' + i + '.jade'; 58 | var dest = out_file_name + '/' + i + '.jade'; 59 | 60 | if(i == 'movie'){ 61 | dest = out_file_name + '/' + e1 + '.jade'; 62 | } 63 | 64 | tpl.tpl_apply(source, t, dest); 65 | }); 66 | } 67 | 68 | module.exports = g; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moajs", 3 | "version": "1.0.27", 4 | "description": "Moajs is a full stack framework based expressjs、mongoose、bluebird、mocha.", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "npm publish .", 8 | "test": "node test.js", 9 | "moag": "node bin/moag.js user name:string password:string uid:object", 10 | "moad": "node bin/moad.js user", 11 | "moan": "node bin/moan.js new_project" 12 | }, 13 | "preferGlobal": "true", 14 | "bin": { 15 | "moa": "bin/moa.js", 16 | "moag": "bin/moag.js", 17 | "moad": "bin/moad.js", 18 | "moan": "bin/moan.js", 19 | "moas": "bin/moas.js", 20 | "km": "bin/km.js", 21 | "moalink": "bin/link.js" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/moajs/moa.git" 26 | }, 27 | "author": "", 28 | "license": "ISC", 29 | "bugs": { 30 | "url": "https://github.com/moajs/moa/issues" 31 | }, 32 | "homepage": "https://github.com/moajs/moa#readme", 33 | "dependencies": { 34 | "bluebird": "^2.9.27", 35 | "body-parser": "~1.12.4", 36 | "commander": "^2.8.1", 37 | "config": "^1.14.0", 38 | "connect-mongo": "^0.8.1", 39 | "cookie-parser": "~1.3.5", 40 | "cors": "^2.7.1", 41 | "debug": "~2.2.0", 42 | "dirw": "^1.0.2", 43 | "express": "~4.12.4", 44 | "express-di": "^4.1.1", 45 | "express-session": "^1.11.2", 46 | "fs-symlink": "^1.1.3", 47 | "inflected": "^1.1.6", 48 | "is_js": "^0.7.4", 49 | "jade": "~1.9.2", 50 | "jsonwebtoken": "^5.0.1", 51 | "log4js": "^0.6.25", 52 | "mkdirp": "^0.5.1", 53 | "moa-middlewares": "^1.0.2", 54 | "moment": "^2.10.3", 55 | "mongoose": "^4.0.4", 56 | "mongoosedao": "^1.0.6", 57 | "morgan": "~1.5.3", 58 | "mount-controllers": "^1.0.7", 59 | "mount-middlewares": "^1.0.5", 60 | "mount-models": "^1.0.8", 61 | "mount-routes": "^1.0.3", 62 | "mount-services": "^1.0.7", 63 | "multer": "^0.1.8", 64 | "nmm-link": "^1.0.4", 65 | "nodemailer": "^1.3.4", 66 | "nodemon": "^1.3.7", 67 | "pm2": "^0.12.15", 68 | "require-directory": "^2.1.1", 69 | "res.api": "^1.0.8", 70 | "serve-favicon": "~2.2.1", 71 | "shelljs": "^0.5.0", 72 | "tpl_apply": "^1.0.2" 73 | }, 74 | "devDependencies": {} 75 | } 76 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | require('shelljs/global'); 2 | 3 | var child_process = require('child_process'); 4 | // var file_path = __dirname; 5 | var current_path = process.cwd(); 6 | 7 | rm('-rf', 'out'); 8 | 9 | var base = current_path + '/out/app' 10 | 11 | // Copy files to release dir 12 | mkdir('-p', base + '/controllers'); 13 | mkdir('-p', base + '/models'); 14 | mkdir('-p', base + '/views'); 15 | mkdir('-p', base + '/routes'); 16 | // 17 | // 18 | // var model = { 19 | // base_path : base, 20 | // entity:'user', 21 | // attr:{ 22 | // username: 'string', 23 | // password: 'string' 24 | // } 25 | // } 26 | // 27 | // // var model = require('./') 28 | // // var c = require('./lib/controller')(model) 29 | // // var m = require('./lib/model')(model) 30 | // // var v = require('./lib/view')(model) 31 | // // var r = require('./lib/route')(model) 32 | // 33 | // 34 | // var Generator = require('./index'); 35 | // var g = new Generator(model,{}); 36 | // 37 | // g.all(); -------------------------------------------------------------------------------- /test/.gitkeeper: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moajs/moa/16f7570974f3d99d01212943faf46f200b1423e2/test/.gitkeeper -------------------------------------------------------------------------------- /tpl/controllers/controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Moajs on {{created_at}}. 3 | */ 4 | 5 | var $models = require('mount-models')(__dirname); 6 | 7 | var {{entity}} = $models.{{model}}; 8 | 9 | exports.list = function (req, res, next) { 10 | console.log(req.method + ' /{{models}} => list, query: ' + JSON.stringify(req.query)); 11 | 12 | {{entity}}.getAll(function(err, {{models}}){ 13 | console.log({{models}}); 14 | res.render('{{models}}/index', { 15 | {{models}} : {{models}} 16 | }) 17 | }); 18 | }; 19 | 20 | exports.new = function (req, res, next) { 21 | console.log(req.method + ' /{{models}}/new => new, query: ' + JSON.stringify(req.query)); 22 | 23 | res.render('{{models}}/new', { 24 | {{model}} : { 25 | "_action" : "new" 26 | } 27 | }) 28 | }; 29 | 30 | exports.show = function (req, res, next) { 31 | console.log(req.method + ' /{{models}}/:id => show, query: ' + JSON.stringify(req.query) + 32 | ', params: ' + JSON.stringify(req.params)); 33 | var id = req.params.id; 34 | 35 | {{entity}}.getById(id, function(err, {{model}}) { 36 | console.log({{model}}); 37 | res.render('{{models}}/show', { 38 | {{model}} : {{model}} 39 | }) 40 | }); 41 | }; 42 | 43 | exports.edit = function (req, res, next) { 44 | console.log(req.method + ' /{{models}}/:id/edit => edit, query: ' + JSON.stringify(req.query) + 45 | ', params: ' + JSON.stringify(req.params)); 46 | 47 | var id = req.params.id; 48 | 49 | {{entity}}.getById(id, function (err, {{model}}) { 50 | console.log({{model}}); 51 | {{model}}._action = 'edit'; 52 | 53 | res.render('{{models}}/edit', { 54 | {{model}} : {{model}} 55 | }) 56 | }); 57 | }; 58 | 59 | exports.create = function (req, res, next) { 60 | console.log(req.method + ' /{{models}} => create, query: ' + JSON.stringify(req.query) + 61 | ', params: ' + JSON.stringify(req.params) + ', body: ' + JSON.stringify(req.body)); 62 | 63 | {{entity}}.create({{keypair}}, function (err, {{model}}) { 64 | console.log({{model}}); 65 | res.render('{{models}}/show', { 66 | {{model}} : {{model}} 67 | }) 68 | }); 69 | }; 70 | 71 | exports.update = function (req, res, next) { 72 | console.log(req.method + ' /{{models}}/:id => update, query: ' + JSON.stringify(req.query) + 73 | ', params: ' + JSON.stringify(req.params) + ', body: ' + JSON.stringify(req.body)); 74 | 75 | var id = req.params.id; 76 | 77 | {{entity}}.updateById(id,{{keypair}}, function (err, {{model}}) { 78 | console.log({{model}}); 79 | 80 | res.json({ 81 | data: { 82 | redirect : '/{{models}}/' + id 83 | }, 84 | status: { 85 | code : 0, 86 | msg : 'delete success!' 87 | } 88 | }); 89 | }); 90 | }; 91 | 92 | exports.destroy = function (req, res, next) { 93 | var id = req.params.id; 94 | {{entity}}.deleteById(id, function (err) { 95 | if (err) { 96 | throw new Error(err); 97 | } 98 | 99 | res.json({ 100 | data: {}, 101 | status: { 102 | code : 0, 103 | msg : 'delete success!' 104 | } 105 | }); 106 | }); 107 | }; 108 | 109 | // -- custom api 110 | 111 | exports.api = { 112 | list: function (req, res, next) { 113 | var user_id = req.api_user._id; 114 | 115 | {{entity}}.query({}, function (err, {{models}}) { 116 | if (err) { 117 | return res.api_error(err); 118 | } 119 | 120 | res.api({ 121 | {{models}} : {{models}} 122 | }) 123 | }); 124 | }, 125 | show: function (req, res, next) { 126 | var user_id = req.api_user._id; 127 | var id = req.params.{{model}}_id; 128 | 129 | {{entity}}.getById(id, function (err, {{model}}) { 130 | if (err) { 131 | return res.api_error(err); 132 | } 133 | 134 | res.api({ 135 | {{model}} : {{model}} 136 | }); 137 | }); 138 | }, 139 | create: function (req, res, next) { 140 | var user_id = req.api_user._id; 141 | 142 | {{entity}}.create({{keypair}}, function (err, {{model}}) { 143 | if (err) { 144 | return res.api_error(err); 145 | } 146 | 147 | res.json({ 148 | {{model}} : {{model}} 149 | }) 150 | }); 151 | }, 152 | update: function (req, res, next) { 153 | var user_id = req.api_user._id; 154 | var id = req.params.{{model}}_id; 155 | {{entity}}.updateById(id, {{keypair}}, function (err, {{model}}) { 156 | if (err) { 157 | return res.api_error(err); 158 | } 159 | 160 | res.api({ 161 | {{model}} : {{model}}, 162 | redirect : '/{{models}}/' + id 163 | }) 164 | }); 165 | }, 166 | delete: function (req, res, next) { 167 | var user_id = req.api_user._id; 168 | var id = req.params.{{model}}_id; 169 | 170 | {{entity}}.deleteById(id, function (err) { 171 | if (err) { 172 | return res.api_error(err); 173 | } 174 | 175 | res.api({id: id}) 176 | }); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /tpl/models/movie.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by alfred on {{created_at}}. 3 | */ 4 | 5 | var mongoose = require('mongoose'); 6 | var Schema = mongoose.Schema; 7 | var MongooseDao = require('mongoosedao'); 8 | 9 | var {{model}}Schema = new Schema( 10 | {{{mongoose_attrs}}} 11 | ); 12 | 13 | var {{entity}} = mongoose.model('{{entity}}', {{model}}Schema); 14 | var {{entity}}Dao = new MongooseDao({{entity}}); 15 | 16 | module.exports = {{entity}}Dao; -------------------------------------------------------------------------------- /tpl/routes/api/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /tpl/routes/api/movie.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | // var res_api = require('res.api'); 5 | var $ = require('mount-controllers')(__dirname).{{models}}_controller; 6 | 7 | var $middlewares = require('mount-middlewares')(__dirname); 8 | 9 | // route define 10 | router.get('/', $middlewares.check_api_token, $.api.list); 11 | 12 | router.post('/', $middlewares.check_api_token, $.api.create); 13 | 14 | router.get('/:{{model}}_id', $middlewares.check_api_token, $.api.show); 15 | 16 | router.patch('/:{{model}}_id', $middlewares.check_api_token, $.api.update); 17 | 18 | router.delete('/:{{model}}_id', $middlewares.check_api_token, $.api.delete); 19 | 20 | 21 | module.exports = router; 22 | -------------------------------------------------------------------------------- /tpl/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /tpl/routes/movies.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | // mount all middlewares in app/middlewares, examples: 5 | // 6 | // router.route('/') 7 | // .get($middlewares.check_session_is_expired, $.list) 8 | // .post($.create); 9 | // 10 | var $middlewares = require('mount-middlewares')(__dirname); 11 | 12 | // core controller 13 | var $ = require('mount-controllers')(__dirname).{{models}}_controller; 14 | 15 | 16 | /** 17 | * Auto generate RESTful url routes. 18 | * 19 | * URL routes: 20 | * 21 | * GET /{{models}}[/] => {{model}}.list() 22 | * GET /{{models}}/new => {{model}}.new() 23 | * GET /{{models}}/:id => {{model}}.show() 24 | * GET /{{models}}/:id/edit => {{model}}.edit() 25 | * POST /{{models}}[/] => {{model}}.create() 26 | * PATCH /{{models}}/:id => {{model}}.update() 27 | * DELETE /{{models}}/:id => {{model}}.destroy() 28 | * 29 | */ 30 | 31 | router.get('/new', $.new); 32 | router.get('/:id/edit', $.edit); 33 | 34 | router.route('/') 35 | .get($.list) 36 | .post($.create); 37 | 38 | router.route('/:id') 39 | .patch($.update) 40 | .get($.show) 41 | .delete($.destroy); 42 | 43 | 44 | // -- custom routes 45 | 46 | 47 | 48 | 49 | module.exports = router; -------------------------------------------------------------------------------- /tpl/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /tpl/views/movies/edit.jade: -------------------------------------------------------------------------------- 1 | extends ../layouts/layout 2 | 3 | block content 4 | h1 Editing {{model}} 5 | 6 | include {{model}} 7 | 8 | a(href='/{{models}}/#{ {{model}}._id}') Show 9 | span | 10 | a(href='/{{models}}') Back 11 | 12 | -------------------------------------------------------------------------------- /tpl/views/movies/index.jade: -------------------------------------------------------------------------------- 1 | extends ../layouts/layout 2 | 3 | block content 4 | h1 Listing {{models}} 5 | 6 | table 7 | thead 8 | tr 9 | each n in [{{{keys}}}] 10 | th #{n} 11 | th(colspan="3") 12 | tbody 13 | each {{model}} in {{models}} 14 | tr 15 | each n in [{{{model_dot_attrs}}}] 16 | td #{ eval(n) } 17 | td 18 | a(href='/{{models}}/#{ {{model}}._id}') Show 19 | td 20 | a(href='/{{models}}/#{ {{model}}._id}/edit') Edit 21 | td 22 | a(onclick="click_del('/{{models}}/#{ {{model}}._id}/')") Delete 23 | 24 | br 25 | 26 | p 27 | a(href='/{{models}}/new') New {{entity}} 28 | -------------------------------------------------------------------------------- /tpl/views/movies/movie.jade: -------------------------------------------------------------------------------- 1 | - var _action = {{model}}._action == 'edit' ? '#' : '/{{models}}/' 2 | - var _method = {{model}}._action == 'edit' ? "" : "post" 3 | - var _type = {{model}}._action == 'edit' ? "button" : "submit" 4 | - var onClick = {{model}}._action == 'edit' ? "click_edit('{{model}}-" + {{model}}._action + "-form','/{{models}}/" + {{model}}._id + "/')" : "" 5 | form(id='{{model}}-#{ {{model}}._action}-form',action="#{_action}", method="#{_method}",role='form') 6 | each n in [{{{model_dot_attrs}}}] 7 | - m = eval(n); 8 | div(class="field") 9 | label #{n.split('.')[1]} #{m} 10 | br 11 | input(type='text',name="#{n.split('.')[1]}" ,value="#{ m == undefined ? '' : m }") 12 | 13 | div(class="actions") 14 | input(type='#{_type}',value='Submit',onClick='#{onClick}') -------------------------------------------------------------------------------- /tpl/views/movies/new.jade: -------------------------------------------------------------------------------- 1 | extends ../layouts/layout 2 | 3 | block content 4 | h1 New {{model}} 5 | 6 | include {{model}} 7 | 8 | a(href='/{{models}}') Back 9 | -------------------------------------------------------------------------------- /tpl/views/movies/show.jade: -------------------------------------------------------------------------------- 1 | extends ../layouts/layout 2 | 3 | block content 4 | p#notice 5 | 6 | each n in [{{{model_dot_attrs}}}] 7 | p 8 | strong #{n.split('.')[1]}: 9 | span #{eval(n)} 10 | 11 | a(href='/{{models}}/#{ {{model}}._id}/edit') Edit 12 | span | 13 | a(href='/{{models}}') Back --------------------------------------------------------------------------------