├── .gitignore ├── FAQ.md ├── PAGE_NEEDED.md ├── README.md ├── SUMMARY.md ├── anatomy ├── README.md └── myApp │ ├── .tmp │ ├── .tmp.md │ └── public │ │ └── public.md │ ├── Gruntfile.js.md │ ├── README.md.md │ ├── api │ ├── api.md │ ├── controllers │ │ ├── UserController.js.md │ │ ├── controllers.md │ │ └── gitkeep.md │ ├── models │ │ ├── User.js.md │ │ ├── gitkeep.md │ │ └── models.md │ ├── policies │ │ ├── policies.md │ │ └── sessionAuth.js.md │ ├── responses │ │ ├── badRequest.js.md │ │ ├── forbidden.js.md │ │ ├── notFound.js.md │ │ ├── ok.js.md │ │ ├── responses.md │ │ └── serverError.js.md │ └── services │ │ ├── gitkeep.md │ │ └── services.md │ ├── app.js.md │ ├── assets │ ├── _templates │ │ ├── _templates.md │ │ └── gitkeep.md │ ├── assets.md │ ├── favicon.ico.md │ ├── images │ │ ├── gitkeep.md │ │ └── images.md │ ├── js │ │ ├── dependencies │ │ │ ├── dependencies.md │ │ │ └── sails.io.js.md │ │ └── js.md │ ├── robots.txt.md │ └── styles │ │ ├── importer.less.md │ │ └── styles.md │ ├── config │ ├── blueprints.js.md │ ├── bootstrap.js.md │ ├── config.md │ ├── connections.js.md │ ├── cors.js.md │ ├── csrf.js.md │ ├── env │ │ ├── development.js.md │ │ ├── env.md │ │ └── production.js.md │ ├── globals.js.md │ ├── http.js.md │ ├── i18n.js.md │ ├── local.js.md │ ├── locales │ │ ├── _README.md.md │ │ ├── de.json.md │ │ ├── en.json.md │ │ ├── es.json.md │ │ ├── fr.json.md │ │ └── locales.md │ ├── log.js.md │ ├── models.js.md │ ├── policies.js.md │ ├── routes.js.md │ ├── session.js.md │ ├── sockets.js.md │ └── views.js.md │ ├── gitignore.md │ ├── myApp.md │ ├── node_modules │ └── node_modules │ │ └── md │ ├── package.json.md │ ├── sailsrc.md │ ├── tasks │ ├── README.md.md │ ├── config │ │ ├── clean.js.md │ │ ├── coffee.js.md │ │ ├── concat.js.md │ │ ├── config.md │ │ ├── copy.js.md │ │ ├── cssmin.js.md │ │ ├── jst.js.md │ │ ├── less.js.md │ │ ├── sails-linker.js.md │ │ ├── sync.js.md │ │ ├── uglify.js.md │ │ └── watch.js.md │ ├── pipeline.js.md │ ├── register │ │ ├── build.js.md │ │ ├── buildProd.js.md │ │ ├── compileAssets.js.md │ │ ├── default.js.md │ │ ├── linkAssets.js.md │ │ ├── linkAssetsBuild.js.md │ │ ├── linkAssetsBuildProd.js.md │ │ ├── prod.js.md │ │ ├── register.md │ │ └── syncAssets.js.md │ └── tasks.md │ └── views │ ├── 403.ejs.md │ ├── 404.ejs.md │ ├── 500.ejs.md │ ├── homepage.ejs.md │ ├── layout.ejs.md │ └── views.md ├── concepts ├── 0home │ └── 0home.md ├── Assets │ ├── Assets.md │ ├── DefaultTasks.md │ ├── DisablingGrunt.md │ └── TaskAutomation.md ├── Configuration │ ├── Configuration.md │ └── usingsailsrcfiles.md ├── Controllers │ └── Controllers.md ├── Custom Responses │ └── Custom Responses.md ├── Deployment │ ├── Deployment.md │ ├── FAQ.md │ ├── Hosting.md │ └── Scaling.md ├── File Uploads │ └── File Uploads.md ├── Globals │ └── Globals.md ├── Internationalization │ └── Internationalization.md ├── Logging │ ├── Logging.md │ └── sails.log.md ├── Middleware │ └── Middleware.md ├── ORM │ ├── Associations │ │ ├── Associations.md │ │ ├── Dominance.md │ │ ├── ManytoMany.md │ │ ├── OneWayAssociation.md │ │ ├── OnetoMany.md │ │ ├── OnetoOne.md │ │ ├── ThroughAssociations.md │ │ └── joinTables.md │ ├── Attributes.md │ ├── Lifecyclecallbacks.md │ ├── Models.md │ ├── ORM.md │ ├── Querylanguage.md │ ├── Validations.md │ └── model-settings.md ├── Policies │ └── Policies.md ├── Routes │ ├── RouteTargetSyntax.md │ ├── Routes.md │ └── URLSlugs.md ├── Security │ ├── CORS.md │ ├── CSRF.md │ ├── Clickjacking.md │ ├── ContentSecurityPolicy.md │ ├── DDOS.md │ ├── P3P.md │ ├── Security.md │ ├── SocketHijacking.md │ ├── StrictTransportSecurity.md │ └── XSS.md ├── Services │ └── Services.md ├── Testing │ └── Testing.md ├── Upgrading │ └── Upgrading.md ├── Views │ ├── Layouts.md │ ├── Locals.md │ ├── Partials.md │ ├── ViewEngines.md │ └── Views.md └── extending-sails │ ├── Adapters │ ├── Adapters.md │ ├── adapterList.md │ └── customAdapters.md │ ├── Generators │ ├── Generators.md │ ├── customGenerators.md │ └── generatorList.md │ ├── Hooks │ ├── Hooks.md │ ├── customhooks.md │ └── hookList.md │ └── extending-sails.md ├── contributing ├── Sending-Pull-Requests.md ├── adapter-specification.md ├── intro-to-custom-adapters.md └── roadmap.md ├── getting-started ├── NewToNode.md ├── WhatIsSails.md └── getting-started.md ├── reference ├── 0home │ └── 0home.md ├── README.md ├── blueprint-api │ ├── Add.md │ ├── Create.md │ ├── Destroy.md │ ├── Find.md │ ├── FindOne.md │ ├── Populate.md │ ├── Remove.md │ ├── Update.md │ └── blueprint-api.md ├── cli │ ├── cli.md │ ├── sailsconsole.md │ ├── sailsdebug.md │ ├── sailsgenerate.md │ ├── sailslift.md │ ├── sailsnew.md │ └── sailsversion.md ├── req │ ├── req.accepted.md │ ├── req.acceptedCharsets.md │ ├── req.acceptedLanguages.md │ ├── req.accepts.md │ ├── req.acceptsCharset.md │ ├── req.acceptsLanguage.md │ ├── req.allParams.md │ ├── req.body.md │ ├── req.cookies.md │ ├── req.file.md │ ├── req.fresh.md │ ├── req.get.md │ ├── req.host.md │ ├── req.ip.md │ ├── req.ips.md │ ├── req.is.md │ ├── req.isSocket.md │ ├── req.md │ ├── req.method.md │ ├── req.param.md │ ├── req.params.md │ ├── req.path.md │ ├── req.protocol.md │ ├── req.query.md │ ├── req.secure.md │ ├── req.signedCookies.md │ ├── req.socket.md │ ├── req.subdomains.md │ ├── req.url.md │ ├── req.wantsJSON.md │ └── req.xhr.md ├── res │ ├── res.attachment.md │ ├── res.badRequest.md │ ├── res.clearCookie.md │ ├── res.cookie.md │ ├── res.forbidden.md │ ├── res.get.md │ ├── res.json.md │ ├── res.jsonp.md │ ├── res.location.md │ ├── res.md │ ├── res.negotiate.md │ ├── res.notFound.md │ ├── res.ok.md │ ├── res.redirect.md │ ├── res.send.md │ ├── res.serverError.md │ ├── res.set.md │ ├── res.status.md │ ├── res.type.md │ └── res.view.md ├── sails.config │ ├── sails.config.blueprints.md │ ├── sails.config.bootstrap.md │ ├── sails.config.connections.md │ ├── sails.config.cors.md │ ├── sails.config.csrf.md │ ├── sails.config.globals.md │ ├── sails.config.http.md │ ├── sails.config.i18n.md │ ├── sails.config.local.md │ ├── sails.config.log.md │ ├── sails.config.md │ ├── sails.config.models.md │ ├── sails.config.policies.md │ ├── sails.config.routes.md │ ├── sails.config.session.md │ ├── sails.config.sockets.md │ └── sails.config.views.md ├── waterline │ ├── models │ │ ├── count.md │ │ ├── create.md │ │ ├── destroy.md │ │ ├── find.md │ │ ├── findOne.md │ │ ├── findOrCreate.md │ │ ├── models.md │ │ ├── native.md │ │ ├── query.md │ │ ├── stream.md │ │ └── update.md │ ├── populated-values │ │ ├── add.md │ │ ├── populated-values.md │ │ └── remove.md │ ├── queries │ │ ├── exec.md │ │ ├── limit.md │ │ ├── populate.md │ │ ├── populateAll.md │ │ ├── queries.md │ │ ├── skip.md │ │ ├── sort.md │ │ └── where.md │ ├── records │ │ ├── records.md │ │ ├── save.md │ │ ├── toJSON.md │ │ ├── toObject.md │ │ └── validate.md │ └── waterline.md └── websockets │ ├── resourceful-pubsub │ ├── message.md │ ├── publishAdd.md │ ├── publishCreate.md │ ├── publishDestroy.md │ ├── publishRemove.md │ ├── publishUpdate.md │ ├── resourceful-pubsub.md │ ├── subscribe.md │ ├── unsubscribe.md │ ├── unwatch.md │ └── watch.md │ ├── sails.io.js │ ├── io.socket.on.md │ ├── sails.io.js.md │ ├── socket.delete.md │ ├── socket.get.md │ ├── socket.post.md │ ├── socket.put.md │ └── socket.request.md │ ├── sails.sockets │ ├── sails.sockets.blast.md │ ├── sails.sockets.broadcast.md │ ├── sails.sockets.emit.md │ ├── sails.sockets.id.md │ ├── sails.sockets.join.md │ ├── sails.sockets.leave.md │ ├── sails.sockets.md │ ├── sails.sockets.rooms.md │ ├── sails.sockets.socketRooms.md │ ├── sails.sockets.subscribeToFirehose.md │ ├── sails.sockets.subscribers.md │ └── sails.sockets.unsubscribeFromFirehose.md │ └── websockets.md ├── resources └── styleguide │ ├── Sails-Style-Guide.pdf │ ├── sailslogo_blue.png │ ├── sailslogo_blue@2x.png │ ├── sailslogo_dark.png │ ├── sailslogo_dark@2x.png │ ├── sailslogo_gray.png │ ├── sailslogo_gray@2x.png │ ├── sailslogo_white.png │ └── sailslogo_white@2x.png ├── status ├── plugins │ ├── README.md │ ├── adapters.js │ ├── generators.js │ └── hooks.js ├── req.md └── res.md ├── support └── irc │ ├── configuringClient.md │ ├── grabClient.md │ ├── irc.md │ └── sailsTroll.md └── userguides ├── contributing.md ├── deployment ├── deployment.md ├── nodejitsu.md └── openshift.md ├── guideStub.md └── userguides.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | _book 3 | -------------------------------------------------------------------------------- /PAGE_NEEDED.md: -------------------------------------------------------------------------------- 1 | # Page Needed 2 | 3 | If you’re seeing this page, it means you've clicked on a link to a Sails doc that has yet to be written. Help make Sails better by contributing to the docs! 4 | 5 | Please send a pull request to master with corrections/additions and they'll be double-checked and merged as soon as possible. 6 | 7 | Secondly, we are open to suggestions about the process we're using to manage our documentation, and to work with the community in general. Please post to the Google Group with your ideas- or if you're interested in helping directly, contact @ncrumrine, @loicsaintroch, or @mikermcneil on Twitter. 8 | 9 | Love, 10 | 11 | The Sails Team -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Sails.js 官方文档中文版 (v0.11.x) 2 | 3 | http://imfly.github.io/sails-docs/ 4 | 5 | 本文档是 [sails.js官方文档](http://www.sailsjs.org) 中文版本(持续更新)。为了阅读方便,我们借助`gitbook`平台推出了PDF等格式的电子书,您可下载使用。欢迎反馈和参与。 6 | 7 | #### 关于`sails.js` 8 | 9 | `sails.js`类似于ruby on rails, 是一个优秀的web后台开发框架。它基于著名的`express`,添加了很多功能模块,支持`REST`、各种流行数据库等,使用它开发适用于多设备、数据密集型、实时web应用是件异常简单、高效、愉快的事情。 10 | 11 | #### 贡献 12 | 13 | 本书原稿托管在 [github](https://github.com/imfly/sails-docs/tree/zh-CN) 上,您也可以参与进来,直接fork、修改、提交PR。 14 | 15 | 电子书生成,使用了插件 [gitbook-summary](https://github.com/imfly/gitbook-summary)自动生成一个目录,然后借助`gitbook`导出。 16 | 17 | #### 反馈 18 | 19 | 请[点击这里](https://github.com/imfly/sails-docs/issues)。 20 | 21 | #### 链接 22 | 23 | 这里提供gitbook上的同步链接地址 24 | 25 | 下载页: https://imfly.gitbooks.io/sailsjs-docs-gitbook/ 26 | 27 | 中文版: https://imfly.gitbooks.io/sailsjs-docs-gitbook/content/cn/index.html 28 | 29 | 英文版: https://imfly.gitbooks.io/sailsjs-docs-gitbook/content/en/index.html 30 | 31 | #### 协议 32 | 33 | MIT 34 | 35 | #### 译者 36 | 37 | imfly,10+开发经验,全栈开发工程师,精通java、ruby on rails、node.js等,关注并擅长Web开发、数据挖掘、即时应用。喜欢新挑战和新事物,是ruby on rails早期开发实践者,目前因业务需要全面转型node.js。在大型国企从事管理工作多年,在企业级、物联网领域有具体实践经验。 38 | 39 | -------------------------------------------------------------------------------- /anatomy/README.md: -------------------------------------------------------------------------------- 1 | sails-docs-anatomy 2 | ================== 3 | 4 | Anatomy documentation for www.sailsjs.org 5 | -------------------------------------------------------------------------------- /anatomy/myApp/.tmp/.tmp.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/.tmp 2 | ### Purpose 3 | 4 | This is your temp directory. It is used for various things by various pieces of node middleware. We use it for asset management. For the most part, you can ignore this directory and everything inside of it. 5 | 6 | ### More Info 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /anatomy/myApp/.tmp/public/public.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/.tmp/public/ 2 | ### Purpose 3 | 4 | Sails stashes your public assets into this directory for it's live updating via grunt-watch 5 | 6 | ### More Info 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /anatomy/myApp/README.md.md: -------------------------------------------------------------------------------- 1 | # myApp/README 2 | ### Purpose 3 | 4 | This is a generic README that you can edit to describe your app. 5 | 6 | 7 | 8 | 9 | ``` 10 | # myApp 11 | 12 | a [Sails](http://sailsjs.org) application 13 | 14 | ``` 15 | -------------------------------------------------------------------------------- /anatomy/myApp/api/api.md: -------------------------------------------------------------------------------- 1 | # myApp/api 2 | ### Purpose 3 | This folder contains the vast majority of your app's back-end logic. It is home to the 'M' and 'C' in [MVC Framework](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). 4 | 5 | In it you will find the following. 6 | 7 | - Controllers: Controllers contain most of the back-end logic for your app. 8 | - Models: Models are the structures that contain data for your Sails App. 9 | - Policies: Policies are typically used to authenticate clients and restrict access to certain parts of your app. 10 | - Responses: Server response logic (404 - Not Found, 500 - Server Error, etc) 11 | - Services: Services are similar to controller actions. They contain logic that used by your app that doesn't necessarily rely on `.req()` and `.res()`. 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /anatomy/myApp/api/controllers/UserController.js.md: -------------------------------------------------------------------------------- 1 | # myApp/api/controllers/UserController.js 2 | ### Purposes 3 | 4 | This file was created when you ran 'sails generate api User'. It contains all of the controller logic for the model called 'User'. 5 | 6 | This is where you will put "controller actions" that send data to your clients and render the views which display that data. 7 | 8 | 9 | 10 | 11 | ``` 12 | /** 13 | * UserController 14 | * 15 | * @description :: Server-side logic for managing users 16 | * @help :: See http://links.sailsjs.org/docs/controllers 17 | */ 18 | 19 | module.exports = { 20 | 21 | }; 22 | 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /anatomy/myApp/api/controllers/controllers.md: -------------------------------------------------------------------------------- 1 | # myApp/api/controllers 2 | ### Purpose 3 | This is the directory that holds your controllers. In Sails, controllers are javascript files that contain logic for interacting with models and rendering appropriate views to the client. 4 | 5 | When you call `sails generate api cats` via the command line from inside your project's root directory, Sails will generate the file `myApp/api/controllers/CatsController.js` along with a matching model. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /anatomy/myApp/api/controllers/gitkeep.md: -------------------------------------------------------------------------------- 1 | # myApp/api/controllers/.gitkeep 2 | ### Purpose 3 | 4 | Ignore this file. It only exists because `git` refuses to push empty directories to a remote server. `.gitkeep` is an unofficial convention that has emerged as a workaround for people who don't discriminate against empty directories. 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /anatomy/myApp/api/models/User.js.md: -------------------------------------------------------------------------------- 1 | # myApp/api/models/User.js 2 | ### Purpose 3 | This file was created when you ran 'sails generate api User'. It contains the structure for the model called 'User'. 4 | 5 | In this file you will specify what attributes each model instance (record) should have. You can also add custom model instance methods, as well as override the global settings for things like `policies` and `connections`. 6 | 7 | One of the best parts about Sails is it uses [Waterline](https://github.com/balderdashy/waterline). This means you can start developing your data models long before you commit to a particular database. 8 | 9 | 10 | 11 | 12 | ``` 13 | /** 14 | * User.js 15 | * 16 | * @description :: TODO: You might write a short summary of how this model works and what it represents here. 17 | * @docs :: http://sailsjs.org/#!documentation/models 18 | */ 19 | 20 | module.exports = { 21 | 22 | attributes: { 23 | 24 | } 25 | }; 26 | 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /anatomy/myApp/api/models/gitkeep.md: -------------------------------------------------------------------------------- 1 | # myApp/api/models/.gitkeep 2 | ### Purpose 3 | 4 | Ignore this file. It only exists because `git` refuses to push empty directories to a remote server. `.gitkeep` is an unofficial convention that has emerged as a workaround for people who don't discriminate against empty directories. 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /anatomy/myApp/api/models/models.md: -------------------------------------------------------------------------------- 1 | # myApp/api/models 2 | ### Purpose 3 | This is the directory that holds your models. In Sails, models are the structures that contain data for your Sails App. 4 | 5 | When you call `sails generate api cats` via the command line from inside your project's root directory, Sails will generate the file `myApp/api/models/Cat.js` as well as a matching controller. In the `myApp/api/models/Cat.js` file you can specify the attributes which determine how the records in your database will be defined. 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /anatomy/myApp/api/policies/policies.md: -------------------------------------------------------------------------------- 1 | # myApp/api/policies 2 | ### Purpose 3 | This is the folder you will store your `policy` files in. A policy file is a .js file that contains what is essentially express middleware for authenticating access to controller actions in your app. 4 | 5 | If you want to make sure only the user `rick1983` can access `http://prism.gov/rick1983` , this is the folder you would put that logic in. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /anatomy/myApp/api/policies/sessionAuth.js.md: -------------------------------------------------------------------------------- 1 | # myApp/api/policies/sessionAuth.js 2 | ### Purpose 3 | This is an example policy file against which all routes are checked before allowing a client access to any part of your app. By default, it allows everyone to access everything but this can (and probably should) be changed before you switch into production mode. 4 | 5 | In Sails, a policy is simply express middleware that does something to authenticate users before they are allowed to access some part of your app. For more information on creating policies, you'll probably want to check our guide on it. 6 | 7 | 8 | 9 | 10 | ``` 11 | /** 12 | * sessionAuth 13 | * 14 | * @module :: Policy 15 | * @description :: Simple policy to allow any authenticated user 16 | * Assumes that your login action in one of your controllers sets `req.session.authenticated = true;` 17 | * @docs :: http://sailsjs.org/#!documentation/policies 18 | * 19 | */ 20 | module.exports = function(req, res, next) { 21 | 22 | // User is allowed, proceed to the next policy, 23 | // or if this is the last policy, the controller 24 | if (req.session.authenticated) { 25 | return next(); 26 | } 27 | 28 | // User is not allowed 29 | // (default res.forbidden() behavior can be overridden in `config/403.js`) 30 | return res.forbidden('You are not permitted to perform this action.'); 31 | }; 32 | 33 | ``` 34 | -------------------------------------------------------------------------------- /anatomy/myApp/api/responses/responses.md: -------------------------------------------------------------------------------- 1 | # myApp/api/responses 2 | ### Purpose 3 | 4 | This folder holds the logic for issuing server responses to your clients. 5 | 6 | When you generate a new Sails project, we include some of the more common ones for you. Feel free to edit them to suit your needs. You can also create a custom response using our `sails-generate-custom-response` generator. 7 | 8 | See the Response section of Reference Documentation for more info. 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /anatomy/myApp/api/services/gitkeep.md: -------------------------------------------------------------------------------- 1 | # myApp/api/services/.gitkeep 2 | ### Purpose 3 | 4 | Ignore this file. It only exists because `git` refuses to push empty directories to a remote server. `.gitkeep` is an unofficial convention that has emerged as a workaround for people who don't discriminate against empty directories. 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /anatomy/myApp/api/services/services.md: -------------------------------------------------------------------------------- 1 | # myApp/api/services 2 | ### Purpose 3 | This folder contains your services. 'Services' are similar to controller actions but are typically used for things that don't nessecarily have to happen between the time when the user sends a request and when the server sends back a response. Any logic that doesn't rely on `.req()` and `.res()` can be turned into a service if for no other reason than to keep your controllers clean and managable. 4 | 5 | Hypothetically, one could create a service for 6 | 7 | - Sending emails 8 | - Automating tweets to celebrities 9 | - Retreiving data from a third party API then pushing that data to your client WHEN IT'S READY (over websockets) 10 | 11 | Services are written in one or more .js file within this directory. 12 | 13 | 14 | ### Example Email.js 15 | 16 | ``` 17 | module.exports = { 18 | send: function(to,from,body){ 19 | // fancy code that sends an email 20 | } 21 | } 22 | 23 | ``` 24 | 25 | You would call this service with ` Email.send('rick','bill','lol') ` 26 | 27 | 28 | > Mind your case. Email.send !== email.send 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/_templates/_templates.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/templates 2 | ### Purpose - Client-side Templates 3 | 4 | HTML templates are important prerequisites of modern, rich client applications. 5 | To work their magic, frameworks like Backbone, Angular, Ember, and Knockout require 6 | that you load these templates client-side. 7 | 8 | By default, your Gruntfile is configured to automatically load and precompile 9 | client-side JST templates in your `assets/templates` folder, then 10 | include them here automatically (between TEMPLATES and TEMPLATES END). 11 | 12 | 13 | 14 | 15 | 16 | To customize this behavior to fit your needs, just edit your Gruntfile. 17 | For example, here are a few things you could do: 18 | 19 | - Import templates from other directories 20 | - Use a different template engine (handlebars, jade, dust, etc) 21 | - Internationalize your client-side templates using a server-side stringfile before they're served. 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/_templates/gitkeep.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/templates/.gitkeep 2 | ### Purpose 3 | 4 | Ignore this file. It only exists because `git` refuses to push empty directories to a remote server. `.gitkeep` is an unofficial convention that has emerged as a workaround for people who don't discriminate against empty directories. 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/assets.md: -------------------------------------------------------------------------------- 1 | # myApp/assets 2 | ### Purpose 3 | This is your assets folder. It houses all of the static files that your app will need to host. Feel free to create your own files and folders in here. Upon lifting, a file called `myApp/assets/newFolder/data.txt` could be accessed at `http://localhost:1337/newFolder/data.txt`. 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/favicon.ico.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/favicon.ico 2 | ### Purpose 3 | This file is the [Favicon](http://en.wikipedia.org/wiki/Favicon") for your app. 4 | 5 | ### More Info 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/images/gitkeep.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/images/.gitkeep 2 | ### Purpose 3 | 4 | Ignore this file. It only exists because `git` refuses to push empty directories to a remote server. `.gitkeep` is an unofficial convention that has emerged as a workaround for people who don't discriminate against empty directories. 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/images/images.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/images 2 | ### Purpose 3 | 4 | This is where you should put image files that need to be statically hosted by your app. 5 | 6 | Upon lifting your app, an image called `omgCat.jpg` could be found at `http://localhost:1337/images/omgCat.jpg` 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/js/dependencies/dependencies.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/js/dependencies 2 | ### Purpose 3 | This directory allows grunt to load javascript files in index.ejs before the rest of the javascript files in the js directory. 4 | 5 | js/ 6 | | main.js 7 | | apple.js 8 | | dependencies/ 9 | | | sails.io.js 10 | 11 | This setup will create 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/js/dependencies/sails.io.js.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/js/dependencies/sails.io.js 2 | ### Purpose 3 | 4 | This file adds a few custom methods to socket.io which provide the "built-in" websockets functionality for Sails. 5 | 6 | Specifically, those methods allow you to send and receive Socket.IO messages to & from Sails by simulating a REST client interface on top of Socket.IO. It models it's API after the $.ajax pattern from jQuery which you might be familiar with. 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/js/js.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/js 2 | ### Purpose 3 | This is where you put client-side javascript files that you want to be statically hosted by your app. Sails puts a few in there for making communication via socket.io easier. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/robots.txt.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/robots.txt 2 | ### Purpose 3 | This file tells web crawlers and search bots about your app. It tells them what kind of content to expect as well as how to index it. 4 | 5 | Learn all about robots.txt [right here](http://www.robotstxt.org/robotstxt.html). 6 | 7 | 8 | 9 | 10 | ``` 11 | # The robots.txt file is used to control how search engines index your live URLs. 12 | # See http://www.robotstxt.org/wc/norobots.html for more information. 13 | 14 | 15 | 16 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 17 | # User-Agent: * 18 | # Disallow: / 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/styles/importer.less.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/styles/importer.less 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * importer.less 9 | * 10 | * By default, new Sails projects are configured to compile this file 11 | * from LESS to CSS. Unlike CSS files, LESS files are not compiled and 12 | * included automatically unless they are imported below. 13 | * 14 | * The LESS files imported below are compiled and included in the order 15 | * they are listed. Mixins, variables, etc. should be imported first 16 | * so that they can be accessed by subsequent LESS stylesheets. 17 | * 18 | * (Just like the rest of the asset pipeline bundled in Sails, you can 19 | * always omit, customize, or replace this behavior with SASS, SCSS, 20 | * or any other Grunt tasks you like.) 21 | */ 22 | 23 | 24 | 25 | // For example: 26 | // 27 | // @import 'variables/colors.less'; 28 | // @import 'mixins/foo.less'; 29 | // @import 'mixins/bar.less'; 30 | // @import 'mixins/baz.less'; 31 | // 32 | // @import 'styleguide.less'; 33 | // @import 'pages/login.less'; 34 | // @import 'pages/signup.less'; 35 | // 36 | // etc. 37 | 38 | ``` 39 | -------------------------------------------------------------------------------- /anatomy/myApp/assets/styles/styles.md: -------------------------------------------------------------------------------- 1 | # myApp/assets/styles 2 | ### Purpose 3 | This is where you will put all of the .css files that you would like to be statically hosted by your app. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /anatomy/myApp/config/bootstrap.js.md: -------------------------------------------------------------------------------- 1 | # myApp/config/bootstrap.js 2 | ### Purpose 3 | This is a server-side javascript file that is executed by Sails just before your app is lifted. 4 | 5 | This gives you an opportunity to set up your data model, run jobs, or perform some special logic. 6 | 7 | 8 | 9 | 10 | 11 | ``` 12 | /** 13 | * Bootstrap 14 | * (sails.config.bootstrap) 15 | * 16 | * An asynchronous bootstrap function that runs before your Sails app gets lifted. 17 | * This gives you an opportunity to set up your data model, run jobs, or perform some special logic. 18 | * 19 | * For more information on bootstrapping your app, check out: 20 | * http://links.sailsjs.org/docs/config/bootstrap 21 | */ 22 | 23 | module.exports.bootstrap = function(cb) { 24 | 25 | // It's very important to trigger this callack method when you are finished 26 | // with the bootstrap! (otherwise your server will never lift, since it's waiting on the bootstrap) 27 | cb(); 28 | }; 29 | 30 | ``` 31 | -------------------------------------------------------------------------------- /anatomy/myApp/config/config.md: -------------------------------------------------------------------------------- 1 | # myApp/config 2 | ### Purpose 3 | This folder contains various files that will allow you to customize and configure your Sails app. 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /anatomy/myApp/config/env/development.js.md: -------------------------------------------------------------------------------- 1 | # myApp/config/env/development.js 2 | ### Purpose 3 | This file will be loaded when Sails is running in `development` mode. Sails runs in `development` mode by default if no other environment is specified. 4 | 5 | 6 | 7 | 8 | ``` 9 | /** 10 | * Development environment settings 11 | * 12 | * This file can include shared settings for a development team, 13 | * such as API keys or remote database passwords. If you're using 14 | * a version control solution for your Sails app, this file will 15 | * be committed to your repository unless you add it to your .gitignore 16 | * file. If your repository will be publicly viewable, don't add 17 | * any private information to this file! 18 | * 19 | */ 20 | 21 | module.exports = { 22 | 23 | /*************************************************************************** 24 | * Set the default database connection for models in the development * 25 | * environment (see config/connections.js and config/models.js ) * 26 | ***************************************************************************/ 27 | 28 | // models: { 29 | // connection: 'someMongodbServer' 30 | // } 31 | 32 | }; 33 | ``` -------------------------------------------------------------------------------- /anatomy/myApp/config/env/env.md: -------------------------------------------------------------------------------- 1 | # myApp/config/env 2 | ### Purpose 3 | This folder contains various environment settings such as API keys or remote database passwords. The environment file used is determined by the environment Sails is going to be running in. Sails loads environments settings into the `sails.config.environment` global object. To switch between different environments, see the [Sails CLI docs](http://sailsjs.org/#/documentation/reference/cli/sailslift.html). 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /anatomy/myApp/config/env/production.js.md: -------------------------------------------------------------------------------- 1 | # myApp/config/env/production.js 2 | ### Purpose 3 | This file will be loaded when Sails is running in `production` mode. If using the CLI command `sails lift --prod`, these settings will be loaded. 4 | 5 | 6 | 7 | 8 | ``` 9 | /** 10 | * Production environment settings 11 | * 12 | * This file can include shared settings for a production environment, 13 | * such as API keys or remote database passwords. If you're using 14 | * a version control solution for your Sails app, this file will 15 | * be committed to your repository unless you add it to your .gitignore 16 | * file. If your repository will be publicly viewable, don't add 17 | * any private information to this file! 18 | * 19 | */ 20 | 21 | module.exports = { 22 | 23 | /*************************************************************************** 24 | * Set the default database connection for models in the production * 25 | * environment (see config/connections.js and config/models.js ) * 26 | ***************************************************************************/ 27 | 28 | // models: { 29 | // connection: 'someMysqlServer' 30 | // }, 31 | 32 | /*************************************************************************** 33 | * Set the port in the production environment to 80 * 34 | ***************************************************************************/ 35 | 36 | // port: 80, 37 | 38 | /*************************************************************************** 39 | * Set the log level in production environment to "silent" * 40 | ***************************************************************************/ 41 | 42 | // log: { 43 | // level: "silent" 44 | // } 45 | 46 | }; 47 | ``` -------------------------------------------------------------------------------- /anatomy/myApp/config/globals.js.md: -------------------------------------------------------------------------------- 1 | # myApp/config/globals.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Global Variable Configuration 9 | * (sails.config.globals) 10 | * 11 | * Configure which global variables which will be exposed 12 | * automatically by Sails. 13 | * 14 | * For more information on configuration, check out: 15 | * http://links.sailsjs.org/docs/config/globals 16 | */ 17 | module.exports.globals = { 18 | _: true, 19 | async: true, 20 | sails: true, 21 | services: true, 22 | models: true 23 | }; 24 | 25 | ``` 26 | -------------------------------------------------------------------------------- /anatomy/myApp/config/http.js.md: -------------------------------------------------------------------------------- 1 | # myApp/config/http.js 2 | 3 | This file is conventionally used for configuring the underlying HTTP server (the `sails.config.http` object.) 4 | 5 | This includes all HTTP-specific middleware, including the serving/caching of flat files. 6 | 7 | 8 | 9 | 10 | ``` 11 | /** 12 | * HTTP Server Settings 13 | * (sails.config.http) 14 | * 15 | * Configuration for the underlying HTTP server in Sails. 16 | * Only applies to HTTP requests (not WebSockets) 17 | * 18 | * For more information on configuration, check out: 19 | * http://links.sailsjs.org/docs/config/http 20 | */ 21 | 22 | module.exports.http = { 23 | 24 | middleware: { 25 | 26 | // The order in which middleware should be run for HTTP request. 27 | // (the Sails router is invoked by the "router" middleware below.) 28 | order: [ 29 | 'startRequestTimer', 30 | 'cookieParser', 31 | 'session', 32 | 'bodyParser', 33 | 'handleBodyParserError', 34 | 'compress', 35 | 'methodOverride', 36 | 'poweredBy', 37 | '$custom', 38 | 'router', 39 | 'www', 40 | 'favicon', 41 | '404', 42 | '500' 43 | ], 44 | 45 | // The body parser that will handle incoming multipart HTTP requests. 46 | // By default as of v0.11, Sails uses [skipper](http://github.com/balderdashy/skipper). 47 | // See http://www.senchalabs.org/connect/multipart.html for other options. 48 | // bodyParser: require('skipper') 49 | 50 | }, 51 | 52 | // The number of seconds to cache flat files on disk being served by 53 | // Express static middleware (by default, these files are in `.tmp/public`) 54 | // 55 | // The HTTP static cache is only active in a 'production' environment, 56 | // since that's the only time Express will cache flat-files. 57 | cache: 31557600000 58 | }; 59 | 60 | ``` 61 | -------------------------------------------------------------------------------- /anatomy/myApp/config/i18n.js.md: -------------------------------------------------------------------------------- 1 | # myApp/config/i18n.js 2 | ### Purpose 3 | This file contains your Sails app's [supported locales](http://en.wikipedia.org/wiki/Locales). 4 | 5 | 6 | 7 | 8 | ``` 9 | /** 10 | * Internationalization / Localization Settings 11 | * (sails.config.i18n) 12 | * 13 | * If your app will touch people from all over the world, i18n (or internationalization) 14 | * may be an important part of your international strategy. 15 | * 16 | * 17 | * For more information, check out: 18 | * http://links.sailsjs.org/docs/config/i18n 19 | */ 20 | 21 | module.exports.i18n = { 22 | 23 | // Which locales are supported? 24 | locales: ['en', 'es', 'fr', 'de'] 25 | 26 | }; 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /anatomy/myApp/config/locales/_README.md.md: -------------------------------------------------------------------------------- 1 | # myApp/config/locales/_README 2 | 3 | 4 | 5 | 6 | ``` 7 | # Internationalization / Localization Settings 8 | 9 | > Also see the official docs on internationalization/localization: 10 | > http://links.sailsjs.org/docs/config/locales 11 | 12 | ## Locales 13 | All locale files live under `config/locales`. Here is where you can add translations 14 | 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. 15 | 16 | Here is an example locale stringfile for the Spanish language (`config/locales/es.json`): 17 | ```json 18 | { 19 | "Hello!": "Hola!", 20 | "Hello %s, how are you today?": "¿Hola %s, como estas?", 21 | } 22 | ``` 23 | ## Usage 24 | Locales can be accessed in controllers/policies through `res.i18n()`, or in views through the `__(key)` or `i18n(key)` functions. 25 | Remember that the keys are case sensitive and require exact key matches, e.g. 26 | 27 | ```ejs 28 |

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

