├── .gitignore ├── LICENSE ├── README.md ├── express ├── app.js └── package.json ├── koa ├── LICENSE ├── README.md ├── app.js ├── config.js ├── lib │ ├── db.js │ └── require-dir.js ├── middleware │ └── index.js ├── model │ ├── index.js │ └── models │ │ └── user.js ├── package.json └── router │ ├── index.js │ └── routers │ ├── index.js │ └── test.js ├── nodejs └── index.js ├── sails ├── .editorconfig ├── .gitignore ├── .sailsrc ├── Gruntfile.js ├── README.md ├── api │ ├── controllers │ │ ├── .gitkeep │ │ └── IndexController.js │ ├── models │ │ └── .gitkeep │ ├── policies │ │ └── sessionAuth.js │ ├── responses │ │ ├── badRequest.js │ │ ├── forbidden.js │ │ ├── notFound.js │ │ ├── ok.js │ │ └── serverError.js │ └── services │ │ └── .gitkeep ├── app.js ├── assets │ ├── favicon.ico │ ├── images │ │ └── .gitkeep │ ├── js │ │ └── dependencies │ │ │ └── sails.io.js │ ├── robots.txt │ ├── styles │ │ └── importer.less │ └── templates │ │ └── .gitkeep ├── config │ ├── blueprints.js │ ├── bootstrap.js │ ├── connections.js │ ├── cors.js │ ├── csrf.js │ ├── env │ │ ├── development.js │ │ └── production.js │ ├── globals.js │ ├── http.js │ ├── i18n.js │ ├── locales │ │ ├── _README.md │ │ ├── de.json │ │ ├── en.json │ │ ├── es.json │ │ └── fr.json │ ├── log.js │ ├── models.js │ ├── policies.js │ ├── routes.js │ ├── session.js │ ├── sockets.js │ └── views.js ├── package.json ├── tasks │ ├── README.md │ ├── config │ │ ├── clean.js │ │ ├── coffee.js │ │ ├── concat.js │ │ ├── copy.js │ │ ├── cssmin.js │ │ ├── jst.js │ │ ├── less.js │ │ ├── sails-linker.js │ │ ├── sync.js │ │ ├── uglify.js │ │ └── watch.js │ ├── pipeline.js │ └── register │ │ ├── build.js │ │ ├── buildProd.js │ │ ├── compileAssets.js │ │ ├── default.js │ │ ├── linkAssets.js │ │ ├── linkAssetsBuild.js │ │ ├── linkAssetsBuildProd.js │ │ ├── prod.js │ │ └── syncAssets.js └── views │ ├── 403.ejs │ ├── 404.ejs │ ├── 500.ejs │ ├── homepage.ejs │ └── layout.ejs └── thinkjs ├── .gitignore ├── .thinkjsrc ├── README.md ├── nginx.conf ├── package.json ├── pm2.json ├── src ├── common │ ├── bootstrap │ │ ├── global.js │ │ └── middleware.js │ ├── config │ │ ├── config.js │ │ ├── db.js │ │ ├── env │ │ │ ├── development.js │ │ │ ├── production.js │ │ │ └── testing.js │ │ ├── error.js │ │ ├── hook.js │ │ ├── locale │ │ │ └── en.js │ │ ├── session.js │ │ └── view.js │ └── controller │ │ └── error.js └── home │ ├── config │ └── config.js │ ├── controller │ ├── base.js │ └── index.js │ ├── logic │ └── index.js │ └── model │ └── index.js ├── view ├── common │ ├── error_400.html │ ├── error_403.html │ ├── error_404.html │ ├── error_500.html │ └── error_503.html └── home │ └── index_index.html └── www ├── README.md ├── development.js ├── production.js └── testing.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 ThinkJS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # performance 2 | ThinkJS Performance vs Koa, Express, Sails.js 3 | -------------------------------------------------------------------------------- /express/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express') 2 | var app = express(); 3 | 4 | app.get('/', function (req, res) { 5 | res.send('Hello World') 6 | }); 7 | app.get('/index/index', function (req, res) { 8 | res.send('Hello World') 9 | }) 10 | console.log('port', 8360) 11 | app.listen(8360) -------------------------------------------------------------------------------- /express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.13.3" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /koa/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Rekey 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | * Neither the name of the {organization} nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /koa/README.md: -------------------------------------------------------------------------------- 1 | #Movie Restful Api -------------------------------------------------------------------------------- /koa/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | const Koa = require('koa'); 6 | const app = new Koa(); 7 | global.Application = app; 8 | 9 | //const middleware = require('./middleware/index.js'); 10 | const router = require('./router/index.js'); 11 | const config = require('./config.js'); 12 | //const db = require('./lib/db.js'); 13 | const co = require('co'); 14 | 15 | 16 | // require('./model/index.js'); 17 | //middleware.init(); 18 | router.init(); 19 | 20 | co(function *() { 21 | try { 22 | //yield db.init(); 23 | app.listen(config.port); 24 | console.log('Application is run on', config.port); 25 | } catch (e) { 26 | console.error(e); 27 | } 28 | }); -------------------------------------------------------------------------------- /koa/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | module.exports = { 6 | "ip": "127.0.0.1", 7 | "port": 8360, 8 | "db": { 9 | url: 'mongodb://user:password@ip/db' 10 | } 11 | }; -------------------------------------------------------------------------------- /koa/lib/db.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | const mongoose = require('mongoose'); 6 | const config = require('../config.js'); 7 | const defer = Promise.defer(); 8 | 9 | console.time('connect'); 10 | mongoose.connect(config.db.url, function () { 11 | console.timeEnd('connect'); 12 | defer.resolve(); 13 | }); 14 | 15 | module.exports = { 16 | init: function () { 17 | return defer.promise; 18 | } 19 | }; -------------------------------------------------------------------------------- /koa/lib/require-dir.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | const fs = require('fs'); 6 | const path = require('path'); 7 | const dict = { 8 | '.js': true, 9 | '.json': true 10 | }; 11 | module.exports = function (dirName, resolveDirName) { 12 | let requireDir = path.resolve(resolveDirName, dirName); 13 | let files = fs.readdirSync(requireDir); 14 | let imports = {}; 15 | files.forEach(function (file) { 16 | let extname = path.extname(file); 17 | let importName = file.replace(extname, ''); 18 | if (dict[extname]) { 19 | imports[importName] = require(path.resolve(requireDir, file)); 20 | } 21 | }); 22 | return imports; 23 | }; -------------------------------------------------------------------------------- /koa/middleware/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | const body = require('koa-better-body'); 6 | const app = global.Application; 7 | 8 | function init() { 9 | console.log('middleware init.'); 10 | //Response Time 11 | app.use(function *responseTime(next) { 12 | this.trace = { 13 | startTime: Date.now() 14 | }; 15 | yield next; 16 | let delta = Math.ceil(Date.now() - this.trace.startTime); 17 | let xResponseTime = delta + 'ms'; 18 | this.set('X-Response-Time', xResponseTime); 19 | //console.log(this.path, this.method, delta + 'ms'); 20 | delta = null; 21 | xResponseTime = null; 22 | }); 23 | //Http Request Body 24 | app.use(body({ 25 | extendTypes: { 26 | // will parse application/x-javascript type body as a JSON string 27 | json: ['application/x-javascript'], 28 | multipart: ['multipart/mixed'] 29 | } 30 | })); 31 | } 32 | 33 | module.exports = { 34 | init: init 35 | }; -------------------------------------------------------------------------------- /koa/model/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | const requireDir = require('../lib/require-dir.js'); 6 | const models = requireDir('./models', __dirname); 7 | console.log('models init.'); 8 | module.exports = models; -------------------------------------------------------------------------------- /koa/model/models/user.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | const mongoose = require('mongoose'); 6 | const userSchema = mongoose.Schema({ 7 | name: { 8 | 'type': String 9 | }, 10 | password: { 11 | 'type': String 12 | } 13 | }); 14 | module.exports = mongoose.model('user', userSchema); -------------------------------------------------------------------------------- /koa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "movie-api", 3 | "version": "0.0.1", 4 | "dependencies": { 5 | "co": "^4.6.0", 6 | "koa": "^1.1.2", 7 | "koa-better-body": "^1.0.17", 8 | "koa-router": "^5.3.0", 9 | "moment": "^2.10.6", 10 | "mongoose": "^4.3.1", 11 | "request": "^2.67.0" 12 | } 13 | } -------------------------------------------------------------------------------- /koa/router/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | const requireDir = require('../lib/require-dir.js'); 6 | function init() { 7 | console.log('router init.'); 8 | requireDir('./routers', __dirname); 9 | } 10 | module.exports = { 11 | init: init 12 | }; -------------------------------------------------------------------------------- /koa/router/routers/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | const koaRouter = require('koa-router'); 6 | const router = new koaRouter(); 7 | const app = global.Application; 8 | 9 | router.get('/', function *indexAction(next) { 10 | this.body = 'hello world'; 11 | yield next; 12 | }); 13 | router.get('/index/index', function *indexAction(next) { 14 | this.body = 'hello world'; 15 | yield next; 16 | }); 17 | 18 | app.use(router.routes()); -------------------------------------------------------------------------------- /koa/router/routers/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Rekey on 15/12/18. 3 | */ 4 | 'use strict'; 5 | const koaRouter = require('koa-router'); 6 | const router = new koaRouter(); 7 | const app = global.Application; 8 | 9 | router.get('/test', function *indexAction(next) { 10 | this.body = 'hello world.'; 11 | yield next; 12 | }); 13 | 14 | app.use(router.routes()); -------------------------------------------------------------------------------- /nodejs/index.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | 3 | const hostname = '127.0.0.1'; 4 | const port = 8360; 5 | 6 | http.createServer((req, res) => { 7 | res.writeHead(200, { 'Content-Type': 'text/plain' }); 8 | res.end('Hello World\n'); 9 | }).listen(port, '', () => { 10 | console.log(`Server running at http://${hostname}:${port}/`); 11 | }); -------------------------------------------------------------------------------- /sails/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | -------------------------------------------------------------------------------- /sails/.gitignore: -------------------------------------------------------------------------------- 1 | ################################################ 2 | ############### .gitignore ################## 3 | ################################################ 4 | # 5 | # This file is only relevant if you are using git. 6 | # 7 | # Files which match the splat patterns below will 8 | # be ignored by git. This keeps random crap and 9 | # and sensitive credentials from being uploaded to 10 | # your repository. It allows you to configure your 11 | # app for your machine without accidentally 12 | # committing settings which will smash the local 13 | # settings of other developers on your team. 14 | # 15 | # Some reasonable defaults are included below, 16 | # but, of course, you should modify/extend/prune 17 | # to fit your needs! 18 | ################################################ 19 | 20 | 21 | 22 | 23 | ################################################ 24 | # Local Configuration 25 | # 26 | # Explicitly ignore files which contain: 27 | # 28 | # 1. Sensitive information you'd rather not push to 29 | # your git repository. 30 | # e.g., your personal API keys or passwords. 31 | # 32 | # 2. Environment-specific configuration 33 | # Basically, anything that would be annoying 34 | # to have to change every time you do a 35 | # `git pull` 36 | # e.g., your local development database, or 37 | # the S3 bucket you're using for file uploads 38 | # development. 39 | # 40 | ################################################ 41 | 42 | config/local.js 43 | 44 | 45 | 46 | 47 | 48 | ################################################ 49 | # Dependencies 50 | # 51 | # When releasing a production app, you may 52 | # consider including your node_modules and 53 | # bower_components directory in your git repo, 54 | # but during development, its best to exclude it, 55 | # since different developers may be working on 56 | # different kernels, where dependencies would 57 | # need to be recompiled anyway. 58 | # 59 | # More on that here about node_modules dir: 60 | # http://www.futurealoof.com/posts/nodemodules-in-git.html 61 | # (credit Mikeal Rogers, @mikeal) 62 | # 63 | # About bower_components dir, you can see this: 64 | # http://addyosmani.com/blog/checking-in-front-end-dependencies/ 65 | # (credit Addy Osmani, @addyosmani) 66 | # 67 | ################################################ 68 | 69 | node_modules 70 | bower_components 71 | 72 | 73 | 74 | 75 | ################################################ 76 | # Sails.js / Waterline / Grunt 77 | # 78 | # Files generated by Sails and Grunt, or related 79 | # tasks and adapters. 80 | ################################################ 81 | .tmp 82 | dump.rdb 83 | 84 | 85 | 86 | 87 | 88 | ################################################ 89 | # Node.js / NPM 90 | # 91 | # Common files generated by Node, NPM, and the 92 | # related ecosystem. 93 | ################################################ 94 | lib-cov 95 | *.seed 96 | *.log 97 | *.out 98 | *.pid 99 | npm-debug.log 100 | 101 | 102 | 103 | 104 | 105 | ################################################ 106 | # Miscellaneous 107 | # 108 | # Common files generated by text editors, 109 | # operating systems, file systems, etc. 110 | ################################################ 111 | 112 | *~ 113 | *# 114 | .DS_STORE 115 | .netbeans 116 | nbproject 117 | .idea 118 | .node_history 119 | -------------------------------------------------------------------------------- /sails/.sailsrc: -------------------------------------------------------------------------------- 1 | { 2 | "generators": { 3 | "modules": {} 4 | } 5 | } -------------------------------------------------------------------------------- /sails/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gruntfile 3 | * 4 | * This Node script is executed when you run `grunt` or `sails lift`. 5 | * It's purpose is to load the Grunt tasks in your project's `tasks` 6 | * folder, and allow you to add and remove tasks as you see fit. 7 | * For more information on how this works, check out the `README.md` 8 | * file that was generated in your `tasks` folder. 9 | * 10 | * WARNING: 11 | * Unless you know what you're doing, you shouldn't change this file. 12 | * Check out the `tasks` directory instead. 13 | */ 14 | 15 | module.exports = function(grunt) { 16 | 17 | 18 | // Load the include-all library in order to require all of our grunt 19 | // configurations and task registrations dynamically. 20 | var includeAll; 21 | try { 22 | includeAll = require('include-all'); 23 | } catch (e0) { 24 | try { 25 | includeAll = require('sails/node_modules/include-all'); 26 | } 27 | catch(e1) { 28 | console.error('Could not find `include-all` module.'); 29 | console.error('Skipping grunt tasks...'); 30 | console.error('To fix this, please run:'); 31 | console.error('npm install include-all --save`'); 32 | console.error(); 33 | 34 | grunt.registerTask('default', []); 35 | return; 36 | } 37 | } 38 | 39 | 40 | /** 41 | * Loads Grunt configuration modules from the specified 42 | * relative path. These modules should export a function 43 | * that, when run, should either load/configure or register 44 | * a Grunt task. 45 | */ 46 | function loadTasks(relPath) { 47 | return includeAll({ 48 | dirname: require('path').resolve(__dirname, relPath), 49 | filter: /(.+)\.js$/ 50 | }) || {}; 51 | } 52 | 53 | /** 54 | * Invokes the function from a Grunt configuration module with 55 | * a single argument - the `grunt` object. 56 | */ 57 | function invokeConfigFn(tasks) { 58 | for (var taskName in tasks) { 59 | if (tasks.hasOwnProperty(taskName)) { 60 | tasks[taskName](grunt); 61 | } 62 | } 63 | } 64 | 65 | 66 | 67 | 68 | // Load task functions 69 | var taskConfigurations = loadTasks('./tasks/config'), 70 | registerDefinitions = loadTasks('./tasks/register'); 71 | 72 | // (ensure that a default task exists) 73 | if (!registerDefinitions.default) { 74 | registerDefinitions.default = function (grunt) { grunt.registerTask('default', []); }; 75 | } 76 | 77 | // Run task functions to configure Grunt. 78 | invokeConfigFn(taskConfigurations); 79 | invokeConfigFn(registerDefinitions); 80 | 81 | }; 82 | -------------------------------------------------------------------------------- /sails/README.md: -------------------------------------------------------------------------------- 1 | # sails 2 | 3 | a [Sails](http://sailsjs.org) application 4 | -------------------------------------------------------------------------------- /sails/api/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkjs/thinkjs-performance-test/711d8a0db34a75a1c4eee9e7e2ed01fb271918a8/sails/api/controllers/.gitkeep -------------------------------------------------------------------------------- /sails/api/controllers/IndexController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * IndexController 3 | * 4 | * @description :: Server-side logic for managing indices 5 | * @help :: See http://links.sailsjs.org/docs/controllers 6 | */ 7 | 8 | module.exports = { 9 | index: function(req, res){ 10 | return res.send("hello word"); 11 | } 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /sails/api/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkjs/thinkjs-performance-test/711d8a0db34a75a1c4eee9e7e2ed01fb271918a8/sails/api/models/.gitkeep -------------------------------------------------------------------------------- /sails/api/policies/sessionAuth.js: -------------------------------------------------------------------------------- 1 | /** 2 | * sessionAuth 3 | * 4 | * @module :: Policy 5 | * @description :: Simple policy to allow any authenticated user 6 | * Assumes that your login action in one of your controllers sets `req.session.authenticated = true;` 7 | * @docs :: http://sailsjs.org/#!documentation/policies 8 | * 9 | */ 10 | module.exports = function(req, res, next) { 11 | 12 | // User is allowed, proceed to the next policy, 13 | // or if this is the last policy, the controller 14 | if (req.session.authenticated) { 15 | return next(); 16 | } 17 | 18 | // User is not allowed 19 | // (default res.forbidden() behavior can be overridden in `config/403.js`) 20 | return res.forbidden('You are not permitted to perform this action.'); 21 | }; 22 | -------------------------------------------------------------------------------- /sails/api/responses/badRequest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 400 (Bad Request) Handler 3 | * 4 | * Usage: 5 | * return res.badRequest(); 6 | * return res.badRequest(data); 7 | * return res.badRequest(data, 'some/specific/badRequest/view'); 8 | * 9 | * e.g.: 10 | * ``` 11 | * return res.badRequest( 12 | * 'Please choose a valid `password` (6-12 characters)', 13 | * 'trial/signup' 14 | * ); 15 | * ``` 16 | */ 17 | 18 | module.exports = function badRequest(data, options) { 19 | 20 | // Get access to `req`, `res`, & `sails` 21 | var req = this.req; 22 | var res = this.res; 23 | var sails = req._sails; 24 | 25 | // Set status code 26 | res.status(400); 27 | 28 | // Log error to console 29 | if (data !== undefined) { 30 | sails.log.verbose('Sending 400 ("Bad Request") response: \n',data); 31 | } 32 | else sails.log.verbose('Sending 400 ("Bad Request") response'); 33 | 34 | // Only include errors in response if application environment 35 | // is not set to 'production'. In production, we shouldn't 36 | // send back any identifying information about errors. 37 | if (sails.config.environment === 'production') { 38 | data = undefined; 39 | } 40 | 41 | // If the user-agent wants JSON, always respond with JSON 42 | if (req.wantsJSON) { 43 | return res.jsonx(data); 44 | } 45 | 46 | // If second argument is a string, we take that to mean it refers to a view. 47 | // If it was omitted, use an empty object (`{}`) 48 | options = (typeof options === 'string') ? { view: options } : options || {}; 49 | 50 | // If a view was provided in options, serve it. 51 | // Otherwise try to guess an appropriate view, or if that doesn't 52 | // work, just send JSON. 53 | if (options.view) { 54 | return res.view(options.view, { data: data }); 55 | } 56 | 57 | // If no second argument provided, try to serve the implied view, 58 | // but fall back to sending JSON(P) if no view can be inferred. 59 | else return res.guessView({ data: data }, function couldNotGuessView () { 60 | return res.jsonx(data); 61 | }); 62 | 63 | }; 64 | 65 | -------------------------------------------------------------------------------- /sails/api/responses/forbidden.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 403 (Forbidden) Handler 3 | * 4 | * Usage: 5 | * return res.forbidden(); 6 | * return res.forbidden(err); 7 | * return res.forbidden(err, 'some/specific/forbidden/view'); 8 | * 9 | * e.g.: 10 | * ``` 11 | * return res.forbidden('Access denied.'); 12 | * ``` 13 | */ 14 | 15 | module.exports = function forbidden (data, options) { 16 | 17 | // Get access to `req`, `res`, & `sails` 18 | var req = this.req; 19 | var res = this.res; 20 | var sails = req._sails; 21 | 22 | // Set status code 23 | res.status(403); 24 | 25 | // Log error to console 26 | if (data !== undefined) { 27 | sails.log.verbose('Sending 403 ("Forbidden") response: \n',data); 28 | } 29 | else sails.log.verbose('Sending 403 ("Forbidden") response'); 30 | 31 | // Only include errors in response if application environment 32 | // is not set to 'production'. In production, we shouldn't 33 | // send back any identifying information about errors. 34 | if (sails.config.environment === 'production') { 35 | data = undefined; 36 | } 37 | 38 | // If the user-agent wants JSON, always respond with JSON 39 | if (req.wantsJSON) { 40 | return res.jsonx(data); 41 | } 42 | 43 | // If second argument is a string, we take that to mean it refers to a view. 44 | // If it was omitted, use an empty object (`{}`) 45 | options = (typeof options === 'string') ? { view: options } : options || {}; 46 | 47 | // If a view was provided in options, serve it. 48 | // Otherwise try to guess an appropriate view, or if that doesn't 49 | // work, just send JSON. 50 | if (options.view) { 51 | return res.view(options.view, { data: data }); 52 | } 53 | 54 | // If no second argument provided, try to serve the default view, 55 | // but fall back to sending JSON(P) if any errors occur. 56 | else return res.view('403', { data: data }, function (err, html) { 57 | 58 | // If a view error occured, fall back to JSON(P). 59 | if (err) { 60 | // 61 | // Additionally: 62 | // • If the view was missing, ignore the error but provide a verbose log. 63 | if (err.code === 'E_VIEW_FAILED') { 64 | sails.log.verbose('res.forbidden() :: Could not locate view for error page (sending JSON instead). Details: ',err); 65 | } 66 | // Otherwise, if this was a more serious error, log to the console with the details. 67 | else { 68 | sails.log.warn('res.forbidden() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err); 69 | } 70 | return res.jsonx(data); 71 | } 72 | 73 | return res.send(html); 74 | }); 75 | 76 | }; 77 | 78 | -------------------------------------------------------------------------------- /sails/api/responses/notFound.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 404 (Not Found) Handler 3 | * 4 | * Usage: 5 | * return res.notFound(); 6 | * return res.notFound(err); 7 | * return res.notFound(err, 'some/specific/notfound/view'); 8 | * 9 | * e.g.: 10 | * ``` 11 | * return res.notFound(); 12 | * ``` 13 | * 14 | * NOTE: 15 | * If a request doesn't match any explicit routes (i.e. `config/routes.js`) 16 | * or route blueprints (i.e. "shadow routes", Sails will call `res.notFound()` 17 | * automatically. 18 | */ 19 | 20 | module.exports = function notFound (data, options) { 21 | 22 | // Get access to `req`, `res`, & `sails` 23 | var req = this.req; 24 | var res = this.res; 25 | var sails = req._sails; 26 | 27 | // Set status code 28 | res.status(404); 29 | 30 | // Log error to console 31 | if (data !== undefined) { 32 | sails.log.verbose('Sending 404 ("Not Found") response: \n',data); 33 | } 34 | else sails.log.verbose('Sending 404 ("Not Found") response'); 35 | 36 | // Only include errors in response if application environment 37 | // is not set to 'production'. In production, we shouldn't 38 | // send back any identifying information about errors. 39 | if (sails.config.environment === 'production') { 40 | data = undefined; 41 | } 42 | 43 | // If the user-agent wants JSON, always respond with JSON 44 | if (req.wantsJSON) { 45 | return res.jsonx(data); 46 | } 47 | 48 | // If second argument is a string, we take that to mean it refers to a view. 49 | // If it was omitted, use an empty object (`{}`) 50 | options = (typeof options === 'string') ? { view: options } : options || {}; 51 | 52 | // If a view was provided in options, serve it. 53 | // Otherwise try to guess an appropriate view, or if that doesn't 54 | // work, just send JSON. 55 | if (options.view) { 56 | return res.view(options.view, { data: data }); 57 | } 58 | 59 | // If no second argument provided, try to serve the default view, 60 | // but fall back to sending JSON(P) if any errors occur. 61 | else return res.view('404', { data: data }, function (err, html) { 62 | 63 | // If a view error occured, fall back to JSON(P). 64 | if (err) { 65 | // 66 | // Additionally: 67 | // • If the view was missing, ignore the error but provide a verbose log. 68 | if (err.code === 'E_VIEW_FAILED') { 69 | sails.log.verbose('res.notFound() :: Could not locate view for error page (sending JSON instead). Details: ',err); 70 | } 71 | // Otherwise, if this was a more serious error, log to the console with the details. 72 | else { 73 | sails.log.warn('res.notFound() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err); 74 | } 75 | return res.jsonx(data); 76 | } 77 | 78 | return res.send(html); 79 | }); 80 | 81 | }; 82 | 83 | -------------------------------------------------------------------------------- /sails/api/responses/ok.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 200 (OK) Response 3 | * 4 | * Usage: 5 | * return res.ok(); 6 | * return res.ok(data); 7 | * return res.ok(data, 'auth/login'); 8 | * 9 | * @param {Object} data 10 | * @param {String|Object} options 11 | * - pass string to render specified view 12 | */ 13 | 14 | module.exports = function sendOK (data, options) { 15 | 16 | // Get access to `req`, `res`, & `sails` 17 | var req = this.req; 18 | var res = this.res; 19 | var sails = req._sails; 20 | 21 | sails.log.silly('res.ok() :: Sending 200 ("OK") response'); 22 | 23 | // Set status code 24 | res.status(200); 25 | 26 | // If appropriate, serve data as JSON(P) 27 | if (req.wantsJSON) { 28 | return res.jsonx(data); 29 | } 30 | 31 | // If second argument is a string, we take that to mean it refers to a view. 32 | // If it was omitted, use an empty object (`{}`) 33 | options = (typeof options === 'string') ? { view: options } : options || {}; 34 | 35 | // If a view was provided in options, serve it. 36 | // Otherwise try to guess an appropriate view, or if that doesn't 37 | // work, just send JSON. 38 | if (options.view) { 39 | return res.view(options.view, { data: data }); 40 | } 41 | 42 | // If no second argument provided, try to serve the implied view, 43 | // but fall back to sending JSON(P) if no view can be inferred. 44 | else return res.guessView({ data: data }, function couldNotGuessView () { 45 | return res.jsonx(data); 46 | }); 47 | 48 | }; 49 | -------------------------------------------------------------------------------- /sails/api/responses/serverError.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 500 (Server Error) Response 3 | * 4 | * Usage: 5 | * return res.serverError(); 6 | * return res.serverError(err); 7 | * return res.serverError(err, 'some/specific/error/view'); 8 | * 9 | * NOTE: 10 | * If something throws in a policy or controller, or an internal 11 | * error is encountered, Sails will call `res.serverError()` 12 | * automatically. 13 | */ 14 | 15 | module.exports = function serverError (data, options) { 16 | 17 | // Get access to `req`, `res`, & `sails` 18 | var req = this.req; 19 | var res = this.res; 20 | var sails = req._sails; 21 | 22 | // Set status code 23 | res.status(500); 24 | 25 | // Log error to console 26 | if (data !== undefined) { 27 | sails.log.error('Sending 500 ("Server Error") response: \n',data); 28 | } 29 | else sails.log.error('Sending empty 500 ("Server Error") response'); 30 | 31 | // Only include errors in response if application environment 32 | // is not set to 'production'. In production, we shouldn't 33 | // send back any identifying information about errors. 34 | if (sails.config.environment === 'production') { 35 | data = undefined; 36 | } 37 | 38 | // If the user-agent wants JSON, always respond with JSON 39 | if (req.wantsJSON) { 40 | return res.jsonx(data); 41 | } 42 | 43 | // If second argument is a string, we take that to mean it refers to a view. 44 | // If it was omitted, use an empty object (`{}`) 45 | options = (typeof options === 'string') ? { view: options } : options || {}; 46 | 47 | // If a view was provided in options, serve it. 48 | // Otherwise try to guess an appropriate view, or if that doesn't 49 | // work, just send JSON. 50 | if (options.view) { 51 | return res.view(options.view, { data: data }); 52 | } 53 | 54 | // If no second argument provided, try to serve the default view, 55 | // but fall back to sending JSON(P) if any errors occur. 56 | else return res.view('500', { data: data }, function (err, html) { 57 | 58 | // If a view error occured, fall back to JSON(P). 59 | if (err) { 60 | // 61 | // Additionally: 62 | // • If the view was missing, ignore the error but provide a verbose log. 63 | if (err.code === 'E_VIEW_FAILED') { 64 | sails.log.verbose('res.serverError() :: Could not locate view for error page (sending JSON instead). Details: ',err); 65 | } 66 | // Otherwise, if this was a more serious error, log to the console with the details. 67 | else { 68 | sails.log.warn('res.serverError() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err); 69 | } 70 | return res.jsonx(data); 71 | } 72 | 73 | return res.send(html); 74 | }); 75 | 76 | }; 77 | 78 | -------------------------------------------------------------------------------- /sails/api/services/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkjs/thinkjs-performance-test/711d8a0db34a75a1c4eee9e7e2ed01fb271918a8/sails/api/services/.gitkeep -------------------------------------------------------------------------------- /sails/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * app.js 3 | * 4 | * Use `app.js` to run your app without `sails lift`. 5 | * To start the server, run: `node app.js`. 6 | * 7 | * This is handy in situations where the sails CLI is not relevant or useful. 8 | * 9 | * For example: 10 | * => `node app.js` 11 | * => `forever start app.js` 12 | * => `node debug app.js` 13 | * => `modulus deploy` 14 | * => `heroku scale` 15 | * 16 | * 17 | * The same command-line arguments are supported, e.g.: 18 | * `node app.js --silent --port=80 --prod` 19 | */ 20 | 21 | // Ensure we're in the project directory, so relative paths work as expected 22 | // no matter where we actually lift from. 23 | process.chdir(__dirname); 24 | 25 | // Ensure a "sails" can be located: 26 | (function() { 27 | var sails; 28 | try { 29 | sails = require('sails'); 30 | } catch (e) { 31 | console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.'); 32 | console.error('To do that, run `npm install sails`'); 33 | console.error(''); 34 | console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.'); 35 | console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,'); 36 | console.error('but if it doesn\'t, the app will run with the global sails instead!'); 37 | return; 38 | } 39 | 40 | // Try to get `rc` dependency 41 | var rc; 42 | try { 43 | rc = require('rc'); 44 | } catch (e0) { 45 | try { 46 | rc = require('sails/node_modules/rc'); 47 | } catch (e1) { 48 | console.error('Could not find dependency: `rc`.'); 49 | console.error('Your `.sailsrc` file(s) will be ignored.'); 50 | console.error('To resolve this, run:'); 51 | console.error('npm install rc --save'); 52 | rc = function () { return {}; }; 53 | } 54 | } 55 | 56 | 57 | // Start server 58 | sails.lift(rc('sails')); 59 | })(); 60 | -------------------------------------------------------------------------------- /sails/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkjs/thinkjs-performance-test/711d8a0db34a75a1c4eee9e7e2ed01fb271918a8/sails/assets/favicon.ico -------------------------------------------------------------------------------- /sails/assets/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkjs/thinkjs-performance-test/711d8a0db34a75a1c4eee9e7e2ed01fb271918a8/sails/assets/images/.gitkeep -------------------------------------------------------------------------------- /sails/assets/robots.txt: -------------------------------------------------------------------------------- 1 | # The robots.txt file is used to control how search engines index your live URLs. 2 | # See http://www.robotstxt.org/wc/norobots.html for more information. 3 | 4 | 5 | 6 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 7 | # User-Agent: * 8 | # Disallow: / 9 | -------------------------------------------------------------------------------- /sails/assets/styles/importer.less: -------------------------------------------------------------------------------- 1 | /** 2 | * importer.less 3 | * 4 | * By default, new Sails projects are configured to compile this file 5 | * from LESS to CSS. Unlike CSS files, LESS files are not compiled and 6 | * included automatically unless they are imported below. 7 | * 8 | * The LESS files imported below are compiled and included in the order 9 | * they are listed. Mixins, variables, etc. should be imported first 10 | * so that they can be accessed by subsequent LESS stylesheets. 11 | * 12 | * (Just like the rest of the asset pipeline bundled in Sails, you can 13 | * always omit, customize, or replace this behavior with SASS, SCSS, 14 | * or any other Grunt tasks you like.) 15 | */ 16 | 17 | 18 | 19 | // For example: 20 | // 21 | // @import 'variables/colors.less'; 22 | // @import 'mixins/foo.less'; 23 | // @import 'mixins/bar.less'; 24 | // @import 'mixins/baz.less'; 25 | // 26 | // @import 'styleguide.less'; 27 | // @import 'pages/login.less'; 28 | // @import 'pages/signup.less'; 29 | // 30 | // etc. 31 | -------------------------------------------------------------------------------- /sails/assets/templates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkjs/thinkjs-performance-test/711d8a0db34a75a1c4eee9e7e2ed01fb271918a8/sails/assets/templates/.gitkeep -------------------------------------------------------------------------------- /sails/config/blueprints.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Blueprint API Configuration 3 | * (sails.config.blueprints) 4 | * 5 | * These settings are for the global configuration of blueprint routes and 6 | * request options (which impact the behavior of blueprint actions). 7 | * 8 | * You may also override any of these settings on a per-controller basis 9 | * by defining a '_config' key in your controller defintion, and assigning it 10 | * a configuration object with overrides for the settings in this file. 11 | * A lot of the configuration options below affect so-called "CRUD methods", 12 | * or your controllers' `find`, `create`, `update`, and `destroy` actions. 13 | * 14 | * It's important to realize that, even if you haven't defined these yourself, as long as 15 | * a model exists with the same name as the controller, Sails will respond with built-in CRUD 16 | * logic in the form of a JSON API, including support for sort, pagination, and filtering. 17 | * 18 | * For more information on the blueprint API, check out: 19 | * http://sailsjs.org/#/documentation/reference/blueprint-api 20 | * 21 | * For more information on the settings in this file, see: 22 | * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.blueprints.html 23 | * 24 | */ 25 | 26 | module.exports.blueprints = { 27 | 28 | /*************************************************************************** 29 | * * 30 | * Action routes speed up the backend development workflow by * 31 | * eliminating the need to manually bind routes. When enabled, GET, POST, * 32 | * PUT, and DELETE routes will be generated for every one of a controller's * 33 | * actions. * 34 | * * 35 | * If an `index` action exists, additional naked routes will be created for * 36 | * it. Finally, all `actions` blueprints support an optional path * 37 | * parameter, `id`, for convenience. * 38 | * * 39 | * `actions` are enabled by default, and can be OK for production-- * 40 | * however, if you'd like to continue to use controller/action autorouting * 41 | * in a production deployment, you must take great care not to * 42 | * inadvertently expose unsafe/unintentional controller logic to GET * 43 | * requests. * 44 | * * 45 | ***************************************************************************/ 46 | 47 | // actions: true, 48 | 49 | /*************************************************************************** 50 | * * 51 | * RESTful routes (`sails.config.blueprints.rest`) * 52 | * * 53 | * REST blueprints are the automatically generated routes Sails uses to * 54 | * expose a conventional REST API on top of a controller's `find`, * 55 | * `create`, `update`, and `destroy` actions. * 56 | * * 57 | * For example, a BoatController with `rest` enabled generates the * 58 | * following routes: * 59 | * ::::::::::::::::::::::::::::::::::::::::::::::::::::::: * 60 | * GET /boat -> BoatController.find * 61 | * GET /boat/:id -> BoatController.findOne * 62 | * POST /boat -> BoatController.create * 63 | * PUT /boat/:id -> BoatController.update * 64 | * DELETE /boat/:id -> BoatController.destroy * 65 | * * 66 | * `rest` blueprint routes are enabled by default, and are suitable for use * 67 | * in a production scenario, as long you take standard security precautions * 68 | * (combine w/ policies, etc.) * 69 | * * 70 | ***************************************************************************/ 71 | 72 | // rest: true, 73 | 74 | /*************************************************************************** 75 | * * 76 | * Shortcut routes are simple helpers to provide access to a * 77 | * controller's CRUD methods from your browser's URL bar. When enabled, * 78 | * GET, POST, PUT, and DELETE routes will be generated for the * 79 | * controller's`find`, `create`, `update`, and `destroy` actions. * 80 | * * 81 | * `shortcuts` are enabled by default, but should be disabled in * 82 | * production. * 83 | * * 84 | ***************************************************************************/ 85 | 86 | // shortcuts: true, 87 | 88 | /*************************************************************************** 89 | * * 90 | * An optional mount path for all blueprint routes on a controller, * 91 | * including `rest`, `actions`, and `shortcuts`. This allows you to take * 92 | * advantage of blueprint routing, even if you need to namespace your API * 93 | * methods. * 94 | * * 95 | * (NOTE: This only applies to blueprint autoroutes, not manual routes from * 96 | * `sails.config.routes`) * 97 | * * 98 | ***************************************************************************/ 99 | 100 | // prefix: '', 101 | 102 | /*************************************************************************** 103 | * * 104 | * Whether to pluralize controller names in blueprint routes. * 105 | * * 106 | * (NOTE: This only applies to blueprint autoroutes, not manual routes from * 107 | * `sails.config.routes`) * 108 | * * 109 | * For example, REST blueprints for `FooController` with `pluralize` * 110 | * enabled: * 111 | * GET /foos/:id? * 112 | * POST /foos * 113 | * PUT /foos/:id? * 114 | * DELETE /foos/:id? * 115 | * * 116 | ***************************************************************************/ 117 | 118 | // pluralize: false, 119 | 120 | /*************************************************************************** 121 | * * 122 | * Whether the blueprint controllers should populate model fetches with * 123 | * data from other models which are linked by associations * 124 | * * 125 | * If you have a lot of data in one-to-many associations, leaving this on * 126 | * may result in very heavy api calls * 127 | * * 128 | ***************************************************************************/ 129 | 130 | // populate: true, 131 | 132 | /**************************************************************************** 133 | * * 134 | * Whether to run Model.watch() in the find and findOne blueprint actions. * 135 | * Can be overridden on a per-model basis. * 136 | * * 137 | ****************************************************************************/ 138 | 139 | // autoWatch: true, 140 | 141 | /**************************************************************************** 142 | * * 143 | * The default number of records to show in the response from a "find" * 144 | * action. Doubles as the default size of populated arrays if populate is * 145 | * true. * 146 | * * 147 | ****************************************************************************/ 148 | 149 | // defaultLimit: 30 150 | 151 | }; 152 | -------------------------------------------------------------------------------- /sails/config/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Bootstrap 3 | * (sails.config.bootstrap) 4 | * 5 | * An asynchronous bootstrap function that runs before your Sails app gets lifted. 6 | * This gives you an opportunity to set up your data model, run jobs, or perform some special logic. 7 | * 8 | * For more information on bootstrapping your app, check out: 9 | * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.bootstrap.html 10 | */ 11 | 12 | module.exports.bootstrap = function(cb) { 13 | 14 | // It's very important to trigger this callback method when you are finished 15 | // with the bootstrap! (otherwise your server will never lift, since it's waiting on the bootstrap) 16 | cb(); 17 | }; 18 | -------------------------------------------------------------------------------- /sails/config/connections.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Connections 3 | * (sails.config.connections) 4 | * 5 | * `Connections` are like "saved settings" for your adapters. What's the difference between 6 | * a connection and an adapter, you might ask? An adapter (e.g. `sails-mysql`) is generic-- 7 | * it needs some additional information to work (e.g. your database host, password, user, etc.) 8 | * A `connection` is that additional information. 9 | * 10 | * Each model must have a `connection` property (a string) which is references the name of one 11 | * of these connections. If it doesn't, the default `connection` configured in `config/models.js` 12 | * will be applied. Of course, a connection can (and usually is) shared by multiple models. 13 | * . 14 | * Note: If you're using version control, you should put your passwords/api keys 15 | * in `config/local.js`, environment variables, or use another strategy. 16 | * (this is to prevent you inadvertently sensitive credentials up to your repository.) 17 | * 18 | * For more information on configuration, check out: 19 | * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.connections.html 20 | */ 21 | 22 | module.exports.connections = { 23 | 24 | /*************************************************************************** 25 | * * 26 | * Local disk storage for DEVELOPMENT ONLY * 27 | * * 28 | * Installed by default. * 29 | * * 30 | ***************************************************************************/ 31 | localDiskDb: { 32 | adapter: 'sails-disk' 33 | }, 34 | 35 | /*************************************************************************** 36 | * * 37 | * MySQL is the world's most popular relational database. * 38 | * http://en.wikipedia.org/wiki/MySQL * 39 | * * 40 | * Run: npm install sails-mysql * 41 | * * 42 | ***************************************************************************/ 43 | someMysqlServer: { 44 | adapter: 'sails-mysql', 45 | host: 'YOUR_MYSQL_SERVER_HOSTNAME_OR_IP_ADDRESS', 46 | user: 'YOUR_MYSQL_USER', 47 | password: 'YOUR_MYSQL_PASSWORD', 48 | database: 'YOUR_MYSQL_DB' 49 | }, 50 | 51 | /*************************************************************************** 52 | * * 53 | * MongoDB is the leading NoSQL database. * 54 | * http://en.wikipedia.org/wiki/MongoDB * 55 | * * 56 | * Run: npm install sails-mongo * 57 | * * 58 | ***************************************************************************/ 59 | someMongodbServer: { 60 | adapter: 'sails-mongo', 61 | host: 'localhost', 62 | port: 27017, 63 | // user: 'username', 64 | // password: 'password', 65 | // database: 'your_mongo_db_name_here' 66 | }, 67 | 68 | /*************************************************************************** 69 | * * 70 | * PostgreSQL is another officially supported relational database. * 71 | * http://en.wikipedia.org/wiki/PostgreSQL * 72 | * * 73 | * Run: npm install sails-postgresql * 74 | * * 75 | * * 76 | ***************************************************************************/ 77 | somePostgresqlServer: { 78 | adapter: 'sails-postgresql', 79 | host: 'YOUR_POSTGRES_SERVER_HOSTNAME_OR_IP_ADDRESS', 80 | user: 'YOUR_POSTGRES_USER', 81 | password: 'YOUR_POSTGRES_PASSWORD', 82 | database: 'YOUR_POSTGRES_DB' 83 | } 84 | 85 | 86 | /*************************************************************************** 87 | * * 88 | * More adapters: https://github.com/balderdashy/sails * 89 | * * 90 | ***************************************************************************/ 91 | 92 | }; 93 | -------------------------------------------------------------------------------- /sails/config/cors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Cross-Origin Resource Sharing (CORS) Settings 3 | * (sails.config.cors) 4 | * 5 | * CORS is like a more modern version of JSONP-- it allows your server/API 6 | * to successfully respond to requests from client-side JavaScript code 7 | * running on some other domain (e.g. google.com) 8 | * Unlike JSONP, it works with POST, PUT, and DELETE requests 9 | * 10 | * For more information on CORS, check out: 11 | * http://en.wikipedia.org/wiki/Cross-origin_resource_sharing 12 | * 13 | * Note that any of these settings (besides 'allRoutes') can be changed on a per-route basis 14 | * by adding a "cors" object to the route configuration: 15 | * 16 | * '/get foo': { 17 | * controller: 'foo', 18 | * action: 'bar', 19 | * cors: { 20 | * origin: 'http://foobar.com,https://owlhoot.com' 21 | * } 22 | * } 23 | * 24 | * For more information on this configuration file, see: 25 | * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.cors.html 26 | * 27 | */ 28 | 29 | module.exports.cors = { 30 | 31 | /*************************************************************************** 32 | * * 33 | * Allow CORS on all routes by default? If not, you must enable CORS on a * 34 | * per-route basis by either adding a "cors" configuration object to the * 35 | * route config, or setting "cors:true" in the route config to use the * 36 | * default settings below. * 37 | * * 38 | ***************************************************************************/ 39 | 40 | // allRoutes: false, 41 | 42 | /*************************************************************************** 43 | * * 44 | * Which domains which are allowed CORS access? This can be a * 45 | * comma-delimited list of hosts (beginning with http:// or https://) or * 46 | * "*" to allow all domains CORS access. * 47 | * * 48 | ***************************************************************************/ 49 | 50 | // origin: '*', 51 | 52 | /*************************************************************************** 53 | * * 54 | * Allow cookies to be shared for CORS requests? * 55 | * * 56 | ***************************************************************************/ 57 | 58 | // credentials: true, 59 | 60 | /*************************************************************************** 61 | * * 62 | * Which methods should be allowed for CORS requests? This is only used in * 63 | * response to preflight requests (see article linked above for more info) * 64 | * * 65 | ***************************************************************************/ 66 | 67 | // methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD', 68 | 69 | /*************************************************************************** 70 | * * 71 | * Which headers should be allowed for CORS requests? This is only used in * 72 | * response to preflight requests. * 73 | * * 74 | ***************************************************************************/ 75 | 76 | // headers: 'content-type' 77 | 78 | }; 79 | -------------------------------------------------------------------------------- /sails/config/csrf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Cross-Site Request Forgery Protection Settings 3 | * (sails.config.csrf) 4 | * 5 | * CSRF tokens are like a tracking chip. While a session tells the server that a user 6 | * "is who they say they are", a csrf token tells the server "you are where you say you are". 7 | * 8 | * When enabled, all non-GET requests to the Sails server must be accompanied by 9 | * a special token, identified as the '_csrf' parameter. 10 | * 11 | * This option protects your Sails app against cross-site request forgery (or CSRF) attacks. 12 | * A would-be attacker needs not only a user's session cookie, but also this timestamped, 13 | * secret CSRF token, which is refreshed/granted when the user visits a URL on your app's domain. 14 | * 15 | * This allows us to have certainty that our users' requests haven't been hijacked, 16 | * and that the requests they're making are intentional and legitimate. 17 | * 18 | * This token has a short-lived expiration timeline, and must be acquired by either: 19 | * 20 | * (a) For traditional view-driven web apps: 21 | * Fetching it from one of your views, where it may be accessed as 22 | * a local variable, e.g.: 23 | *
24 | * 25 | *
26 | * 27 | * or (b) For AJAX/Socket-heavy and/or single-page apps: 28 | * Sending a GET request to the `/csrfToken` route, where it will be returned 29 | * as JSON, e.g.: 30 | * { _csrf: 'ajg4JD(JGdajhLJALHDa' } 31 | * 32 | * 33 | * Enabling this option requires managing the token in your front-end app. 34 | * For traditional web apps, it's as easy as passing the data from a view into a form action. 35 | * In AJAX/Socket-heavy apps, just send a GET request to the /csrfToken route to get a valid token. 36 | * 37 | * For more information on CSRF, check out: 38 | * http://en.wikipedia.org/wiki/Cross-site_request_forgery 39 | * 40 | * For more information on this configuration file, including info on CSRF + CORS, see: 41 | * http://beta.sailsjs.org/#/documentation/reference/sails.config/sails.config.csrf.html 42 | * 43 | */ 44 | 45 | /**************************************************************************** 46 | * * 47 | * Enabled CSRF protection for your site? * 48 | * * 49 | ****************************************************************************/ 50 | 51 | // module.exports.csrf = false; 52 | 53 | /**************************************************************************** 54 | * * 55 | * You may also specify more fine-grained settings for CSRF, including the * 56 | * domains which are allowed to request the CSRF token via AJAX. These * 57 | * settings override the general CORS settings in your config/cors.js file. * 58 | * * 59 | ****************************************************************************/ 60 | 61 | // module.exports.csrf = { 62 | // grantTokenViaAjax: true, 63 | // origin: '' 64 | // } 65 | -------------------------------------------------------------------------------- /sails/config/env/development.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Development environment settings 3 | * 4 | * This file can include shared settings for a development team, 5 | * such as API keys or remote database passwords. If you're using 6 | * a version control solution for your Sails app, this file will 7 | * be committed to your repository unless you add it to your .gitignore 8 | * file. If your repository will be publicly viewable, don't add 9 | * any private information to this file! 10 | * 11 | */ 12 | 13 | module.exports = { 14 | 15 | port: 8360 16 | /*************************************************************************** 17 | * Set the default database connection for models in the development * 18 | * environment (see config/connections.js and config/models.js ) * 19 | ***************************************************************************/ 20 | 21 | // models: { 22 | // connection: 'someMongodbServer' 23 | // } 24 | 25 | }; 26 | -------------------------------------------------------------------------------- /sails/config/env/production.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Production environment settings 3 | * 4 | * This file can include shared settings for a production environment, 5 | * such as API keys or remote database passwords. If you're using 6 | * a version control solution for your Sails app, this file will 7 | * be committed to your repository unless you add it to your .gitignore 8 | * file. If your repository will be publicly viewable, don't add 9 | * any private information to this file! 10 | * 11 | */ 12 | 13 | module.exports = { 14 | 15 | /*************************************************************************** 16 | * Set the default database connection for models in the production * 17 | * environment (see config/connections.js and config/models.js ) * 18 | ***************************************************************************/ 19 | 20 | // models: { 21 | // connection: 'someMysqlServer' 22 | // }, 23 | 24 | /*************************************************************************** 25 | * Set the port in the production environment to 80 * 26 | ***************************************************************************/ 27 | 28 | // port: 80, 29 | 30 | /*************************************************************************** 31 | * Set the log level in production environment to "silent" * 32 | ***************************************************************************/ 33 | 34 | // log: { 35 | // level: "silent" 36 | // } 37 | 38 | }; 39 | -------------------------------------------------------------------------------- /sails/config/globals.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Global Variable Configuration 3 | * (sails.config.globals) 4 | * 5 | * Configure which global variables which will be exposed 6 | * automatically by Sails. 7 | * 8 | * For more information on configuration, check out: 9 | * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.globals.html 10 | */ 11 | module.exports.globals = { 12 | 13 | port: 8360 14 | 15 | /**************************************************************************** 16 | * * 17 | * Expose the lodash installed in Sails core as a global variable. If this * 18 | * is disabled, like any other node module you can always run npm install * 19 | * lodash --save, then var _ = require('lodash') at the top of any file. * 20 | * * 21 | ****************************************************************************/ 22 | 23 | // _: true, 24 | 25 | /**************************************************************************** 26 | * * 27 | * Expose the async installed in Sails core as a global variable. If this is * 28 | * disabled, like any other node module you can always run npm install async * 29 | * --save, then var async = require('async') at the top of any file. * 30 | * * 31 | ****************************************************************************/ 32 | 33 | // async: true, 34 | 35 | /**************************************************************************** 36 | * * 37 | * Expose the sails instance representing your app. If this is disabled, you * 38 | * can still get access via req._sails. * 39 | * * 40 | ****************************************************************************/ 41 | 42 | // sails: true, 43 | 44 | /**************************************************************************** 45 | * * 46 | * Expose each of your app's services as global variables (using their * 47 | * "globalId"). E.g. a service defined in api/models/NaturalLanguage.js * 48 | * would have a globalId of NaturalLanguage by default. If this is disabled, * 49 | * you can still access your services via sails.services.* * 50 | * * 51 | ****************************************************************************/ 52 | 53 | // services: true, 54 | 55 | /**************************************************************************** 56 | * * 57 | * Expose each of your app's models as global variables (using their * 58 | * "globalId"). E.g. a model defined in api/models/User.js would have a * 59 | * globalId of User by default. If this is disabled, you can still access * 60 | * your models via sails.models.*. * 61 | * * 62 | ****************************************************************************/ 63 | 64 | // models: true 65 | }; 66 | -------------------------------------------------------------------------------- /sails/config/http.js: -------------------------------------------------------------------------------- 1 | /** 2 | * HTTP Server Settings 3 | * (sails.config.http) 4 | * 5 | * Configuration for the underlying HTTP server in Sails. 6 | * Only applies to HTTP requests (not WebSockets) 7 | * 8 | * For more information on configuration, check out: 9 | * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.http.html 10 | */ 11 | 12 | module.exports.http = { 13 | 14 | /**************************************************************************** 15 | * * 16 | * Express middleware to use for every Sails request. To add custom * 17 | * middleware to the mix, add a function to the middleware config object and * 18 | * add its key to the "order" array. The $custom key is reserved for * 19 | * backwards-compatibility with Sails v0.9.x apps that use the * 20 | * `customMiddleware` config option. * 21 | * * 22 | ****************************************************************************/ 23 | 24 | // middleware: { 25 | 26 | /*************************************************************************** 27 | * * 28 | * The order in which middleware should be run for HTTP request. (the Sails * 29 | * router is invoked by the "router" middleware below.) * 30 | * * 31 | ***************************************************************************/ 32 | 33 | // order: [ 34 | // 'startRequestTimer', 35 | // 'cookieParser', 36 | // 'session', 37 | // 'myRequestLogger', 38 | // 'bodyParser', 39 | // 'handleBodyParserError', 40 | // 'compress', 41 | // 'methodOverride', 42 | // 'poweredBy', 43 | // '$custom', 44 | // 'router', 45 | // 'www', 46 | // 'favicon', 47 | // '404', 48 | // '500' 49 | // ], 50 | 51 | /**************************************************************************** 52 | * * 53 | * Example custom middleware; logs each request to the console. * 54 | * * 55 | ****************************************************************************/ 56 | 57 | // myRequestLogger: function (req, res, next) { 58 | // console.log("Requested :: ", req.method, req.url); 59 | // return next(); 60 | // } 61 | 62 | 63 | /*************************************************************************** 64 | * * 65 | * The body parser that will handle incoming multipart HTTP requests. By * 66 | * default as of v0.10, Sails uses * 67 | * [skipper](http://github.com/balderdashy/skipper). See * 68 | * http://www.senchalabs.org/connect/multipart.html for other options. * 69 | * * 70 | ***************************************************************************/ 71 | 72 | // bodyParser: require('skipper') 73 | 74 | // }, 75 | 76 | /*************************************************************************** 77 | * * 78 | * The number of seconds to cache flat files on disk being served by * 79 | * Express static middleware (by default, these files are in `.tmp/public`) * 80 | * * 81 | * The HTTP static cache is only active in a 'production' environment, * 82 | * since that's the only time Express will cache flat-files. * 83 | * * 84 | ***************************************************************************/ 85 | 86 | // cache: 31557600000 87 | }; 88 | -------------------------------------------------------------------------------- /sails/config/i18n.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internationalization / Localization Settings 3 | * (sails.config.i18n) 4 | * 5 | * If your app will touch people from all over the world, i18n (or internationalization) 6 | * may be an important part of your international strategy. 7 | * 8 | * 9 | * For more informationom i18n in Sails, check out: 10 | * http://sailsjs.org/#/documentation/concepts/Internationalization 11 | * 12 | * For a complete list of i18n options, see: 13 | * https://github.com/mashpie/i18n-node#list-of-configuration-options 14 | * 15 | * 16 | */ 17 | 18 | module.exports.i18n = { 19 | 20 | /*************************************************************************** 21 | * * 22 | * Which locales are supported? * 23 | * * 24 | ***************************************************************************/ 25 | 26 | // locales: ['en', 'es', 'fr', 'de'] 27 | 28 | /**************************************************************************** 29 | * * 30 | * What is the default locale for the site? Note that this setting will be * 31 | * overridden for any request that sends an "Accept-Language" header (i.e. * 32 | * most browsers), but it's still useful if you need to localize the * 33 | * response for requests made by non-browser clients (e.g. cURL). * 34 | * * 35 | ****************************************************************************/ 36 | 37 | // defaultLocale: 'en', 38 | 39 | /**************************************************************************** 40 | * * 41 | * Automatically add new keys to locale (translation) files when they are * 42 | * encountered during a request? * 43 | * * 44 | ****************************************************************************/ 45 | 46 | // updateFiles: false, 47 | 48 | /**************************************************************************** 49 | * * 50 | * Path (relative to app root) of directory to store locale (translation) * 51 | * files in. * 52 | * * 53 | ****************************************************************************/ 54 | 55 | // localesDirectory: '/config/locales' 56 | 57 | }; 58 | -------------------------------------------------------------------------------- /sails/config/locales/_README.md: -------------------------------------------------------------------------------- 1 | # Internationalization / Localization Settings 2 | 3 | > Also see the official docs on internationalization/localization: 4 | > http://links.sailsjs.org/docs/config/locales 5 | 6 | ## Locales 7 | All locale files live under `config/locales`. Here is where you can add translations 8 | as JSON key-value pairs. The name of the file should match the language that you are supporting, which allows for automatic language detection based on request headers. 9 | 10 | Here is an example locale stringfile for the Spanish language (`config/locales/es.json`): 11 | ```json 12 | { 13 | "Hello!": "Hola!", 14 | "Hello %s, how are you today?": "¿Hola %s, como estas?", 15 | } 16 | ``` 17 | ## Usage 18 | Locales can be accessed in controllers/policies through `res.i18n()`, or in views through the `__(key)` or `i18n(key)` functions. 19 | Remember that the keys are case sensitive and require exact key matches, e.g. 20 | 21 | ```ejs 22 |

