diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..c6ea43bc --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,23 @@ + + +* **Platform**: +* **Database**: +* **Lux Version**: +* **Node Version**: + + diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..9c0be88a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v6 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..6d7a95dd --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,95 @@ +# The Lux Code of Conduct + +## Conduct + +**Contact**: [lux@postlight.com](mailto:lux@postlight.com) + +* We are committed to providing a friendly, safe and welcoming environment for +all, regardless of level of experience, gender, gender identity and expression, +sexual orientation, disability, personal appearance, body size, race, ethnicity, +age, religion, nationality, or other similar characteristic. + +* On Gitter, please avoid using overtly sexual nicknames or other nicknames +that might detract from a friendly, safe and welcoming environment for all. + +* Please be kind and courteous. There's no need to be mean or rude. + +* Respect that people have differences of opinion and that every design or +implementation choice carries a trade-off and numerous costs. There is seldom a +right answer. + +* Please keep unstructured critique to a minimum. If you have solid ideas you +want to experiment with, make a fork and see how it works. + +* We will exclude you from interaction if you insult, demean or harass anyone. +That is not welcome behavior. We interpret the term "harassment" as including +the definition in the [Citizen Code of Conduct](http://bit.ly/2jCvEok); if you +have any lack of clarity about what might be included in that concept, please +read their definition. In particular, we don't tolerate behavior that excludes +people in socially marginalized groups. + +* Private harassment is also unacceptable. No matter who you are, if you feel +you have been or are being harassed or made uncomfortable by a community member, +please contact one of the channel ops or any of the [Lux moderation team](mailto:lux@postlight.com) +immediately. Whether you're a regular contributor or a newcomer, we care about +making this community a safe place for you and we've got your back. + +* Likewise any spamming, trolling, flaming, baiting or other attention-stealing +behavior is not welcome. + +## Moderation + +These are the policies for upholding our community's standards of conduct. If you +feel that a thread needs moderation, please contact the [Lux moderation team](mailto:lux@postlight.com). + +1. Remarks that violate the Lux standards of conduct, including hateful, hurtful, +oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but +never targeting another user, and never in a hateful manner.) + +2. Remarks that moderators find inappropriate, whether listed in the code of +conduct or not, are also not allowed. + +3. Moderators will first respond to such remarks with a warning. + +4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of +the communication channel to cool off. + +5. If the user comes back and continues to make trouble, they will be banned, +i.e., indefinitely excluded. + +6. Moderators may choose at their discretion to un-ban the user if it was a first +offense and they offer the offended party a genuine apology. + +7. If a moderator bans someone and you think it was unjustified, please take it +up with that moderator, or with a different moderator, **in private**. Complaints +about bans in-channel are not allowed. + +8. Moderators are held to a higher standard than other community members. If a +moderator creates an inappropriate situation, they should expect less leeway than +others. + +In the Lux community we strive to go the extra step to look out for each other. +Don't just aim to be technically unimpeachable, try to be your best self. In +particular, avoid flirting with offensive or sensitive issues, particularly if +they're off-topic; this all too often leads to unnecessary fights, hurt feelings, +and damaged trust; worse, it can drive people away from the community entirely. + +And if someone takes issue with something you said or did, resist the urge to be +defensive. Just stop doing what it was they complained about and apologize. Even +if you feel you were misinterpreted or unfairly accused, chances are good there +was something you could've communicated better — remember that it's your responsibility +to make your fellow community members comfortable. Everyone wants to get along and we +are all here first and foremost because we want to talk about cool technology. +You will find that people will be eager to assume good intent and forgive as long +as you earn their trust. + +The enforcement policies listed above apply to all official Lux venues; including +the official Gitter room ([*postlight/lux*](http://bit.ly/2k4qS1k)); GitHub +repositories under postlight/lux such as Lux core and other Postlight repositories +with a \*-lux or lux-\* naming convention; For other projects adopting the Lux +Code of Conduct, please contact the maintainers of those projects for enforcement. +If you wish to use this code of conduct for your own project, consider explicitly +mentioning your moderation policy or making a copy with your own moderation policy +so as to avoid confusion. + +*Adapted from the [Rust Code of Conduct](https://bit.ly/2jhrmEo).* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c180496c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,248 @@ +# Contributing to Lux + +Thank you for your interest in contributing to Lux! This document will help +answer any outstanding questions you may have about the contribution process. + +*Please read the [Code of Conduct](./CODE_OF_CONDUCT.md) before you participate +in community.* + +## Contents + +* [Reporting a Bug](#reporting-a-bug) +* [Requesting a Feature](#requesting-a-feature) +* [Development Workflow](#development-workflow) +* [Writing Documentation](#writing-documentation) +* [Submitting a Pull Request](#submitting-a-pull-request) +* [Helpful Links and Information](#helpful-links-and-information) + +## Reporting a Bug + +While bugs are unfortunate, they're a reality in software. We can't fix what we +don't know about, so please report liberally. If you're not sure if something is +a bug or not, feel free to file a bug anyway. + +If you have the chance, before reporting a bug, please search existing issues, +as it's possible that someone else has already reported your error. This doesn't +always work, and sometimes it's hard to know what to search for, so consider +this extra credit. We won't mind if you accidentally file a duplicate report. + +Opening an issue is as easy as following [this link](https://github.com/postlight/lux/issues/new) +and filling out the fields. + +## Requesting a Feature + +To request a change to the way that Lux works, please open an issue in the RFCs +repository rather than this one. New features and other significant API changes +must go through the RFC process. For more information about the RFC process, head +over to the [lux-rfcs repository](https://github.com/postlight/lux-rfcs). + +## Development Workflow + +This section of the document outlines how to build, run, and test Lux locally. + +### Building + +![lux build](https://media.giphy.com/media/l0ExhMFcO0stlw0q4/giphy.gif) + +When a project that is built with Lux executes a command like `lux serve` it goes +through a build process. During this build process, Lux core is also being built. +The output of this build process is a bundled JavaScript file that includes only +the parts of Lux core and your application that you actually use. This is known as +tree shaking. Although saving bytes may not be necessary for server side applications, +tree shaking can still help optimize application start time amongst other things. +Technically speaking, Lux is not built until a project that uses Lux is built—so why +build in development at all? Well, some parts of Lux core are required to be built and +executable in the targeted Node.js version(s). + +To build the required modules for local development, execute the following commands: + +```bash +# Clone this repository from GitHub. +git clone https://github.com/postlight/lux.git + +# Navigate into the root of this repository. +cd lux + +# Install local dependencies. +npm install + +# Clean any build artifacts remaining from prior builds. This step is optional +# and only makes sense if a build has already occurred. +npm run clean + +# Run the build tools. +npm run build + +# Symlink the lux-framework to the global node_modules directory. This ensures +# that the "lux" command will use the files we just built instead of another +# install. +npm link +``` + +For general debugging and sanity checking code changes to Lux core, you can use +the [test app](./test/test-app). To run the test app for the first time, +execute the following commands: + +```bash +# Navigate to the test/test-app directory from the root of this repository. +cd test/test-app + +# Create the database schema. +lux db:create + +# Run any pending database migrations. +lux db:migrate + +# Seed the database with fixtures. +lux db:seed + +# Run the application server. +lux serve +``` + +### Testing + +First make sure you have built lux locally and it is symlinked to your global +`node_modules` directory. Once you have completed the build steps, execute the +following command: + +```bash +# Run the test suite from the root of this repository. +NODE_ENV="test" npm test +``` + +*NOTE:* + +Subsequent executions of the test suite can run without going through the build +steps again. + +### Code Style + +#### Flow + +The Lux codebase is statically typed with [Flow](https://flowtype.org). This +helps prevent many common bugs including ones caused by [unexpected type coercions](https://www.destroyallsoftware.com/talks/wat). + +If you have never written JavaScript with [Flow](https://flowtype.org) or +[TypeScript](https://www.typescriptlang.org/) before, you may have a bit of a +learning curve. If you get stuck on something, feel free to ask a question in the +[*postlight/lux*](https://gitter.im/postlight/lux) and/or [*facebook/flow*](https://gitter.im/facebook/flow) +Gitter room. We recommend installing an editor plugin with autocompletion and realtime error +checking. Below you will find a few example plugins for many common editors. + +* [Nuclide (Atom)](https://nuclide.io/) +* [FlowIDE (Sublime Text)](https://github.com/tptee/FlowIDE) +* [flow-for-vscode (Visual Studio Code)](https://github.com/flowtype/flow-for-vscode) +* [flow-for-emacs (Emacs)](https://github.com/flowtype/flow-for-emacs) +* [vim-flow (Vim)](https://github.com/flowtype/vim-flow) + +#### JavaScript + +We use a slightly modified version of the Airbnb JavaScript [Style Guide](https://github.com/airbnb/javascript). +To enforce this, all pull requests that must pass [ESLint](http://eslint.org/) +before they can merge. + +#### Markdown + +In addition to enforcing a JavaScript style guide, we also require that markdown +files pass [remarklint](https://github.com/wooorm/remark-lint) with the recommended +preset. This helps keep our markdown tidy, consistent, and compatible with a range of +markdown parsers used for generating documentation. + +### Node.js Version Requirement + +Lux is built against Node `>= v6`. Since this is the latest LTS release and the +version we run in our CI environments, we recommend you use it when working on +the Lux codebase. + +If you use [nvm](https://github.com/creationix/nvm) to manage Node.js versions +and zsh (like [Oh-My-ZSH](https://github.com/robbyrussell/oh-my-zsh)), you can +have nvm switch to the correct Node.js version automatically when you cd into +this repository. To do so, add the following to your `~/.zshrc` file: + +```bash +# place this after nvm initialization! +autoload -U add-zsh-hook +load-nvmrc() { + local node_version="$(nvm version)" + local nvmrc_path="$(nvm_find_nvmrc)" + + if [ -n "$nvmrc_path" ]; then + local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")") + + if [ "$nvmrc_node_version" != "N/A" ] && [ "$nvmrc_node_version" != "$node_version" ]; then + nvm install + fi + elif [ "$node_version" != "$(nvm version default)" ]; then + echo "Reverting to nvm default version" + nvm use default + fi +} +add-zsh-hook chpwd load-nvmrc +load-nvmrc +``` + +## Writing Documentation + +Improvements to documentation are a great way to start contributing to Lux. The +sources for the official documentation is generated from source code comments +and markdown files that live in this repository. + +The [Guide](https://lux.postlight.com/docs/latest/guide) section of the official +documentation is generated from markdown files found in files within the[`./guide`](./guide) +directory of this repository. + +The [API reference](https://lux.postlight.com/docs/latest/api) section of the official +documentation is generated from source code comments found in files within the [`./src`](./src) +directory of this repository. + +## Submitting a Pull Request + +Want to make a change to Lux? Submit a pull request! We use the "fork and pull" +model [described here](https://help.github.com/articles/creating-a-pull-request-from-a-fork). + +**Before submitting a pull request**, please make sure you do the following: + +* [X] You have added tests for modifications you made to the codebase. +* [X] You have updated any documentation in the source code comments for APIs +that you may have changed. +* [X] You have no linter errors to correct after running `npm run lint`. +* [X] You have no type errors to correct after running `npm run flow`. +* [X] You have ran the test suite via `npm test` and it passed. + +### Commit Style + +Commit messages should follow the format outlined below: + +`prefix: message in present tense` + + Prefix | Description +------------:|:------------------------------------------------------------------------- + chore | does not effect the production version of the app in any way. + deps | add, update, or remove a dependency. + docs | add, update, or remove documentation. no code changes. + dx | improve the development experience of lux core. + feat | a feature or enhancement. can be incredibly small. + fix | a bug fix for something that was broken. + perf | add, update, or fix a test. + refactor | change code, but not functionality. + style | change code style, like removing whitespace. no functional code changes. + test | add, update, or fix a test. + +### Code Reviews + +Once you have submitted a pull request, a member of the core team must review it +before it is merged. We try to review pull requests within 3 days but sometimes +fall behind. Feel free to reach out to someone in the [*postlight/lux*](https://gitter.im/postlight/lux) +room on Gitter if you have not received a review after 3 days. + +## Helpful Links and Information + +Some useful places to look for information are: + +* The [*postlight/lux*](https://gitter.im/postlight/lux) room on Gitter +* The official [guides and documentation](https://lux.postlight.com/docs/latest) +* Example applications in [this repository](./examples) + +*Adapted from [Contributing to Node.js](https://github.com/nodejs/node/blob/master/CONTRIBUTING.md) +as well as [Contributing to Rust](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md).* diff --git a/README.md b/README.md index 2a17698c..136921da 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Could you imagine how ugly that gets when you have to implement pagination, filt Also, where does that code live? In what file and folder would I find it? What pattern do you use for organizing this code? -😲Ok ok give me back Rails I'll worry about performance and scaling later. After all, premature optimization is the root of all evil. +😲 Ok ok give me back Rails I'll worry about performance and scaling later. After all, premature optimization is the root of all evil. ##### Problem.resolve(); @@ -145,33 +145,9 @@ For more information checkout out the [Guides](https://lux.postlight.com/). [**postlight/lux-benchmarks**](https://github.com/postlight/lux-benchmarks) -## Contributing +## Contribution -### Installation - -```bash -git clone https://github.com/postlight/lux -cd lux -npm install -``` - -### Testing - -```bash -git clone https://github.com/postlight/lux - -# Install Lux dependencies -cd lux -npm install - -# Install test app dependencies -cd test/test-app -npm install - -# Run the test suite -cd ../../ -npm test -``` +See [CONTRIBUTING.md](./CONTRIBUTING.md). ## Useful Links diff --git a/ROADMAP.md b/ROADMAP.md deleted file mode 100644 index 8c5b20f5..00000000 --- a/ROADMAP.md +++ /dev/null @@ -1,152 +0,0 @@ -# Roadmap - -In this document you will find a proposed list of features that will be released during the Lux `1.0` lifecycle. - - -## Router Namespaces - -Similar to [Rails](http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing), Lux should provide a simple API for defining a router namespace. There are a number of common use cases for router namespaces that make this feature a must. API versioning and a simple way to define "Admin Only" are two good examples. - -#### API - -##### Routes - -Defining router namespaces will be done in the `routes.js` file where you currently define your applications resources and routes. - -Similar to the `resource` and `route` arguments, the `namespace` argument will also be a function. - -```javascript -// ./app/routes.js -export default function routes() { - this.resource('posts'); - - this.namespace('admin', function admin(route, resource) { - this.resource('posts'); - }); -} -``` - -There will also be the ability to pass an options hash as the second argument to the `namespace` function with properties such as `mount` in case the name of a declared namespace is different from the intended mount point. - -```javascript -// ./app/routes.js -export default function routes() { - this.namespace('legacy', { - mount: 'v1' - }, function legacy() { - this.resource('posts'); - }); - - this.namespace('current', { - mount: 'v2' - }, function current() { - this.resource('posts'); - }); -} -``` - -##### Controllers - -When you declare a namespace, Lux will expect that namespace to have it's own directory and `ApplicationController` in the `./controllers` directory. - -``` -controllers -├── admin -│   ├── application.js -│   └── posts.js -├── application.js -└── posts.js -``` - -This is the difference between a namespace and nested route. Namespaces have an `ApplicationController` unique to the namespace. This allows for middleware to be declared at the namespace level. - -```javascript -// ./app/controllers/application.js -class ApplicationController extends Controller { - beforeAction = [ - async function authorizeUser(req, res) { - // Ensure a user is logged in. - } - ]; -} - -// ./app/controllers/admin/application.js -class AdminController extends Controller { - beforeAction = [ - async function authorizeAdmin(req, res) { - // Ensure an admin is logged in. - } - ]; -} -``` - -##### Nesting - -Namespaces nesting will be supported without a limit to the level of nesting. Even though middleware appears to be a nested tree structure during the declaration, Lux will flatten and cache these functions as a one dimensional array upon the application's boot sequence. - -Here is the middleware that would be executed when a user visits `/posts` - -```javascript -[ - authorizeUser, - PostsController.index -] -``` - -Here is the middleware that would be executed when a user visits `/admin/posts` - -```javascript -[ - authorizeUser, - authorizeAdmin, - AdminPostsController.index -] -``` - -[\* Middleware flattening already is implemented in the current release of Lux.](https://github.com/postlight/lux/blob/master/src/packages/route/utils/create-action.js#L31) - - -## Polymorphic Relationships (#75) - -#### API - -Declaring a polymorphic relationship on a model should be as simple as a boolean flag. - -```javascript -class Comment extends Model { - static hasOne = { - commentable: { - polymorphic: true - } - } -} - -class Post extends Model { - static hasMany = { - comments: { - model: 'comment', - inverse: 'commentable' - } - } -} -``` - -The example above would create the columns `commentable_id` and `commentable_type` on the `comments` table. - - --- - - -## In Progress - -Below is a list of features that will likely be a part of the `1.0` release but their API is still in very early stages. - -* WebSockets - * Controller API - * Model Hook API - -* Application Testing - * Test Generators - * Debugging Tools - * ~~Generated SQL Logging ([#48](https://github.com/postlight/lux/issues/48))~~ - * Implemented in #65