29 |

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

30 |

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

31 | ``` 32 | 33 | ## Configuration 34 | Localization/internationalization config can be found in `config/i18n.js`, from where you can set your supported locales. 35 | 36 | ``` 37 | -------------------------------------------------------------------------------- /anatomy/myApp/config/locales/de.json.md: -------------------------------------------------------------------------------- 1 | # myApp/config/locales/de.json 2 | 3 | 4 | 5 | 6 | ``` 7 | { 8 | "Welcome": "Wilkommen" 9 | } 10 | ``` 11 | -------------------------------------------------------------------------------- /anatomy/myApp/config/locales/en.json.md: -------------------------------------------------------------------------------- 1 | # myApp/config/locales/en.json 2 | 3 | 4 | 5 | 6 | ``` 7 | { 8 | "Welcome": "Welcome" 9 | } 10 | 11 | ``` 12 | -------------------------------------------------------------------------------- /anatomy/myApp/config/locales/es.json.md: -------------------------------------------------------------------------------- 1 | # myApp/config/locales/es.json 2 | 3 | 4 | 5 | 6 | ``` 7 | { 8 | "Welcome": "Bienvenido" 9 | } 10 | 11 | ``` 12 | -------------------------------------------------------------------------------- /anatomy/myApp/config/locales/fr.json.md: -------------------------------------------------------------------------------- 1 | # myApp/config/locales/fr.json 2 | ### Purpose 3 | This tells French browsers sexy things in JSON. 4 | 5 | 6 | 7 | 8 | 9 | ``` 10 | { 11 | "Welcome": "Bienvenue" 12 | } 13 | 14 | ``` 15 | -------------------------------------------------------------------------------- /anatomy/myApp/config/locales/locales.md: -------------------------------------------------------------------------------- 1 | # myApp/config/locales 2 | ### Purpose 3 | This folder contains the information that is used by your app in supporting visiting client's different [locales](http://en.wikipedia.org/wiki/Locale). 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /anatomy/myApp/config/log.js.md: -------------------------------------------------------------------------------- 1 | # myApp/config/log.js 2 | ### Purpose 3 | 4 | This file contains the logger configuration for your Sails app. 5 | 6 | Configure the log level for your app, as well as the transport. 7 | 8 | Underneath the covers, Sails uses Winston for logging, which allows for some pretty neat custom transports/adapters for log messages. 9 | 10 | 11 | 12 | 13 | 14 | ``` 15 | /** 16 | * Built-in Log Configuration 17 | * (sails.config.log) 18 | * 19 | * Configure the log level for your app, as well as the transport 20 | * (Underneath the covers, Sails uses Winston for logging, which 21 | * allows for some pretty neat custom transports/adapters for log messages) 22 | * 23 | * For more information on the Sails logger, check out: 24 | * http://links.sailsjs.org/docs/config/log 25 | */ 26 | 27 | module.exports = { 28 | 29 | // Valid `level` configs: 30 | // i.e. the minimum log level to capture with sails.log.*() 31 | // 32 | // 'error' : Display calls to `.error()` 33 | // 'warn' : Display calls from `.error()` to `.warn()` 34 | // 'debug' : Display calls from `.error()`, `.warn()` to `.debug()` 35 | // 'info' : Display calls from `.error()`, `.warn()`, `.debug()` to `.info()` 36 | // 'verbose': Display calls from `.error()`, `.warn()`, `.debug()`, `.info()` to `.verbose()` 37 | // 38 | log: { 39 | level: 'info' 40 | } 41 | 42 | }; 43 | 44 | ``` 45 | -------------------------------------------------------------------------------- /anatomy/myApp/config/models.js.md: -------------------------------------------------------------------------------- 1 | # myApp/config/models.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Default model configuration 9 | * (sails.config.models) 10 | * 11 | * Unless you override them, the following properties will be included 12 | * in each of your models. 13 | */ 14 | 15 | module.exports.models = { 16 | 17 | // Your app's default connection. 18 | // i.e. the name of one of your app's connections (see `config/connections.js`) 19 | // 20 | // (defaults to localDiskDb) 21 | connection: 'localDiskDb' 22 | }; 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /anatomy/myApp/config/policies.js.md: -------------------------------------------------------------------------------- 1 | # myApp/config/policies.js 2 | ### Purpose 3 | This file contains the default policies for your app. 4 | 5 | Policies are simply Express middleware functions which run before your controllers. You can apply one or more policies to a given controller, or protect just one of it's actions. Any policy file (e.g. `myApp/api/policies/authenticated.js`) can be dropped into the `myApp/api/policies/` folder, at which point it can be accessed by it's filename, minus the extension, (e.g. `authenticated`). 6 | 7 | 8 | 9 | 10 | 11 | ``` 12 | /** 13 | * Policy Mappings 14 | * (sails.config.policies) 15 | * 16 | * Policies are simple functions which run **before** your controllers. 17 | * You can apply one or more policies to a given controller, or protect 18 | * its actions individually. 19 | * 20 | * Any policy file (e.g. `api/policies/authenticated.js`) can be accessed 21 | * below by its filename, minus the extension, (e.g. "authenticated") 22 | * 23 | * For more information on configuring policies, check out: 24 | * http://sailsjs.org/#!documentation/ 25 | */ 26 | 27 | 28 | module.exports.policies = { 29 | 30 | // Default policy for all controllers and actions 31 | // (`true` allows public access) 32 | '*': true, 33 | 34 | // Here's an example of mapping some policies to run before 35 | // a controller and its actions 36 | // RabbitController: { 37 | 38 | // Apply the `false` policy as the default for all of RabbitController's actions 39 | // (`false` prevents all access, which ensures that nothing bad happens to our rabbits) 40 | // '*': false, 41 | 42 | // For the action `nurture`, apply the 'isRabbitMother' policy 43 | // (this overrides `false` above) 44 | // nurture : 'isRabbitMother', 45 | 46 | // Apply the `isNiceToAnimals` AND `hasRabbitFood` policies 47 | // before letting any users feed our rabbits 48 | // feed : ['isNiceToAnimals', 'hasRabbitFood'] 49 | // } 50 | }; 51 | 52 | ``` 53 | -------------------------------------------------------------------------------- /anatomy/myApp/myApp.md: -------------------------------------------------------------------------------- 1 | # myApp 2 | ### Purpose 3 | This is your Sails project's root directory. With the exception of your model and controller, all the files and folders that are in it were generated upon running `sails new` . 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /anatomy/myApp/node_modules/node_modules/md: -------------------------------------------------------------------------------- 1 | node_modules folder missing 2 | -------------------------------------------------------------------------------- /anatomy/myApp/package.json.md: -------------------------------------------------------------------------------- 1 | # myApp/package.json 2 | ### Purpose 3 | This is a standard configuration file for [npm](https://npmjs.org/doc/json.html). Among other things, this file contains the name and version of all of the Node Modules that your app depends on to run. You can change this manually but be careful to adhere to their rules or things might break. 4 | 5 | ### More Info 6 | > Check out [this awesome interactive guide by Nodejitsu](http://package.json.nodejitsu.com) explaining package.json 7 | 8 | 9 | 10 | 11 | 12 | ``` 13 | { 14 | "name": "myApp", 15 | "private": true, 16 | "version": "0.0.0", 17 | "description": "a Sails application", 18 | "keywords": [], 19 | "dependencies": { 20 | "sails": "~0.10.0-rc7", 21 | "sails-disk": "~0.10.0", 22 | "rc": "~0.3.3", 23 | "include-all": "~0.1.3", 24 | "ejs": "~0.8.4", 25 | "grunt": "0.4.2", 26 | "grunt-sync": "~0.0.4", 27 | "grunt-contrib-copy": "~0.5.0", 28 | "grunt-contrib-clean": "~0.5.0", 29 | "grunt-contrib-concat": "~0.3.0", 30 | "grunt-sails-linker": "~0.9.5", 31 | "grunt-contrib-jst": "~0.6.0", 32 | "grunt-contrib-watch": "~0.5.3", 33 | "grunt-contrib-uglify": "~0.4.0", 34 | "grunt-contrib-cssmin": "~0.9.0", 35 | "grunt-contrib-less": "~0.10.0", 36 | "grunt-contrib-coffee": "~0.10.1" 37 | }, 38 | "scripts": { 39 | "start": "node app.js", 40 | "debug": "node debug app.js" 41 | }, 42 | "main": "app.js", 43 | "repository": { 44 | "type": "git", 45 | "url": "git://github.com/dude/myApp.git" 46 | }, 47 | "author": "dude", 48 | "license": "" 49 | } 50 | ``` 51 | -------------------------------------------------------------------------------- /anatomy/myApp/sailsrc.md: -------------------------------------------------------------------------------- 1 | # myApp/.sailsrc 2 | ### Purpose 3 | 4 | This file is useful for setting configuration for ALL Sails apps on a computer. You can also use it to extend the functionality of the Sails CLI tool. 5 | 6 | [Reference docs for .sailsrc](http://beta.sailsjs.org/#!documentation/reference/Configuration/Configuration.html) 7 | 8 | 9 | 10 | 11 | 12 | ``` 13 | { 14 | "generators": { 15 | "modules": {} 16 | } 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/clean.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/clean.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Clean files and folders. 9 | * 10 | * --------------------------------------------------------------- 11 | * 12 | * This grunt task is configured to clean out the contents in the .tmp/public of your 13 | * sails project. 14 | * 15 | * For usage docs see: 16 | * https://github.com/gruntjs/grunt-contrib-clean 17 | */ 18 | module.exports = function(grunt) { 19 | 20 | grunt.config.set('clean', { 21 | dev: ['.tmp/public/**'], 22 | build: ['www'] 23 | }); 24 | 25 | grunt.loadNpmTasks('grunt-contrib-clean'); 26 | }; 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/coffee.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/coffee.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Compile CoffeeScript files to JavaScript. 9 | * 10 | * --------------------------------------------------------------- 11 | * 12 | * Compiles coffeeScript files from `assest/js` into Javascript and places them into 13 | * `.tmp/public/js` directory. 14 | * 15 | * For usage docs see: 16 | * https://github.com/gruntjs/grunt-contrib-coffee 17 | */ 18 | module.exports = function(grunt) { 19 | 20 | grunt.config.set('coffee', { 21 | dev: { 22 | options: { 23 | bare: true, 24 | sourceMap: true, 25 | sourceRoot: './' 26 | }, 27 | files: [{ 28 | expand: true, 29 | cwd: 'assets/js/', 30 | src: ['**/*.coffee'], 31 | dest: '.tmp/public/js/', 32 | ext: '.js' 33 | }, { 34 | expand: true, 35 | cwd: 'assets/js/', 36 | src: ['**/*.coffee'], 37 | dest: '.tmp/public/js/', 38 | ext: '.js' 39 | }] 40 | } 41 | }); 42 | 43 | grunt.loadNpmTasks('grunt-contrib-coffee'); 44 | }; 45 | 46 | ``` 47 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/concat.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/concat.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Concatenate files. 9 | * 10 | * --------------------------------------------------------------- 11 | * 12 | * Concatenates files javascript and css from a defined array. Creates concatenated files in 13 | * .tmp/public/contact directory 14 | * [concat](https://github.com/gruntjs/grunt-contrib-concat) 15 | * 16 | * For usage docs see: 17 | * https://github.com/gruntjs/grunt-contrib-concat 18 | */ 19 | module.exports = function(grunt) { 20 | 21 | grunt.config.set('concat', { 22 | js: { 23 | src: require('../pipeline').jsFilesToInject, 24 | dest: '.tmp/public/concat/production.js' 25 | }, 26 | css: { 27 | src: require('../pipeline').cssFilesToInject, 28 | dest: '.tmp/public/concat/production.css' 29 | } 30 | }); 31 | 32 | grunt.loadNpmTasks('grunt-contrib-concat'); 33 | }; 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/config.md: -------------------------------------------------------------------------------- 1 | # config 2 | ### Purpose 3 | Halp! I need info. You, make this file better! 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/copy.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/copy.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Copy files and folders. 9 | * 10 | * --------------------------------------------------------------- 11 | * 12 | * # dev task config 13 | * Copies all directories and files, exept coffeescript and less fiels, from the sails 14 | * assets folder into the .tmp/public directory. 15 | * 16 | * # build task config 17 | * Copies all directories nd files from the .tmp/public directory into a www directory. 18 | * 19 | * For usage docs see: 20 | * https://github.com/gruntjs/grunt-contrib-copy 21 | */ 22 | module.exports = function(grunt) { 23 | 24 | grunt.config.set('copy', { 25 | dev: { 26 | files: [{ 27 | expand: true, 28 | cwd: './assets', 29 | src: ['**/*.!(coffee|less)'], 30 | dest: '.tmp/public' 31 | }] 32 | }, 33 | build: { 34 | files: [{ 35 | expand: true, 36 | cwd: '.tmp/public', 37 | src: ['**/*'], 38 | dest: 'www' 39 | }] 40 | } 41 | }); 42 | 43 | grunt.loadNpmTasks('grunt-contrib-copy'); 44 | }; 45 | 46 | ``` 47 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/cssmin.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/cssmin.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Compress CSS files. 9 | * 10 | * --------------------------------------------------------------- 11 | * 12 | * Minifies css files and places them into .tmp/public/min directory. 13 | * 14 | * For usage docs see: 15 | * https://github.com/gruntjs/grunt-contrib-cssmin 16 | */ 17 | module.exports = function(grunt) { 18 | 19 | grunt.config.set('cssmin', { 20 | dist: { 21 | src: ['.tmp/public/concat/production.css'], 22 | dest: '.tmp/public/min/production.min.css' 23 | } 24 | }); 25 | 26 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 27 | }; 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/jst.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/jst.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Precompiles Underscore templates to a `.jst` file. 9 | * 10 | * --------------------------------------------------------------- 11 | * 12 | * (i.e. basically it takes HTML files and turns them into tiny little 13 | * javascript functions that you pass data to and return HTML. This can 14 | * speed up template rendering on the client, and reduce bandwidth usage.) 15 | * 16 | * For usage docs see: 17 | * https://github.com/gruntjs/grunt-contrib-jst 18 | * 19 | */ 20 | 21 | module.exports = function(grunt) { 22 | 23 | var templateFilesToInject = [ 24 | 'templates/**/*.html' 25 | ]; 26 | 27 | grunt.config.set('jst', { 28 | dev: { 29 | 30 | // To use other sorts of templates, specify a regexp like the example below: 31 | // options: { 32 | // templateSettings: { 33 | // interpolate: /\{\{(.+?)\}\}/g 34 | // } 35 | // }, 36 | 37 | // Note that the interpolate setting above is simply an example of overwriting lodash's 38 | // default interpolation. If you want to parse templates with the default _.template behavior 39 | // (i.e. using
), there's no need to overwrite `templateSettings.interpolate`. 40 | 41 | 42 | files: { 43 | // e.g. 44 | // 'relative/path/from/gruntfile/to/compiled/template/destination' : ['relative/path/to/sourcefiles/**/*.html'] 45 | '.tmp/public/jst.js': require('../pipeline').templateFilesToInject 46 | } 47 | } 48 | }); 49 | 50 | grunt.loadNpmTasks('grunt-contrib-jst'); 51 | }; 52 | 53 | ``` 54 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/less.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/less.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Compiles LESS files into CSS. 9 | * 10 | * --------------------------------------------------------------- 11 | * 12 | * Only the `assets/styles/importer.less` is compiled. 13 | * This allows you to control the ordering yourself, i.e. import your 14 | * dependencies, mixins, variables, resets, etc. before other stylesheets) 15 | * 16 | * For usage docs see: 17 | * https://github.com/gruntjs/grunt-contrib-less 18 | */ 19 | module.exports = function(grunt) { 20 | 21 | grunt.config.set('less', { 22 | dev: { 23 | files: [{ 24 | expand: true, 25 | cwd: 'assets/styles/', 26 | src: ['importer.less'], 27 | dest: '.tmp/public/styles/', 28 | ext: '.css' 29 | }] 30 | } 31 | }); 32 | 33 | grunt.loadNpmTasks('grunt-contrib-less'); 34 | }; 35 | 36 | ``` 37 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/sync.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/sync.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * A grunt task to keep directories in sync. It is very similar to grunt-contrib-copy 9 | * but tries to copy only those files that has actually changed. 10 | * 11 | * --------------------------------------------------------------- 12 | * 13 | * Synchronize files from the `assets` folder to `.tmp/public`, 14 | * smashing anything that's already there. 15 | * 16 | * For usage docs see: 17 | * https://github.com/tomusdrw/grunt-sync 18 | * 19 | */ 20 | module.exports = function(grunt) { 21 | 22 | grunt.config.set('sync', { 23 | dev: { 24 | files: [{ 25 | cwd: './assets', 26 | src: ['**/*.!(coffee)'], 27 | dest: '.tmp/public' 28 | }] 29 | } 30 | }); 31 | 32 | grunt.loadNpmTasks('grunt-sync'); 33 | }; 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/uglify.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/uglify.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Minify files with UglifyJS. 9 | * 10 | * --------------------------------------------------------------- 11 | * 12 | * Minifies client-side javascript `assets`. 13 | * 14 | * For usage docs see: 15 | * https://github.com/gruntjs/grunt-contrib-uglify 16 | * 17 | */ 18 | module.exports = function(grunt) { 19 | 20 | grunt.config.set('uglify', { 21 | dist: { 22 | src: ['.tmp/public/concat/production.js'], 23 | dest: '.tmp/public/min/production.min.js' 24 | } 25 | }); 26 | 27 | grunt.loadNpmTasks('grunt-contrib-uglify'); 28 | }; 29 | 30 | ``` 31 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/config/watch.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/config/watch.js 2 | 3 | 4 | 5 | 6 | ``` 7 | /** 8 | * Run predefined tasks whenever watched file patterns are added, changed or deleted. 9 | * 10 | * --------------------------------------------------------------- 11 | * 12 | * Watch for changes on 13 | * - files in the `assets` folder 14 | * - the `tasks/pipeline.js` file 15 | * and re-run the appropriate tasks. 16 | * 17 | * For usage docs see: 18 | * https://github.com/gruntjs/grunt-contrib-watch 19 | * 20 | */ 21 | module.exports = function(grunt) { 22 | 23 | grunt.config.set('watch', { 24 | api: { 25 | 26 | // API files to watch: 27 | files: ['api/**/*'] 28 | }, 29 | assets: { 30 | 31 | // Assets to watch: 32 | files: ['assets/**/*', 'tasks/pipeline.js'], 33 | 34 | // When assets are changed: 35 | tasks: ['syncAssets' , 'linkAssets'] 36 | } 37 | }); 38 | 39 | grunt.loadNpmTasks('grunt-contrib-watch'); 40 | }; 41 | 42 | ``` 43 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/build.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/register/build.js 2 | 3 | 4 | 5 | 6 | ``` 7 | module.exports = function (grunt) { 8 | grunt.registerTask('build', [ 9 | 'compileAssets', 10 | 'linkAssetsBuild', 11 | 'clean:build', 12 | 'copy:build' 13 | ]); 14 | }; 15 | 16 | ``` 17 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/buildProd.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/register/buildProd.js 2 | 3 | 4 | 5 | 6 | ``` 7 | module.exports = function (grunt) { 8 | grunt.registerTask('buildProd', [ 9 | 'compileAssets', 10 | 'concat', 11 | 'uglify', 12 | 'cssmin', 13 | 'linkAssetsBuildProd', 14 | 'clean:build', 15 | 'copy:build' 16 | ]); 17 | }; 18 | 19 | ``` 20 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/compileAssets.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/register/compileAssets.js 2 | 3 | 4 | 5 | 6 | ``` 7 | module.exports = function (grunt) { 8 | grunt.registerTask('compileAssets', [ 9 | 'clean:dev', 10 | 'jst:dev', 11 | 'less:dev', 12 | 'copy:dev', 13 | 'coffee:dev' 14 | ]); 15 | }; 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/default.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/register/default.js 2 | 3 | 4 | 5 | 6 | ``` 7 | module.exports = function (grunt) { 8 | grunt.registerTask('default', ['compileAssets', 'linkAssets', 'watch']); 9 | }; 10 | 11 | ``` 12 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/linkAssets.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/register/linkAssets.js 2 | 3 | 4 | 5 | 6 | ``` 7 | module.exports = function (grunt) { 8 | grunt.registerTask('linkAssets', [ 9 | 'sails-linker:devJs', 10 | 'sails-linker:devStyles', 11 | 'sails-linker:devTpl', 12 | 'sails-linker:devJsJade', 13 | 'sails-linker:devStylesJade', 14 | 'sails-linker:devTplJade' 15 | ]); 16 | }; 17 | 18 | ``` 19 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/linkAssetsBuild.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/register/linkAssetsBuild.js 2 | 3 | 4 | 5 | 6 | ``` 7 | module.exports = function (grunt) { 8 | grunt.registerTask('linkAssetsBuild', [ 9 | 'sails-linker:devJsRelative', 10 | 'sails-linker:devStylesRelative', 11 | 'sails-linker:devTpl', 12 | 'sails-linker:devJsRelativeJade', 13 | 'sails-linker:devStylesRelativeJade', 14 | 'sails-linker:devTplJade' 15 | ]); 16 | }; 17 | 18 | ``` 19 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/linkAssetsBuildProd.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/register/linkAssetsBuildProd.js 2 | 3 | 4 | 5 | 6 | ``` 7 | module.exports = function (grunt) { 8 | grunt.registerTask('linkAssetsBuildProd', [ 9 | 'sails-linker:prodJsRelative', 10 | 'sails-linker:prodStylesRelative', 11 | 'sails-linker:devTpl', 12 | 'sails-linker:prodJsRelativeJade', 13 | 'sails-linker:prodStylesRelativeJade', 14 | 'sails-linker:devTplJade' 15 | ]); 16 | }; 17 | 18 | ``` 19 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/prod.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/register/prod.js 2 | 3 | 4 | 5 | 6 | ``` 7 | module.exports = function (grunt) { 8 | grunt.registerTask('prod', [ 9 | 'compileAssets', 10 | 'concat', 11 | 'uglify', 12 | 'cssmin', 13 | 'sails-linker:prodJs', 14 | 'sails-linker:prodStyles', 15 | 'sails-linker:devTpl', 16 | 'sails-linker:prodJsJade', 17 | 'sails-linker:prodStylesJade', 18 | 'sails-linker:devTplJade' 19 | ]); 20 | }; 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/register.md: -------------------------------------------------------------------------------- 1 | # register 2 | ### Purpose 3 | Halp! Make this document better!! 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/register/syncAssets.js.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks/register/syncAssets.js 2 | 3 | 4 | 5 | 6 | ``` 7 | module.exports = function (grunt) { 8 | grunt.registerTask('syncAssets', [ 9 | 'jst:dev', 10 | 'less:dev', 11 | 'sync:dev', 12 | 'coffee:dev' 13 | ]); 14 | }; 15 | 16 | ``` 17 | -------------------------------------------------------------------------------- /anatomy/myApp/tasks/tasks.md: -------------------------------------------------------------------------------- 1 | # myApp/tasks 2 | ### Grunt Tasks 3 | 4 | Sails uses [Grunt](http://gruntjs.com) for asset management. This file contains configuration information for the GRUNT tasks that Sails for this purpose. 5 | 6 | If you created your Sails app with `sails new foo --linker`, this is also where you can define the location of files that are automatically minified and injected (in order) into the views rendered by your app. 7 | 8 | At the top part of this file, you'll find a few of the most commonly configured options, but Sails' integration with Grunt is also fully customizable. If you'd like to work with your assets differently you can change this file to do anything you like! 9 | 10 | ### More Info 11 | > More information on using Grunt to work with static assets: http://gruntjs.com/configuring-tasks 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /anatomy/myApp/views/views.md: -------------------------------------------------------------------------------- 1 | # myApp/views 2 | ### Purpose 3 | This is the directory that holds all of your custom views. 4 | 5 | To create a custom view, create a new directory inside of this then create a new .ejs file. In order for it to be rendered by a client, you must either set up a route in `myApp/config/routes.js` or use the `res.view()` method inside of a custom controller action. 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /concepts/Assets/Assets.md: -------------------------------------------------------------------------------- 1 | # 资源(Assets) 2 | 3 | ### 概述 4 | 5 | 资源指的是在你的服务器上想让外界存取的[静态文档](http://en.wikipedia.org/wiki/Static_web_page)(js、css、图档等等)。在 Sails,这些文档都放在 [`assets/`](http://beta.sailsjs.org/#/documentation/anatomy/myApp/assets) 目录,当你启动应用程序,他们会被处理并同步到一个隐藏的暂存目录(`.tmp/public/`)。这个 `.tmp/public` 文件夹就是 Sails 实际提供的内容,大致等同于 [express](https://github.com/expressjs) 的「public」文件夹,或是其他你或许熟悉的网站服务器如 Apache 的「www」文件夹。这中间的过程允许 Sails 准备或预先编译在用户端上使用的资源,像是 LESS、CoffeeScript、SASS、spritesheets、Jade 模板等等。 6 | 7 | ### 静态中间件(Static middleware) 8 | 9 | 在幕后,Sails 使用 Express 的[静态中间件](http://www.senchalabs.org/connect/static.html)来提供你的资源。你可以在 [`/config/http.js`](/#/documentation/reference/sails.config/sails.config.http.html) 设置这个中间件(例如 cache 设置)。 10 | 11 | ##### `index.html` 12 | 如同大多数网页服务器,Sails 实践了 `index.html` 约定。举例来说,如果你在新的 Sails 工程建立 `assets/foo.html`,便可通过 `http://localhost:1337/foo.html` 存取。但是,如果你建立 `assets/foo/index.html`,则可通过 `http://localhost:1337/foo/index.html` 及 `http://localhost:1337/foo` 存取。 13 | 14 | ##### 优先权 15 | 重要的是需注意静态[中间件](http://stephensugden.com/middleware_guide/)是安装在 Sails 路由**之后**。所以,如果你定义了一个[自定义路由](/#/documentation/concepts/Routes?q=custom-routes),但在你的资源目录也有文档与该路径冲突,自定义路由会在到达静态中间件前拦截请求。举例来说,如果你建立 `assets/index.html` 且没有定义路由在 [`config/routes.js`](/#/documentation/reference/sails.config/sails.config.routes.html) 文档,它会被当成你的首页。但是如果你定义一个自定义路由 `'/': 'FooController.bar'`,将优先采用此路由。 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /concepts/Assets/DisablingGrunt.md: -------------------------------------------------------------------------------- 1 | # 禁用 Grunt(Disabling Grunt) 2 | 3 | 要禁用整合在 Sails 的 Grunt,只需删除 Gruntfile(和/或 [`tasks/`](/#/documentation/anatomy/myApp/tasks) 文件夹)。你还可以禁用 Grunt hook。只要像这样在 `.sailsrc` hooks 设置 `grunt` 属性为 `false`: 4 | 5 | ```json 6 | { 7 | "hooks": { 8 | "grunt": false 9 | } 10 | } 11 | ``` 12 | 13 | ### 我可以为 SASS、Angular、用户端 Jade 模板等自定义任务吗? 14 | 15 | 是的!只需取代 `tasks/` 目录中对应的 grunt 任务,或新增一个。如同 [SASS](https://github.com/sails101/using-sass) 例子。 16 | 17 | 如果你仍然想使用 Grunt 做其他用途,但不想要任何默认的网页前端工作,只要删除工程的资源文件夹并从 `grunt/register/` 和 `grunt/config/` 文件夹移除前端相关任务。你还可以在往后的工程执行 `sails new myCoolApi --no-frontend` 来省略资源文件夹和前端相关 Grunt 任务。你也可以用社区的产生器或[建立自己的](https://github.com/balderdashy/sails-generate-generator)产生器来取代 `sails-generate-frontend` 模组。这让 `sails new` 可以建立原生 iOS 应用程序、Android 应用程序、Cordova 应用程序、SteroidsJS 应用程序等等的模板。 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /concepts/Configuration/usingsailsrcfiles.md: -------------------------------------------------------------------------------- 1 | # 使用 .sailsrc 文档(Using .sailsrc Files) 2 | 3 | 4 | 除了设置应用程序的其他方法外,从 0.10 版开始,你可以在 `.sailsrc` 文档里为指定一个或多个应用程序的设置(感谢 Dominic Tarr 的优秀 [`rc` 模组](https://github.com/dominictarr/rc))。`rc` 文档对于设置命令行和/或套用组件设置到所有执行在你电脑上的 Sails 应用程序最有用。 5 | 6 | 当 Sails 命令行界面执行一个指令时,它会先在当前目录和你的家目录(即 `~/.sailsrc`)(任何新建立的 Sails 应用程序附带的模板 `.sailsrc` 文档)寻找 `.sailsrc` 文档(JSON 或 [.ini](http://en.wikipedia.org/wiki/INI_file) 格式)。然后将它们合并到现有的组件设置。 7 | 8 | > 其实,Sails 会从其它几个地方寻找 `.sailsrc` 文档(遵循 [rc 约定](https://github.com/dominictarr/rc#standards))。你可以放置 `.sailsrc` 文档到这些路径。也就是说,你最好能遵循约定,放置公用 `.sailsrc` 文档的地方是你的家目录(即 `~/.sailsrc`)。 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /concepts/Controllers/Controllers.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfly/sails-docs/ce06b23006f5f2b9d65ac05eaa352542cba76481/concepts/Controllers/Controllers.md -------------------------------------------------------------------------------- /concepts/Deployment/Deployment.md: -------------------------------------------------------------------------------- 1 | # 部署(Deployment) 2 | 3 | ### 概述 4 | 5 | #### 在部署之前 6 | 7 | 在你启动任何网页应用程序前,你应该问自己几个问题: 8 | 9 | + 你预期的流量为何? 10 | + 你的合约是否要求满足任何正常执行时间保证,如服务层级协议(SLA)? 11 | + 哪种前端应用程序会触及你的网页应用程序? 12 | + Android 应用程序 13 | + iOS 应用程序 14 | + 桌面版网页浏览器 15 | + 行动版网页浏览器(平板电脑、电话、iPad mini?) 16 | + 电视、手表、烤面包机…? 17 | + 以及它们会要求什么东西? 18 | + JSON? 19 | + HTML? 20 | + XML? 21 | + 你会利用 Socket.io 的即时发布订阅功能? 22 | + 例如聊天、即时分析、应用程序内通知/讯息 23 | + 你是如何追踪崩溃与错误? 24 | + 看看 Sails 的日志设置 25 | 26 | 27 | 28 | #### 部署在单一服务器 29 | 30 | Node.js 非常快速。对于许多应用程序,在一开始一台服务器就足够处理预期的流量。 31 | 32 | ##### 设置 33 | 34 | + 所有生产环境设置都储存在 `config/env/production.js` 35 | + 设置应用程序执行于连接埠 80(如果不是在如 nginx 之类的代理之后)。如果你使用的是 nginx,一定要对其设置中继 WebSocket 到应用程序。你可以在 nginx 文件 [WebSocket proxying](http://nginx.org/en/docs/http/websocket.html) 找到指南。 36 | + 设置「正式」环境,让所有的 css/js 被打包,且内部服务器被切换到适当的环境(需要[连接器](https://github.com/balderdashy/sails-wiki/blob/0.9/assets.md))。 37 | + 务必确认资料库已设置在正式服务器。更重要的一点是,如果你使用的是关联式资料库如 MySQL,当执行于生产环境时, Sails 会设置所有的模型为 `migrate:safe`,这代表启动应用程序时不会进行自动移转。你可以用以下方法设置资料库: 38 | + 在服务器上建立资料库,使用正式服务器作为资料库,然后在本地使用 `migrate:alter` 设置执行 Sails 应用程序。这样就自动设置好了。 39 | + 如果你无法远端连线服务器,你可以倒出在本地端的结构,并将其汇入到资料库服务器。 40 | + 启用 CSRF 来保护 POST、PUT 及 DELETE 请求 41 | + 启用 SSL 42 | + 如果你使用 SOCKETS: 43 | + 设置 `config/sockets.js` 并使用 socket.io 的[生产环境建议设置](https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO#recommended-production-settings) 44 | + 例如启用 `flashsocket` 传输 45 | 46 | ##### 部署 47 | 48 | 在生产环境中,你会想要使用 forever 或 PM2 来取代 `sails lift`,以确保即使应用程序崩溃了也会继续运作。 49 | 50 | + 安装 forever:`sudo npm install -g forever` 51 | + 更多关于 forever 的资讯:https://github.com/nodejitsu/forever 52 | + 或安装 PM2:`sudo npm install pm2 -g --unsafe-perm` 53 | + 更多关于 PM2 的资讯:https://github.com/Unitech/pm2 54 | + 从你的应用程序目录,使用 `forever start app.js --prod` 或 `pm2 start app.js -x -- --prod` 启动服务器 55 | + 这和 `sails lift --prod` 所做的事相同,但是当服务器崩溃时,它会自动重新启动。 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /concepts/Deployment/FAQ.md: -------------------------------------------------------------------------------- 1 | # 常见问题(FAQ) 2 | 3 | 4 | ##### 我可以使用环境变数吗? 5 | 6 | 你可以在 Sails 使用环境变数设置 `port` 和 `environment`。 7 | `NODE_ENV=production sails lift` 8 | `PORT=443 sails lift` 9 | 10 | ##### 在哪边放置我的生产环境资料库凭证(credentials)或其它设置? 11 | 12 | 对于其它部署/特定机器的设置,也就是任何形式的凭证,你应该使用 `config/local.js`。 13 | 它默认包含在 `.gitignore` 文档,这样你就不会无意中提交凭证到程序码储存库。 14 | 15 | **config/local.js** 16 | ```javascript 17 | // Local configuration 18 | // 19 | // Included in the .gitignore by default, 20 | // this is where you include configuration overrides for your local system 21 | // or for a production deployment. 22 | // 23 | // For example, to use port 80 on the local machine, override the `port` config 24 | module.exports = { 25 | port: 80, 26 | environment: 'production', 27 | adapters: { 28 | mysql: { 29 | user: 'root', 30 | password: '12345' 31 | } 32 | } 33 | } 34 | ``` 35 | 36 | ##### 如何让应用程序运作在服务器上? 37 | 你的 Node.js 实例已正常运作吗?在第一次的时候,当你有一个 IP 位址,便可以 ssh 连线到它,执行 `sudo npm install -g forever` 来安装 Sails 和 forever。 38 | 39 | 然后,`git clone` 你的工程(或 `scp` 到服务器,如果它不在 git 储存库中)到服务器并 `cd` 进入,接著 `forever start app.js`。 40 | 41 | 42 | ### 效能基准 43 | 44 | Sails 的效能可与你所期望的标准 Node.js/Express 应用程序相比。换句话说,就是「快」!我们在 Sails 和 Waterline 做了一些优化,但本质上,我们的重点是不要把已经非常快的东西搞糟了。最重要的,我们要感谢 @ry、@visionmedia、@isaacs、#v8、@joyent 和在 Node.js 核心团队的其他成员。 45 | 46 | + http://serdardogruyol.com/?p=111 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /concepts/Deployment/Scaling.md: -------------------------------------------------------------------------------- 1 | # 扩充(Scaling) 2 | 3 | 如果你预料到会有大流量到应用程序(或者更好的是,你已经拥有大流量!),你要建立一个可扩充的架构,让应用程序可以随著越来越多人使用而进行扩充。 4 | 5 | ### 效能基准(Benchmarks) 6 | 7 | 在大多数情况下,Sails 效能与任何 Connect、Express 或 Socket.io 应用程序相同。这已在几个不同的场合下被证实,最近一次是在[这里](http://serdardogruyol.com/?p=111)。如果你有自己的效能基准想和大家分享,请在 Github 发送 pull request 到本页面。 8 | 9 | 10 | ### 例子架构 11 | 12 | ``` 13 |       Sails.js 服务器 14 |       .... 15 |       / Sails.js 服务器 \ / 资料库(如 Mongo、Postgres 等) 16 | 负载平衡器 <--> Sails.js 服务器 <--> Socket 储存区(Redis) 17 |       \ Sails.js 服务器 / \ 会话(Session)储存区(Redis) 18 |       .... 19 |       Sails.js 服务器 20 | ``` 21 | 22 | 23 | ### 设置应用程序的丛集部署 24 | 25 | + 确保模型所使用的资料库(如 MySQL、Postgres、Mongo)具有可扩充性(如分片丛集) 26 | + 设置应用程序使用共享的会话(Session)储存区 27 | + 内建支持 redis(查看 `config/session.js` 内的 `adapter` 选项) 28 | + 如果你使用 SOCKETS: 29 | + 设置应用程序使用共享的 socket 储存区 30 | + 内建支持 redis(查看 `config/sockets.js` 内的 `adapter` 选项) 31 | + 注意:如果你不想设置 socket 储存区,这种状况下可行的解决方案是在负载平衡器使用黏性会话(sticky sessions)。 32 | + 确保应用程序可能会使用的其他相依功能没有依赖于共享记忆体。 33 | 34 | ### 部署 Sails 丛集到多台服务器 35 | 36 | + 在负载平衡器之后部署多个实例(又称服务器执行应用程序的副本) 37 | + 在每个实例使用 `forever` 启动 Sails 38 | + 更多关于负载平衡器的资讯:http://en.wikipedia.org/wiki/Load_balancing_(computing) 39 | + 设置负载平衡器终止 SSL 请求 40 | + 因为传输已经被解密,你不需要在 Sails 使用 SSL 设置 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /concepts/Logging/Logging.md: -------------------------------------------------------------------------------- 1 | # 日志(Logging) 2 | 3 | ### 概述 4 | Sails 内建一个名为 [`captains-log`](https://github.com/balderdashy/captains-log) 的简单日志记录器。它的用法与 Node 的 [`console.log`](http://nodejs.org/api/stdio.html) 非常类似,但有一些额外的功能;即支持在终端机输出多种含前缀字和颜色的日志等级。 5 | 6 | ### 组件设置 7 | Sails 日志记录器的设置在 [`sails.config.log`](http://beta.sailsjs.org/#/documentation/reference/sails.config/sails.config.log.html),照约定默认对应 Sails 工程的设置文档([`config/log.js`](http://beta.sailsjs.org/#/documentation/anatomy/myApp/config/log.js.html))。 8 | 9 | 当设置了一个日志输出等级,Sails 会在相同或高于目前设置等级时输出日志讯息。这个日志等级已标准化,且适用于从 socket.io、Waterline 及其它相依功能产生输出。日志等级和相应的优先权分级结构总结为以下图表: 10 | 11 | | 优先权 | 等级 | 可见的日志 | 12 | |-------|-----------|-------------------| 13 | | 0 | silent | 无 | 14 | | 1 | error | `.error()` | 15 | | 2 | warn | `.warn()`, `.error()` | 16 | | 3 | debug | `.debug()`, `.warn()`, `.error()` | 17 | | 4 | info | `.info()`, `.debug()`, `.warn()`, `.error()` | 18 | | 5 | verbose | `.verbose()`, `.info()`, `.debug()`, `.warn()`, `.error()` | 19 | | 6 | silly | `.silly()`, `.verbose()`, `.info()`, `.debug()`, `.warn()`, `.error()` | 20 | 21 | 22 | #### 注意事项 23 | + 默认的日志等级是「info」。当你设置应用程序的日志等级为「info」,Sails 会记录关于服务器/应用程序状态的有限资讯。 24 | + 当日志等级设置为「silly」,Sails 会记录已被绑定的路由、其它详细的框架生命周期资讯、诊断和实践细节等内部资讯。 25 | + 当日志等级设置为「verbose」,Sails 会记录 Grunt 的输出,以及更详细的路由、模型、挂勾(hook)等被载入的资讯。 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /concepts/Logging/sails.log.md: -------------------------------------------------------------------------------- 1 | # sails.log() 2 | ### 概述 3 | 4 | 下列方法接受以逗点分隔的参数,没有数量与资料型态限制。如同 `console.log`,作为参数传入 Sails 日志记录器的资料会使用 Node 的 [`util.inspect()`](http://nodejs.org/api/util.html#util_util_inspect_object_options) 自动美化,以方便阅读。因此,适用于标准 Node.js 约定,也就是说,如果你使用 `inspect()` 方法记录一个对象,它会自动执行并返回将被写入到终端机的字串。相同的,对象、日期、阵列和大多数其它资料型态会使用 `util.inspect()` 内建的逻辑来美化(例如,你会看到 `{ pet: { name: 'Hamlet' } }` 而不是 `[object Object]`。) 5 | 6 | 7 | 8 | ### `sails.log()` 9 | 10 | 默认的日志功能,会将「debug」等级的日志输出到 `stderr`。 11 | 12 | ```js 13 | sails.log('hello'); 14 | // -> debug: hello. 15 | ``` 16 | 17 | ### `sails.log.error()` 18 | 19 | 将「error」等级的日志输出到 `stderr`。 20 | 21 | ```js 22 | sails.log.error('Unexpected error occurred.'); 23 | // -> error: Unexpected error occurred. 24 | ``` 25 | 26 | ### `sails.log.warn()` 27 | 28 | 将「warn」等级的日志输出到 `stderr`。 29 | 30 | ```js 31 | sails.log.warn('File upload quota exceeded for user','request aborted.'); 32 | // -> warn: File upload quota exceeded for user- request aborted. 33 | ``` 34 | 35 | ### `sails.log.debug()` 36 | _`sails.log()` 的别名_ 37 | 38 | ### `sails.log.info()` 39 | 40 | 将「info」等级的日志输出到 `stderr`。 41 | 42 | ```js 43 | sails.log.info('A new user (', 'mike@foobar.com', ') just signed up!'); 44 | // -> info: A new user ( mike@foobar.com ) just signed up! 45 | ``` 46 | 47 | 48 | ### `sails.log.verbose()` 49 | 50 | 将「verbose」等级的日志输出到 `stderr`。 51 | 可用于截取应用程序的详细资讯,你可能只会在少数情况下使用。 52 | 53 | ```js 54 | sails.log.verbose('A user initiated an account transfer...') 55 | // -> verbose: A user initiated an account transfer... 56 | ``` 57 | 58 | 59 | ### `sails.log.silly()` 60 | 61 | 将「silly」等级的日志输出到 `stderr`。 62 | 可用于截取应用程序的完整资讯,你可能只会在少数情况下使用。 63 | 64 | ```js 65 | sails.log.silly('A user probably clicked on something..?'); 66 | // -> silly: A user probably clicked on something..? 67 | ``` 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /concepts/Middleware/Middleware.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfly/sails-docs/ce06b23006f5f2b9d65ac05eaa352542cba76481/concepts/Middleware/Middleware.md -------------------------------------------------------------------------------- /concepts/ORM/Associations/Associations.md: -------------------------------------------------------------------------------- 1 | # 关联(Associations) 2 | 3 | 使用 Sails 和 Waterline,你可以跨多个资料储存区来关联模型。这代表,即使你的使用者储存在 [PostgreSQL](http://www.postgresql.org/),而他们的相片储存在 [MongoDB](http://www.mongodb.com/),你可以与资料进行互动,就好像他们储存在相同的资料库中。你也可以使用相同桥接器跨越不同[连线](http://beta.sailsjs.org/#/documentation/reference/sails.config/sails.config.connections.html)(即资料储存区/资料库)的关联。举个能派上用场的例子,你的应用程序需要从公司的资料中心的 [MySQL](http://www.mysql.com/) 资料库存取/更新旧的食谱资料,但也要从云端的全新 MySQL 资料库存取材料资料。 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /concepts/ORM/Associations/Dominance.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfly/sails-docs/ce06b23006f5f2b9d65ac05eaa352542cba76481/concepts/ORM/Associations/Dominance.md -------------------------------------------------------------------------------- /concepts/ORM/Associations/ThroughAssociations.md: -------------------------------------------------------------------------------- 1 | # 穿透关联(Through Associations) 2 | ### 概述 3 | 4 | 多对多穿透关联的行为和多对多关联相同,且会自动为你建立例外的连接表。这使你可以附加额外的属性到连接表内的关联。 5 | 6 | 不幸的是,他们尚未支持。请不要担心,有一个简单的解决方法。 7 | 8 | 你可以通过使用一个额外的模型为中介来实现这一目标。你可以使用多个一对多关联到中介模型,取代两个模型间的多对多关联。 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /concepts/ORM/Associations/joinTables.md: -------------------------------------------------------------------------------- 1 | # 直接存取连接资料表(Direct Access to Join Tables) 2 | ### 极危险!! 3 | 4 | 你可以使用 waterline 来存取底层连接资料表。除非你知道自己在做什么,否则别这样做! 5 | 6 | 7 | TODO 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /concepts/ORM/Attributes.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfly/sails-docs/ce06b23006f5f2b9d65ac05eaa352542cba76481/concepts/ORM/Attributes.md -------------------------------------------------------------------------------- /concepts/ORM/Lifecyclecallbacks.md: -------------------------------------------------------------------------------- 1 | # 生命周期回呼(Lifecycle callbacks) 2 | 3 | ### 概述 4 | 5 | Sails 公开了一些模型的生命周期回呼,在做某些动作之前或之后会自动被呼叫。例如,我们有时候会使用生命周期回呼在建立或更新帐号模型前自动加密密码。另一个使用情况是当工程的 `name` 属性更新时自动重新产生网址。 6 | 7 | ##### `create` 的回呼 8 | 9 | - beforeValidate: fn(values, cb) 10 | - afterValidate: fn(values, cb) 11 | - beforeCreate: fn(values, cb) 12 | - afterCreate: fn(newlyInsertedRecord, cb) 13 | 14 | ##### `update` 的回呼 15 | 16 | - beforeValidate: fn(valuesToUpdate, cb) 17 | - afterValidate: fn(valuesToUpdate, cb) 18 | - beforeUpdate: fn(valuesToUpdate, cb) 19 | - afterUpdate: fn(updatedRecord, cb) 20 | 21 | ##### `destroy` 的回呼 22 | 23 | - beforeDestroy: fn(criteria, cb) 24 | - afterDestroy: fn(destroyedRecords, cb) 25 | 26 | 27 | ### 例子 28 | 29 | 如果你想在密码储存到资料库前先加密,你可以使用 `beforeCreate` 生命周期回呼。 30 | 31 | ```javascript 32 | var bcrypt = require('bcrypt'); 33 | 34 | module.exports = { 35 | 36 | attributes: { 37 | 38 | username: { 39 | type: 'string', 40 | required: true 41 | }, 42 | 43 | password: { 44 | type: 'string', 45 | minLength: 6, 46 | required: true, 47 | columnName: 'encrypted_password' 48 | } 49 | 50 | }, 51 | 52 | 53 | // 生命周期回呼 54 | beforeCreate: function (values, cb) { 55 | 56 | // 密码加密 57 | bcrypt.hash(values.password, 10, function(err, hash) { 58 | if(err) return cb(err); 59 | values.password = hash; 60 | // 呼叫 cb() 时带入一个参数,会返回错误。当某些条件失败要取消整个操作时很有用。 61 | cb(); 62 | }); 63 | } 64 | }; 65 | ``` 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /concepts/Routes/URLSlugs.md: -------------------------------------------------------------------------------- 1 | # URL Slugs 2 | A common use case for explicit routes is the design of slugs or [vanity URLs](http://en.wikipedia.org/wiki/Clean_URL#Slug). For example, consider the URL of a repository on Github, [`http://www.github.com/balderdashy/sailsjs`](http://www.github.com/balderdashy/sailsjs). In Sails, we might define this route at the **bottom of our `config/routes.js` file** like so: 3 | 4 | ```javascript 5 | 'get /:account/:repo': { 6 | controller: 'RepoController', 7 | action: 'show', 8 | skipAssets: true 9 | } 10 | ``` 11 | 12 | In your `RepoController`'s `show` action, we'd use `req.param('account')` and `req.param('repo')` to look up the data for the appropriate repository, then pass it in to the appropriate [view](http://beta.sailsjs.org/#/documentation/concepts/Views) as [locals](http://beta.sailsjs.org/#/documentation/concepts/Views/Locals.html). The [`skipAssets` option](http://beta.sailsjs.org/#/documentation/concepts/Routes/RouteTargetSyntax.html?q=route-target-options) ensures that the vanity route doesn't accidentally match any of our [assets](http://beta.sailsjs.org/#/documentation/concepts/Assets) (e.g. `/images/logo.png`), so they are still accessible. 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /concepts/Security/Clickjacking.md: -------------------------------------------------------------------------------- 1 | # Clickjacking 2 | 3 | 4 | [Clickjacking](https://www.owasp.org/index.php/Clickjacking) (aka "UI redress attacks") are where an attacker manages to trick your users into triggering "unintended" UI events (e.g. DOM events.) 5 | 6 | 7 | 8 | ### X-FRAME-OPTIONS 9 | 10 | One simple way to help prevent clickjacking attacks is to enable the X-FRAME-OPTIONS header. 11 | 12 | ##### Using [lusca](https://github.com/krakenjs/lusca#luscaxframevalue) 13 | 14 | > `lusca` is open-source under the [Apache license](https://github.com/krakenjs/lusca/blob/master/LICENSE.txt) 15 | 16 | ```sh 17 | # In your sails app 18 | npm install lusca --save 19 | ``` 20 | 21 | Then in the `middleware` config object in `config/http.js`: 22 | 23 | ```js 24 | // ... 25 | // maxAge ==> Number of seconds strict transport security will stay in effect. 26 | xframe: require('lusca').xframe('SAMEORIGIN') 27 | // ... 28 | order: [ 29 | // ... 30 | 'xframe' 31 | // ... 32 | ] 33 | ``` 34 | 35 | 36 | 37 | ### Additional Resources 38 | + [Clickjacking (OWasp)](https://www.owasp.org/index.php/Clickjacking) 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /concepts/Security/ContentSecurityPolicy.md: -------------------------------------------------------------------------------- 1 | # Content Security Policy 2 | 3 | > TODO: flesh this section out 4 | > https://www.owasp.org/index.php/Content_Security_Policy 5 | 6 | stuff 7 | stuff 8 | stuff 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /concepts/Security/Security.md: -------------------------------------------------------------------------------- 1 | # Security 2 | 3 | ### Overview 4 | 5 | Sails and Express provide built-in, easily configurable protection against most known types of web-application-level attacks. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /concepts/Security/SocketHijacking.md: -------------------------------------------------------------------------------- 1 | # Socket Hijacking 2 | 3 | Unfortunately, cross-site request forgery attacks are not limited to the HTTP protocol. WebSocket hijacking (sometimes known as [CSWSH](http://www.christian-schneider.net/CrossSiteWebSocketHijacking.html)) is a commonly overlooked vulnerability in most realtime applications. Fortunately, since Sails treats both HTTP and WebSocket requests as first-class citizens, its built-in [CSRF protection](http://beta.sailsjs.org/#/documentation/concepts/Security/CSRF.html) and [configurable CORS rulesets](http://beta.sailsjs.org/#/documentation/concepts/Security/CORS.html) apply to both protocols. 4 | 5 | You can prepare your Sails app against CSWSH attacks by enabling the built-in protection in [`config/csrf.js`](http://beta.sailsjs.org/#/documentation/anatomy/myApp/config/csrf.js.html) and ensuring that a `_csrf` token is sent with all relevant incoming socket requests. Additionally, if you're planning on allowing sockets to connect to your Sails app cross-origin (i.e. from a different domain, subdomain, or port) you'll want to configure your CORS settings accordingly. You can also define the `authorization` setting in [`config/sockets.js`](http://beta.sailsjs.org/#/documentation/anatomy/myApp/config/sockets.js.html) as a custom function which allows or denies the initial socket connection based on your needs. 6 | 7 | #### Notes 8 | + CSWSH prevention is only a concern in scenarios where people use the same client application to connect sockets to multiple web services (e.g. cookies in a browser like Google Chrome can be used to connect a socket to Chase.com from both Chase.com and Horrible-Hacker-Site.com.) 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /concepts/Security/StrictTransportSecurity.md: -------------------------------------------------------------------------------- 1 | # HTTP Strict Transport Security 2 | 3 | 4 | ### Enabling STS 5 | 6 | Implementing STS is actually very simple and [only takes a few lines of code](https://github.com/krakenjs/lusca/blob/master/lib/hsts.js). But better yet, a few different open-source modules exist that bring support for this feature to Express and Sails. To use one of these modules, install it from npm using the directions below, then open `config/http.js` in your project and [configure it as a custom middleware](http://beta.sailsjs.org/#/documentation/concepts/Middleware). The example(s) below cover basic usage and configuration. For more guidance and advanced usage details, be sure and follow the link to the docs. 7 | 8 | 9 | ##### Using [lusca](https://github.com/krakenjs/lusca#luscahstsoptions) 10 | 11 | > `lusca` is open-source under the [Apache license](https://github.com/krakenjs/lusca/blob/master/LICENSE.txt) 12 | 13 | 14 | ```sh 15 | # In your sails app 16 | npm install lusca --save 17 | ``` 18 | 19 | Then in the `middleware` config object in `config/http.js`: 20 | 21 | ```js 22 | // ... 23 | // maxAge ==> Number of seconds strict transport security will stay in effect. 24 | strictTransportSecurity: require('lusca').hsts({ maxAge: 31536000 }) 25 | // ... 26 | ``` 27 | 28 | 29 | 30 | ### Additional Resources 31 | + [HTTP Strict Transport Security (OWasp)](https://www.owasp.org/index.php/HTTP_Strict_Transport_Security) 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /concepts/Security/XSS.md: -------------------------------------------------------------------------------- 1 | # XSS 2 | 3 | Cross-site scripting (XSS) is a type of attack in which a malicious agent manages to inject client-side JavaScript into your website, so that it runs in the trusted environment of your users' browsers. 4 | 5 | 6 | 7 | ### Additional Resources 8 | + [XSS (OWasp)](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)) 9 | + [XSS Prevention Cheatsheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet) 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /concepts/Services/Services.md: -------------------------------------------------------------------------------- 1 | # Services 2 | 3 | ## Overview 4 | 5 | Services can be thought of as libraries which contain functions that you might want to use in many places of your application. For example, you might have an EmailService which wraps some default email message boilerplate code that you would want to use in many parts of your application. The main benefit of using services in Sails is that they are *globalized*--you don't have to use `require()` to access them. 6 | 7 | 8 | ## How do I create a service? 9 | 10 | Simply save a Javascript file containing a function or object into your **api/services** folder. The filename will be used as the globally-accessible variable name for the service. For example, an email service might look something like this: 11 | 12 | ```javascript 13 | // EmailService.js - in api/services 14 | module.exports = { 15 | 16 | sendInviteEmail: function(options) { 17 | 18 | var opts = {"type":"messages","call":"send","message": 19 | { 20 | "subject": "YourIn!", 21 | "from_email": "info@balderdash.co", 22 | "from_name": "AmazingStartupApp", 23 | "to":[ 24 | {"email": options.email, "name": options.name} 25 | ], 26 | "text": "Dear "+options.name+",\nYou're in the Beta! Click to verify your account" 27 | } 28 | }; 29 | 30 | myEmailSendingLibrary.send(opts); 31 | 32 | } 33 | }; 34 | ``` 35 | 36 | You can then use `EmailService` anywhere in your app: 37 | 38 | ```javascript 39 | // Somewhere in a controller 40 | EmailService.sendInviteEmail({email: 'test@test.com', name: 'test'}); 41 | ``` 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /concepts/Views/Partials.md: -------------------------------------------------------------------------------- 1 | # Partials 2 | 3 | Sails uses `ejs-locals` in its view rendering code, so in your views you can do: 4 | 5 | ``` 6 | <%- partial ('foo.ejs') %> 7 | ``` 8 | 9 | to render a partial located at `/views/foo.ejs`. All of your locals will be sent to the partial automatically. 10 | 11 | the paths are relative to the view, that is loading the partial. So if you have a a user view at `/views/users/view.ejs` and want to load `/views/partials/widget.ejs` then you would use: 12 | 13 | ``` 14 | <%- partial ('../../partials/widget.ejs') %> 15 | ``` 16 | 17 | One thing to note: partials are rendered synchronously, so they will block Sails from serving more requests until they're done loading. It's something to keep in mind while developing your app, especially if you anticipate a large number of connections. 18 | 19 | NOTE: When using other templating languages than ejs, their syntax for loading partials or block, etc. will be used. Please refer to their documentation for more information on their syntax and conventions 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /concepts/extending-sails/Adapters/customAdapters.md: -------------------------------------------------------------------------------- 1 | # Custom Adapters 2 | ### Overview 3 | 4 | Sails makes it fairly easy to write your own adapter. Check out the [sails-boilerplate-repo](https://github.com/balderdashy/sails-adapter-boilerplate) to learn how 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /concepts/extending-sails/Generators/Generators.md: -------------------------------------------------------------------------------- 1 | # Generators 2 | ## Status 3 | 4 | ##### Stability: [2](http://nodejs.org/api/documentation.html#documentation_stability_index) - Unstable 5 | 6 | The API is in the process of settling, but has not yet had sufficient real-world testing to be considered stable. 7 | 8 | Backwards-compatibility will be maintained if reasonable. 9 | 10 | 11 | ### Purpose 12 | 13 | What is my purpose in this world? 14 | 15 | ### old partial content from when spec was an itty bitty baby 16 | 17 | Generators are designed to make it easier to customize the `sails new` and `sails generate` command-line tools, and provide better support for different Gruntfiles, configuration options, view engines, coffeescript, etc. 18 | 19 | 20 | #### Structure 21 | 22 | 23 | A generator has either: 24 | 25 | (1) a `generate` method, or 26 | 27 | (2) a `configure` + `render` method (render may be omitted in the simplest of cases) 28 | 29 | 30 | Sails 31 | 32 | ``` 33 | app (appPath + name) 34 | <- view 35 | <- folder 36 | <- jsonfile 37 | <- file 38 | 39 | api (appPath + name) 40 | <- controller 41 | <- model 42 | 43 | controller (appPath + template + name) 44 | <- file 45 | 46 | model (appPath + template + name) 47 | <- file 48 | 49 | view (appPath + template + name) 50 | <- file 51 | 52 | file (destination + name + template + data) 53 | 54 | jsonfile (destination + name + data) 55 | 56 | folder (destination + name) 57 | ``` 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /concepts/extending-sails/Generators/customGenerators.md: -------------------------------------------------------------------------------- 1 | # Custom Generators 2 | ### Overview 3 | 4 | Here is some info on writing custom generators. 5 | 6 | 7 | -------------------------------------------------------------------------------- /concepts/extending-sails/Generators/generatorList.md: -------------------------------------------------------------------------------- 1 | # List of Available Adapters 2 | This file is meant to be an up to date, comprehensive list of all of the generators available for the Sails.js framework. If we missed one or you would like to add a generator you've made, just submit a Pull Request to this file, adding to the list. 3 | 4 | ### Officially Supported Generators 5 | 6 | #### sails-generate-generator 7 | ###### Github Repo 8 | https://github.com/balderdashy/sails-generate-generator/ 9 | 10 | ###### On NPM 11 | 'npm install sails-generate-generator` 12 | 13 | ###### Description 14 | Generate the boilerplates to make your own generator. 15 | 16 | 17 | 18 | 19 | 20 | ### Community Supported Generators 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /concepts/extending-sails/Hooks/hookList.md: -------------------------------------------------------------------------------- 1 | # List of Available Hooks 2 | This file is meant to be an up to date, comprehensive list of all of the `hooks` available for the Sails.js framework. If we missed one or you would like to add a `hook` you've made, just submit a Pull Request to this file, adding to the list. 3 | 4 | 5 | ### Community Supported Hooks 6 | 7 | #### IRC Bot Hook 8 | ##### Github Repo 9 | https://github.com/uncletammy/sails-hooks-irc 10 | 11 | ##### On NPM 12 | 'npm install sails-userhooks-ircbot` 13 | 14 | ##### Description 15 | Easily add an IRC bot to your Sails.js app 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /concepts/extending-sails/extending-sails.md: -------------------------------------------------------------------------------- 1 | # Extending Sails 2 | 3 | There are currently three types of plugins in Sails: 4 | 5 | + **Generators** - for adding and overriding functionality in the Sails CLI 6 | + **Adapters** - for integrating Waterline (Sails' ORM) with new data sources, including databases, APIs, or even hardware. 7 | + **Hooks** - for overriding or injecting new low-level functionality in the Sails runtime 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /getting-started/getting-started.md: -------------------------------------------------------------------------------- 1 | # 新手上路 2 | 3 | ## 安装 4 | 要安装最新稳定版的命令行工具: 5 | 6 | ``` 7 | sudo npm -g install sails 8 | ``` 9 | 10 | 在 Windows 上,不需要 sudo: 11 | 12 | ``` 13 | npm -g install sails 14 | ``` 15 | 16 | ## 建立一个新的 Sails 工程 17 | 建立一个新的应用程序: 18 | 19 | ``` 20 | sails new testProject 21 | ``` 22 | 23 | 现在,启动服务器: 24 | 25 | ``` 26 | cd testProject 27 | sails lift 28 | ``` 29 | 30 | 此时,访问(http://localhost:1337/),你会看到默认的首页。 31 | 32 | 现在,让我们用 Sails 做更酷的东西吧! 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /reference/README.md: -------------------------------------------------------------------------------- 1 | # sails-docs-reference 2 | 3 | Reference Section of Sails.js documentation 4 | 5 | 6 | 7 | ## ideas for some restructuring: 8 | 9 | 10 | ``` 11 | | 12 | |- Usage 13 | | 14 | |- Request (req) 15 | | 16 | |- Response (res) 17 | | 18 | |- Config (sails.config) 19 | | 20 | |- Model (sails.models) 21 | | 22 | |- Sockets (sails.sockets) 23 | | 24 | |- Sails CLI 25 | | 26 | |- Blueprint API 27 | | 28 | |- Browser SDK (sails.io.js) 29 | 30 | | 31 | |- Concepts 32 | | 33 | |- Security 34 | | 35 | |- Deployment 36 | | 37 | |- FAQ 38 | |- Hosting 39 | |- Scaling 40 | | 41 | |- Testing 42 | | 43 | |- Internationalization 44 | | 45 | |- Logging 46 | | 47 | |- File Uploads 48 | | 49 | |- Assets & Tasks 50 | | 51 | |- Middleware 52 | | 53 | |- Routes 54 | | 55 | |- Blueprints 56 | | 57 | |- Policies 58 | | 59 | |- Controllers 60 | | 61 | |- Custom Responses 62 | | 63 | |- Models 64 | | 65 | |- Attributes 66 | |- Validations 67 | |- Associations 68 | |- Lifecycle Callbacks 69 | |- Custom Schemas 70 | |- Migrations 71 | | 72 | |- Services 73 | |- todo: add example: Sending Email 74 | | 75 | |- Views 76 | 77 | | 78 | |- Advanced 79 | | 80 | |- Plugins 81 | | 82 | |- Programmatic Usage 83 | | 84 | |- Globals 85 | | 86 | |- .sailsrc 87 | 88 | 89 | ``` 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /reference/cli/cli.md: -------------------------------------------------------------------------------- 1 | # Command Line Interface (CLI) 2 | 3 | ### Overview 4 | Sails comes with a convenient command line tool to quickly get your app scaffolded and running. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /reference/cli/sailsdebug.md: -------------------------------------------------------------------------------- 1 | # sails debug 2 | 3 | Attach the node debugger and lift the sails app; similar to running `node --debug app.js`. Takes the same options as `sails lift`. You can then use [node-inspector](https://github.com/node-inspector/node-inspector) to debug your app as it runs. 4 | 5 | 6 | ### Example 7 | 8 | ```sh 9 | $ sails debug 10 | 11 | info: Running node-inspector on this app... 12 | info: If you don't know what to do next, type `help` 13 | info: Or check out the docs: 14 | info: http://nodejs.org/api/debugger.html 15 | 16 | info: ( to exit, type + ) 17 | 18 | debugger listening on port 5858 19 | ``` 20 | 21 | 22 | 23 | 24 | > To use the standard (command-line) node debugger with sails, you can always just run `node debug app.js`. 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /reference/cli/sailsgenerate.md: -------------------------------------------------------------------------------- 1 | # sails generate 2 | 3 | Sails ships with several *generators* to help you scaffold new projects. You can also [create your own generators](http://beta.sailsjs.org/#/documentation/concepts/extending-sails/Generators/customGenerators.html) to handle frequent tasks, or extend functionality (for example, by creating a generator that outputs view files for your [favorite templating language](https://github.com/balderdashy/sails-generate-views-jade)). 4 | 5 | The following generators are bundled with Sails: 6 | 7 | #### `sails generate new ` 8 | Create a new Sails project in a folder called **appName**. See [`sails new`](http://beta.sailsjs.org/#/documentation/reference/cli/sailsnew.html) for usage options. 9 | 10 | #### `sails generate api ` 11 | Generate **api/models/Foo.js** and **api/controllers/FooController.js** 12 | 13 | #### `sails generate model [attribute1:type1, attribute2:type2 ... ]` 14 | Generate **api/models/Foo.js**, optionally include attributes with the specified types. 15 | 16 | #### `sails generate controller [action1, action2, ...]` 17 | Generate **api/controllers/FooController.js**, optionally include actions with the specified names. 18 | 19 | #### `sails generate adapter ` 20 | Generate a **api/adapters/foo** folder containing the files necessary for building a new adapter. 21 | 22 | #### `sails generate generator ` 23 | Generate a **foo** folder containing the files necessary for building a new generator. 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /reference/cli/sailslift.md: -------------------------------------------------------------------------------- 1 | # sails lift 2 | 3 | Run the Sails app in the current dir (if `node_modules/sails` exists, it will be used instead of the globally installed Sails) 4 | 5 | ##### Options: 6 | 7 | * `--dev` - in development environment (the default). In the development environment Sails use *grunt-watch* to keep a eye on your files in `/assets`. If you change something (for example in one of our css-files) and reload your browser Sails will automatically show your changes. Also you views won't be cached so you can change your view-files without restarting Sails like the assets. 8 | * `--prod` - in production environment 9 | * `--port ` - on the port specified by `portNum` instead of the default (1337) 10 | * `--verbose` - with verbose logging enabled 11 | * `--silly` - with insane logging enabled 12 | 13 | 14 | ### Example 15 | 16 | ```sh 17 | $ sails lift 18 | 19 | info: Starting app... 20 | 21 | info: 22 | info: 23 | info: Sails <| 24 | info: v0.11.3 |\ 25 | info: /|.\ 26 | info: / || \ 27 | info: ,' |' \ 28 | info: .-'.-==|/_--' 29 | info: `--'-------' 30 | info: __---___--___---___--___---___--___ 31 | info: ____---___--___---___--___---___--___-__ 32 | info: 33 | info: Server lifted in `/Users/mikermcneil/code/sandbox/second` 34 | info: To see your app, visit http://localhost:1337 35 | info: To shut down Sails, press + C at any time. 36 | 37 | debug: -------------------------------------------------------- 38 | debug: :: Sat Apr 05 2014 17:03:39 GMT-0500 (CDT) 39 | 40 | debug: Environment : development 41 | debug: Port : 1337 42 | debug: -------------------------------------------------------- 43 | ``` 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /reference/cli/sailsnew.md: -------------------------------------------------------------------------------- 1 | # sails new 2 | 3 | `sails new ` creates a new Sails project in a folder called **appName**. 4 | 5 | ##### Options: 6 | 7 | * `--no-linker` Disable automatic asset linking in your view and static HTML files (the relevant grunt tasks will not be created) 8 | * `--no-frontend` Disable the generation of the `assets` folder and files. Views will be created with hardcopied linked resources off of sailsjs.org. 9 | * `--template=[template language]` Use a different template language than the default (e.g. `jade`). Requires that a views generator for that language (e.g. `sails-generate-views-jade`) be installed in your global node path (e.g. `~/node_modules/` works). 10 | 11 | > `sails new` is really just a special [generator](http://beta.sailsjs.org/#/documentation/concepts/extending-sails/Generators) which runs [`sails-generate-new`](http://github.com/balderdashy/sails-generate-new). In other words, running `sails new foo` is an alias for running `sails generate new foo`, and like any Sails generator, the actual generator module which gets run can be overridden in your global `~/.sailsrc` file. 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /reference/cli/sailsversion.md: -------------------------------------------------------------------------------- 1 | # sails version 2 | 3 | Get the current globally installed Sails version. 4 | 5 | ### Example 6 | 7 | ```sh 8 | $ sails version 9 | 0.10.0-rc5 10 | ``` 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /reference/req/req.accepted.md: -------------------------------------------------------------------------------- 1 | # req.accepted 2 | 3 | Contains an array of the "media types" this request (`req`) can accept (e.g. `text/html` or `application/json`), ordered from highest to lowest quality. 4 | 5 | ### Usage 6 | ```javascript 7 | req.accepted; 8 | ``` 9 | 10 | ### Example 11 | 12 | ```javascript 13 | req.accepted; 14 | 15 | /* 16 | [ { value: 'application/json', 17 | quality: 1, 18 | type: 'application', 19 | subtype: 'json' }, 20 | { value: 'text/html', 21 | quality: 0.5, 22 | type: 'text', 23 | subtype: 'html' } ] 24 | */ 25 | ``` 26 | 27 | ### Notes 28 | > + See the [`accepts` module](https://github.com/expressjs/accepts) for the finer details of the header parsing algorithm used in Sails/Express/Koa/Connect. 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /reference/req/req.acceptedCharsets.md: -------------------------------------------------------------------------------- 1 | # req.acceptedCharsets 2 | This property is an array that contains the acceptable charsets specified by the user agent in the request. 3 | 4 | 5 | 6 | ### Usage 7 | 8 | ```js 9 | req.acceptedCharsets; 10 | ``` 11 | 12 | ### Details 13 | 14 | Useful for advanced content negotiation where a client may or may not support certain character sets, such as unicode (utf-8.) This returns all of the "acceptable" charsets specified in this request's `Accept-Charset` header (see [RFC-2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2).) 15 | 16 | 17 | 18 | ### Example 19 | 20 | ```js 21 | req.acceptedCharsets; 22 | // -> ['utf-8', 'utf-16'] 23 | ``` 24 | 25 | ### Notes 26 | > + See the [`accepts` module](https://github.com/expressjs/accepts) for the finer details of the header parsing algorithm used in Sails/Express/Koa/Connect. 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /reference/req/req.acceptedLanguages.md: -------------------------------------------------------------------------------- 1 | # req.acceptedLanguages 2 | An array containing the "acceptable" response languages specified by the user agent in the "[Accept-Language](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4)" header of this request (`req`). 3 | 4 | ### Usage 5 | ```js 6 | req.acceptedLanguages; 7 | ``` 8 | 9 | ### Details 10 | 11 | `req.acceptedLanguages` contains all the languages specified by the request's `Accept-Language` header (see [RFC-2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4).) 12 | 13 | This method is used by Sails internally for its implementation of internationalization and localization. The [i18n](http://beta.sailsjs.org/#/documentation/concepts/Internationalization) hook automatically serves different content to different locales, based on the request. 14 | 15 | 16 | ### Example 17 | 18 | ```js 19 | req.acceptedLanguages; 20 | // -> ['en-US', 'en'] 21 | ``` 22 | 23 | ### Notes 24 | > + See the [`accepts` module](https://github.com/expressjs/accepts) for the finer details of the header parsing algorithm used in Sails/Express/Koa/Connect. 25 | > + Browsers send the "Accept-Language" header automatically based on the user's language settings. 26 | > + You can expect the "Accept-Language" header to exist in most requests which originate from web browsers. 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /reference/req/req.accepts.md: -------------------------------------------------------------------------------- 1 | # req.accepts() 2 | 3 | Checks whether this request's stated list of "accepted" [media types](http://www.iana.org/assignments/media-types/media-types.xhtml) includes the specified `type`. Returns true or false. 4 | 5 | 6 | ### Usage 7 | ```javascript 8 | req.accepts(type); 9 | ``` 10 | 11 | ### Example 12 | 13 | ```javascript 14 | req.accepts('application/json'); 15 | // -> true 16 | req.accepts('json'); 17 | // -> true 18 | ``` 19 | 20 | ### Notes 21 | > + See the [`accepts` module](https://github.com/expressjs/accepts) for the finer details of the header parsing algorithm used in Sails/Express/Koa/Connect. 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/req/req.acceptsCharset.md: -------------------------------------------------------------------------------- 1 | # req.acceptsCharset() 2 | 3 | Returns whether this request (`req`) is able to handle a specified `characterSet`. 4 | 5 | 6 | ### Usage 7 | 8 | ```js 9 | req.acceptsCharset(characterSet); 10 | ``` 11 | 12 | ### Details 13 | 14 | Useful for advanced content negotiation where a client may or may not support certain character sets, such as unicode (utf-8.) This method determines whether or not a request has specified the given `characterSet` as "acceptable" its `Accept-Charset` header (see [RFC-2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2).) 15 | 16 | 17 | 18 | ### Example 19 | 20 | If a request is sent with a `"Accept-Charset: utf-8"` header: 21 | 22 | ```js 23 | req.acceptsCharset('utf-8'); 24 | // -> true 25 | ``` 26 | 27 | ### Notes 28 | > + See the [`accepts` module](https://github.com/expressjs/accepts) for the finer details of the header parsing algorithm used in Sails/Express/Koa/Connect. 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /reference/req/req.acceptsLanguage.md: -------------------------------------------------------------------------------- 1 | # req.acceptsLanguage() 2 | 3 | Returns whether this request (`req`) considers a certain `language` "acceptable". 4 | 5 | 6 | ### Usage 7 | 8 | ```js 9 | req.acceptsLanguage(language); 10 | ``` 11 | 12 | ### Details 13 | 14 | `req.acceptsLanguage()` returns true if a request has specified the given `language` as "acceptable" its `Accept-Language` header (see [RFC-2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4).) 15 | 16 | This method is used by Sails internally for its implementation of internationalization and localization. The [i18n](http://beta.sailsjs.org/#/documentation/concepts/Internationalization) hook automatically serves different content to different locales, based on the request. 17 | 18 | 19 | ### Example 20 | 21 | If a request is sent with a `"Accept-Charset: utf-8"` header: 22 | 23 | ```js 24 | req.acceptsCharset('utf-8'); 25 | // -> true 26 | ``` 27 | 28 | ### Notes 29 | > + See the [`accepts` module](https://github.com/expressjs/accepts) for the finer details of the header parsing algorithm used in Sails/Express/Koa/Connect. 30 | > + Browsers send the "Accept-Language" header automatically based on the user's language settings. 31 | > + You can expect the "Accept-Language" header to exist in most requests which originate from web browsers. 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /reference/req/req.allParams.md: -------------------------------------------------------------------------------- 1 | # req.allParams() 2 | 3 | Returns the value of _all_ parameters sent in the request, merged together into a single object. Includes parameters parsed from the url path, the query string, and the request body. See [`req.param()`](./#!documentation/reference/req.param) for details. 4 | 5 | ### Usage 6 | 7 | ```js 8 | req.allParams(); 9 | ``` 10 | 11 | 12 | ### Example 13 | 14 | Update the product with the specified `sku`, setting new values using the parameters which were passed in: 15 | 16 | ```javascript 17 | var values = req.allParams(); 18 | 19 | // Don't allow `price` or `isAvailable` to be edited. 20 | delete values.price; 21 | delete values.isAvailable; 22 | 23 | // At this point, `values` might look something like this: 24 | // values ==> { displayName: 'Bubble Trouble Bubble Bath' } 25 | 26 | Product.update({sku: sku}) 27 | .set(values) 28 | .then(function (newProduct) { 29 | // ... 30 | }); 31 | ``` 32 | 33 | ### Notes 34 | 35 | >+ This method can also be called as `req.params.all()` - they are synonyms. 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /reference/req/req.body.md: -------------------------------------------------------------------------------- 1 | # req.body 2 | 3 | An object containing text parameters from the parsed request body, defaulting to `{}`. 4 | 5 | By default, the request body can be url-encoded or stringified as JSON. Support for other formats, such as serialized XML, is possible using the [middleware](http://beta.sailsjs.org/#/documentation/concepts/Middleware) configuration. 6 | 7 | ### Usage 8 | ```js 9 | req.body; 10 | ``` 11 | 12 | ### Notes 13 | >+ If a request contains one or more file uploads, only the text parameters sent _**before**_ the first file parameter will be available in `req.body`. 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /reference/req/req.cookies.md: -------------------------------------------------------------------------------- 1 | # req.cookies 2 | An object containing all of the [**unsigned cookies**](https://github.com/balderdashy/sails-docs/blob/master/PAGE_NEEDED.md) from this request (`req`). 3 | 4 | 5 | ### Usage 6 | ```javascript 7 | req.cookies; 8 | ``` 9 | 10 | 11 | ### Example 12 | Assuming the request contained a cookie named "chocolatechip" with value "Yummy: 13 | 14 | ```javascript 15 | req.cookies.chocolatechip; 16 | // "Yummy" 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/req/req.fresh.md: -------------------------------------------------------------------------------- 1 | # req.fresh 2 | 3 | A flag indicating the user-agent sending this request (`req`) wants "fresh" data (as indicated by the "[if-none-match](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26)", "[cache-control](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9)", and/or "[if-modified-since](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25)" request headers.) 4 | 5 | If the request wants "fresh" data, usually you'll want to `.find()` fresh data from your models and send it back to the client. 6 | 7 | ### Usage 8 | ```js 9 | req.fresh; 10 | ``` 11 | 12 | ### Example 13 | ```js 14 | if (req.fresh) { 15 | // The user-agent is asking for a more up-to-date version of the requested resource. 16 | // Let's hit the database to get some stuff and send it back. 17 | } 18 | ``` 19 | 20 | ### Notes 21 | > + See the [`node-fresh`](https://github.com/visionmedia/node-fresh) module for details specific to the implementation in Sails/Express/Koa/Connect. 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /reference/req/req.get.md: -------------------------------------------------------------------------------- 1 | # req.get() 2 | 3 | Returns the value of the specified `header` field in this request (`req`). Note that header names are case-_insensitive_. 4 | 5 | ### Usage 6 | 7 | ```js 8 | req.get(header); 9 | ``` 10 | 11 | ### Example 12 | Assuming `req` contains a header named 'myField' with value 'cat': 13 | 14 | ```javascript 15 | req.get('myField'); 16 | // -> cat 17 | ``` 18 | 19 | ### Notes 20 | >+ The `header` argument is case-insensitive. 21 | >+ The `header` argument treats both "referrer" and "referer" as synonyms, because sp3ll1n6. 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /reference/req/req.host.md: -------------------------------------------------------------------------------- 1 | # req.host 2 | The hostname of this request, without the port number, as specified by its "Host" header. 3 | 4 | 5 | ### Usage 6 | ```javascript 7 | req.host; 8 | ``` 9 | 10 | ### Example 11 | 12 | If this request's "Host" header was: "ww3.staging.ibm.com:1492": 13 | 14 | ```javascript 15 | req.host; 16 | // -> "ww3.staging.ibm.com" 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /reference/req/req.ip.md: -------------------------------------------------------------------------------- 1 | # req.ip 2 | ### Purpose 3 | The IP address of the client who sent this request (`req`). 4 | 5 | If the `trust proxy` option is disabled, this is the "remote address". Otherwise, if `trust proxy` is enabled, this is the "upstream address". 6 | 7 | 8 | ### Usage 9 | ```javascript 10 | req.ip; 11 | ``` 12 | 13 | ### Example 14 | ```javascript 15 | req.ip; 16 | // -> "127.0.0.1" 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /reference/req/req.ips.md: -------------------------------------------------------------------------------- 1 | # req.ips 2 | If "trust proxy" is enabled, this variable contains the IP addresses in this request's "X-Forwarded-For" header as an array of the IP address strings. Otherwise an empty array is returned. 3 | 4 | ### Usage 5 | ```js 6 | req.ips; 7 | ``` 8 | 9 | ### Example 10 | If a request contains a header: "X-Forwarded-For: client, proxy1, proxy2": 11 | 12 | ```js 13 | req.ips; 14 | // -> ["client", "proxy1", "proxy2"]` 15 | 16 | // ("proxy2" is the furthest "down-stream" IP address) 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /reference/req/req.is.md: -------------------------------------------------------------------------------- 1 | # req.is() 2 | Returns true if this request's declared "Content-Type" matches the specified media/mime `type`. 3 | 4 | Specifically, this method matches the given `type` against this request's "Content-Type" header. 5 | 6 | ### Usage 7 | ```js 8 | req.is(type); 9 | ``` 10 | 11 | 12 | ### Example 13 | Assuming the request contains a "Content-Type" header, "text/html; charset=utf-8": 14 | ```javascript 15 | req.is('html'); 16 | // -> true 17 | req.is('text/html'); 18 | // -> true 19 | req.is('text/*'); 20 | // -> true 21 | ``` 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/req/req.isSocket.md: -------------------------------------------------------------------------------- 1 | # req.isSocket 2 | 3 | A flag indicating whether or not this request (`req`) originated from a Socket.io connection. 4 | 5 | 6 | ### Usage 7 | ```js 8 | req.isSocket; 9 | ``` 10 | 11 | ### Example 12 | ```javascript 13 | if (req.isSocket){ 14 | // You're a socket. Do cool socket stuff. 15 | } 16 | else { 17 | // Just another HTTP request. 18 | } 19 | ``` 20 | 21 | ### Notes 22 | 23 | > + Useful for allowing HTTP requests to skip calls to pubsub or WebSocket-centric methods like `subscribe()` or `watch()` that depend on an actual Socket.io request. This allows you to reuse backend code, using it for both WebSocket and HTTP clients. 24 | > + As you might expect, `req.isSocket` doesn't need to be checked before running methods which **publish to other** connected sockets. Those methods don't depend on the request, so they work either way. 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /reference/req/req.method.md: -------------------------------------------------------------------------------- 1 | # req.method 2 | The request method (aka "verb".) 3 | 4 | ### Usage 5 | ```js 6 | req.method; 7 | ``` 8 | 9 | ### Example 10 | 11 | If a client sends a POST request to `/product`: 12 | 13 | ```js 14 | req.method; 15 | // -> "POST" 16 | ``` 17 | 18 | ### Notes 19 | 20 | > + All requests to a Sails server have a "method", even via WebSockets (this is thanks to the request interpreter) 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /reference/req/req.param.md: -------------------------------------------------------------------------------- 1 | # req.param() 2 | Returns the value of the parameter with the specified name. 3 | 4 | ### Usage 5 | 6 | ```javascript 7 | req.param(name); 8 | ``` 9 | 10 | ### Details 11 | 12 | `req.param()` searches the url path, query string, and body of the request for the specified parameter. If no parameter value exists anywhere in the request with the given `name`, it returns `undefined`. 13 | 14 | + url path parameters ([`req.params`](http://beta.sailsjs.org/#/documentation/reference/req/req.params.html)) 15 | + e.g. a request "/foo/4" to route `/foo/:id` has url path params `{ id: 4 }` 16 | + query string parameters ([`req.query`](http://beta.sailsjs.org/#/documentation/reference/req/req.query.html)) 17 | + e.g. a request "/foo?email=5" has query params `{ email: 5 }` 18 | + body parameters ([`req.body`](http://beta.sailsjs.org/#/documentation/reference/req/req.body.html)) 19 | + e.g. a request with a parseable body (e.g. JSON, url-encoded, or XML) has body parameters equal to its parsed value 20 | 21 | 22 | ### Example 23 | 24 | Consider a route (`POST /product/:sku`) which points to a blueprint, controller, or policy with the following code: 25 | 26 | ```javascript 27 | req.param('sku'); 28 | // -> 123 29 | ``` 30 | 31 | We can get the expected result by sending the `sku` parameter any of the following ways: 32 | 33 | + `POST /product/123` 34 | + `POST /product?sku=123` 35 | + `POST /product` 36 | + with a JSON request body: `{ "sku": 123 }` 37 | 38 | 39 | 40 | ### Notes 41 | > + If you'd like to get ALL parameters from ALL sources (including the URL path, query string, and parsed request body) you can use [`req.allParams()`](http://beta.sailsjs.org/#/documentation/reference/req/req.allParams.html). 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /reference/req/req.params.md: -------------------------------------------------------------------------------- 1 | # req.params 2 | 3 | An object containing parameter values parsed from the URL path. 4 | 5 | For example if you have the route `/user/:name`, then the "name" from the URL path wil be available as `req.params.name`. This object defaults to `{}`. 6 | 7 | 8 | ### Usage 9 | 10 | ```javascript 11 | req.params; 12 | ``` 13 | 14 | ### Notes 15 | > + When a route address is defined using a regular expression, each capture group match from the regex is available as `req.params[0]`, `req.params[1]`, etc.This strategy is also applied to unnamed wild-card matches in string routes such as `/file/*`. 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /reference/req/req.path.md: -------------------------------------------------------------------------------- 1 | # req.path 2 | 3 | The URL pathname from the [request URL string](http://nodejs.org/api/http.html#http_message_url) of the current request (`req`). Note that this is the part of the URL after and including the leading slash (e.g. `/foo/bar`), but without the query string (e.g. `?name=foo`) or fragment (e.g. `#foobar`.) 4 | 5 | 6 | ### Usage 7 | 8 | ```js 9 | req.path; 10 | ``` 11 | 12 | 13 | ### Example 14 | 15 | Assuming a client sends the following request: 16 | 17 | > http://localhost:1337/donor/37?name=foo#foobar 18 | 19 | `req.path` will be defined as follows: 20 | 21 | ```js 22 | req.path; 23 | // -> "/donor/37" 24 | ``` 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /reference/req/req.protocol.md: -------------------------------------------------------------------------------- 1 | # req.protocol 2 | The protocol used to send this request (`req`). 3 | 4 | ### Usage 5 | ```javascript 6 | req.protocol; 7 | ``` 8 | 9 | ### Example 10 | 11 | ```js 12 | switch (req.protocol) { 13 | case 'http': 14 | // this is an HTTP request 15 | break; 16 | case 'https': 17 | // this is a secure HTTPS request 18 | break; 19 | } 20 | ``` 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /reference/req/req.query.md: -------------------------------------------------------------------------------- 1 | # req.query 2 | 3 | An object containing the parsed query-string, defaulting to `{}`. 4 | 5 | ### Usage 6 | ```js 7 | req.query; 8 | ``` 9 | 10 | ### Example 11 | 12 | If the request is `GET /search?q=mudslide`: 13 | 14 | ```js 15 | req.query.q 16 | // -> "mudslide" 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /reference/req/req.secure.md: -------------------------------------------------------------------------------- 1 | # req.secure 2 | 3 | Indicates whether or not the request was sent over a secure [TLS](http://en.wikipedia.org/wiki/Transport_Layer_Security) connection (i.e. `https://` or `wss://`). 4 | 5 | ### Usage 6 | ```javascript 7 | req.secure; 8 | ``` 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /reference/req/req.signedCookies.md: -------------------------------------------------------------------------------- 1 | # req.signedCookies 2 | 3 | ### Purpose 4 | An object containing all of the [**signed cookies**](https://github.com/balderdashy/sails-docs/blob/master/PAGE_NEEDED.md) from this request (`req`). 5 | 6 | 7 | ### Usage 8 | ```javascript 9 | req.signedCookies; 10 | ``` 11 | 12 | 13 | 14 | ### Example 15 | Assuming the request contained a signed cookie named "chocolatechip" with value "Yummy: 16 | 17 | ```javascript 18 | req.cookies.chocolatechip; 19 | // "Yummy" 20 | ``` 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /reference/req/req.socket.md: -------------------------------------------------------------------------------- 1 | # req.socket 2 | 3 | If the current Request (`req`) originated from a connected Socket.io client, `req.socket` refers to the raw Socket.io socket instance. 4 | 5 | ### Usage 6 | 7 | ```js 8 | req.socket; 9 | ``` 10 | 11 | 12 | ### Details 13 | 14 | > **Warning:** 15 | > 16 | > `req.socket` may be deprecated in a future release of Sails. You should use the [`sails.sockets.*`](./#!documentation/reference/Sockets) methods instead. 17 | 18 | If the current request (`req`) did NOT originate from a Socket.io client, `req.socket` does not have the same meaning. In the most common scenario, HTTP requests, `req.socket` actually _does exist_, but it refers instead to the underlying TCP socket. Before using `req.socket`, you should check the [`req.isSocket`](http://beta.sailsjs.org/#/documentation/reference/req/req.isSocket.html) flag to ensure the request arrived via a connected Socket.io client. 19 | 20 | `req.socket.id` is a unique identifier representing the current socket. This is generated by the Socket.io server when a client first connects, and is a valid unique identifier until the socket is disconnected (e.g. if the client is a web browser, until the user closes her browser tab.) 21 | 22 | Sails also provides direct, low-level access to all of the other methods and properties from a Socket.io `Socket`, including `req.socket`, including `req.socket.join`, `req.socket.leave`, `req.socket.broadcast`, and more. See the relevant docs in the [Socket.io wiki](https://github.com/LearnBoost/socket.io/wiki/Rooms) for more information. 23 | 24 | 25 | ### Example 26 | 27 | ```js 28 | if (req.isSocket) { 29 | // Low-level Socket.io methods and properties accessible on req.socket. 30 | // ... 31 | } 32 | else { 33 | // This is not a request from a Socket.io client, so req.socket 34 | // may or may not exist. If this is an HTTP request, req.socket is actually 35 | // the underlying TCP socket. 36 | // ... 37 | } 38 | ``` 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /reference/req/req.subdomains.md: -------------------------------------------------------------------------------- 1 | # req.subdomains 2 | An array of all the subdomains in this request's URL. 3 | 4 | ### Usage 5 | ```javascript 6 | req.subdomains; 7 | ``` 8 | 9 | ### Example 10 | 11 | If the requested URL was "https://ww3.staging.ibm.com": 12 | 13 | ```javascript 14 | req.subdomains; 15 | // -> ['ww3', 'staging'] 16 | ``` 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /reference/req/req.url.md: -------------------------------------------------------------------------------- 1 | # req.url 2 | 3 | Like [`req.path`](http://sailsjs.org/#/documentation/reference/req/req.path.html), but also includes the query string suffix. 4 | 5 | ```js 6 | req.url; 7 | 8 | // => "/search?q=worlds%20largest%20dogs" 9 | ``` 10 | 11 | 12 | ### Notes 13 | > + It is worth mentioning that the URL fragment/hash (e.g. "#some/clientside/route") part of the url is [not available on the server](https://github.com/strongloop/express/issues/1083#issuecomment-5179035). This is an [open issue with the current HTTP specification](http://stackoverflow.com/a/2305927/486547). So if you write an action to redirect from one subdomain to another, for instance, you won't be able to peek at the URL fragment in that action. 14 | > + However, if you respond with a 302 redirect (i.e. `res.redirect()`) the user agent on the other end will preserve the URL fragment/hash and tack it on to the end of the new redirected URL. In many cases, this is exactly what you want! 15 | 16 | 17 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/req/req.xhr.md: -------------------------------------------------------------------------------- 1 | # req.xhr 2 | A flag indicating whether the current request (`req`) appears to be an AJAX request (i.e. it was issued with its "X-Requested-With" header set to "XMLHttpRequest".) 3 | 4 | 5 | ### Usage 6 | ```js 7 | req.xhr; 8 | ``` 9 | 10 | ### Example 11 | ```javascript 12 | if (req.xhr) { 13 | // Yup, it's AJAX alright. 14 | } 15 | ``` 16 | 17 | 18 | ### Notes 19 | > + Whenever possible, you should prefer the `req.wantsJSON` flag. Avoid writing custom content-negotiation negotiation logic into your app - it makes your code more brittle and more verbose. 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/res/res.attachment.md: -------------------------------------------------------------------------------- 1 | # res.attachment() 2 | 3 | Sets the "Content-Disposition" header of the current response to "attachment". If a `filename` is given, then the "Content-Type" will be automatically set based on the extension of the file (e.g. `.jpg` or `.html`), and the "Content-Disposition" header will be set to "filename=`filename`". 4 | 5 | ### Usage 6 | ```javascript 7 | res.attachment([filename]); 8 | ``` 9 | 10 | ### Example 11 | ```javascript 12 | res.attachment(); 13 | // -> response header will contain: 14 | // Content-Disposition: attachment 15 | 16 | res.attachment('path/to/logo.png'); 17 | // -> response header will contain: 18 | // Content-Disposition: attachment; filename="logo.png" 19 | // Content-Type: image/png 20 | ``` 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/res/res.clearCookie.md: -------------------------------------------------------------------------------- 1 | # res.clearCookie() 2 | 3 | Clears cookie (`name`) in the response. 4 | 5 | ### Usage 6 | 7 | ```js 8 | res.clearCookie(name [,options]); 9 | ``` 10 | 11 | ### Details 12 | 13 | The path option defaults to "/". 14 | 15 | 16 | ### Example 17 | ```javascript 18 | res.cookie('name', 'tobi', { path: '/admin' }); 19 | res.clearCookie('name', { path: '/admin' }); 20 | ``` 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /reference/res/res.cookie.md: -------------------------------------------------------------------------------- 1 | # res.cookie() 2 | 3 | Sets a cookie with name (`name`) and value (`value`) to be sent along with the response. 4 | 5 | 6 | ### Usage 7 | ```js 8 | res.cookie(name, value [,options]); 9 | ``` 10 | 11 | 12 | ### Details 13 | 14 | The "path" option defaults to "/". 15 | 16 | The "maxAge" option is a convenience option for setting "expires" relative to the current time in milliseconds. The following is equivalent to the previous example. 17 | 18 | ```javascript 19 | res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true }) 20 | ``` 21 | 22 | An object may be passed which is then serialized as JSON, which is automatically parsed by the bodyParser() middleware. 23 | 24 | ```javascript 25 | res.cookie('cart', { items: [1,2,3] }); 26 | res.cookie('cart', { items: [1,2,3] }, { maxAge: 900000 }); 27 | ``` 28 | 29 | Signed cookies are also supported through this method. Simply pass the signed option. When given res.cookie() will use the secret passed to express.cookieParser(secret) to sign the value. 30 | 31 | ```javascript 32 | res.cookie('name', 'tobi', { signed: true }); 33 | ``` 34 | 35 | 36 | ### Example 37 | ```javascript 38 | res.cookie('name', 'tobi', { 39 | domain: '.example.com', 40 | path: '/admin', 41 | secure: true 42 | }); 43 | 44 | res.cookie('rememberme', '1', { 45 | expires: new Date(Date.now() + 900000), 46 | httpOnly: true 47 | }); 48 | ``` 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /reference/res/res.get.md: -------------------------------------------------------------------------------- 1 | # res.get() 2 | 3 | Returns the current value of the specified response header (`header`). 4 | 5 | ### Usage 6 | ```js 7 | res.get(header); 8 | ``` 9 | 10 | ### Example 11 | ```javascript 12 | res.get('Content-Type'); 13 | // -> "text/plain" 14 | ``` 15 | 16 | ### Notes 17 | >+ The `header` argument is case-insensitive. 18 | >+Response headers can be changed up until the response is sent - see [`res.set()`](/#/documentation/reference/res/res.set.html). 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /reference/res/res.json.md: -------------------------------------------------------------------------------- 1 | # res.json() 2 | 3 | Sends a JSON response composed of a stringified version of the specified `data`. 4 | 5 | ### Usage 6 | ```js 7 | return res.json([statusCode, ] data); 8 | ``` 9 | 10 | ### Details 11 | 12 | This method is identical to res.send() when an object or array is passed, however it may be used for explicit JSON conversion of non-objects (null, undefined, etc), though these are technically not valid JSON. 13 | 14 | ### Example 15 | ```javascript 16 | res.json(null) 17 | res.json({ user: 'tobi' }) 18 | res.json(500, { error: 'message' }) 19 | ``` 20 | 21 | ### Notes 22 | > + Don't forget this method's name is all lowercase. 23 | > + This method is **terminal**, meaning it is generally the last line of code your app should run for a given request (hence the advisory usage of `return` throughout these docs). 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /reference/res/res.jsonp.md: -------------------------------------------------------------------------------- 1 | # res.jsonp() 2 | 3 | Send a JSON or JSONP response. 4 | 5 | Identical to [`res.json()`](/#/documentation/reference/res/res.json.html), except if a "callback" parameter exists, a [JSONP](http://en.wikipedia.org/wiki/JSONP) response will be sent instead, using the value of the "callback" parameter as the name of the function wrapper. 6 | 7 | ### Usage 8 | ```js 9 | return res.jsonp([statusCode, ] data); 10 | ``` 11 | 12 | ### Example 13 | 14 | ```js 15 | return res.jsonp({ 16 | users: [{ 17 | name: 'Thelma', 18 | id: 1 19 | }, { 20 | name: 'Leonardo' 21 | id: 2 22 | }] 23 | }); 24 | ``` 25 | 26 | 44 | 45 | ### Notes 46 | > + Don't forget this method's name is all lowercase. 47 | > + This method is **terminal**, meaning it is generally the last line of code your app should run for a given request (hence the advisory usage of `return` throughout these docs). 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /reference/res/res.location.md: -------------------------------------------------------------------------------- 1 | # res.location() 2 | Sets the "Location" response header to the specified URL expression (`url`). 3 | 4 | ### Usage 5 | res.location(url); 6 | 7 | ### Example 8 | ```javascript 9 | res.location('/foo/bar'); 10 | res.location('foo/bar'); 11 | res.location('http://example.com'); 12 | res.location('../login'); 13 | res.location('back'); 14 | ``` 15 | 16 | ### Notes 17 | >+ You can use the same kind of URL expressions as in res.redirect(). 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /reference/res/res.send.md: -------------------------------------------------------------------------------- 1 | # res.send() 2 | 3 | Send a simple response. `statusCode` defaults to 200 ("OK"). 4 | 5 | This method is used in the underlying implementation of most of the other terminal response methods. 6 | 7 | ### Usage 8 | ```javascript 9 | return res.send([statusCode,] body); 10 | ``` 11 | 12 | 13 | ### Details 14 | This method performs a myriad of useful tasks for simple non-streaming responses such as automatically assigning the Content-Length unless previously defined and providing automatic HEAD and HTTP cache freshness support. 15 | 16 | When a Buffer is given the Content-Type is set to "application/octet-stream" unless previously defined as shown below: 17 | 18 | ```javascript 19 | res.set('Content-Type', 'text/html'); 20 | res.send(new Buffer('some html')); 21 | ``` 22 | When a String is given the Content-Type is set defaulted to "text/html": 23 | 24 | ```javascript 25 | res.send('some html'); 26 | ``` 27 | When an Array or Object is given Express will respond with the JSON representation: 28 | 29 | ```javascript 30 | res.send({ user: 'tobi' }) 31 | res.send([1,2,3]) 32 | ``` 33 | Finally when a Number is given without any of the previously mentioned bodies, then a response body string is assigned for you. For example 200 will respond will the text "OK", and 404 "Not Found" and so on. 34 | 35 | ```javascript 36 | res.send(200) 37 | res.send(404) 38 | res.send(500) 39 | ``` 40 | 41 | 42 | ### Example 43 | ```javascript 44 | res.send(new Buffer('whoop')); 45 | res.send({ some: 'json' }); 46 | res.send('some html'); 47 | res.send(404, 'Sorry, we cannot find that!'); 48 | res.send(500, { error: 'something blew up' }); 49 | res.send(200); 50 | ``` 51 | 52 | 53 | ### Notes 54 | > + This method is **terminal**, meaning it is generally the last line of code your app should run for a given request (hence the advisory usage of `return` throughout these docs). 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /reference/res/res.set.md: -------------------------------------------------------------------------------- 1 | # res.set() 2 | Sets specified response header (`header`) to the specified value (`value`). 3 | 4 | Alternatively, you can pass in a single object argument (`headers`) to set multiple header fields at once, where the keys are the header field names, and the corresponding values are the desired values. 5 | 6 | ### Usage 7 | ```js 8 | res.set(header, value); 9 | ``` 10 | 11 | -or- 12 | 13 | ```js 14 | res.set(headers); 15 | ``` 16 | 17 | ### Example 18 | ```javascript 19 | 20 | res.set('Content-Type', 'text/plain'); 21 | 22 | res.set({ 23 | 'Content-Type': 'text/plain', 24 | 'Content-Length': '123', 25 | 'ETag': '12345' 26 | }) 27 | 28 | ``` 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /reference/res/res.status.md: -------------------------------------------------------------------------------- 1 | # res.status() 2 | 3 | Set the status code of this response. 4 | 5 | ### Usage 6 | ```js 7 | res.status(200); 8 | ``` 9 | 10 | ### Example 11 | ```javascript 12 | res.status(404); 13 | res.send('oops'); 14 | ``` 15 | 16 | ### Notes 17 | >+ The status code may be set up until the response is sent. 18 | >+ `res.status()` is effectively just a chainable alias of node's '`res.statusCode=`. 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /reference/res/res.type.md: -------------------------------------------------------------------------------- 1 | # res.type() 2 | 3 | Sets the "Content-Type" response header to the specified `type`. 4 | 5 | This method is pretty forgiving (see examples below), but note that if `type` contains a `"/"`, `res.type()` assumes it is a MIME type and interprets it literally. 6 | 7 | ### Usage 8 | ```javascript 9 | res.type(type); 10 | ``` 11 | 12 | ### Example 13 | ```javascript 14 | res.type('.html'); 15 | res.type('html'); 16 | res.type('json'); 17 | res.type('application/json'); 18 | res.type('png'); 19 | ``` 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/sails.config/sails.config.bootstrap.md: -------------------------------------------------------------------------------- 1 | # sails.config.bootstrap 2 | 3 | ### What is this? 4 | This is an asynchronous boostrap function that runs before your Sails app gets lifted (i.e. starts up). This gives you an opportunity to set up your data model, run jobs, or perform some special logic. 5 | 6 | ### Description 7 | 8 | ```javascript 9 | module.exports.bootstrap = function (cb) { 10 | 11 | // It's very important to trigger this callback method when you are finished 12 | // with the bootstrap! (otherwise your server will never lift, since it's waiting on the bootstrap) 13 | cb(); 14 | }; 15 | ``` 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /reference/sails.config/sails.config.i18n.md: -------------------------------------------------------------------------------- 1 | # sails.config.i18n 2 | 3 | 4 | Configuration for Sails' built-in internationalization & localization features. For more information see the [concepts section on internationalization](http://beta.sailsjs.org/#/documentation/concepts/Internationalization). 5 | 6 | 7 | ### Properties 8 | 9 | | Property | Type | Default | Details | 10 | |--------------------|:-----------:|-----------------------|---------| 11 | | `locales` | ((array)) | ['en','es','fr','de'] | List of supported [locale codes](http://en.wikipedia.org/wiki/BCP_47) 12 | | `localesDirectory` | ((string)) | '/config/locales' | The project-relative path to the folder containing your locale translations (i.e. stringfiles) 13 | | `defaultLocale` | ((string)) | 'en' | The default locale for the site. Note that this setting will be overridden for any request that sends an "Accept-Language" header (i.e. most browsers), but it's still useful if you need to localize the response for requests made by non-browser clients (e.g. cURL). 14 | | `updateFiles` | ((boolean)) | false | Whether to automatically add new keys to locale (translation) files when they are encountered during a request. 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /reference/sails.config/sails.config.log.md: -------------------------------------------------------------------------------- 1 | # sails.config.log 2 | 3 | 4 | Configuration for the instance of the [Sails logger](http://beta.sailsjs.org/#/documentation/reference/Logs) (`sails.log`) used in your Sails app. The options are conventionally specified in the [config/log.js](/#/documentation/anatomy/myApp/config/log.js.html) configuration file. 5 | 6 | 7 | ### Properties 8 | 9 | 10 | | Property | Type | Default | Details | 11 | |-----------|:----------:|-----------|---------| 12 | | `level` | ((string)) | `'info'` | Set the level of detail to be shown in your app's log | 13 | 14 | 20 | 21 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /reference/sails.config/sails.config.md: -------------------------------------------------------------------------------- 1 | # Configuration (`sails.config`) 2 | 3 | The `sails.config` object contains the runtime values of your app's configuration. It is assembled automatically when Sails loads your app; merging together command-line arguments, environment variables, your `.sailsrc` file, and the configuration objects exported from any and all modules in your app's [`config/`](/#/documentation/anatomy/myApp/config) directory. 4 | 5 | More specifically, when you load your app, whether that's using `node app`, [programmatic usage inside of a script](https://github.com/balderdashy/sails-docs/blob/master/PAGE_NEEDED.md), or [`sails lift`](/#/documentation/reference/cli/sailslift.html), Sails will look in a [few different places](https://github.com/dominictarr/rc#standards) for configuration. Here they are listed in order of descending priority: 6 | 7 | + an optional object of configuration overrides passed-in programmatically 8 | + a local `.sailsrc` file in your app's directory, or the first found looking in `../`, `../../` etc. 9 | + a global `.sailsrc` file in your home folder (e.g. `~/.sailsrc`) 10 | + command-line arguments (parsed by minimist) 11 | + environment variables (prefixed with `SAILS_`, e.g. `SAILS_PORT=1492`) 12 | + files in your app's `config/` directory (if one exists) 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /reference/sails.config/sails.config.models.md: -------------------------------------------------------------------------------- 1 | # sails.config.models 2 | 3 | Your default project-wide **model settings**. Can also be overridden on a per-model basis by providing a top-level property with the same name in that model definition. For more details, see the conceptual docs on [Model Settings](/#/documentation/concepts/ORM/model-settings.html). These options are conventionally specified in the [config/models.js](/#/documentation/anatomy/myApp/config/models.js.html) configuration file. 4 | 5 | ```js 6 | sails.config.models; 7 | ``` 8 | 9 | ### Properties 10 | 11 | 12 | Property | Type | Default | Details 13 | ----------------------|:------------:|-------------------------------- | -------- 14 | `attributes` | ((object)) | `{}` | The basic pieces of information to store about a model. See [Attributes](). 15 | `migrate` | ((string)) | _see [Model Settings](/#/documentation/concepts/ORM/model-settings.html)_ | How & whether Sails will attempt to automatically rebuild the tables/collections/etc. in your schema 16 | `connection` | ((string)) | `"localDiskDb"` | The default database [connection](http://beta.sailsjs.org/#/documentation/reference/sails.config/sails.config.connections.html) any given model will use without a configured override 17 | `autoPK` | ((boolean)) | `true` | Toggle the automatic definition of a primary key in your model 18 | `autoCreatedAt` | ((boolean)) | `true` | Toggle the automatic definition of a property createdAt in your model 19 | `autoUpdatedAt` | ((boolean)) | `true` | Toggle the automatic definition of a property updatedAt in your model 20 | `tableName` | ((string)) | _identity_ | Used to specify database table name for the model 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /reference/sails.config/sails.config.routes.md: -------------------------------------------------------------------------------- 1 | # sails.config.routes 2 | 3 | Configuration for custom (aka "explicit") routes. `sails.config.routes` consists of a single Javascript object whose keys are URL paths (the "address") and whose values are one of several types of route handler configurations (the "target"), for example: 4 | 5 | ``` 6 | module.exports.routes = { 7 | 8 | "GET /": {view: "homepage"}, 9 | "POST /foo/bar": {controller: "FooController", action: "bar"} 10 | 11 | } 12 | ``` 13 | 14 | Please see the [routes concept overview](/#/documentation/concepts/Routes) for a full discussion of Sails routes, and the [custom routes documentation](/#/documentation/concepts/Routes/RouteTargetSyntax.html) for a detailed description of the available configurations for both the route address and target. 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /reference/sails.config/sails.config.views.md: -------------------------------------------------------------------------------- 1 | # sails.config.views 2 | 3 | Configuration for your app's server-side [views](./#!documentation/reference/Views). The options are conventionally specified in the [`config/views.js`](/#/documentation/anatomy/myApp/config/views.js.html) configuration file. 4 | 5 | 6 | ### Properties 7 | 8 | | Property | Type | Default | Details | 9 | |-----------|:----------:|-----------|---------| 10 | | `layout` | ((string)) -or- ((boolean)) | `"layout"` | Set the default [layout](./#!documentation/reference/Views/Layouts.html) for your app by specifying the relative path to the desired layout file from your views folder (i.e. `views/`.) Or disable layout support altogether with `false`. 11 | | `engine` | ((string)) | `"ejs"` | The [view engine](./#!documentation/reference/Views/ViewEngines.html) your app will use to compile server-side markup into HTML. 12 | | `locals` | ((object)) | `{}` | Default data to be included as [view locals](./#!documentation/reference/Views/Locals.html) every time a server-side view is compiled anywhere in this app. | 13 | 14 | ### Notes 15 | 16 | > + If your app is NOT using `ejs` (the default view engine) Sails will function as if the `layout` option was set to `false`. To take advantage of layouts when using a custom view engine like Jade or Handlebars, check out [that view engine's documentation](./#!documentation/reference/Views/ViewEngines.html) to find the appropriate syntax. 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /reference/waterline/models/count.md: -------------------------------------------------------------------------------- 1 | # .count( [`criteria`, ] `callback` ) 2 | ### Purpose 3 | Returns the number of records in your database that meet the given search criteria. 4 | 5 | ### Overview 6 | #### Parameters 7 | 8 | | # | Description | Accepted Data Types | Required ? | 9 | |---|---------------|------------------------------|------------| 10 | | 1 | Find Criteria | `{}`,`[{}]`, `string`, `int` | No | 11 | | 2 | Callback | `function` | No | 12 | 13 | #### Callback Parameters 14 | 15 | | # | Description | Possible Data Types | 16 | |---|-------------------|---------------------| 17 | | 1 | Error | `Error` | 18 | | 2 | Number of Records | `int` | 19 | 20 | ### Example Usage 21 | 22 | ```javascript 23 | User.count({name:'Flynn'}).exec(function countCB(error, found) { 24 | console.log('There are ' + found + ' users called "Flynn"'); 25 | 26 | // There are 1 users called 'Flynn' 27 | // Don't forget to handle your errors 28 | }); 29 | 30 | 31 | ``` 32 | ### Notes 33 | > Any string arguments passed must be the ID of the record. 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /reference/waterline/models/create.md: -------------------------------------------------------------------------------- 1 | # .create( `values`, [`callback`] ) 2 | ### Purpose 3 | Creates a new instance of this model in the database. 4 | 5 | ### Overview 6 | 7 | #### Parameters 8 | | | Description | Accepted Data Types | Required ? | 9 | |---|---------------------|---------------------|------------| 10 | | 1 | Record(s) to Create | `{}`, `[{}]` | Yes | 11 | | 2 | Callback | `function` | No | 12 | 13 | #### Callback Parameters 14 | 15 | | | Description | Possible Data Types | 16 | |---|---------------------|---------------------| 17 | | 1 | Error | `Error` | 18 | | 2 | Records Created | `{}`, `[{}]` | 19 | 20 | 21 | 22 | ### Example Usage 23 | 24 | ```javascript 25 | // create a new record with name 'Walter Jr' 26 | 27 | User.create({name:'Walter Jr'}).exec(function createCB(err,created){ 28 | console.log('Created user with name '+created.name); 29 | }); 30 | 31 | // Created user with name Walter Jr 32 | // Don't forget to handle your errors and abide by the rules you defined in your model 33 | ``` 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /reference/waterline/models/destroy.md: -------------------------------------------------------------------------------- 1 | # .destroy( `criteria` , [`callback`] ) 2 | ### Purpose 3 | Destroys all records in your database that match the given criteria. 4 | 5 | ### Overview 6 | #### Parameters 7 | 8 | | | Description | Accepted Data Types | Required ? | 9 | |---|---------------------|---------------------|------------| 10 | | 1 | Find Criteria | `{}`,`[{}]`, `string`, `int` | Yes | 11 | | 2 | Callback | `function` | No | 12 | 13 | #### Callback Parameters 14 | 15 | | | Description | Possible Data Types | 16 | |---|---------------------|---------------------| 17 | | 1 | Error | `Error` | 18 | | 2 | Deleted Records | `[{}]` | 19 | 20 | ### Example Usage 21 | 22 | ```javascript 23 | User.destroy({name:'Flynn'}).exec(function deleteCB(err){ 24 | console.log('The record has been deleted'); 25 | }); 26 | 27 | // If the record existed, then it has been deleted 28 | // Don't forget to handle your errors 29 | 30 | ``` 31 | ### Notes 32 | > If you want to confirm the record exists before you delete it, you must first perform a find() 33 | > Any string arguments passed must be the ID of the record. 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /reference/waterline/models/find.md: -------------------------------------------------------------------------------- 1 | # .find(`criteria` , [`callback`]) 2 | ### Purpose 3 | Finds and returns all records that meet the criteria object(s) that you pass it. 4 | 5 | ### Overview 6 | #### Parameters 7 | 8 | | | Description | Accepted Data Types | Required ? | 9 | |---|---------------------|---------------------|------------| 10 | | 1 | Find Criteria | `{}`,`[{}]`, `string`, `int`| Yes | 11 | | 2 | Callback | `function` | Yes | 12 | 13 | #### Callback Parameters 14 | 15 | | | Description | Possible Data Types | 16 | |---|---------------------|---------------------| 17 | | 1 | Error | `Error` | 18 | | 2 | Found Records | `[{}]` | 19 | 20 | ### Example Usage 21 | 22 | ```javascript 23 | User.find({}).exec(function findCB(err,found){ 24 | while (found.length) 25 | console.log('Found User with name '+found.pop().name) 26 | }); 27 | 28 | // Found User with name Flynn 29 | // Found User with name Jessie 30 | 31 | // Don't forget to handle your errors 32 | 33 | ``` 34 | ### Notes 35 | > Any string arguments passed must be the ID of the record. 36 | > This method will ALWAYS return records in an array. 37 | > If you are trying to find an attribute that is an array, you must wrap it in an additional set of brackets otherwise Waterline will think you want to perform an inQuery. 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /reference/waterline/models/findOne.md: -------------------------------------------------------------------------------- 1 | # .findOne( `criteria` , [`callback`] ) 2 | ### Purpose 3 | This finds and returns a single record that meets the criteria. 4 | 5 | ### Overview 6 | #### Parameters 7 | 8 | | | Description | Accepted Data Types | Required ? | 9 | |---|---------------------|---------------------|------------| 10 | | 1 | Find Criteria | `{}`, `string` | Yes | 11 | | 2 | Callback | `function` | Yes | 12 | 13 | #### Callback Parameters 14 | 15 | | | Description | Possible Data Types | 16 | |---|---------------------|---------------------| 17 | | 1 | Error | `Error` | 18 | | 2 | Found Record | `{}` | 19 | 20 | 21 | ### Example Usage 22 | 23 | ```javascript 24 | User.findOne({name:'Jessie'}).exec(function findOneCB(err,found){ 25 | console.log('We found '+found.name); 26 | }); 27 | 28 | // We found Jessie 29 | // Don't forget to handle your errors 30 | 31 | ``` 32 | ### Notes 33 | > Any string arguments passed must be the ID of the record. 34 | > If you are trying to find an attribute that is an array, you must wrap it in an additional set of brackets otherwise Waterline will think you want to perform an inQuery. 35 | 36 | > If no matching record is found, the value of `found` will be `undefined`. Not finding a record does *not* constitute an error for `findOne`. 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /reference/waterline/models/findOrCreate.md: -------------------------------------------------------------------------------- 1 | # .findOrCreate( `criteria` , `record` , [`callback`] ) 2 | ### Purpose 3 | Checks for the existence of the record in the first parameter. If it can't be found, the record in the second parameter is created. 4 | 5 | ### Overview 6 | #### Parameters 7 | 8 | | | Description | Accepted Data Types | Required ? | 9 | |---|---------------------|---------------------|------------| 10 | | 1 | Find Criteria | `{}`,`[{}]`, `string`, `int` | Yes | 11 | | 2 | Records to Create | `{}`,`[{}]` | Yes | 12 | | 2 | Callback | `function` | No | 13 | 14 | #### Callback Parameters 15 | 16 | | | Description | Possible Data Types | 17 | |---|---------------------|---------------------| 18 | | 1 | Error | `Error` | 19 | | 2 | Records Created | `{}`, `[{}]` | 20 | 21 | ### Example Usage 22 | 23 | ```javascript 24 | User.findOrCreate({name:'Walter'},{name:'Jessie'}).exec(function createFindCB(err,record){ 25 | console.log('What\'s cookin\' '+record.name+'?'); 26 | }); 27 | 28 | // What's cookin' Jessie? 29 | // Don't forget to handle your errors and abide by the rules you defined in your model 30 | 31 | ``` 32 | ### Notes 33 | > Any string arguments passed must be the ID of the record. 34 | > If you are trying to find an attribute that is an array, you must wrap it in an additional set of brackets otherwise Waterline will think you want to perform an inQuery. 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /reference/waterline/models/native.md: -------------------------------------------------------------------------------- 1 | # .native() 2 | 3 | `.native()` is only available when using Sails/Waterline with MongoDB. 4 | 5 | Returns a raw Mongo collection instance representing the specified model, allowing you to perform raw Mongo queries. 6 | 7 | For full documentation and usage examples, check out the [native Node Mongo driver](https://github.com/mongodb/node-mongodb-native#introduction). 8 | 9 | 10 | Note that `sails-mongo` maintains a single Mongo connection for each of your configured connections/datastores. Consequently, when using `.native()`, you don't need to close or open `db` manually. For lower-level usage, you can `require('mongodb')` directly. 11 | 12 | ### Example 13 | 14 | ```js 15 | Pet.native(function(err, collection) { 16 | if (err) return res.serverError(err); 17 | 18 | collection.find({}, { 19 | name: true 20 | }).toArray(function (err, results) { 21 | if (err) return res.serverError(err); 22 | return res.ok(results); 23 | }); 24 | }); 25 | ``` 26 | 27 | Source: https://gist.github.com/mikermcneil/483987369d54512b6104 28 | 29 | ### Notes 30 | 31 | > + This method only works with Mongo! For raw functionality in SQL databases, use [`.query()`](/#/documentation/reference/waterline/models/query.html). 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /reference/waterline/models/query.md: -------------------------------------------------------------------------------- 1 | # .query() 2 | 3 | `.query()` is only available on Sails/Waterline models using a SQL database (PostgreSQL and mySQL) adapter. Its purpose is to perform raw SQL queries. 4 | 5 | 6 | ### Example 7 | 8 | ```js 9 | Pet.query('SELECT pet.name FROM pet', function(err, results) { 10 | if (err) return res.serverError(err); 11 | return res.ok(results); 12 | }); 13 | ``` 14 | 15 | 16 | 17 | ### Notes 18 | > This method only works with PostgreSQL and mySQL! use .native() for Mongo. 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /reference/waterline/models/update.md: -------------------------------------------------------------------------------- 1 | # .update() 2 | ### Purpose 3 | Updates existing records in the database that match the specified criteria. 4 | 5 | ### Overview 6 | #### Parameters 7 | 8 | | | Description | Accepted Data Types | Required ? | 9 | |---|---------------------|---------------------|------------| 10 | | 1 | Find Criteria | `{}`,`[{}]`, `string`, `int` | Yes | 11 | | 2 | Updated Records | `{}`,`[{}]` | Yes | 12 | | 3 | Callback | `function` | No | 13 | 14 | #### Callback Parameters 15 | 16 | | | Description | Possible Data Types | 17 | |---|---------------------|---------------------| 18 | | 1 | Error | `Error` | 19 | | 2 | Sucessfully Updated Records | `[{}]` | 20 | 21 | ### Example Usage 22 | 23 | ```javascript 24 | User.update({name:'Walter Jr'},{name:'Flynn'}).exec(function afterwards(err,updated){ 25 | 26 | if (err) { 27 | // handle error here- e.g. `res.serverError(err);` 28 | return; 29 | } 30 | 31 | console.log('Updated user to have name '+updated[0].name); 32 | }); 33 | 34 | ``` 35 | ### Notes 36 | > + An array of primary key values passed to `.update()` for a `collection` association will set the association to contain **only** the records with those primary key values provided. That is- it **unlinks all other** records from the association. 37 | > + Although you may pass .update() an object or an array of objects, it will always return an array of objects. 38 | > + If you specify a primary key (e.g. `7` or `"50c9b254b07e040200000028"`) instead of a criteria object, any `.where()` filters will be ignored. 39 | > + Currently, calling `.populate()` on an `.update()` query has no effect. To populate attributes on the results, you should follow up your update with a `find().populate()` query. 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /reference/waterline/populated-values/remove.md: -------------------------------------------------------------------------------- 1 | # *.remove( `primary key` ) 2 | ### Purpose 3 | Used to remove records from the join table that is automatically generated during a many-to-many association. Unlike .add(), it only accepts the primary key of the model instance (defaults to record ID). 4 | 5 | 6 | 7 | ### Overview 8 | #### Parameters 9 | 10 | | | Description | Accepted Data Types | Required ? | 11 | |---|---------------------|---------------------|------------| 12 | | 1 | Primary Key | `string`, `int` | Yes | 13 | 14 | ### Example Usage 15 | 16 | ```javascript 17 | 18 | User.find({name:'Mike'}).populate('pets').exec(function(e,r){ 19 | r[0].pets.remove(7); 20 | r[0].save(console.log) 21 | }); 22 | 23 | /* 24 | 25 | { pets: 26 | [ { name: 'Rainbow Dash', 27 | color: 'blue', 28 | id: 8, 29 | createdAt: Wed Feb 12 2014 18:06:50 GMT-0600 (CST), 30 | updatedAt: Wed Feb 12 2014 18:06:50 GMT-0600 (CST) }, 31 | { name: 'Applejack', 32 | color: 'orange', 33 | id: 9, 34 | createdAt: Wed Feb 12 2014 18:06:50 GMT-0600 (CST), 35 | updatedAt: Wed Feb 12 2014 18:06:50 GMT-0600 (CST) } ], 36 | name: 'Mike', 37 | age: 16, 38 | createdAt: Wed Feb 12 2014 18:06:50 GMT-0600 (CST), 39 | updatedAt: Wed Feb 12 2014 19:30:54 GMT-0600 (CST), 40 | id: 7 } 41 | 42 | */ 43 | 44 | 45 | ``` 46 | 47 | ### Notes 48 | > + Any string arguments passed must be the primary key of the record. 49 | > + `.remove()` alone won't actually persist the change in associations to the databse. You should call `.save()` after using `.add()` or `.remove()`. 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /reference/waterline/queries/exec.md: -------------------------------------------------------------------------------- 1 | # .exec(`callback`) 2 | ### Purpose 3 | This is run at the end of a chain of stringable methods. It signals the adapter to run the query. 4 | #### Parameters 5 | | | Description | Accepted Data Types | Required ? | 6 | |-----|---------------------|---------------------|------------| 7 | | 1 | Callback | `function` | Yes | 8 | #### Callback Parameters 9 | | | Description | Possible Data Types | 10 | |---|---------------------|---------------------| 11 | | 1 | Error | `Error` | 12 | | 2 | Data Returned | `{}`, `[{}]`, `int` | 13 | ### Example Usage 14 | ```javascript 15 | // refer to any of the examples above 16 | ``` 17 | ### Notes 18 | > The .find() method returns a chainable object if you don't supply a callback. This method can be chained to .find() to further filter your results. 19 | 20 | > If you don't run .exec(), your query will not execute. 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /reference/waterline/queries/limit.md: -------------------------------------------------------------------------------- 1 | # .limit(`integer`) 2 | ### Purpose 3 | 4 | ### Parameters 5 | | | Description | Accepted Data Types | Required ? | 6 | |---|---------------------|---------------------|------------| 7 | | 1 | Number to Return | `int` | Yes | 8 | 9 | ### Example Usage 10 | 11 | ```javascript 12 | var myQuery = User.find(); 13 | myQuery.limit(12); 14 | 15 | myQuery.exec(function callBack(err,results){ 16 | console.log(results) 17 | }); 18 | 19 | ``` 20 | ### Notes 21 | > The .find() method returns a chainable object if you don't supply a callback. This method can be chained to .find() to further filter your results. 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/waterline/queries/skip.md: -------------------------------------------------------------------------------- 1 | # .skip(`integer`) 2 | ### Purpose 3 | 4 | ### Parameters 5 | | | Description | Accepted Data Types | Required ? | 6 | |---|---------------------|---------------------|------------| 7 | | 1 | Number to Skip | `int` | Yes | 8 | 9 | ### Example Usage 10 | 11 | ```javascript 12 | var myQuery = User.find(); 13 | myQuery.skip(12); 14 | 15 | myQuery.exec(function callBack(err,results){ 16 | console.log(results) 17 | }); 18 | 19 | ``` 20 | ### Notes 21 | > The .find() method returns a chainable object if you don't supply a callback. This method can be chained to .find() to further filter your results. 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/waterline/queries/sort.md: -------------------------------------------------------------------------------- 1 | # .sort(`string`) 2 | ### Purpose 3 | 4 | ### Parameters 5 | | | Description | Accepted Data Types | Required ? | 6 | |---|---------------------|---------------------|------------| 7 | | 1 | Sort String | `string` | Yes | 8 | 9 | ### Example Usage 10 | 11 | ```javascript 12 | var myQuery = User.find(); 13 | 14 | var sortString= 'name ASC'; 15 | 16 | // Sort strings look like this 17 | 18 | // ' ' 19 | 20 | myQuery.sort('name ASC'); 21 | 22 | myQuery.exec(function callBack(err,results){ 23 | console.log(results) 24 | }); 25 | 26 | ``` 27 | ### Notes 28 | > The .find() method returns a chainable object if you don't supply a callback. This method can be chained to .find() to further filter your results. 29 | 30 | > Other Sort Types include 31 | - ASC 32 | - DESC 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /reference/waterline/queries/where.md: -------------------------------------------------------------------------------- 1 | # .where(`criteria`) 2 | ### Purpose 3 | 4 | 5 | ### Parameters 6 | | | Description | Accepted Data Types | Required ? | 7 | |---|---------------------|---------------------|------------| 8 | | 1 | Criteria Object | `{}` | Yes | 9 | 10 | 11 | ### Example Usage 12 | 13 | ```javascript 14 | var myQuery = User.find(); 15 | myQuery.where({'name':{startsWith:'W'}}); 16 | 17 | myQuery.exec(function callBack(err,results){ 18 | console.log(results) 19 | }); 20 | 21 | ``` 22 | ### Notes 23 | > The .find() method returns a chainable object if you don't supply a callback. This method can be chained to .find() to further filter your results. 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /reference/waterline/records/records.md: -------------------------------------------------------------------------------- 1 | # Records 2 | 3 | A record is a uniquely identifiable object that corresponds 1-to-1 with a database entry; e.g. a row in Oracle/MSSQL/PostgreSQL/MySQL, a document in MongoDB, or a hash in Redis. 4 | 5 | ```js 6 | Order.findOne().exec(function (err, order){ 7 | var record = order; 8 | }); 9 | ``` 10 | 11 | For the most part, records are just plain old JavaScript objects (aka POJOs). However they do have a few protected (non-enumerable) methods for formatting their wrapped data, as well as a special method ([`.save()`](/#/documentation/reference/waterline/records/save.html)) for persisting [programmatic changes](http://en.wikipedia.org/wiki/Active_record_pattern) to the database. 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /reference/waterline/records/save.md: -------------------------------------------------------------------------------- 1 | # * .save(`callback`) 2 | 3 | ### Purpose 4 | The `save()` method updates your record in the database using the current attributes. It then returns the newly saved object in the callback. 5 | 6 | ### Overview 7 | #### Parameters 8 | 9 | | | Description | Accepted Data Types | Required ? | 10 | |---|---------------------|---------------------|------------| 11 | | 1 | Callback | `function` | Yes | 12 | 13 | #### Callback Parameters 14 | 15 | | | Description | Possible Data Types | 16 | |---|---------------------|---------------------| 17 | | 1 | Error | `Error` | 18 | | 2 | Saved Record | `{ }` | 19 | 20 | 21 | ### Example Usage 22 | 23 | ```javascript 24 | User.find().exec( 25 | function(err,myRecords){ 26 | 27 | // Grab a record off the top of the returned array and save a new attribute to it 28 | var getOneRecord = myRecords.pop(); 29 | getOneRecord.name = 'Hank'; 30 | getOneRecord.save( 31 | function(err,s){ 32 | console.log('User with ID '+s.id+' now has name '+s.name); 33 | }); 34 | }); 35 | 36 | // User with ID 1 now has name Hank 37 | 38 | // Don't forget to handle your errors. 39 | // Don't forget to abide by the rules you set in your model 40 | 41 | ``` 42 | ### Notes 43 | > This is an instance method. Currently, instance methods ARE NOT TRANSACTIONAL. Because of this, it is recommended that you use the equivalent model method instead. 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /reference/waterline/records/toObject.md: -------------------------------------------------------------------------------- 1 | # .toObject() 2 | 3 | ### Purpose 4 | The toObject method returns a cloned model instance (record) but stripped of all instance methods. 5 | 6 | ### Overview 7 | 8 | #### Return Value 9 | 10 | | | Description | Possible Data Types | 11 | |---|---------------------|---------------------| 12 | | | Cloned Record | `{ }` | 13 | 14 | ### Example Usage 15 | _See usage in .toJSON()_ 16 | 17 | 18 | ### Notes 19 | > You will only want to use .toObject when overriding the default .toJSON instance method. 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reference/waterline/waterline.md: -------------------------------------------------------------------------------- 1 | # Waterline (ORM) 2 | 3 | By default, Sails comes bundled with an ORM called Waterline (implemented in the [orm hook](https://github.com/balderdashy/sails/tree/master/lib/hooks/orm).) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /reference/websockets/resourceful-pubsub/message.md: -------------------------------------------------------------------------------- 1 | # .message( `models`,`data`, [`request`] ) 2 | ### Purpose 3 | Publishes a custom message to a model’s subscribers. 4 | 5 | | | Description | Accepted Data Types | Required ? | 6 | |---|---------------------|---------------------|------------| 7 | | 1 | Record (or ID of record) to send message to | `int`, `string`, `object` | Yes | 8 | | 2 | Message payload | `object` | Yes | 9 | | 3 | Request | `request object` | No | 10 | 11 | `message()` emits a socket message using the model identity as the event name. The message is broadcast to all sockets subscribed to the model instance via the `.subscribe` model method. 12 | 13 | The socket message is an object with the following properties: 14 | 15 | + **id** - the `id` attribute of the model instance 16 | + **verb** - `"messaged"` (a string) 17 | + **data** - the message payload 18 | 19 | #### `data` 20 | Arbitrary data to send to the subscribed sockets. 21 | 22 | #### `request` 23 | If this argument is included then the socket attached to that request will *not* receive the notification. 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /reference/websockets/resourceful-pubsub/publishAdd.md: -------------------------------------------------------------------------------- 1 | # .publishAdd( `{id}`,`attribute`, `idAdded`, [`request`], [`options`] ) 2 | ### Purpose 3 | Publishes a notification when an associated record is added to a model's collection. For example, if a `User` model has an association with the `Pet` model so that a user can have one or more pets available in its `pets` attribute, then any time a new pet is associated with a user `publishAdd` may be called. 4 | 5 | | | Description | Accepted Data Types | Required ? | 6 | |---|---------------------|---------------------|------------| 7 | | 1 | ID of Updated Record| `int`, `string` | Yes | 8 | | 2 | Attribute of associated collection | `string` | Yes | 9 | | 3 | ID of associated record that was added | `int`, `string` | Yes | 10 | | 4 | Request | `request object` | No | 11 | | 5 | Additional Options | `object` | No | 12 | 13 | `publishAdd()` emits a socket message using the model identity as the event name. The message is broadcast to all sockets subscribed to the model instance via the `.subscribe` model method. 14 | 15 | The socket message is an object with the following properties: 16 | 17 | + **id** - the `id` attribute of the model instance 18 | + **verb** - `"addedTo"` (a string) 19 | + **attribute** - the name of the model attribute that was added to 20 | + **addedId** - the ID of the record that was added 21 | 22 | #### `request` 23 | If this argument is included then the socket attached to that request will *not* receive the notification. 24 | 25 | #### `options.noReverse` 26 | See the documentation for `publishUpdate` for information about `options.noReverse`. In general, you should not have to set this argument unless you are writing your own implementation of `publishAdd` for a model. 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /reference/websockets/resourceful-pubsub/unsubscribe.md: -------------------------------------------------------------------------------- 1 | # .unsubscribe(`request`,`records`,[`contexts`]) 2 | ### Purpose 3 | This method will unsubscribe a socket from one or more model instances. 4 | 5 | | | Description | Accepted Data Types | Required ? | 6 | |---|---------------------|---------------------|------------| 7 | | 1 | Request | `Request object` | Yes | 8 | | 2 | Records | `[]`, `object` | Yes | 9 | | 3 | Contexts to unsubscribe from | `string`, `array` | No | 10 | 11 | *Note*: `unsubscribe` will only work when the request is made over a socket connection (e.g. using `socket.get`), *not* over an http connection (e.g. using `jquery.get`). 12 | 13 | #### `context` 14 | 15 | See `.subscribe()` for a discussion of pubsub contexts. Omit this argument to unsubscribe a socket from all contexts. 16 | 17 | ### Example Usage 18 | Controller Code 19 | ```javascript 20 | User.findOne({id: 123}).exec(function(err, userInstance) { 21 | User.unsubscribe(req.socket, userInstance); 22 | }); 23 | ``` 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /reference/websockets/resourceful-pubsub/unwatch.md: -------------------------------------------------------------------------------- 1 | # .unwatch(`request`) 2 | 3 | ### Purpose 4 | This unsubscribes a client from publishCreate events for the model. 5 | 6 | | | Description | Accepted Data Types | Required ? | 7 | |---|---------------------|---------------------|------------| 8 | | 1 | Request | `request object` | Yes | 9 | 10 | *Note*: `unwatch` will only work when the request is made over a socket connection (e.g. using `socket.get`), *not* over an http connection (e.g. using `jquery.get`). 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /reference/websockets/resourceful-pubsub/watch.md: -------------------------------------------------------------------------------- 1 | # .watch(`request`) 2 | 3 | ### Purpose 4 | This subscribes a client to publishCreate events for the model. Any connections that are "watching" the model class will be automatically subscribed to new model instances that are created using the blueprint `create` method. 5 | 6 | | | Description | Accepted Data Types | Required ? | 7 | |---|---------------------|---------------------|------------| 8 | | 1 | Request | `request object` | Yes | 9 | 10 | *Note*: `watch` will only work when the request is made over a socket connection (e.g. using `socket.get`), *not* over an http connection (e.g. using `jquery.get`). 11 | 12 | ### Blueprints and .watch() 13 | > By default, the blueprint `find` and `findOne` actions will call `.watch()` on the model class. This behavior can be changed for all models by setting the `sails.config.blueprints.autoWatch` to `false`, or for a specific model by setting `autoWatch` to `false` in the model's class file. 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /reference/websockets/sails.io.js/socket.delete.md: -------------------------------------------------------------------------------- 1 | # socket.delete() 2 | 3 | Sends a virtual DELETE request to a Sails server using Socket.io. 4 | 5 | 6 | ### Usage 7 | 8 | ```js 9 | io.socket.delete(url, data, function (data, jwres){ 10 | // ... 11 | }); 12 | ``` 13 | 14 | | | Argument | Type | Details | 15 | |---|------------|:------------:|---------| 16 | | 1 | `url` | ((string)) | The destination URL path, e.g. "/checkout". 17 | | 2 | `data` | ((*)) | Optional request data- if provided, will be URL encoded and appended to `url` (existing query string params in url will be preserved) 18 | | 3 | `callback` | ((function)) | Optional callback- if provided, will be called when the server responds. 19 | 20 | ##### Callback 21 | 22 | | | Argument | Type | Details | 23 | |---|-----------|:------------:|---------| 24 | | 1 | `resData` | ((*)) | Data received in the response from the Sails server (=== `jwres.body`, equivalent to the HTTP response body.) 25 | | 2 | `jwres` | ((JWR)) | The [JSON WebSocket Response](https://github.com/balderdashy/sails-docs/blob/master/PAGE_NEEDED.md) object. Has `headers`, a `body`, and a `statusCode`. 26 | 27 | 28 | ### Example 29 | 30 | ```html 31 | 36 | ``` 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /reference/websockets/sails.io.js/socket.get.md: -------------------------------------------------------------------------------- 1 | # socket.get() 2 | 3 | Sends a virtual GET request to a Sails server using Socket.io. 4 | 5 | 6 | ### Usage 7 | 8 | ```js 9 | io.socket.get(url, data, function (data, jwres){ 10 | // ... 11 | }); 12 | ``` 13 | 14 | | | Argument | Type | Details | 15 | |---|------------|:------------:|---------| 16 | | 1 | `url` | ((string)) | The destination URL path, e.g. "/checkout". 17 | | 2 | `data` | ((*)) | Optional request data- if provided, will be URL encoded and appended to `url` (existing query string params in url will be preserved) 18 | | 3 | `callback` | ((function)) | Optional callback- if provided, will be called when the server responds. 19 | 20 | ##### Callback 21 | 22 | | | Argument | Type | Details | 23 | |---|-----------|:------------:|---------| 24 | | 1 | `resData` | ((*)) | Data received in the response from the Sails server (=== `jwres.body`, equivalent to the HTTP response body.) 25 | | 2 | `jwres` | ((JWR)) | The [JSON WebSocket Response](https://github.com/balderdashy/sails-docs/blob/master/PAGE_NEEDED.md) object. Has `headers`, a `body`, and a `statusCode`. 26 | 27 | 28 | ### Example 29 | 30 | ```html 31 | 36 | ``` 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /reference/websockets/sails.io.js/socket.post.md: -------------------------------------------------------------------------------- 1 | # socket.post() 2 | 3 | Sends a virtual POST request to a Sails server using Socket.io. 4 | 5 | 6 | ### Usage 7 | 8 | ```js 9 | io.socket.post(url, data, function (data, jwres){ 10 | // ... 11 | }); 12 | ``` 13 | 14 | | | Argument | Type | Details | 15 | |---|------------|:------------:|---------| 16 | | 1 | `url` | ((string)) | The destination URL path, e.g. "/checkout". 17 | | 2 | `data` | ((*)) | Optional request data- if provided, will be JSON-encoded and included as the virtual HTTP body 18 | | 3 | `callback` | ((function)) | Optional callback- if provided, will be called when the server responds. 19 | 20 | ##### Callback 21 | 22 | | | Argument | Type | Details | 23 | |---|-----------|:------------:|---------| 24 | | 1 | `resData` | ((*)) | Data received in the response from the Sails server (=== `jwres.body`, equivalent to the HTTP response body.) 25 | | 2 | `jwres` | ((JWR)) | The [JSON WebSocket Response](https://github.com/balderdashy/sails-docs/blob/master/PAGE_NEEDED.md) object. Has `headers`, a `body`, and a `statusCode`. 26 | 27 | 28 | ### Example 29 | 30 | ```html 31 | 36 | ``` 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /reference/websockets/sails.io.js/socket.put.md: -------------------------------------------------------------------------------- 1 | # socket.put() 2 | 3 | Sends a virtual PUT request to a Sails server using Socket.io. 4 | 5 | 6 | ### Usage 7 | 8 | ```js 9 | io.socket.put(url, data, function (data, jwres){ 10 | // ... 11 | }); 12 | ``` 13 | 14 | | | Argument | Type | Details | 15 | |---|------------|:------------:|---------| 16 | | 1 | `url` | ((string)) | The destination URL path, e.g. "/checkout". 17 | | 2 | `data` | ((*)) | Optional request data- if provided, will be JSON-encoded and included as the virtual HTTP body 18 | | 3 | `callback` | ((function)) | Optional callback- if provided, will be called when the server responds. 19 | 20 | ##### Callback 21 | 22 | | | Argument | Type | Details | 23 | |---|-----------|:------------:|---------| 24 | | 1 | `resData` | ((*)) | Data received in the response from the Sails server (=== `jwres.body`, equivalent to the HTTP response body.) 25 | | 2 | `jwres` | ((JWR)) | The [JSON WebSocket Response](https://github.com/balderdashy/sails-docs/blob/master/PAGE_NEEDED.md) object. Has `headers`, a `body`, and a `statusCode`. 26 | 27 | 28 | ### Example 29 | 30 | ```html 31 | 36 | ``` 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.blast.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.blast() 2 | 3 | Broadcast a message to all sockets connected to the server. 4 | 5 | ```javascript 6 | sails.sockets.blast(data); 7 | ``` 8 | 9 | _Or:_ 10 | + `sails.sockets.blast(eventName, data);` 11 | + `sails.sockets.blast(data, socketToOmit);` 12 | + `sails.sockets.blast(eventName, data, socketToOmit);` 13 | 14 | 15 | 16 | ### Usage 17 | 18 | | | Argument | Type | Details 19 | | - | --------------------------- | ------------------- | ----------- 20 | | 1 | eventName | ((string)) | Optional. Defaults to `'message'`. 21 | | 2 | data | ((*)) | The data to send in the message. 22 | | 3 | socketToOmit | ((Socket)) | Optional. If provided, that request socket will **not** receive the message blasted out to everyone else. Useful when the broadcast-worthy event is triggered by a requesting user who doesn't need to hear about it again. 23 | 24 | 25 | 26 | 27 | ### Example 28 | 29 | In a controller action... 30 | 31 | ```javascript 32 | sails.sockets.blast('user_logged_in', { 33 | msg: 'User #' + req.session.userId + ' just logged in.', 34 | user: { 35 | id: req.session.userId, 36 | username: req.session.username 37 | } 38 | }, req.socket); 39 | ``` 40 | 41 | ### Notes 42 | > + The phrase "request socket" here refers to an application-layer WebSocket/Socket.io connection. `req.socket` also exists for HTTP requests, but it refers to the underlying TCP socket at the transport layer, which is different. Be sure and ensure `req.isSocket == true` before using `req.socket` with this method. 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.broadcast.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.broadcast( `roomName`, [`event`], `data`, [`socketToOmit`] ) 2 | 3 | Broadcast a message to a room. 4 | 5 | ```javascript 6 | sails.sockets.broadcast(roomName, data); 7 | ``` 8 | 9 | _Or:_ 10 | + `sails.sockets.broadcast(roomName, eventName, data);` 11 | + `sails.sockets.broadcast(roomName, data, socketToOmit);` 12 | + `sails.sockets.broadcast(roomName, eventName, data, socketToOmit);` 13 | 14 | 15 | ### Usage 16 | 17 | | | Argument | Type | Details 18 | | - | --------------------------- | ------------------- | ----------- 19 | | 1 | roomName | ((string)) | The room to broadcast a message in (see [sails.sockets.join](http://beta.sailsjs.org/#/documentation/reference/websockets/sails.sockets/sails.sockets.join.html)) 20 | | 2 | eventName | ((string)) | Optional. Defaults to `'message'`. 21 | | 3 | data | ((*)) | The data to send in the message. 22 | | 4 | socketToOmit | ((Socket)) | Optional. If provided, that socket will *not* receive the message. This is useful if you trigger the broadcast from a client, but don't want that client to receive the message itself (for example, sending a message to everybody else in a chat room). 23 | 24 | 25 | ### Example 26 | 27 | ```javascript 28 | sails.sockets.broadcast('artsAndEntertainment', { msg: 'Hi there!' }); 29 | ``` 30 | 31 | ### Notes 32 | > + The phrase "request socket" here refers to an application-layer WebSocket/Socket.io connection. `req.socket` also exists for HTTP requests, but it refers to the underlying TCP socket at the transport layer, which is different. Be sure and ensure `req.isSocket == true` before using `req.socket` with this method. 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.emit.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.emit( `socketIds`, [`event`], `data`) 2 | ### Purpose 3 | Send a message to one or more sockets by ID. 4 | 5 | ### Overview 6 | #### Parameters 7 | | | Description | Accepted Data Types | Required ? | 8 | |---|-----------------------------|---------------------|------------| 9 | | 1 | IDs of sockets to receive message | `string`, `array` | Yes | 10 | | 2 | Event name | `string` | No | 11 | | 3 | Message data | `object` | Yes | 12 | 13 | ### Example Usage 14 | ```javascript 15 | // Controller action 16 | 17 | sayHiToFriend: function(req, res) { 18 | var friendId = req.param('friendId'); 19 | sails.sockets.emit(friendId, 'privateMessage', {from: req.session.userId, msg: 'Hi!'}); 20 | res.json({ 21 | message: 'Message sent!' 22 | }); 23 | } 24 | ``` 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.id.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.id() 2 | 3 | Gets the ID of a request socket object. 4 | 5 | ```javascript 6 | sails.sockets.id(socket); 7 | ``` 8 | 9 | ### Usage 10 | 11 | | | Argument | Type | Details 12 | | - | --------------------------- | ------------------- | ----------- 13 | | 1 | socket | ((Socket)) | A request socket (WebSocket/Socket.io) object
e.g. `req.socket`. 14 | 15 | 16 | Once acquired, the socket object's ID can be used to send direct messages to that socket (see [sails.sockets.emit](http://beta.sailsjs.org/#/documentation/reference/websockets/sails.sockets/sails.sockets.emit.html)) or get information about the rooms that the socket is subscribed to (see [sails.sockets.socketRooms](http://beta.sailsjs.org/#/documentation/reference/websockets/sails.sockets/sails.sockets.rooms.html)). 17 | 18 | 19 | ### Example 20 | ```javascript 21 | // Controller action 22 | 23 | getSocketID: function(req, res) { 24 | if (!req.isSocket) return res.badRequest(); 25 | 26 | var socketId = sails.sockets.id(req.socket); 27 | // => "BetX2G-2889Bg22xi-jy" 28 | 29 | return res.ok('My socket ID is: ' + socketId); 30 | } 31 | ``` 32 | 33 | 34 | ### Notes 35 | > + The phrase "request socket" here refers to an application-layer WebSocket/Socket.io connection. `req.socket` also exists for HTTP requests, but it refers to the underlying TCP socket at the transport layer, which is different. Be sure and ensure `req.isSocket == true` before using `req.socket` with this method. 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.join.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.join() 2 | 3 | Subscribes a socket to a generic room. 4 | 5 | ### Usage 6 | 7 | ```js 8 | sails.sockets.join(socket, roomName); 9 | ``` 10 | 11 | 12 | | | Argument | Type | Details | 13 | |---|------------|:-----------:|---------| 14 | | 1 | `socket` | ((string)) -or- ((socket)) | The socket to be subscribed. May be specified by the socket's id or a raw socket object. 15 | | 2 | `roomName` | ((string)) | The name of the room to which the socket will be subscribed. If the room does not exist yet, it will be created. 16 | 17 | ### Example 18 | 19 | In a controller action: 20 | 21 | ```javascript 22 | subscribeToFunRoom: function(req, res) { 23 | var roomName = req.param('roomName'); 24 | sails.sockets.join(req.socket, roomName); 25 | res.json({ 26 | message: 'Subscribed to a fun room called '+roomName+'!' 27 | }); 28 | } 29 | ``` 30 | 31 | *Note: `req.socket` is only valid if the action is triggered via a socket request, e.g. `socket.get('/subscribeToFunRoom/someRoomName')`* 32 | 33 | ### Notes 34 | > + The phrase "request socket" here refers to an application-layer WebSocket/Socket.io connection. `req.socket` also exists for HTTP requests, but it refers to the underlying TCP socket at the transport layer, which is different. Be sure and ensure `req.isSocket == true` before using `req.socket` with this method. 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.leave.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.leave( `socket`, `roomName` ) 2 | ### Purpose 3 | Unsubscribe a socket from a generic room. 4 | 5 | ### Overview 6 | #### Parameters 7 | | | Description | Accepted Data Types | Required ? | 8 | |---|-----------------------------|---------------------|------------| 9 | | 1 | Socket object | `object` | Yes | 10 | | 2 | Room Name | `string` | Yes | 11 | 12 | ### Example Usage 13 | ```javascript 14 | // Controller action 15 | 16 | leaveFunRoom: function(req, res) { 17 | var roomName = req.param('roomName'); 18 | sails.sockets.leave(req.socket, roomName); 19 | res.json({ 20 | message: 'Left a fun room called '+roomName+'!' 21 | }); 22 | } 23 | ``` 24 | 25 | *Note: `req.socket` is only valid if the action is triggered via a socket request, e.g. `socket.get('/leaveFunRoom/someRoomName')`* 26 | 27 | ### Notes 28 | > + The phrase "request socket" here refers to an application-layer WebSocket/Socket.io connection. `req.socket` also exists for HTTP requests, but it refers to the underlying TCP socket at the transport layer, which is different. Be sure and ensure `req.isSocket == true` before using `req.socket` with this method. 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.md: -------------------------------------------------------------------------------- 1 | # Sockets (sails.sockets) 2 | 3 | ### Overview 4 | 5 | Sails exposes several low-level methods for realtime communication with the client via `sails.sockets`. These methods are implemented using a [Socket.io](http://socket.io) connection which is available as `sails.io`; however, using the `sails.sockets` methods instead will future-proof your app against possible changes in underlying implementation. If your app is mainly sending messages to the client regarding changes in your models, you should try and use the [model PubSub methods](https://github.com/balderdashy/sails-docs/blob/0.10/reference/ModelMethods.md#publishcreate-datasocket-) instead. 6 | 7 | ### Looking for `sails.io`? 8 | 9 | For raw access to the underlying [socket.io](http://socket.io/) singleton, you can still access `sails.io`. But starting with Sails v0.11, you should use `sails.sockets` for most low-level use-cases involving sockets, since `sails.io` may be deprecated in an upcoming release to allow for more flexibility/extensibility in the underlying socket implementation. 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.rooms.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.rooms() 2 | ### Purpose 3 | Get the list of all current socket rooms 4 | 5 | ### Overview 6 | #### Parameters 7 | None. 8 | ### Example Usage 9 | ```javascript 10 | // Controller action 11 | 12 | getRoomsList: function(req, res) { 13 | var roomNames = JSON.stringify(sails.sockets.rooms()); 14 | res.json({ 15 | message: 'A list of all the rooms: '+roomNames 16 | }); 17 | } 18 | ``` 19 | 20 | *Note: In Socket.io, all sockets are automatically subscribed to a global room with an empty name (''). This room is not returned as part of the array in `sails.sockets.rooms`* 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.socketRooms.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.socketRooms( `socket` ) 2 | ### Purpose 3 | Get the list of rooms a socket is subscribed to 4 | 5 | ### Overview 6 | #### Parameters 7 | | | Description | Accepted Data Types | Required ? | 8 | |---|-----------------------------|---------------------|------------| 9 | | 1 | Socket | `object` | Yes | 10 | 11 | ### Example Usage 12 | ```javascript 13 | // Controller action 14 | 15 | getMyRooms: function(req, res) { 16 | var roomNames = JSON.stringify(sails.sockets.socketRooms(req.socket)); 17 | res.json({ 18 | message: 'I am subscribed to: '+roomNames 19 | }); 20 | } 21 | ``` 22 | 23 | ### Notes 24 | > + The phrase "request socket" here refers to an application-layer WebSocket/Socket.io connection. `req.socket` also exists for HTTP requests, but it refers to the underlying TCP socket at the transport layer, which is different. Be sure and ensure `req.isSocket == true` before using `req.socket` with this method. 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.subscribeToFirehose.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.subscribeToFirehose() 2 | 3 | Subscribe to the "firehose", which (while running in the development environment) broadcasts messages about _all_ model events. 4 | 5 | ```javascript 6 | sails.sockets.subscribeToFirehose(socket); 7 | ``` 8 | 9 | 10 | ### Usage 11 | 12 | | | Argument | Type | Details 13 | | - | --------------------------- | ------------------- | ----------- 14 | | 1 | socket | ((Socket)) | A request socket (WebSocket/Socket.io) object
e.g. `req.socket`. 15 | 16 | 17 | The firehose publishes messages using the "firehose" event. By default, messages will be published when a model instance is created, destroyed, or updated, or when an associated collection is added to or removed from. The message content is similar to that for the [PubSub methods](#!documentation/reference/ModelMethods/ModelMethods.html) like `publishUpdate`, `publishCreate`, etc. 18 | 19 | 20 | ### Example 21 | ```javascript 22 | // Controller action 23 | 24 | enableDebugMode: function(req, res) { 25 | if (!req.isSocket) return res.badRequest(); 26 | sails.sockets.subscribeToFirehose(req.socket); 27 | return res.ok(); 28 | } 29 | ``` 30 | 31 | ### Notes 32 | > + You can also subscribe to the firehose using only client-side code by making a socket GET request to `/firehose` (only enabled when `process.env.NODE_ENV==='development'`) 33 | > + The phrase "request socket" here refers to an application-layer WebSocket/Socket.io connection. `req.socket` also exists for HTTP requests, but it refers to the underlying TCP socket at the transport layer, which is different. Be sure and ensure `req.isSocket == true` before using `req.socket` with this method. 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.subscribers.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.subscribers() 2 | 3 | Get the IDs of all sockets subscribed to a room. 4 | 5 | ```javascript 6 | sails.sockets.subscribers(roomName); 7 | ``` 8 | 9 | ### Usage 10 | 11 | | | Argument | Type | Details 12 | | - | --------------------------- | ------------------- | ----------- 13 | | 1 | roomName | ((string)) | The name of the room whose socket ids should be retrieved.
e.g. `'supportchat'` 14 | 15 | ### Example 16 | 17 | ```javascript 18 | sails.sockets.subscribers('supportchat'); 19 | // => ['BetX2G-2889Bg22xi-jy', 'BTA4G-8126Kr32bi-za'] 20 | ``` 21 | 22 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /reference/websockets/sails.sockets/sails.sockets.unsubscribeFromFirehose.md: -------------------------------------------------------------------------------- 1 | # sails.sockets.unsubscribeFromFirehose() 2 | 3 | Unsubscribe from the firehose. 4 | 5 | ```javascript 6 | sails.sockets.unsubscribeFromFirehose(socket); 7 | ``` 8 | 9 | ### Usage 10 | 11 | | | Argument | Type | Details 12 | | - | --------------------------- | ------------------- | ----------- 13 | | 1 | socket | ((Socket)) | A request socket (WebSocket/Socket.io) object
e.g. `req.socket`. 14 | 15 | ### Example 16 | ```javascript 17 | // Controller action 18 | 19 | disableDebugMode: function(req, res) { 20 | if (!req.isSocket) return res.badRequest(); 21 | sails.sockets.unsubscribeFromFirehose(req.socket); 22 | return res.ok(); 23 | } 24 | ``` 25 | 26 | 27 | ### Notes 28 | > + The phrase "request socket" here refers to an application-layer WebSocket/Socket.io connection. `req.socket` also exists for HTTP requests, but it refers to the underlying TCP socket at the transport layer, which is different. Be sure and ensure `req.isSocket == true` before using `req.socket` with this method. 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /reference/websockets/websockets.md: -------------------------------------------------------------------------------- 1 | # WebSockets 2 | 3 | ### Overview 4 | 5 | There are two main continents in the world of WebSockets- the client (e.g. browser) and the server (e.g. your routes, controllers, and so forth). 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/styleguide/sailslogo_blue.png: -------------------------------------------------------------------------------- 1 | ɐNG 2 |  3 | -------------------------------------------------------------------------------- /resources/styleguide/sailslogo_blue@2x.png: -------------------------------------------------------------------------------- 1 | ɐNG 2 |  3 | -------------------------------------------------------------------------------- /resources/styleguide/sailslogo_dark.png: -------------------------------------------------------------------------------- 1 | ɐNG 2 |  3 | -------------------------------------------------------------------------------- /resources/styleguide/sailslogo_dark@2x.png: -------------------------------------------------------------------------------- 1 | ɐNG 2 |  3 | -------------------------------------------------------------------------------- /resources/styleguide/sailslogo_gray.png: -------------------------------------------------------------------------------- 1 | ɐNG 2 |  3 | -------------------------------------------------------------------------------- /resources/styleguide/sailslogo_gray@2x.png: -------------------------------------------------------------------------------- 1 | ɐNG 2 |  3 | -------------------------------------------------------------------------------- /resources/styleguide/sailslogo_white.png: -------------------------------------------------------------------------------- 1 | ɐNG 2 |  3 | -------------------------------------------------------------------------------- /resources/styleguide/sailslogo_white@2x.png: -------------------------------------------------------------------------------- 1 | ɐNG 2 |  3 | -------------------------------------------------------------------------------- /status/plugins/README.md: -------------------------------------------------------------------------------- 1 | # Plugins 2 | 3 | There are currently three types of plugins in Sails: 4 | 5 | + **Generators** - for adding and overriding functionality in the Sails CLI 6 | + **Adapters** - for integrating Waterline (Sails' ORM) with new data sources, including databases, APIs, or even hardware. 7 | + **Hooks** - for overriding or injecting new low-level functionality in the Sails runtime 8 | 9 | ## API Status 10 | 11 | > ##### Stability: [1-2](http://nodejs.org/api/documentation.html#documentation_stability_index) - Varies 12 | > 13 | > The API is in the process of settling, but has not yet had sufficient real-world testing to be considered stable. 14 | 15 | -------------------------------------------------------------------------------- /status/plugins/generators.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Known generators for Sails.js. 3 | * 4 | * The `generators` API has not settled yet-- it is still experimental. 5 | * Please read: https://github.com/balderdashy/sails/blob/master/CONTRIBUTING.md#authoring-a-new-generator 6 | */ 7 | module.exports = { 8 | 9 | // 10 | // Core generators 11 | // 12 | 13 | // TODO 14 | 15 | 16 | 17 | 18 | // 19 | // Community generators 20 | // 21 | 22 | // TODO 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /status/plugins/hooks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Known hooks for Sails.js. 3 | * 4 | * The hooks API has not settled yet-- it is still experimental. 5 | * Please read: https://github.com/balderdashy/sails/tree/v0.10/lib/hooks#custom-hooks--plugins 6 | */ 7 | module.exports = { 8 | 9 | // 10 | // Core hooks 11 | // 12 | 13 | // TODO 14 | 15 | 16 | 17 | 18 | // 19 | // Community hooks 20 | // 21 | 22 | // TODO 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /status/res.md: -------------------------------------------------------------------------------- 1 | # res 2 | 3 | The chart below describes support for the methods and properties on the Sails [Response](/#/documentation/reference/res) object (`res`) across multiple transports: 4 | 5 | 6 | | | HTTP | WebSockets | 7 | |----------------|---------|------------| 8 | | res.status() | :white_check_mark: | :white_check_mark: | 9 | | res.set() | :white_check_mark: | :white_large_square: | 10 | | res.get() | :white_check_mark: | :white_large_square: | 11 | | res.cookie() | :white_check_mark: | :white_large_square: | 12 | | res.clearCookie() | :white_check_mark: | :white_large_square: | 13 | | res.redirect() | :white_check_mark: | :white_check_mark: | 14 | | res.location() | :white_check_mark: | :white_large_square: | 15 | | res.charset | :white_check_mark: | :white_check_mark: | 16 | | res.send() | :white_check_mark: | :white_check_mark: | 17 | | res.json() | :white_check_mark: | :white_check_mark: | 18 | | res.jsonp() | :white_check_mark: | :white_check_mark: | 19 | | res.type() | :white_check_mark: | :white_large_square: | 20 | | res.format() | :white_check_mark: | :white_large_square: | 21 | | res.attachment() | :white_check_mark: | :white_large_square: | 22 | | res.sendfile() | :white_check_mark: | :white_large_square: | 23 | | res.download() | :white_check_mark: | :white_large_square: | 24 | | res.links() | :white_check_mark: | :white_large_square: | 25 | | res.locals | :white_check_mark: | :white_check_mark: | 26 | | res.render() | :white_check_mark: | :white_large_square: | 27 | | res.view() | :white_check_mark: | :white_large_square: | 28 | 29 | 30 | ### Legend 31 | 32 | - :white_check_mark: - supported feature 33 | - :white_large_square: - feature not yet implemented for this transport 34 | - :heavy_multiplication_x: - unsupported feature due to protocol restrictions 35 | -------------------------------------------------------------------------------- /support/irc/configuringClient.md: -------------------------------------------------------------------------------- 1 | # Setting Up Your Client 2 | ## Registering On Freenode 3 | Our chat room is on the Freenode network. Freenode does not require that you register your `nick` name. You do have the option to though. If you want to do this, read about how to do it [on the freenode website](https://freenode.net/faq.shtml#registering) 4 | 5 | ## Getting on Freenode 6 | 7 | Each IRC Client is a little different to configure. All of the ones we have recommended have very straight forward configuration process. If your client provides a list of available servers, look for the one called Freenode. 8 | 9 | Make sure to put in a `nick` to go by. 10 | 11 | Upon connecting to the Freenode network, join us by typing `/join #sailsjs`. 12 | 13 | If you registered a nick, you can identify yourself with `/msg nickserv identify ` 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /support/irc/grabClient.md: -------------------------------------------------------------------------------- 1 | # Grab An IRC Client 2 | Below you'll find some of the more popular IRC Clients. 3 | 4 | ## Linux 5 | - [xChat](http://xchat.org) 6 | - [irssi](http://irssi.org) 7 | - [weeChat]](http://www.weechat.org) 8 | 9 | #### Using apt package manager for Ubuntu/Debian 10 | ``` 11 | sudo apt-get install weechat 12 | 13 | ``` 14 | 15 | ## OSX 16 | - [irssi](http://irssi.org) 17 | 18 | ``` 19 | sudo steveJobsPM --prettyPlease install -m 'is this okay?' irssi 20 | 21 | ``` 22 | ## Windows 23 | - [xChat](http://xchat.org) 24 | - [hydra IRC](http://www.hydrairc.com/content/downloads) 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /support/irc/irc.md: -------------------------------------------------------------------------------- 1 | # Getting help on IRC 2 | ## `#sailsjs` on irc.freenode.net 3 | If you are looking for a quick answer and you can't find what you're looking for in the docs, come ask in our IRC chat room. While there is typically somebody there who can answer your question, please remember that #sailsjs is 100% community maintained. That means that help is given at the discretion of the community. For best results, be polite and to the point. 4 | 5 | If you've never been on IRC, now is the perfect time. Getting started is easy. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /support/irc/sailsTroll.md: -------------------------------------------------------------------------------- 1 | # Sails Troll 2 | Sails Troll is our resident IRC Bot. His job is to write down what people say in case someone wants to find it later. 3 | 4 | He also informs the room whenever someone pushes up a change to any of the repos in the Sails.js ecosystem. 5 | 6 | ## Searching with SailsTroll 7 | 8 | ## Yo Mama Jokes 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /userguides/deployment/deployment.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | ### Deploying your app 3 | 4 | Make sure you see 'before deployment' guide in 'security' 5 | 6 | ### Picking a host 7 | 8 | Here are some hosts... 9 | 10 | 11 | -------------------------------------------------------------------------------- /userguides/deployment/nodejitsu.md: -------------------------------------------------------------------------------- 1 | # Nodejitsu 2 | ### Deploying to Nodejitsu 3 | 4 | ### This guide was brought to you by 5 | ##### Name 6 | ##### Bio 7 | ##### Link 8 | ##### Organization 9 | ##### Etc... 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /userguides/deployment/openshift.md: -------------------------------------------------------------------------------- 1 | # Openshift 2 | ### Deploying to OpenShift 3 | 4 | 5 | ### This guide was brought to you by 6 | ##### Name 7 | ##### Bio 8 | ##### Link 9 | ##### Organization 10 | ##### Etc... 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /userguides/guideStub.md: -------------------------------------------------------------------------------- 1 | # Document Stubb 2 | ### This is a stub! 3 | 4 | Here is some information 5 | 6 | ### Contributed By 7 | ##### Name 8 | ##### Bio 9 | ##### Link 10 | ##### Organization 11 | ##### Etc... 12 | 13 | 14 | -------------------------------------------------------------------------------- /userguides/userguides.md: -------------------------------------------------------------------------------- 1 | # Sails.js User Guides 2 | ### Guides 3 | 4 | > This will be a top level documentation section on the sails.js website as soon as we get a little more content for it. 5 | 6 | Sails.js was created by the Balderdash team out of necessity in order to quickly and efficiently make rock solid apps for our clients. We then open sourced it so others could do the same. Client work is still what pays the bills at Balderdash and while we love to work on Sails full time, we just can't. This section is part of an ongoing effort to further open up the Sails.js framework to the community and keep Balderdash from constraining it's growth. 7 | 8 | #### How can you help? 9 | Think about how you have used Sails for your project then write a guide about it! 10 | 11 | #### What should I write about? 12 | - If you have a less than common use case, write a guide about it. 13 | - If you had a hard time finding a solution to a particular problem while using Sails, write a guide describing your workaround. 14 | - Are you doing something unconventional with Sails? Write a guide. 15 | - Are you using Sails for your embedded hardware project? Please, for the love of God, write a guide! 16 | 17 | #### Okay, I'll do it! Now what? 18 | 19 | Thanks. You're awesome! Now, before you write anything, see the very first user guide in this folder under [contributing.md](https://github.com/balderdashy/sails-docs/blob/master/userguides/contributing.md) 20 | 21 | #### Legal Disclaimer 22 | 23 | Just kidding about the legal disclaimer. Seriously though, thank you for contibuting. If it weren't for the help of folks like you, this project wouldn't be half of what it is today. You guys rock. 24 | 25 | #### Sincerely and Truly 26 | Nick (@uncletammy) 27 | 28 | 29 | 30 | --------------------------------------------------------------------------------