<%= __('Welcome to PencilPals!') %>

23 |

<%= i18n('Hello %s, how are you today?', 'Pencil Maven') %>

24 |

<%= i18n('That\'s right-- you can use either i18n() or __()') %>

25 | ``` 26 | 27 | ## Configuration 28 | Localization/internationalization config can be found in `config/i18n.js`, from where you can set your supported locales. 29 | -------------------------------------------------------------------------------- /sails/config/locales/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Willkommen", 3 | "A brand new app.": "Eine neue App." 4 | } 5 | -------------------------------------------------------------------------------- /sails/config/locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Welcome", 3 | "A brand new app.": "A brand new app." 4 | } 5 | -------------------------------------------------------------------------------- /sails/config/locales/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Bienvenido", 3 | "A brand new app.": "Una aplicación de la nueva marca." 4 | } 5 | -------------------------------------------------------------------------------- /sails/config/locales/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Bienvenue", 3 | "A brand new app.": "Une toute nouvelle application." 4 | } 5 | -------------------------------------------------------------------------------- /sails/config/log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Built-in Log Configuration 3 | * (sails.config.log) 4 | * 5 | * Configure the log level for your app, as well as the transport 6 | * (Underneath the covers, Sails uses Winston for logging, which 7 | * allows for some pretty neat custom transports/adapters for log messages) 8 | * 9 | * For more information on the Sails logger, check out: 10 | * http://sailsjs.org/#/documentation/concepts/Logging 11 | */ 12 | 13 | module.exports.log = { 14 | 15 | /*************************************************************************** 16 | * * 17 | * Valid `level` configs: i.e. the minimum log level to capture with * 18 | * sails.log.*() * 19 | * * 20 | * The order of precedence for log levels from lowest to highest is: * 21 | * silly, verbose, info, debug, warn, error * 22 | * * 23 | * You may also set the level to "silent" to suppress all logs. * 24 | * * 25 | ***************************************************************************/ 26 | 27 | // level: 'info' 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /sails/config/models.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Default model configuration 3 | * (sails.config.models) 4 | * 5 | * Unless you override them, the following properties will be included 6 | * in each of your models. 7 | * 8 | * For more info on Sails models, see: 9 | * http://sailsjs.org/#/documentation/concepts/ORM 10 | */ 11 | 12 | module.exports.models = { 13 | 14 | /*************************************************************************** 15 | * * 16 | * Your app's default connection. i.e. the name of one of your app's * 17 | * connections (see `config/connections.js`) * 18 | * * 19 | ***************************************************************************/ 20 | // connection: 'localDiskDb', 21 | 22 | /*************************************************************************** 23 | * * 24 | * How and whether Sails will attempt to automatically rebuild the * 25 | * tables/collections/etc. in your schema. * 26 | * * 27 | * See http://sailsjs.org/#/documentation/concepts/ORM/model-settings.html * 28 | * * 29 | ***************************************************************************/ 30 | // migrate: 'alter' 31 | 32 | }; 33 | -------------------------------------------------------------------------------- /sails/config/policies.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Policy Mappings 3 | * (sails.config.policies) 4 | * 5 | * Policies are simple functions which run **before** your controllers. 6 | * You can apply one or more policies to a given controller, or protect 7 | * its actions individually. 8 | * 9 | * Any policy file (e.g. `api/policies/authenticated.js`) can be accessed 10 | * below by its filename, minus the extension, (e.g. "authenticated") 11 | * 12 | * For more information on how policies work, see: 13 | * http://sailsjs.org/#/documentation/concepts/Policies 14 | * 15 | * For more information on configuring policies, check out: 16 | * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.policies.html 17 | */ 18 | 19 | 20 | module.exports.policies = { 21 | 22 | /*************************************************************************** 23 | * * 24 | * Default policy for all controllers and actions (`true` allows public * 25 | * access) * 26 | * * 27 | ***************************************************************************/ 28 | 29 | // '*': true, 30 | 31 | /*************************************************************************** 32 | * * 33 | * Here's an example of mapping some policies to run before a controller * 34 | * and its actions * 35 | * * 36 | ***************************************************************************/ 37 | // RabbitController: { 38 | 39 | // Apply the `false` policy as the default for all of RabbitController's actions 40 | // (`false` prevents all access, which ensures that nothing bad happens to our rabbits) 41 | // '*': false, 42 | 43 | // For the action `nurture`, apply the 'isRabbitMother' policy 44 | // (this overrides `false` above) 45 | // nurture : 'isRabbitMother', 46 | 47 | // Apply the `isNiceToAnimals` AND `hasRabbitFood` policies 48 | // before letting any users feed our rabbits 49 | // feed : ['isNiceToAnimals', 'hasRabbitFood'] 50 | // } 51 | }; 52 | -------------------------------------------------------------------------------- /sails/config/routes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Route Mappings 3 | * (sails.config.routes) 4 | * 5 | * Your routes map URLs to views and controllers. 6 | * 7 | * If Sails receives a URL that doesn't match any of the routes below, 8 | * it will check for matching files (images, scripts, stylesheets, etc.) 9 | * in your assets directory. e.g. `http://localhost:1337/images/foo.jpg` 10 | * might match an image file: `/assets/images/foo.jpg` 11 | * 12 | * Finally, if those don't match either, the default 404 handler is triggered. 13 | * See `api/responses/notFound.js` to adjust your app's 404 logic. 14 | * 15 | * Note: Sails doesn't ACTUALLY serve stuff from `assets`-- the default Gruntfile in Sails copies 16 | * flat files from `assets` to `.tmp/public`. This allows you to do things like compile LESS or 17 | * CoffeeScript for the front-end. 18 | * 19 | * For more information on configuring custom routes, check out: 20 | * http://sailsjs.org/#/documentation/concepts/Routes/RouteTargetSyntax.html 21 | */ 22 | 23 | module.exports.routes = { 24 | 25 | /*************************************************************************** 26 | * * 27 | * Make the view located at `views/homepage.ejs` (or `views/homepage.jade`, * 28 | * etc. depending on your default view engine) your home page. * 29 | * * 30 | * (Alternatively, remove this and add an `index.html` file in your * 31 | * `assets` directory) * 32 | * * 33 | ***************************************************************************/ 34 | 35 | '/': { 36 | view: 'homepage' 37 | } 38 | 39 | /*************************************************************************** 40 | * * 41 | * Custom routes here... * 42 | * * 43 | * If a request to a URL doesn't match any of the custom routes above, it * 44 | * is matched against Sails route blueprints. See `config/blueprints.js` * 45 | * for configuration options and examples. * 46 | * * 47 | ***************************************************************************/ 48 | 49 | }; 50 | -------------------------------------------------------------------------------- /sails/config/session.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Session Configuration 3 | * (sails.config.session) 4 | * 5 | * Sails session integration leans heavily on the great work already done by 6 | * Express, but also unifies Socket.io with the Connect session store. It uses 7 | * Connect's cookie parser to normalize configuration differences between Express 8 | * and Socket.io and hooks into Sails' middleware interpreter to allow you to access 9 | * and auto-save to `req.session` with Socket.io the same way you would with Express. 10 | * 11 | * For more information on configuring the session, check out: 12 | * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.session.html 13 | */ 14 | 15 | module.exports.session = { 16 | 17 | /*************************************************************************** 18 | * * 19 | * Session secret is automatically generated when your new app is created * 20 | * Replace at your own risk in production-- you will invalidate the cookies * 21 | * of your users, forcing them to log in again. * 22 | * * 23 | ***************************************************************************/ 24 | secret: '624ad70a38d3ac84dea3b343133632da', 25 | 26 | 27 | /*************************************************************************** 28 | * * 29 | * Set the session cookie expire time The maxAge is set by milliseconds, * 30 | * the example below is for 24 hours * 31 | * * 32 | ***************************************************************************/ 33 | 34 | // cookie: { 35 | // maxAge: 24 * 60 * 60 * 1000 36 | // }, 37 | 38 | /*************************************************************************** 39 | * * 40 | * In production, uncomment the following lines to set up a shared redis * 41 | * session store that can be shared across multiple Sails.js servers * 42 | ***************************************************************************/ 43 | 44 | // adapter: 'redis', 45 | 46 | /*************************************************************************** 47 | * * 48 | * The following values are optional, if no options are set a redis * 49 | * instance running on localhost is expected. Read more about options at: * 50 | * https://github.com/visionmedia/connect-redis * 51 | * * 52 | * * 53 | ***************************************************************************/ 54 | 55 | // host: 'localhost', 56 | // port: 6379, 57 | // ttl: , 58 | // db: 0, 59 | // pass: , 60 | // prefix: 'sess:', 61 | 62 | 63 | /*************************************************************************** 64 | * * 65 | * Uncomment the following lines to use your Mongo adapter as a session * 66 | * store * 67 | * * 68 | ***************************************************************************/ 69 | 70 | // adapter: 'mongo', 71 | // host: 'localhost', 72 | // port: 27017, 73 | // db: 'sails', 74 | // collection: 'sessions', 75 | 76 | /*************************************************************************** 77 | * * 78 | * Optional Values: * 79 | * * 80 | * # Note: url will override other connection settings url: * 81 | * 'mongodb://user:pass@host:port/database/collection', * 82 | * * 83 | ***************************************************************************/ 84 | 85 | // username: '', 86 | // password: '', 87 | // auto_reconnect: false, 88 | // ssl: false, 89 | // stringify: true 90 | 91 | }; 92 | -------------------------------------------------------------------------------- /sails/config/sockets.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WebSocket Server Settings 3 | * (sails.config.sockets) 4 | * 5 | * These settings provide transparent access to the options for Sails' 6 | * encapsulated WebSocket server, as well as some additional Sails-specific 7 | * configuration layered on top. 8 | * 9 | * For more information on sockets configuration, including advanced config options, see: 10 | * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.sockets.html 11 | */ 12 | 13 | module.exports.sockets = { 14 | 15 | 16 | /*************************************************************************** 17 | * * 18 | * Node.js (and consequently Sails.js) apps scale horizontally. It's a * 19 | * powerful, efficient approach, but it involves a tiny bit of planning. At * 20 | * scale, you'll want to be able to copy your app onto multiple Sails.js * 21 | * servers and throw them behind a load balancer. * 22 | * * 23 | * One of the big challenges of scaling an application is that these sorts * 24 | * of clustered deployments cannot share memory, since they are on * 25 | * physically different machines. On top of that, there is no guarantee * 26 | * that a user will "stick" with the same server between requests (whether * 27 | * HTTP or sockets), since the load balancer will route each request to the * 28 | * Sails server with the most available resources. However that means that * 29 | * all room/pubsub/socket processing and shared memory has to be offloaded * 30 | * to a shared, remote messaging queue (usually Redis) * 31 | * * 32 | * Luckily, Socket.io (and consequently Sails.js) apps support Redis for * 33 | * sockets by default. To enable a remote redis pubsub server, uncomment * 34 | * the config below. * 35 | * * 36 | * Worth mentioning is that, if `adapter` config is `redis`, but host/port * 37 | * is left unset, Sails will try to connect to redis running on localhost * 38 | * via port 6379 * 39 | * * 40 | ***************************************************************************/ 41 | // adapter: 'memory', 42 | 43 | // 44 | // -OR- 45 | // 46 | 47 | // adapter: 'redis', 48 | // host: '127.0.0.1', 49 | // port: 6379, 50 | // db: 'sails', 51 | // pass: '' 52 | 53 | 54 | 55 | /*************************************************************************** 56 | * * 57 | * Whether to expose a 'get /__getcookie' route with CORS support that sets * 58 | * a cookie (this is used by the sails.io.js socket client to get access to * 59 | * a 3rd party cookie and to enable sessions). * 60 | * * 61 | * Warning: Currently in this scenario, CORS settings apply to interpreted * 62 | * requests sent via a socket.io connection that used this cookie to * 63 | * connect, even for non-browser clients! (e.g. iOS apps, toasters, node.js * 64 | * unit tests) * 65 | * * 66 | ***************************************************************************/ 67 | 68 | // grant3rdPartyCookie: true, 69 | 70 | 71 | 72 | /*************************************************************************** 73 | * * 74 | * `beforeConnect` * 75 | * * 76 | * This custom beforeConnect function will be run each time BEFORE a new * 77 | * socket is allowed to connect, when the initial socket.io handshake is * 78 | * performed with the server. * 79 | * * 80 | * By default, when a socket tries to connect, Sails allows it, every time. * 81 | * (much in the same way any HTTP request is allowed to reach your routes. * 82 | * If no valid cookie was sent, a temporary session will be created for the * 83 | * connecting socket. * 84 | * * 85 | * If the cookie sent as part of the connetion request doesn't match any * 86 | * known user session, a new user session is created for it. * 87 | * * 88 | * In most cases, the user would already have a cookie since they loaded * 89 | * the socket.io client and the initial HTML pageyou're building. * 90 | * * 91 | * However, in the case of cross-domain requests, it is possible to receive * 92 | * a connection upgrade request WITHOUT A COOKIE (for certain transports) * 93 | * In this case, there is no way to keep track of the requesting user * 94 | * between requests, since there is no identifying information to link * 95 | * him/her with a session. The sails.io.js client solves this by connecting * 96 | * to a CORS/jsonp endpoint first to get a 3rd party cookie(fortunately this* 97 | * works, even in Safari), then opening the connection. * 98 | * * 99 | * You can also pass along a ?cookie query parameter to the upgrade url, * 100 | * which Sails will use in the absense of a proper cookie e.g. (when * 101 | * connecting from the client): * 102 | * io.sails.connect('http://localhost:1337?cookie=smokeybear') * 103 | * * 104 | * Finally note that the user's cookie is NOT (and will never be) accessible* 105 | * from client-side javascript. Using HTTP-only cookies is crucial for your * 106 | * app's security. * 107 | * * 108 | ***************************************************************************/ 109 | // beforeConnect: function(handshake, cb) { 110 | // // `true` allows the connection 111 | // return cb(null, true); 112 | // 113 | // // (`false` would reject the connection) 114 | // }, 115 | 116 | 117 | /*************************************************************************** 118 | * * 119 | * This custom afterDisconnect function will be run each time a socket * 120 | * disconnects * 121 | * * 122 | ***************************************************************************/ 123 | // afterDisconnect: function(session, socket, cb) { 124 | // // By default: do nothing. 125 | // return cb(); 126 | // }, 127 | 128 | 129 | 130 | 131 | 132 | // More configuration options for Sails+Socket.io: 133 | // http://sailsjs.org/#/documentation/reference/sails.config/sails.config.sockets.html 134 | 135 | }; 136 | -------------------------------------------------------------------------------- /sails/config/views.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View Engine Configuration 3 | * (sails.config.views) 4 | * 5 | * Server-sent views are a classic and effective way to get your app up 6 | * and running. Views are normally served from controllers. Below, you can 7 | * configure your templating language/framework of choice and configure 8 | * Sails' layout support. 9 | * 10 | * For more information on views and layouts, check out: 11 | * http://sailsjs.org/#/documentation/concepts/Views 12 | */ 13 | 14 | module.exports.views = { 15 | 16 | /**************************************************************************** 17 | * * 18 | * View engine (aka template language) to use for your app's *server-side* * 19 | * views * 20 | * * 21 | * Sails+Express supports all view engines which implement TJ Holowaychuk's * 22 | * `consolidate.js`, including, but not limited to: * 23 | * * 24 | * ejs, jade, handlebars, mustache underscore, hogan, haml, haml-coffee, * 25 | * dust atpl, eco, ect, jazz, jqtpl, JUST, liquor, QEJS, swig, templayed, * 26 | * toffee, walrus, & whiskers * 27 | * * 28 | * For more options, check out the docs: * 29 | * https://github.com/balderdashy/sails-wiki/blob/0.9/config.views.md#engine * 30 | * * 31 | ****************************************************************************/ 32 | 33 | engine: 'ejs', 34 | 35 | 36 | /**************************************************************************** 37 | * * 38 | * Layouts are simply top-level HTML templates you can use as wrappers for * 39 | * your server-side views. If you're using ejs or jade, you can take * 40 | * advantage of Sails' built-in `layout` support. * 41 | * * 42 | * When using a layout, when one of your views is served, it is injected * 43 | * into the `body` partial defined in the layout. This lets you reuse header * 44 | * and footer logic between views. * 45 | * * 46 | * NOTE: Layout support is only implemented for the `ejs` view engine! * 47 | * For most other engines, it is not necessary, since they implement * 48 | * partials/layouts themselves. In those cases, this config will be * 49 | * silently ignored. * 50 | * * 51 | * The `layout` setting may be set to one of the following: * 52 | * * 53 | * If `false`, layouts will be disabled. Otherwise, if a string is * 54 | * specified, it will be interpreted as the relative path to your layout * 55 | * file from `views/` folder. (the file extension, ".ejs", should be * 56 | * omitted) * 57 | * * 58 | ****************************************************************************/ 59 | 60 | /**************************************************************************** 61 | * * 62 | * Using Multiple Layouts * 63 | * * 64 | * If you're using the default `ejs` or `handlebars` Sails supports the use * 65 | * of multiple `layout` files. To take advantage of this, before rendering a * 66 | * view, override the `layout` local in your controller by setting * 67 | * `res.locals.layout`. (this is handy if you parts of your app's UI look * 68 | * completely different from each other) * 69 | * * 70 | * e.g. your default might be * 71 | * layout: 'layouts/public' * 72 | * * 73 | * But you might override that in some of your controllers with: * 74 | * layout: 'layouts/internal' * 75 | * * 76 | ****************************************************************************/ 77 | 78 | layout: 'layout', 79 | 80 | /**************************************************************************** 81 | * * 82 | * Partials are simply top-level snippets you can leverage to reuse template * 83 | * for your server-side views. If you're using handlebars, you can take * 84 | * advantage of Sails' built-in `partials` support. * 85 | * * 86 | * If `false` or empty partials will be located in the same folder as views. * 87 | * Otherwise, if a string is specified, it will be interpreted as the * 88 | * relative path to your partial files from `views/` folder. * 89 | * * 90 | ****************************************************************************/ 91 | 92 | partials: false 93 | 94 | 95 | }; -------------------------------------------------------------------------------- /sails/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sails", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "a Sails application", 6 | "keywords": [], 7 | "dependencies": { 8 | "sails": "~0.11.0", 9 | "sails-disk": "~0.10.0", 10 | "rc": "~0.5.0", 11 | "include-all": "~0.1.3", 12 | "ejs": "~2.5.7", 13 | "grunt": "0.4.2", 14 | "grunt-sync": "~0.0.4", 15 | "grunt-contrib-copy": "~0.5.0", 16 | "grunt-contrib-clean": "~0.5.0", 17 | "grunt-contrib-concat": "~0.3.0", 18 | "grunt-sails-linker": "~0.9.5", 19 | "grunt-contrib-jst": "~0.6.0", 20 | "grunt-contrib-watch": "~0.5.3", 21 | "grunt-contrib-uglify": "~0.4.0", 22 | "grunt-contrib-cssmin": "~0.9.0", 23 | "grunt-contrib-less": "0.11.1", 24 | "grunt-contrib-coffee": "~0.10.1" 25 | }, 26 | "scripts": { 27 | "start": "node app.js", 28 | "debug": "node debug app.js" 29 | }, 30 | "main": "app.js", 31 | "repository": { 32 | "type": "git", 33 | "url": "git://github.com/welefen/sails.git" 34 | }, 35 | "author": "welefen", 36 | "license": "" 37 | } 38 | -------------------------------------------------------------------------------- /sails/tasks/README.md: -------------------------------------------------------------------------------- 1 | # About the `tasks` folder 2 | 3 | The `tasks` directory is a suite of Grunt tasks and their configurations, bundled for your convenience. The Grunt integration is mainly useful for bundling front-end assets, (like stylesheets, scripts, & markup templates) but it can also be used to run all kinds of development tasks, from browserify compilation to database migrations. 4 | 5 | If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, read on! 6 | 7 | 8 | ### How does this work? 9 | 10 | The asset pipeline bundled in Sails is a set of Grunt tasks configured with conventional defaults designed to make your project more consistent and productive. 11 | 12 | The entire front-end asset workflow in Sails is completely customizable-- while it provides some suggestions out of the box, Sails makes no pretense that it can anticipate all of the needs you'll encounter building the browser-based/front-end portion of your application. Who's to say you're even building an app for a browser? 13 | 14 | 15 | 16 | ### What tasks does Sails run automatically? 17 | 18 | Sails runs some of these tasks (the ones in the `tasks/register` folder) automatically when you run certain commands. 19 | 20 | ###### `sails lift` 21 | 22 | Runs the `default` task (`tasks/register/default.js`). 23 | 24 | ###### `sails lift --prod` 25 | 26 | Runs the `prod` task (`tasks/register/prod.js`). 27 | 28 | ###### `sails www` 29 | 30 | Runs the `build` task (`tasks/register/build.js`). 31 | 32 | ###### `sails www --prod` (production) 33 | 34 | Runs the `buildProd` task (`tasks/register/buildProd.js`). 35 | 36 | 37 | ### Can I customize this for SASS, Angular, client-side Jade templates, etc? 38 | 39 | You can modify, omit, or replace any of these Grunt tasks to fit your requirements. You can also add your own Grunt tasks- just add a `someTask.js` file in the `grunt/config` directory to configure the new task, then register it with the appropriate parent task(s) (see files in `grunt/register/*.js`). 40 | 41 | 42 | ### Do I have to use Grunt? 43 | 44 | Nope! To disable Grunt integration in Sails, just delete your Gruntfile or disable the Grunt hook. 45 | 46 | 47 | ### What if I'm not building a web frontend? 48 | 49 | That's ok! A core tenant of Sails is client-agnosticism-- it's especially designed for building APIs used by all sorts of clients; native Android/iOS/Cordova, serverside SDKs, etc. 50 | 51 | You can completely disable Grunt by following the instructions above. 52 | 53 | If you still want to use Grunt for other purposes, but don't want any of the default web front-end stuff, just delete your project's `assets` folder and remove the front-end oriented tasks from the `grunt/register` and `grunt/config` folders. You can also run `sails new myCoolApi --no-frontend` to omit the `assets` folder and front-end-oriented Grunt tasks for future projects. You can also replace your `sails-generate-frontend` module with alternative community generators, or create your own. This allows `sails new` to create the boilerplate for native iOS apps, Android apps, Cordova apps, SteroidsJS apps, etc. 54 | 55 | -------------------------------------------------------------------------------- /sails/tasks/config/clean.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Clean files and folders. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This grunt task is configured to clean out the contents in the .tmp/public of your 7 | * sails project. 8 | * 9 | * For usage docs see: 10 | * https://github.com/gruntjs/grunt-contrib-clean 11 | */ 12 | module.exports = function(grunt) { 13 | 14 | grunt.config.set('clean', { 15 | dev: ['.tmp/public/**'], 16 | build: ['www'] 17 | }); 18 | 19 | grunt.loadNpmTasks('grunt-contrib-clean'); 20 | }; 21 | -------------------------------------------------------------------------------- /sails/tasks/config/coffee.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Compile CoffeeScript files to JavaScript. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Compiles coffeeScript files from `assest/js` into Javascript and places them into 7 | * `.tmp/public/js` directory. 8 | * 9 | * For usage docs see: 10 | * https://github.com/gruntjs/grunt-contrib-coffee 11 | */ 12 | module.exports = function(grunt) { 13 | 14 | grunt.config.set('coffee', { 15 | dev: { 16 | options: { 17 | bare: true, 18 | sourceMap: true, 19 | sourceRoot: './' 20 | }, 21 | files: [{ 22 | expand: true, 23 | cwd: 'assets/js/', 24 | src: ['**/*.coffee'], 25 | dest: '.tmp/public/js/', 26 | ext: '.js' 27 | }, { 28 | expand: true, 29 | cwd: 'assets/js/', 30 | src: ['**/*.coffee'], 31 | dest: '.tmp/public/js/', 32 | ext: '.js' 33 | }] 34 | } 35 | }); 36 | 37 | grunt.loadNpmTasks('grunt-contrib-coffee'); 38 | }; 39 | -------------------------------------------------------------------------------- /sails/tasks/config/concat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Concatenate files. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Concatenates files javascript and css from a defined array. Creates concatenated files in 7 | * .tmp/public/contact directory 8 | * [concat](https://github.com/gruntjs/grunt-contrib-concat) 9 | * 10 | * For usage docs see: 11 | * https://github.com/gruntjs/grunt-contrib-concat 12 | */ 13 | module.exports = function(grunt) { 14 | 15 | grunt.config.set('concat', { 16 | js: { 17 | src: require('../pipeline').jsFilesToInject, 18 | dest: '.tmp/public/concat/production.js' 19 | }, 20 | css: { 21 | src: require('../pipeline').cssFilesToInject, 22 | dest: '.tmp/public/concat/production.css' 23 | } 24 | }); 25 | 26 | grunt.loadNpmTasks('grunt-contrib-concat'); 27 | }; 28 | -------------------------------------------------------------------------------- /sails/tasks/config/copy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copy files and folders. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * # dev task config 7 | * Copies all directories and files, exept coffescript and less fiels, from the sails 8 | * assets folder into the .tmp/public directory. 9 | * 10 | * # build task config 11 | * Copies all directories nd files from the .tmp/public directory into a www directory. 12 | * 13 | * For usage docs see: 14 | * https://github.com/gruntjs/grunt-contrib-copy 15 | */ 16 | module.exports = function(grunt) { 17 | 18 | grunt.config.set('copy', { 19 | dev: { 20 | files: [{ 21 | expand: true, 22 | cwd: './assets', 23 | src: ['**/*.!(coffee|less)'], 24 | dest: '.tmp/public' 25 | }] 26 | }, 27 | build: { 28 | files: [{ 29 | expand: true, 30 | cwd: '.tmp/public', 31 | src: ['**/*'], 32 | dest: 'www' 33 | }] 34 | } 35 | }); 36 | 37 | grunt.loadNpmTasks('grunt-contrib-copy'); 38 | }; 39 | -------------------------------------------------------------------------------- /sails/tasks/config/cssmin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Compress CSS files. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Minifies css files and places them into .tmp/public/min directory. 7 | * 8 | * For usage docs see: 9 | * https://github.com/gruntjs/grunt-contrib-cssmin 10 | */ 11 | module.exports = function(grunt) { 12 | 13 | grunt.config.set('cssmin', { 14 | dist: { 15 | src: ['.tmp/public/concat/production.css'], 16 | dest: '.tmp/public/min/production.min.css' 17 | } 18 | }); 19 | 20 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 21 | }; 22 | -------------------------------------------------------------------------------- /sails/tasks/config/jst.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Precompiles Underscore templates to a `.jst` file. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * (i.e. basically it takes HTML files and turns them into tiny little 7 | * javascript functions that you pass data to and return HTML. This can 8 | * speed up template rendering on the client, and reduce bandwidth usage.) 9 | * 10 | * For usage docs see: 11 | * https://github.com/gruntjs/grunt-contrib-jst 12 | * 13 | */ 14 | 15 | module.exports = function(grunt) { 16 | 17 | var templateFilesToInject = [ 18 | 'templates/**/*.html' 19 | ]; 20 | 21 | grunt.config.set('jst', { 22 | dev: { 23 | 24 | // To use other sorts of templates, specify a regexp like the example below: 25 | // options: { 26 | // templateSettings: { 27 | // interpolate: /\{\{(.+?)\}\}/g 28 | // } 29 | // }, 30 | 31 | // Note that the interpolate setting above is simply an example of overwriting lodash's 32 | // default interpolation. If you want to parse templates with the default _.template behavior 33 | // (i.e. using
), there's no need to overwrite `templateSettings.interpolate`. 34 | 35 | 36 | files: { 37 | // e.g. 38 | // 'relative/path/from/gruntfile/to/compiled/template/destination' : ['relative/path/to/sourcefiles/**/*.html'] 39 | '.tmp/public/jst.js': require('../pipeline').templateFilesToInject 40 | } 41 | } 42 | }); 43 | 44 | grunt.loadNpmTasks('grunt-contrib-jst'); 45 | }; 46 | -------------------------------------------------------------------------------- /sails/tasks/config/less.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Compiles LESS files into CSS. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Only the `assets/styles/importer.less` is compiled. 7 | * This allows you to control the ordering yourself, i.e. import your 8 | * dependencies, mixins, variables, resets, etc. before other stylesheets) 9 | * 10 | * For usage docs see: 11 | * https://github.com/gruntjs/grunt-contrib-less 12 | */ 13 | module.exports = function(grunt) { 14 | 15 | grunt.config.set('less', { 16 | dev: { 17 | files: [{ 18 | expand: true, 19 | cwd: 'assets/styles/', 20 | src: ['importer.less'], 21 | dest: '.tmp/public/styles/', 22 | ext: '.css' 23 | }] 24 | } 25 | }); 26 | 27 | grunt.loadNpmTasks('grunt-contrib-less'); 28 | }; 29 | -------------------------------------------------------------------------------- /sails/tasks/config/sails-linker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Autoinsert script tags (or other filebased tags) in an html file. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Automatically inject ', 22 | appRoot: '.tmp/public' 23 | }, 24 | files: { 25 | '.tmp/public/**/*.html': require('../pipeline').jsFilesToInject, 26 | 'views/**/*.html': require('../pipeline').jsFilesToInject, 27 | 'views/**/*.ejs': require('../pipeline').jsFilesToInject 28 | } 29 | }, 30 | 31 | devJsRelative: { 32 | options: { 33 | startTag: '', 34 | endTag: '', 35 | fileTmpl: '', 36 | appRoot: '.tmp/public', 37 | relative: true 38 | }, 39 | files: { 40 | '.tmp/public/**/*.html': require('../pipeline').jsFilesToInject, 41 | 'views/**/*.html': require('../pipeline').jsFilesToInject, 42 | 'views/**/*.ejs': require('../pipeline').jsFilesToInject 43 | } 44 | }, 45 | 46 | prodJs: { 47 | options: { 48 | startTag: '', 49 | endTag: '', 50 | fileTmpl: '', 51 | appRoot: '.tmp/public' 52 | }, 53 | files: { 54 | '.tmp/public/**/*.html': ['.tmp/public/min/production.min.js'], 55 | 'views/**/*.html': ['.tmp/public/min/production.min.js'], 56 | 'views/**/*.ejs': ['.tmp/public/min/production.min.js'] 57 | } 58 | }, 59 | 60 | prodJsRelative: { 61 | options: { 62 | startTag: '', 63 | endTag: '', 64 | fileTmpl: '', 65 | appRoot: '.tmp/public', 66 | relative: true 67 | }, 68 | files: { 69 | '.tmp/public/**/*.html': ['.tmp/public/min/production.min.js'], 70 | 'views/**/*.html': ['.tmp/public/min/production.min.js'], 71 | 'views/**/*.ejs': ['.tmp/public/min/production.min.js'] 72 | } 73 | }, 74 | 75 | devStyles: { 76 | options: { 77 | startTag: '', 78 | endTag: '', 79 | fileTmpl: '', 80 | appRoot: '.tmp/public' 81 | }, 82 | 83 | files: { 84 | '.tmp/public/**/*.html': require('../pipeline').cssFilesToInject, 85 | 'views/**/*.html': require('../pipeline').cssFilesToInject, 86 | 'views/**/*.ejs': require('../pipeline').cssFilesToInject 87 | } 88 | }, 89 | 90 | devStylesRelative: { 91 | options: { 92 | startTag: '', 93 | endTag: '', 94 | fileTmpl: '', 95 | appRoot: '.tmp/public', 96 | relative: true 97 | }, 98 | 99 | files: { 100 | '.tmp/public/**/*.html': require('../pipeline').cssFilesToInject, 101 | 'views/**/*.html': require('../pipeline').cssFilesToInject, 102 | 'views/**/*.ejs': require('../pipeline').cssFilesToInject 103 | } 104 | }, 105 | 106 | prodStyles: { 107 | options: { 108 | startTag: '', 109 | endTag: '', 110 | fileTmpl: '', 111 | appRoot: '.tmp/public' 112 | }, 113 | files: { 114 | '.tmp/public/index.html': ['.tmp/public/min/production.min.css'], 115 | 'views/**/*.html': ['.tmp/public/min/production.min.css'], 116 | 'views/**/*.ejs': ['.tmp/public/min/production.min.css'] 117 | } 118 | }, 119 | 120 | prodStylesRelative: { 121 | options: { 122 | startTag: '', 123 | endTag: '', 124 | fileTmpl: '', 125 | appRoot: '.tmp/public', 126 | relative: true 127 | }, 128 | files: { 129 | '.tmp/public/index.html': ['.tmp/public/min/production.min.css'], 130 | 'views/**/*.html': ['.tmp/public/min/production.min.css'], 131 | 'views/**/*.ejs': ['.tmp/public/min/production.min.css'] 132 | } 133 | }, 134 | 135 | // Bring in JST template object 136 | devTpl: { 137 | options: { 138 | startTag: '', 139 | endTag: '', 140 | fileTmpl: '', 141 | appRoot: '.tmp/public' 142 | }, 143 | files: { 144 | '.tmp/public/index.html': ['.tmp/public/jst.js'], 145 | 'views/**/*.html': ['.tmp/public/jst.js'], 146 | 'views/**/*.ejs': ['.tmp/public/jst.js'] 147 | } 148 | }, 149 | 150 | devJsJade: { 151 | options: { 152 | startTag: '// SCRIPTS', 153 | endTag: '// SCRIPTS END', 154 | fileTmpl: 'script(src="%s")', 155 | appRoot: '.tmp/public' 156 | }, 157 | files: { 158 | 'views/**/*.jade': require('../pipeline').jsFilesToInject 159 | } 160 | }, 161 | 162 | devJsRelativeJade: { 163 | options: { 164 | startTag: '// SCRIPTS', 165 | endTag: '// SCRIPTS END', 166 | fileTmpl: 'script(src="%s")', 167 | appRoot: '.tmp/public', 168 | relative: true 169 | }, 170 | files: { 171 | 'views/**/*.jade': require('../pipeline').jsFilesToInject 172 | } 173 | }, 174 | 175 | prodJsJade: { 176 | options: { 177 | startTag: '// SCRIPTS', 178 | endTag: '// SCRIPTS END', 179 | fileTmpl: 'script(src="%s")', 180 | appRoot: '.tmp/public' 181 | }, 182 | files: { 183 | 'views/**/*.jade': ['.tmp/public/min/production.min.js'] 184 | } 185 | }, 186 | 187 | prodJsRelativeJade: { 188 | options: { 189 | startTag: '// SCRIPTS', 190 | endTag: '// SCRIPTS END', 191 | fileTmpl: 'script(src="%s")', 192 | appRoot: '.tmp/public', 193 | relative: true 194 | }, 195 | files: { 196 | 'views/**/*.jade': ['.tmp/public/min/production.min.js'] 197 | } 198 | }, 199 | 200 | devStylesJade: { 201 | options: { 202 | startTag: '// STYLES', 203 | endTag: '// STYLES END', 204 | fileTmpl: 'link(rel="stylesheet", href="%s")', 205 | appRoot: '.tmp/public' 206 | }, 207 | 208 | files: { 209 | 'views/**/*.jade': require('../pipeline').cssFilesToInject 210 | } 211 | }, 212 | 213 | devStylesRelativeJade: { 214 | options: { 215 | startTag: '// STYLES', 216 | endTag: '// STYLES END', 217 | fileTmpl: 'link(rel="stylesheet", href="%s")', 218 | appRoot: '.tmp/public', 219 | relative: true 220 | }, 221 | 222 | files: { 223 | 'views/**/*.jade': require('../pipeline').cssFilesToInject 224 | } 225 | }, 226 | 227 | prodStylesJade: { 228 | options: { 229 | startTag: '// STYLES', 230 | endTag: '// STYLES END', 231 | fileTmpl: 'link(rel="stylesheet", href="%s")', 232 | appRoot: '.tmp/public' 233 | }, 234 | files: { 235 | 'views/**/*.jade': ['.tmp/public/min/production.min.css'] 236 | } 237 | }, 238 | 239 | prodStylesRelativeJade: { 240 | options: { 241 | startTag: '// STYLES', 242 | endTag: '// STYLES END', 243 | fileTmpl: 'link(rel="stylesheet", href="%s")', 244 | appRoot: '.tmp/public', 245 | relative: true 246 | }, 247 | files: { 248 | 'views/**/*.jade': ['.tmp/public/min/production.min.css'] 249 | } 250 | }, 251 | 252 | // Bring in JST template object 253 | devTplJade: { 254 | options: { 255 | startTag: '// TEMPLATES', 256 | endTag: '// TEMPLATES END', 257 | fileTmpl: 'script(type="text/javascript", src="%s")', 258 | appRoot: '.tmp/public' 259 | }, 260 | files: { 261 | 'views/**/*.jade': ['.tmp/public/jst.js'] 262 | } 263 | } 264 | }); 265 | 266 | grunt.loadNpmTasks('grunt-sails-linker'); 267 | }; 268 | -------------------------------------------------------------------------------- /sails/tasks/config/sync.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A grunt task to keep directories in sync. It is very similar to grunt-contrib-copy 3 | * but tries to copy only those files that has actually changed. 4 | * 5 | * --------------------------------------------------------------- 6 | * 7 | * Synchronize files from the `assets` folder to `.tmp/public`, 8 | * smashing anything that's already there. 9 | * 10 | * For usage docs see: 11 | * https://github.com/tomusdrw/grunt-sync 12 | * 13 | */ 14 | module.exports = function(grunt) { 15 | 16 | grunt.config.set('sync', { 17 | dev: { 18 | files: [{ 19 | cwd: './assets', 20 | src: ['**/*.!(coffee)'], 21 | dest: '.tmp/public' 22 | }] 23 | } 24 | }); 25 | 26 | grunt.loadNpmTasks('grunt-sync'); 27 | }; 28 | -------------------------------------------------------------------------------- /sails/tasks/config/uglify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Minify files with UglifyJS. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Minifies client-side javascript `assets`. 7 | * 8 | * For usage docs see: 9 | * https://github.com/gruntjs/grunt-contrib-uglify 10 | * 11 | */ 12 | module.exports = function(grunt) { 13 | 14 | grunt.config.set('uglify', { 15 | dist: { 16 | src: ['.tmp/public/concat/production.js'], 17 | dest: '.tmp/public/min/production.min.js' 18 | } 19 | }); 20 | 21 | grunt.loadNpmTasks('grunt-contrib-uglify'); 22 | }; 23 | -------------------------------------------------------------------------------- /sails/tasks/config/watch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Run predefined tasks whenever watched file patterns are added, changed or deleted. 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Watch for changes on 7 | * - files in the `assets` folder 8 | * - the `tasks/pipeline.js` file 9 | * and re-run the appropriate tasks. 10 | * 11 | * For usage docs see: 12 | * https://github.com/gruntjs/grunt-contrib-watch 13 | * 14 | */ 15 | module.exports = function(grunt) { 16 | 17 | grunt.config.set('watch', { 18 | api: { 19 | 20 | // API files to watch: 21 | files: ['api/**/*', '!**/node_modules/**'] 22 | }, 23 | assets: { 24 | 25 | // Assets to watch: 26 | files: ['assets/**/*', 'tasks/pipeline.js', '!**/node_modules/**'], 27 | 28 | // When assets are changed: 29 | tasks: ['syncAssets' , 'linkAssets'] 30 | } 31 | }); 32 | 33 | grunt.loadNpmTasks('grunt-contrib-watch'); 34 | }; 35 | -------------------------------------------------------------------------------- /sails/tasks/pipeline.js: -------------------------------------------------------------------------------- 1 | /** 2 | * grunt/pipeline.js 3 | * 4 | * The order in which your css, javascript, and template files should be 5 | * compiled and linked from your views and static HTML files. 6 | * 7 | * (Note that you can take advantage of Grunt-style wildcard/glob/splat expressions 8 | * for matching multiple files.) 9 | */ 10 | 11 | 12 | 13 | // CSS files to inject in order 14 | // 15 | // (if you're using LESS with the built-in default config, you'll want 16 | // to change `assets/styles/importer.less` instead.) 17 | var cssFilesToInject = [ 18 | 'styles/**/*.css' 19 | ]; 20 | 21 | 22 | // Client-side javascript files to inject in order 23 | // (uses Grunt-style wildcard/glob/splat expressions) 24 | var jsFilesToInject = [ 25 | 26 | // Load sails.io before everything else 27 | 'js/dependencies/sails.io.js', 28 | 29 | // Dependencies like jQuery, or Angular are brought in here 30 | 'js/dependencies/**/*.js', 31 | 32 | // All of the rest of your client-side js files 33 | // will be injected here in no particular order. 34 | 'js/**/*.js' 35 | ]; 36 | 37 | 38 | // Client-side HTML templates are injected using the sources below 39 | // The ordering of these templates shouldn't matter. 40 | // (uses Grunt-style wildcard/glob/splat expressions) 41 | // 42 | // By default, Sails uses JST templates and precompiles them into 43 | // functions for you. If you want to use jade, handlebars, dust, etc., 44 | // with the linker, no problem-- you'll just want to make sure the precompiled 45 | // templates get spit out to the same file. Be sure and check out `tasks/README.md` 46 | // for information on customizing and installing new tasks. 47 | var templateFilesToInject = [ 48 | 'templates/**/*.html' 49 | ]; 50 | 51 | 52 | 53 | // Prefix relative paths to source files so they point to the proper locations 54 | // (i.e. where the other Grunt tasks spit them out, or in some cases, where 55 | // they reside in the first place) 56 | module.exports.cssFilesToInject = cssFilesToInject.map(function(path) { 57 | return '.tmp/public/' + path; 58 | }); 59 | module.exports.jsFilesToInject = jsFilesToInject.map(function(path) { 60 | return '.tmp/public/' + path; 61 | }); 62 | module.exports.templateFilesToInject = templateFilesToInject.map(function(path) { 63 | return 'assets/' + path; 64 | }); 65 | -------------------------------------------------------------------------------- /sails/tasks/register/build.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.registerTask('build', [ 3 | 'compileAssets', 4 | 'linkAssetsBuild', 5 | 'clean:build', 6 | 'copy:build' 7 | ]); 8 | }; 9 | -------------------------------------------------------------------------------- /sails/tasks/register/buildProd.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.registerTask('buildProd', [ 3 | 'compileAssets', 4 | 'concat', 5 | 'uglify', 6 | 'cssmin', 7 | 'linkAssetsBuildProd', 8 | 'clean:build', 9 | 'copy:build' 10 | ]); 11 | }; 12 | -------------------------------------------------------------------------------- /sails/tasks/register/compileAssets.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.registerTask('compileAssets', [ 3 | 'clean:dev', 4 | 'jst:dev', 5 | 'less:dev', 6 | 'copy:dev', 7 | 'coffee:dev' 8 | ]); 9 | }; 10 | -------------------------------------------------------------------------------- /sails/tasks/register/default.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.registerTask('default', ['compileAssets', 'linkAssets', 'watch']); 3 | }; 4 | -------------------------------------------------------------------------------- /sails/tasks/register/linkAssets.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.registerTask('linkAssets', [ 3 | 'sails-linker:devJs', 4 | 'sails-linker:devStyles', 5 | 'sails-linker:devTpl', 6 | 'sails-linker:devJsJade', 7 | 'sails-linker:devStylesJade', 8 | 'sails-linker:devTplJade' 9 | ]); 10 | }; 11 | -------------------------------------------------------------------------------- /sails/tasks/register/linkAssetsBuild.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.registerTask('linkAssetsBuild', [ 3 | 'sails-linker:devJsRelative', 4 | 'sails-linker:devStylesRelative', 5 | 'sails-linker:devTpl', 6 | 'sails-linker:devJsRelativeJade', 7 | 'sails-linker:devStylesRelativeJade', 8 | 'sails-linker:devTplJade' 9 | ]); 10 | }; 11 | -------------------------------------------------------------------------------- /sails/tasks/register/linkAssetsBuildProd.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.registerTask('linkAssetsBuildProd', [ 3 | 'sails-linker:prodJsRelative', 4 | 'sails-linker:prodStylesRelative', 5 | 'sails-linker:devTpl', 6 | 'sails-linker:prodJsRelativeJade', 7 | 'sails-linker:prodStylesRelativeJade', 8 | 'sails-linker:devTplJade' 9 | ]); 10 | }; 11 | -------------------------------------------------------------------------------- /sails/tasks/register/prod.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.registerTask('prod', [ 3 | 'compileAssets', 4 | 'concat', 5 | 'uglify', 6 | 'cssmin', 7 | 'sails-linker:prodJs', 8 | 'sails-linker:prodStyles', 9 | 'sails-linker:devTpl', 10 | 'sails-linker:prodJsJade', 11 | 'sails-linker:prodStylesJade', 12 | 'sails-linker:devTplJade' 13 | ]); 14 | }; 15 | -------------------------------------------------------------------------------- /sails/tasks/register/syncAssets.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.registerTask('syncAssets', [ 3 | 'jst:dev', 4 | 'less:dev', 5 | 'sync:dev', 6 | 'coffee:dev' 7 | ]); 8 | }; 9 | -------------------------------------------------------------------------------- /sails/views/403.ejs: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | Forbidden 39 | 40 | 44 | 45 | 46 | 47 |
48 |
49 | 50 |
51 | 52 |
53 |

54 | Forbidden 55 |

56 |

57 | <% if (typeof error !== 'undefined') { %> 58 | <%= error %> 59 | <% } else { %> 60 | You don't have permission to see the page you're trying to reach. 61 | <% } %> 62 |

63 |

64 | Why might this be happening? 65 |

66 |
67 | 68 | 73 |
74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /sails/views/404.ejs: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | Page Not Found 39 | 40 | 44 | 45 | 46 | 47 |
48 |
49 | 50 |
51 | 52 |
53 |

54 | Something's fishy here. 55 |

56 |

57 | <% if (typeof error!== 'undefined') { %> 58 | <%= error %> 59 | <% } else { %> 60 | The page you were trying to reach doesn't exist. 61 | <% } %> 62 |

63 |

64 | Why might this be happening? 65 |

66 |
67 | 68 | 73 |
74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /sails/views/homepage.ejs: -------------------------------------------------------------------------------- 1 | hello word -------------------------------------------------------------------------------- /sails/views/layout.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | New Sails App 5 | 6 | 7 | 8 | 9 | 10 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | <%- body %> 38 | 39 | 40 | 41 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /thinkjs/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage/ 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Dependency directory 23 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 24 | node_modules/ 25 | 26 | # IDE config 27 | .idea 28 | 29 | # output 30 | output/ 31 | output.tar.gz 32 | 33 | app/ -------------------------------------------------------------------------------- /thinkjs/.thinkjsrc: -------------------------------------------------------------------------------- 1 | { 2 | "createAt": "2016-01-13 15:17:19", 3 | "mode": "module", 4 | "es": true 5 | } -------------------------------------------------------------------------------- /thinkjs/README.md: -------------------------------------------------------------------------------- 1 | 2 | application created by [ThinkJS](http://www.thinkjs.org) 3 | 4 | ## install dependencies 5 | 6 | ``` 7 | npm install 8 | ``` 9 | 10 | ## start server 11 | 12 | ``` 13 | npm start 14 | ``` 15 | 16 | ## deploy with pm2 17 | 18 | use pm2 to deploy app on production envrioment. 19 | 20 | ``` 21 | pm2 startOrReload pm2.json 22 | ``` -------------------------------------------------------------------------------- /thinkjs/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name example.com www.example.com; 4 | root /Users/welefen/Develop/git/thinkjs-performance-test//Users/welefen/Develop/git/thinkjs-performance-test/thinkjs/www; 5 | set $node_port 8360; 6 | 7 | index index.js index.html index.htm; 8 | if ( -f $request_filename/index.html ){ 9 | rewrite (.*) $1/index.html break; 10 | } 11 | if ( !-f $request_filename ){ 12 | rewrite (.*) /index.js; 13 | } 14 | location = /index.js { 15 | proxy_http_version 1.1; 16 | proxy_set_header X-Real-IP $remote_addr; 17 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 18 | proxy_set_header Host $http_host; 19 | proxy_set_header X-NginX-Proxy true; 20 | proxy_set_header Upgrade $http_upgrade; 21 | proxy_set_header Connection "upgrade"; 22 | proxy_pass http://127.0.0.1:$node_port$request_uri; 23 | proxy_redirect off; 24 | } 25 | 26 | location = /development.js { 27 | deny all; 28 | } 29 | 30 | location = /testing.js { 31 | deny all; 32 | } 33 | 34 | location = /production.js { 35 | deny all; 36 | } 37 | 38 | location ~ /static/ { 39 | etag on; 40 | expires max; 41 | } 42 | } 43 | 44 | 45 | 46 | 47 | ## http/2 nginx conf 48 | 49 | # server { 50 | # listen 80; 51 | # server_name example.com www.example.com; 52 | # rewrite ^(.*) https://example.com$1 permanent; 53 | # } 54 | # 55 | # server { 56 | # listen 443 ssl http2 fastopen=3 reuseport; 57 | # server_name www.thinkjs.org thinkjs.org; 58 | # set $node_port 8360; 59 | # 60 | # root /Users/welefen/Develop/git/thinkjs-performance-test//Users/welefen/Develop/git/thinkjs-performance-test/thinkjs/www; 61 | # 62 | # keepalive_timeout 70; 63 | # 64 | # ssl_certificate /path/to/certificate; 65 | # ssl_certificate_key /path/to/certificate.key; 66 | # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 67 | # ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"; 68 | # ssl_prefer_server_ciphers on; 69 | 70 | # # openssl dhparam -out dhparams.pem 2048 71 | # ssl_dhparam /path/to/dhparams.pem; 72 | # 73 | # ssl_session_cache shared:SSL:10m; 74 | # ssl_session_timeout 10m; 75 | # 76 | # ssl_session_ticket_key /path/to/tls_session_ticket.key; 77 | # ssl_session_tickets on; 78 | # 79 | # ssl_stapling on; 80 | # ssl_stapling_verify on; 81 | # ssl_trusted_certificate /path/to/startssl_trust_chain.crt; 82 | # 83 | # 84 | # add_header x-Content-Type-Options nosniff; 85 | # add_header X-Frame-Options deny; 86 | # add_header Strict-Transport-Security "max-age=16070400"; 87 | # 88 | # index index.js index.html index.htm; 89 | # if ( -f $request_filename/index.html ){ 90 | # rewrite (.*) $1/index.html break; 91 | # } 92 | # if ( !-f $request_filename ){ 93 | # rewrite (.*) /index.js; 94 | # } 95 | # location = /index.js { 96 | # proxy_http_version 1.1; 97 | # proxy_set_header X-Real-IP $remote_addr; 98 | # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 99 | # proxy_set_header Host $http_host; 100 | # proxy_set_header X-NginX-Proxy true; 101 | # proxy_set_header Upgrade $http_upgrade; 102 | # proxy_set_header Connection "upgrade"; 103 | # proxy_pass http://127.0.0.1:$node_port$request_uri; 104 | # proxy_redirect off; 105 | # } 106 | # 107 | # location = /production.js { 108 | # deny all; 109 | # } 110 | # 111 | # location = /testing.js { 112 | # deny all; 113 | # } 114 | # 115 | # location ~ /static/ { 116 | # etag on; 117 | # expires max; 118 | # } 119 | #} 120 | 121 | -------------------------------------------------------------------------------- /thinkjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thinkjs-application", 3 | "description": "application created by thinkjs", 4 | "version": "1.0.0", 5 | "scripts": { 6 | "start": "node www/development.js", 7 | "compile": "babel --presets es2015-loose,stage-1 --plugins transform-runtime src/ --out-dir app/ --retain-lines", 8 | "watch-compile": "node -e \"console.log(' no longer need, use command direct.');console.log();\"", 9 | "watch": "npm run watch-compile" 10 | }, 11 | "dependencies": { 12 | "thinkjs": "2.1.x", 13 | "babel-runtime": "6.x.x" 14 | }, 15 | "devDependencies": { 16 | "babel-cli": "6.x.x", 17 | "babel-preset-es2015-loose": "6.x.x", 18 | "babel-preset-stage-1": "6.x.x", 19 | "babel-plugin-transform-runtime": "6.x.x", 20 | "babel-core": "6.x.x" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /thinkjs/pm2.json: -------------------------------------------------------------------------------- 1 | { 2 | "apps": [{ 3 | "name": "thinkjs", 4 | "script": "www/production.js", 5 | "cwd": "/Users/welefen/Develop/git/thinkjs-performance-test//Users/welefen/Develop/git/thinkjs-performance-test/thinkjs", 6 | "exec_mode": "cluster", 7 | "instances": 0, 8 | "max_memory_restart": "1G", 9 | "autorestart": true, 10 | "node_args": [], 11 | "args": [], 12 | "env": { 13 | 14 | } 15 | }] 16 | } -------------------------------------------------------------------------------- /thinkjs/src/common/bootstrap/global.js: -------------------------------------------------------------------------------- 1 | /** 2 | * this file will be loaded before server started 3 | * you can define global functions used in controllers, models, templates 4 | */ 5 | 6 | /** 7 | * use global.xxx to define global functions 8 | * 9 | * global.fn1 = function(){ 10 | * 11 | * } 12 | */ -------------------------------------------------------------------------------- /thinkjs/src/common/bootstrap/middleware.js: -------------------------------------------------------------------------------- 1 | /** 2 | * this file will be loaded before server started 3 | * you can register middleware 4 | * https://thinkjs.org/doc/middleware.html 5 | */ 6 | 7 | /** 8 | * 9 | * think.middleware('xxx', http => { 10 | * 11 | * }) 12 | * 13 | */ 14 | -------------------------------------------------------------------------------- /thinkjs/src/common/config/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * config 4 | */ 5 | export default { 6 | resource_on: false, 7 | logic_on: false 8 | //key: value 9 | }; -------------------------------------------------------------------------------- /thinkjs/src/common/config/db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * db config 4 | * @type {Object} 5 | */ 6 | export default { 7 | type: 'mysql', 8 | log_sql: true, 9 | log_connect: true, 10 | adapter: { 11 | mysql: { 12 | host: '127.0.0.1', 13 | port: '', 14 | database: '', 15 | user: '', 16 | password: '', 17 | prefix: 'think_', 18 | encoding: 'utf8' 19 | }, 20 | mongo: { 21 | 22 | } 23 | } 24 | }; -------------------------------------------------------------------------------- /thinkjs/src/common/config/env/development.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default { 4 | 5 | }; -------------------------------------------------------------------------------- /thinkjs/src/common/config/env/production.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default { 4 | 5 | }; -------------------------------------------------------------------------------- /thinkjs/src/common/config/env/testing.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default { 4 | 5 | }; -------------------------------------------------------------------------------- /thinkjs/src/common/config/error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * err config 4 | */ 5 | export default { 6 | //key: value 7 | key: "errno", //error number 8 | msg: "errmsg" //error message 9 | }; -------------------------------------------------------------------------------- /thinkjs/src/common/config/hook.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * hook config 5 | * https://thinkjs.org/doc/middleware.html#toc-df6 6 | */ 7 | export default { 8 | 9 | } -------------------------------------------------------------------------------- /thinkjs/src/common/config/locale/en.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default { 4 | 5 | }; -------------------------------------------------------------------------------- /thinkjs/src/common/config/session.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * session configs 5 | */ 6 | export default { 7 | name: 'thinkjs', 8 | type: 'file', 9 | secret: 'ET5KU&69', 10 | timeout: 24 * 3600, 11 | cookie: { // cookie options 12 | length: 32, 13 | httponly: true 14 | }, 15 | adapter: { 16 | file: { 17 | path: think.getPath('common', 'runtime') + '/session', 18 | } 19 | } 20 | }; -------------------------------------------------------------------------------- /thinkjs/src/common/config/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * template config 4 | */ 5 | export default { 6 | type: 'ejs', 7 | content_type: 'text/html', 8 | file_ext: '.html', 9 | file_depr: '_', 10 | root_path: think.ROOT_PATH + '/view', 11 | adapter: { 12 | ejs: {} 13 | } 14 | }; -------------------------------------------------------------------------------- /thinkjs/src/common/controller/error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * error controller 4 | */ 5 | export default class extends think.controller.base { 6 | /** 7 | * display error page 8 | * @param {Number} status [] 9 | * @return {Promise} [] 10 | */ 11 | displayError(status){ 12 | 13 | //hide error message on production env 14 | if(think.env === 'production'){ 15 | this.http.error = null; 16 | } 17 | 18 | let errorConfig = this.config('error'); 19 | let message = this.http.error && this.http.error.message || 'error'; 20 | if(this.isJsonp()){ 21 | return this.jsonp({ 22 | [errorConfig.key]: status, 23 | [errorConfig.msg]: message 24 | }) 25 | }else if(this.isAjax()){ 26 | return this.fail(status, message); 27 | } 28 | 29 | let module = 'common'; 30 | if(think.mode !== think.mode_module){ 31 | module = this.config('default_module'); 32 | } 33 | let file = `${module}/error/${status}.html`; 34 | let options = this.config('tpl'); 35 | options = think.extend({}, options, {type: 'ejs', file_depr: '_'}); 36 | return this.display(file, options); 37 | } 38 | /** 39 | * Bad Request 40 | * @return {Promise} [] 41 | */ 42 | _400Action(){ 43 | return this.displayError(400); 44 | } 45 | /** 46 | * Forbidden 47 | * @return {Promise} [] 48 | */ 49 | _403Action(){ 50 | return this.displayError(403); 51 | } 52 | /** 53 | * Not Found 54 | * @return {Promise} [] 55 | */ 56 | _404Action(){ 57 | return this.displayError(404); 58 | } 59 | /** 60 | * Internal Server Error 61 | * @return {Promise} [] 62 | */ 63 | _500Action(){ 64 | return this.displayError(500); 65 | } 66 | /** 67 | * Service Unavailable 68 | * @return {Promise} [] 69 | */ 70 | _503Action(){ 71 | return this.displayError(503); 72 | } 73 | } -------------------------------------------------------------------------------- /thinkjs/src/home/config/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * config 4 | */ 5 | export default { 6 | //key: value 7 | }; -------------------------------------------------------------------------------- /thinkjs/src/home/controller/base.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default class extends think.controller.base { 4 | /** 5 | * some base method in here 6 | */ 7 | } -------------------------------------------------------------------------------- /thinkjs/src/home/controller/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import Base from './base.js'; 4 | 5 | export default class extends Base { 6 | /** 7 | * index action 8 | * @return {Promise} [] 9 | */ 10 | indexAction(){ 11 | this.end('hello word'); 12 | //auto render template file index_index.html 13 | //return this.display(); 14 | } 15 | } -------------------------------------------------------------------------------- /thinkjs/src/home/logic/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * logic 4 | * @param {} [] 5 | * @return {} [] 6 | */ 7 | export default class extends think.logic.base { 8 | /** 9 | * index action logic 10 | * @return {} [] 11 | */ 12 | indexAction(){ 13 | 14 | } 15 | } -------------------------------------------------------------------------------- /thinkjs/src/home/model/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * model 4 | */ 5 | export default class extends think.model.base { 6 | 7 | } -------------------------------------------------------------------------------- /thinkjs/view/common/error_400.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bad Request - ThinkJS 5 | 21 | 22 | 23 |
24 |
25 | 26 | 29 |
30 |
31 |
32 |
33 |

Bad Request

34 |
<%if(http.error){%><%=http.error.message%><%}%>
35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /thinkjs/view/common/error_404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Not Found - ThinkJS 5 | 21 | 22 | 23 |
24 |
25 | 26 | 29 |
30 |
31 |
32 |
33 |

Not Found

34 |
<%if(http.error){%><%=http.error.message%><%}%>
35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /thinkjs/view/home/index_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | New ThinkJS Application 6 | 21 | 22 | 23 |
24 |
25 |

A New App Created By ThinkJS

26 |
27 |
28 |
29 |
30 |
31 |
1
32 |

Generate Files

33 |

Run thinkjs command to create module, controler, model, service and so on. visit https://thinkjs.org/doc/thinkjs_command.html to view more infomation.

34 |
35 |
36 |
2
37 |

Documatation

38 |

ThinkJS has html and pdf documents. visit https://thinkjs.org/doc.html

39 |
40 |
41 |
3
42 |

WebSocket

43 |

ThinkJS support socket.io and sockjs WebSocket client and server node. visit https://thinkjs.org/doc/adapter_websocket.html

44 |
45 |
46 |
47 | 48 | -------------------------------------------------------------------------------- /thinkjs/www/README.md: -------------------------------------------------------------------------------- 1 | ## application 2 | 3 | ### start server 4 | 5 | *development* 6 | 7 | ```js 8 | node www/index.js 9 | ``` 10 | 11 | *testing* 12 | 13 | ```js 14 | node www/testing.js 15 | ``` 16 | 17 | *production* 18 | 19 | ```js 20 | node www/production.js 21 | ``` 22 | 23 | or use pm2 to manage node: 24 | 25 | ``` 26 | pm2 start www/production.js 27 | ``` 28 | 29 | ### compile es6 code 30 | 31 | ``` 32 | npm run compile 33 | ``` 34 | 35 | ### how to link resource 36 | 37 | *in template file* 38 | 39 | ```html 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | ``` 48 | 49 | *link image in css* 50 | 51 | ```css 52 | .a{ 53 | background: url(../img/a.png) no-repeat; 54 | } 55 | ``` -------------------------------------------------------------------------------- /thinkjs/www/development.js: -------------------------------------------------------------------------------- 1 | var thinkjs = require('thinkjs'); 2 | var path = require('path'); 3 | 4 | var rootPath = path.dirname(__dirname); 5 | 6 | var instance = new thinkjs({ 7 | APP_PATH: rootPath + path.sep + 'app', 8 | ROOT_PATH: rootPath, 9 | RESOURCE_PATH: __dirname, 10 | env: 'development' 11 | }); 12 | 13 | //compile src/ to app/ 14 | instance.compile({ 15 | retainLines: true, 16 | log: true 17 | }); 18 | 19 | instance.run(); -------------------------------------------------------------------------------- /thinkjs/www/production.js: -------------------------------------------------------------------------------- 1 | var thinkjs = require('thinkjs'); 2 | var path = require('path'); 3 | 4 | var rootPath = path.dirname(__dirname); 5 | 6 | var instance = new thinkjs({ 7 | APP_PATH: rootPath + path.sep + 'app', 8 | ROOT_PATH: rootPath, 9 | RESOURCE_PATH: __dirname, 10 | env: 'production' 11 | }); 12 | 13 | instance.run(); -------------------------------------------------------------------------------- /thinkjs/www/testing.js: -------------------------------------------------------------------------------- 1 | var thinkjs = require('thinkjs'); 2 | var path = require('path'); 3 | 4 | var rootPath = path.dirname(__dirname); 5 | 6 | var instance = new thinkjs({ 7 | APP_PATH: rootPath + path.sep + 'app', 8 | ROOT_PATH: rootPath, 9 | RESOURCE_PATH: __dirname, 10 | env: 'testing' 11 | }); 12 | 13 | instance.run(); --------------------------------------------------------------------------------